diff options
author | Nicolas LÅ“uillet <nicolas@loeuillet.org> | 2017-05-05 13:56:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-05 13:56:34 +0200 |
commit | 69803049688179e1b03ef424dec91f1b9a4f9e91 (patch) | |
tree | 3171881d9aaba386505ff9b3e3a26c59dcee8f2b /src/Wallabag | |
parent | cebed9c01f20d47cb60259f0c002ea57a80da4d0 (diff) | |
parent | 72db15ca5d7950a604f359056fc6a627f25e4ee4 (diff) | |
download | wallabag-69803049688179e1b03ef424dec91f1b9a4f9e91.tar.gz wallabag-69803049688179e1b03ef424dec91f1b9a4f9e91.tar.zst wallabag-69803049688179e1b03ef424dec91f1b9a4f9e91.zip |
Merge pull request #3053 from wallabag/api-bulk-add
Added API endpoint to handle a list of URL
Diffstat (limited to 'src/Wallabag')
3 files changed, 179 insertions, 76 deletions
diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php index 7590efbb..dbff6065 100644 --- a/src/Wallabag/ApiBundle/Controller/EntryRestController.php +++ b/src/Wallabag/ApiBundle/Controller/EntryRestController.php | |||
@@ -5,6 +5,7 @@ namespace Wallabag\ApiBundle\Controller; | |||
5 | use Hateoas\Configuration\Route; | 5 | use Hateoas\Configuration\Route; |
6 | use Hateoas\Representation\Factory\PagerfantaFactory; | 6 | use Hateoas\Representation\Factory\PagerfantaFactory; |
7 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; | 7 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; |
8 | use Symfony\Component\HttpKernel\Exception\HttpException; | ||
8 | use Symfony\Component\HttpFoundation\Request; | 9 | use Symfony\Component\HttpFoundation\Request; |
9 | use Symfony\Component\HttpFoundation\JsonResponse; | 10 | use Symfony\Component\HttpFoundation\JsonResponse; |
10 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | 11 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; |
@@ -44,9 +45,7 @@ class EntryRestController extends WallabagRestController | |||
44 | $results[$url] = $res instanceof Entry ? $res->getId() : false; | 45 | $results[$url] = $res instanceof Entry ? $res->getId() : false; |
45 | } | 46 | } |
46 | 47 | ||
47 | $json = $this->get('serializer')->serialize($results, 'json'); | 48 | return $this->sendResponse($results); |
48 | |||
49 | return (new JsonResponse())->setJson($json); | ||
50 | } | 49 | } |
51 | 50 | ||
52 | // let's see if it is a simple url? | 51 | // let's see if it is a simple url? |
@@ -62,9 +61,7 @@ class EntryRestController extends WallabagRestController | |||
62 | 61 | ||
63 | $exists = $res instanceof Entry ? $res->getId() : false; | 62 | $exists = $res instanceof Entry ? $res->getId() : false; |
64 | 63 | ||
65 | $json = $this->get('serializer')->serialize(['exists' => $exists], 'json'); | 64 | return $this->sendResponse(['exists' => $exists]); |
66 | |||
67 | return (new JsonResponse())->setJson($json); | ||
68 | } | 65 | } |
69 | 66 | ||
70 | /** | 67 | /** |
@@ -124,9 +121,7 @@ class EntryRestController extends WallabagRestController | |||
124 | ) | 121 | ) |
125 | ); | 122 | ); |
126 | 123 | ||
127 | $json = $this->get('serializer')->serialize($paginatedCollection, 'json'); | 124 | return $this->sendResponse($paginatedCollection); |
128 | |||
129 | return (new JsonResponse())->setJson($json); | ||
130 | } | 125 | } |
131 | 126 | ||
132 | /** | 127 | /** |
@@ -145,9 +140,7 @@ class EntryRestController extends WallabagRestController | |||
145 | $this->validateAuthentication(); | 140 | $this->validateAuthentication(); |
146 | $this->validateUserAccess($entry->getUser()->getId()); | 141 | $this->validateUserAccess($entry->getUser()->getId()); |
147 | 142 | ||
148 | $json = $this->get('serializer')->serialize($entry, 'json'); | 143 | return $this->sendResponse($entry); |
149 | |||
150 | return (new JsonResponse())->setJson($json); | ||
151 | } | 144 | } |
152 | 145 | ||
153 | /** | 146 | /** |
@@ -173,6 +166,110 @@ class EntryRestController extends WallabagRestController | |||
173 | } | 166 | } |
174 | 167 | ||
175 | /** | 168 | /** |
169 | * Handles an entries list and delete URL. | ||
170 | * | ||
171 | * @ApiDoc( | ||
172 | * parameters={ | ||
173 | * {"name"="urls", "dataType"="string", "required"=true, "format"="A JSON array of urls [{'url': 'http://...'}, {'url': 'http://...'}]", "description"="Urls (as an array) to delete."} | ||
174 | * } | ||
175 | * ) | ||
176 | * | ||
177 | * @return JsonResponse | ||
178 | */ | ||
179 | public function deleteEntriesListAction(Request $request) | ||
180 | { | ||
181 | $this->validateAuthentication(); | ||
182 | |||
183 | $urls = json_decode($request->query->get('urls', [])); | ||
184 | |||
185 | if (empty($urls)) { | ||
186 | return $this->sendResponse([]); | ||
187 | } | ||
188 | |||
189 | $results = []; | ||
190 | |||
191 | // handle multiple urls | ||
192 | foreach ($urls as $key => $url) { | ||
193 | $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId( | ||
194 | $url, | ||
195 | $this->getUser()->getId() | ||
196 | ); | ||
197 | |||
198 | $results[$key]['url'] = $url; | ||
199 | |||
200 | if (false !== $entry) { | ||
201 | $em = $this->getDoctrine()->getManager(); | ||
202 | $em->remove($entry); | ||
203 | $em->flush(); | ||
204 | |||
205 | // entry deleted, dispatch event about it! | ||
206 | $this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry)); | ||
207 | } | ||
208 | |||
209 | $results[$key]['entry'] = $entry instanceof Entry ? true : false; | ||
210 | } | ||
211 | |||
212 | return $this->sendResponse($results); | ||
213 | } | ||
214 | |||
215 | /** | ||
216 | * Handles an entries list and create URL. | ||
217 | * | ||
218 | * @ApiDoc( | ||
219 | * parameters={ | ||
220 | * {"name"="urls", "dataType"="string", "required"=true, "format"="A JSON array of urls [{'url': 'http://...'}, {'url': 'http://...'}]", "description"="Urls (as an array) to create."} | ||
221 | * } | ||
222 | * ) | ||
223 | * | ||
224 | * @return JsonResponse | ||
225 | * | ||
226 | * @throws HttpException When limit is reached | ||
227 | */ | ||
228 | public function postEntriesListAction(Request $request) | ||
229 | { | ||
230 | $this->validateAuthentication(); | ||
231 | |||
232 | $urls = json_decode($request->query->get('urls', [])); | ||
233 | $results = []; | ||
234 | |||
235 | $limit = $this->container->getParameter('wallabag_core.api_limit_mass_actions'); | ||
236 | |||
237 | if (count($urls) > $limit) { | ||
238 | throw new HttpException(400, 'API limit reached'); | ||
239 | } | ||
240 | |||
241 | // handle multiple urls | ||
242 | if (!empty($urls)) { | ||
243 | foreach ($urls as $key => $url) { | ||
244 | $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId( | ||
245 | $url, | ||
246 | $this->getUser()->getId() | ||
247 | ); | ||
248 | |||
249 | $results[$key]['url'] = $url; | ||
250 | |||
251 | if (false === $entry) { | ||
252 | $entry = $this->get('wallabag_core.content_proxy')->updateEntry( | ||
253 | new Entry($this->getUser()), | ||
254 | $url | ||
255 | ); | ||
256 | } | ||
257 | |||
258 | $em = $this->getDoctrine()->getManager(); | ||
259 | $em->persist($entry); | ||
260 | $em->flush(); | ||
261 | |||
262 | $results[$key]['entry'] = $entry instanceof Entry ? $entry->getId() : false; | ||
263 | |||
264 | // entry saved, dispatch event about it! | ||
265 | $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); | ||
266 | } | ||
267 | } | ||
268 | |||
269 | return $this->sendResponse($results); | ||
270 | } | ||
271 | |||
272 | /** | ||
176 | * Create an entry. | 273 | * Create an entry. |
177 | * | 274 | * |
178 | * @ApiDoc( | 275 | * @ApiDoc( |
@@ -229,9 +326,7 @@ class EntryRestController extends WallabagRestController | |||
229 | // entry saved, dispatch event about it! | 326 | // entry saved, dispatch event about it! |
230 | $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); | 327 | $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); |
231 | 328 | ||
232 | $json = $this->get('serializer')->serialize($entry, 'json'); | 329 | return $this->sendResponse($entry); |
233 | |||
234 | return (new JsonResponse())->setJson($json); | ||
235 | } | 330 | } |
236 | 331 | ||
237 | /** | 332 | /** |
@@ -280,9 +375,7 @@ class EntryRestController extends WallabagRestController | |||
280 | $em = $this->getDoctrine()->getManager(); | 375 | $em = $this->getDoctrine()->getManager(); |
281 | $em->flush(); | 376 | $em->flush(); |
282 | 377 | ||
283 | $json = $this->get('serializer')->serialize($entry, 'json'); | 378 | return $this->sendResponse($entry); |
284 | |||
285 | return (new JsonResponse())->setJson($json); | ||
286 | } | 379 | } |
287 | 380 | ||
288 | /** | 381 | /** |
@@ -325,9 +418,7 @@ class EntryRestController extends WallabagRestController | |||
325 | // entry saved, dispatch event about it! | 418 | // entry saved, dispatch event about it! |
326 | $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); | 419 | $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); |
327 | 420 | ||
328 | $json = $this->get('serializer')->serialize($entry, 'json'); | 421 | return $this->sendResponse($entry); |
329 | |||
330 | return (new JsonResponse())->setJson($json); | ||
331 | } | 422 | } |
332 | 423 | ||
333 | /** | 424 | /** |
@@ -353,9 +444,7 @@ class EntryRestController extends WallabagRestController | |||
353 | // entry deleted, dispatch event about it! | 444 | // entry deleted, dispatch event about it! |
354 | $this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry)); | 445 | $this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry)); |
355 | 446 | ||
356 | $json = $this->get('serializer')->serialize($entry, 'json'); | 447 | return $this->sendResponse($entry); |
357 | |||
358 | return (new JsonResponse())->setJson($json); | ||
359 | } | 448 | } |
360 | 449 | ||
361 | /** | 450 | /** |
@@ -374,9 +463,7 @@ class EntryRestController extends WallabagRestController | |||
374 | $this->validateAuthentication(); | 463 | $this->validateAuthentication(); |
375 | $this->validateUserAccess($entry->getUser()->getId()); | 464 | $this->validateUserAccess($entry->getUser()->getId()); |
376 | 465 | ||
377 | $json = $this->get('serializer')->serialize($entry->getTags(), 'json'); | 466 | return $this->sendResponse($entry->getTags()); |
378 | |||
379 | return (new JsonResponse())->setJson($json); | ||
380 | } | 467 | } |
381 | 468 | ||
382 | /** | 469 | /** |
@@ -407,9 +494,7 @@ class EntryRestController extends WallabagRestController | |||
407 | $em->persist($entry); | 494 | $em->persist($entry); |
408 | $em->flush(); | 495 | $em->flush(); |
409 | 496 | ||
410 | $json = $this->get('serializer')->serialize($entry, 'json'); | 497 | return $this->sendResponse($entry); |
411 | |||
412 | return (new JsonResponse())->setJson($json); | ||
413 | } | 498 | } |
414 | 499 | ||
415 | /** | 500 | /** |
@@ -434,9 +519,7 @@ class EntryRestController extends WallabagRestController | |||
434 | $em->persist($entry); | 519 | $em->persist($entry); |
435 | $em->flush(); | 520 | $em->flush(); |
436 | 521 | ||
437 | $json = $this->get('serializer')->serialize($entry, 'json'); | 522 | return $this->sendResponse($entry); |
438 | |||
439 | return (new JsonResponse())->setJson($json); | ||
440 | } | 523 | } |
441 | 524 | ||
442 | /** | 525 | /** |
@@ -455,45 +538,46 @@ class EntryRestController extends WallabagRestController | |||
455 | $this->validateAuthentication(); | 538 | $this->validateAuthentication(); |
456 | 539 | ||
457 | $list = json_decode($request->query->get('list', [])); | 540 | $list = json_decode($request->query->get('list', [])); |
458 | $results = []; | 541 | |
542 | if (empty($list)) { | ||
543 | return $this->sendResponse([]); | ||
544 | } | ||
459 | 545 | ||
460 | // handle multiple urls | 546 | // handle multiple urls |
461 | if (!empty($list)) { | 547 | $results = []; |
462 | foreach ($list as $key => $element) { | ||
463 | $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId( | ||
464 | $element->url, | ||
465 | $this->getUser()->getId() | ||
466 | ); | ||
467 | 548 | ||
468 | $results[$key]['url'] = $element->url; | 549 | foreach ($list as $key => $element) { |
469 | $results[$key]['entry'] = $entry instanceof Entry ? $entry->getId() : false; | 550 | $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId( |
551 | $element->url, | ||
552 | $this->getUser()->getId() | ||
553 | ); | ||
470 | 554 | ||
471 | $tags = $element->tags; | 555 | $results[$key]['url'] = $element->url; |
556 | $results[$key]['entry'] = $entry instanceof Entry ? $entry->getId() : false; | ||
472 | 557 | ||
473 | if (false !== $entry && !(empty($tags))) { | 558 | $tags = $element->tags; |
474 | $tags = explode(',', $tags); | ||
475 | foreach ($tags as $label) { | ||
476 | $label = trim($label); | ||
477 | 559 | ||
478 | $tag = $this->getDoctrine() | 560 | if (false !== $entry && !(empty($tags))) { |
479 | ->getRepository('WallabagCoreBundle:Tag') | 561 | $tags = explode(',', $tags); |
480 | ->findOneByLabel($label); | 562 | foreach ($tags as $label) { |
563 | $label = trim($label); | ||
481 | 564 | ||
482 | if (false !== $tag) { | 565 | $tag = $this->getDoctrine() |
483 | $entry->removeTag($tag); | 566 | ->getRepository('WallabagCoreBundle:Tag') |
484 | } | 567 | ->findOneByLabel($label); |
485 | } | ||
486 | 568 | ||
487 | $em = $this->getDoctrine()->getManager(); | 569 | if (false !== $tag) { |
488 | $em->persist($entry); | 570 | $entry->removeTag($tag); |
489 | $em->flush(); | 571 | } |
490 | } | 572 | } |
573 | |||
574 | $em = $this->getDoctrine()->getManager(); | ||
575 | $em->persist($entry); | ||
576 | $em->flush(); | ||
491 | } | 577 | } |
492 | } | 578 | } |
493 | 579 | ||
494 | $json = $this->get('serializer')->serialize($results, 'json'); | 580 | return $this->sendResponse($results); |
495 | |||
496 | return (new JsonResponse())->setJson($json); | ||
497 | } | 581 | } |
498 | 582 | ||
499 | /** | 583 | /** |
@@ -512,32 +596,47 @@ class EntryRestController extends WallabagRestController | |||
512 | $this->validateAuthentication(); | 596 | $this->validateAuthentication(); |
513 | 597 | ||
514 | $list = json_decode($request->query->get('list', [])); | 598 | $list = json_decode($request->query->get('list', [])); |
599 | |||
600 | if (empty($list)) { | ||
601 | return $this->sendResponse([]); | ||
602 | } | ||
603 | |||
515 | $results = []; | 604 | $results = []; |
516 | 605 | ||
517 | // handle multiple urls | 606 | // handle multiple urls |
518 | if (!empty($list)) { | 607 | foreach ($list as $key => $element) { |
519 | foreach ($list as $key => $element) { | 608 | $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId( |
520 | $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId( | 609 | $element->url, |
521 | $element->url, | 610 | $this->getUser()->getId() |
522 | $this->getUser()->getId() | 611 | ); |
523 | ); | ||
524 | 612 | ||
525 | $results[$key]['url'] = $element->url; | 613 | $results[$key]['url'] = $element->url; |
526 | $results[$key]['entry'] = $entry instanceof Entry ? $entry->getId() : false; | 614 | $results[$key]['entry'] = $entry instanceof Entry ? $entry->getId() : false; |
527 | 615 | ||
528 | $tags = $element->tags; | 616 | $tags = $element->tags; |
529 | 617 | ||
530 | if (false !== $entry && !(empty($tags))) { | 618 | if (false !== $entry && !(empty($tags))) { |
531 | $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags); | 619 | $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags); |
532 | 620 | ||
533 | $em = $this->getDoctrine()->getManager(); | 621 | $em = $this->getDoctrine()->getManager(); |
534 | $em->persist($entry); | 622 | $em->persist($entry); |
535 | $em->flush(); | 623 | $em->flush(); |
536 | } | ||
537 | } | 624 | } |
538 | } | 625 | } |
539 | 626 | ||
540 | $json = $this->get('serializer')->serialize($results, 'json'); | 627 | return $this->sendResponse($results); |
628 | } | ||
629 | |||
630 | /** | ||
631 | * Shortcut to send data serialized in json. | ||
632 | * | ||
633 | * @param mixed $data | ||
634 | * | ||
635 | * @return JsonResponse | ||
636 | */ | ||
637 | private function sendResponse($data) | ||
638 | { | ||
639 | $json = $this->get('serializer')->serialize($data, 'json'); | ||
541 | 640 | ||
542 | return (new JsonResponse())->setJson($json); | 641 | return (new JsonResponse())->setJson($json); |
543 | } | 642 | } |
diff --git a/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php b/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php index 006a18c3..75b37729 100644 --- a/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php +++ b/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php | |||
@@ -47,6 +47,9 @@ class Configuration implements ConfigurationInterface | |||
47 | ->scalarNode('list_mode') | 47 | ->scalarNode('list_mode') |
48 | ->defaultValue(1) | 48 | ->defaultValue(1) |
49 | ->end() | 49 | ->end() |
50 | ->scalarNode('api_limit_mass_actions') | ||
51 | ->defaultValue(10) | ||
52 | ->end() | ||
50 | ->end() | 53 | ->end() |
51 | ; | 54 | ; |
52 | 55 | ||
diff --git a/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php b/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php index aa9ee339..c075c19f 100644 --- a/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php +++ b/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php | |||
@@ -26,6 +26,7 @@ class WallabagCoreExtension extends Extension | |||
26 | $container->setParameter('wallabag_core.action_mark_as_read', $config['action_mark_as_read']); | 26 | $container->setParameter('wallabag_core.action_mark_as_read', $config['action_mark_as_read']); |
27 | $container->setParameter('wallabag_core.list_mode', $config['list_mode']); | 27 | $container->setParameter('wallabag_core.list_mode', $config['list_mode']); |
28 | $container->setParameter('wallabag_core.fetching_error_message', $config['fetching_error_message']); | 28 | $container->setParameter('wallabag_core.fetching_error_message', $config['fetching_error_message']); |
29 | $container->setParameter('wallabag_core.api_limit_mass_actions', $config['api_limit_mass_actions']); | ||
29 | 30 | ||
30 | $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); | 31 | $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); |
31 | $loader->load('services.yml'); | 32 | $loader->load('services.yml'); |