Sequenzia/app/models/TagAlias.php
2014-06-06 02:29:01 -05:00

143 lines
4.5 KiB
PHP
Executable File

<?php
class TagAlias extends Rails\ActiveRecord\Base
{
static public function tableName()
{
return 'tag_aliases';
}
protected $alias_name;
protected function callbacks()
{
return array(
'before_create' => array(
'normalize',
'validate_uniqueness',
'validate_tag',
'validate_alias'
),
'after_destroy' => [
'expire_tag_cache_after_deletion'
]
);
}
static public function to_aliased($tags)
{
!is_array($tags) && $tags = array($tags);
$aliased_tags = array();
foreach ($tags as $tag_name)
$aliased_tags[] = self::to_aliased_helper($tag_name);
return $aliased_tags;
}
static public function to_aliased_helper($tag_name)
{
# TODO: add memcached support
$tag = self::where("tag_aliases.name = ? AND tag_aliases.is_pending = FALSE", $tag_name)
->select("tags.name AS name")
->joins("JOIN tags ON tags.id = tag_aliases.alias_id")
->first();
return $tag ? $tag->name : $tag_name;
}
# Strips out any illegal characters and makes sure the name is lowercase.
public function normalize()
{
$this->name = trim(str_replace(' ', '_', strtolower($this->name)), '-~');
}
# Makes sure the alias does not conflict with any other aliases.
public function validate_uniqueness()
{
if (self::where("name = ?", $this->name)->exists()) {
$this->errors()->addToBase("{$this->name} is already aliased to something");
return false;
}
if (self::where("alias_id = (select id from tags where name = ?)", $this->name)->exists()) {
$this->errors()->addToBase($this->name . " is already aliased to something");
return false;
}
if (self::where("name = ?", $this->alias_name())->exists()) {
$this->errors()->addToBase($this->alias_name() . " is already aliased to something");
return false;
}
}
protected function validate_tag()
{
if (!Tag::where(['name' => $this->name])->first()) {
$this->errors()->add('tag', "couldn't be created");
return false;
}
}
protected function validate_alias()
{
if (!$this->alias_id) {
$this->errors()->add('alias', "couldn't be created");
return false;
}
}
public function setAlias($name)
{
$tag = Tag::find_or_create_by_name($this->name);
$alias_tag = Tag::find_or_create_by_name($name);
if ($tag->tag_type != $alias_tag->tag_type)
$tag->updateAttribute('tag_type', $alias_tag->tag_type);
$this->alias_id = $alias_tag->id;
}
public function alias_name()
{
if ($this->alias_name === null) {
$this->alias_name = Tag::find($this->alias_id)->name;
}
return $this->alias_name;
}
public function alias_tag()
{
return Tag::find_or_create_by_name($this->name);
}
# Destroys the alias and sends a message to the alias's creator.
#TODO:
public function destroy_and_notify($current_user, $reason)
{
if ($this->creator_id && $this->creator_id != $current_user->id) {
$msg = "A tag alias you submitted (".$this->name." &rarr; " . $this->alias_name() . ") was deleted for the following reason: ".$reason;
Dmail::create(array('from_id' => current_user()->id, 'to_id' => $this->creator_id, 'title' => "One of your tag aliases was deleted", 'body' => $msg));
}
$this->destroy();
}
public function approve($user_id, $ip_addr)
{
self::connection()->executeSql("UPDATE tag_aliases SET is_pending = FALSE WHERE id = ?", $this->id);
Post::select('posts.*')
->joins('JOIN posts_tags pt ON posts.id = pt.post_id JOIN tags ON pt.tag_id = tags.id')
->where("tags.name LIKE ?", $this->name)
->take()->each(function($post) use ($user_id, $ip_addr) {
$post->reload();
$post->updateAttributes(['tags' => $post->cached_tags, 'updater_user_id' => $user_id, 'updater_ip_addr' => $ip_addr]);
});
Moebooru\CacheHelper::expire_tag_version();
}
public function expire_tag_cache_after_deletion()
{
Moebooru\CacheHelper::expire_tag_version();
}
}