From 4dc872238a61f33c886c423c5812cc578b3b1cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20L=C5=93uillet?= Date: Fri, 26 Feb 2016 13:59:08 +0100 Subject: Rename CommentBundle with AnnotationBundle --- .../Controller/WallabagAnnotationController.php | 146 +++++++++++ .../DataFixtures/ORM/LoadAnnotationData.php | 45 ++++ .../DependencyInjection/Configuration.php | 20 ++ .../WallabagAnnotationExtension.php | 18 ++ .../AnnotationBundle/Entity/Annotation.php | 270 +++++++++++++++++++++ .../Repository/AnnotationRepository.php | 91 +++++++ .../Resources/config/routing_annotations.yml | 4 + .../Tests/Controller/AnnotationControllerTest.php | 81 +++++++ .../Tests/WallabagAnnotationTestCase.php | 63 +++++ .../AnnotationBundle/WallabagAnnotationBundle.php | 9 + 10 files changed, 747 insertions(+) create mode 100644 src/Wallabag/AnnotationBundle/Controller/WallabagAnnotationController.php create mode 100644 src/Wallabag/AnnotationBundle/DataFixtures/ORM/LoadAnnotationData.php create mode 100644 src/Wallabag/AnnotationBundle/DependencyInjection/Configuration.php create mode 100644 src/Wallabag/AnnotationBundle/DependencyInjection/WallabagAnnotationExtension.php create mode 100644 src/Wallabag/AnnotationBundle/Entity/Annotation.php create mode 100644 src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php create mode 100644 src/Wallabag/AnnotationBundle/Resources/config/routing_annotations.yml create mode 100644 src/Wallabag/AnnotationBundle/Tests/Controller/AnnotationControllerTest.php create mode 100644 src/Wallabag/AnnotationBundle/Tests/WallabagAnnotationTestCase.php create mode 100644 src/Wallabag/AnnotationBundle/WallabagAnnotationBundle.php (limited to 'src/Wallabag/AnnotationBundle') diff --git a/src/Wallabag/AnnotationBundle/Controller/WallabagAnnotationController.php b/src/Wallabag/AnnotationBundle/Controller/WallabagAnnotationController.php new file mode 100644 index 00000000..5f981eb5 --- /dev/null +++ b/src/Wallabag/AnnotationBundle/Controller/WallabagAnnotationController.php @@ -0,0 +1,146 @@ +getDoctrine() + ->getRepository('WallabagAnnotationBundle:Annotation') + ->findAnnotationsByPageId($entry->getId(), $this->getUser()->getId()); + $total = count($annotationRows); + $annotations = array('total' => $total, 'rows' => $annotationRows); + + $json = $this->get('serializer')->serialize($annotations, 'json'); + + return $this->renderJsonResponse($json); + } + + /** + * Creates a new annotation. + * + * @param Entry $entry + * + * @ApiDoc( + * requirements={ + * {"name"="ranges", "dataType"="array", "requirement"="\w+", "description"="The range array for the annotation"}, + * {"name"="quote", "dataType"="string", "required"=false, "description"="Optional, quote for the annotation"}, + * {"name"="text", "dataType"="string", "required"=true, "description"=""}, + * } + * ) + * + * @return Response + */ + public function postAnnotationAction(Request $request, Entry $entry) + { + $data = json_decode($request->getContent(), true); + + $em = $this->getDoctrine()->getManager(); + + $annotation = new Annotation($this->getUser()); + + $annotation->setText($data['text']); + if (array_key_exists('quote', $data)) { + $annotation->setQuote($data['quote']); + } + if (array_key_exists('ranges', $data)) { + $annotation->setRanges($data['ranges']); + } + + $annotation->setEntry($entry); + + $em->persist($annotation); + $em->flush(); + + $json = $this->get('serializer')->serialize($annotation, 'json'); + + return $this->renderJsonResponse($json); + } + + /** + * Updates an annotation. + * + * @ApiDoc( + * requirements={ + * {"name"="annotation", "dataType"="string", "requirement"="\w+", "description"="The annotation ID"} + * } + * ) + * + * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation") + * + * @return Response + */ + public function putAnnotationAction(Annotation $annotation, Request $request) + { + $data = json_decode($request->getContent(), true); + + if (!is_null($data['text'])) { + $annotation->setText($data['text']); + } + + $em = $this->getDoctrine()->getManager(); + $em->flush(); + + $json = $this->get('serializer')->serialize($annotation, 'json'); + + return $this->renderJsonResponse($json); + } + + /** + * Removes an annotation. + * + * @ApiDoc( + * requirements={ + * {"name"="annotation", "dataType"="string", "requirement"="\w+", "description"="The annotation ID"} + * } + * ) + * + * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation") + * + * @return Response + */ + public function deleteAnnotationAction(Annotation $annotation) + { + $em = $this->getDoctrine()->getManager(); + $em->remove($annotation); + $em->flush(); + + $json = $this->get('serializer')->serialize($annotation, 'json'); + + return $this->renderJsonResponse($json); + } + + /** + * Send a JSON Response. + * We don't use the Symfony JsonRespone, because it takes an array as parameter instead of a JSON string. + * + * @param string $json + * + * @return Response + */ + private function renderJsonResponse($json, $code = 200) + { + return new Response($json, $code, array('application/json')); + } +} diff --git a/src/Wallabag/AnnotationBundle/DataFixtures/ORM/LoadAnnotationData.php b/src/Wallabag/AnnotationBundle/DataFixtures/ORM/LoadAnnotationData.php new file mode 100644 index 00000000..20e07fa3 --- /dev/null +++ b/src/Wallabag/AnnotationBundle/DataFixtures/ORM/LoadAnnotationData.php @@ -0,0 +1,45 @@ +getReference('admin-user')); + $annotation1->setEntry($this->getReference('entry1')); + $annotation1->setText('This is my annotation /o/'); + $annotation1->setQuote('content'); + + $manager->persist($annotation1); + + $this->addReference('annotation1', $annotation1); + + $annotation2 = new Annotation($this->getReference('admin-user')); + $annotation2->setEntry($this->getReference('entry2')); + $annotation2->setText('This is my 2nd annotation /o/'); + $annotation2->setQuote('content'); + + $manager->persist($annotation2); + + $this->addReference('annotation2', $annotation2); + + $manager->flush(); + } + + /** + * {@inheritdoc} + */ + public function getOrder() + { + return 35; + } +} diff --git a/src/Wallabag/AnnotationBundle/DependencyInjection/Configuration.php b/src/Wallabag/AnnotationBundle/DependencyInjection/Configuration.php new file mode 100644 index 00000000..5e4e4e9c --- /dev/null +++ b/src/Wallabag/AnnotationBundle/DependencyInjection/Configuration.php @@ -0,0 +1,20 @@ +root('wallabag_annotation'); + + return $treeBuilder; + } +} diff --git a/src/Wallabag/AnnotationBundle/DependencyInjection/WallabagAnnotationExtension.php b/src/Wallabag/AnnotationBundle/DependencyInjection/WallabagAnnotationExtension.php new file mode 100644 index 00000000..159576d6 --- /dev/null +++ b/src/Wallabag/AnnotationBundle/DependencyInjection/WallabagAnnotationExtension.php @@ -0,0 +1,18 @@ +processConfiguration($configuration, $configs); + } +} diff --git a/src/Wallabag/AnnotationBundle/Entity/Annotation.php b/src/Wallabag/AnnotationBundle/Entity/Annotation.php new file mode 100644 index 00000000..db9590b0 --- /dev/null +++ b/src/Wallabag/AnnotationBundle/Entity/Annotation.php @@ -0,0 +1,270 @@ +user = $user; + } + + /** + * Get id. + * + * @return int + */ + public function getId() + { + return $this->id; + } + + /** + * Set text. + * + * @param string $text + * + * @return Annotation + */ + public function setText($text) + { + $this->text = $text; + + return $this; + } + + /** + * Get text. + * + * @return string + */ + public function getText() + { + return $this->text; + } + + /** + * @ORM\PrePersist + * @ORM\PreUpdate + */ + public function timestamps() + { + if (is_null($this->createdAt)) { + $this->createdAt = new \DateTime(); + } + $this->updatedAt = new \DateTime(); + } + + /** + * Get created. + * + * @return \DateTime + */ + public function getCreatedAt() + { + return $this->createdAt; + } + + /** + * Get updated. + * + * @return \DateTime + */ + public function getUpdatedAt() + { + return $this->updatedAt; + } + + /** + * Get quote. + * + * @return string + */ + public function getQuote() + { + return $this->quote; + } + + /** + * Set quote. + * + * @param string $quote + * + * @return Annotation + */ + public function setQuote($quote) + { + $this->quote = $quote; + + return $this; + } + + /** + * Get ranges. + * + * @return array + */ + public function getRanges() + { + return $this->ranges; + } + + /** + * Set ranges. + * + * @param array $ranges + * + * @return Annotation + */ + public function setRanges($ranges) + { + $this->ranges = $ranges; + + return $this; + } + + /** + * Set user. + * + * @param string $user + * + * @return Annotation + */ + public function setUser($user) + { + $this->user = $user; + + return $this; + } + + /** + * Get user. + * + * @return string + */ + public function getUser() + { + return $this->user; + } + + /** + * @VirtualProperty + * @SerializedName("user") + */ + public function getUserName() + { + return $this->user->getName(); + } + + /** + * Set entry. + * + * @param Entry $entry + * + * @return Annotation + */ + public function setEntry($entry) + { + $this->entry = $entry; + $entry->setAnnotation($this); + + return $this; + } + + /** + * Get entry. + * + * @return Entry + */ + public function getEntry() + { + return $this->entry; + } + + /** + * @VirtualProperty + * @SerializedName("annotator_schema_version") + */ + public function getVersion() + { + return 'v1.0'; + } +} diff --git a/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php b/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php new file mode 100644 index 00000000..c1c6e638 --- /dev/null +++ b/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php @@ -0,0 +1,91 @@ +createQueryBuilder('a') + ->leftJoin('a.user', 'u') + ->andWhere('u.id = :userId')->setParameter('userId', $userId) + ->orderBy('a.id', 'desc') + ; + } + + /** + * Retrieves all annotations for a user. + * + * @param int $userId + * + * @return QueryBuilder + */ + public function getBuilderForAllByUser($userId) + { + return $this + ->getBuilderByUser($userId) + ; + } + + /** + * Get annotation for this id. + * + * @param int $annotationId + * + * @return array + */ + public function findAnnotationById($annotationId) + { + return $this->createQueryBuilder('a') + ->andWhere('a.id = :annotationId')->setParameter('annotationId', $annotationId) + ->getQuery()->getSingleResult() + ; + } + + /** + * Find annotations for entry id. + * + * @param int $entryId + * @param int $userId + * + * @return array + */ + public function findAnnotationsByPageId($entryId, $userId) + { + return $this->createQueryBuilder('a') + ->where('a.entry = :entryId')->setParameter('entryId', $entryId) + ->andwhere('a.user = :userId')->setParameter('userId', $userId) + ->getQuery()->getResult() + ; + } + + /** + * Find last annotation for a given entry id. Used only for tests. + * + * @param int $entryId + * + * @return array + */ + public function findLastAnnotationByPageId($entryId, $userId) + { + return $this->createQueryBuilder('a') + ->where('a.entry = :entryId')->setParameter('entryId', $entryId) + ->andwhere('a.user = :userId')->setParameter('userId', $userId) + ->orderBy('a.id', 'DESC') + ->setMaxResults(1) + ->getQuery() + ->getOneOrNullResult(); + } +} diff --git a/src/Wallabag/AnnotationBundle/Resources/config/routing_annotations.yml b/src/Wallabag/AnnotationBundle/Resources/config/routing_annotations.yml new file mode 100644 index 00000000..4f3a5c93 --- /dev/null +++ b/src/Wallabag/AnnotationBundle/Resources/config/routing_annotations.yml @@ -0,0 +1,4 @@ +annotations: + type: rest + resource: "WallabagAnnotationBundle:WallabagAnnotation" + name_prefix: annotations_ diff --git a/src/Wallabag/AnnotationBundle/Tests/Controller/AnnotationControllerTest.php b/src/Wallabag/AnnotationBundle/Tests/Controller/AnnotationControllerTest.php new file mode 100644 index 00000000..c0efe272 --- /dev/null +++ b/src/Wallabag/AnnotationBundle/Tests/Controller/AnnotationControllerTest.php @@ -0,0 +1,81 @@ +client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagAnnotationBundle:Annotation') + ->findOneBy(array('user' => 1)); + + if (!$annotation) { + $this->markTestSkipped('No content found in db.'); + } + $this->logInAs('admin'); + $crawler = $this->client->request('GET', 'annotations/'.$annotation->getEntry()->getId().'.json'); + $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); + + $content = json_decode($this->client->getResponse()->getContent(), true); + $this->assertEquals(1, $content['total']); + $this->assertEquals($annotation->getText(), $content['rows'][0]['text']); + } + + public function testSetAnnotation() + { + $this->logInAs('admin'); + + $entry = $this->client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->findOneBy(array('user' => 1)); + + $headers = array('CONTENT_TYPE' => 'application/json'); + $content = json_encode(array( + 'text' => 'my annotation', + 'quote' => 'my quote', + 'range' => '[{"start":"","startOffset":24,"end":"","endOffset":31}]', + )); + $crawler = $this->client->request('POST', 'annotations/'.$entry->getId().'.json', array(), array(), $headers, $content); + + $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); + + $annotation = $this->client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagAnnotationBundle:Annotation') + ->findLastAnnotationByPageId($entry->getId(), 1); + + $this->assertEquals('my annotation', $annotation->getText()); + } + + public function testEditAnnotation() + { + $annotation = $this->client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagAnnotationBundle:Annotation') + ->findOneBy(array('user' => 1)); + + $this->logInAs('admin'); + + $headers = array('CONTENT_TYPE' => 'application/json'); + $content = json_encode(array( + 'text' => 'a modified annotation', + )); + $crawler = $this->client->request('PUT', 'annotations/'.$annotation->getId().'.json', array(), array(), $headers, $content); + $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); + + $content = json_decode($this->client->getResponse()->getContent(), true); + + $this->assertEquals('a modified annotation', $content['text']); + + $annotationUpdated = $this->client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagAnnotationBundle:Annotation') + ->findAnnotationById($annotation->getId()); + $this->assertEquals('a modified annotation', $annotationUpdated->getText()); + } +} diff --git a/src/Wallabag/AnnotationBundle/Tests/WallabagAnnotationTestCase.php b/src/Wallabag/AnnotationBundle/Tests/WallabagAnnotationTestCase.php new file mode 100644 index 00000000..2deff6bf --- /dev/null +++ b/src/Wallabag/AnnotationBundle/Tests/WallabagAnnotationTestCase.php @@ -0,0 +1,63 @@ +client = $this->createAuthorizedClient(); + } + + public function logInAs($username) + { + $crawler = $this->client->request('GET', '/login'); + $form = $crawler->filter('button[type=submit]')->form(); + $data = array( + '_username' => $username, + '_password' => 'mypassword', + ); + + $this->client->submit($form, $data); + } + + /** + * @return Client + */ + protected function createAuthorizedClient() + { + $client = static::createClient(); + $container = $client->getContainer(); + + /** @var $userManager \FOS\UserBundle\Doctrine\UserManager */ + $userManager = $container->get('fos_user.user_manager'); + /** @var $loginManager \FOS\UserBundle\Security\LoginManager */ + $loginManager = $container->get('fos_user.security.login_manager'); + $firewallName = $container->getParameter('fos_user.firewall_name'); + + $this->user = $userManager->findUserBy(array('username' => 'admin')); + $loginManager->loginUser($firewallName, $this->user); + + // save the login token into the session and put it in a cookie + $container->get('session')->set('_security_'.$firewallName, serialize($container->get('security.token_storage')->getToken())); + $container->get('session')->save(); + + $session = $container->get('session'); + $client->getCookieJar()->set(new Cookie($session->getName(), $session->getId())); + + return $client; + } +} diff --git a/src/Wallabag/AnnotationBundle/WallabagAnnotationBundle.php b/src/Wallabag/AnnotationBundle/WallabagAnnotationBundle.php new file mode 100644 index 00000000..b64920a3 --- /dev/null +++ b/src/Wallabag/AnnotationBundle/WallabagAnnotationBundle.php @@ -0,0 +1,9 @@ +