From 2a4e1e981157dd29c82a96f42ee794c5981b6161 Mon Sep 17 00:00:00 2001 From: "Michael J. Rubinsky" Date: Thu, 29 Jan 2009 13:46:51 -0500 Subject: [PATCH] More work on tagging. This adds tagging to the event edit form, deletion of tags from the view panel and other tweaks. Still need to add via panel and calendar form. --- kronolith/edit.php | 2 + kronolith/lib/Imple/TagActions.php | 80 ++++++++++++++++++++++++++++++++------ kronolith/lib/Tagger.php | 68 ++++++++++++++++++++++++++++++-- kronolith/lib/Views/EditEvent.php | 4 ++ kronolith/templates/edit/edit.inc | 10 ++++- 5 files changed, 148 insertions(+), 16 deletions(-) diff --git a/kronolith/edit.php b/kronolith/edit.php index 372df1534..c2523886c 100644 --- a/kronolith/edit.php +++ b/kronolith/edit.php @@ -12,6 +12,8 @@ function _save(&$event) { $res = $event->save(); + $tagger = new Kronolith_Tagger(); + $tagger->replaceTags($event->getUID(), Util::getFormData('tags')); if (is_a($res, 'PEAR_Error')) { $GLOBALS['notification']->push(sprintf(_("There was an error editing the event: %s"), $res->getMessage()), 'horde.error'); } elseif (Util::getFormData('sendupdates', false)) { diff --git a/kronolith/lib/Imple/TagActions.php b/kronolith/lib/Imple/TagActions.php index 115698085..89a5923ac 100644 --- a/kronolith/lib/Imple/TagActions.php +++ b/kronolith/lib/Imple/TagActions.php @@ -1,6 +1,13 @@ + * + * @package Kronolith */ class Kronolith_Imple_TagActions extends Kronolith_Imple { @@ -27,6 +34,14 @@ class Kronolith_Imple_TagActions extends Kronolith_Imple Kronolith::addInlineScript($js, 'window'); } + /** + * Handle the tag related action. + * + * If removing a tag, needs a 'resource' which is the local identifier of + * the kronolith object, a 'type' which should be the string reprentation of + * the type of object (event/calendar) and 'tags' should be the integer + * tag_id of the tag to remove. + */ public function handle($args) { global $ansel_storage; @@ -35,23 +50,64 @@ class Kronolith_Imple_TagActions extends Kronolith_Imple $content = array('id' => $args['resource'], 'type' => $args['type']); $tags = $args['tags']; - /* Get the resource owner */ - /* Perms checks */ - - switch ($request) { - case 'add': - break; - case 'remove': - $tagger = new Kronolith_Tagger(); - //$tagger-> - + // Check perms + if ($args['type'] == 'calendar') { + $cal = $GLOBALS['kronolith_shares']->getShare($args['resource']); + $perm = $cal->hasPermission(Auth::getAuth(), PERMS_EDIT); + } elseif($args['type'] == 'event') { + $event = $GLOBALS['kronolith_driver']->getByUID($args['resource']); + $perm = $event->hasPermission(PERMS_EDIT, Auth::getAuth()); + } - break; + if ($perm) { + /* Get the resource owner */ + switch ($request) { + case 'add': + //@TODO + break; + case 'remove': + $tagger = new Kronolith_Tagger(); + $tagger->untag($args['resource'], (int)$tags, $args['type']); + break; + } } + return $this->_getTagHtml($tagger, $args['resource'], $args['type']); + } - private function _getTagHtml($tags, $hasEdit) + /** + * Generate the HTML for the tag lists to send back to the browser. + * + * TODO: This should be made a view helper when we move to using Horde_View + * + * @param Kronolith_Tagger $tagger The tagger object + * @param string $id The identifier (share name or event uid) + * @param string $type The type of resource (calendar/event) + * + * @return string The HTML + */ + private function _getTagHtml($tagger, $id, $type) { + $tags = $tagger->getTags($id, 'calendar'); + $html = ''; + $js = ''; + + if ($type == 'calendar') { + $cal = $GLOBALS['kronolith_shares']->getShare($id); + $hasEdit = $cal->hasPermission(Auth::getAuth(), PERMS_EDIT); + } elseif ($type == 'event') { + if ($kronolith_driver->getCalendar() != $cal) { + $kronolith_driver->open($cal); + } + $event = $GLOBALS['kronolith_driver']->getByUID($id); + $hasEdit = $event->hasPermission(PERMS_EDIT, Auth::getAuth()); + } + + foreach ($tags as $tag_id => $tag) { + $html .= '
  • ' . $tag . ($hasEdit ? '' . Horde::img('delete-small.png', _("Remove Tag"), '', $GLOBALS['registry']->getImageDir('horde')) . '' : '') . '
  • '; + } + + return $html; } } diff --git a/kronolith/lib/Tagger.php b/kronolith/lib/Tagger.php index 2ffc471d5..969a0c79e 100644 --- a/kronolith/lib/Tagger.php +++ b/kronolith/lib/Tagger.php @@ -2,14 +2,21 @@ /** * Kronolith interface to the Horde_Content tagger * + * Copyright 2009 The Horde Project (http://www.horde.org) * + * @author Michael J. Rubinsky + * + * @package Kronolith */ -// Note:: Autoloading depends on there being a registry entry for content +// NOTE: For now, autoloading depends on there being a registry entry for the +// 'content' application. + Horde_Autoloader::addClassPattern('/^Content_/', $GLOBALS['registry']->get('fileroot', 'content') . '/lib/'); -class Kronolith_Tagger { +class Kronolith_Tagger +{ /** * Local cache of the type name => ids from Content, so we don't have to @@ -74,6 +81,7 @@ class Kronolith_Tagger { if (!is_array($tags)) { $tags = self::$_tagger->splitTags($tags); } + self::$_tagger->tag(Auth::getAuth(), array('object' => $localId, 'type' => self::$_type_ids[$content_type]), @@ -115,11 +123,65 @@ class Kronolith_Tagger { public function untag($localId, $tag, $content_type = 'event') { self::$_tagger->removeTagFromObject( - array('object' => $localId, 'type' => $content_type), + array('object' => $localId, 'type' => self::$_type_ids[$content_type]), $tag); } /** + * Tag the given resource with *only* the tags provided, removing any tags + * that are already present but not in the list. + * + * @param $localId + * @param $tags + * @param $content_type + * + * @return void + */ + public function replaceTags($localId, $tags, $content_type = 'event') + { + // First get a list of existing tags. + $existing_tags = $this->getTags($localId, $content_type); + + // If we don't have an array - split the string. + if (!is_array($tags)) { + $tags = self::$_tagger->splitTags($tags); + } + $remove = array(); + foreach ($existing_tags as $tag_id => $existing_tag) { + $found = false; + foreach ($tags as $tag_text) { + //if ($existing_tag == String::lower($tag_text, true)) { + if ($existing_tag == $tag_text) { + $found = true; + break; + } + } + // Remove any tags that were not found in the passed in list. + if (!$found) { + $remove[] = $tag_id; + } + } + + $this->untag($localId, $remove, $content_type); + $add = array(); + foreach ($tags as $tag_text) { + $found = false; + foreach ($existing_tags as $existing_tag) { + if ($tag_text == $existing_tag) { + $found = true; + break; + } + } + if (!$found) { + $add[] = $tag_text; + } + } + + $this->tag($localId, $add, $content_type); + } + + + /** * @TODO * @param array $tags An array of tag ids. */ diff --git a/kronolith/lib/Views/EditEvent.php b/kronolith/lib/Views/EditEvent.php index 649fa8399..73dd679ae 100644 --- a/kronolith/lib/Views/EditEvent.php +++ b/kronolith/lib/Views/EditEvent.php @@ -99,6 +99,10 @@ class Kronolith_View_EditEvent { $event = &$this->event; + // Tags + $tagger = new Kronolith_Tagger(); + $tags = $tagger->getTags($event->getUID(), 'event'); + $tags = implode(',', array_values($tags)); echo '