diff --git a/core/imageboard.pack.php b/core/imageboard.pack.php index dc92b145..e27bc7a0 100644 --- a/core/imageboard.pack.php +++ b/core/imageboard.pack.php @@ -576,9 +576,6 @@ class Image { assert('is_array($tags) && count($tags) > 0', var_export($tags, true)); global $database; - $tags = array_map(array('Tag', 'sanitise'), $tags); - $tags = Tag::resolve_aliases($tags); - if(count($tags) <= 0) { throw new SCoreException('Tried to set zero tags'); } @@ -588,12 +585,6 @@ class Image { $this->delete_tags_from_image(); // insert each new tags foreach($tags as $tag) { - $ttpe = new TagTermParseEvent($tag, $this->id); - send_event($ttpe); - if($ttpe->is_metatag()) { - continue; - } - if(mb_strlen($tag, 'UTF-8') > 255){ flash_message("The tag below is longer than 255 characters, please use a shorter tag.\n$tag\n"); continue; @@ -632,6 +623,19 @@ class Image { } } + /** + * Send list of metatags to be parsed. + * + * @param [] $metatags + * @param int $image_id + */ + public function parse_metatags($metatags, $image_id) { + foreach($metatags as $tag) { + $ttpe = new TagTermParseEvent($tag, $image_id, TRUE); + send_event($ttpe); + } + } + /** * Delete this image from the database and disk */ @@ -1156,6 +1160,8 @@ class Tag { $tag_array = array("tagme"); } + $tag_array = array_iunique($tag_array); //remove duplicate tags + sort($tag_array); return $tag_array; @@ -1254,7 +1260,7 @@ class Tag { $i = 0; $tag_count = count($tags); while($i<$tag_count) { - $aliases = explode(' ', Tag::resolve_alias($tags[$i])); + $aliases = Tag::explode(Tag::resolve_alias($tags[$i]), FALSE); foreach($aliases as $alias){ if(!in_array($alias, $new)){ if($tags[$i] == $alias){ diff --git a/ext/numeric_score/main.php b/ext/numeric_score/main.php index 8cb65a7b..9286e7e2 100644 --- a/ext/numeric_score/main.php +++ b/ext/numeric_score/main.php @@ -247,9 +247,9 @@ class NumericScore extends Extension { "images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=:ns_user_id AND score=-1)", array("ns_user_id"=>$iid))); } - else if(preg_match("/^order[=|:](numeric_)?(score)[_]?(desc|asc)?$/i", $event->term, $matches)){ + else if(preg_match("/^order[=|:](?:numeric_)?(score)(?:_(desc|asc))?$/i", $event->term, $matches)){ $default_order_for_column = "DESC"; - $sort = isset($matches[3]) ? strtoupper($matches[3]) : $default_order_for_column; + $sort = isset($matches[2]) ? strtoupper($matches[2]) : $default_order_for_column; Image::$order_sql = "images.numeric_score $sort"; $event->add_querylet(new Querylet("1=1")); //small hack to avoid metatag being treated as normal tag } @@ -258,7 +258,7 @@ class NumericScore extends Extension { public function onTagTermParse(TagTermParseEvent $event) { $matches = array(); - if(preg_match("/^vote[=|:](up|down|remove)$/", $event->term, $matches)) { + if(preg_match("/^vote[=|:](up|down|remove)$/", $event->term, $matches) && $event->parse) { global $user; $score = ($matches[1] == "up" ? 1 : ($matches[1] == "down" ? -1 : 0)); if(!$user->is_anonymous()) { diff --git a/ext/relatationships/main.php b/ext/relatationships/main.php index 6cd1a7b0..8ecc6991 100644 --- a/ext/relatationships/main.php +++ b/ext/relatationships/main.php @@ -58,7 +58,7 @@ class Relationships extends Extension { public function onTagTermParse(TagTermParseEvent $event) { $matches = array(); - if(preg_match("/^parent[=|:]([0-9]+|none)$/", $event->term, $matches)) { + if(preg_match("/^parent[=|:]([0-9]+|none)$/", $event->term, $matches) && $event->parse) { $parentID = $matches[1]; if($parentID == "none" || $parentID == "0"){ @@ -67,7 +67,7 @@ class Relationships extends Extension { $this->set_parent($event->id, $parentID); } } - else if(preg_match("/^child[=|:]([0-9]+)$/", $event->term, $matches)) { + else if(preg_match("/^child[=|:]([0-9]+)$/", $event->term, $matches) && $event->parse) { $childID = $matches[1]; $this->set_child($event->id, $childID); diff --git a/ext/tag_edit/main.php b/ext/tag_edit/main.php index 1dfa025e..12be5ab7 100644 --- a/ext/tag_edit/main.php +++ b/ext/tag_edit/main.php @@ -95,11 +95,38 @@ class SourceSetEvent extends Event { class TagSetEvent extends Event { /** @var \Image */ public $image; - var $tags; + public $tags; + public $metatags; public function __construct(Image $image, $tags) { - $this->image = $image; - $this->tags = Tag::explode($tags); + $this->image = $image; + + $this->tags = array(); + $this->metatags = array(); + + //tags need to be sanitised, alias checked & have metatags removed before being passed to onTagSet + $tag_array = Tag::explode($tags); + $tag_array = array_map(array('Tag', 'sanitise'), $tag_array); + $tag_array = Tag::resolve_aliases($tag_array); + + foreach($tag_array as $tag) { + if((strpos($tag, ':') === FALSE) && (strpos($tag, '=') === FALSE)) { + //Tag doesn't contain : or =, meaning it can't possibly be a metatag. + //This should help speed wise, as it avoids running every single tag through a bunch of preg_match instead. + array_push($this->tags, $tag); + continue; + } + + $ttpe = new TagTermParseEvent($tag, $this->image->id, FALSE); //Only check for metatags, don't parse. Parsing is done after set_tags. + send_event($ttpe); + + //seperate tags from metatags + if(!$ttpe->is_metatag()) { + array_push($this->tags, $tag); + }else{ + array_push($this->metatags, $tag); + } + } } } @@ -131,14 +158,17 @@ class LockSetEvent extends Event { * Signal that a tag term needs parsing */ class TagTermParseEvent extends Event { - var $term = null; - var $id = null; + public $term = NULL; //tag + public $id = NULL; //image_id /** @var bool */ - public $metatag = false; + public $metatag = FALSE; + /** @var bool */ + public $parse = TRUE; //marks the tag to be parsed, and not just checked if valid metatag - public function __construct($term, $id) { - $this->term = $term; - $this->id = $id; + public function __construct($term, $id, $parse) { + $this->term = $term; + $this->id = $id; + $this->parse = $parse; } /** @@ -215,6 +245,7 @@ class TagEdit extends Extension { if($user->can("edit_image_tag") && (!$event->image->is_locked() || $user->can("edit_image_lock"))) { $event->image->set_tags($event->tags); } + $event->image->parse_metatags($event->metatags, $event->image->id); } public function onSourceSet(SourceSetEvent $event) { @@ -257,7 +288,7 @@ class TagEdit extends Extension { public function onTagTermParse(TagTermParseEvent $event) { $matches = array(); - if(preg_match("/^source[=|:](.*)$/i", $event->term, $matches)) { + if(preg_match("/^source[=|:](.*)$/i", $event->term, $matches) && $event->parse) { $source = ($matches[1] !== "none" ? $matches[1] : null); send_event(new SourceSetEvent(Image::by_id($event->id), $source)); } diff --git a/ext/user/main.php b/ext/user/main.php index 19f87ca7..32d31eaa 100644 --- a/ext/user/main.php +++ b/ext/user/main.php @@ -313,8 +313,8 @@ class UserPage extends Extension { global $user; $matches = array(); - if(preg_match("/^(poster|user)[=|:](.*)$/i", $event->term, $matches)) { - $duser = User::by_name($matches[2]); + if(preg_match("/^(?:poster|user)[=|:](.*)$/i", $event->term, $matches)) { + $duser = User::by_name($matches[1]); if(!is_null($duser)) { $user_id = $duser->id; } @@ -323,12 +323,12 @@ class UserPage extends Extension { } $event->add_querylet(new Querylet("images.owner_id = $user_id")); } - else if(preg_match("/^(poster|user)_id[=|:]([0-9]+)$/i", $event->term, $matches)) { - $user_id = int_escape($matches[2]); + else if(preg_match("/^(?:poster|user)_id[=|:]([0-9]+)$/i", $event->term, $matches)) { + $user_id = int_escape($matches[1]); $event->add_querylet(new Querylet("images.owner_id = $user_id")); } - else if($user->can("view_ip") && preg_match("/^(poster|user)_ip[=|:]([0-9\.]+)$/i", $event->term, $matches)) { - $user_ip = $matches[2]; // FIXME: ip_escape? + else if($user->can("view_ip") && preg_match("/^(?:poster|user)_ip[=|:]([0-9\.]+)$/i", $event->term, $matches)) { + $user_ip = $matches[1]; // FIXME: ip_escape? $event->add_querylet(new Querylet("images.owner_ip = '$user_ip'")); } }