*/
public function load(ObjectManager $manager)
{
- $entry1 = new Entry($this->getReference('admin-user'));
- $entry1->setUrl('http://0.0.0.0/entry1');
- $entry1->setReadingTime(11);
- $entry1->setDomainName('domain.io');
- $entry1->setMimetype('text/html');
- $entry1->setTitle('test title entry1');
- $entry1->setContent('This is my content /o/');
- $entry1->setLanguage('en');
-
- $entry1->addTag($this->getReference('foo-tag'));
- $entry1->addTag($this->getReference('baz-tag'));
-
- $manager->persist($entry1);
-
- $this->addReference('entry1', $entry1);
-
- $entry2 = new Entry($this->getReference('admin-user'));
- $entry2->setUrl('http://0.0.0.0/entry2');
- $entry2->setReadingTime(1);
- $entry2->setDomainName('domain.io');
- $entry2->setMimetype('text/html');
- $entry2->setTitle('test title entry2');
- $entry2->setContent('This is my content /o/');
- $entry2->setOriginUrl('ftp://oneftp.tld');
- $entry2->setLanguage('fr');
-
- $manager->persist($entry2);
-
- $this->addReference('entry2', $entry2);
-
- $entry3 = new Entry($this->getReference('bob-user'));
- $entry3->setUrl('http://0.0.0.0/entry3');
- $entry3->setReadingTime(1);
- $entry3->setDomainName('domain.io');
- $entry3->setMimetype('text/html');
- $entry3->setTitle('test title entry3');
- $entry3->setContent('This is my content /o/');
- $entry3->setLanguage('en');
-
- $entry3->addTag($this->getReference('foo-tag'));
- $entry3->addTag($this->getReference('bar-tag'));
-
- $manager->persist($entry3);
-
- $this->addReference('entry3', $entry3);
-
- $entry4 = new Entry($this->getReference('admin-user'));
- $entry4->setUrl('http://0.0.0.0/entry4');
- $entry4->setReadingTime(12);
- $entry4->setDomainName('domain.io');
- $entry4->setMimetype('text/html');
- $entry4->setTitle('test title entry4');
- $entry4->setContent('This is my content /o/');
- $entry4->setLanguage('en');
-
- $entry4->addTag($this->getReference('foo-tag'));
- $entry4->addTag($this->getReference('bar-tag'));
-
- $manager->persist($entry4);
-
- $this->addReference('entry4', $entry4);
-
- $entry5 = new Entry($this->getReference('admin-user'));
- $entry5->setUrl('http://0.0.0.0/entry5');
- $entry5->setReadingTime(12);
- $entry5->setDomainName('domain.io');
- $entry5->setMimetype('text/html');
- $entry5->setTitle('test title entry5');
- $entry5->setContent('This is my content /o/');
- $entry5->setStarred(true);
- $entry5->setLanguage('fr');
- $entry5->setPreviewPicture('http://0.0.0.0/image.jpg');
-
- $manager->persist($entry5);
-
- $this->addReference('entry5', $entry5);
-
- $entry6 = new Entry($this->getReference('admin-user'));
- $entry6->setUrl('http://0.0.0.0/entry6');
- $entry6->setReadingTime(12);
- $entry6->setDomainName('domain.io');
- $entry6->setMimetype('text/html');
- $entry6->setTitle('test title entry6');
- $entry6->setContent('This is my content /o/');
- $entry6->setArchived(true);
- $entry6->setLanguage('de');
- $entry6->addTag($this->getReference('bar-tag'));
-
- $manager->persist($entry6);
-
- $this->addReference('entry6', $entry6);
+ $entries = [
+ 'entry1' => [
+ 'user' => 'admin-user',
+ 'url' => 'http://0.0.0.0/entry1',
+ 'reading_time' => 11,
+ 'domain' => 'domain.io',
+ 'mime' => 'text/html',
+ 'title' => 'test title entry1',
+ 'content' => 'This is my content /o/',
+ 'language' => 'en',
+ 'tags' => ['foo-tag', 'baz-tag'],
+ ],
+ 'entry2' => [
+ 'user' => 'admin-user',
+ 'url' => 'http://0.0.0.0/entry2',
+ 'reading_time' => 1,
+ 'domain' => 'domain.io',
+ 'mime' => 'text/html',
+ 'title' => 'test title entry2',
+ 'content' => 'This is my content /o/',
+ 'origin' => 'ftp://oneftp.tld',
+ 'language' => 'fr',
+ ],
+ 'entry3' => [
+ 'user' => 'bob-user',
+ 'url' => 'http://0.0.0.0/entry3',
+ 'reading_time' => 1,
+ 'domain' => 'domain.io',
+ 'mime' => 'text/html',
+ 'title' => 'test title entry3',
+ 'content' => 'This is my content /o/',
+ 'language' => 'en',
+ 'tags' => ['foo-tag', 'bar-tag', 'bob-tag'],
+ ],
+ 'entry4' => [
+ 'user' => 'admin-user',
+ 'url' => 'http://0.0.0.0/entry4',
+ 'reading_time' => 12,
+ 'domain' => 'domain.io',
+ 'mime' => 'text/html',
+ 'title' => 'test title entry4',
+ 'content' => 'This is my content /o/',
+ 'language' => 'en',
+ 'tags' => ['foo-tag', 'bar-tag'],
+ ],
+ 'entry5' => [
+ 'user' => 'admin-user',
+ 'url' => 'http://0.0.0.0/entry5',
+ 'reading_time' => 12,
+ 'domain' => 'domain.io',
+ 'mime' => 'text/html',
+ 'title' => 'test title entry5',
+ 'content' => 'This is my content /o/',
+ 'language' => 'fr',
+ 'starred' => true,
+ 'preview' => 'http://0.0.0.0/image.jpg',
+ ],
+ 'entry6' => [
+ 'user' => 'admin-user',
+ 'url' => 'http://0.0.0.0/entry6',
+ 'reading_time' => 12,
+ 'domain' => 'domain.io',
+ 'mime' => 'text/html',
+ 'title' => 'test title entry6',
+ 'content' => 'This is my content /o/',
+ 'language' => 'de',
+ 'archived' => true,
+ 'tags' => ['bar-tag'],
+ ],
+ ];
+
+ foreach ($entries as $reference => $item) {
+ $entry = new Entry($this->getReference($item['user']));
+ $entry->setUrl($item['url']);
+ $entry->setReadingTime($item['reading_time']);
+ $entry->setDomainName($item['domain']);
+ $entry->setMimetype($item['mime']);
+ $entry->setTitle($item['title']);
+ $entry->setContent($item['content']);
+ $entry->setLanguage($item['language']);
+
+ if (isset($item['tags'])) {
+ foreach ($item['tags'] as $tag) {
+ $entry->addTag($this->getReference($tag));
+ }
+ }
+
+ if (isset($item['origin'])) {
+ $entry->setOriginUrl($item['origin']);
+ }
+
+ if (isset($item['starred'])) {
+ $entry->setStarred($item['starred']);
+ }
+
+ if (isset($item['archived'])) {
+ $entry->setArchived($item['archived']);
+ }
+
+ if (isset($item['preview'])) {
+ $entry->setPreviewPicture($item['preview']);
+ }
+
+ $manager->persist($entry);
+ $this->addReference($reference, $entry);
+ }
$manager->flush();
}
namespace Wallabag\CoreBundle\Repository;
use Doctrine\ORM\EntityRepository;
+use Doctrine\ORM\QueryBuilder;
use Wallabag\CoreBundle\Entity\Tag;
class TagRepository extends EntityRepository
*/
public function findAllTags($userId)
{
- $ids = $this->createQueryBuilder('t')
+ $ids = $this->getQueryBuilderByUser($userId)
->select('t.id')
- ->leftJoin('t.entries', 'e')
- ->where('e.user = :userId')->setParameter('userId', $userId)
- ->groupBy('t.id')
- ->orderBy('t.slug')
->getQuery()
->getArrayResult();
*/
public function findAllFlatTagsWithNbEntries($userId)
{
- return $this->createQueryBuilder('t')
+ return $this->getQueryBuilderByUser($userId)
->select('t.id, t.label, t.slug, count(e.id) as nbEntries')
->distinct(true)
- ->leftJoin('t.entries', 'e')
- ->where('e.user = :userId')
- ->groupBy('t.id')
- ->orderBy('t.slug')
- ->setParameter('userId', $userId)
->getQuery()
->getArrayResult();
}
+ public function findByLabelsAndUser($labels, $userId)
+ {
+ $qb = $this->getQueryBuilderByUser($userId)
+ ->select('t.id');
+
+ $ids = $qb->andWhere($qb->expr()->in('t.label', $labels))
+ ->getQuery()
+ ->getArrayResult();
+
+ $tags = [];
+ foreach ($ids as $id) {
+ $tags[] = $this->find($id);
+ }
+
+ return $tags;
+ }
+
/**
* Used only in test case to get a tag for our entry.
*
public function findForArchivedArticlesByUser($userId)
{
- $ids = $this->createQueryBuilder('t')
+ $ids = $this->getQueryBuilderByUser($userId)
->select('t.id')
- ->leftJoin('t.entries', 'e')
- ->where('e.user = :userId')->setParameter('userId', $userId)
->andWhere('e.isArchived = true')
- ->groupBy('t.id')
- ->orderBy('t.slug')
->getQuery()
->getArrayResult();
return $tags;
}
+
+ /**
+ * Retrieve a sorted list of tags used by a user.
+ *
+ * @param int $userId
+ *
+ * @return QueryBuilder
+ */
+ private function getQueryBuilderByUser($userId)
+ {
+ return $this->createQueryBuilder('t')
+ ->leftJoin('t.entries', 'e')
+ ->where('e.user = :userId')->setParameter('userId', $userId)
+ ->groupBy('t.id')
+ ->orderBy('t.slug');
+ }
}
class TagRestControllerTest extends WallabagApiTestCase
{
+ private $otherUserTagLabel = 'bob';
+
public function testGetUserTags()
{
$this->client->request('GET', '/api/tags.json');
$this->assertArrayHasKey('id', $content[0]);
$this->assertArrayHasKey('label', $content[0]);
+ $tagLabels = array_map(function ($i) {
+ return $i['label'];
+ }, $content);
+
+ $this->assertNotContains($this->otherUserTagLabel, $tagLabels, 'There is a possible tag leak');
+
return end($content);
}
public function testDeleteUserTag()
{
+ $em = $this->client->getContainer()->get('doctrine.orm.entity_manager');
+ $entry = $this->client->getContainer()
+ ->get('doctrine.orm.entity_manager')
+ ->getRepository('WallabagCoreBundle:Entry')
+ ->findOneWithTags($this->user->getId());
+
+ $entry = $entry[0];
+
$tagLabel = 'tagtest';
$tag = new Tag();
$tag->setLabel($tagLabel);
-
- $em = $this->client->getContainer()->get('doctrine.orm.entity_manager');
$em->persist($tag);
+
+ $entry->addTag($tag);
+
+ $em->persist($entry);
$em->flush();
$em->clear();
$this->assertNull($tag, $tagLabel . ' was removed because it begun an orphan tag');
}
+ public function testDeleteOtherUserTag()
+ {
+ $em = $this->client->getContainer()->get('doctrine.orm.entity_manager');
+ $tag = $em->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($this->otherUserTagLabel);
+
+ $this->client->request('DELETE', '/api/tags/' . $tag->getId() . '.json');
+
+ $this->assertSame(404, $this->client->getResponse()->getStatusCode());
+ }
+
public function dataForDeletingTagByLabel()
{
return [
$this->assertSame(404, $this->client->getResponse()->getStatusCode());
}
+ public function testDeleteTagByLabelOtherUser()
+ {
+ $this->client->request('DELETE', '/api/tag/label.json', ['tag' => $this->otherUserTagLabel]);
+
+ $this->assertSame(404, $this->client->getResponse()->getStatusCode());
+ }
+
/**
* @dataProvider dataForDeletingTagByLabel
*/
$this->assertSame(404, $this->client->getResponse()->getStatusCode());
}
+
+ public function testDeleteTagsByLabelOtherUser()
+ {
+ $this->client->request('DELETE', '/api/tags/label.json', ['tags' => $this->otherUserTagLabel]);
+
+ $this->assertSame(404, $this->client->getResponse()->getStatusCode());
+ }
}