diff options
author | Nicolas LÅ“uillet <nicolas@loeuillet.org> | 2017-05-01 09:04:41 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-01 09:04:41 +0200 |
commit | 3cbb0cc3ef89873a06bda6583747a2660b989fb8 (patch) | |
tree | 9395ac30e1555c6f473d5c612a8effc406e00bf3 | |
parent | c5e04b0109655ebffff855670935496f49c1aebf (diff) | |
parent | dcbebc17aaa50ea16eb0b7e379c14ebbcf0a645a (diff) | |
download | wallabag-3cbb0cc3ef89873a06bda6583747a2660b989fb8.tar.gz wallabag-3cbb0cc3ef89873a06bda6583747a2660b989fb8.tar.zst wallabag-3cbb0cc3ef89873a06bda6583747a2660b989fb8.zip |
Merge pull request #3055 from wallabag/api-bulk-add-tags
Added API endpoint to handle a list of URL and to add/delete tags
3 files changed, 174 insertions, 3 deletions
diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php index af5f7603..7590efbb 100644 --- a/src/Wallabag/ApiBundle/Controller/EntryRestController.php +++ b/src/Wallabag/ApiBundle/Controller/EntryRestController.php | |||
@@ -438,4 +438,107 @@ class EntryRestController extends WallabagRestController | |||
438 | 438 | ||
439 | return (new JsonResponse())->setJson($json); | 439 | return (new JsonResponse())->setJson($json); |
440 | } | 440 | } |
441 | |||
442 | /** | ||
443 | * Handles an entries list delete tags from them. | ||
444 | * | ||
445 | * @ApiDoc( | ||
446 | * parameters={ | ||
447 | * {"name"="list", "dataType"="string", "required"=true, "format"="A JSON array of urls [{'url': 'http://...','tags': 'tag1, tag2'}, {'url': 'http://...','tags': 'tag1, tag2'}]", "description"="Urls (as an array) to handle."} | ||
448 | * } | ||
449 | * ) | ||
450 | * | ||
451 | * @return JsonResponse | ||
452 | */ | ||
453 | public function deleteEntriesTagsListAction(Request $request) | ||
454 | { | ||
455 | $this->validateAuthentication(); | ||
456 | |||
457 | $list = json_decode($request->query->get('list', [])); | ||
458 | $results = []; | ||
459 | |||
460 | // handle multiple urls | ||
461 | if (!empty($list)) { | ||
462 | foreach ($list as $key => $element) { | ||
463 | $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId( | ||
464 | $element->url, | ||
465 | $this->getUser()->getId() | ||
466 | ); | ||
467 | |||
468 | $results[$key]['url'] = $element->url; | ||
469 | $results[$key]['entry'] = $entry instanceof Entry ? $entry->getId() : false; | ||
470 | |||
471 | $tags = $element->tags; | ||
472 | |||
473 | if (false !== $entry && !(empty($tags))) { | ||
474 | $tags = explode(',', $tags); | ||
475 | foreach ($tags as $label) { | ||
476 | $label = trim($label); | ||
477 | |||
478 | $tag = $this->getDoctrine() | ||
479 | ->getRepository('WallabagCoreBundle:Tag') | ||
480 | ->findOneByLabel($label); | ||
481 | |||
482 | if (false !== $tag) { | ||
483 | $entry->removeTag($tag); | ||
484 | } | ||
485 | } | ||
486 | |||
487 | $em = $this->getDoctrine()->getManager(); | ||
488 | $em->persist($entry); | ||
489 | $em->flush(); | ||
490 | } | ||
491 | } | ||
492 | } | ||
493 | |||
494 | $json = $this->get('serializer')->serialize($results, 'json'); | ||
495 | |||
496 | return (new JsonResponse())->setJson($json); | ||
497 | } | ||
498 | |||
499 | /** | ||
500 | * Handles an entries list and add tags to them. | ||
501 | * | ||
502 | * @ApiDoc( | ||
503 | * parameters={ | ||
504 | * {"name"="list", "dataType"="string", "required"=true, "format"="A JSON array of urls [{'url': 'http://...','tags': 'tag1, tag2'}, {'url': 'http://...','tags': 'tag1, tag2'}]", "description"="Urls (as an array) to handle."} | ||
505 | * } | ||
506 | * ) | ||
507 | * | ||
508 | * @return JsonResponse | ||
509 | */ | ||
510 | public function postEntriesTagsListAction(Request $request) | ||
511 | { | ||
512 | $this->validateAuthentication(); | ||
513 | |||
514 | $list = json_decode($request->query->get('list', [])); | ||
515 | $results = []; | ||
516 | |||
517 | // handle multiple urls | ||
518 | if (!empty($list)) { | ||
519 | foreach ($list as $key => $element) { | ||
520 | $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId( | ||
521 | $element->url, | ||
522 | $this->getUser()->getId() | ||
523 | ); | ||
524 | |||
525 | $results[$key]['url'] = $element->url; | ||
526 | $results[$key]['entry'] = $entry instanceof Entry ? $entry->getId() : false; | ||
527 | |||
528 | $tags = $element->tags; | ||
529 | |||
530 | if (false !== $entry && !(empty($tags))) { | ||
531 | $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags); | ||
532 | |||
533 | $em = $this->getDoctrine()->getManager(); | ||
534 | $em->persist($entry); | ||
535 | $em->flush(); | ||
536 | } | ||
537 | } | ||
538 | } | ||
539 | |||
540 | $json = $this->get('serializer')->serialize($results, 'json'); | ||
541 | |||
542 | return (new JsonResponse())->setJson($json); | ||
543 | } | ||
441 | } | 544 | } |
diff --git a/src/Wallabag/ApiBundle/Controller/TagRestController.php b/src/Wallabag/ApiBundle/Controller/TagRestController.php index bc6d4e64..47298d7e 100644 --- a/src/Wallabag/ApiBundle/Controller/TagRestController.php +++ b/src/Wallabag/ApiBundle/Controller/TagRestController.php | |||
@@ -31,7 +31,7 @@ class TagRestController extends WallabagRestController | |||
31 | } | 31 | } |
32 | 32 | ||
33 | /** | 33 | /** |
34 | * Permanently remove one tag from **every** entry. | 34 | * Permanently remove one tag from **every** entry by passing the Tag label. |
35 | * | 35 | * |
36 | * @ApiDoc( | 36 | * @ApiDoc( |
37 | * requirements={ | 37 | * requirements={ |
@@ -106,7 +106,7 @@ class TagRestController extends WallabagRestController | |||
106 | } | 106 | } |
107 | 107 | ||
108 | /** | 108 | /** |
109 | * Permanently remove one tag from **every** entry. | 109 | * Permanently remove one tag from **every** entry by passing the Tag ID. |
110 | * | 110 | * |
111 | * @ApiDoc( | 111 | * @ApiDoc( |
112 | * requirements={ | 112 | * requirements={ |
diff --git a/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php b/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php index dc5160c7..19fb5170 100644 --- a/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php +++ b/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php | |||
@@ -298,7 +298,7 @@ class EntryRestControllerTest extends WallabagApiTestCase | |||
298 | $entry = $this->client->getContainer() | 298 | $entry = $this->client->getContainer() |
299 | ->get('doctrine.orm.entity_manager') | 299 | ->get('doctrine.orm.entity_manager') |
300 | ->getRepository('WallabagCoreBundle:Entry') | 300 | ->getRepository('WallabagCoreBundle:Entry') |
301 | ->findOneByUser(1); | 301 | ->findOneByUser(1, ['id' => 'asc']); |
302 | 302 | ||
303 | if (!$entry) { | 303 | if (!$entry) { |
304 | $this->markTestSkipped('No content found in db.'); | 304 | $this->markTestSkipped('No content found in db.'); |
@@ -714,4 +714,72 @@ class EntryRestControllerTest extends WallabagApiTestCase | |||
714 | 714 | ||
715 | $this->assertEquals('application/json', $this->client->getResponse()->headers->get('Content-Type')); | 715 | $this->assertEquals('application/json', $this->client->getResponse()->headers->get('Content-Type')); |
716 | } | 716 | } |
717 | |||
718 | public function testPostEntriesTagsListAction() | ||
719 | { | ||
720 | $entry = $this->client->getContainer()->get('doctrine.orm.entity_manager') | ||
721 | ->getRepository('WallabagCoreBundle:Entry') | ||
722 | ->findByUrlAndUserId('http://0.0.0.0/entry4', 1); | ||
723 | |||
724 | $tags = $entry->getTags(); | ||
725 | |||
726 | $this->assertCount(2, $tags); | ||
727 | |||
728 | $list = [ | ||
729 | [ | ||
730 | 'url' => 'http://0.0.0.0/entry4', | ||
731 | 'tags' => 'new tag 1, new tag 2', | ||
732 | ], | ||
733 | ]; | ||
734 | |||
735 | $this->client->request('POST', '/api/entries/tags/lists?list='.json_encode($list)); | ||
736 | |||
737 | $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); | ||
738 | |||
739 | $content = json_decode($this->client->getResponse()->getContent(), true); | ||
740 | |||
741 | $this->assertInternalType('int', $content[0]['entry']); | ||
742 | $this->assertEquals('http://0.0.0.0/entry4', $content[0]['url']); | ||
743 | |||
744 | $entry = $this->client->getContainer()->get('doctrine.orm.entity_manager') | ||
745 | ->getRepository('WallabagCoreBundle:Entry') | ||
746 | ->findByUrlAndUserId('http://0.0.0.0/entry4', 1); | ||
747 | |||
748 | $tags = $entry->getTags(); | ||
749 | $this->assertCount(4, $tags); | ||
750 | } | ||
751 | |||
752 | public function testDeleteEntriesTagsListAction() | ||
753 | { | ||
754 | $entry = $this->client->getContainer()->get('doctrine.orm.entity_manager') | ||
755 | ->getRepository('WallabagCoreBundle:Entry') | ||
756 | ->findByUrlAndUserId('http://0.0.0.0/entry4', 1); | ||
757 | |||
758 | $tags = $entry->getTags(); | ||
759 | |||
760 | $this->assertCount(4, $tags); | ||
761 | |||
762 | $list = [ | ||
763 | [ | ||
764 | 'url' => 'http://0.0.0.0/entry4', | ||
765 | 'tags' => 'new tag 1, new tag 2', | ||
766 | ], | ||
767 | ]; | ||
768 | |||
769 | $this->client->request('DELETE', '/api/entries/tags/list?list='.json_encode($list)); | ||
770 | |||
771 | $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); | ||
772 | |||
773 | $content = json_decode($this->client->getResponse()->getContent(), true); | ||
774 | |||
775 | $this->assertInternalType('int', $content[0]['entry']); | ||
776 | $this->assertEquals('http://0.0.0.0/entry4', $content[0]['url']); | ||
777 | |||
778 | $entry = $this->client->getContainer()->get('doctrine.orm.entity_manager') | ||
779 | ->getRepository('WallabagCoreBundle:Entry') | ||
780 | ->findByUrlAndUserId('http://0.0.0.0/entry4', 1); | ||
781 | |||
782 | $tags = $entry->getTags(); | ||
783 | $this->assertCount(2, $tags); | ||
784 | } | ||
717 | } | 785 | } |