summaryrefslogtreecommitdiff
path: root/modules/tag
diff options
context:
space:
mode:
Diffstat (limited to 'modules/tag')
-rw-r--r--modules/tag/controllers/admin_tags.php31
-rw-r--r--modules/tag/controllers/tag.php62
-rw-r--r--modules/tag/controllers/tags.php3
-rw-r--r--modules/tag/helpers/tag.php20
-rw-r--r--modules/tag/helpers/tag_block.php2
-rw-r--r--modules/tag/helpers/tag_event.php14
-rw-r--r--modules/tag/helpers/tag_installer.php7
-rw-r--r--modules/tag/helpers/tag_item_rest.php1
-rw-r--r--modules/tag/helpers/tag_items_rest.php1
-rw-r--r--modules/tag/models/tag.php64
-rw-r--r--modules/tag/module.info6
-rw-r--r--modules/tag/tests/Tag_Test.php50
12 files changed, 200 insertions, 61 deletions
diff --git a/modules/tag/controllers/admin_tags.php b/modules/tag/controllers/admin_tags.php
index 73042a55..77b5f20a 100644
--- a/modules/tag/controllers/admin_tags.php
+++ b/modules/tag/controllers/admin_tags.php
@@ -81,17 +81,25 @@ class Admin_Tags_Controller extends Admin_Controller {
$in_place_edit = InPlaceEdit::factory($tag->name)
->action("admin/tags/rename/$tag->id")
- ->rules(array("required", "length[1,64]"))
- ->messages(array("in_use" => t("There is already a tag with that name")))
- ->callback(array($this, "check_for_duplicate"));
+ ->rules(array("required", "length[1,64]"));
if ($in_place_edit->validate()) {
$old_name = $tag->name;
- $tag->name = $in_place_edit->value();
+ $new_name_or_list = $in_place_edit->value();
+ $tag_list = explode(",", $new_name_or_list);
+
+ $tag->name = array_shift($tag_list);
$tag->save();
- $message = t("Renamed tag <b>%old_name</b> to <b>%new_name</b>",
- array("old_name" => $old_name, "new_name" => $tag->name));
+ if (!empty($tag_list)) {
+ $this->_copy_items_for_tags($tag, $tag_list);
+ $message = t("Split tag <i>%old_name</i> into <i>%tag_list</i>",
+ array("old_name" => $old_name, "tag_list" => $new_name_or_list));
+ } else {
+ $message = t("Renamed tag <i>%old_name</i> to <i>%new_name</i>",
+ array("old_name" => $old_name, "new_name" => $tag->name));
+ }
+
message::success($message);
log::success("tags", $message);
@@ -101,12 +109,11 @@ class Admin_Tags_Controller extends Admin_Controller {
}
}
- public function check_for_duplicate(Validation $post_data, $field) {
- $tag_exists = ORM::factory("tag")->where("name", "=", $post_data[$field])->count_all();
- if ($tag_exists) {
- $post_data->add_error($field, "in_use");
+ private function _copy_items_for_tags($tag, $tag_list) {
+ foreach ($tag->items() as $item) {
+ foreach ($tag_list as $new_tag_name) {
+ tag::add($item, trim($new_tag_name));
+ }
}
}
-
}
-
diff --git a/modules/tag/controllers/tag.php b/modules/tag/controllers/tag.php
index 8f885dea..559e2a5a 100644
--- a/modules/tag/controllers/tag.php
+++ b/modules/tag/controllers/tag.php
@@ -22,7 +22,22 @@ class Tag_Controller extends Controller {
$tag_id = $function;
$tag = ORM::factory("tag")->where("id", "=", $tag_id)->find();
$page_size = module::get_var("gallery", "page_size", 9);
- $page = (int) Input::instance()->get("page", "1");
+
+ $input = Input::instance();
+ $show = $input->get("show");
+
+ if ($show) {
+ $child = ORM::factory("item", $show);
+ $index = tag::get_position($tag, $child);
+ if ($index) {
+ $page = ceil($index / $page_size);
+ $uri = "tag/$tag_id/" . urlencode($tag->name);
+ url::redirect($uri . ($page == 1 ? "" : "?page=$page"));
+ }
+ } else {
+ $page = (int) $input->get("page", "1");
+ }
+
$children_count = $tag->items_count();
$offset = ($page-1) * $page_size;
$max_pages = max(ceil($children_count / $page_size), 1);
@@ -34,16 +49,47 @@ class Tag_Controller extends Controller {
url::redirect(url::merge(array("page" => $max_pages)));
}
+ $root = item::root();
$template = new Theme_View("page.html", "collection", "tag");
- $template->set_global(array("page" => $page,
- "max_pages" => $max_pages,
- "page_size" => $page_size,
- "tag" => $tag,
- "children" => $tag->items($page_size, $offset),
- "children_count" => $children_count));
+ $template->set_global(
+ array("page" => $page,
+ "max_pages" => $max_pages,
+ "page_size" => $page_size,
+ "tag" => $tag,
+ "children" => $tag->items($page_size, $offset),
+ "breadcrumbs" => array(
+ Breadcrumb::instance($root->title, $root->url())->set_first(),
+ Breadcrumb::instance(t("Tag: %tag_name", array("tag_name" => $tag->name)),
+ $tag->url())->set_last()),
+ "children_count" => $children_count));
$template->content = new View("dynamic.html");
$template->content->title = t("Tag: %tag_name", array("tag_name" => $tag->name));
-
print $template;
+
+ item::set_display_context_callback("Tag_Controller::get_display_context", $tag->id);
+ }
+
+ static function get_display_context($item, $tag_id) {
+ $tag = ORM::factory("tag", $tag_id);
+ $where = array(array("type", "!=", "album"));
+
+ $position = tag::get_position($tag, $item, $where);
+ if ($position > 1) {
+ list ($previous_item, $ignore, $next_item) = $tag->items(3, $position - 2, $where);
+ } else {
+ $previous_item = null;
+ list ($next_item) = $tag->items(1, $position, $where);
+ }
+
+ $root = item::root();
+ return array("position" => $position,
+ "previous_item" => $previous_item,
+ "next_item" => $next_item,
+ "sibling_count" => $tag->items_count($where),
+ "breadcrumbs" => array(
+ Breadcrumb::instance($root->title, $root->url())->set_first(),
+ Breadcrumb::instance(t("Tag: %tag_name", array("tag_name" => $tag->name)),
+ $tag->url("show={$item->id}")),
+ Breadcrumb::instance($item->title, $item->url())->set_last()));
}
}
diff --git a/modules/tag/controllers/tags.php b/modules/tag/controllers/tags.php
index fe6d747b..bf41c4df 100644
--- a/modules/tag/controllers/tags.php
+++ b/modules/tag/controllers/tags.php
@@ -22,7 +22,8 @@ class Tags_Controller extends Controller {
// Far from perfection, but at least require view permission for the root album
$album = ORM::factory("item", 1);
access::required("view", $album);
- print tag::cloud(30);
+
+ print tag::cloud(module::get_var("tag", "tag_cloud_size", 30));
}
public function create($item_id) {
diff --git a/modules/tag/helpers/tag.php b/modules/tag/helpers/tag.php
index 733215b3..83a00080 100644
--- a/modules/tag/helpers/tag.php
+++ b/modules/tag/helpers/tag.php
@@ -48,6 +48,7 @@ class tag_Core {
* @return ORM_Iterator of Tag_Model in descending tag count order
*/
static function popular_tags($count) {
+ $count = max($count, 1);
return ORM::factory("tag")
->order_by("count", "DESC")
->limit($count)
@@ -135,4 +136,23 @@ class tag_Core {
// extremely rare case.
db::build()->delete("tags")->where("count", "=", 0)->execute();
}
+
+ /**
+ * Find the position of the given item in the tag collection. The resulting
+ * value is 1-indexed, so the first child in the album is at position 1.
+ *
+ * @param Tag_Model $tag
+ * @param Item_Model $item
+ * @param array $where an array of arrays, each compatible with ORM::where()
+ */
+ static function get_position($tag, $item, $where=array()) {
+ return ORM::factory("item")
+ ->viewable()
+ ->join("items_tags", "items.id", "items_tags.item_id")
+ ->where("items_tags.tag_id", "=", $tag->id)
+ ->where("items.id", "<=", $item->id)
+ ->merge_where($where)
+ ->order_by("items.id")
+ ->count_all();
+ }
} \ No newline at end of file
diff --git a/modules/tag/helpers/tag_block.php b/modules/tag/helpers/tag_block.php
index 8df58a6e..69a9a1c4 100644
--- a/modules/tag/helpers/tag_block.php
+++ b/modules/tag/helpers/tag_block.php
@@ -30,7 +30,7 @@ class tag_block_Core {
$block->css_id = "g-tag";
$block->title = t("Popular tags");
$block->content = new View("tag_block.html");
- $block->content->cloud = tag::cloud(30);
+ $block->content->cloud = tag::cloud(module::get_var("tag", "tag_cloud_size", 30));
if ($theme->item() && $theme->page_subtype() != "tag" && access::can("edit", $theme->item())) {
$controller = new Tags_Controller();
diff --git a/modules/tag/helpers/tag_event.php b/modules/tag/helpers/tag_event.php
index cd79f734..b415b42d 100644
--- a/modules/tag/helpers/tag_event.php
+++ b/modules/tag/helpers/tag_event.php
@@ -36,10 +36,7 @@ class tag_event_Core {
$tag = str_replace("\0", "", $tag);
foreach (explode(",", $tag) as $word) {
$word = trim($word);
- if (function_exists("mb_detect_encoding") &&
- mb_detect_encoding($word, "ISO-8859-1, UTF-8") != "UTF-8") {
- $word = utf8_encode($word);
- }
+ $word = encoding::convert_to_utf8($word);
$tags[$word] = 1;
}
}
@@ -113,11 +110,11 @@ class tag_event_Core {
}
static function add_photos_form($album, $form) {
- if (!isset($group->uploadify)) {
+ $group = $form->add_photos;
+ if (!is_object($group->uploadify)) {
return;
}
- $group = $form->add_photos;
$group->input("tags")
->label(t("Add tags to all uploaded files"))
->value("");
@@ -136,7 +133,8 @@ class tag_event_Core {
}
static function add_photos_form_completed($album, $form) {
- if (!isset($group->uploadify)) {
+ $group = $form->add_photos;
+ if (!is_object($group->uploadify)) {
return;
}
@@ -151,7 +149,7 @@ class tag_event_Core {
static function info_block_get_metadata($block, $item) {
$tags = array();
foreach (tag::item_tags($item) as $tag) {
- $tags[] = "<a href=\"" . url::site("tag/{$tag->name}") . "\">{$tag->name}</a>";
+ $tags[] = "<a href=\"{$tag->url()}\">{$tag->name}</a>";
}
if ($tags) {
$info = $block->content->metadata;
diff --git a/modules/tag/helpers/tag_installer.php b/modules/tag/helpers/tag_installer.php
index 16ad1239..66a78b91 100644
--- a/modules/tag/helpers/tag_installer.php
+++ b/modules/tag/helpers/tag_installer.php
@@ -36,7 +36,8 @@ class tag_installer {
KEY(`tag_id`, `id`),
KEY(`item_id`, `id`))
DEFAULT CHARSET=utf8;");
- module::set_version("tag", 2);
+ module::set_var("tag", "tag_cloud_size", 30);
+ module::set_version("tag", 3);
}
static function upgrade($version) {
@@ -45,6 +46,10 @@ class tag_installer {
$db->query("ALTER TABLE {tags} MODIFY COLUMN `name` VARCHAR(128)");
module::set_version("tag", $version = 2);
}
+ if ($version == 2) {
+ module::set_var("tag", "tag_cloud_size", 30);
+ module::set_version("tag", $version = 3);
+ }
}
static function uninstall() {
diff --git a/modules/tag/helpers/tag_item_rest.php b/modules/tag/helpers/tag_item_rest.php
index a8d3d0bc..be1fa653 100644
--- a/modules/tag/helpers/tag_item_rest.php
+++ b/modules/tag/helpers/tag_item_rest.php
@@ -29,6 +29,7 @@ class tag_item_rest_Core {
static function delete($request) {
list ($tag, $item) = rest::resolve($request->url);
+ access::required("edit", $item);
$tag->remove($item);
$tag->save();
}
diff --git a/modules/tag/helpers/tag_items_rest.php b/modules/tag/helpers/tag_items_rest.php
index 535ab513..8ed07276 100644
--- a/modules/tag/helpers/tag_items_rest.php
+++ b/modules/tag/helpers/tag_items_rest.php
@@ -51,6 +51,7 @@ class tag_items_rest_Core {
static function delete($request) {
list ($tag, $item) = rest::resolve($request->url);
+ access::required("edit", $item);
$tag->remove($item);
$tag->save();
}
diff --git a/modules/tag/models/tag.php b/modules/tag/models/tag.php
index 479a7da0..a7150df8 100644
--- a/modules/tag/models/tag.php
+++ b/modules/tag/models/tag.php
@@ -33,35 +33,39 @@ class Tag_Model_Core extends ORM {
* Return all viewable items associated with this tag.
* @param integer $limit number of rows to limit result to
* @param integer $offset offset in result to start returning rows from
- * @param string $type the type of item (album, photo)
+ * @param string $where an array of arrays, each compatible with ORM::where()
* @return ORM_Iterator
*/
- public function items($limit=null, $offset=null, $type=null) {
- $model = ORM::factory("item")
+ public function items($limit=null, $offset=null, $where=array()) {
+ if (is_scalar($where)) {
+ // backwards compatibility
+ $where = array(array("items.type", "=", $where));
+ }
+ return ORM::factory("item")
->viewable()
->join("items_tags", "items.id", "items_tags.item_id")
- ->where("items_tags.tag_id", "=", $this->id);
- if ($type) {
- $model->where("items.type", "=", $type);
- }
- return $model->find_all($limit, $offset);
+ ->where("items_tags.tag_id", "=", $this->id)
+ ->merge_where($where)
+ ->order_by("items.id")
+ ->find_all($limit, $offset);
}
/**
* Return the count of all viewable items associated with this tag.
- * @param string $type the type of item (album, photo)
+ * @param string $where an array of arrays, each compatible with ORM::where()
* @return integer
*/
- public function items_count($type=null) {
- $model = ORM::factory("item")
+ public function items_count($where=array()) {
+ if (is_scalar($where)) {
+ // backwards compatibility
+ $where = array(array("items.type", "=", $where));
+ }
+ return $model = ORM::factory("item")
->viewable()
->join("items_tags", "items.id", "items_tags.item_id")
- ->where("items_tags.tag_id", "=", $this->id);
-
- if ($type) {
- $model->where("items.type", "=", $type);
- }
- return $model->count_all();
+ ->where("items_tags.tag_id", "=", $this->id)
+ ->merge_where($where)
+ ->count_all();
}
/**
@@ -69,13 +73,23 @@ class Tag_Model_Core extends ORM {
* to this tag.
*/
public function save() {
- $related_item_ids = array();
- foreach (db::build()
- ->select("item_id")
- ->from("items_tags")
- ->where("tag_id", "=", $this->id)
- ->execute() as $row) {
- $related_item_ids[$row->item_id] = 1;
+ // Check to see if another tag exists with the same name
+ $duplicate_tag = ORM::factory("tag")
+ ->where("name", "=", $this->name)
+ ->where("id", "!=", $this->id)
+ ->find();
+ if ($duplicate_tag->loaded()) {
+ // If so, tag its items with this tag so as to merge it
+ $duplicate_tag_items = ORM::factory("item")
+ ->join("items_tags", "items.id", "items_tags.item_id")
+ ->where("items_tags.tag_id", "=", $duplicate_tag->id)
+ ->find_all();
+ foreach ($duplicate_tag_items as $item) {
+ $this->add($item);
+ }
+
+ // ... and remove the duplicate tag
+ $duplicate_tag->delete();
}
if (isset($this->object_relations["items"])) {
@@ -132,7 +146,7 @@ class Tag_Model_Core extends ORM {
* @param string $query the query string (eg "page=3")
*/
public function url($query=null) {
- $url = url::site("tag/{$this->id}/{$this->name}");
+ $url = url::site("tag/{$this->id}/" . urlencode($this->name));
if ($query) {
$url .= "?$query";
}
diff --git a/modules/tag/module.info b/modules/tag/module.info
index 8851d119..75d16bf0 100644
--- a/modules/tag/module.info
+++ b/modules/tag/module.info
@@ -1,3 +1,7 @@
name = "Tags"
description = "Allows users to tag photos and albums"
-version = 2
+version = 3
+author_name = "Gallery Team"
+author_url = "http://codex.gallery2.org/Gallery:Team"
+info_url = "http://codex.gallery2.org/Gallery3:Modules:tag"
+discuss_url = "http://gallery.menalto.com/forum_module_tag"
diff --git a/modules/tag/tests/Tag_Test.php b/modules/tag/tests/Tag_Test.php
index f5ccb3a2..52fd4fdd 100644
--- a/modules/tag/tests/Tag_Test.php
+++ b/modules/tag/tests/Tag_Test.php
@@ -18,18 +18,60 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class Tag_Test extends Gallery_Unit_Test_Case {
+ public function setup() {
+ ORM::factory("tag")->delete_all();
+ }
+
public function create_tag_test() {
$album = test::random_album();
tag::add($album, "tag1");
$tag = ORM::factory("tag")->where("name", "=", "tag1")->find();
- $this->assert_true(1, $tag->count);
+ $this->assert_equal(1, $tag->count);
// Make sure adding the tag again doesn't increase the count
tag::add($album, "tag1");
- $this->assert_true(1, $tag->reload()->count);
+ $this->assert_equal(1, $tag->reload()->count);
tag::add(test::random_album(), "tag1");
- $this->assert_true(2, $tag->reload()->count);
+ $this->assert_equal(2, $tag->reload()->count);
+ }
+
+ public function rename_merge_tag_test() {
+ $album1 = test::random_album();
+ $album2 = test::random_album();
+
+ tag::add($album1, "tag1");
+ tag::add($album2, "tag2");
+
+ $tag1 = ORM::factory("tag")->where("name", "=", "tag1")->find();
+ $tag1->name = "tag2";
+ $tag1->save();
+
+ // Tags should be merged; $tag2 should be deleted
+ $tag1->reload();
+
+ $this->assert_equal(2, $tag1->count);
+ $this->assert_true($tag1->has($album1));
+ $this->assert_true($tag1->has($album2));
+ $this->assert_equal(1, ORM::factory("tag")->count_all());
+ }
+
+ public function rename_merge_tag_with_same_items_test() {
+ $album = test::random_album();
+
+ tag::add($album, "tag1");
+ tag::add($album, "tag2");
+
+ $tag1 = ORM::factory("tag")->where("name", "=", "tag1")->find();
+ $tag1->name = "tag2";
+ $tag1->save();
+
+ // Tags should be merged
+ $tag1->reload();
+
+ $this->assert_equal(1, $tag1->count);
+ $this->assert_true($tag1->has($album));
+ $this->assert_equal(1, ORM::factory("tag")->count_all());
}
-} \ No newline at end of file
+}