diff options
author | lizyn <zhiylin@outlook.com> | 2020-02-24 10:04:13 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-24 10:04:13 +0800 |
commit | b19df31d78d881a43bcf6b3215e5fc3781e8e8aa (patch) | |
tree | d0d9861694a4b5e5fbfdbeb53c255ecd15fe9328 /src/Wallabag/ApiBundle/Controller | |
parent | 4d0c632c70ea50d459c3c55ddda2e0f394dd51cb (diff) | |
parent | 04d918cae0227c06a41d27fb6533dddbf30dfe71 (diff) | |
download | wallabag-b19df31d78d881a43bcf6b3215e5fc3781e8e8aa.tar.gz wallabag-b19df31d78d881a43bcf6b3215e5fc3781e8e8aa.tar.zst wallabag-b19df31d78d881a43bcf6b3215e5fc3781e8e8aa.zip |
Merge pull request #1 from wallabag/master
Keep up with the master again
Diffstat (limited to 'src/Wallabag/ApiBundle/Controller')
8 files changed, 255 insertions, 97 deletions
diff --git a/src/Wallabag/ApiBundle/Controller/AnnotationRestController.php b/src/Wallabag/ApiBundle/Controller/AnnotationRestController.php index 28d55ba9..66693189 100644 --- a/src/Wallabag/ApiBundle/Controller/AnnotationRestController.php +++ b/src/Wallabag/ApiBundle/Controller/AnnotationRestController.php | |||
@@ -20,8 +20,6 @@ class AnnotationRestController extends WallabagRestController | |||
20 | * } | 20 | * } |
21 | * ) | 21 | * ) |
22 | * | 22 | * |
23 | * @param Entry $entry | ||
24 | * | ||
25 | * @return JsonResponse | 23 | * @return JsonResponse |
26 | */ | 24 | */ |
27 | public function getAnnotationsAction(Entry $entry) | 25 | public function getAnnotationsAction(Entry $entry) |
@@ -39,14 +37,11 @@ class AnnotationRestController extends WallabagRestController | |||
39 | * @ApiDoc( | 37 | * @ApiDoc( |
40 | * requirements={ | 38 | * requirements={ |
41 | * {"name"="ranges", "dataType"="array", "requirement"="\w+", "description"="The range array for the annotation"}, | 39 | * {"name"="ranges", "dataType"="array", "requirement"="\w+", "description"="The range array for the annotation"}, |
42 | * {"name"="quote", "dataType"="string", "required"=false, "description"="Optional, quote for the annotation"}, | 40 | * {"name"="quote", "dataType"="string", "description"="The annotated text"}, |
43 | * {"name"="text", "dataType"="string", "required"=true, "description"=""}, | 41 | * {"name"="text", "dataType"="string", "required"=true, "description"="Content of annotation"}, |
44 | * } | 42 | * } |
45 | * ) | 43 | * ) |
46 | * | 44 | * |
47 | * @param Request $request | ||
48 | * @param Entry $entry | ||
49 | * | ||
50 | * @return JsonResponse | 45 | * @return JsonResponse |
51 | */ | 46 | */ |
52 | public function postAnnotationAction(Request $request, Entry $entry) | 47 | public function postAnnotationAction(Request $request, Entry $entry) |
@@ -70,9 +65,6 @@ class AnnotationRestController extends WallabagRestController | |||
70 | * | 65 | * |
71 | * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation") | 66 | * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation") |
72 | * | 67 | * |
73 | * @param Annotation $annotation | ||
74 | * @param Request $request | ||
75 | * | ||
76 | * @return JsonResponse | 68 | * @return JsonResponse |
77 | */ | 69 | */ |
78 | public function putAnnotationAction(Annotation $annotation, Request $request) | 70 | public function putAnnotationAction(Annotation $annotation, Request $request) |
@@ -96,8 +88,6 @@ class AnnotationRestController extends WallabagRestController | |||
96 | * | 88 | * |
97 | * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation") | 89 | * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation") |
98 | * | 90 | * |
99 | * @param Annotation $annotation | ||
100 | * | ||
101 | * @return JsonResponse | 91 | * @return JsonResponse |
102 | */ | 92 | */ |
103 | public function deleteAnnotationAction(Annotation $annotation) | 93 | public function deleteAnnotationAction(Annotation $annotation) |
diff --git a/src/Wallabag/ApiBundle/Controller/DeveloperController.php b/src/Wallabag/ApiBundle/Controller/DeveloperController.php index c7178017..3224d789 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 | ||
@@ -29,8 +29,6 @@ class DeveloperController extends Controller | |||
29 | /** | 29 | /** |
30 | * Create a client (an app). | 30 | * Create a client (an app). |
31 | * | 31 | * |
32 | * @param Request $request | ||
33 | * | ||
34 | * @Route("/developer/client/create", name="developer_create_client") | 32 | * @Route("/developer/client/create", name="developer_create_client") |
35 | * | 33 | * |
36 | * @return \Symfony\Component\HttpFoundation\Response | 34 | * @return \Symfony\Component\HttpFoundation\Response |
@@ -67,8 +65,6 @@ class DeveloperController extends Controller | |||
67 | /** | 65 | /** |
68 | * Remove a client. | 66 | * Remove a client. |
69 | * | 67 | * |
70 | * @param Client $client | ||
71 | * | ||
72 | * @Route("/developer/client/delete/{id}", requirements={"id" = "\d+"}, name="developer_delete_client") | 68 | * @Route("/developer/client/delete/{id}", requirements={"id" = "\d+"}, name="developer_delete_client") |
73 | * | 69 | * |
74 | * @return \Symfony\Component\HttpFoundation\RedirectResponse | 70 | * @return \Symfony\Component\HttpFoundation\RedirectResponse |
diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php index 0b4e74a0..c09fdaeb 100644 --- a/src/Wallabag/ApiBundle/Controller/EntryRestController.php +++ b/src/Wallabag/ApiBundle/Controller/EntryRestController.php | |||
@@ -4,17 +4,17 @@ 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; |
11 | use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; | ||
12 | use Symfony\Component\HttpKernel\Exception\HttpException; | 12 | use Symfony\Component\HttpKernel\Exception\HttpException; |
13 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | ||
14 | use Wallabag\CoreBundle\Entity\Entry; | 13 | use Wallabag\CoreBundle\Entity\Entry; |
15 | use Wallabag\CoreBundle\Entity\Tag; | 14 | use Wallabag\CoreBundle\Entity\Tag; |
16 | use Wallabag\CoreBundle\Event\EntryDeletedEvent; | 15 | use Wallabag\CoreBundle\Event\EntryDeletedEvent; |
17 | use Wallabag\CoreBundle\Event\EntrySavedEvent; | 16 | use Wallabag\CoreBundle\Event\EntrySavedEvent; |
17 | use Wallabag\CoreBundle\Helper\UrlHasher; | ||
18 | 18 | ||
19 | class EntryRestController extends WallabagRestController | 19 | class EntryRestController extends WallabagRestController |
20 | { | 20 | { |
@@ -28,8 +28,10 @@ class EntryRestController extends WallabagRestController | |||
28 | * @ApiDoc( | 28 | * @ApiDoc( |
29 | * parameters={ | 29 | * parameters={ |
30 | * {"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"}, | 30 | * {"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"}, |
31 | * {"name"="url", "dataType"="string", "required"=true, "format"="An url", "description"="Url to check if it exists"}, | 31 | * {"name"="url", "dataType"="string", "required"=true, "format"="An url", "description"="DEPRECATED, use hashed_url instead"}, |
32 | * {"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 | * {"name"="urls", "dataType"="string", "required"=false, "format"="An array of urls (?urls[]=http...&urls[]=http...)", "description"="DEPRECATED, use hashed_urls instead"}, |
33 | * {"name"="hashed_url", "dataType"="string", "required"=false, "format"="A hashed url", "description"="Hashed url using SHA1 to check if it exists"}, | ||
34 | * {"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"} | ||
33 | * } | 35 | * } |
34 | * ) | 36 | * ) |
35 | * | 37 | * |
@@ -38,38 +40,49 @@ class EntryRestController extends WallabagRestController | |||
38 | public function getEntriesExistsAction(Request $request) | 40 | public function getEntriesExistsAction(Request $request) |
39 | { | 41 | { |
40 | $this->validateAuthentication(); | 42 | $this->validateAuthentication(); |
43 | $repo = $this->getDoctrine()->getRepository('WallabagCoreBundle:Entry'); | ||
41 | 44 | ||
42 | $returnId = (null === $request->query->get('return_id')) ? false : (bool) $request->query->get('return_id'); | 45 | $returnId = (null === $request->query->get('return_id')) ? false : (bool) $request->query->get('return_id'); |
43 | $urls = $request->query->get('urls', []); | ||
44 | |||
45 | // handle multiple urls first | ||
46 | if (!empty($urls)) { | ||
47 | $results = []; | ||
48 | foreach ($urls as $url) { | ||
49 | $res = $this->getDoctrine() | ||
50 | ->getRepository('WallabagCoreBundle:Entry') | ||
51 | ->findByUrlAndUserId($url, $this->getUser()->getId()); | ||
52 | 46 | ||
53 | $results[$url] = $this->returnExistInformation($res, $returnId); | 47 | $hashedUrls = $request->query->get('hashed_urls', []); |
54 | } | 48 | $hashedUrl = $request->query->get('hashed_url', ''); |
55 | 49 | if (!empty($hashedUrl)) { | |
56 | return $this->sendResponse($results); | 50 | $hashedUrls[] = $hashedUrl; |
57 | } | 51 | } |
58 | 52 | ||
59 | // let's see if it is a simple url? | 53 | $urls = $request->query->get('urls', []); |
60 | $url = $request->query->get('url', ''); | 54 | $url = $request->query->get('url', ''); |
55 | if (!empty($url)) { | ||
56 | $urls[] = $url; | ||
57 | } | ||
58 | |||
59 | $urlHashMap = []; | ||
60 | foreach ($urls as $urlToHash) { | ||
61 | $urlHash = UrlHasher::hashUrl($urlToHash); | ||
62 | $hashedUrls[] = $urlHash; | ||
63 | $urlHashMap[$urlHash] = $urlToHash; | ||
64 | } | ||
61 | 65 | ||
62 | if (empty($url)) { | 66 | if (empty($hashedUrls)) { |
63 | throw $this->createAccessDeniedException('URL is empty?, logged user id: ' . $this->getUser()->getId()); | 67 | throw $this->createAccessDeniedException('URL is empty?, logged user id: ' . $this->getUser()->getId()); |
64 | } | 68 | } |
65 | 69 | ||
66 | $res = $this->getDoctrine() | 70 | $results = []; |
67 | ->getRepository('WallabagCoreBundle:Entry') | 71 | foreach ($hashedUrls as $hashedUrlToSearch) { |
68 | ->findByUrlAndUserId($url, $this->getUser()->getId()); | 72 | $res = $repo->findByHashedUrlAndUserId($hashedUrlToSearch, $this->getUser()->getId()); |
73 | |||
74 | $results[$hashedUrlToSearch] = $this->returnExistInformation($res, $returnId); | ||
75 | } | ||
76 | |||
77 | $results = $this->replaceUrlHashes($results, $urlHashMap); | ||
69 | 78 | ||
70 | $exists = $this->returnExistInformation($res, $returnId); | 79 | if (!empty($url) || !empty($hashedUrl)) { |
80 | $hu = array_keys($results)[0]; | ||
71 | 81 | ||
72 | return $this->sendResponse(['exists' => $exists]); | 82 | return $this->sendResponse(['exists' => $results[$hu]]); |
83 | } | ||
84 | |||
85 | return $this->sendResponse($results); | ||
73 | } | 86 | } |
74 | 87 | ||
75 | /** | 88 | /** |
@@ -79,13 +92,14 @@ class EntryRestController extends WallabagRestController | |||
79 | * parameters={ | 92 | * parameters={ |
80 | * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by archived status."}, | 93 | * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by archived status."}, |
81 | * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by starred status."}, | 94 | * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by starred status."}, |
82 | * {"name"="sort", "dataType"="string", "required"=false, "format"="'created' or 'updated', default 'created'", "description"="sort entries by date."}, | 95 | * {"name"="sort", "dataType"="string", "required"=false, "format"="'created' or 'updated' or 'archived', default 'created'", "description"="sort entries by date."}, |
83 | * {"name"="order", "dataType"="string", "required"=false, "format"="'asc' or 'desc', default 'desc'", "description"="order of sort."}, | 96 | * {"name"="order", "dataType"="string", "required"=false, "format"="'asc' or 'desc', default 'desc'", "description"="order of sort."}, |
84 | * {"name"="page", "dataType"="integer", "required"=false, "format"="default '1'", "description"="what page you want."}, | 97 | * {"name"="page", "dataType"="integer", "required"=false, "format"="default '1'", "description"="what page you want."}, |
85 | * {"name"="perPage", "dataType"="integer", "required"=false, "format"="default'30'", "description"="results per page."}, | 98 | * {"name"="perPage", "dataType"="integer", "required"=false, "format"="default'30'", "description"="results per page."}, |
86 | * {"name"="tags", "dataType"="string", "required"=false, "format"="api,rest", "description"="a list of tags url encoded. Will returns entries that matches ALL tags."}, | 99 | * {"name"="tags", "dataType"="string", "required"=false, "format"="api,rest", "description"="a list of tags url encoded. Will returns entries that matches ALL tags."}, |
87 | * {"name"="since", "dataType"="integer", "required"=false, "format"="default '0'", "description"="The timestamp since when you want entries updated."}, | 100 | * {"name"="since", "dataType"="integer", "required"=false, "format"="default '0'", "description"="The timestamp since when you want entries updated."}, |
88 | * {"name"="public", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by entries with a public link"}, | 101 | * {"name"="public", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by entries with a public link"}, |
102 | * {"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."}, | ||
89 | * } | 103 | * } |
90 | * ) | 104 | * ) |
91 | * | 105 | * |
@@ -98,24 +112,30 @@ class EntryRestController extends WallabagRestController | |||
98 | $isArchived = (null === $request->query->get('archive')) ? null : (bool) $request->query->get('archive'); | 112 | $isArchived = (null === $request->query->get('archive')) ? null : (bool) $request->query->get('archive'); |
99 | $isStarred = (null === $request->query->get('starred')) ? null : (bool) $request->query->get('starred'); | 113 | $isStarred = (null === $request->query->get('starred')) ? null : (bool) $request->query->get('starred'); |
100 | $isPublic = (null === $request->query->get('public')) ? null : (bool) $request->query->get('public'); | 114 | $isPublic = (null === $request->query->get('public')) ? null : (bool) $request->query->get('public'); |
101 | $sort = $request->query->get('sort', 'created'); | 115 | $sort = strtolower($request->query->get('sort', 'created')); |
102 | $order = $request->query->get('order', 'desc'); | 116 | $order = strtolower($request->query->get('order', 'desc')); |
103 | $page = (int) $request->query->get('page', 1); | 117 | $page = (int) $request->query->get('page', 1); |
104 | $perPage = (int) $request->query->get('perPage', 30); | 118 | $perPage = (int) $request->query->get('perPage', 30); |
105 | $tags = \is_array($request->query->get('tags')) ? '' : (string) $request->query->get('tags', ''); | 119 | $tags = \is_array($request->query->get('tags')) ? '' : (string) $request->query->get('tags', ''); |
106 | $since = $request->query->get('since', 0); | 120 | $since = $request->query->get('since', 0); |
121 | $detail = strtolower($request->query->get('detail', 'full')); | ||
107 | 122 | ||
108 | /** @var \Pagerfanta\Pagerfanta $pager */ | 123 | try { |
109 | $pager = $this->get('wallabag_core.entry_repository')->findEntries( | 124 | /** @var \Pagerfanta\Pagerfanta $pager */ |
110 | $this->getUser()->getId(), | 125 | $pager = $this->get('wallabag_core.entry_repository')->findEntries( |
111 | $isArchived, | 126 | $this->getUser()->getId(), |
112 | $isStarred, | 127 | $isArchived, |
113 | $isPublic, | 128 | $isStarred, |
114 | $sort, | 129 | $isPublic, |
115 | $order, | 130 | $sort, |
116 | $since, | 131 | $order, |
117 | $tags | 132 | $since, |
118 | ); | 133 | $tags, |
134 | $detail | ||
135 | ); | ||
136 | } catch (\Exception $e) { | ||
137 | throw new BadRequestHttpException($e->getMessage()); | ||
138 | } | ||
119 | 139 | ||
120 | $pager->setMaxPerPage($perPage); | 140 | $pager->setMaxPerPage($perPage); |
121 | $pager->setCurrentPage($page); | 141 | $pager->setCurrentPage($page); |
@@ -135,8 +155,9 @@ class EntryRestController extends WallabagRestController | |||
135 | 'perPage' => $perPage, | 155 | 'perPage' => $perPage, |
136 | 'tags' => $tags, | 156 | 'tags' => $tags, |
137 | 'since' => $since, | 157 | 'since' => $since, |
158 | 'detail' => $detail, | ||
138 | ], | 159 | ], |
139 | UrlGeneratorInterface::ABSOLUTE_URL | 160 | true |
140 | ) | 161 | ) |
141 | ); | 162 | ); |
142 | 163 | ||
@@ -344,9 +365,7 @@ class EntryRestController extends WallabagRestController | |||
344 | 'language' => !empty($data['language']) ? $data['language'] : $entry->getLanguage(), | 365 | 'language' => !empty($data['language']) ? $data['language'] : $entry->getLanguage(), |
345 | 'date' => !empty($data['publishedAt']) ? $data['publishedAt'] : $entry->getPublishedAt(), | 366 | 'date' => !empty($data['publishedAt']) ? $data['publishedAt'] : $entry->getPublishedAt(), |
346 | // faking the open graph preview picture | 367 | // faking the open graph preview picture |
347 | 'open_graph' => [ | 368 | 'image' => !empty($data['picture']) ? $data['picture'] : $entry->getPreviewPicture(), |
348 | 'og_image' => !empty($data['picture']) ? $data['picture'] : $entry->getPreviewPicture(), | ||
349 | ], | ||
350 | 'authors' => \is_string($data['authors']) ? explode(',', $data['authors']) : $entry->getPublishedBy(), | 369 | 'authors' => \is_string($data['authors']) ? explode(',', $data['authors']) : $entry->getPublishedBy(), |
351 | ] | 370 | ] |
352 | ); | 371 | ); |
@@ -358,7 +377,7 @@ class EntryRestController extends WallabagRestController | |||
358 | } | 377 | } |
359 | 378 | ||
360 | if (null !== $data['isArchived']) { | 379 | if (null !== $data['isArchived']) { |
361 | $entry->setArchived((bool) $data['isArchived']); | 380 | $entry->updateArchived((bool) $data['isArchived']); |
362 | } | 381 | } |
363 | 382 | ||
364 | if (null !== $data['isStarred']) { | 383 | if (null !== $data['isStarred']) { |
@@ -474,7 +493,7 @@ class EntryRestController extends WallabagRestController | |||
474 | } | 493 | } |
475 | 494 | ||
476 | if (null !== $data['isArchived']) { | 495 | if (null !== $data['isArchived']) { |
477 | $entry->setArchived((bool) $data['isArchived']); | 496 | $entry->updateArchived((bool) $data['isArchived']); |
478 | } | 497 | } |
479 | 498 | ||
480 | if (null !== $data['isStarred']) { | 499 | if (null !== $data['isStarred']) { |
@@ -545,7 +564,7 @@ class EntryRestController extends WallabagRestController | |||
545 | } | 564 | } |
546 | 565 | ||
547 | // if refreshing entry failed, don't save it | 566 | // if refreshing entry failed, don't save it |
548 | if ($this->getParameter('wallabag_core.fetching_error_message') === $entry->getContent()) { | 567 | if ($this->container->getParameter('wallabag_core.fetching_error_message') === $entry->getContent()) { |
549 | return new JsonResponse([], 304); | 568 | return new JsonResponse([], 304); |
550 | } | 569 | } |
551 | 570 | ||
@@ -565,18 +584,31 @@ class EntryRestController extends WallabagRestController | |||
565 | * @ApiDoc( | 584 | * @ApiDoc( |
566 | * requirements={ | 585 | * requirements={ |
567 | * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"} | 586 | * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"} |
587 | * }, | ||
588 | * parameters={ | ||
589 | * {"name"="expect", "dataType"="string", "required"=false, "format"="id or entry", "description"="Only returns the id instead of the deleted entry's full entity if 'id' is specified. Default to entry"}, | ||
568 | * } | 590 | * } |
569 | * ) | 591 | * ) |
570 | * | 592 | * |
571 | * @return JsonResponse | 593 | * @return JsonResponse |
572 | */ | 594 | */ |
573 | public function deleteEntriesAction(Entry $entry) | 595 | public function deleteEntriesAction(Entry $entry, Request $request) |
574 | { | 596 | { |
597 | $expect = $request->query->get('expect', 'entry'); | ||
598 | if (!\in_array($expect, ['id', 'entry'], true)) { | ||
599 | throw new BadRequestHttpException(sprintf("expect: 'id' or 'entry' expected, %s given", $expect)); | ||
600 | } | ||
575 | $this->validateAuthentication(); | 601 | $this->validateAuthentication(); |
576 | $this->validateUserAccess($entry->getUser()->getId()); | 602 | $this->validateUserAccess($entry->getUser()->getId()); |
577 | 603 | ||
578 | // We copy $entry to keep id in returned object | 604 | $response = $this->sendResponse([ |
579 | $e = $entry; | 605 | 'id' => $entry->getId(), |
606 | ]); | ||
607 | // We clone $entry to keep id in returned object | ||
608 | if ('entry' === $expect) { | ||
609 | $e = clone $entry; | ||
610 | $response = $this->sendResponse($e); | ||
611 | } | ||
580 | 612 | ||
581 | $em = $this->getDoctrine()->getManager(); | 613 | $em = $this->getDoctrine()->getManager(); |
582 | $em->remove($entry); | 614 | $em->remove($entry); |
@@ -585,7 +617,7 @@ class EntryRestController extends WallabagRestController | |||
585 | // entry deleted, dispatch event about it! | 617 | // entry deleted, dispatch event about it! |
586 | $this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry)); | 618 | $this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry)); |
587 | 619 | ||
588 | return $this->sendResponse($e); | 620 | return $response; |
589 | } | 621 | } |
590 | 622 | ||
591 | /** | 623 | /** |
@@ -769,29 +801,27 @@ class EntryRestController extends WallabagRestController | |||
769 | } | 801 | } |
770 | 802 | ||
771 | /** | 803 | /** |
772 | * Shortcut to send data serialized in json. | 804 | * Replace the hashedUrl keys in $results with the unhashed URL from the |
773 | * | 805 | * request, as recorded in $urlHashMap. |
774 | * @param mixed $data | ||
775 | * | ||
776 | * @return JsonResponse | ||
777 | */ | 806 | */ |
778 | private function sendResponse($data) | 807 | private function replaceUrlHashes(array $results, array $urlHashMap) |
779 | { | 808 | { |
780 | // https://github.com/schmittjoh/JMSSerializerBundle/issues/293 | 809 | $newResults = []; |
781 | $context = new SerializationContext(); | 810 | foreach ($results as $hash => $res) { |
782 | $context->setSerializeNull(true); | 811 | if (isset($urlHashMap[$hash])) { |
783 | 812 | $newResults[$urlHashMap[$hash]] = $res; | |
784 | $json = $this->get('jms_serializer')->serialize($data, 'json', $context); | 813 | } else { |
814 | $newResults[$hash] = $res; | ||
815 | } | ||
816 | } | ||
785 | 817 | ||
786 | return (new JsonResponse())->setJson($json); | 818 | return $newResults; |
787 | } | 819 | } |
788 | 820 | ||
789 | /** | 821 | /** |
790 | * Retrieve value from the request. | 822 | * Retrieve value from the request. |
791 | * Used for POST & PATCH on a an entry. | 823 | * Used for POST & PATCH on a an entry. |
792 | * | 824 | * |
793 | * @param Request $request | ||
794 | * | ||
795 | * @return array | 825 | * @return array |
796 | */ | 826 | */ |
797 | private function retrieveValueFromRequest(Request $request) | 827 | private function retrieveValueFromRequest(Request $request) |
@@ -814,8 +844,8 @@ class EntryRestController extends WallabagRestController | |||
814 | /** | 844 | /** |
815 | * Return information about the entry if it exist and depending on the id or not. | 845 | * Return information about the entry if it exist and depending on the id or not. |
816 | * | 846 | * |
817 | * @param Entry|null $entry | 847 | * @param Entry|bool|null $entry |
818 | * @param bool $returnId | 848 | * @param bool $returnId |
819 | * | 849 | * |
820 | * @return bool|int | 850 | * @return bool|int |
821 | */ | 851 | */ |
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/TagRestController.php b/src/Wallabag/ApiBundle/Controller/TagRestController.php index c6d6df6a..f3498f55 100644 --- a/src/Wallabag/ApiBundle/Controller/TagRestController.php +++ b/src/Wallabag/ApiBundle/Controller/TagRestController.php | |||
@@ -46,12 +46,14 @@ class TagRestController extends WallabagRestController | |||
46 | $this->validateAuthentication(); | 46 | $this->validateAuthentication(); |
47 | $label = $request->get('tag', ''); | 47 | $label = $request->get('tag', ''); |
48 | 48 | ||
49 | $tag = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($label); | 49 | $tags = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findByLabelsAndUser([$label], $this->getUser()->getId()); |
50 | 50 | ||
51 | if (empty($tag)) { | 51 | if (empty($tags)) { |
52 | throw $this->createNotFoundException('Tag not found'); | 52 | throw $this->createNotFoundException('Tag not found'); |
53 | } | 53 | } |
54 | 54 | ||
55 | $tag = $tags[0]; | ||
56 | |||
55 | $this->getDoctrine() | 57 | $this->getDoctrine() |
56 | ->getRepository('WallabagCoreBundle:Entry') | 58 | ->getRepository('WallabagCoreBundle:Entry') |
57 | ->removeTag($this->getUser()->getId(), $tag); | 59 | ->removeTag($this->getUser()->getId(), $tag); |
@@ -80,15 +82,7 @@ class TagRestController extends WallabagRestController | |||
80 | 82 | ||
81 | $tagsLabels = $request->get('tags', ''); | 83 | $tagsLabels = $request->get('tags', ''); |
82 | 84 | ||
83 | $tags = []; | 85 | $tags = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findByLabelsAndUser(explode(',', $tagsLabels), $this->getUser()->getId()); |
84 | |||
85 | foreach (explode(',', $tagsLabels) as $tagLabel) { | ||
86 | $tagEntity = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($tagLabel); | ||
87 | |||
88 | if (!empty($tagEntity)) { | ||
89 | $tags[] = $tagEntity; | ||
90 | } | ||
91 | } | ||
92 | 86 | ||
93 | if (empty($tags)) { | 87 | if (empty($tags)) { |
94 | throw $this->createNotFoundException('Tags not found'); | 88 | throw $this->createNotFoundException('Tags not found'); |
@@ -120,6 +114,12 @@ class TagRestController extends WallabagRestController | |||
120 | { | 114 | { |
121 | $this->validateAuthentication(); | 115 | $this->validateAuthentication(); |
122 | 116 | ||
117 | $tagFromDb = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findByLabelsAndUser([$tag->getLabel()], $this->getUser()->getId()); | ||
118 | |||
119 | if (empty($tagFromDb)) { | ||
120 | throw $this->createNotFoundException('Tag not found'); | ||
121 | } | ||
122 | |||
123 | $this->getDoctrine() | 123 | $this->getDoctrine() |
124 | ->getRepository('WallabagCoreBundle:Entry') | 124 | ->getRepository('WallabagCoreBundle:Entry') |
125 | ->removeTag($this->getUser()->getId(), $tag); | 125 | ->removeTag($this->getUser()->getId(), $tag); |
diff --git a/src/Wallabag/ApiBundle/Controller/TaggingRuleRestController.php b/src/Wallabag/ApiBundle/Controller/TaggingRuleRestController.php new file mode 100644 index 00000000..2496298a --- /dev/null +++ b/src/Wallabag/ApiBundle/Controller/TaggingRuleRestController.php | |||
@@ -0,0 +1,39 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\ApiBundle\Controller; | ||
4 | |||
5 | use JMS\Serializer\SerializationContext; | ||
6 | use JMS\Serializer\SerializerBuilder; | ||
7 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; | ||
8 | use Symfony\Component\HttpFoundation\Response; | ||
9 | |||
10 | class TaggingRuleRestController extends WallabagRestController | ||
11 | { | ||
12 | /** | ||
13 | * Export all tagging rules as a json file. | ||
14 | * | ||
15 | * @ApiDoc() | ||
16 | * | ||
17 | * @return Response | ||
18 | */ | ||
19 | public function getTaggingruleExportAction() | ||
20 | { | ||
21 | $this->validateAuthentication(); | ||
22 | |||
23 | $data = SerializerBuilder::create()->build()->serialize( | ||
24 | $this->getUser()->getConfig()->getTaggingRules(), | ||
25 | 'json', | ||
26 | SerializationContext::create()->setGroups(['export_tagging_rule']) | ||
27 | ); | ||
28 | |||
29 | return Response::create( | ||
30 | $data, | ||
31 | 200, | ||
32 | [ | ||
33 | 'Content-type' => 'application/json', | ||
34 | 'Content-Disposition' => 'attachment; filename="tagging_rules_' . $this->getUser()->getUsername() . '.json"', | ||
35 | 'Content-Transfer-Encoding' => 'UTF-8', | ||
36 | ] | ||
37 | ); | ||
38 | } | ||
39 | } | ||
diff --git a/src/Wallabag/ApiBundle/Controller/UserRestController.php b/src/Wallabag/ApiBundle/Controller/UserRestController.php index 3a4dafcd..922ab7bb 100644 --- a/src/Wallabag/ApiBundle/Controller/UserRestController.php +++ b/src/Wallabag/ApiBundle/Controller/UserRestController.php | |||
@@ -45,7 +45,7 @@ class UserRestController extends WallabagRestController | |||
45 | */ | 45 | */ |
46 | public function putUserAction(Request $request) | 46 | public function putUserAction(Request $request) |
47 | { | 47 | { |
48 | if (!$this->getParameter('fosuser_registration') || !$this->get('craue_config')->get('api_user_registration')) { | 48 | if (!$this->container->getParameter('fosuser_registration') || !$this->get('craue_config')->get('api_user_registration')) { |
49 | $json = $this->get('jms_serializer')->serialize(['error' => "Server doesn't allow registrations"], 'json'); | 49 | $json = $this->get('jms_serializer')->serialize(['error' => "Server doesn't allow registrations"], 'json'); |
50 | 50 | ||
51 | return (new JsonResponse()) | 51 | return (new JsonResponse()) |
@@ -119,7 +119,6 @@ class UserRestController extends WallabagRestController | |||
119 | /** | 119 | /** |
120 | * Send user response. | 120 | * Send user response. |
121 | * | 121 | * |
122 | * @param User $user | ||
123 | * @param string $group Used to define with serialized group might be used | 122 | * @param string $group Used to define with serialized group might be used |
124 | * @param int $status HTTP Status code to send | 123 | * @param int $status HTTP Status code to send |
125 | * | 124 | * |
diff --git a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php index 7d8cfbba..44fd9683 100644 --- a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php +++ b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php | |||
@@ -2,18 +2,21 @@ | |||
2 | 2 | ||
3 | namespace Wallabag\ApiBundle\Controller; | 3 | namespace Wallabag\ApiBundle\Controller; |
4 | 4 | ||
5 | use FOS\RestBundle\Controller\FOSRestController; | 5 | use FOS\RestBundle\Controller\AbstractFOSRestController; |
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; |
9 | 10 | ||
10 | class WallabagRestController extends FOSRestController | 11 | class WallabagRestController extends AbstractFOSRestController |
11 | { | 12 | { |
12 | /** | 13 | /** |
13 | * Retrieve version number. | 14 | * Retrieve version number. |
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 | } |