Sequenzia/app/models/Artist.php
2013-10-26 18:06:58 -05:00

282 lines
7.8 KiB
PHP
Executable File

<?php
// ActiveRecord::load_model(array('ArtistUrl', 'WikiPage'));
class Artist extends Rails\ActiveRecord\Base
{
protected $alias_names = [];
protected $member_names = [];
public $updater_ip_addr = [];
protected $notes;
protected $urls;
public function __toString()
{
return $this->name;
}
protected function associations()
{
return [
'has_many' => [
'artist_urls' => ['class_name' => 'ArtistUrl']
],
'belongs_to' => [
'updater' => ['class_name' => 'User', 'foreign_key' => "updater_id"]
]
];
}
protected function callbacks()
{
return [
'after_save' => ['commit_urls', 'commit_notes', 'commit_aliases', 'commit_members'],
'before_validation' => ['normalize']
];
}
protected function validations()
{
return [
'name' => ['uniqueness' => true]
];
}
/* UrlMethods { */
static public function find_all_by_url($url)
{
$url = ArtistUrl::normalize($url);
$artists = new Rails\ActiveRecord\Collection();
while ($artists->blank() && strlen($url) > 10) {
$u = str_replace('*', '%', $url) . '%';
$artists->merge(Artist::where("artists.alias_id IS NULL AND artists_urls.normalized_url LIKE ?", $u)->joins("JOIN artists_urls ON artists_urls.artist_id = artists.id")->order("artists.name")->take());
# Remove duplicates based on name
$artists->unique('name');
$url = dirname($url);
}
return $artists->slice(0, 20);
}
protected function commit_urls()
{
if ($this->urls) {
$this->artist_urls->each('destroy');
foreach (array_unique(array_filter(preg_split('/\v/', $this->urls))) as $url)
ArtistUrl::create(array('url' => $url, 'artist_id' => $this->id));
}
}
public function urls()
{
$urls = array();
foreach($this->artist_urls as $x)
$urls[] = $x->url;
return implode("\n", $urls);
}
public function setUrls($url)
{
$this->urls = $url;
}
/* Note Methods */
protected function wiki_page()
{
return WikiPage::find_page($this->name);
}
public function notes_locked()
{
if ($this->wiki_page()) {
return !empty($this->wiki_page()->is_locked);
}
}
public function notes()
{
if ($this->wiki_page())
return $this->wiki_page()->body;
else
return '';
}
public function setNotes($notes)
{
$this->notes = $notes;
}
protected function commit_notes()
{
if ($this->notes) {
if (!$this->wiki_page())
WikiPage::create(array('title' => $this->name, 'body' => $this->notes, 'ip_addr' => $this->updater_ip_addr, 'user_id' => $this->updater_id));
elseif ($this->wiki_page()->is_locked)
$this->errors()->add('notes', "are locked");
else
$this->wiki_page()->updateAttributes(array('body' => $this->notes, 'ip_addr' => $this->updater_ip_addr, 'user_id' => $this->updater_id));
}
}
/* Alias Methods */
protected function commit_aliases()
{
self::connection()->executeSql("UPDATE artists SET alias_id = NULL WHERE alias_id = ".$this->id);
if ($this->alias_names) {
foreach ($this->alias_names as $name) {
$a = Artist::where(['name' => $name])->firstOrCreate()->updateAttributes(array('alias_id' => $this->id, 'updater_id' => $this->updater_id));
}
}
}
public function alias_names()
{
return implode(', ', $this->aliases()->getAttributes('name'));
}
public function aliases()
{
if ($this->isNewRecord())
return new Rails\ActiveRecord\Collection();
else
return Artist::where("alias_id = ".$this->id)->order("name")->take();
}
public function alias_name()
{
$name = '';
if ($this->alias_id) {
try {
$name = Artist::find($this->alias_id)->name;
} catch(Rails\ActiveRecord\Exception\RecordNotFoundException $e) {
}
}
return $name;
}
/* Group Methods */
protected function commit_members()
{
self::connection()->executeSql("UPDATE artists SET group_id = NULL WHERE group_id = ".$this->id);
if ($this->member_names) {
foreach ($this->member_names as $name) {
$a = Artist::where(['name' => $name])->firstOrCreate();
$a->updateAttributes(array('group_id' => $this->id, 'updater_id' => $this->updater_id));
}
}
}
public function group_name()
{
if ($this->group_id) {
$artist = Artist::where('id = ' . $this->group_id)->first();
return $artist ? $artist->name : '';
}
}
public function members()
{
if ($this->isNewRecord())
return new Rails\ActiveRecord\Collection();
else
return Artist::where("group_id = ".$this->id)->order("name")->take();
}
public function member_names()
{
return implode(', ', $this->members()->getAttributes('name'));
}
public function setAliasNames($names)
{
if ($names = array_filter(explode(',', trim($names)))) {
foreach ($names as $name)
$this->alias_names[] = trim($name);
}
}
public function setAliasName($name)
{
if ($name) {
if ($artist = Artist::where(['name' => $name])->firstOrCreate())
$this->alias_id = $artist->id;
else
$this->alias_id = null;
} else
$this->alias_id = null;
}
public function setMemberNames($names)
{
if ($names = array_filter(explode(',', trim($names)))) {
foreach ($names as $name)
$this->member_names[] = trim($name);
}
}
public function setGroupName($name)
{
if (!$name)
$this->group_id = null;
else
$this->group_id = Artist::where(['name' => $name])->firstOrCreate()->id;
}
/* Api Methods */
public function api_attributes()
{
return [
'id' => $this->id,
'name' => $this->name,
'alias_id' => $this->alias_id,
'group_id' => $this->group_id,
'urls' => $this->artist_urls->getAttributes('url')
];
}
public function toXml(array $options = array())
{
$options['root'] = "artist";
$options['attributes'] = $this->api_attributes();
return parent::toXml($options);
}
public function asJson(array $args = array())
{
return $this->api_attributes();
}
public function normalize()
{
$this->name = str_replace(' ', '_', trim(strtolower($this->name)));
}
static public function generate_sql($name)
{
if (strpos($name, 'http') === 0) {
// $conds = array('artists.id IN (?)', self::where(['url' => $name])->pluck('id'));
// $sql = self::where('true');
if (!$ids = self::find_all_by_url($name)->getAttributes('id'))
$ids = [0];
$sql = self::where('artists.id IN (?)', $ids);
} else {
$sql = self::where(
"(artists.name LIKE ? OR a2.name LIKE ?)",
$name . "%",
$name . "%")
->joins('LEFT JOIN artists a2 ON artists.alias_id = a2.id');
}
return $sql;
}
}