->findOneByLabel($label);
if (is_null($tagEntity)) {
- $tagEntity = new Tag($this->getUser());
+ $tagEntity = new Tag();
$tagEntity->setLabel($label);
}
$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);
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);
}
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);
$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');
$this->assertArrayHasKey('label', $content);
$this->assertEquals($tag['label'], $content['label']);
+ $this->assertEquals($tag['slug'], $content['slug']);
}
}
*/
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();
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
{
$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);
$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);
--- /dev/null
+<?php
+
+namespace Wallabag\CoreBundle\DataFixtures\ORM;
+
+use Doctrine\Common\DataFixtures\AbstractFixture;
+use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
+use Doctrine\Common\Persistence\ObjectManager;
+use Wallabag\CoreBundle\Entity\Tag;
+
+class LoadTagData extends AbstractFixture implements OrderedFixtureInterface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function load(ObjectManager $manager)
+ {
+ $tag1 = new Tag();
+ $tag1->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;
+ }
+}
// 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;
}
}
private $label;
/**
+ * @Expose
* @Gedmo\Slug(fields={"label"})
* @ORM\Column(length=128, unique=true)
*/
*/
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();
}
{
return $this->entries->contains($entry);
}
-
- /**
- * @return User
- */
- public function getUser()
- {
- return $this->user;
- }
}
}
foreach ($rule->getTags() as $label) {
- $tag = $this->getTag($entry->getUser(), $label);
+ $tag = $this->getTag($label);
$entry->addTag($tag);
}
foreach ($entries as $entry) {
foreach ($rule->getTags() as $label) {
- $tag = $this->getTag($user, $label);
+ $tag = $this->getTag($label);
$entry->addTag($tag);
}
}
/**
- * 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);
}
use Doctrine\ORM\EntityRepository;
use Pagerfanta\Adapter\DoctrineORMAdapter;
use Pagerfanta\Pagerfanta;
+use Wallabag\CoreBundle\Entity\Tag;
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(),
+ ]);
+ }
}
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);
}
/**
- * 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();
}
}
$form = $crawler->filter('button[id=config_save]')->form();
$data = array(
- 'config[theme]' => 0,
+ 'config[theme]' => 'baggy',
'config[items_per_page]' => '30',
'config[language]' => 'en',
);
{
return array(
array(array(
- 'config[theme]' => 0,
+ 'config[theme]' => 'baggy',
'config[items_per_page]' => '',
'config[language]' => 'en',
)),
$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()
$tags = $entry->getTags();
$this->assertSame('foo', $tags[0]->getLabel());
- $this->assertSame($user, $tags[0]->getUser());
}
public function testWhenTheTagExists()
$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())
$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);
$this->assertFalse($entry->getTags()->isEmpty());
$tags = $entry->getTags();
- $this->assertSame($tag, $tags[0]);
+ $this->assertSame($tag->getLabel(), $tags[0]->getLabel());
}
public function testSameTagWithDifferentfMatchingRules()
use FOS\UserBundle\Model\User as BaseUser;
use Wallabag\CoreBundle\Entity\Config;
use Wallabag\CoreBundle\Entity\Entry;
-use Wallabag\CoreBundle\Entity\Tag;
/**
* User.
*/
protected $config;
- /**
- * @ORM\OneToMany(targetEntity="Wallabag\CoreBundle\Entity\Tag", mappedBy="user", cascade={"remove"})
- */
- protected $tags;
-
/**
* @ORM\Column(type="integer", nullable=true)
*/
{
parent::__construct();
$this->entries = new ArrayCollection();
- $this->tags = new ArrayCollection();
$this->roles = array('ROLE_USER');
}
return $this->entries;
}
- /**
- * @param Entry $entry
- *
- * @return User
- */
- public function addTag(Tag $tag)
- {
- $this->tags[] = $tag;
-
- return $this;
- }
-
- /**
- * @return ArrayCollection<Tag>
- */
- public function getTags()
- {
- return $this->tags;
- }
-
public function isEqualTo(UserInterface $user)
{
return $this->username === $user->getUsername();