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; } }