From fc73222723c7a0c9b577805d3ef51eb96b124b92 Mon Sep 17 00:00:00 2001 From: Jeremy Benoist Date: Tue, 29 Dec 2015 14:50:52 +0100 Subject: Remove user reference in tag Fix #1543 --- .../Controller/WallabagRestController.php | 17 ++++++--- .../Controller/WallabagRestControllerTest.php | 3 +- .../CoreBundle/Controller/TagController.php | 12 +++---- .../CoreBundle/DataFixtures/ORM/LoadEntryData.php | 19 +++------- .../CoreBundle/DataFixtures/ORM/LoadTagData.php | 41 ++++++++++++++++++++++ src/Wallabag/CoreBundle/Entity/Entry.php | 2 +- src/Wallabag/CoreBundle/Entity/Tag.php | 17 ++------- src/Wallabag/CoreBundle/Helper/RuleBasedTagger.php | 13 ++++--- .../CoreBundle/Repository/EntryRepository.php | 19 ++++++++++ .../CoreBundle/Repository/TagRepository.php | 36 ++++++++++++------- .../Tests/Controller/ConfigControllerTest.php | 4 +-- .../Tests/Helper/RuleBasedTaggerTest.php | 12 +++---- src/Wallabag/UserBundle/Entity/User.php | 27 -------------- 13 files changed, 123 insertions(+), 99 deletions(-) create mode 100644 src/Wallabag/CoreBundle/DataFixtures/ORM/LoadTagData.php diff --git a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php index 74bfe4dc..587013f6 100644 --- a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php +++ b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php @@ -27,7 +27,7 @@ class WallabagRestController extends FOSRestController ->findOneByLabel($label); if (is_null($tagEntity)) { - $tagEntity = new Tag($this->getUser()); + $tagEntity = new Tag(); $tagEntity->setLabel($label); } @@ -74,8 +74,7 @@ class WallabagRestController extends FOSRestController $perPage = (int) $request->query->get('perPage', 30); $tags = $request->query->get('tags', []); - $pager = $this - ->getDoctrine() + $pager = $this->getDoctrine() ->getRepository('WallabagCoreBundle:Entry') ->findEntries($this->getUser()->getId(), $isArchived, $isStarred, $sort, $order); @@ -311,7 +310,12 @@ class WallabagRestController extends FOSRestController public function getTagsAction() { $this->validateAuthentication(); - $json = $this->get('serializer')->serialize($this->getUser()->getTags(), 'json'); + + $tags = $this->getDoctrine() + ->getRepository('WallabagCoreBundle:Tag') + ->findAllTags($this->getUser()->getId()); + + $json = $this->get('serializer')->serialize($tags, 'json'); return $this->renderJsonResponse($json); } @@ -328,7 +332,10 @@ class WallabagRestController extends FOSRestController public function deleteTagAction(Tag $tag) { $this->validateAuthentication(); - $this->validateUserAccess($tag->getUser()->getId()); + + $this->getDoctrine() + ->getRepository('WallabagCoreBundle:Entry') + ->removeTag($this->getUser()->getId(), $tag); $em = $this->getDoctrine()->getManager(); $em->remove($tag); diff --git a/src/Wallabag/ApiBundle/Tests/Controller/WallabagRestControllerTest.php b/src/Wallabag/ApiBundle/Tests/Controller/WallabagRestControllerTest.php index bdd36e0c..a7120e83 100644 --- a/src/Wallabag/ApiBundle/Tests/Controller/WallabagRestControllerTest.php +++ b/src/Wallabag/ApiBundle/Tests/Controller/WallabagRestControllerTest.php @@ -208,7 +208,7 @@ class WallabagRestControllerTest extends WallabagApiTestCase $tags = array(); foreach ($entry->getTags() as $tag) { - $tags[] = array('id' => $tag->getId(), 'label' => $tag->getLabel()); + $tags[] = array('id' => $tag->getId(), 'label' => $tag->getLabel(), 'slug' => $tag->getSlug()); } $this->client->request('GET', '/api/entries/'.$entry->getId().'/tags'); @@ -309,5 +309,6 @@ class WallabagRestControllerTest extends WallabagApiTestCase $this->assertArrayHasKey('label', $content); $this->assertEquals($tag['label'], $content['label']); + $this->assertEquals($tag['slug'], $content['slug']); } } diff --git a/src/Wallabag/CoreBundle/Controller/TagController.php b/src/Wallabag/CoreBundle/Controller/TagController.php index fd2069e0..64d53f0c 100644 --- a/src/Wallabag/CoreBundle/Controller/TagController.php +++ b/src/Wallabag/CoreBundle/Controller/TagController.php @@ -20,25 +20,23 @@ class TagController extends Controller */ public function addTagFormAction(Request $request, Entry $entry) { - $tag = new Tag($this->getUser()); + $tag = new Tag(); $form = $this->createForm(new NewTagType(), $tag); $form->handleRequest($request); if ($form->isValid()) { $existingTag = $this->getDoctrine() ->getRepository('WallabagCoreBundle:Tag') - ->findOneByLabelAndUserId($tag->getLabel(), $this->getUser()->getId()); + ->findOneByLabel($tag->getLabel()); $em = $this->getDoctrine()->getManager(); if (is_null($existingTag)) { $entry->addTag($tag); $em->persist($tag); - } else { - if (!$existingTag->hasEntry($entry)) { - $entry->addTag($existingTag); - $em->persist($existingTag); - } + } elseif (!$existingTag->hasEntry($entry)) { + $entry->addTag($existingTag); + $em->persist($existingTag); } $em->flush(); diff --git a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadEntryData.php b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadEntryData.php index 0513cdb8..6c6a331a 100644 --- a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadEntryData.php +++ b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadEntryData.php @@ -6,7 +6,6 @@ use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Common\DataFixtures\OrderedFixtureInterface; use Doctrine\Common\Persistence\ObjectManager; use Wallabag\CoreBundle\Entity\Entry; -use Wallabag\CoreBundle\Entity\Tag; class LoadEntryData extends AbstractFixture implements OrderedFixtureInterface { @@ -50,13 +49,8 @@ class LoadEntryData extends AbstractFixture implements OrderedFixtureInterface $entry3->setContent('This is my content /o/'); $entry3->setLanguage('en'); - $tag1 = new Tag($this->getReference('bob-user')); - $tag1->setLabel('foo'); - $tag2 = new Tag($this->getReference('bob-user')); - $tag2->setLabel('bar'); - - $entry3->addTag($tag1); - $entry3->addTag($tag2); + $entry3->addTag($this->getReference('foo-tag')); + $entry3->addTag($this->getReference('bar-tag')); $manager->persist($entry3); @@ -71,13 +65,8 @@ class LoadEntryData extends AbstractFixture implements OrderedFixtureInterface $entry4->setContent('This is my content /o/'); $entry4->setLanguage('en'); - $tag1 = new Tag($this->getReference('admin-user')); - $tag1->setLabel('foo'); - $tag2 = new Tag($this->getReference('admin-user')); - $tag2->setLabel('bar'); - - $entry4->addTag($tag1); - $entry4->addTag($tag2); + $entry4->addTag($this->getReference('foo-tag')); + $entry4->addTag($this->getReference('bar-tag')); $manager->persist($entry4); diff --git a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadTagData.php b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadTagData.php new file mode 100644 index 00000000..8553dced --- /dev/null +++ b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadTagData.php @@ -0,0 +1,41 @@ +setLabel('foo'); + + $manager->persist($tag1); + + $this->addReference('foo-tag', $tag1); + + $tag2 = new Tag(); + $tag2->setLabel('bar'); + + $manager->persist($tag2); + + $this->addReference('bar-tag', $tag2); + + $manager->flush(); + } + + /** + * {@inheritdoc} + */ + public function getOrder() + { + return 25; + } +} diff --git a/src/Wallabag/CoreBundle/Entity/Entry.php b/src/Wallabag/CoreBundle/Entity/Entry.php index 2813c944..b413c489 100644 --- a/src/Wallabag/CoreBundle/Entity/Entry.php +++ b/src/Wallabag/CoreBundle/Entity/Entry.php @@ -465,7 +465,7 @@ class Entry // check if tag already exist but has not yet be persisted // it seems that the previous condition with `contains()` doesn't check that case foreach ($this->tags as $existingTag) { - if ($existingTag->getUser() !== $tag->getUser() || $existingTag->getLabel() === $tag->getLabel()) { + if ($existingTag->getLabel() === $tag->getLabel()) { return; } } diff --git a/src/Wallabag/CoreBundle/Entity/Tag.php b/src/Wallabag/CoreBundle/Entity/Tag.php index 4ed588be..0689c7b3 100644 --- a/src/Wallabag/CoreBundle/Entity/Tag.php +++ b/src/Wallabag/CoreBundle/Entity/Tag.php @@ -38,6 +38,7 @@ class Tag private $label; /** + * @Expose * @Gedmo\Slug(fields={"label"}) * @ORM\Column(length=128, unique=true) */ @@ -48,14 +49,8 @@ class Tag */ private $entries; - /** - * @ORM\ManyToOne(targetEntity="Wallabag\UserBundle\Entity\User", inversedBy="tags") - */ - private $user; - - public function __construct(\Wallabag\UserBundle\Entity\User $user) + public function __construct() { - $this->user = $user; $this->entries = new ArrayCollection(); } @@ -112,12 +107,4 @@ class Tag { return $this->entries->contains($entry); } - - /** - * @return User - */ - public function getUser() - { - return $this->user; - } } diff --git a/src/Wallabag/CoreBundle/Helper/RuleBasedTagger.php b/src/Wallabag/CoreBundle/Helper/RuleBasedTagger.php index 41ef25b8..991c9a56 100644 --- a/src/Wallabag/CoreBundle/Helper/RuleBasedTagger.php +++ b/src/Wallabag/CoreBundle/Helper/RuleBasedTagger.php @@ -37,7 +37,7 @@ class RuleBasedTagger } foreach ($rule->getTags() as $label) { - $tag = $this->getTag($entry->getUser(), $label); + $tag = $this->getTag($label); $entry->addTag($tag); } @@ -62,7 +62,7 @@ class RuleBasedTagger foreach ($entries as $entry) { foreach ($rule->getTags() as $label) { - $tag = $this->getTag($user, $label); + $tag = $this->getTag($label); $entry->addTag($tag); } @@ -73,19 +73,18 @@ class RuleBasedTagger } /** - * Fetch a tag for a user. + * Fetch a tag. * - * @param User $user * @param string $label The tag's label. * * @return Tag */ - private function getTag(User $user, $label) + private function getTag($label) { - $tag = $this->tagRepository->findOneByLabelAndUserId($label, $user->getId()); + $tag = $this->tagRepository->findOneByLabel($label); if (!$tag) { - $tag = new Tag($user); + $tag = new Tag(); $tag->setLabel($label); } diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php index 57bf8024..9ff80d6e 100644 --- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php +++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php @@ -5,6 +5,7 @@ namespace Wallabag\CoreBundle\Repository; use Doctrine\ORM\EntityRepository; use Pagerfanta\Adapter\DoctrineORMAdapter; use Pagerfanta\Pagerfanta; +use Wallabag\CoreBundle\Entity\Tag; class EntryRepository extends EntityRepository { @@ -179,4 +180,22 @@ class EntryRepository extends EntityRepository ->getQuery() ->getSingleResult(); } + + /** + * Remove a tag from all user entries. + * We are using a native SQL query because Doctrine doesn't know EntryTag entity because it's a ManyToMany relation. + * Instead of that SQL query we should loop on every entry and remove the tag, could be really long ... + * + * @param int $userId + * @param Tag $tag + */ + public function removeTag($userId, Tag $tag) + { + $sql = 'DELETE et FROM entry_tag et WHERE et.entry_id IN ( SELECT e.id FROM entry e WHERE e.user_id = :userId ) AND et.tag_id = :tagId'; + $stmt = $this->getEntityManager()->getConnection()->prepare($sql); + $stmt->execute([ + 'userId' => $userId, + 'tagId' => $tag->getId(), + ]); + } } diff --git a/src/Wallabag/CoreBundle/Repository/TagRepository.php b/src/Wallabag/CoreBundle/Repository/TagRepository.php index ac3145a1..c4aeb594 100644 --- a/src/Wallabag/CoreBundle/Repository/TagRepository.php +++ b/src/Wallabag/CoreBundle/Repository/TagRepository.php @@ -9,16 +9,29 @@ use Pagerfanta\Pagerfanta; class TagRepository extends EntityRepository { /** - * Find Tags. + * Return only the QueryBuilder to retrieve all tags for a given user. * * @param int $userId * - * @return array + * @return QueryBuilder + */ + private function getQbForAllTags($userId) + { + return $this->createQueryBuilder('t') + ->leftJoin('t.entries', 'e') + ->where('e.user = :userId')->setParameter('userId', $userId); + } + + /** + * Find Tags and return a Pager. + * + * @param int $userId + * + * @return Pagerfanta */ public function findTags($userId) { - $qb = $this->createQueryBuilder('t') - ->where('t.user =:userId')->setParameter('userId', $userId); + $qb = $this->getQbForAllTags($userId); $pagerAdapter = new DoctrineORMAdapter($qb); @@ -26,19 +39,16 @@ class TagRepository extends EntityRepository } /** - * Find a tag by its label and its owner. + * Find Tags. * - * @param string $label - * @param int $userId + * @param int $userId * - * @return Tag|null + * @return array */ - public function findOneByLabelAndUserId($label, $userId) + public function findAllTags($userId) { - return $this->createQueryBuilder('t') - ->where('t.label = :label')->setParameter('label', $label) - ->andWhere('t.user = :user_id')->setParameter('user_id', $userId) + return $this->getQbForAllTags($userId) ->getQuery() - ->getOneOrNullResult(); + ->getResult(); } } diff --git a/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php index 7b32354f..89ca31e2 100644 --- a/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php +++ b/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php @@ -44,7 +44,7 @@ class ConfigControllerTest extends WallabagCoreTestCase $form = $crawler->filter('button[id=config_save]')->form(); $data = array( - 'config[theme]' => 0, + 'config[theme]' => 'baggy', 'config[items_per_page]' => '30', 'config[language]' => 'en', ); @@ -63,7 +63,7 @@ class ConfigControllerTest extends WallabagCoreTestCase { return array( array(array( - 'config[theme]' => 0, + 'config[theme]' => 'baggy', 'config[items_per_page]' => '', 'config[language]' => 'en', )), diff --git a/src/Wallabag/CoreBundle/Tests/Helper/RuleBasedTaggerTest.php b/src/Wallabag/CoreBundle/Tests/Helper/RuleBasedTaggerTest.php index 1de134b8..cddc8b08 100644 --- a/src/Wallabag/CoreBundle/Tests/Helper/RuleBasedTaggerTest.php +++ b/src/Wallabag/CoreBundle/Tests/Helper/RuleBasedTaggerTest.php @@ -69,9 +69,7 @@ class RuleBasedTaggerTest extends \PHPUnit_Framework_TestCase $tags = $entry->getTags(); $this->assertSame('foo', $tags[0]->getLabel()); - $this->assertSame($user, $tags[0]->getUser()); $this->assertSame('bar', $tags[1]->getLabel()); - $this->assertSame($user, $tags[1]->getUser()); } public function testTagWithAMixOfMatchingRules() @@ -92,7 +90,6 @@ class RuleBasedTaggerTest extends \PHPUnit_Framework_TestCase $tags = $entry->getTags(); $this->assertSame('foo', $tags[0]->getLabel()); - $this->assertSame($user, $tags[0]->getUser()); } public function testWhenTheTagExists() @@ -100,7 +97,8 @@ class RuleBasedTaggerTest extends \PHPUnit_Framework_TestCase $taggingRule = $this->getTaggingRule('rule as string', array('foo')); $user = $this->getUser([$taggingRule]); $entry = new Entry($user); - $tag = new Tag($user); + $tag = new Tag(); + $tag->setLabel('foo'); $this->rulerz ->expects($this->once()) @@ -110,7 +108,9 @@ class RuleBasedTaggerTest extends \PHPUnit_Framework_TestCase $this->tagRepository ->expects($this->once()) - ->method('findOneByLabelAndUserId') + // the method `findOneByLabel` doesn't exist, EntityRepository will then call `_call` method + // to magically call the `findOneBy` with ['label' => 'foo'] + ->method('__call') ->willReturn($tag); $this->tagger->tag($entry); @@ -118,7 +118,7 @@ class RuleBasedTaggerTest extends \PHPUnit_Framework_TestCase $this->assertFalse($entry->getTags()->isEmpty()); $tags = $entry->getTags(); - $this->assertSame($tag, $tags[0]); + $this->assertSame($tag->getLabel(), $tags[0]->getLabel()); } public function testSameTagWithDifferentfMatchingRules() diff --git a/src/Wallabag/UserBundle/Entity/User.php b/src/Wallabag/UserBundle/Entity/User.php index e3b9a519..e6528420 100644 --- a/src/Wallabag/UserBundle/Entity/User.php +++ b/src/Wallabag/UserBundle/Entity/User.php @@ -13,7 +13,6 @@ use JMS\Serializer\Annotation\Expose; use FOS\UserBundle\Model\User as BaseUser; use Wallabag\CoreBundle\Entity\Config; use Wallabag\CoreBundle\Entity\Entry; -use Wallabag\CoreBundle\Entity\Tag; /** * User. @@ -69,11 +68,6 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf */ protected $config; - /** - * @ORM\OneToMany(targetEntity="Wallabag\CoreBundle\Entity\Tag", mappedBy="user", cascade={"remove"}) - */ - protected $tags; - /** * @ORM\Column(type="integer", nullable=true) */ @@ -94,7 +88,6 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf { parent::__construct(); $this->entries = new ArrayCollection(); - $this->tags = new ArrayCollection(); $this->roles = array('ROLE_USER'); } @@ -171,26 +164,6 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf return $this->entries; } - /** - * @param Entry $entry - * - * @return User - */ - public function addTag(Tag $tag) - { - $this->tags[] = $tag; - - return $this; - } - - /** - * @return ArrayCollection - */ - public function getTags() - { - return $this->tags; - } - public function isEqualTo(UserInterface $user) { return $this->username === $user->getUsername(); -- cgit v1.2.3 From 01fddd0cb2fc6c83998a54d24d4ca6a27b564d36 Mon Sep 17 00:00:00 2001 From: Jeremy Benoist Date: Tue, 29 Dec 2015 14:54:55 +0100 Subject: Fix parameters regarding documentation Parameters are `star` & `archived`, not `is_starred` & `is_archived` --- src/Wallabag/ApiBundle/Controller/WallabagRestController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php index 587013f6..c5df1e03 100644 --- a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php +++ b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php @@ -174,8 +174,8 @@ class WallabagRestController extends FOSRestController $this->validateUserAccess($entry->getUser()->getId()); $title = $request->request->get('title'); - $isArchived = $request->request->get('is_archived'); - $isStarred = $request->request->get('is_starred'); + $isArchived = $request->request->get('archive'); + $isStarred = $request->request->get('star'); if (!is_null($title)) { $entry->setTitle($title); -- cgit v1.2.3 From 1bb1939ab76cfbf1cdb5fa1dccbdd15ba17cdfb0 Mon Sep 17 00:00:00 2001 From: Jeremy Benoist Date: Tue, 29 Dec 2015 15:04:46 +0100 Subject: Cleanup tests - WallabagRestController: remove the tag deletion from the API since we can't remove a tag now, we only remove reference to entries - RuleBasedTaggerTest: remove workaround for asserting tag are equal since problem was related to mock expects (_call instead of findOneByLabel which was removed from the tag repository) --- src/Wallabag/ApiBundle/Controller/WallabagRestController.php | 4 ---- src/Wallabag/CoreBundle/Tests/Helper/RuleBasedTaggerTest.php | 3 +-- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php index c5df1e03..459c4172 100644 --- a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php +++ b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php @@ -337,10 +337,6 @@ class WallabagRestController extends FOSRestController ->getRepository('WallabagCoreBundle:Entry') ->removeTag($this->getUser()->getId(), $tag); - $em = $this->getDoctrine()->getManager(); - $em->remove($tag); - $em->flush(); - $json = $this->get('serializer')->serialize($tag, 'json'); return $this->renderJsonResponse($json); diff --git a/src/Wallabag/CoreBundle/Tests/Helper/RuleBasedTaggerTest.php b/src/Wallabag/CoreBundle/Tests/Helper/RuleBasedTaggerTest.php index cddc8b08..dee17d65 100644 --- a/src/Wallabag/CoreBundle/Tests/Helper/RuleBasedTaggerTest.php +++ b/src/Wallabag/CoreBundle/Tests/Helper/RuleBasedTaggerTest.php @@ -98,7 +98,6 @@ class RuleBasedTaggerTest extends \PHPUnit_Framework_TestCase $user = $this->getUser([$taggingRule]); $entry = new Entry($user); $tag = new Tag(); - $tag->setLabel('foo'); $this->rulerz ->expects($this->once()) @@ -118,7 +117,7 @@ class RuleBasedTaggerTest extends \PHPUnit_Framework_TestCase $this->assertFalse($entry->getTags()->isEmpty()); $tags = $entry->getTags(); - $this->assertSame($tag->getLabel(), $tags[0]->getLabel()); + $this->assertSame($tag, $tags[0]); } public function testSameTagWithDifferentfMatchingRules() -- cgit v1.2.3 From 4059a061c0c8cc787f71e96aef2ab01599d3241d Mon Sep 17 00:00:00 2001 From: Jeremy Benoist Date: Tue, 29 Dec 2015 15:08:33 +0100 Subject: Fix the way to remove a tag from all user entries --- .../Controller/WallabagRestControllerTest.php | 7 ++++ .../ApiBundle/Tests/WallabagApiTestCase.php | 9 ++++- .../CoreBundle/Repository/EntryRepository.php | 47 ++++++++++++++++++---- 3 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/Wallabag/ApiBundle/Tests/Controller/WallabagRestControllerTest.php b/src/Wallabag/ApiBundle/Tests/Controller/WallabagRestControllerTest.php index a7120e83..22894a77 100644 --- a/src/Wallabag/ApiBundle/Tests/Controller/WallabagRestControllerTest.php +++ b/src/Wallabag/ApiBundle/Tests/Controller/WallabagRestControllerTest.php @@ -310,5 +310,12 @@ class WallabagRestControllerTest extends WallabagApiTestCase $this->assertArrayHasKey('label', $content); $this->assertEquals($tag['label'], $content['label']); $this->assertEquals($tag['slug'], $content['slug']); + + $entries = $entry = $this->client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->findAllByTagId($this->user->getId(), $tag['id']); + + $this->assertCount(0, $entries); } } diff --git a/src/Wallabag/ApiBundle/Tests/WallabagApiTestCase.php b/src/Wallabag/ApiBundle/Tests/WallabagApiTestCase.php index 8a57fea2..a415c749 100644 --- a/src/Wallabag/ApiBundle/Tests/WallabagApiTestCase.php +++ b/src/Wallabag/ApiBundle/Tests/WallabagApiTestCase.php @@ -12,6 +12,11 @@ abstract class WallabagApiTestCase extends WebTestCase */ protected $client = null; + /** + * @var \FOS\UserBundle\Model\UserInterface + */ + protected $user; + public function setUp() { $this->client = $this->createAuthorizedClient(); @@ -31,8 +36,8 @@ abstract class WallabagApiTestCase extends WebTestCase $loginManager = $container->get('fos_user.security.login_manager'); $firewallName = $container->getParameter('fos_user.firewall_name'); - $user = $userManager->findUserBy(array('username' => 'admin')); - $loginManager->loginUser($firewallName, $user); + $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())); diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php index 9ff80d6e..e658a359 100644 --- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php +++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php @@ -183,19 +183,50 @@ class EntryRepository extends EntityRepository /** * Remove a tag from all user entries. - * We are using a native SQL query because Doctrine doesn't know EntryTag entity because it's a ManyToMany relation. - * Instead of that SQL query we should loop on every entry and remove the tag, could be really long ... + * + * We need to loop on each entry attached to the given tag to remove it, since Doctrine doesn't know EntryTag entity because it's a ManyToMany relation. + * It could be faster with one query but I don't know how to retrieve the table name `entry_tag` which can have a prefix. * * @param int $userId * @param Tag $tag */ public function removeTag($userId, Tag $tag) { - $sql = 'DELETE et FROM entry_tag et WHERE et.entry_id IN ( SELECT e.id FROM entry e WHERE e.user_id = :userId ) AND et.tag_id = :tagId'; - $stmt = $this->getEntityManager()->getConnection()->prepare($sql); - $stmt->execute([ - 'userId' => $userId, - 'tagId' => $tag->getId(), - ]); + $entries = $this->getBuilderByUser($userId) + ->innerJoin('e.tags', 't') + ->andWhere('t.id = :tagId')->setParameter('tagId', $tag->getId()) + ->getQuery() + ->getResult(); + + foreach ($entries as $entry) { + $entry->removeTag($tag); + } + + $this->getEntityManager()->flush(); + + // An other solution can be to use raw query but I can't find a way to retrieve the `entry_tag` table name since it can be prefixed.... + // $sql = 'DELETE et FROM entry_tag et WHERE et.entry_id IN ( SELECT e.id FROM entry e WHERE e.user_id = :userId ) AND et.tag_id = :tagId'; + // $stmt = $this->getEntityManager()->getConnection()->prepare($sql); + // $stmt->execute([ + // 'userId' => $userId, + // 'tagId' => $tag->getId(), + // ]); + } + + /** + * Find all entries that are attached to a give tag id. + * + * @param int $userId + * @param int $tagId + * + * @return array + */ + public function findAllByTagId($userId, $tagId) + { + return $this->getBuilderByUser($userId) + ->innerJoin('e.tags', 't') + ->andWhere('t.id = :tagId')->setParameter('tagId', $tagId) + ->getQuery() + ->getResult(); } } -- cgit v1.2.3 From 6be9750155fa731d75898b4973a126a090345c2d Mon Sep 17 00:00:00 2001 From: Jeremy Benoist Date: Tue, 29 Dec 2015 21:59:34 +0100 Subject: Removed comment And move the SQL query inside the php doc --- src/Wallabag/CoreBundle/Repository/EntryRepository.php | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php index e658a359..ca71970b 100644 --- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php +++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php @@ -185,7 +185,9 @@ class EntryRepository extends EntityRepository * Remove a tag from all user entries. * * We need to loop on each entry attached to the given tag to remove it, since Doctrine doesn't know EntryTag entity because it's a ManyToMany relation. - * It could be faster with one query but I don't know how to retrieve the table name `entry_tag` which can have a prefix. + * It could be faster with one query but I don't know how to retrieve the table name `entry_tag` which can have a prefix: + * + * DELETE et FROM entry_tag et WHERE et.entry_id IN ( SELECT e.id FROM entry e WHERE e.user_id = :userId ) AND et.tag_id = :tagId * * @param int $userId * @param Tag $tag @@ -203,14 +205,6 @@ class EntryRepository extends EntityRepository } $this->getEntityManager()->flush(); - - // An other solution can be to use raw query but I can't find a way to retrieve the `entry_tag` table name since it can be prefixed.... - // $sql = 'DELETE et FROM entry_tag et WHERE et.entry_id IN ( SELECT e.id FROM entry e WHERE e.user_id = :userId ) AND et.tag_id = :tagId'; - // $stmt = $this->getEntityManager()->getConnection()->prepare($sql); - // $stmt->execute([ - // 'userId' => $userId, - // 'tagId' => $tag->getId(), - // ]); } /** -- cgit v1.2.3