/** * Tags saving logic, runned after the object himself has been saved * * @param Doctrine_Event $event */ public function postSave(Doctrine_Event $event) { $object = $event->getInvoker(); $added_tags = Taggable::get_tags($object); $removed_tags = array_keys(Taggable::get_removed_tags($object)); sfContext::getInstance()->getLogger()->notice(print_r($added_tags, true) . print_r($removed_tags, true)); // save new tags foreach ($added_tags as $tagname) { $tag = PluginTagTable::findOrCreateByTagName($tagname); $tag->save(); $tagging = new Tagging(); $tagging->tag_id = $tag->id; $tagging->taggable_id = $object->id; $tagging->taggable_model = get_class($object); $tagging->save(); } if ($removed_tags) { $q = Doctrine_Query::create()->select('t.id')->from('Tag t INDEXBY t.id')->whereIn('t.name', $removed_tags); $removed_tag_ids = array_keys($q->execute(array(), Doctrine::HYDRATE_ARRAY)); Doctrine::getTable('Tagging')->createQuery()->delete()->whereIn('tag_id', $removed_tag_ids)->addWhere('taggable_id = ?', $object->id)->addWhere('taggable_model = ?', get_class($object))->execute(); } $tags = array_merge(Taggable::get_tags($object), $object->getSavedTags()); Taggable::set_saved_tags($object, $tags); Taggable::clear_tags($object); Taggable::clear_removed_tags($object); }
/** * Preload tags for a set of objects. It might be usefull in case you want to * display a long list of taggable objects with their associated tags: it * avoids to load tags per object, and gets all tags in a few requests. * * @param array $objects */ public static function preloadTags(&$objects) { $searched = array(); foreach ($objects as $object) { $class = get_class($object); if (!isset($searched[$class])) { $searched[$class] = array(); } $searched[$class][$object->getPrimaryKey()] = $object; Taggable::set_saved_tags($object, array()); } $q = Doctrine_Core::getTable('Tagging')->createQuery('t')->leftJoin('t.Tag as tag')->orderBy('t.taggable_id')->setHydrationMode(Doctrine_Core::HYDRATE_ARRAY); foreach ($searched as $model => $instances) { $qClone = clone $q; $taggings = $qClone->addWhere('t.taggable_model = ?', $model)->andWhereIn('t.taggable_id', array_keys($instances))->execute(); foreach ($taggings as $tagging) { Taggable::add_saved_tag($instances[$tagging['taggable_id']], $tagging['Tag']['name']); } } }