diff options
author | Paulino Michelazzo <paulino@michelazzo.com.br> | 2016-10-18 22:48:23 +0200 |
---|---|---|
committer | Paulino Michelazzo <paulino@michelazzo.com.br> | 2016-10-18 22:48:23 +0200 |
commit | 99731f0bb1f6fd2815eeb9af504ce86df927657b (patch) | |
tree | b080efc608d2bbd52b77a4a0067402007f50c5a8 /src/Wallabag/ApiBundle | |
parent | 3a3c6b866b52721431bed22426d9abfcd0d2dfe0 (diff) | |
parent | 7180aaed45dce62e40620a9e4b202526ebd6a3bb (diff) | |
download | wallabag-99731f0bb1f6fd2815eeb9af504ce86df927657b.tar.gz wallabag-99731f0bb1f6fd2815eeb9af504ce86df927657b.tar.zst wallabag-99731f0bb1f6fd2815eeb9af504ce86df927657b.zip |
Merge remote-tracking branch 'wallabag/master'
Diffstat (limited to 'src/Wallabag/ApiBundle')
-rw-r--r-- | src/Wallabag/ApiBundle/Controller/DeveloperController.php | 101 | ||||
-rw-r--r-- | src/Wallabag/ApiBundle/Controller/WallabagRestController.php | 231 | ||||
-rw-r--r-- | src/Wallabag/ApiBundle/Entity/AccessToken.php | 2 | ||||
-rw-r--r-- | src/Wallabag/ApiBundle/Entity/Client.php | 41 | ||||
-rw-r--r-- | src/Wallabag/ApiBundle/Entity/RefreshToken.php | 2 | ||||
-rw-r--r-- | src/Wallabag/ApiBundle/Form/Type/ClientType.php | 46 |
6 files changed, 383 insertions, 40 deletions
diff --git a/src/Wallabag/ApiBundle/Controller/DeveloperController.php b/src/Wallabag/ApiBundle/Controller/DeveloperController.php new file mode 100644 index 00000000..5a36a260 --- /dev/null +++ b/src/Wallabag/ApiBundle/Controller/DeveloperController.php | |||
@@ -0,0 +1,101 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\ApiBundle\Controller; | ||
4 | |||
5 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | ||
6 | use Symfony\Component\HttpFoundation\Request; | ||
7 | use Symfony\Bundle\FrameworkBundle\Controller\Controller; | ||
8 | use Wallabag\ApiBundle\Entity\Client; | ||
9 | use Wallabag\ApiBundle\Form\Type\ClientType; | ||
10 | |||
11 | class DeveloperController extends Controller | ||
12 | { | ||
13 | /** | ||
14 | * List all clients and link to create a new one. | ||
15 | * | ||
16 | * @Route("/developer", name="developer") | ||
17 | * | ||
18 | * @return \Symfony\Component\HttpFoundation\Response | ||
19 | */ | ||
20 | public function indexAction() | ||
21 | { | ||
22 | $clients = $this->getDoctrine()->getRepository('WallabagApiBundle:Client')->findAll(); | ||
23 | |||
24 | return $this->render('@WallabagCore/themes/common/Developer/index.html.twig', [ | ||
25 | 'clients' => $clients, | ||
26 | ]); | ||
27 | } | ||
28 | |||
29 | /** | ||
30 | * Create a client (an app). | ||
31 | * | ||
32 | * @param Request $request | ||
33 | * | ||
34 | * @Route("/developer/client/create", name="developer_create_client") | ||
35 | * | ||
36 | * @return \Symfony\Component\HttpFoundation\Response | ||
37 | */ | ||
38 | public function createClientAction(Request $request) | ||
39 | { | ||
40 | $em = $this->getDoctrine()->getManager(); | ||
41 | $client = new Client(); | ||
42 | $clientForm = $this->createForm(ClientType::class, $client); | ||
43 | $clientForm->handleRequest($request); | ||
44 | |||
45 | if ($clientForm->isValid()) { | ||
46 | $client->setAllowedGrantTypes(['token', 'authorization_code', 'password', 'refresh_token']); | ||
47 | $em->persist($client); | ||
48 | $em->flush(); | ||
49 | |||
50 | $this->get('session')->getFlashBag()->add( | ||
51 | 'notice', | ||
52 | $this->get('translator')->trans('flashes.developer.notice.client_created', ['%name%' => $client->getName()]) | ||
53 | ); | ||
54 | |||
55 | return $this->render('@WallabagCore/themes/common/Developer/client_parameters.html.twig', [ | ||
56 | 'client_id' => $client->getPublicId(), | ||
57 | 'client_secret' => $client->getSecret(), | ||
58 | 'client_name' => $client->getName(), | ||
59 | ]); | ||
60 | } | ||
61 | |||
62 | return $this->render('@WallabagCore/themes/common/Developer/client.html.twig', [ | ||
63 | 'form' => $clientForm->createView(), | ||
64 | ]); | ||
65 | } | ||
66 | |||
67 | /** | ||
68 | * Remove a client. | ||
69 | * | ||
70 | * @param Client $client | ||
71 | * | ||
72 | * @Route("/developer/client/delete/{id}", requirements={"id" = "\d+"}, name="developer_delete_client") | ||
73 | * | ||
74 | * @return \Symfony\Component\HttpFoundation\RedirectResponse | ||
75 | */ | ||
76 | public function deleteClientAction(Client $client) | ||
77 | { | ||
78 | $em = $this->getDoctrine()->getManager(); | ||
79 | $em->remove($client); | ||
80 | $em->flush(); | ||
81 | |||
82 | $this->get('session')->getFlashBag()->add( | ||
83 | 'notice', | ||
84 | $this->get('translator')->trans('flashes.developer.notice.client_deleted', ['%name%' => $client->getName()]) | ||
85 | ); | ||
86 | |||
87 | return $this->redirect($this->generateUrl('developer')); | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * Display developer how to use an existing app. | ||
92 | * | ||
93 | * @Route("/developer/howto/first-app", name="developer_howto_firstapp") | ||
94 | * | ||
95 | * @return \Symfony\Component\HttpFoundation\Response | ||
96 | */ | ||
97 | public function howtoFirstAppAction() | ||
98 | { | ||
99 | return $this->render('@WallabagCore/themes/common/Developer/howto_app.html.twig'); | ||
100 | } | ||
101 | } | ||
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 | } |
diff --git a/src/Wallabag/ApiBundle/Entity/AccessToken.php b/src/Wallabag/ApiBundle/Entity/AccessToken.php index 2ff63a83..c09a0c80 100644 --- a/src/Wallabag/ApiBundle/Entity/AccessToken.php +++ b/src/Wallabag/ApiBundle/Entity/AccessToken.php | |||
@@ -19,7 +19,7 @@ class AccessToken extends BaseAccessToken | |||
19 | protected $id; | 19 | protected $id; |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @ORM\ManyToOne(targetEntity="Client") | 22 | * @ORM\ManyToOne(targetEntity="Client", inversedBy="accessTokens") |
23 | * @ORM\JoinColumn(nullable=false) | 23 | * @ORM\JoinColumn(nullable=false) |
24 | */ | 24 | */ |
25 | protected $client; | 25 | protected $client; |
diff --git a/src/Wallabag/ApiBundle/Entity/Client.php b/src/Wallabag/ApiBundle/Entity/Client.php index c04ed0f6..f7898ac8 100644 --- a/src/Wallabag/ApiBundle/Entity/Client.php +++ b/src/Wallabag/ApiBundle/Entity/Client.php | |||
@@ -18,8 +18,49 @@ class Client extends BaseClient | |||
18 | */ | 18 | */ |
19 | protected $id; | 19 | protected $id; |
20 | 20 | ||
21 | /** | ||
22 | * @var string | ||
23 | * | ||
24 | * @ORM\Column(name="name", type="text", nullable=true) | ||
25 | */ | ||
26 | protected $name; | ||
27 | |||
28 | /** | ||
29 | * @ORM\OneToMany(targetEntity="RefreshToken", mappedBy="client", cascade={"remove"}) | ||
30 | */ | ||
31 | protected $refreshTokens; | ||
32 | |||
33 | /** | ||
34 | * @ORM\OneToMany(targetEntity="AccessToken", mappedBy="client", cascade={"remove"}) | ||
35 | */ | ||
36 | protected $accessTokens; | ||
37 | |||
21 | public function __construct() | 38 | public function __construct() |
22 | { | 39 | { |
23 | parent::__construct(); | 40 | parent::__construct(); |
24 | } | 41 | } |
42 | |||
43 | /** | ||
44 | * Get name. | ||
45 | * | ||
46 | * @return string | ||
47 | */ | ||
48 | public function getName() | ||
49 | { | ||
50 | return $this->name; | ||
51 | } | ||
52 | |||
53 | /** | ||
54 | * Set name. | ||
55 | * | ||
56 | * @param string $name | ||
57 | * | ||
58 | * @return Client | ||
59 | */ | ||
60 | public function setName($name) | ||
61 | { | ||
62 | $this->name = $name; | ||
63 | |||
64 | return $this; | ||
65 | } | ||
25 | } | 66 | } |
diff --git a/src/Wallabag/ApiBundle/Entity/RefreshToken.php b/src/Wallabag/ApiBundle/Entity/RefreshToken.php index 6d0cab68..822a02d8 100644 --- a/src/Wallabag/ApiBundle/Entity/RefreshToken.php +++ b/src/Wallabag/ApiBundle/Entity/RefreshToken.php | |||
@@ -19,7 +19,7 @@ class RefreshToken extends BaseRefreshToken | |||
19 | protected $id; | 19 | protected $id; |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @ORM\ManyToOne(targetEntity="Client") | 22 | * @ORM\ManyToOne(targetEntity="Client", inversedBy="refreshTokens") |
23 | * @ORM\JoinColumn(nullable=false) | 23 | * @ORM\JoinColumn(nullable=false) |
24 | */ | 24 | */ |
25 | protected $client; | 25 | protected $client; |
diff --git a/src/Wallabag/ApiBundle/Form/Type/ClientType.php b/src/Wallabag/ApiBundle/Form/Type/ClientType.php new file mode 100644 index 00000000..0ea1a9c5 --- /dev/null +++ b/src/Wallabag/ApiBundle/Form/Type/ClientType.php | |||
@@ -0,0 +1,46 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\ApiBundle\Form\Type; | ||
4 | |||
5 | use Symfony\Component\Form\AbstractType; | ||
6 | use Symfony\Component\Form\CallbackTransformer; | ||
7 | use Symfony\Component\Form\Extension\Core\Type\SubmitType; | ||
8 | use Symfony\Component\Form\Extension\Core\Type\UrlType; | ||
9 | use Symfony\Component\Form\Extension\Core\Type\TextType; | ||
10 | use Symfony\Component\Form\FormBuilderInterface; | ||
11 | use Symfony\Component\OptionsResolver\OptionsResolver; | ||
12 | |||
13 | class ClientType extends AbstractType | ||
14 | { | ||
15 | public function buildForm(FormBuilderInterface $builder, array $options) | ||
16 | { | ||
17 | $builder | ||
18 | ->add('name', TextType::class, ['label' => 'developer.client.form.name_label']) | ||
19 | ->add('redirect_uris', UrlType::class, ['required' => false, 'label' => 'developer.client.form.redirect_uris_label']) | ||
20 | ->add('save', SubmitType::class, ['label' => 'developer.client.form.save_label']) | ||
21 | ; | ||
22 | |||
23 | $builder->get('redirect_uris') | ||
24 | ->addModelTransformer(new CallbackTransformer( | ||
25 | function ($originalUri) { | ||
26 | return $originalUri; | ||
27 | }, | ||
28 | function ($submittedUri) { | ||
29 | return [$submittedUri]; | ||
30 | } | ||
31 | )) | ||
32 | ; | ||
33 | } | ||
34 | |||
35 | public function configureOptions(OptionsResolver $resolver) | ||
36 | { | ||
37 | $resolver->setDefaults([ | ||
38 | 'data_class' => 'Wallabag\ApiBundle\Entity\Client', | ||
39 | ]); | ||
40 | } | ||
41 | |||
42 | public function getBlockPrefix() | ||
43 | { | ||
44 | return 'client'; | ||
45 | } | ||
46 | } | ||