From dff1a536961cd401b8e133e260fcc3cca7c13dc6 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Mon, 25 Oct 2010 21:04:48 -0700 Subject: All modules should be named Xxx_Core for extensibility. Fixes #1458. --- modules/tag/models/tag.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'modules/tag') diff --git a/modules/tag/models/tag.php b/modules/tag/models/tag.php index 269a0f39..d6ad4dfd 100644 --- a/modules/tag/models/tag.php +++ b/modules/tag/models/tag.php @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Tag_Model extends ORM { +class Tag_Model_Core extends ORM { protected $has_and_belongs_to_many = array("items"); /** -- cgit v1.2.3 From 3d952f41c8d90b5c217616fb060697f93fb9db07 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Mon, 8 Nov 2010 22:16:57 -0800 Subject: Fix a bug in the way that we add tags that causes it to be really slow when adding a tag to lots of items. Tag_Model::save() would call item_related_update for every tag related to an item upon save which is an O(N!) operation. Fixes ticket #1412. --- modules/tag/controllers/admin_tags.php | 1 - modules/tag/helpers/tag.php | 1 + modules/tag/models/tag.php | 26 +++++++++++--------------- 3 files changed, 12 insertions(+), 16 deletions(-) (limited to 'modules/tag') diff --git a/modules/tag/controllers/admin_tags.php b/modules/tag/controllers/admin_tags.php index 0c82579b..99743a8e 100644 --- a/modules/tag/controllers/admin_tags.php +++ b/modules/tag/controllers/admin_tags.php @@ -52,7 +52,6 @@ class Admin_Tags_Controller extends Admin_Controller { $form = tag::get_delete_form($tag); if ($form->validate()) { $name = $tag->name; - db::build()->delete("items_tags")->where("tag_id", "=", $tag->id)->execute(); $tag->delete(); message::success(t("Deleted tag %tag_name", array("tag_name" => $name))); log::success("tags", t("Deleted tag %tag_name", array("tag_name" => $name))); diff --git a/modules/tag/helpers/tag.php b/modules/tag/helpers/tag.php index 14d27c94..79e74385 100644 --- a/modules/tag/helpers/tag.php +++ b/modules/tag/helpers/tag.php @@ -126,6 +126,7 @@ class tag_Core { ->delete("items_tags") ->where("item_id", "=", $item->id) ->execute(); + module::event("item_related_update", $item); } /** diff --git a/modules/tag/models/tag.php b/modules/tag/models/tag.php index d6ad4dfd..c038f6d1 100644 --- a/modules/tag/models/tag.php +++ b/modules/tag/models/tag.php @@ -57,8 +57,7 @@ class Tag_Model_Core extends ORM { /** * Overload ORM::save() to trigger an item_related_update event for all items that are related - * to this tag. Since items can be added or removed as part of the save, we need to trigger an - * event for the union of all related items before and after the save. + * to this tag. */ public function save() { $related_item_ids = array(); @@ -70,20 +69,16 @@ class Tag_Model_Core extends ORM { $related_item_ids[$row->item_id] = 1; } - $result = parent::save(); - - foreach (db::build() - ->select("item_id") - ->from("items_tags") - ->where("tag_id", "=", $this->id) - ->execute() as $row) { - $related_item_ids[$row->item_id] = 1; + if (isset($this->changed_relations["items"])) { + $changed = array_merge( + array_diff($this->changed_relations["items"], $this->object_relations["items"]), + array_diff($this->object_relations["items"], $this->changed_relations["items"])); } - if ($related_item_ids) { - foreach (ORM::factory("item") - ->where("id", "IN", array_keys($related_item_ids)) - ->find_all() as $item) { + $result = parent::save(); + + if (!empty($changed)) { + foreach (ORM::factory("item")->where("id", "IN", $changed)->find_all() as $item) { module::event("item_related_update", $item); } } @@ -93,7 +88,7 @@ class Tag_Model_Core extends ORM { /** * Overload ORM::delete() to trigger an item_related_update event for all items that are - * related to this tag. + * related to this tag, and delete all items_tags relationships. */ public function delete($ignored_id=null) { $related_item_ids = array(); @@ -105,6 +100,7 @@ class Tag_Model_Core extends ORM { $related_item_ids[$row->item_id] = 1; } + db::build()->delete("items_tags")->where("tag_id", "=", $this->id)->execute(); $result = parent::delete(); if ($related_item_ids) { -- cgit v1.2.3 From 7efa9a5b87eaa8fe86972376af8c58dc29c44392 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sun, 14 Nov 2010 15:01:29 -0800 Subject: Fix two issues with item deletion: 1) We're compacting tags on every deletion which is slow. Since we delete albums in batch, we should just do one tag compaction at the end. Fixes #1487. 2) Issue introduced in 3d952f41c8d90b5c217616fb060697f93fb9db07 where we trigger an item_related_update in tag::clear_all(). Since tag::clear_all() is called when we delete an item, this causes the search module to attempt to index a deleted item. Move that triggering upstream. --- modules/tag/helpers/tag.php | 1 - modules/tag/helpers/tag_event.php | 11 +++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'modules/tag') diff --git a/modules/tag/helpers/tag.php b/modules/tag/helpers/tag.php index 79e74385..14d27c94 100644 --- a/modules/tag/helpers/tag.php +++ b/modules/tag/helpers/tag.php @@ -126,7 +126,6 @@ class tag_Core { ->delete("items_tags") ->where("item_id", "=", $item->id) ->execute(); - module::event("item_related_update", $item); } /** diff --git a/modules/tag/helpers/tag_event.php b/modules/tag/helpers/tag_event.php index 0cc2170c..829089c4 100644 --- a/modules/tag/helpers/tag_event.php +++ b/modules/tag/helpers/tag_event.php @@ -62,6 +62,12 @@ class tag_event_Core { static function item_deleted($item) { tag::clear_all($item); + if (!batch::in_progress()) { + tag::compact(); + } + } + + static function batch_complete() { tag::compact(); } @@ -88,6 +94,7 @@ class tag_event_Core { tag::add($item, trim($tag_name)); } } + module::event("item_related_update", $item); tag::compact(); } @@ -109,7 +116,7 @@ class tag_event_Core { if (!isset($group->uploadify)) { return; } - + $group = $form->add_photos; $group->input("tags") ->label(t("Add tags to all uploaded files")) @@ -132,7 +139,7 @@ class tag_event_Core { if (!isset($group->uploadify)) { return; } - + foreach (explode(",", $form->add_photos->tags->value) as $tag_name) { $tag_name = trim($tag_name); if ($tag_name) { -- cgit v1.2.3 From d49a6dcc995d0c0073b3173d81cac7f3eb6ee30f Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sun, 14 Nov 2010 15:45:30 -0800 Subject: Create a new task to resync tag task counts and delete tags that have no associated items. --- modules/tag/helpers/tag_task.php | 97 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 modules/tag/helpers/tag_task.php (limited to 'modules/tag') diff --git a/modules/tag/helpers/tag_task.php b/modules/tag/helpers/tag_task.php new file mode 100644 index 00000000..087c85de --- /dev/null +++ b/modules/tag/helpers/tag_task.php @@ -0,0 +1,97 @@ +callback("tag_task::clean_up_tags") + ->name(t("Clean up tags")) + ->description(t("Correct tag counts and remove tags with no items")) + ->severity(log::SUCCESS); + return $tasks; + } + + /** + * Fix up tag counts and delete any tags that have no associated items. + * @param Task_Model the task + */ + static function clean_up_tags($task) { + $errors = array(); + try { + $start = microtime(true); + $last_tag_id = $task->get("last_tag_id", null); + $current = 0; + $total = 0; + + switch ($task->get("mode", "init")) { + case "init": + $task->set("total", ORM::factory("tag")->count_all()); + $task->set("mode", "clean_up_tags"); + $task->set("completed", 0); + $task->set("last_tag_id", 0); + + case "clean_up_tags": + $completed = $task->get("completed"); + $total = $task->get("total"); + $last_tag_id = $task->get("last_tag_id"); + $tags = ORM::factory("tag")->where("id", ">", $last_tag_id)->find_all(); + Kohana_Log::add("error",print_r(Database::instance()->last_query(),1)); + while ($current < $total && microtime(true) - $start < 1 && $tag = $tags->current()) { + $last_tag_id = $tag->id; + $real_count = $tag->items_count(); + if ($tag->count != $real_count) { + $tag->count = $real_count; + if ($tag->count) { + $task->log( + "Fixing count for tag {$tag->name} (id: {$tag->id}, new count: {$tag->count})"); + $tag->save(); + } else { + $task->log("Deleting empty tag {$tag->name} ({$tag->id})"); + $tag->delete(); + } + } + + $completed++; + $tags->next(); + } + $task->percent_complete = $completed / $total * 100; + $task->set("completed", $completed); + $task->set("last_tag_id", $last_tag_id); + } + + $task->status = t2("Examined %count tag", "Examined %count tags", $completed); + + if ($completed == $total) { + $task->done = true; + $task->state = "success"; + $task->percent_complete = 100; + } + } catch (Exception $e) { + Kohana_Log::add("error",(string)$e); + $task->done = true; + $task->state = "error"; + $task->status = $e->getMessage(); + $errors[] = (string)$e; + } + if ($errors) { + $task->log($errors); + } + } +} \ No newline at end of file -- cgit v1.2.3 From add586bbb129280badb484ae0fdaaa10372e4dc7 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sun, 14 Nov 2010 15:53:30 -0800 Subject: Create a task to clean up tag counts and delete tag with no associated items. Fixes #1488. --- modules/tag/helpers/tag_task.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'modules/tag') diff --git a/modules/tag/helpers/tag_task.php b/modules/tag/helpers/tag_task.php index 087c85de..7bf50546 100644 --- a/modules/tag/helpers/tag_task.php +++ b/modules/tag/helpers/tag_task.php @@ -51,7 +51,7 @@ class tag_task_Core { $completed = $task->get("completed"); $total = $task->get("total"); $last_tag_id = $task->get("last_tag_id"); - $tags = ORM::factory("tag")->where("id", ">", $last_tag_id)->find_all(); + $tags = ORM::factory("tag")->where("id", ">", $last_tag_id)->find_all(25); Kohana_Log::add("error",print_r(Database::instance()->last_query(),1)); while ($current < $total && microtime(true) - $start < 1 && $tag = $tags->current()) { $last_tag_id = $tag->id; -- cgit v1.2.3