diff options
Diffstat (limited to 'src/Wallabag/ApiBundle/Controller/WallabagRestController.php')
-rw-r--r-- | src/Wallabag/ApiBundle/Controller/WallabagRestController.php | 231 |
1 files changed, 193 insertions, 38 deletions
diff --git a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php index af24e498..9997913d 100644 --- a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php +++ b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php | |||
@@ -7,7 +7,7 @@ use Hateoas\Configuration\Route; | |||
7 | use Hateoas\Representation\Factory\PagerfantaFactory; | 7 | use Hateoas\Representation\Factory\PagerfantaFactory; |
8 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; | 8 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; |
9 | use Symfony\Component\HttpFoundation\Request; | 9 | use Symfony\Component\HttpFoundation\Request; |
10 | use Symfony\Component\HttpFoundation\Response; | 10 | use Symfony\Component\HttpFoundation\JsonResponse; |
11 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | 11 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; |
12 | use Symfony\Component\Security\Core\Exception\AccessDeniedException; | 12 | use Symfony\Component\Security\Core\Exception\AccessDeniedException; |
13 | use Wallabag\CoreBundle\Entity\Entry; | 13 | use Wallabag\CoreBundle\Entity\Entry; |
@@ -23,6 +23,58 @@ class WallabagRestController extends FOSRestController | |||
23 | } | 23 | } |
24 | 24 | ||
25 | /** | 25 | /** |
26 | * Check if an entry exist by url. | ||
27 | * | ||
28 | * @ApiDoc( | ||
29 | * parameters={ | ||
30 | * {"name"="url", "dataType"="string", "required"=true, "format"="An url", "description"="Url to check if it exists"}, | ||
31 | * {"name"="urls", "dataType"="string", "required"=false, "format"="An array of urls (?urls[]=http...&urls[]=http...)", "description"="Urls (as an array) to check if it exists"} | ||
32 | * } | ||
33 | * ) | ||
34 | * | ||
35 | * @return JsonResponse | ||
36 | */ | ||
37 | public function getEntriesExistsAction(Request $request) | ||
38 | { | ||
39 | $this->validateAuthentication(); | ||
40 | |||
41 | $urls = $request->query->get('urls', []); | ||
42 | |||
43 | // handle multiple urls first | ||
44 | if (!empty($urls)) { | ||
45 | $results = []; | ||
46 | foreach ($urls as $url) { | ||
47 | $res = $this->getDoctrine() | ||
48 | ->getRepository('WallabagCoreBundle:Entry') | ||
49 | ->findByUrlAndUserId($url, $this->getUser()->getId()); | ||
50 | |||
51 | $results[$url] = false === $res ? false : true; | ||
52 | } | ||
53 | |||
54 | $json = $this->get('serializer')->serialize($results, 'json'); | ||
55 | |||
56 | return (new JsonResponse())->setJson($json); | ||
57 | } | ||
58 | |||
59 | // let's see if it is a simple url? | ||
60 | $url = $request->query->get('url', ''); | ||
61 | |||
62 | if (empty($url)) { | ||
63 | throw $this->createAccessDeniedException('URL is empty?, logged user id: '.$this->getUser()->getId()); | ||
64 | } | ||
65 | |||
66 | $res = $this->getDoctrine() | ||
67 | ->getRepository('WallabagCoreBundle:Entry') | ||
68 | ->findByUrlAndUserId($url, $this->getUser()->getId()); | ||
69 | |||
70 | $exists = false === $res ? false : true; | ||
71 | |||
72 | $json = $this->get('serializer')->serialize(['exists' => $exists], 'json'); | ||
73 | |||
74 | return (new JsonResponse())->setJson($json); | ||
75 | } | ||
76 | |||
77 | /** | ||
26 | * Retrieve all entries. It could be filtered by many options. | 78 | * Retrieve all entries. It could be filtered by many options. |
27 | * | 79 | * |
28 | * @ApiDoc( | 80 | * @ApiDoc( |
@@ -34,10 +86,11 @@ class WallabagRestController extends FOSRestController | |||
34 | * {"name"="page", "dataType"="integer", "required"=false, "format"="default '1'", "description"="what page you want."}, | 86 | * {"name"="page", "dataType"="integer", "required"=false, "format"="default '1'", "description"="what page you want."}, |
35 | * {"name"="perPage", "dataType"="integer", "required"=false, "format"="default'30'", "description"="results per page."}, | 87 | * {"name"="perPage", "dataType"="integer", "required"=false, "format"="default'30'", "description"="results per page."}, |
36 | * {"name"="tags", "dataType"="string", "required"=false, "format"="api,rest", "description"="a list of tags url encoded. Will returns entries that matches ALL tags."}, | 88 | * {"name"="tags", "dataType"="string", "required"=false, "format"="api,rest", "description"="a list of tags url encoded. Will returns entries that matches ALL tags."}, |
89 | * {"name"="since", "dataType"="integer", "required"=false, "format"="default '0'", "description"="The timestamp since when you want entries updated."}, | ||
37 | * } | 90 | * } |
38 | * ) | 91 | * ) |
39 | * | 92 | * |
40 | * @return Response | 93 | * @return JsonResponse |
41 | */ | 94 | */ |
42 | public function getEntriesAction(Request $request) | 95 | public function getEntriesAction(Request $request) |
43 | { | 96 | { |
@@ -49,10 +102,12 @@ class WallabagRestController extends FOSRestController | |||
49 | $order = $request->query->get('order', 'desc'); | 102 | $order = $request->query->get('order', 'desc'); |
50 | $page = (int) $request->query->get('page', 1); | 103 | $page = (int) $request->query->get('page', 1); |
51 | $perPage = (int) $request->query->get('perPage', 30); | 104 | $perPage = (int) $request->query->get('perPage', 30); |
105 | $tags = $request->query->get('tags', ''); | ||
106 | $since = $request->query->get('since', 0); | ||
52 | 107 | ||
53 | $pager = $this->getDoctrine() | 108 | $pager = $this->getDoctrine() |
54 | ->getRepository('WallabagCoreBundle:Entry') | 109 | ->getRepository('WallabagCoreBundle:Entry') |
55 | ->findEntries($this->getUser()->getId(), $isArchived, $isStarred, $sort, $order); | 110 | ->findEntries($this->getUser()->getId(), $isArchived, $isStarred, $sort, $order, $since, $tags); |
56 | 111 | ||
57 | $pager->setCurrentPage($page); | 112 | $pager->setCurrentPage($page); |
58 | $pager->setMaxPerPage($perPage); | 113 | $pager->setMaxPerPage($perPage); |
@@ -60,12 +115,25 @@ class WallabagRestController extends FOSRestController | |||
60 | $pagerfantaFactory = new PagerfantaFactory('page', 'perPage'); | 115 | $pagerfantaFactory = new PagerfantaFactory('page', 'perPage'); |
61 | $paginatedCollection = $pagerfantaFactory->createRepresentation( | 116 | $paginatedCollection = $pagerfantaFactory->createRepresentation( |
62 | $pager, | 117 | $pager, |
63 | new Route('api_get_entries', [], UrlGeneratorInterface::ABSOLUTE_URL) | 118 | new Route( |
119 | 'api_get_entries', | ||
120 | [ | ||
121 | 'archive' => $isArchived, | ||
122 | 'starred' => $isStarred, | ||
123 | 'sort' => $sort, | ||
124 | 'order' => $order, | ||
125 | 'page' => $page, | ||
126 | 'perPage' => $perPage, | ||
127 | 'tags' => $tags, | ||
128 | 'since' => $since, | ||
129 | ], | ||
130 | UrlGeneratorInterface::ABSOLUTE_URL | ||
131 | ) | ||
64 | ); | 132 | ); |
65 | 133 | ||
66 | $json = $this->get('serializer')->serialize($paginatedCollection, 'json'); | 134 | $json = $this->get('serializer')->serialize($paginatedCollection, 'json'); |
67 | 135 | ||
68 | return $this->renderJsonResponse($json); | 136 | return (new JsonResponse())->setJson($json); |
69 | } | 137 | } |
70 | 138 | ||
71 | /** | 139 | /** |
@@ -77,7 +145,7 @@ class WallabagRestController extends FOSRestController | |||
77 | * } | 145 | * } |
78 | * ) | 146 | * ) |
79 | * | 147 | * |
80 | * @return Response | 148 | * @return JsonResponse |
81 | */ | 149 | */ |
82 | public function getEntryAction(Entry $entry) | 150 | public function getEntryAction(Entry $entry) |
83 | { | 151 | { |
@@ -86,7 +154,7 @@ class WallabagRestController extends FOSRestController | |||
86 | 154 | ||
87 | $json = $this->get('serializer')->serialize($entry, 'json'); | 155 | $json = $this->get('serializer')->serialize($entry, 'json'); |
88 | 156 | ||
89 | return $this->renderJsonResponse($json); | 157 | return (new JsonResponse())->setJson($json); |
90 | } | 158 | } |
91 | 159 | ||
92 | /** | 160 | /** |
@@ -102,7 +170,7 @@ class WallabagRestController extends FOSRestController | |||
102 | * } | 170 | * } |
103 | * ) | 171 | * ) |
104 | * | 172 | * |
105 | * @return Response | 173 | * @return JsonResponse |
106 | */ | 174 | */ |
107 | public function postEntriesAction(Request $request) | 175 | public function postEntriesAction(Request $request) |
108 | { | 176 | { |
@@ -146,7 +214,7 @@ class WallabagRestController extends FOSRestController | |||
146 | 214 | ||
147 | $json = $this->get('serializer')->serialize($entry, 'json'); | 215 | $json = $this->get('serializer')->serialize($entry, 'json'); |
148 | 216 | ||
149 | return $this->renderJsonResponse($json); | 217 | return (new JsonResponse())->setJson($json); |
150 | } | 218 | } |
151 | 219 | ||
152 | /** | 220 | /** |
@@ -164,7 +232,7 @@ class WallabagRestController extends FOSRestController | |||
164 | * } | 232 | * } |
165 | * ) | 233 | * ) |
166 | * | 234 | * |
167 | * @return Response | 235 | * @return JsonResponse |
168 | */ | 236 | */ |
169 | public function patchEntriesAction(Entry $entry, Request $request) | 237 | public function patchEntriesAction(Entry $entry, Request $request) |
170 | { | 238 | { |
@@ -197,7 +265,7 @@ class WallabagRestController extends FOSRestController | |||
197 | 265 | ||
198 | $json = $this->get('serializer')->serialize($entry, 'json'); | 266 | $json = $this->get('serializer')->serialize($entry, 'json'); |
199 | 267 | ||
200 | return $this->renderJsonResponse($json); | 268 | return (new JsonResponse())->setJson($json); |
201 | } | 269 | } |
202 | 270 | ||
203 | /** | 271 | /** |
@@ -209,7 +277,7 @@ class WallabagRestController extends FOSRestController | |||
209 | * } | 277 | * } |
210 | * ) | 278 | * ) |
211 | * | 279 | * |
212 | * @return Response | 280 | * @return JsonResponse |
213 | */ | 281 | */ |
214 | public function deleteEntriesAction(Entry $entry) | 282 | public function deleteEntriesAction(Entry $entry) |
215 | { | 283 | { |
@@ -222,7 +290,7 @@ class WallabagRestController extends FOSRestController | |||
222 | 290 | ||
223 | $json = $this->get('serializer')->serialize($entry, 'json'); | 291 | $json = $this->get('serializer')->serialize($entry, 'json'); |
224 | 292 | ||
225 | return $this->renderJsonResponse($json); | 293 | return (new JsonResponse())->setJson($json); |
226 | } | 294 | } |
227 | 295 | ||
228 | /** | 296 | /** |
@@ -234,7 +302,7 @@ class WallabagRestController extends FOSRestController | |||
234 | * } | 302 | * } |
235 | * ) | 303 | * ) |
236 | * | 304 | * |
237 | * @return Response | 305 | * @return JsonResponse |
238 | */ | 306 | */ |
239 | public function getEntriesTagsAction(Entry $entry) | 307 | public function getEntriesTagsAction(Entry $entry) |
240 | { | 308 | { |
@@ -243,7 +311,7 @@ class WallabagRestController extends FOSRestController | |||
243 | 311 | ||
244 | $json = $this->get('serializer')->serialize($entry->getTags(), 'json'); | 312 | $json = $this->get('serializer')->serialize($entry->getTags(), 'json'); |
245 | 313 | ||
246 | return $this->renderJsonResponse($json); | 314 | return (new JsonResponse())->setJson($json); |
247 | } | 315 | } |
248 | 316 | ||
249 | /** | 317 | /** |
@@ -258,7 +326,7 @@ class WallabagRestController extends FOSRestController | |||
258 | * } | 326 | * } |
259 | * ) | 327 | * ) |
260 | * | 328 | * |
261 | * @return Response | 329 | * @return JsonResponse |
262 | */ | 330 | */ |
263 | public function postEntriesTagsAction(Request $request, Entry $entry) | 331 | public function postEntriesTagsAction(Request $request, Entry $entry) |
264 | { | 332 | { |
@@ -276,7 +344,7 @@ class WallabagRestController extends FOSRestController | |||
276 | 344 | ||
277 | $json = $this->get('serializer')->serialize($entry, 'json'); | 345 | $json = $this->get('serializer')->serialize($entry, 'json'); |
278 | 346 | ||
279 | return $this->renderJsonResponse($json); | 347 | return (new JsonResponse())->setJson($json); |
280 | } | 348 | } |
281 | 349 | ||
282 | /** | 350 | /** |
@@ -289,7 +357,7 @@ class WallabagRestController extends FOSRestController | |||
289 | * } | 357 | * } |
290 | * ) | 358 | * ) |
291 | * | 359 | * |
292 | * @return Response | 360 | * @return JsonResponse |
293 | */ | 361 | */ |
294 | public function deleteEntriesTagsAction(Entry $entry, Tag $tag) | 362 | public function deleteEntriesTagsAction(Entry $entry, Tag $tag) |
295 | { | 363 | { |
@@ -303,7 +371,7 @@ class WallabagRestController extends FOSRestController | |||
303 | 371 | ||
304 | $json = $this->get('serializer')->serialize($entry, 'json'); | 372 | $json = $this->get('serializer')->serialize($entry, 'json'); |
305 | 373 | ||
306 | return $this->renderJsonResponse($json); | 374 | return (new JsonResponse())->setJson($json); |
307 | } | 375 | } |
308 | 376 | ||
309 | /** | 377 | /** |
@@ -311,7 +379,7 @@ class WallabagRestController extends FOSRestController | |||
311 | * | 379 | * |
312 | * @ApiDoc() | 380 | * @ApiDoc() |
313 | * | 381 | * |
314 | * @return Response | 382 | * @return JsonResponse |
315 | */ | 383 | */ |
316 | public function getTagsAction() | 384 | public function getTagsAction() |
317 | { | 385 | { |
@@ -323,7 +391,82 @@ class WallabagRestController extends FOSRestController | |||
323 | 391 | ||
324 | $json = $this->get('serializer')->serialize($tags, 'json'); | 392 | $json = $this->get('serializer')->serialize($tags, 'json'); |
325 | 393 | ||
326 | return $this->renderJsonResponse($json); | 394 | return (new JsonResponse())->setJson($json); |
395 | } | ||
396 | |||
397 | /** | ||
398 | * Permanently remove one tag from **every** entry. | ||
399 | * | ||
400 | * @ApiDoc( | ||
401 | * requirements={ | ||
402 | * {"name"="tag", "dataType"="string", "required"=true, "requirement"="\w+", "description"="Tag as a string"} | ||
403 | * } | ||
404 | * ) | ||
405 | * | ||
406 | * @return JsonResponse | ||
407 | */ | ||
408 | public function deleteTagLabelAction(Request $request) | ||
409 | { | ||
410 | $this->validateAuthentication(); | ||
411 | $label = $request->request->get('tag', ''); | ||
412 | |||
413 | $tag = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($label); | ||
414 | |||
415 | if (empty($tag)) { | ||
416 | throw $this->createNotFoundException('Tag not found'); | ||
417 | } | ||
418 | |||
419 | $this->getDoctrine() | ||
420 | ->getRepository('WallabagCoreBundle:Entry') | ||
421 | ->removeTag($this->getUser()->getId(), $tag); | ||
422 | |||
423 | $this->cleanOrphanTag($tag); | ||
424 | |||
425 | $json = $this->get('serializer')->serialize($tag, 'json'); | ||
426 | |||
427 | return (new JsonResponse())->setJson($json); | ||
428 | } | ||
429 | |||
430 | /** | ||
431 | * Permanently remove some tags from **every** entry. | ||
432 | * | ||
433 | * @ApiDoc( | ||
434 | * requirements={ | ||
435 | * {"name"="tags", "dataType"="string", "required"=true, "format"="tag1,tag2", "description"="Tags as strings (comma splitted)"} | ||
436 | * } | ||
437 | * ) | ||
438 | * | ||
439 | * @return JsonResponse | ||
440 | */ | ||
441 | public function deleteTagsLabelAction(Request $request) | ||
442 | { | ||
443 | $this->validateAuthentication(); | ||
444 | |||
445 | $tagsLabels = $request->request->get('tags', ''); | ||
446 | |||
447 | $tags = []; | ||
448 | |||
449 | foreach (explode(',', $tagsLabels) as $tagLabel) { | ||
450 | $tagEntity = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($tagLabel); | ||
451 | |||
452 | if (!empty($tagEntity)) { | ||
453 | $tags[] = $tagEntity; | ||
454 | } | ||
455 | } | ||
456 | |||
457 | if (empty($tags)) { | ||
458 | throw $this->createNotFoundException('Tags not found'); | ||
459 | } | ||
460 | |||
461 | $this->getDoctrine() | ||
462 | ->getRepository('WallabagCoreBundle:Entry') | ||
463 | ->removeTags($this->getUser()->getId(), $tags); | ||
464 | |||
465 | $this->cleanOrphanTag($tags); | ||
466 | |||
467 | $json = $this->get('serializer')->serialize($tags, 'json'); | ||
468 | |||
469 | return (new JsonResponse())->setJson($json); | ||
327 | } | 470 | } |
328 | 471 | ||
329 | /** | 472 | /** |
@@ -335,7 +478,7 @@ class WallabagRestController extends FOSRestController | |||
335 | * } | 478 | * } |
336 | * ) | 479 | * ) |
337 | * | 480 | * |
338 | * @return Response | 481 | * @return JsonResponse |
339 | */ | 482 | */ |
340 | public function deleteTagAction(Tag $tag) | 483 | public function deleteTagAction(Tag $tag) |
341 | { | 484 | { |
@@ -345,16 +488,19 @@ class WallabagRestController extends FOSRestController | |||
345 | ->getRepository('WallabagCoreBundle:Entry') | 488 | ->getRepository('WallabagCoreBundle:Entry') |
346 | ->removeTag($this->getUser()->getId(), $tag); | 489 | ->removeTag($this->getUser()->getId(), $tag); |
347 | 490 | ||
491 | $this->cleanOrphanTag($tag); | ||
492 | |||
348 | $json = $this->get('serializer')->serialize($tag, 'json'); | 493 | $json = $this->get('serializer')->serialize($tag, 'json'); |
349 | 494 | ||
350 | return $this->renderJsonResponse($json); | 495 | return (new JsonResponse())->setJson($json); |
351 | } | 496 | } |
497 | |||
352 | /** | 498 | /** |
353 | * Retrieve version number. | 499 | * Retrieve version number. |
354 | * | 500 | * |
355 | * @ApiDoc() | 501 | * @ApiDoc() |
356 | * | 502 | * |
357 | * @return Response | 503 | * @return JsonResponse |
358 | */ | 504 | */ |
359 | public function getVersionAction() | 505 | public function getVersionAction() |
360 | { | 506 | { |
@@ -362,7 +508,29 @@ class WallabagRestController extends FOSRestController | |||
362 | 508 | ||
363 | $json = $this->get('serializer')->serialize($version, 'json'); | 509 | $json = $this->get('serializer')->serialize($version, 'json'); |
364 | 510 | ||
365 | return $this->renderJsonResponse($json); | 511 | return (new JsonResponse())->setJson($json); |
512 | } | ||
513 | |||
514 | /** | ||
515 | * Remove orphan tag in case no entries are associated to it. | ||
516 | * | ||
517 | * @param Tag|array $tags | ||
518 | */ | ||
519 | private function cleanOrphanTag($tags) | ||
520 | { | ||
521 | if (!is_array($tags)) { | ||
522 | $tags = [$tags]; | ||
523 | } | ||
524 | |||
525 | $em = $this->getDoctrine()->getManager(); | ||
526 | |||
527 | foreach ($tags as $tag) { | ||
528 | if (count($tag->getEntries()) === 0) { | ||
529 | $em->remove($tag); | ||
530 | } | ||
531 | } | ||
532 | |||
533 | $em->flush(); | ||
366 | } | 534 | } |
367 | 535 | ||
368 | /** | 536 | /** |
@@ -378,17 +546,4 @@ class WallabagRestController extends FOSRestController | |||
378 | throw $this->createAccessDeniedException('Access forbidden. Entry user id: '.$requestUserId.', logged user id: '.$user->getId()); | 546 | throw $this->createAccessDeniedException('Access forbidden. Entry user id: '.$requestUserId.', logged user id: '.$user->getId()); |
379 | } | 547 | } |
380 | } | 548 | } |
381 | |||
382 | /** | ||
383 | * Send a JSON Response. | ||
384 | * We don't use the Symfony JsonRespone, because it takes an array as parameter instead of a JSON string. | ||
385 | * | ||
386 | * @param string $json | ||
387 | * | ||
388 | * @return Response | ||
389 | */ | ||
390 | private function renderJsonResponse($json) | ||
391 | { | ||
392 | return new Response($json, 200, ['application/json']); | ||
393 | } | ||
394 | } | 549 | } |