correct bugs on database opt
authorymh <ymh.work@gmail.com>
Mon, 26 Dec 2011 22:53:50 +0100
changeset 67 989d9e117586
parent 66 868d0fcdbb99
child 68 e7384fb35f7a
correct bugs on database opt
Command/QueryWikipediaCommand.php
Controller/WikiTagController.php
Entity/DocumentRepository.php
Entity/DocumentTagRepository.php
Entity/TagRepository.php
Listener/DocumentListener.php
Services/DocumentService.php
Tests/Services/DocumentServiceTest.php
Utils/WikiTagUtils.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);
         
--- 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();
--- 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]))
--- 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
--- 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 <NULL, \IRI\Bundle\WikiTagBundle\Entity\Tag> Ambigous <NULL, unknown, mixed, string> (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 <NULL, \IRI\Bundle\WikiTagBundle\Entity\Tag> Ambigous <NULL, unknown, mixed, string> (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 {
--- 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);
+            }
         }
     }
     
--- 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
--- 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())
--- 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){