# HG changeset patch # User ymh # Date 1323901737 -3600 # Node ID 774ba82dca59276c8c402bb292db656f1c0ca96c # Parent 10be6b9e55e760b9f2dc4179990a098169612002 add tests and fixtures diff -r 10be6b9e55e7 -r 774ba82dca59 Controller/WikiTagController.php --- a/Controller/WikiTagController.php Fri Dec 09 06:43:49 2011 +0100 +++ b/Controller/WikiTagController.php Wed Dec 14 23:28:57 2011 +0100 @@ -16,6 +16,7 @@ use IRI\Bundle\WikiTagBundle\Entity\DocumentTag; use IRI\Bundle\WikiTagBundle\Entity\Tag; use IRI\Bundle\WikiTagBundle\Utils\WikiTagUtils; +use IRI\Bundle\WikiTagBundle\Services\WikiTagServiceException; use Pagerfanta\Pagerfanta; use Pagerfanta\Adapter\ArrayAdapter; use Pagerfanta\Adapter\DoctrineORMAdapter; @@ -267,52 +268,15 @@ { $id_doc = $this->getRequest()->request->get('wikitag_document_id'); $tag_label = $this->getRequest()->request->get('value'); - // We get the DocumentTags - $em = $this->getDoctrine()->getEntityManager(); - $tags = $this->getDoctrine()->getRepository('WikiTagBundle:DocumentTag')->findByDocumentExternalId($id_doc); - $nb_tags = count($tags); - $found = false; - $i = 0; - while($i<$nb_tags && $found==false){ - $dt = $tags[$i]; - if(strtolower($dt->getTag()->getLabel())==strtolower($tag_label)){ - $found = true; - } - $i++; - } - // If the label was found, we sent a bad request - if($found==true){ - //TODO : translation - return new Response(json_encode(array('error' => 'duplicate_tag', 'message' => sprintf("Le tag %s existe déjà pour cette fiche.", $tag_label))),400); - } - // returns array($tag, $revision_id, $created) - try { - $ar = $this->getDoctrine()->getRepository('WikiTagBundle:Tag')->getOrCreateTag($tag_label); + + + try + { + $this->get('wiki_tag.document')->addTag($id_doc, $tag_label); } - catch (\Exception $e){ - return new Response(json_encode(array('error' => 'wikipedia_request_failed', 'message' => $e->getMessage())),400); - } - - $tag = $ar[0]; - $revision_id = $ar[1]; - $created = $ar[2]; - - $tags = $this->getDoctrine()->getRepository('WikiTagBundle:DocumentTag')->findByDocumentExternalId($id_doc, array('tag'=>$tag->getId())); - $nb_tags = count($tags); - - if($created==true || $nb_tags==0){ - $new_order_ar = $this->getDoctrine()->getRepository('WikiTagBundle:DocumentTag')->getMaxOrder($id_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; - $new_DT = new DocumentTag(); - $new_DT->setDocument($this->getDoctrine()->getRepository('WikiTagBundle:Document')->findOneByExternalId($id_doc)); - $new_DT->setTag($tag); - $new_DT->setOriginalOrder($new_order); - $new_DT->setTagOrder($new_order); - $new_DT->setWikipediaRevisionId($revision_id); - $em->persist($new_DT); - $em->flush(); + catch (WikiTagServiceException $e) + { + return new Response(json_encode(array('error' => $e->getErrorCode(), 'message' => $e->getMessage())),$e->getCode()); } return $this->renderDocTags($id_doc, $this->getRequest()->request->get('wikitag_document_profile')); @@ -540,7 +504,7 @@ $this->updateTagWithNewLabel($moved_tag, $tag_label); } catch (\Exception $e){ - return new Response(json_encode(array('error' => 'wikipedia_request_failed', 'message' => $e->getMessage())),400); + return new Response(json_encode(array('error' => 'wikipedia_request_failed', 'message' => $e->getMessage())),500); } // We render the tag list. return $this->renderAllTags(); @@ -560,7 +524,7 @@ $this->updateTagWithNewLabel($moved_tag, $moved_tag->getOriginalLabel()); } catch (\Exception $e){ - return new Response(json_encode(array('error' => 'wikipedia_request_failed', 'message' => $e->getMessage())),400); + return new Response(json_encode(array('error' => 'wikipedia_request_failed', 'message' => $e->getMessage())),500); } // We render the tag list. @@ -580,7 +544,7 @@ $this->updateTagWithNewLabel($tag, $tag->getLabel()); } catch (\Exception $e){ - return new Response(json_encode(array('error' => 'wikipedia_request_failed', 'message' => $e->getMessage())),400); + return new Response(json_encode(array('error' => 'wikipedia_request_failed', 'message' => $e->getMessage())),500); } // We render the tag list. diff -r 10be6b9e55e7 -r 774ba82dca59 DependencyInjection/Configuration.php --- a/DependencyInjection/Configuration.php Fri Dec 09 06:43:49 2011 +0100 +++ b/DependencyInjection/Configuration.php Wed Dec 14 23:28:57 2011 +0100 @@ -25,6 +25,7 @@ $rootNode ->children() ->scalarNode('route_for_documents_by_tag')->defaultNull()->end() + ->booleanNode('ignore_wikipedia_error')->defaultFalse()->end() ->scalarNode('document_class')->isRequired()->end() ->scalarNode('document_id_column')->defaultValue('id')->end() ->end() diff -r 10be6b9e55e7 -r 774ba82dca59 DependencyInjection/WikiTagExtension.php --- a/DependencyInjection/WikiTagExtension.php Fri Dec 09 06:43:49 2011 +0100 +++ b/DependencyInjection/WikiTagExtension.php Wed Dec 14 23:28:57 2011 +0100 @@ -29,6 +29,12 @@ { $container->setParameter("wiki_tag.document_class", $config['document_class']); } + + if(isset($config['ignore_wikipedia_error'])) + { + $container->setParameter("wiki_tag.ignore_wikipedia_error", $config['ignore_wikipedia_error']); + } + if(isset($config['document_id_column'])) { diff -r 10be6b9e55e7 -r 774ba82dca59 Entity/DocumentRepository.php --- a/Entity/DocumentRepository.php Fri Dec 09 06:43:49 2011 +0100 +++ b/Entity/DocumentRepository.php Wed Dec 14 23:28:57 2011 +0100 @@ -243,7 +243,7 @@ public function getTagsStr($document) { $em = $this->getEntityManager(); - $query = $em->createQuery("SELECT t.label FROM WikiTagBundle:DocumentTag dt JOIN dt.tag t WHERE dt.document = :docid"); + $query = $em->createQuery("SELECT t.label FROM WikiTagBundle:DocumentTag dt JOIN dt.tag t WHERE dt.document = :docid ORDER BY dt.tagOrder"); $query = $query->setParameter("docid", $document); $result = $query->getScalarResult(); $tagstr = array(); @@ -253,6 +253,7 @@ return $tagstr; } + /** * Update a wikitag document tags string. * @param DocumentInterface $document the wikitag document diff -r 10be6b9e55e7 -r 774ba82dca59 Entity/TagRepository.php --- a/Entity/TagRepository.php Fri Dec 09 06:43:49 2011 +0100 +++ b/Entity/TagRepository.php Wed Dec 14 23:28:57 2011 +0100 @@ -34,6 +34,7 @@ $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),"%_"))), $qb->expr()->like('t.label',$qb->expr()->literal("% ".addcslashes(mysql_real_escape_string($seed),"%_")."%")) )); diff -r 10be6b9e55e7 -r 774ba82dca59 Listener/DocumentListener.php --- a/Listener/DocumentListener.php Fri Dec 09 06:43:49 2011 +0100 +++ b/Listener/DocumentListener.php Wed Dec 14 23:28:57 2011 +0100 @@ -19,6 +19,7 @@ use Doctrine\Common\EventSubscriber; use Doctrine\ORM\Events; use Doctrine\ORM\Event\LifecycleEventArgs; +use Doctrine\ORM\Event\OnFlushEventArgs; use Doctrine\ORM\Event\PreUpdateEventArgs; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -59,6 +60,7 @@ Events::postUpdate, Events::preRemove, Events::postRemove, + Events::onFlush, ); } @@ -70,6 +72,11 @@ $event_dispatcher->dispatch(WikiTagEvents::onTagChanged, $event); } + public function onFlush(OnFlushEventArgs $eventArgs) + { + + } + public function postPersist(LifecycleEventArgs $args) { $logger = $this->container->get('logger'); diff -r 10be6b9e55e7 -r 774ba82dca59 Model/Document.php --- a/Model/Document.php Fri Dec 09 06:43:49 2011 +0100 +++ b/Model/Document.php Wed Dec 14 23:28:57 2011 +0100 @@ -26,7 +26,7 @@ protected $manualOrder = false; /** - * @var string $externalId + * @var mixed $externalId */ protected $externalId; diff -r 10be6b9e55e7 -r 774ba82dca59 Services/DocumentService.php --- a/Services/DocumentService.php Fri Dec 09 06:43:49 2011 +0100 +++ b/Services/DocumentService.php Wed Dec 14 23:28:57 2011 +0100 @@ -9,8 +9,10 @@ */ namespace IRI\Bundle\WikiTagBundle\Services; +use IRI\Bundle\WikiTagBundle\Entity\DocumentTag; use Symfony\Component\DependencyInjection\ContainerAware; use Symfony\Component\DependencyInjection\ContainerInterface; +use IRI\Bundle\WikiTagBundle\Utils\WikiTagUtils; class DocumentService extends ContainerAware { @@ -46,6 +48,7 @@ /** * Copy the list of tags of one document to another. + * The ids are the ids of the "host" document. * * @param mixed $id_doc_src the source document id * @param mixed $id_doc_tgt the target document id @@ -77,5 +80,90 @@ } + /** + * + * Add a new tag to a "host" document. + * If the label already exists, an exception is raised. + * + * @param mixed $id_doc + * @param string|array $tag_label : the label of the new tag + */ + public function addTags($id_doc, $tag_labels) + { + // We get the DocumentTags + $em = $this->getDoctrine()->getEntityManager(); + + $need_flush = false; + + + if(!is_array($tag_labels)) { + $tag_labels = array($tag_labels); + } + + foreach ($tag_labels as $tag_label) { + + $normalized_tag_label = WikiTagUtils::normalizeTag($tag_label); + + $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"=>$id_doc, "label"=>$normalized_tag_label)); + + $nb_tags = $query->getSingleScalarResult(); + + // If the label was found, we sent a bad request + 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); + } + catch (\Exception $e){ + throw new WikiTagServiceException($e->getMessage(), 500 , $e, "wikipedia_request_failed"); + } + + $tag = $ar[0]; + $revision_id = $ar[1]; + $created = $ar[2]; + + $tags = $this->getDoctrine()->getRepository('WikiTagBundle:DocumentTag')->findByDocumentExternalId($id_doc, array('tag'=>$tag->getId())); + $nb_tags = count($tags); + + if($created==true || $nb_tags==0){ + $new_order_ar = $this->getDoctrine()->getRepository('WikiTagBundle:DocumentTag')->getMaxOrder($id_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; + $new_DT = new DocumentTag(); + $new_DT->setDocument($this->getDoctrine()->getRepository('WikiTagBundle:Document')->findOneByExternalId($id_doc)); + $new_DT->setTag($tag); + $new_DT->setOriginalOrder($new_order); + $new_DT->setTagOrder($new_order); + $new_DT->setWikipediaRevisionId($revision_id); + $em->persist($new_DT); + $need_flush = true; + + } + } + + if($need_flush) { + $em->flush(); + } + + + } + + public function getTagLabels($id_doc) + { + $rep = $this->getDoctrine()->getRepository('WikiTagBundle:Document'); + $doc = $rep->findOneByExternalId($id_doc); + + if(is_null($doc)) { + throw new WikiTagServiceException("Unknown document id"); + } + + return $rep->getTagsStr($doc); + + } + } \ No newline at end of file diff -r 10be6b9e55e7 -r 774ba82dca59 Services/WikiTagServiceException.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Services/WikiTagServiceException.php Wed Dec 14 23:28:57 2011 +0100 @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace IRI\Bundle\WikiTagBundle\Services; + +class WikiTagServiceException extends \Exception +{ + /** + * The error code + * @var string + */ + protected $error_code; + + public function __construct ($message = "", $code = 0, $previous = null, $error_code = "") + { + parent::__construct($message, $code, $previous); + $this->error_code = $error_code; + } + + public function getErrorCode() { + return $this->error_code; + } +} \ No newline at end of file diff -r 10be6b9e55e7 -r 774ba82dca59 Tests/Services/DocumentServiceTest.php --- a/Tests/Services/DocumentServiceTest.php Fri Dec 09 06:43:49 2011 +0100 +++ b/Tests/Services/DocumentServiceTest.php Wed Dec 14 23:28:57 2011 +0100 @@ -16,12 +16,15 @@ { protected $_container; + protected $_doctrine; + protected $_application; + protected $_kernel; public function __construct() { - $kernel = new \AppKernel("test", true); - $kernel->boot(); - $this->_container = $kernel->getContainer(); + $this->_kernel = new \AppKernel("test", true); + $this->_kernel->boot(); + $this->_container = $this->_kernel->getContainer(); parent::__construct(); } @@ -30,18 +33,67 @@ return $this->_container->get($service); } + protected function getDoctrine() + { + if(is_null($this->_doctrine)) + { + $this->_doctrine = $this->get('doctrine'); + } + return $this->_doctrine; + } + + + public function testGetTagLabels() + { + $doc_service = $this->get("wiki_tag.document"); + $doc1 = $this->getDoctrine()->getRepository("CompanyBaseBundle:Document")->findOneByTitle("Title 1"); + $tags = $doc_service->getTagLabels($doc1->getId()); + + $this->assertEquals(4,count($tags)); + + $this->assertEquals(array("Tag1","Tag2","Tag3","Tag4"),$tags); + + } + public function testCopyTags() { - $search_service = $this->get("wiki_tag.document"); + $doc_service = $this->get("wiki_tag.document"); + + $doc1 = $this->getDoctrine()->getRepository("CompanyBaseBundle:Document")->findOneByTitle("Title 1"); + + $this->assertEquals(4,count($doc_service->getTagLabels($doc1->getId()))); + + $doc2 = $this->getDoctrine()->getRepository("CompanyBaseBundle:Document")->findOneByTitle("Title 4"); - // TODO : get doc 1 - // TODO : get doc 2 - // call copyTags - + $this->assertEquals(0,count($doc_service->getTagLabels($doc2->getId()))); + + $doc_service->copyTags($doc1->getId(), $doc2->getId()); + + $this->assertEquals(4,count($doc_service->getTagLabels($doc2->getId()))); + $this->assertEquals(array("Tag1","Tag2","Tag3","Tag4"),$doc_service->getTagLabels($doc2->getId())); + } + public function setUp() + { + $this->_application = new \Symfony\Bundle\FrameworkBundle\Console\Application($this->_kernel); + $this->_application->setAutoExit(false); + $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")); + } + + protected function runConsole($command, Array $options = array()) + { + + $options["-e"] = "test"; + $options["-q"] = null; + $options = array_merge($options, array('command' => $command)); + return $this->_application->run(new \Symfony\Component\Console\Input\ArrayInput($options)); + } } diff -r 10be6b9e55e7 -r 774ba82dca59 Tests/Services/SearchServiceTest.php --- a/Tests/Services/SearchServiceTest.php Fri Dec 09 06:43:49 2011 +0100 +++ b/Tests/Services/SearchServiceTest.php Wed Dec 14 23:28:57 2011 +0100 @@ -48,10 +48,10 @@ $search_service = $this->get("wiki_tag.search"); - $result = $search_service->completion("fra"); + $result = $search_service->completion("tag"); $this->assertNotNull($result, "tag cloud should not be null"); - $this->assertGreaterThanOrEqual(1, count($result)); + $this->assertEquals(4, count($result)); } diff -r 10be6b9e55e7 -r 774ba82dca59 Utils/WikiTagUtils.php --- a/Utils/WikiTagUtils.php Fri Dec 09 06:43:49 2011 +0100 +++ b/Utils/WikiTagUtils.php Wed Dec 14 23:28:57 2011 +0100 @@ -49,6 +49,15 @@ */ public static function getWikipediaInfo($tag_label_normalized, $page_id=null) { + // 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){ $params['titles'] = urlencode($tag_label_normalized); @@ -60,7 +69,17 @@ return WikiTagUtils::returnNullResult(null); } - $ar = WikiTagUtils::requestWikipedia($params); + try { + $ar = WikiTagUtils::requestWikipedia($params); + } + catch(\Exception $e) { + if($ignore_wikipedia_error) { + return WikiTagUtils::returnNullResult(null); + } + else { + throw $e; + } + } $res = $ar[0]; $original_response = $res; @@ -99,7 +118,18 @@ if($status==Tag::$TAG_URL_STATUS_DICT["redirection"]) { $params['redirects'] = "true"; - $ar = WikiTagUtils::requestWikipedia($params); + try { + $ar = WikiTagUtils::requestWikipedia($params); + } + catch(\Exception $e) { + if($ignore_wikipedia_error) { + return WikiTagUtils::returnNullResult(null); + } + else { + throw $e; + } + } + $res = $ar[0]; $pages = $ar[1]; #we know that we have at least one answer @@ -144,7 +174,7 @@ 'dbpedia_uri'=>$dbpedia_uri, 'revision_id'=>$revision_id, 'response'=>$original_response); - //return $url."
RES = ".$res/*."
DUMP = ".var_dump($pages)*/."
COUNT = ".count($pages)."
page = ".var_dump($page); + return $wp_response; } @@ -172,6 +202,7 @@ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + //TODO: change curl_setopt($ch, CURLOPT_USERAGENT, 'http://www.iri.centrepompidou.fr'); curl_setopt($ch, CURLOPT_TIMEOUT_MS, 5000); $res = curl_exec($ch); @@ -180,7 +211,7 @@ curl_close($ch); if ($curl_errno > 0) { - throw new \Exception("Wikipedia request failed. cURLError #$curl_errno: $curl_error\n"); + throw new \Exception("Wikipedia request failed. cURLError #$curl_errno: $curl_error\n", $curl_errno, null); } $val = json_decode($res, true);