add event on tag changed
authorymh <ymh.work@gmail.com>
Thu, 17 Nov 2011 11:29:26 +0100
changeset 34 21fab44f46fe
parent 30 d2fba1e3b94b
child 35 92ddb5488eb4
add event on tag changed
Command/ReorderTagsCommand.php
Command/SyncDocumentsCommand.php
Controller/WikiTagController.php
Entity/DocumentRepository.php
Entity/DocumentTagRepository.php
Entity/TagRepository.php
Event/DocumentTagEvent.php
Event/WikiTagEvents.php
Listener/DocumentListener.php
Search/Search.php
Tests/Controller/DefaultControllerTest.php
Tests/Controller/WikiTagControllerTest.php
Tests/Search/SearchServiceTest.php
phpunit.xml.dist
--- a/Command/ReorderTagsCommand.php	Wed Nov 09 16:25:13 2011 +0100
+++ b/Command/ReorderTagsCommand.php	Thu Nov 17 11:29:26 2011 +0100
@@ -54,7 +54,6 @@
         
         $done = 0;
         $iterable = $query->iterate();
-        $todetach = array();
         while (($row = $iterable->next()) !== false)
         {
             $done++;
@@ -66,17 +65,12 @@
             $doctrine->getEntityManager()->persist($doc);
             
             $search_service->reorderTagsForDocument($doc);
-            $todetach[] = $doc;
             
             
             if($done%100 == 0)
             {
                 $doctrine->getEntityManager()->flush();
                 $doctrine->getEntityManager()->clear();
-                /*foreach($todetach as $obj)
-                {
-                    $doctrine->getEntityManager()->detach($obj);
-                }*/
                 $todetach = array();
                 $output->writeln("memory : ".strval(memory_get_usage(true)));
             }
--- a/Command/SyncDocumentsCommand.php	Wed Nov 09 16:25:13 2011 +0100
+++ b/Command/SyncDocumentsCommand.php	Thu Nov 17 11:29:26 2011 +0100
@@ -10,8 +10,9 @@
 
 namespace IRI\Bundle\WikiTagBundle\Command;
 
+use IRI\Bundle\WikiTagBundle\Event\WikiTagEvents;
+use IRI\Bundle\WikiTagBundle\Event\DocumentTagEvent;
 use Doctrine\ORM\Query;
-
 use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
 use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
@@ -75,6 +76,11 @@
                 $todetach[] = $doc;
                 $output->writeln("Process doc id ".$doc->getId()." $done/$total ".strval(intval(floatval($done)/floatval($total)*100.0))."%$memory");
                 $docrep->updateTagsStr($doc);
+                //dispatch event
+                $event_dispatcher = $this->getContainer()->get('event_dispatcher');
+                $event = new DocumentTagEvent($doc);
+                $event_dispatcher->dispatch(WikiTagEvents::onTagChanged, $event);
+                
                 if($done%10 == 0)
                 {
                     $doctrine->getEntityManager()->flush();
--- a/Controller/WikiTagController.php	Wed Nov 09 16:25:13 2011 +0100
+++ b/Controller/WikiTagController.php	Thu Nov 17 11:29:26 2011 +0100
@@ -170,13 +170,19 @@
             $dt = $this->getDoctrine()->getRepository('WikiTagBundle:DocumentTag')->findOneBy(array('document' => $id_doc, 'tag' => $id_moved_tag));
             $dt->setTag($tag);
             $dt->setWikipediaRevisionId($revision_id);
-            //
-            // TODO: HERE QUERY TO GET A INDEX_NOTE/SCORE for the tag. Here is python code :
-            //kwargs = {DJANGO_ID + "__exact": unicode(ds_id)}
-            //results = SearchQuerySet().filter(title=tag_label).filter_or(description=tag_label).filter(**kwargs)
-            //if len(results) > 0:
-            //    ts.index_note = results[0].score
-            //
+            
+            $score_res = $this->container->get('wiki_tag.search')->search($tag_label, array("id"=>$id_doc));
+            
+            if(count($score_res)>0)
+            {
+                $score = floatval($score_res[0]['score']);
+            }
+            else
+            {
+                $score = 0.0;
+            }
+            $dt->setIndexNote($score);
+            
             // We set ManualOrder = true for the current document
             $doc = $this->getDoctrine()->getRepository('WikiTagBundle:Document')->findOneBy(array('externalId' => $id_doc));
             $doc->setManualOrder(true);
--- a/Entity/DocumentRepository.php	Wed Nov 09 16:25:13 2011 +0100
+++ b/Entity/DocumentRepository.php	Thu Nov 17 11:29:26 2011 +0100
@@ -208,11 +208,13 @@
         $this->getEntityManager()->persist($document);
     }
     
+
     /**
      *
      * Enter description here ...
-     * @param array $values : key: the fields to search into, value array('value'=>value, 'weight'=>weight)
-     * @param unknown_type $conditions
+     * @param array $values : key: the fields to search into, value : array('value'=>value, 'weight'=>weight)
+     * @param array $conditions : array : key : field name, value : simple value (operator is "=") or array(valuea, value2,...) (operatr is IN) or array("operator"=>"", "value"=>value)
+     * @return Ambigous <multitype:, \Doctrine\ORM\mixed, \Doctrine\DBAL\Driver\Statement, \Doctrine\ORM\Internal\Hydration\mixed>
      */
     function search(array $values, array $conditions=NULL)
     {
--- a/Entity/DocumentTagRepository.php	Wed Nov 09 16:25:13 2011 +0100
+++ b/Entity/DocumentTagRepository.php	Thu Nov 17 11:29:26 2011 +0100
@@ -67,12 +67,24 @@
         return $qb;
     }
     
+    /**
+     *
+     * Enter description here ...
+     * @param unknown_type $external_id
+     * @param array $filter_array
+     */
     public function findByDocumentExternalId($external_id, array $filter_array=null)
     {
         $qb = $this->createQueryBuilderByDocumentExternalId($external_id, $filter_array);
         return $qb->getQuery()->getResult();
     }
     
+    /**
+     *
+     * Enter description here ...
+     * @param unknown_type $external_id
+     * @param array $filter_array
+     */
     public function findOneByDocumentExternalId($external_id, array $filter_array=null) {
         
         $qb = $this->createQueryBuilderByDocumentExternalId($external_id, $filter_array)->setMaxResults(1);
--- a/Entity/TagRepository.php	Wed Nov 09 16:25:13 2011 +0100
+++ b/Entity/TagRepository.php	Thu Nov 17 11:29:26 2011 +0100
@@ -12,4 +12,33 @@
  */
 class TagRepository extends EntityRepository
 {
+    public function getTagCloud($max_tags)
+    {
+        $qb = $this->getEntityManager()->createQueryBuilder();
+        $qb->select('t.id', 't.label', 'COUNT( dt.id ) AS nb_docs');
+        $qb->from('WikiTagBundle:Tag','t');
+        $qb->leftJoin('t.documents', 'dt', 'WITH', 't = dt.tag');
+        $qb->addGroupBy('t.id');
+        $qb->addOrderBy('nb_docs','DESC');
+        $qb->setMaxResults($max_tags);
+        
+        $query = $qb->getQuery();
+        return $query->getResult();
+    }
+    
+    public function getCompletion($seed)
+    {
+        $qb = $this->getEntityManager()->createQueryBuilder();
+        $qb->select('t.label');
+        $qb->from('WikiTagBundle:Tag','t');
+        $qb->where($qb->expr()->orx(
+            $qb->expr()->like('t.label',$qb->expr()->literal("%".addcslashes(mysql_real_escape_string($seed),"%_"))),
+            $qb->expr()->like('t.label',$qb->expr()->literal("% ".addcslashes(mysql_real_escape_string($seed),"%_")."%"))
+        ));
+        
+        $query = $qb->getQuery();
+        
+        return $query->getResult();
+        
+    }
 }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Event/DocumentTagEvent.php	Thu Nov 17 11:29:26 2011 +0100
@@ -0,0 +1,28 @@
+<?php
+/*
+ * This file is part of the WikiTagBundle package.
+ *
+ * (c) IRI <http://www.iri.centrepompidou.fr/>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace IRI\Bundle\WikiTagBundle\Event;
+
+use Symfony\Component\EventDispatcher\Event;
+use IRI\Bundle\WikiTagBundle\Model\DocumentInterface;
+
+class DocumentTagEvent extends Event
+{
+    protected $document;
+
+    public function __construct(DocumentInterface $doc)
+    {
+        $this->document = $doc;
+    }
+
+    public function getDocument()
+    {
+        return $this->document;
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Event/WikiTagEvents.php	Thu Nov 17 11:29:26 2011 +0100
@@ -0,0 +1,20 @@
+<?php
+/*
+ * This file is part of the WikiTagBundle package.
+ *
+ * (c) IRI <http://www.iri.centrepompidou.fr/>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace IRI\Bundle\WikiTagBundle\Event;
+
+final class WikiTagEvents
+{
+    /**
+     * the wikitag.tag_change events is thrown each time the tag list of a document is modified.
+     * @var string
+     */
+    const onTagChanged = 'wikitag.tag_changed';
+
+}
\ No newline at end of file
--- a/Listener/DocumentListener.php	Wed Nov 09 16:25:13 2011 +0100
+++ b/Listener/DocumentListener.php	Thu Nov 17 11:29:26 2011 +0100
@@ -10,6 +10,10 @@
 
 namespace IRI\Bundle\WikiTagBundle\Listener;
 
+use IRI\Bundle\WikiTagBundle\Event\WikiTagEvents;
+
+use IRI\Bundle\WikiTagBundle\Event\DocumentTagEvent;
+
 use Doctrine\ORM\Tools\ToolEvents;
 
 use Doctrine\Common\EventSubscriber;
@@ -58,6 +62,14 @@
         );
     }
     
+    private function updateTagsStr($doc)
+    {
+        $this->getContainer()->get('doctrine')->getRepository("WikiTagBundle:Document")->updateTagsStr($doc);
+        $event_dispatcher = $this->getContainer()->get('event_dispatcher');
+        $event = new DocumentTagEvent($doc);
+        $event_dispatcher->dispatch(WikiTagEvents::onTagChanged, $event);
+    }
+    
     public function postPersist(LifecycleEventArgs $args)
     {
         $logger = $this->container->get('logger');
@@ -91,7 +103,7 @@
         if (is_a($entity, "IRI\Bundle\WikiTagBundle\Model\DocumentTagInterface"))
         {
             $doc = $entity->getDocument();
-            $this->getContainer()->get('doctrine')->getRepository("WikiTagBundle:Document")->updateTagsStr($doc);
+            $this->updateTagsStr($doc);
         }
     }
     
@@ -111,7 +123,7 @@
         elseif (is_a($entity, "IRI\Bundle\WikiTagBundle\Model\DocumentTagInterface"))
         {
             $doc = $entity->getDocument();
-            $this->getContainer()->get('doctrine')->getRepository("WikiTagBundle:Document")->updateTagsStr($doc);
+            $this->updateTagsStr($doc);
         }
         elseif (is_a($entity, "IRI\Bundle\WikiTagBundle\Model\TagInterface"))
         {
@@ -120,7 +132,7 @@
             {
                 foreach($documents as $doctag)
                 {
-                    $this->getContainer()->get('doctrine')->getRepository("WikiTagBundle:Document")->updateTagsStr($doctag->getDocument());
+                    $this->updateTagsStr($doctag->getDocument());
                 }
             }
         }
--- a/Search/Search.php	Wed Nov 09 16:25:13 2011 +0100
+++ b/Search/Search.php	Thu Nov 17 11:29:26 2011 +0100
@@ -42,6 +42,38 @@
         }
         return $this->doctrine;
     }
+    /**
+     *
+     * Enter description here ...
+     * @param string $value
+     * @param array $conditions
+     * @param array $fields
+     */
+    public function search($value, array $conditions, array $fields=null)
+    {
+        if(is_null($fields))
+        {
+            $fields = $this->getContainer()->getParameter("wiki_tag.fields");
+        }
+        $doctrine = $this->getContainer()->get('doctrine');
+        $res = $doctrine->getRepository('WikiTagBundle:Document');
+        $fieldquery = array();
+        foreach ($fields as $fieldname => $fielddef) {
+            if(isset($fielddef['weight']))
+            {
+                $weight = $fielddef['weight'];
+            }
+            else
+            {
+                $weight = 1.0;
+            }
+            $fieldquery[] = array("columns"=>$fieldname, "value"=>$value, "weight"=>$weight);
+        }
+        
+        $score_res = $res->search($fieldquery, $conditions);
+        
+        return $score_res;
+    }
     
     /**
      * Service to reorder the tags using their notes in the index search
@@ -50,31 +82,14 @@
     public function reorderTagsForDocument($document)
     {
         $doctrine = $this->getContainer()->get('doctrine');
-        $res = $doctrine->getRepository('WikiTagBundle:Document');
+        
         $tags_score = array();
+        
         foreach($document->getTags() as $tag)
         {
             $label = $tag->getTag()->getLabel();
             
-            //
-            $fields = $this->getContainer()->getParameter("wiki_tag.fields");
-            
-            $fieldquery = array();
-            foreach ($fields as $fieldname => $fielddef) {
-                $columns = "$fieldname";
-                $value = $label;
-                if(isset($fielddef['weight']))
-                {
-                    $weight = $fielddef['weight'];
-                }
-                else
-                {
-                    $weight = 1.0;
-                }
-                $fieldquery[] = array("columns"=>$columns, "value"=>$value, "weight"=>$weight);
-            }
-            
-            $score_res = $res->search($fieldquery, array("id"=>$document->getId()));
+            $score_res = $this->search($label, array("id"=>$document->getId()));
             
             if(count($score_res)>0)
             {
@@ -104,12 +119,20 @@
     
     public function getTagCloud($max_tags)
     {
-        $qb = $this->getDoctrine()->getEntityManager()->createQueryBuilder();
-        $qb->select('t', 'COUNT( dt.id ) AS nb_docs');
-        $qb->from('WikiTagBundle:Tag','t');
-        $qb->leftJoin('t.documents', 'dt', 'WITH', 't = dt.tag');
-        $qb->addGroupBy('t.id');
-        $qb->addOrderBy('nb_docs','DESC');
+        $rep = $this->getDoctrine()->getRepository('WikiTagBundle:Tag');
+        return $rep->getTagCloud($max_tags);
+    }
+    
+    public function completion($seed)
+    {
+        $rep = $this->getDoctrine()->getRepository('WikiTagBundle:Tag');
+        
+        $res = array();
+        foreach ($rep->getCompletion($seed) as $value) {
+            $res[] = $value['label'];
+        }
+        
+        return $res;
         
     }
     
--- a/Tests/Controller/DefaultControllerTest.php	Wed Nov 09 16:25:13 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-<?php
-
-namespace IRI\Bundle\WikiTagBundle\Tests\Controller;
-
-use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
-
-class DefaultControllerTest extends WebTestCase
-{
-    public function testIndex()
-    {
-        $client = static::createClient();
-
-        $crawler = $client->request('GET', '/hello/Fabien');
-
-        $this->assertTrue($crawler->filter('html:contains("Hello Fabien")')->count() > 0);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Tests/Controller/WikiTagControllerTest.php	Thu Nov 17 11:29:26 2011 +0100
@@ -0,0 +1,17 @@
+<?php
+
+namespace IRI\Bundle\WikiTagBundle\Tests\Controller;
+
+use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
+
+class WikiTagControllerTest extends WebTestCase
+{
+    public function testIndex()
+    {
+        /*$client = static::createClient();
+
+        $crawler = $client->request('GET', '/tag/');
+
+        $this->assertTrue($crawler->filter('html:contains("Nothing to see here")')->count() > 0);*/
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Tests/Search/SearchServiceTest.php	Thu Nov 17 11:29:26 2011 +0100
@@ -0,0 +1,59 @@
+<?php
+/*
+ * This file is part of the WikiTagBundle package.
+ *
+ * (c) IRI <http://www.iri.centrepompidou.fr/>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace IRI\Bundle\WikiTagBundle\Tests\Services;
+
+require_once(__DIR__ . "/../../../../../../../app/AppKernel.php");
+
+class SearchServiceTest extends \PHPUnit_Framework_TestCase
+{
+
+    protected $_container;
+    
+    public function __construct()
+    {
+        $kernel = new \AppKernel("test", true);
+        $kernel->boot();
+        $this->_container = $kernel->getContainer();
+        parent::__construct();
+    }
+    
+    protected function get($service)
+    {
+        return $this->_container->get($service);
+    }
+    
+    
+    public function testTagCloud()
+    {
+        
+        $search_service = $this->get("wiki_tag.search");
+        
+        $result = $search_service->getTagCloud(30);
+        
+        $this->assertNotNull($result, "tag cloud should not be null");
+        $this->assertLessThanOrEqual(30, count($result));
+    }
+
+    
+    public function testCompletion()
+    {
+    
+        $search_service = $this->get("wiki_tag.search");
+    
+        $result = $search_service->completion("fra");
+    
+        $this->assertNotNull($result, "tag cloud should not be null");
+        $this->assertGreaterThanOrEqual(1, count($result));
+    }
+    
+    
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phpunit.xml.dist	Thu Nov 17 11:29:26 2011 +0100
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- http://www.phpunit.de/manual/current/en/appendixes.configuration.html -->
+<phpunit
+    backupGlobals               = "false"
+    backupStaticAttributes      = "false"
+    colors                      = "true"
+    convertErrorsToExceptions   = "true"
+    convertNoticesToExceptions  = "true"
+    convertWarningsToExceptions = "true"
+    processIsolation            = "false"
+    stopOnFailure               = "false"
+    syntaxCheck                 = "false"
+    bootstrap                   = "../../../../../app/bootstrap.php.cache" >
+
+    <testsuites>
+        <testsuite name="Project Test Suite">
+            <directory>Tests</directory>
+        </testsuite>
+    </testsuites>
+
+    <!--
+    <php>
+        <server name="KERNEL_DIR" value="/path/to/your/app/" />
+    </php>
+    -->
+
+    <!--filter>
+        <whitelist>
+            <directory>../src</directory>
+            <exclude>
+                <directory>../src/*/*Bundle/Resources</directory>
+                <directory>../src/*/*Bundle/Tests</directory>
+                <directory>../src/*/Bundle/*Bundle/Resources</directory>
+                <directory>../src/*/Bundle/*Bundle/Tests</directory>
+            </exclude>
+        </whitelist>
+    </filter-->
+
+</phpunit>