aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Wallabag/ApiBundle/Controller
diff options
context:
space:
mode:
Diffstat (limited to 'src/Wallabag/ApiBundle/Controller')
-rw-r--r--src/Wallabag/ApiBundle/Controller/DeveloperController.php101
-rw-r--r--src/Wallabag/ApiBundle/Controller/WallabagRestController.php231
2 files changed, 294 insertions, 38 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
3namespace Wallabag\ApiBundle\Controller;
4
5use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
6use Symfony\Component\HttpFoundation\Request;
7use Symfony\Bundle\FrameworkBundle\Controller\Controller;
8use Wallabag\ApiBundle\Entity\Client;
9use Wallabag\ApiBundle\Form\Type\ClientType;
10
11class 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;
7use Hateoas\Representation\Factory\PagerfantaFactory; 7use Hateoas\Representation\Factory\PagerfantaFactory;
8use Nelmio\ApiDocBundle\Annotation\ApiDoc; 8use Nelmio\ApiDocBundle\Annotation\ApiDoc;
9use Symfony\Component\HttpFoundation\Request; 9use Symfony\Component\HttpFoundation\Request;
10use Symfony\Component\HttpFoundation\Response; 10use Symfony\Component\HttpFoundation\JsonResponse;
11use Symfony\Component\Routing\Generator\UrlGeneratorInterface; 11use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
12use Symfony\Component\Security\Core\Exception\AccessDeniedException; 12use Symfony\Component\Security\Core\Exception\AccessDeniedException;
13use Wallabag\CoreBundle\Entity\Entry; 13use 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}