diff options
author | Jeremy Benoist <jeremy.benoist@gmail.com> | 2017-06-10 15:31:57 +0200 |
---|---|---|
committer | Jeremy Benoist <jeremy.benoist@gmail.com> | 2017-06-10 15:31:57 +0200 |
commit | 1112e54772c9308ee3d7417869b5b8ef9b2b9812 (patch) | |
tree | 1d4341b1a4889baf5c934dc2064a4f4e982f9947 | |
parent | e8911f7c09fa9d8009d7c7ee9fb0c181d2ffbc31 (diff) | |
download | wallabag-1112e54772c9308ee3d7417869b5b8ef9b2b9812.tar.gz wallabag-1112e54772c9308ee3d7417869b5b8ef9b2b9812.tar.zst wallabag-1112e54772c9308ee3d7417869b5b8ef9b2b9812.zip |
Add public filter/field in the API
Listing entries can now be filtered by “public”.
Creating or patching an entry can now set is to public or remove the public.
Entry response now include “is_public” boolean field
4 files changed, 88 insertions, 6 deletions
diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php index 09b73ccb..ae9a93aa 100644 --- a/src/Wallabag/ApiBundle/Controller/EntryRestController.php +++ b/src/Wallabag/ApiBundle/Controller/EntryRestController.php | |||
@@ -77,6 +77,7 @@ class EntryRestController extends WallabagRestController | |||
77 | * {"name"="perPage", "dataType"="integer", "required"=false, "format"="default'30'", "description"="results per page."}, | 77 | * {"name"="perPage", "dataType"="integer", "required"=false, "format"="default'30'", "description"="results per page."}, |
78 | * {"name"="tags", "dataType"="string", "required"=false, "format"="api,rest", "description"="a list of tags url encoded. Will returns entries that matches ALL tags."}, | 78 | * {"name"="tags", "dataType"="string", "required"=false, "format"="api,rest", "description"="a list of tags url encoded. Will returns entries that matches ALL tags."}, |
79 | * {"name"="since", "dataType"="integer", "required"=false, "format"="default '0'", "description"="The timestamp since when you want entries updated."}, | 79 | * {"name"="since", "dataType"="integer", "required"=false, "format"="default '0'", "description"="The timestamp since when you want entries updated."}, |
80 | * {"name"="public", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by entries with a public link"}, | ||
80 | * } | 81 | * } |
81 | * ) | 82 | * ) |
82 | * | 83 | * |
@@ -88,6 +89,7 @@ class EntryRestController extends WallabagRestController | |||
88 | 89 | ||
89 | $isArchived = (null === $request->query->get('archive')) ? null : (bool) $request->query->get('archive'); | 90 | $isArchived = (null === $request->query->get('archive')) ? null : (bool) $request->query->get('archive'); |
90 | $isStarred = (null === $request->query->get('starred')) ? null : (bool) $request->query->get('starred'); | 91 | $isStarred = (null === $request->query->get('starred')) ? null : (bool) $request->query->get('starred'); |
92 | $isPublic = (null === $request->query->get('public')) ? null : (bool) $request->query->get('public'); | ||
91 | $sort = $request->query->get('sort', 'created'); | 93 | $sort = $request->query->get('sort', 'created'); |
92 | $order = $request->query->get('order', 'desc'); | 94 | $order = $request->query->get('order', 'desc'); |
93 | $page = (int) $request->query->get('page', 1); | 95 | $page = (int) $request->query->get('page', 1); |
@@ -96,9 +98,16 @@ class EntryRestController extends WallabagRestController | |||
96 | $since = $request->query->get('since', 0); | 98 | $since = $request->query->get('since', 0); |
97 | 99 | ||
98 | /** @var \Pagerfanta\Pagerfanta $pager */ | 100 | /** @var \Pagerfanta\Pagerfanta $pager */ |
99 | $pager = $this->getDoctrine() | 101 | $pager = $this->get('wallabag_core.entry_repository')->findEntries( |
100 | ->getRepository('WallabagCoreBundle:Entry') | 102 | $this->getUser()->getId(), |
101 | ->findEntries($this->getUser()->getId(), $isArchived, $isStarred, $sort, $order, $since, $tags); | 103 | $isArchived, |
104 | $isStarred, | ||
105 | $isPublic, | ||
106 | $sort, | ||
107 | $order, | ||
108 | $since, | ||
109 | $tags | ||
110 | ); | ||
102 | 111 | ||
103 | $pager->setMaxPerPage($perPage); | 112 | $pager->setMaxPerPage($perPage); |
104 | $pager->setCurrentPage($page); | 113 | $pager->setCurrentPage($page); |
@@ -111,6 +120,7 @@ class EntryRestController extends WallabagRestController | |||
111 | [ | 120 | [ |
112 | 'archive' => $isArchived, | 121 | 'archive' => $isArchived, |
113 | 'starred' => $isStarred, | 122 | 'starred' => $isStarred, |
123 | 'public' => $isPublic, | ||
114 | 'sort' => $sort, | 124 | 'sort' => $sort, |
115 | 'order' => $order, | 125 | 'order' => $order, |
116 | 'page' => $page, | 126 | 'page' => $page, |
@@ -289,6 +299,7 @@ class EntryRestController extends WallabagRestController | |||
289 | * {"name"="preview_picture", "dataType"="string", "required"=false, "description"="Preview picture of the entry"}, | 299 | * {"name"="preview_picture", "dataType"="string", "required"=false, "description"="Preview picture of the entry"}, |
290 | * {"name"="published_at", "dataType"="datetime|integer", "format"="YYYY-MM-DDTHH:II:SS+TZ or a timestamp", "required"=false, "description"="Published date of the entry"}, | 300 | * {"name"="published_at", "dataType"="datetime|integer", "format"="YYYY-MM-DDTHH:II:SS+TZ or a timestamp", "required"=false, "description"="Published date of the entry"}, |
291 | * {"name"="authors", "dataType"="string", "format"="Name Firstname,author2,author3", "required"=false, "description"="Authors of the entry"}, | 301 | * {"name"="authors", "dataType"="string", "format"="Name Firstname,author2,author3", "required"=false, "description"="Authors of the entry"}, |
302 | * {"name"="public", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="will generate a public link for the entry"}, | ||
292 | * } | 303 | * } |
293 | * ) | 304 | * ) |
294 | * | 305 | * |
@@ -332,6 +343,7 @@ class EntryRestController extends WallabagRestController | |||
332 | * {"name"="preview_picture", "dataType"="string", "required"=false, "description"="Preview picture of the entry"}, | 343 | * {"name"="preview_picture", "dataType"="string", "required"=false, "description"="Preview picture of the entry"}, |
333 | * {"name"="published_at", "dataType"="datetime|integer", "format"="YYYY-MM-DDTHH:II:SS+TZ or a timestamp", "required"=false, "description"="Published date of the entry"}, | 344 | * {"name"="published_at", "dataType"="datetime|integer", "format"="YYYY-MM-DDTHH:II:SS+TZ or a timestamp", "required"=false, "description"="Published date of the entry"}, |
334 | * {"name"="authors", "dataType"="string", "format"="Name Firstname,author2,author3", "required"=false, "description"="Authors of the entry"}, | 345 | * {"name"="authors", "dataType"="string", "format"="Name Firstname,author2,author3", "required"=false, "description"="Authors of the entry"}, |
346 | * {"name"="public", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="will generate a public link for the entry"}, | ||
335 | * } | 347 | * } |
336 | * ) | 348 | * ) |
337 | * | 349 | * |
@@ -623,6 +635,7 @@ class EntryRestController extends WallabagRestController | |||
623 | $tags = $request->request->get('tags', []); | 635 | $tags = $request->request->get('tags', []); |
624 | $isArchived = $request->request->get('archive'); | 636 | $isArchived = $request->request->get('archive'); |
625 | $isStarred = $request->request->get('starred'); | 637 | $isStarred = $request->request->get('starred'); |
638 | $isPublic = $request->request->get('public'); | ||
626 | $content = $request->request->get('content'); | 639 | $content = $request->request->get('content'); |
627 | $language = $request->request->get('language'); | 640 | $language = $request->request->get('language'); |
628 | $picture = $request->request->get('preview_picture'); | 641 | $picture = $request->request->get('preview_picture'); |
@@ -666,6 +679,14 @@ class EntryRestController extends WallabagRestController | |||
666 | $this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $tags); | 679 | $this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $tags); |
667 | } | 680 | } |
668 | 681 | ||
682 | if (!is_null($isPublic)) { | ||
683 | $entry->cleanUid(); | ||
684 | |||
685 | if (true === (bool) $isPublic && null === $entry->getUid()) { | ||
686 | $entry->generateUid(); | ||
687 | } | ||
688 | } | ||
689 | |||
669 | $em = $this->getDoctrine()->getManager(); | 690 | $em = $this->getDoctrine()->getManager(); |
670 | $em->persist($entry); | 691 | $em->persist($entry); |
671 | $em->flush(); | 692 | $em->flush(); |
diff --git a/src/Wallabag/CoreBundle/Entity/Entry.php b/src/Wallabag/CoreBundle/Entity/Entry.php index 365030c7..07d41ed8 100644 --- a/src/Wallabag/CoreBundle/Entity/Entry.php +++ b/src/Wallabag/CoreBundle/Entity/Entry.php | |||
@@ -687,6 +687,10 @@ class Entry | |||
687 | /** | 687 | /** |
688 | * Used in the entries filter so it's more explicit for the end user than the uid. | 688 | * Used in the entries filter so it's more explicit for the end user than the uid. |
689 | * | 689 | * |
690 | * @VirtualProperty | ||
691 | * @SerializedName("is_public") | ||
692 | * @Groups({"entries_for_user"}) | ||
693 | * | ||
690 | * @return bool | 694 | * @return bool |
691 | */ | 695 | */ |
692 | public function isPublic() | 696 | public function isPublic() |
diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php index 6972e974..9bda4e15 100644 --- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php +++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php | |||
@@ -135,6 +135,7 @@ class EntryRepository extends EntityRepository | |||
135 | * @param int $userId | 135 | * @param int $userId |
136 | * @param bool $isArchived | 136 | * @param bool $isArchived |
137 | * @param bool $isStarred | 137 | * @param bool $isStarred |
138 | * @param bool $isPublic | ||
138 | * @param string $sort | 139 | * @param string $sort |
139 | * @param string $order | 140 | * @param string $order |
140 | * @param int $since | 141 | * @param int $since |
@@ -142,18 +143,22 @@ class EntryRepository extends EntityRepository | |||
142 | * | 143 | * |
143 | * @return array | 144 | * @return array |
144 | */ | 145 | */ |
145 | public function findEntries($userId, $isArchived = null, $isStarred = null, $sort = 'created', $order = 'ASC', $since = 0, $tags = '') | 146 | public function findEntries($userId, $isArchived = null, $isStarred = null, $isPublic = null, $sort = 'created', $order = 'ASC', $since = 0, $tags = '') |
146 | { | 147 | { |
147 | $qb = $this->createQueryBuilder('e') | 148 | $qb = $this->createQueryBuilder('e') |
148 | ->leftJoin('e.tags', 't') | 149 | ->leftJoin('e.tags', 't') |
149 | ->where('e.user =:userId')->setParameter('userId', $userId); | 150 | ->where('e.user =:userId')->setParameter('userId', $userId); |
150 | 151 | ||
151 | if (null !== $isArchived) { | 152 | if (null !== $isArchived) { |
152 | $qb->andWhere('e.isArchived =:isArchived')->setParameter('isArchived', (bool) $isArchived); | 153 | $qb->andWhere('e.isArchived = :isArchived')->setParameter('isArchived', (bool) $isArchived); |
153 | } | 154 | } |
154 | 155 | ||
155 | if (null !== $isStarred) { | 156 | if (null !== $isStarred) { |
156 | $qb->andWhere('e.isStarred =:isStarred')->setParameter('isStarred', (bool) $isStarred); | 157 | $qb->andWhere('e.isStarred = :isStarred')->setParameter('isStarred', (bool) $isStarred); |
158 | } | ||
159 | |||
160 | if (null !== $isPublic) { | ||
161 | $qb->andWhere('e.uid IS '.(true === $isPublic ? 'NOT' : '').' NULL'); | ||
157 | } | 162 | } |
158 | 163 | ||
159 | if ($since > 0) { | 164 | if ($since > 0) { |
diff --git a/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php b/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php index 4aa60e90..067aed2c 100644 --- a/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php +++ b/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php | |||
@@ -128,6 +128,7 @@ class EntryRestControllerTest extends WallabagApiTestCase | |||
128 | 'perPage' => 2, | 128 | 'perPage' => 2, |
129 | 'tags' => 'foo', | 129 | 'tags' => 'foo', |
130 | 'since' => 1443274283, | 130 | 'since' => 1443274283, |
131 | 'public' => 0, | ||
131 | ]); | 132 | ]); |
132 | 133 | ||
133 | $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); | 134 | $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); |
@@ -154,6 +155,53 @@ class EntryRestControllerTest extends WallabagApiTestCase | |||
154 | $this->assertContains('order=asc', $content['_links'][$link]['href']); | 155 | $this->assertContains('order=asc', $content['_links'][$link]['href']); |
155 | $this->assertContains('tags=foo', $content['_links'][$link]['href']); | 156 | $this->assertContains('tags=foo', $content['_links'][$link]['href']); |
156 | $this->assertContains('since=1443274283', $content['_links'][$link]['href']); | 157 | $this->assertContains('since=1443274283', $content['_links'][$link]['href']); |
158 | $this->assertContains('public=0', $content['_links'][$link]['href']); | ||
159 | } | ||
160 | |||
161 | $this->assertEquals('application/json', $this->client->getResponse()->headers->get('Content-Type')); | ||
162 | } | ||
163 | |||
164 | public function testGetEntriesPublicOnly() | ||
165 | { | ||
166 | $entry = $this->client->getContainer() | ||
167 | ->get('doctrine.orm.entity_manager') | ||
168 | ->getRepository('WallabagCoreBundle:Entry') | ||
169 | ->findOneByUser(1); | ||
170 | |||
171 | if (!$entry) { | ||
172 | $this->markTestSkipped('No content found in db.'); | ||
173 | } | ||
174 | |||
175 | // generate at least one public entry | ||
176 | $entry->generateUid(); | ||
177 | |||
178 | $em = $this->client->getContainer()->get('doctrine.orm.entity_manager'); | ||
179 | $em->persist($entry); | ||
180 | $em->flush(); | ||
181 | |||
182 | $this->client->request('GET', '/api/entries', [ | ||
183 | 'public' => 1, | ||
184 | ]); | ||
185 | |||
186 | $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); | ||
187 | |||
188 | $content = json_decode($this->client->getResponse()->getContent(), true); | ||
189 | |||
190 | $this->assertGreaterThanOrEqual(1, count($content)); | ||
191 | $this->assertArrayHasKey('items', $content['_embedded']); | ||
192 | $this->assertGreaterThanOrEqual(1, $content['total']); | ||
193 | $this->assertEquals(1, $content['page']); | ||
194 | $this->assertEquals(30, $content['limit']); | ||
195 | $this->assertGreaterThanOrEqual(1, $content['pages']); | ||
196 | |||
197 | $this->assertArrayHasKey('_links', $content); | ||
198 | $this->assertArrayHasKey('self', $content['_links']); | ||
199 | $this->assertArrayHasKey('first', $content['_links']); | ||
200 | $this->assertArrayHasKey('last', $content['_links']); | ||
201 | |||
202 | foreach (['self', 'first', 'last'] as $link) { | ||
203 | $this->assertArrayHasKey('href', $content['_links'][$link]); | ||
204 | $this->assertContains('public=1', $content['_links'][$link]['href']); | ||
157 | } | 205 | } |
158 | 206 | ||
159 | $this->assertEquals('application/json', $this->client->getResponse()->headers->get('Content-Type')); | 207 | $this->assertEquals('application/json', $this->client->getResponse()->headers->get('Content-Type')); |
@@ -348,6 +396,7 @@ class EntryRestControllerTest extends WallabagApiTestCase | |||
348 | 'language' => 'de', | 396 | 'language' => 'de', |
349 | 'published_at' => '2016-09-08T11:55:58+0200', | 397 | 'published_at' => '2016-09-08T11:55:58+0200', |
350 | 'authors' => 'bob,helen', | 398 | 'authors' => 'bob,helen', |
399 | 'public' => 1, | ||
351 | ]); | 400 | ]); |
352 | 401 | ||
353 | $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); | 402 | $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); |
@@ -367,6 +416,7 @@ class EntryRestControllerTest extends WallabagApiTestCase | |||
367 | $this->assertCount(2, $content['published_by']); | 416 | $this->assertCount(2, $content['published_by']); |
368 | $this->assertContains('bob', $content['published_by']); | 417 | $this->assertContains('bob', $content['published_by']); |
369 | $this->assertContains('helen', $content['published_by']); | 418 | $this->assertContains('helen', $content['published_by']); |
419 | $this->assertTrue($content['is_public'], 'A public link has been generated for that entry'); | ||
370 | } | 420 | } |
371 | 421 | ||
372 | public function testPostSameEntry() | 422 | public function testPostSameEntry() |
@@ -481,6 +531,7 @@ class EntryRestControllerTest extends WallabagApiTestCase | |||
481 | 'preview_picture' => 'http://preview.io/picture.jpg', | 531 | 'preview_picture' => 'http://preview.io/picture.jpg', |
482 | 'authors' => 'bob,sponge', | 532 | 'authors' => 'bob,sponge', |
483 | 'content' => 'awesome', | 533 | 'content' => 'awesome', |
534 | 'public' => 0, | ||
484 | ]); | 535 | ]); |
485 | 536 | ||
486 | $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); | 537 | $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); |
@@ -497,6 +548,7 @@ class EntryRestControllerTest extends WallabagApiTestCase | |||
497 | $this->assertContains('sponge', $content['published_by']); | 548 | $this->assertContains('sponge', $content['published_by']); |
498 | $this->assertContains('bob', $content['published_by']); | 549 | $this->assertContains('bob', $content['published_by']); |
499 | $this->assertEquals('awesome', $content['content']); | 550 | $this->assertEquals('awesome', $content['content']); |
551 | $this->assertFalse($content['is_public'], 'Entry is no more shared'); | ||
500 | } | 552 | } |
501 | 553 | ||
502 | public function testPatchEntryWithoutQuotes() | 554 | public function testPatchEntryWithoutQuotes() |