diff options
author | Kevin Decherf <kevin@kdecherf.com> | 2019-05-12 00:00:00 +0200 |
---|---|---|
committer | Kevin Decherf <kevin@kdecherf.com> | 2019-05-18 18:11:08 +0200 |
commit | 2c290747cb0d235392f6e5d22205a706c6474168 (patch) | |
tree | fdf67f203aca096e8b61bd245b387d05cc38e20b | |
parent | de1162b91a205a98a3f8ed01bd80285793b18380 (diff) | |
download | wallabag-2c290747cb0d235392f6e5d22205a706c6474168.tar.gz wallabag-2c290747cb0d235392f6e5d22205a706c6474168.tar.zst wallabag-2c290747cb0d235392f6e5d22205a706c6474168.zip |
api/entries: add parameter detail to exclude or include content in response
detail=metadata will nullify the content field of entries in order to
make smaller responses.
detail=full keeps the former behavior, it sends the content of entries.
It's the default, for backward compatibility.
Fixes #2817
Signed-off-by: Kevin Decherf <kevin@kdecherf.com>
3 files changed, 42 insertions, 2 deletions
diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php index 06520af9..aff0534a 100644 --- a/src/Wallabag/ApiBundle/Controller/EntryRestController.php +++ b/src/Wallabag/ApiBundle/Controller/EntryRestController.php | |||
@@ -103,6 +103,7 @@ class EntryRestController extends WallabagRestController | |||
103 | * {"name"="tags", "dataType"="string", "required"=false, "format"="api,rest", "description"="a list of tags url encoded. Will returns entries that matches ALL tags."}, | 103 | * {"name"="tags", "dataType"="string", "required"=false, "format"="api,rest", "description"="a list of tags url encoded. Will returns entries that matches ALL tags."}, |
104 | * {"name"="since", "dataType"="integer", "required"=false, "format"="default '0'", "description"="The timestamp since when you want entries updated."}, | 104 | * {"name"="since", "dataType"="integer", "required"=false, "format"="default '0'", "description"="The timestamp since when you want entries updated."}, |
105 | * {"name"="public", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by entries with a public link"}, | 105 | * {"name"="public", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by entries with a public link"}, |
106 | * {"name"="detail", "dataType"="string", "required"=false, "format"="metadata or full, metadata by default", "description"="include content field if 'full'. 'full' by default for backward compatibility."}, | ||
106 | * } | 107 | * } |
107 | * ) | 108 | * ) |
108 | * | 109 | * |
@@ -121,6 +122,7 @@ class EntryRestController extends WallabagRestController | |||
121 | $perPage = (int) $request->query->get('perPage', 30); | 122 | $perPage = (int) $request->query->get('perPage', 30); |
122 | $tags = \is_array($request->query->get('tags')) ? '' : (string) $request->query->get('tags', ''); | 123 | $tags = \is_array($request->query->get('tags')) ? '' : (string) $request->query->get('tags', ''); |
123 | $since = $request->query->get('since', 0); | 124 | $since = $request->query->get('since', 0); |
125 | $detail = strtolower($request->query->get('detail', 'full')); | ||
124 | 126 | ||
125 | try { | 127 | try { |
126 | /** @var \Pagerfanta\Pagerfanta $pager */ | 128 | /** @var \Pagerfanta\Pagerfanta $pager */ |
@@ -132,7 +134,8 @@ class EntryRestController extends WallabagRestController | |||
132 | $sort, | 134 | $sort, |
133 | $order, | 135 | $order, |
134 | $since, | 136 | $since, |
135 | $tags | 137 | $tags, |
138 | $detail | ||
136 | ); | 139 | ); |
137 | } catch (\Exception $e) { | 140 | } catch (\Exception $e) { |
138 | throw new BadRequestHttpException($e->getMessage()); | 141 | throw new BadRequestHttpException($e->getMessage()); |
@@ -156,6 +159,7 @@ class EntryRestController extends WallabagRestController | |||
156 | 'perPage' => $perPage, | 159 | 'perPage' => $perPage, |
157 | 'tags' => $tags, | 160 | 'tags' => $tags, |
158 | 'since' => $since, | 161 | 'since' => $since, |
162 | 'detail' => $detail, | ||
159 | ], | 163 | ], |
160 | true | 164 | true |
161 | ) | 165 | ) |
diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php index f5089729..3990932e 100644 --- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php +++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php | |||
@@ -139,15 +139,30 @@ class EntryRepository extends EntityRepository | |||
139 | * @param string $order | 139 | * @param string $order |
140 | * @param int $since | 140 | * @param int $since |
141 | * @param string $tags | 141 | * @param string $tags |
142 | * @param string $detail 'metadata' or 'full'. Include content field if 'full' | ||
143 | * | ||
144 | * @todo Breaking change: replace default detail=full by detail=metadata in a future version | ||
142 | * | 145 | * |
143 | * @return Pagerfanta | 146 | * @return Pagerfanta |
144 | */ | 147 | */ |
145 | public function findEntries($userId, $isArchived = null, $isStarred = null, $isPublic = null, $sort = 'created', $order = 'asc', $since = 0, $tags = '') | 148 | public function findEntries($userId, $isArchived = null, $isStarred = null, $isPublic = null, $sort = 'created', $order = 'asc', $since = 0, $tags = '', $detail = 'full') |
146 | { | 149 | { |
150 | if (!\in_array(strtolower($detail), ['full', 'metadata'], true)) { | ||
151 | throw new \Exception('Detail "' . $detail . '" parameter is wrong, allowed: full or metadata'); | ||
152 | } | ||
153 | |||
147 | $qb = $this->createQueryBuilder('e') | 154 | $qb = $this->createQueryBuilder('e') |
148 | ->leftJoin('e.tags', 't') | 155 | ->leftJoin('e.tags', 't') |
149 | ->where('e.user = :userId')->setParameter('userId', $userId); | 156 | ->where('e.user = :userId')->setParameter('userId', $userId); |
150 | 157 | ||
158 | if ('metadata' === $detail) { | ||
159 | $fieldNames = $this->getClassMetadata()->getFieldNames(); | ||
160 | $fields = array_filter($fieldNames, function ($k) { | ||
161 | return 'content' !== $k; | ||
162 | }); | ||
163 | $qb->select(sprintf('partial e.{%s}', implode(',', $fields))); | ||
164 | } | ||
165 | |||
151 | if (null !== $isArchived) { | 166 | if (null !== $isArchived) { |
152 | $qb->andWhere('e.isArchived = :isArchived')->setParameter('isArchived', (bool) $isArchived); | 167 | $qb->andWhere('e.isArchived = :isArchived')->setParameter('isArchived', (bool) $isArchived); |
153 | } | 168 | } |
diff --git a/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php b/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php index 8cc12ed3..8b7898ee 100644 --- a/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php +++ b/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php | |||
@@ -133,6 +133,27 @@ class EntryRestControllerTest extends WallabagApiTestCase | |||
133 | $this->assertSame(1, $content['page']); | 133 | $this->assertSame(1, $content['page']); |
134 | $this->assertGreaterThanOrEqual(1, $content['pages']); | 134 | $this->assertGreaterThanOrEqual(1, $content['pages']); |
135 | 135 | ||
136 | $this->assertNotNull($content['_embedded']['items'][0]['content']); | ||
137 | |||
138 | $this->assertSame('application/json', $this->client->getResponse()->headers->get('Content-Type')); | ||
139 | } | ||
140 | |||
141 | public function testGetEntriesDetailMetadata() | ||
142 | { | ||
143 | $this->client->request('GET', '/api/entries?detail=metadata'); | ||
144 | |||
145 | $this->assertSame(200, $this->client->getResponse()->getStatusCode()); | ||
146 | |||
147 | $content = json_decode($this->client->getResponse()->getContent(), true); | ||
148 | |||
149 | $this->assertGreaterThanOrEqual(1, \count($content)); | ||
150 | $this->assertNotEmpty($content['_embedded']['items']); | ||
151 | $this->assertGreaterThanOrEqual(1, $content['total']); | ||
152 | $this->assertSame(1, $content['page']); | ||
153 | $this->assertGreaterThanOrEqual(1, $content['pages']); | ||
154 | |||
155 | $this->assertNull($content['_embedded']['items'][0]['content']); | ||
156 | |||
136 | $this->assertSame('application/json', $this->client->getResponse()->headers->get('Content-Type')); | 157 | $this->assertSame('application/json', $this->client->getResponse()->headers->get('Content-Type')); |
137 | } | 158 | } |
138 | 159 | ||