# HG changeset patch # User ymh # Date 1324936430 -3600 # Node ID 989d9e1175866532b01d777bc657a02c94a23f71 # Parent 868d0fcdbb99baf2d4cd6e909301a641163cd36d correct bugs on database opt diff -r 868d0fcdbb99 -r 989d9e117586 Command/QueryWikipediaCommand.php --- a/Command/QueryWikipediaCommand.php Mon Dec 19 18:15:42 2011 +0100 +++ b/Command/QueryWikipediaCommand.php Mon Dec 26 22:53:50 2011 +0100 @@ -24,7 +24,7 @@ private function processTag($tag, $em) { $tag_label_normalized = WikiTagUtils::normalizeTag($tag->getLabel()); - $wp_response = WikiTagUtils::getWikipediaInfo($tag_label_normalized); + $wp_response = WikiTagUtils::getWikipediaInfo($tag_label_normalized, null, $this->getContainer()->getParameter('wiki_tag.ignore_wikipedia_error')); $tag->setWikipediaInfo($wp_response); diff -r 868d0fcdbb99 -r 989d9e117586 Controller/WikiTagController.php --- a/Controller/WikiTagController.php Mon Dec 19 18:15:42 2011 +0100 +++ b/Controller/WikiTagController.php Mon Dec 26 22:53:50 2011 +0100 @@ -201,7 +201,7 @@ } // We create the new tag or get the already existing tag. $tag, $revision_id, $created try { - $ar = $this->getDoctrine()->getRepository('WikiTagBundle:Tag')->getOrCreateTag($tag_label); + $ar = $this->getDoctrine()->getRepository('WikiTagBundle:Tag')->getOrCreateTag($tag_label, $this->container->getParameter('wiki_tag.ignore_wikipedia_error')); } catch (\Exception $e){ return new Response(json_encode(array('error' => 'wikipedia_request_failed', 'message' => $e->getMessage())),400); @@ -563,7 +563,7 @@ if($tag!=null && $label!=null){ // We get the Wikipedia informations for the sent label $tag_label_normalized = WikiTagUtils::normalizeTag($label); - $wp_response = WikiTagUtils::getWikipediaInfo($tag_label_normalized); + $wp_response = WikiTagUtils::getWikipediaInfo($tag_label_normalized, null, $this->container->getParameter('wiki_tag.ignore_wikipedia_error')); $tag->setWikipediaInfo($wp_response); // Save datas. $em = $this->getDoctrine()->getEntityManager(); diff -r 868d0fcdbb99 -r 989d9e117586 Entity/DocumentRepository.php --- a/Entity/DocumentRepository.php Mon Dec 19 18:15:42 2011 +0100 +++ b/Entity/DocumentRepository.php Mon Dec 26 22:53:50 2011 +0100 @@ -44,7 +44,7 @@ } - private function reflectionSetField($object, $method_name, $value) + public function reflectionSetField($object, $method_name, $value) { if(isset($this->set_methods[$method_name])) { @@ -79,7 +79,7 @@ } - private function reflectionGetField($document, $accessor) + public function reflectionGetField($document, $accessor) { if(!isset($this->get_methods[$accessor]) || is_null($this->get_methods[$accessor])) diff -r 868d0fcdbb99 -r 989d9e117586 Entity/DocumentTagRepository.php --- a/Entity/DocumentTagRepository.php Mon Dec 19 18:15:42 2011 +0100 +++ b/Entity/DocumentTagRepository.php Mon Dec 26 22:53:50 2011 +0100 @@ -17,7 +17,7 @@ */ class DocumentTagRepository extends EntityRepository { - /** + /** * Find ordered tags by document id */ public function findOrderedTagsForDoc($doc_id) @@ -28,20 +28,42 @@ ->getResult(); } + private function findMaxOrderInUow($entityList, $doc_id, $max_order) { + foreach($entityList as $entity) { + if(is_a($entity, "\IRI\Bundle\WikiTagBundle\Model\DocumentTagInterface") && + !is_null($entity->getDocument()) && + ( $entity->getDocument() === $doc_id || $entity->getDocument()->getId() === $doc_id ) ) + { + $max_order = max(array($max_order, $entity->getTagOrder())); + } + } + return $max_order; + } + + /** * Gets the max order of all tags for one document */ public function getMaxOrder($doc_id) { - return $this->getEntityManager() - ->createQuery("SELECT MAX(doctag.tagOrder) FROM WikiTagBundle:DocumentTag doctag JOIN doctag.document doc WHERE doc.externalId= :doc_id") - ->setParameter("doc_id", strval($doc_id)) - ->getResult(); + $max_order_res = $this->getEntityManager() + ->createQuery("SELECT MAX(doctag.tagOrder) FROM WikiTagBundle:DocumentTag doctag JOIN doctag.document doc WHERE doc.externalId= :doc_id") + ->setParameter("doc_id", strval($doc_id)) + ->getSingleScalarResult(); - //todo: look in work unit + $max_order = 0; + if(!is_null($max_order_res)) { + $max_order = intval($max_order_res); + } + + $uow = $this->getEntityManager()->getUnitOfWork(); + + $max_order = $this->findMaxOrderInUow($uow->getScheduledEntityInsertions(), $doc_id, $max_order); + $max_order = $this->findMaxOrderInUow($uow->getScheduledEntityUpdates(), $doc_id, $max_order); + + return $max_order; } - /** * * Enter description here ... @@ -81,7 +103,7 @@ return $qb->getQuery()->getResult(); } - /** + /** * * Enter description here ... * @param unknown_type $external_id diff -r 868d0fcdbb99 -r 989d9e117586 Entity/TagRepository.php --- a/Entity/TagRepository.php Mon Dec 19 18:15:42 2011 +0100 +++ b/Entity/TagRepository.php Mon Dec 26 22:53:50 2011 +0100 @@ -45,21 +45,14 @@ } - /** - * Get or create tag. Returns an array(tag:WikiTagTag, revision_id=int, created:Boolean) - * @param $tag_label - * @param $doctrine - * @return multitype:boolean Ambigous Ambigous (array(\IRI\Bundle\WikiTagBundle\Model\TagInterface, revision_id=int, created:Boolean)) - */ - public function getOrCreateTag($tag_label) + private function findSemantizedTag($entityList, $normalized_label) { - $tag_label_normalized = WikiTagUtils::normalizeTag($tag_label); - // We get the wikipedia references for the tag_label - // We get or create the tag object - // TODO: search also in work unit ? - $tags = $this->findBy(array('normalizedLabel' => $tag_label_normalized)); $tag = null; - foreach ($tags as $t) { + foreach ($entityList as $entity) { + if(!is_null($normalized_label) && (!is_a($entity, "\IRI\Bundle\WikiTagBundle\Model\TagInterface") || $normalized_label !== $entity->getNormalizedLabel())) { + continue; + } + $t = $entity; if($tag==null || $tag->getUrlStatus() === Tag::$TAG_URL_STATUS_DICT['unsemantized'] || ($tag->getUrlStatus() === Tag::$TAG_URL_STATUS_DICT['null_result'] && $t->getUrlStatus() !== Tag::$TAG_URL_STATUS_DICT['unsemantized'])) { @@ -69,6 +62,31 @@ } } } + + return $tag; + + } + + /** + * Get or create tag. Returns an array(tag:WikiTagTag, revision_id=int, created:Boolean) + * @param $tag_label + * @param $doctrine + * @return multitype:boolean Ambigous Ambigous (array(\IRI\Bundle\WikiTagBundle\Model\TagInterface, revision_id=int, created:Boolean)) + */ + public function getOrCreateTag($tag_label, $ignore_wikipedia_info=false) + { + $tag_label_normalized = WikiTagUtils::normalizeTag($tag_label); + // We get the wikipedia references for the tag_label + // We get or create the tag object + $tags = $this->findBy(array('normalizedLabel' => $tag_label_normalized)); + $tag = $this->findSemantizedTag($tags, null); + $uow = $this->getEntityManager()->getUnitOfWork(); + if(is_null($tag)) { + $tag = $this->findSemantizedTag($uow->getScheduledEntityInsertions(), $tag_label_normalized); + } + if(is_null($tag)) { + $tag = $this->findSemantizedTag($uow->getScheduledEntityUpdates(), $tag_label_normalized); + } $wp_request_done = false; if($tag==null) { $tag = new Tag(); @@ -85,7 +103,7 @@ if($created==true || $tag->getUrlStatus()===Tag::$TAG_URL_STATUS_DICT['null_result']) { if($wp_request_done==false) { - $wp_response = WikiTagUtils::getWikipediaInfo($tag_label_normalized); + $wp_response = WikiTagUtils::getWikipediaInfo($tag_label_normalized, null, $ignore_wikipedia_info); } $tag->setWikipediaInfo($wp_response); @@ -98,7 +116,7 @@ } elseif($tag!=null && $tag->getWikipediaPageId()!=null) { - $wp_response = WikiTagUtils::getWikipediaInfo(null, $tag->getWikipediaPageId()); + $wp_response = WikiTagUtils::getWikipediaInfo(null, $tag->getWikipediaPageId(), $ignore_wikipedia_info); $wikipedia_revision_id = $wp_response['revision_id']; } else { diff -r 868d0fcdbb99 -r 989d9e117586 Listener/DocumentListener.php --- a/Listener/DocumentListener.php Mon Dec 19 18:15:42 2011 +0100 +++ b/Listener/DocumentListener.php Mon Dec 26 22:53:50 2011 +0100 @@ -10,6 +10,8 @@ namespace IRI\Bundle\WikiTagBundle\Listener; +use Doctrine\ORM\UnitOfWork; + use IRI\Bundle\WikiTagBundle\Event\WikiTagEvents; use IRI\Bundle\WikiTagBundle\Event\DocumentTagEvent; @@ -56,9 +58,9 @@ public function getSubscribedEvents() { return array( + Events::preRemove, Events::postPersist, Events::postUpdate, - Events::preRemove, Events::postRemove, Events::onFlush, ); @@ -71,6 +73,7 @@ $event = new DocumentTagEvent($doc); $event_dispatcher->dispatch(WikiTagEvents::onTagChanged, $event); } + public function onFlush(OnFlushEventArgs $eventArgs) { @@ -90,6 +93,7 @@ $this->writeDoc($entity, $em); } } + } private function writeDoc($entity, $em) @@ -122,7 +126,6 @@ public function preRemove(LifecycleEventArgs $args) { $logger = $this->container->get('logger'); - $logger->debug("HandleEvent : REMOVE"); $entity = $args->getEntity(); $class = $this->getContainer()->getParameter("wiki_tag.document_class"); if (is_a($entity, $class)) @@ -137,7 +140,10 @@ if (is_a($entity, "IRI\Bundle\WikiTagBundle\Model\DocumentTagInterface")) { $doc = $entity->getDocument(); - $this->updateTagsStr($doc); + $state = $args->getEntityManager()->getUnitOfWork()->getEntityState($doc); + if($state != UnitOfWork::STATE_REMOVED) { + $this->updateTagsStr($doc); + } } } diff -r 868d0fcdbb99 -r 989d9e117586 Services/DocumentService.php --- a/Services/DocumentService.php Mon Dec 19 18:15:42 2011 +0100 +++ b/Services/DocumentService.php Mon Dec 26 22:53:50 2011 +0100 @@ -47,8 +47,10 @@ /** - * Copy the list of tags of one document to another. - * The ids are the ids of the "host" document. + * Copy the list of tags of one document to another. + * The ids are the ids of the "host" document. + * Beware, both Documents must exists in the database. therefore this method can be called only after a EntityManager::push() + * If one or the other doc is not found, an execption is raised. * * @param mixed $id_doc_src the source document id * @param mixed $id_doc_tgt the target document id @@ -81,11 +83,11 @@ } /** - * - * Add a new tag to a "host" document. + * Add a new tag (or tags) to a "host" document. * If the label already exists, an exception is raised. + * Also, the document must exists in the database, i.e. Entitymanager::flush() must have been called on this objects before. * - * @param mixed $doc + * @param mixed $doc the document to add the tags to * @param string|array $tag_label : the label of the new tag */ public function addTags($doc, $tag_labels) @@ -96,13 +98,15 @@ $class = $this->getContainer()->getParameter("wiki_tag.document_class"); if(! is_a($doc,"\IRI\Bundle\WikiTagBundle\Model\DocumentInterface")) { + $doc_rep = $this->getDoctrine()->getRepository('WikiTagBundle:Document'); if(is_a($doc, $class)) { - $doc_id = $doc->getId(); + // todo: use reflection to get the id + $doc_id = $doc_rep->reflectionGetField($doc, Container()->getParameter("wiki_tag.document_id_column")); } else { $doc_id = $doc; } - $doc = $this->getDoctrine()->getRepository('WikiTagBundle:Document')->findOneByExternalId($doc_id); + $doc = $doc_rep->findOneByExternalId($doc_id); } @@ -113,19 +117,37 @@ foreach ($tag_labels as $tag_label) { $normalized_tag_label = WikiTagUtils::normalizeTag($tag_label); + $created = false; $query = $em->createQuery("SELECT COUNT(dt.id) FROM WikiTagBundle:DocumentTag dt JOIN dt.tag t WHERE dt.document = :id_doc AND t.normalizedLabel = :label"); $query->setParameters(array("id_doc"=>$doc, "label"=>$normalized_tag_label)); $nb_tags = $query->getSingleScalarResult(); + if($nb_tags == 0) { + # look in unit of work + $uow = $em->getUnitOfWork(); + foreach($uow->getScheduledEntityInsertions() as $entity) { + if(is_a($entity, "\IRI\Bundle\WikiTagBundle\Model\DocumentTagInterface")) { + $tag = $entity->getTag(); + if(!is_null($tag)) { + if($tag->getNormalizedLabel() === $normalized_tag_label) + { + $nb_tags++; + break; + } + } + } + } + } + // If the label was found, we sent a bad request - if($nb_tags > 0){ + if($nb_tags > 0) { throw new WikiTagServiceException(sprintf("Le tag %s existe déjà pour cette fiche.", $tag_label), 400, null, "duplicate_tag"); } // returns array($tag, $revision_id, $created) try { - $ar = $this->getDoctrine()->getRepository('WikiTagBundle:Tag')->getOrCreateTag($tag_label); + $ar = $this->getDoctrine()->getRepository('WikiTagBundle:Tag')->getOrCreateTag($tag_label, $this->getContainer()->getParameter('wiki_tag.ignore_wikipedia_error')); } catch (\Exception $e){ throw new WikiTagServiceException($e->getMessage(), 500 , $e, "wikipedia_request_failed"); @@ -142,10 +164,9 @@ } if($created || $nb_tags==0){ - $new_order_ar = $this->getDoctrine()->getRepository('WikiTagBundle:DocumentTag')->getMaxOrder($doc); - // The result is a double array. And reset(reset($newOrderAr)) is not allowed. And a string is returned. - $a1 = reset($new_order_ar); - $new_order = intval(reset($a1)) + 1; + + $max_order = $this->getDoctrine()->getRepository('WikiTagBundle:DocumentTag')->getMaxOrder($doc); + $new_order = $max_order + 1; $new_DT = new DocumentTag(); $new_DT->setDocument($doc); $new_DT->setTag($tag); @@ -158,6 +179,12 @@ } + /** + * Returns the list of tags labels for @author ymh + * + * @param mixed $id_doc the document id. + * @throws WikiTagServiceException if the document is not found + */ public function getTagLabels($id_doc) { $rep = $this->getDoctrine()->getRepository('WikiTagBundle:Document'); @@ -168,8 +195,6 @@ } return $rep->getTagsStr($doc); - } - } \ No newline at end of file diff -r 868d0fcdbb99 -r 989d9e117586 Tests/Services/DocumentServiceTest.php --- a/Tests/Services/DocumentServiceTest.php Mon Dec 19 18:15:42 2011 +0100 +++ b/Tests/Services/DocumentServiceTest.php Mon Dec 26 22:53:50 2011 +0100 @@ -61,6 +61,18 @@ } + + public function testTagOrder() + { + $doc = $this->getDoctrine()->getRepository("WikiTagBundle:Document")->findOneByTitle("Title 1"); + + $this->assertNotNull($doc); + $i = 1; + foreach($doc->getTags() as $dt) { + $this->assertEquals($i++, $dt->getTagOrder()); + } + + } public function testUpdate() { @@ -119,7 +131,7 @@ $doc = $this->getDoctrine()->getRepository("WikiTagBundle:Document")->findOneByExternalId($hostdocid); - //$this->assertNull($doc); + $this->assertTrue(is_null($doc)); } @@ -164,7 +176,7 @@ $this->runConsole("doctrine:schema:drop", array("--force" => true)); $this->runConsole("wikitag:schema:create"); $this->runConsole("cache:warmup"); - $this->runConsole("doctrine:fixtures:load", array("--fixtures" => __DIR__ . "/../../../../../../../src/Company/BaseBundle/DataFixtures")); + $this->runConsole("doctrine:fixtures:load"/*, array("--fixtures" => __DIR__ . "/../../../../../../../src/Company/BaseBundle/DataFixtures")*/); } protected function runConsole($command, Array $options = array()) diff -r 868d0fcdbb99 -r 989d9e117586 Utils/WikiTagUtils.php --- a/Utils/WikiTagUtils.php Mon Dec 19 18:15:42 2011 +0100 +++ b/Utils/WikiTagUtils.php Mon Dec 26 22:53:50 2011 +0100 @@ -47,16 +47,9 @@ * @param bigint $page_id * @return array */ - public static function getWikipediaInfo($tag_label_normalized, $page_id=null) + public static function getWikipediaInfo($tag_label_normalized, $page_id=null, $ignore_wikipedia_error=false) { // get ignore_wikipedia_error parameter - $ignore_wikipedia_error = false; - - if(key_exists('kernel', $GLOBALS)) { - $kernel = $GLOBALS['kernel']; - $ignore_wikipedia_error = $kernel->getContainer()->getParameter('wiki_tag.ignore_wikipedia_error'); - } - $params = array('action'=>'query', 'prop'=>'info|categories|langlinks', 'inprop'=>'url', 'lllimit'=>'500', 'cllimit'=>'500', 'rvprop'=>'ids', 'format'=>'json'); if($tag_label_normalized!=null){