diff options
Diffstat (limited to 'src/Wallabag/ApiBundle/Controller')
4 files changed, 143 insertions, 37 deletions
diff --git a/src/Wallabag/ApiBundle/Controller/DeveloperController.php b/src/Wallabag/ApiBundle/Controller/DeveloperController.php index c7178017..ae7e83da 100644 --- a/src/Wallabag/ApiBundle/Controller/DeveloperController.php +++ b/src/Wallabag/ApiBundle/Controller/DeveloperController.php | |||
@@ -2,9 +2,9 @@ | |||
2 | 2 | ||
3 | namespace Wallabag\ApiBundle\Controller; | 3 | namespace Wallabag\ApiBundle\Controller; |
4 | 4 | ||
5 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | ||
6 | use Symfony\Bundle\FrameworkBundle\Controller\Controller; | 5 | use Symfony\Bundle\FrameworkBundle\Controller\Controller; |
7 | use Symfony\Component\HttpFoundation\Request; | 6 | use Symfony\Component\HttpFoundation\Request; |
7 | use Symfony\Component\Routing\Annotation\Route; | ||
8 | use Wallabag\ApiBundle\Entity\Client; | 8 | use Wallabag\ApiBundle\Entity\Client; |
9 | use Wallabag\ApiBundle\Form\Type\ClientType; | 9 | use Wallabag\ApiBundle\Form\Type\ClientType; |
10 | 10 | ||
diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php index 33b75665..aff0534a 100644 --- a/src/Wallabag/ApiBundle/Controller/EntryRestController.php +++ b/src/Wallabag/ApiBundle/Controller/EntryRestController.php | |||
@@ -4,14 +4,12 @@ namespace Wallabag\ApiBundle\Controller; | |||
4 | 4 | ||
5 | use Hateoas\Configuration\Route; | 5 | use Hateoas\Configuration\Route; |
6 | use Hateoas\Representation\Factory\PagerfantaFactory; | 6 | use Hateoas\Representation\Factory\PagerfantaFactory; |
7 | use JMS\Serializer\SerializationContext; | ||
8 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; | 7 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; |
9 | use Symfony\Component\HttpFoundation\JsonResponse; | 8 | use Symfony\Component\HttpFoundation\JsonResponse; |
10 | use Symfony\Component\HttpFoundation\Request; | 9 | use Symfony\Component\HttpFoundation\Request; |
11 | use Symfony\Component\HttpFoundation\Response; | 10 | use Symfony\Component\HttpFoundation\Response; |
12 | use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; | 11 | use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; |
13 | use Symfony\Component\HttpKernel\Exception\HttpException; | 12 | use Symfony\Component\HttpKernel\Exception\HttpException; |
14 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | ||
15 | use Wallabag\CoreBundle\Entity\Entry; | 13 | use Wallabag\CoreBundle\Entity\Entry; |
16 | use Wallabag\CoreBundle\Entity\Tag; | 14 | use Wallabag\CoreBundle\Entity\Tag; |
17 | use Wallabag\CoreBundle\Event\EntryDeletedEvent; | 15 | use Wallabag\CoreBundle\Event\EntryDeletedEvent; |
@@ -29,8 +27,10 @@ class EntryRestController extends WallabagRestController | |||
29 | * @ApiDoc( | 27 | * @ApiDoc( |
30 | * parameters={ | 28 | * parameters={ |
31 | * {"name"="return_id", "dataType"="string", "required"=false, "format"="1 or 0", "description"="Set 1 if you want to retrieve ID in case entry(ies) exists, 0 by default"}, | 29 | * {"name"="return_id", "dataType"="string", "required"=false, "format"="1 or 0", "description"="Set 1 if you want to retrieve ID in case entry(ies) exists, 0 by default"}, |
32 | * {"name"="url", "dataType"="string", "required"=true, "format"="An url", "description"="Url to check if it exists"}, | 30 | * {"name"="url", "dataType"="string", "required"=true, "format"="An url", "description"="DEPRECATED, use hashed_url instead"}, |
33 | * {"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"} | 31 | * {"name"="urls", "dataType"="string", "required"=false, "format"="An array of urls (?urls[]=http...&urls[]=http...)", "description"="DEPRECATED, use hashed_urls instead"}, |
32 | * {"name"="hashed_url", "dataType"="string", "required"=false, "format"="A hashed url", "description"="Hashed url using SHA1 to check if it exists"}, | ||
33 | * {"name"="hashed_urls", "dataType"="string", "required"=false, "format"="An array of hashed urls (?hashed_urls[]=xxx...&hashed_urls[]=xxx...)", "description"="An array of hashed urls using SHA1 to check if they exist"} | ||
34 | * } | 34 | * } |
35 | * ) | 35 | * ) |
36 | * | 36 | * |
@@ -39,17 +39,30 @@ class EntryRestController extends WallabagRestController | |||
39 | public function getEntriesExistsAction(Request $request) | 39 | public function getEntriesExistsAction(Request $request) |
40 | { | 40 | { |
41 | $this->validateAuthentication(); | 41 | $this->validateAuthentication(); |
42 | $repo = $this->getDoctrine()->getRepository('WallabagCoreBundle:Entry'); | ||
42 | 43 | ||
43 | $returnId = (null === $request->query->get('return_id')) ? false : (bool) $request->query->get('return_id'); | 44 | $returnId = (null === $request->query->get('return_id')) ? false : (bool) $request->query->get('return_id'); |
45 | |||
44 | $urls = $request->query->get('urls', []); | 46 | $urls = $request->query->get('urls', []); |
47 | $hashedUrls = $request->query->get('hashed_urls', []); | ||
45 | 48 | ||
46 | // handle multiple urls first | 49 | // handle multiple urls first |
50 | if (!empty($hashedUrls)) { | ||
51 | $results = []; | ||
52 | foreach ($hashedUrls as $hashedUrl) { | ||
53 | $res = $repo->findByHashedUrlAndUserId($hashedUrl, $this->getUser()->getId()); | ||
54 | |||
55 | $results[$hashedUrl] = $this->returnExistInformation($res, $returnId); | ||
56 | } | ||
57 | |||
58 | return $this->sendResponse($results); | ||
59 | } | ||
60 | |||
61 | // @deprecated, to be remove in 3.0 | ||
47 | if (!empty($urls)) { | 62 | if (!empty($urls)) { |
48 | $results = []; | 63 | $results = []; |
49 | foreach ($urls as $url) { | 64 | foreach ($urls as $url) { |
50 | $res = $this->getDoctrine() | 65 | $res = $repo->findByUrlAndUserId($url, $this->getUser()->getId()); |
51 | ->getRepository('WallabagCoreBundle:Entry') | ||
52 | ->findByUrlAndUserId($url, $this->getUser()->getId()); | ||
53 | 66 | ||
54 | $results[$url] = $this->returnExistInformation($res, $returnId); | 67 | $results[$url] = $this->returnExistInformation($res, $returnId); |
55 | } | 68 | } |
@@ -59,18 +72,21 @@ class EntryRestController extends WallabagRestController | |||
59 | 72 | ||
60 | // let's see if it is a simple url? | 73 | // let's see if it is a simple url? |
61 | $url = $request->query->get('url', ''); | 74 | $url = $request->query->get('url', ''); |
75 | $hashedUrl = $request->query->get('hashed_url', ''); | ||
62 | 76 | ||
63 | if (empty($url)) { | 77 | if (empty($url) && empty($hashedUrl)) { |
64 | throw $this->createAccessDeniedException('URL is empty?, logged user id: ' . $this->getUser()->getId()); | 78 | throw $this->createAccessDeniedException('URL is empty?, logged user id: ' . $this->getUser()->getId()); |
65 | } | 79 | } |
66 | 80 | ||
67 | $res = $this->getDoctrine() | 81 | $method = 'findByUrlAndUserId'; |
68 | ->getRepository('WallabagCoreBundle:Entry') | 82 | if (!empty($hashedUrl)) { |
69 | ->findByUrlAndUserId($url, $this->getUser()->getId()); | 83 | $method = 'findByHashedUrlAndUserId'; |
84 | $url = $hashedUrl; | ||
85 | } | ||
70 | 86 | ||
71 | $exists = $this->returnExistInformation($res, $returnId); | 87 | $res = $repo->$method($url, $this->getUser()->getId()); |
72 | 88 | ||
73 | return $this->sendResponse(['exists' => $exists]); | 89 | return $this->sendResponse(['exists' => $this->returnExistInformation($res, $returnId)]); |
74 | } | 90 | } |
75 | 91 | ||
76 | /** | 92 | /** |
@@ -80,13 +96,14 @@ class EntryRestController extends WallabagRestController | |||
80 | * parameters={ | 96 | * parameters={ |
81 | * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by archived status."}, | 97 | * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by archived status."}, |
82 | * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by starred status."}, | 98 | * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by starred status."}, |
83 | * {"name"="sort", "dataType"="string", "required"=false, "format"="'created' or 'updated', default 'created'", "description"="sort entries by date."}, | 99 | * {"name"="sort", "dataType"="string", "required"=false, "format"="'created' or 'updated' or 'archived', default 'created'", "description"="sort entries by date."}, |
84 | * {"name"="order", "dataType"="string", "required"=false, "format"="'asc' or 'desc', default 'desc'", "description"="order of sort."}, | 100 | * {"name"="order", "dataType"="string", "required"=false, "format"="'asc' or 'desc', default 'desc'", "description"="order of sort."}, |
85 | * {"name"="page", "dataType"="integer", "required"=false, "format"="default '1'", "description"="what page you want."}, | 101 | * {"name"="page", "dataType"="integer", "required"=false, "format"="default '1'", "description"="what page you want."}, |
86 | * {"name"="perPage", "dataType"="integer", "required"=false, "format"="default'30'", "description"="results per page."}, | 102 | * {"name"="perPage", "dataType"="integer", "required"=false, "format"="default'30'", "description"="results per page."}, |
87 | * {"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."}, |
88 | * {"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."}, |
89 | * {"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."}, | ||
90 | * } | 107 | * } |
91 | * ) | 108 | * ) |
92 | * | 109 | * |
@@ -105,6 +122,7 @@ class EntryRestController extends WallabagRestController | |||
105 | $perPage = (int) $request->query->get('perPage', 30); | 122 | $perPage = (int) $request->query->get('perPage', 30); |
106 | $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', ''); |
107 | $since = $request->query->get('since', 0); | 124 | $since = $request->query->get('since', 0); |
125 | $detail = strtolower($request->query->get('detail', 'full')); | ||
108 | 126 | ||
109 | try { | 127 | try { |
110 | /** @var \Pagerfanta\Pagerfanta $pager */ | 128 | /** @var \Pagerfanta\Pagerfanta $pager */ |
@@ -116,7 +134,8 @@ class EntryRestController extends WallabagRestController | |||
116 | $sort, | 134 | $sort, |
117 | $order, | 135 | $order, |
118 | $since, | 136 | $since, |
119 | $tags | 137 | $tags, |
138 | $detail | ||
120 | ); | 139 | ); |
121 | } catch (\Exception $e) { | 140 | } catch (\Exception $e) { |
122 | throw new BadRequestHttpException($e->getMessage()); | 141 | throw new BadRequestHttpException($e->getMessage()); |
@@ -140,8 +159,9 @@ class EntryRestController extends WallabagRestController | |||
140 | 'perPage' => $perPage, | 159 | 'perPage' => $perPage, |
141 | 'tags' => $tags, | 160 | 'tags' => $tags, |
142 | 'since' => $since, | 161 | 'since' => $since, |
162 | 'detail' => $detail, | ||
143 | ], | 163 | ], |
144 | UrlGeneratorInterface::ABSOLUTE_URL | 164 | true |
145 | ) | 165 | ) |
146 | ); | 166 | ); |
147 | 167 | ||
@@ -363,7 +383,7 @@ class EntryRestController extends WallabagRestController | |||
363 | } | 383 | } |
364 | 384 | ||
365 | if (null !== $data['isArchived']) { | 385 | if (null !== $data['isArchived']) { |
366 | $entry->setArchived((bool) $data['isArchived']); | 386 | $entry->updateArchived((bool) $data['isArchived']); |
367 | } | 387 | } |
368 | 388 | ||
369 | if (null !== $data['isStarred']) { | 389 | if (null !== $data['isStarred']) { |
@@ -479,7 +499,7 @@ class EntryRestController extends WallabagRestController | |||
479 | } | 499 | } |
480 | 500 | ||
481 | if (null !== $data['isArchived']) { | 501 | if (null !== $data['isArchived']) { |
482 | $entry->setArchived((bool) $data['isArchived']); | 502 | $entry->updateArchived((bool) $data['isArchived']); |
483 | } | 503 | } |
484 | 504 | ||
485 | if (null !== $data['isStarred']) { | 505 | if (null !== $data['isStarred']) { |
@@ -787,24 +807,6 @@ class EntryRestController extends WallabagRestController | |||
787 | } | 807 | } |
788 | 808 | ||
789 | /** | 809 | /** |
790 | * Shortcut to send data serialized in json. | ||
791 | * | ||
792 | * @param mixed $data | ||
793 | * | ||
794 | * @return JsonResponse | ||
795 | */ | ||
796 | private function sendResponse($data) | ||
797 | { | ||
798 | // https://github.com/schmittjoh/JMSSerializerBundle/issues/293 | ||
799 | $context = new SerializationContext(); | ||
800 | $context->setSerializeNull(true); | ||
801 | |||
802 | $json = $this->get('jms_serializer')->serialize($data, 'json', $context); | ||
803 | |||
804 | return (new JsonResponse())->setJson($json); | ||
805 | } | ||
806 | |||
807 | /** | ||
808 | * Retrieve value from the request. | 810 | * Retrieve value from the request. |
809 | * Used for POST & PATCH on a an entry. | 811 | * Used for POST & PATCH on a an entry. |
810 | * | 812 | * |
diff --git a/src/Wallabag/ApiBundle/Controller/SearchRestController.php b/src/Wallabag/ApiBundle/Controller/SearchRestController.php new file mode 100644 index 00000000..d9f99844 --- /dev/null +++ b/src/Wallabag/ApiBundle/Controller/SearchRestController.php | |||
@@ -0,0 +1,65 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\ApiBundle\Controller; | ||
4 | |||
5 | use Hateoas\Configuration\Route; | ||
6 | use Hateoas\Representation\Factory\PagerfantaFactory; | ||
7 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; | ||
8 | use Pagerfanta\Adapter\DoctrineORMAdapter; | ||
9 | use Pagerfanta\Pagerfanta; | ||
10 | use Symfony\Component\HttpFoundation\JsonResponse; | ||
11 | use Symfony\Component\HttpFoundation\Request; | ||
12 | |||
13 | class SearchRestController extends WallabagRestController | ||
14 | { | ||
15 | /** | ||
16 | * Search all entries by term. | ||
17 | * | ||
18 | * @ApiDoc( | ||
19 | * parameters={ | ||
20 | * {"name"="term", "dataType"="string", "required"=false, "format"="any", "description"="Any query term"}, | ||
21 | * {"name"="page", "dataType"="integer", "required"=false, "format"="default '1'", "description"="what page you want."}, | ||
22 | * {"name"="perPage", "dataType"="integer", "required"=false, "format"="default'30'", "description"="results per page."} | ||
23 | * } | ||
24 | * ) | ||
25 | * | ||
26 | * @return JsonResponse | ||
27 | */ | ||
28 | public function getSearchAction(Request $request) | ||
29 | { | ||
30 | $this->validateAuthentication(); | ||
31 | |||
32 | $term = $request->query->get('term'); | ||
33 | $page = (int) $request->query->get('page', 1); | ||
34 | $perPage = (int) $request->query->get('perPage', 30); | ||
35 | |||
36 | $qb = $this->get('wallabag_core.entry_repository') | ||
37 | ->getBuilderForSearchByUser( | ||
38 | $this->getUser()->getId(), | ||
39 | $term, | ||
40 | null | ||
41 | ); | ||
42 | |||
43 | $pagerAdapter = new DoctrineORMAdapter($qb->getQuery(), true, false); | ||
44 | $pager = new Pagerfanta($pagerAdapter); | ||
45 | |||
46 | $pager->setMaxPerPage($perPage); | ||
47 | $pager->setCurrentPage($page); | ||
48 | |||
49 | $pagerfantaFactory = new PagerfantaFactory('page', 'perPage'); | ||
50 | $paginatedCollection = $pagerfantaFactory->createRepresentation( | ||
51 | $pager, | ||
52 | new Route( | ||
53 | 'api_get_search', | ||
54 | [ | ||
55 | 'term' => $term, | ||
56 | 'page' => $page, | ||
57 | 'perPage' => $perPage, | ||
58 | ], | ||
59 | true | ||
60 | ) | ||
61 | ); | ||
62 | |||
63 | return $this->sendResponse($paginatedCollection); | ||
64 | } | ||
65 | } | ||
diff --git a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php index 7d8cfbba..f18b0910 100644 --- a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php +++ b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php | |||
@@ -3,6 +3,7 @@ | |||
3 | namespace Wallabag\ApiBundle\Controller; | 3 | namespace Wallabag\ApiBundle\Controller; |
4 | 4 | ||
5 | use FOS\RestBundle\Controller\FOSRestController; | 5 | use FOS\RestBundle\Controller\FOSRestController; |
6 | use JMS\Serializer\SerializationContext; | ||
6 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; | 7 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; |
7 | use Symfony\Component\HttpFoundation\JsonResponse; | 8 | use Symfony\Component\HttpFoundation\JsonResponse; |
8 | use Symfony\Component\Security\Core\Exception\AccessDeniedException; | 9 | use Symfony\Component\Security\Core\Exception\AccessDeniedException; |
@@ -14,6 +15,8 @@ class WallabagRestController extends FOSRestController | |||
14 | * | 15 | * |
15 | * @ApiDoc() | 16 | * @ApiDoc() |
16 | * | 17 | * |
18 | * @deprecated Should use info endpoint instead | ||
19 | * | ||
17 | * @return JsonResponse | 20 | * @return JsonResponse |
18 | */ | 21 | */ |
19 | public function getVersionAction() | 22 | public function getVersionAction() |
@@ -24,6 +27,24 @@ class WallabagRestController extends FOSRestController | |||
24 | return (new JsonResponse())->setJson($json); | 27 | return (new JsonResponse())->setJson($json); |
25 | } | 28 | } |
26 | 29 | ||
30 | /** | ||
31 | * Retrieve information about the wallabag instance. | ||
32 | * | ||
33 | * @ApiDoc() | ||
34 | * | ||
35 | * @return JsonResponse | ||
36 | */ | ||
37 | public function getInfoAction() | ||
38 | { | ||
39 | $info = [ | ||
40 | 'appname' => 'wallabag', | ||
41 | 'version' => $this->container->getParameter('wallabag_core.version'), | ||
42 | 'allowed_registration' => $this->container->getParameter('wallabag_user.registration_enabled'), | ||
43 | ]; | ||
44 | |||
45 | return (new JsonResponse())->setJson($this->get('jms_serializer')->serialize($info, 'json')); | ||
46 | } | ||
47 | |||
27 | protected function validateAuthentication() | 48 | protected function validateAuthentication() |
28 | { | 49 | { |
29 | if (false === $this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) { | 50 | if (false === $this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) { |
@@ -44,4 +65,22 @@ class WallabagRestController extends FOSRestController | |||
44 | throw $this->createAccessDeniedException('Access forbidden. Entry user id: ' . $requestUserId . ', logged user id: ' . $user->getId()); | 65 | throw $this->createAccessDeniedException('Access forbidden. Entry user id: ' . $requestUserId . ', logged user id: ' . $user->getId()); |
45 | } | 66 | } |
46 | } | 67 | } |
68 | |||
69 | /** | ||
70 | * Shortcut to send data serialized in json. | ||
71 | * | ||
72 | * @param mixed $data | ||
73 | * | ||
74 | * @return JsonResponse | ||
75 | */ | ||
76 | protected function sendResponse($data) | ||
77 | { | ||
78 | // https://github.com/schmittjoh/JMSSerializerBundle/issues/293 | ||
79 | $context = new SerializationContext(); | ||
80 | $context->setSerializeNull(true); | ||
81 | |||
82 | $json = $this->get('jms_serializer')->serialize($data, 'json', $context); | ||
83 | |||
84 | return (new JsonResponse())->setJson($json); | ||
85 | } | ||
47 | } | 86 | } |