How to get rid of unused tags? And how to merge tags?


After doing some cleaning up of unused tags in my repository, I’ve noticed it’s a time consuming process, because the only way seems to be to browse tags by count (one click), then revert sorting order (second click), delete one tag with 0 items using it, and then start all over again because the tags get redisplayed by Name, Desc.

  1. So, is there a way to stop the resetting of sort criteria after the deletion of every tag?
  2. And is there a simple way to implement an extra button that will take care of all tags used 0 times, once and for all?
  3. And, as an extra feature: is there any way to have tags merging, when they have the same value? (example: two tags, “bravo 1” and “bravo 2”, if I rename the first one to “bravo” it will work, but if I try to rename also the second one to “bravo” it will throw an error, instead of merging it with the first one).

Thanks for any help on this.

Been thinking about (2). An alternative way would be for the page to behave like the item’s tags page, i.e. to allow the selection-for-deletion of one or more tags, and then the effective deletion would happen when users presses the Save button. This way it would be possible to delete also tags used 1 time or more. I’m afraid that would probably need a change of the whole/admin/tags/browse.php page, though.

As usual, any help or comment would be appreciated.

I’ve been working on the “merge” part, and manage to have it working by changing the code (if anybody wants to try to turn the changes into a plugin, is more than welcome, although maybe the changes could be implemented in the core of a future release). Here’s what I’ve done:

file application/controllers/TagsController.php (modified the last 5 lines)

public function renameAjaxAction() {
        $csrf = new Omeka_Form_SessionCsrf;
        $oldTagId = $_POST['pk'];
        $oldTag = $this->_helper->db->findById($oldTagId);
        $oldName = $oldTag->name;
        $newName = trim($_POST['value']);
        $error = __('Error occurred.');

        $oldTag->name = $newName;
        if ($csrf->isValid($_POST)) {
			if ($oldTag->save(false)) {
			} else {
				$newTag = $this->_helper->db->findOrNew($newName);
				$newTagId = $newTag->id;
				$this->_helper->db->mergeTags($oldTagId, $newTagID);
		} else {

and file application/models/Table/Tag.php (new function added)

public function mergeTags($oldTagId, $newTagId) {
        $db = $this->getDb();
        $sql = "UPDATE $db->RecordsTag SET tag_id = $newTagId, time = CURRENT_TIMESTAMP WHERE tag_id = $oldTagId AND record_id NOT IN (SELECT record_id FROM (SELECT DISTINCT record_id FROM $db->RecordsTag WHERE tag_id = $newTagId) AS tmptable)";
		$sql = "DELETE FROM $db->RecordsTag WHERE tag_id = $oldTagId";
		$sql = "DELETE FROM $db->Tag WHERE id = $oldTagId";

Now, here’re some possible improvements, in case anybody wanted to contribute:

  1. before the merging takes place, a message box asking for confirmation;
  2. after the merging has taken place, update the count of the tag, at the same time hiding the emptied one;
  3. error message in case of mishap during the merging.

Hope this helps.