diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/tag/controllers/tags.php | 116 | ||||
-rw-r--r-- | modules/tag/helpers/tag.php | 25 | ||||
-rw-r--r-- | modules/tag/helpers/tag_event.php | 5 |
3 files changed, 145 insertions, 1 deletions
diff --git a/modules/tag/controllers/tags.php b/modules/tag/controllers/tags.php index 9090e51d..5e42526d 100644 --- a/modules/tag/controllers/tags.php +++ b/modules/tag/controllers/tags.php @@ -76,4 +76,120 @@ class Tags_Controller extends REST_Controller { return tag::get_add_form($item); } + + public function organize() { + access::verify_csrf(); + + $itemids = explode("|", Input::instance()->post("item")); + $form = tag::get_organize_form($itemids); + $old_tags = $form->tags->value; + if ($form->validate()) { + + $old_tags = preg_split("/[;,\s]+/", $old_tags); + sort($old_tags); + $new_tags = preg_split("/[;,\s]+/", $form->tags->value); + sort($new_tags); + + $HIGH_VALUE_STRING = "\256"; + for ($old_index = $new_index = 0;;) { + $old_tag = $old_index >= count($old_tags) ? $HIGH_VALUE_STRING : $old_tags[$old_index]; + $new_tag = $new_index >= count($new_tags) ? $HIGH_VALUE_STRING : $new_tags[$new_index]; + if ($old_tag == $HIGH_VALUE_STRING && $new_tag == $HIGH_VALUE_STRING) { + break; + } + $matches = array(); + $old_star = false; + if (preg_match("/(.*)(\*)$/", $old_tag, $matches)) { + $old_star = true; + $old_tag = $matches[1]; + } + $new_star = false; + if (preg_match("/(.*)(\*)$/", $new_tag, $matches)) { + $new_star = true; + $new_tag = $matches[1]; + } + if ($old_tag > $new_tag) { + // Its missing in the old list so add it + $this->_add_tag($new_tag, $itemids); + $new_index++; + } else if ($old_tag < $new_tag) { + // Its missing in the new list so its been removed + $this->_delete_tag($old_tag, $itemids); + $old_index++; + } else { + if ($old_star && !$new_star) { + // User wants tag to apply to all items, originally only on some of selected + $this->_update_tag($old_tag, $itemids); + } // Not changed ignore + $old_index++; + $new_index++; + } + } + } + print json_encode(array("form" => $form->__toString(), "message" => t("Tags updated"))); + } + + public function reset_organize() { + $itemids = Input::instance()->get("item"); + + print tag::get_organize_form($itemids); + } + + private function _add_tag($new_tag, $itemids) { + $tag = ORM::factory("tag") + ->where("name", $new_tag) + ->find(); + if ($tag->loaded) { + $tag->count += count($itemids); + } else { + $tag->name = $new_tag; + $tag->count = count($itemids); + } + $tag->save(); + + $db = Database::instance(); + foreach ($itemids as $item_id) { + $db->query("INSERT INTO {items_tags} SET item_id = $item_id, tag_id = {$tag->id};"); + } + } + + private function _delete_tag($new_tag, $itemids) { + $tag = ORM::factory("tag") + ->where("name", $new_tag) + ->find(); + $tag->count -= count($itemids); + if ($tag->count > 0) { + $tag->save(); + } else { + $tag->delete(); + } + + $ids = implode(", ", $itemids); + Database::instance()->query( + "DELETE FROM {items_tags} WHERE tag_id = {$tag->id} AND item_id IN ($ids);"); + } + + private function _update_tag($new_tag, $itemids) { + $tag = ORM::factory("tag") + ->where("name", $new_tag) + ->find(); + + $db = Database::instance(); + $ids = implode(", ", $itemids); + $result = $db->query( + "SELECT item_id FROM {items_tags} + WHERE tag_id = {$tag->id} + AND item_id IN ($ids)"); + + $add_items = array_fill_keys($itemids, 1); + foreach($result as $row) { + unset($add_items[$row->item_id]); + } + $add_items = array_keys($add_items); + $tag->count += count($add_items); + $tag->save(); + foreach ($add_items as $item_id) { + $db->query("INSERT INTO {items_tags} SET item_id = $item_id, tag_id = {$tag->id};"); + } + } } diff --git a/modules/tag/helpers/tag.php b/modules/tag/helpers/tag.php index ba67fbbd..50c4b41a 100644 --- a/modules/tag/helpers/tag.php +++ b/modules/tag/helpers/tag.php @@ -104,4 +104,27 @@ class tag_Core { $group->submit("")->value(t("Delete Tag")); return $form; } -} + + static function get_organize_form($itemids) { + $tagPane = new Forge("tags/__FUNCTION__", "", "post", + array("id" => "gEditTags", "ref" => "organize")); + $tagPane->hidden("item")->value(implode("|", $itemids)); + $item_count = count($itemids); + $ids = implode(", ", $itemids); + $tags = Database::instance()->query( + "SELECT t.name, COUNT(it.item_id) as count + FROM {items_tags} it, {tags} t + WHERE it.tag_id = t.id + AND it.item_id in($ids) + GROUP BY it.tag_id + ORDER BY t.name ASC"); + $taglist = array(); + foreach ($tags as $tag) { + $taglist[] = $tag->name . ($item_count > $tag->count ? "*" : ""); + } + $taglist = implode("; ", $taglist); + $tagPane->textarea("tags")->label(t("Tags"))->value($taglist); + + return $tagPane; + } +}
\ No newline at end of file diff --git a/modules/tag/helpers/tag_event.php b/modules/tag/helpers/tag_event.php index 735422b5..2a08cb6d 100644 --- a/modules/tag/helpers/tag_event.php +++ b/modules/tag/helpers/tag_event.php @@ -59,4 +59,9 @@ class tag_event_Core { "SELECT `tag_id` from {items_tags} WHERE `item_id` = $item->id)"); $db->delete("items_tags", array("item_id" => "$item->id")); } + + static function organize_form_creation($event_parms) { + $event_parms->panes[] = array("label" => t("Manage Tags"), + "content" => tag::get_organize_form($event_parms->itemids)); + } } |