mirror of
https://github.com/Pathduck/gallery3.git
synced 2026-08-22 06:46:05 -04:00
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.
This commit is contained in:
@@ -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)));
|
||||
|
||||
@@ -126,6 +126,7 @@ class tag_Core {
|
||||
->delete("items_tags")
|
||||
->where("item_id", "=", $item->id)
|
||||
->execute();
|
||||
module::event("item_related_update", $item);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+11
-15
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user