]> git.immae.eu Git - github/wallabag/wallabag.git/blame - src/Wallabag/ApiBundle/Controller/WallabagRestController.php
Merge remote-tracking branch 'origin/master' into 2.2
[github/wallabag/wallabag.git] / src / Wallabag / ApiBundle / Controller / WallabagRestController.php
CommitLineData
f8bf8952
NL
1<?php
2
769e19dc 3namespace Wallabag\ApiBundle\Controller;
f8bf8952 4
fcb1fba5 5use FOS\RestBundle\Controller\FOSRestController;
3f3a6087 6use Hateoas\Configuration\Route as HateoasRoute;
619cc453 7use Hateoas\Representation\Factory\PagerfantaFactory;
f8bf8952 8use Nelmio\ApiDocBundle\Annotation\ApiDoc;
351eb8d9 9use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
27f15aa4 10use Symfony\Component\HttpFoundation\Request;
60faee00 11use Symfony\Component\HttpFoundation\JsonResponse;
1d76102a 12use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
b0b893ea 13use Symfony\Component\Security\Core\Exception\AccessDeniedException;
be463487 14use Wallabag\CoreBundle\Entity\Entry;
653e8be4 15use Wallabag\CoreBundle\Entity\Tag;
351eb8d9 16use Wallabag\AnnotationBundle\Entity\Annotation;
f8bf8952 17
fcb1fba5 18class WallabagRestController extends FOSRestController
f8bf8952 19{
77273253
NL
20 private function validateAuthentication()
21 {
18f8f32f 22 if (false === $this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) {
77273253
NL
23 throw new AccessDeniedException();
24 }
25 }
26
6273fefd 27 /**
3583cadf 28 * Check if an entry exist by url.
6273fefd
JB
29 *
30 * @ApiDoc(
31 * parameters={
f0abc22d
JB
32 * {"name"="url", "dataType"="string", "required"=true, "format"="An url", "description"="Url to check if it exists"},
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"}
6273fefd
JB
34 * }
35 * )
36 *
37 * @return JsonResponse
38 */
39 public function getEntriesExistsAction(Request $request)
40 {
41 $this->validateAuthentication();
42
f0abc22d
JB
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
53 $results[$url] = false === $res ? false : true;
54 }
55
56 $json = $this->get('serializer')->serialize($results, 'json');
57
58 return (new JsonResponse())->setJson($json);
59 }
60
61 // let's see if it is a simple url?
6273fefd
JB
62 $url = $request->query->get('url', '');
63
64 if (empty($url)) {
0b174d69 65 throw $this->createAccessDeniedException('URL is empty?, logged user id: '.$this->getUser()->getId());
6273fefd
JB
66 }
67
68 $res = $this->getDoctrine()
69 ->getRepository('WallabagCoreBundle:Entry')
70 ->findByUrlAndUserId($url, $this->getUser()->getId());
71
72 $exists = false === $res ? false : true;
73
74 $json = $this->get('serializer')->serialize(['exists' => $exists], 'json');
75
76 return (new JsonResponse())->setJson($json);
77 }
78
f8bf8952 79 /**
a8c90c5c 80 * Retrieve all entries. It could be filtered by many options.
f8bf8952
NL
81 *
82 * @ApiDoc(
a8c90c5c 83 * parameters={
189ef634
TC
84 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by archived status."},
85 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by starred status."},
a8c90c5c
NL
86 * {"name"="sort", "dataType"="string", "required"=false, "format"="'created' or 'updated', default 'created'", "description"="sort entries by date."},
87 * {"name"="order", "dataType"="string", "required"=false, "format"="'asc' or 'desc', default 'desc'", "description"="order of sort."},
88 * {"name"="page", "dataType"="integer", "required"=false, "format"="default '1'", "description"="what page you want."},
89 * {"name"="perPage", "dataType"="integer", "required"=false, "format"="default'30'", "description"="results per page."},
189ef634 90 * {"name"="tags", "dataType"="string", "required"=false, "format"="api,rest", "description"="a list of tags url encoded. Will returns entries that matches ALL tags."},
e5fb89e5 91 * {"name"="since", "dataType"="integer", "required"=false, "format"="default '0'", "description"="The timestamp since when you want entries updated."},
a8c90c5c 92 * }
f8bf8952 93 * )
4346a860 94 *
60faee00 95 * @return JsonResponse
f8bf8952 96 */
27f15aa4 97 public function getEntriesAction(Request $request)
f8bf8952 98 {
77273253
NL
99 $this->validateAuthentication();
100
0135c98b
NL
101 $isArchived = (null === $request->query->get('archive')) ? null : (bool) $request->query->get('archive');
102 $isStarred = (null === $request->query->get('starred')) ? null : (bool) $request->query->get('starred');
8ce32af6
JB
103 $sort = $request->query->get('sort', 'created');
104 $order = $request->query->get('order', 'desc');
105 $page = (int) $request->query->get('page', 1);
106 $perPage = (int) $request->query->get('perPage', 30);
28803f10 107 $tags = $request->query->get('tags', '');
c3f8b428 108 $since = $request->query->get('since', 0);
a8c90c5c 109
fc732227 110 $pager = $this->getDoctrine()
be463487 111 ->getRepository('WallabagCoreBundle:Entry')
28803f10 112 ->findEntries($this->getUser()->getId(), $isArchived, $isStarred, $sort, $order, $since, $tags);
a8c90c5c 113
6e22bd73
WD
114 $pager->setCurrentPage($page);
115 $pager->setMaxPerPage($perPage);
116
8ce32af6 117 $pagerfantaFactory = new PagerfantaFactory('page', 'perPage');
6e22bd73
WD
118 $paginatedCollection = $pagerfantaFactory->createRepresentation(
119 $pager,
3f3a6087 120 new HateoasRoute(
c3f8b428
JB
121 'api_get_entries',
122 [
123 'archive' => $isArchived,
124 'starred' => $isStarred,
125 'sort' => $sort,
126 'order' => $order,
127 'page' => $page,
128 'perPage' => $perPage,
129 'tags' => $tags,
130 'since' => $since,
131 ],
132 UrlGeneratorInterface::ABSOLUTE_URL
133 )
6e22bd73
WD
134 );
135
136 $json = $this->get('serializer')->serialize($paginatedCollection, 'json');
0f006880 137
60faee00 138 return (new JsonResponse())->setJson($json);
f8bf8952
NL
139 }
140
141 /**
4346a860 142 * Retrieve a single entry.
f8bf8952
NL
143 *
144 * @ApiDoc(
145 * requirements={
146 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
147 * }
148 * )
4346a860 149 *
60faee00 150 * @return JsonResponse
f8bf8952 151 */
be463487 152 public function getEntryAction(Entry $entry)
f8bf8952 153 {
77273253 154 $this->validateAuthentication();
fcb1fba5 155 $this->validateUserAccess($entry->getUser()->getId());
092ca707 156
aa4d6562 157 $json = $this->get('serializer')->serialize($entry, 'json');
0f006880 158
60faee00 159 return (new JsonResponse())->setJson($json);
f8bf8952
NL
160 }
161
3f3a6087
JB
162 /**
163 * Retrieve a single entry as a predefined format.
164 *
165 * @ApiDoc(
166 * requirements={
167 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
168 * }
169 * )
170 *
3f3a6087
JB
171 * @return Response
172 */
173 public function getEntryExportAction(Entry $entry, Request $request)
174 {
175 $this->validateAuthentication();
176 $this->validateUserAccess($entry->getUser()->getId());
177
178 return $this->get('wallabag_core.helper.entries_export')
179 ->setEntries($entry)
180 ->updateTitle('entry')
181 ->exportAs($request->attributes->get('_format'));
182 }
183
f8bf8952 184 /**
4346a860 185 * Create an entry.
f8bf8952
NL
186 *
187 * @ApiDoc(
a8c90c5c
NL
188 * parameters={
189 * {"name"="url", "dataType"="string", "required"=true, "format"="http://www.test.com/article.html", "description"="Url for the entry."},
190 * {"name"="title", "dataType"="string", "required"=false, "description"="Optional, we'll get the title from the page."},
191 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
189ef634
TC
192 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already starred"},
193 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already archived"},
a8c90c5c 194 * }
f8bf8952 195 * )
4346a860 196 *
60faee00 197 * @return JsonResponse
f8bf8952 198 */
843dbe51 199 public function postEntriesAction(Request $request)
f8bf8952 200 {
77273253
NL
201 $this->validateAuthentication();
202
c3235553 203 $url = $request->request->get('url');
51a15609 204 $title = $request->request->get('title');
873e3806
YE
205 $isArchived = $request->request->get('archive');
206 $isStarred = $request->request->get('starred');
c3235553 207
3107f92a
TC
208 $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($url, $this->getUser()->getId());
209
210 if (false === $entry) {
211 $entry = $this->get('wallabag_core.content_proxy')->updateEntry(
212 new Entry($this->getUser()),
213 $url
214 );
215 }
092ca707 216
51a15609
NL
217 if (!is_null($title)) {
218 $entry->setTitle($title);
219 }
220
0ca374e6
NL
221 $tags = $request->request->get('tags', '');
222 if (!empty($tags)) {
c2656f96 223 $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
0ca374e6 224 }
092ca707 225
bc2b947c
TC
226 if (!is_null($isStarred)) {
227 $entry->setStarred((bool) $isStarred);
228 }
816ad405 229
bc2b947c
TC
230 if (!is_null($isArchived)) {
231 $entry->setArchived((bool) $isArchived);
232 }
816ad405 233
843dbe51
NL
234 $em = $this->getDoctrine()->getManager();
235 $em->persist($entry);
816ad405 236
843dbe51
NL
237 $em->flush();
238
aa4d6562
NL
239 $json = $this->get('serializer')->serialize($entry, 'json');
240
60faee00 241 return (new JsonResponse())->setJson($json);
f8bf8952
NL
242 }
243
244 /**
4346a860 245 * Change several properties of an entry.
f8bf8952
NL
246 *
247 * @ApiDoc(
248 * requirements={
249 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
a8c90c5c
NL
250 * },
251 * parameters={
252 * {"name"="title", "dataType"="string", "required"=false},
253 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
189ef634
TC
254 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="archived the entry."},
255 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="starred the entry."},
1d147791 256 * }
f8bf8952 257 * )
4346a860 258 *
60faee00 259 * @return JsonResponse
f8bf8952 260 */
be463487 261 public function patchEntriesAction(Entry $entry, Request $request)
f8bf8952 262 {
77273253 263 $this->validateAuthentication();
fcb1fba5 264 $this->validateUserAccess($entry->getUser()->getId());
092ca707 265
8ce32af6 266 $title = $request->request->get('title');
614a0bfd
YE
267 $isArchived = $request->request->get('archive');
268 $isStarred = $request->request->get('starred');
2c093b03
NL
269
270 if (!is_null($title)) {
271 $entry->setTitle($title);
272 }
273
274 if (!is_null($isArchived)) {
189ef634 275 $entry->setArchived((bool) $isArchived);
2c093b03
NL
276 }
277
2c093b03 278 if (!is_null($isStarred)) {
189ef634 279 $entry->setStarred((bool) $isStarred);
2c093b03
NL
280 }
281
0ca374e6
NL
282 $tags = $request->request->get('tags', '');
283 if (!empty($tags)) {
c2656f96 284 $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
0ca374e6 285 }
092ca707 286
2c093b03 287 $em = $this->getDoctrine()->getManager();
2c093b03
NL
288 $em->flush();
289
0ca374e6
NL
290 $json = $this->get('serializer')->serialize($entry, 'json');
291
60faee00 292 return (new JsonResponse())->setJson($json);
f8bf8952
NL
293 }
294
295 /**
4346a860 296 * Delete **permanently** an entry.
f8bf8952
NL
297 *
298 * @ApiDoc(
a8c90c5c
NL
299 * requirements={
300 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
301 * }
f8bf8952 302 * )
4346a860 303 *
60faee00 304 * @return JsonResponse
f8bf8952 305 */
be463487 306 public function deleteEntriesAction(Entry $entry)
f8bf8952 307 {
77273253 308 $this->validateAuthentication();
fcb1fba5 309 $this->validateUserAccess($entry->getUser()->getId());
092ca707 310
42a90646 311 $em = $this->getDoctrine()->getManager();
1d147791 312 $em->remove($entry);
42a90646
NL
313 $em->flush();
314
1d147791
NL
315 $json = $this->get('serializer')->serialize($entry, 'json');
316
60faee00 317 return (new JsonResponse())->setJson($json);
f8bf8952
NL
318 }
319
320 /**
4346a860 321 * Retrieve all tags for an entry.
f8bf8952
NL
322 *
323 * @ApiDoc(
324 * requirements={
325 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
326 * }
327 * )
8eedc8cf 328 *
60faee00 329 * @return JsonResponse
f8bf8952 330 */
be463487 331 public function getEntriesTagsAction(Entry $entry)
7df80cb3 332 {
77273253 333 $this->validateAuthentication();
fcb1fba5 334 $this->validateUserAccess($entry->getUser()->getId());
092ca707 335
1bd12b62 336 $json = $this->get('serializer')->serialize($entry->getTags(), 'json');
0a018fe0 337
60faee00 338 return (new JsonResponse())->setJson($json);
f8bf8952
NL
339 }
340
341 /**
4346a860 342 * Add one or more tags to an entry.
f8bf8952
NL
343 *
344 * @ApiDoc(
345 * requirements={
346 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
a8c90c5c
NL
347 * },
348 * parameters={
349 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
350 * }
f8bf8952 351 * )
8eedc8cf 352 *
60faee00 353 * @return JsonResponse
f8bf8952 354 */
a36737f4 355 public function postEntriesTagsAction(Request $request, Entry $entry)
7df80cb3 356 {
77273253 357 $this->validateAuthentication();
fcb1fba5 358 $this->validateUserAccess($entry->getUser()->getId());
a36737f4 359
0ca374e6
NL
360 $tags = $request->request->get('tags', '');
361 if (!empty($tags)) {
c2656f96 362 $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
0ca374e6 363 }
092ca707 364
a36737f4
NL
365 $em = $this->getDoctrine()->getManager();
366 $em->persist($entry);
367 $em->flush();
368
369 $json = $this->get('serializer')->serialize($entry, 'json');
370
60faee00 371 return (new JsonResponse())->setJson($json);
f8bf8952
NL
372 }
373
374 /**
4346a860 375 * Permanently remove one tag for an entry.
f8bf8952
NL
376 *
377 * @ApiDoc(
378 * requirements={
769e19dc 379 * {"name"="tag", "dataType"="integer", "requirement"="\w+", "description"="The tag ID"},
f8bf8952
NL
380 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
381 * }
382 * )
8eedc8cf 383 *
60faee00 384 * @return JsonResponse
f8bf8952 385 */
653e8be4 386 public function deleteEntriesTagsAction(Entry $entry, Tag $tag)
f8bf8952 387 {
77273253 388 $this->validateAuthentication();
fcb1fba5 389 $this->validateUserAccess($entry->getUser()->getId());
092ca707
NL
390
391 $entry->removeTag($tag);
392 $em = $this->getDoctrine()->getManager();
393 $em->persist($entry);
394 $em->flush();
395
396 $json = $this->get('serializer')->serialize($entry, 'json');
397
60faee00 398 return (new JsonResponse())->setJson($json);
f8bf8952
NL
399 }
400
401 /**
4346a860 402 * Retrieve all tags.
f8bf8952 403 *
092ca707 404 * @ApiDoc()
8eedc8cf 405 *
60faee00 406 * @return JsonResponse
f8bf8952 407 */
092ca707 408 public function getTagsAction()
7df80cb3 409 {
77273253 410 $this->validateAuthentication();
fc732227
JB
411
412 $tags = $this->getDoctrine()
413 ->getRepository('WallabagCoreBundle:Tag')
28bb4890 414 ->findAllTags($this->getUser()->getId());
fc732227
JB
415
416 $json = $this->get('serializer')->serialize($tags, 'json');
092ca707 417
60faee00 418 return (new JsonResponse())->setJson($json);
f8bf8952
NL
419 }
420
f8bf8952 421 /**
4346a860 422 * Permanently remove one tag from **every** entry.
f8bf8952
NL
423 *
424 * @ApiDoc(
425 * requirements={
a0e1eafc 426 * {"name"="tag", "dataType"="string", "required"=true, "requirement"="\w+", "description"="Tag as a string"}
f8bf8952
NL
427 * }
428 * )
8eedc8cf 429 *
60faee00 430 * @return JsonResponse
f8bf8952 431 */
a0e1eafc 432 public function deleteTagLabelAction(Request $request)
f8bf8952 433 {
77273253 434 $this->validateAuthentication();
a0e1eafc
JB
435 $label = $request->request->get('tag', '');
436
437 $tag = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($label);
438
439 if (empty($tag)) {
440 throw $this->createNotFoundException('Tag not found');
441 }
fc732227
JB
442
443 $this->getDoctrine()
444 ->getRepository('WallabagCoreBundle:Entry')
445 ->removeTag($this->getUser()->getId(), $tag);
092ca707 446
ac8cf632
JB
447 $this->cleanOrphanTag($tag);
448
092ca707
NL
449 $json = $this->get('serializer')->serialize($tag, 'json');
450
60faee00 451 return (new JsonResponse())->setJson($json);
769e19dc 452 }
4da01f49
TC
453
454 /**
a0e1eafc 455 * Permanently remove some tags from **every** entry.
4da01f49
TC
456 *
457 * @ApiDoc(
458 * requirements={
a0e1eafc 459 * {"name"="tags", "dataType"="string", "required"=true, "format"="tag1,tag2", "description"="Tags as strings (comma splitted)"}
4da01f49
TC
460 * }
461 * )
462 *
60faee00 463 * @return JsonResponse
4da01f49 464 */
a0e1eafc 465 public function deleteTagsLabelAction(Request $request)
4da01f49
TC
466 {
467 $this->validateAuthentication();
4da01f49 468
a0e1eafc
JB
469 $tagsLabels = $request->request->get('tags', '');
470
471 $tags = [];
472
473 foreach (explode(',', $tagsLabels) as $tagLabel) {
474 $tagEntity = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($tagLabel);
475
476 if (!empty($tagEntity)) {
477 $tags[] = $tagEntity;
478 }
479 }
480
481 if (empty($tags)) {
482 throw $this->createNotFoundException('Tags not found');
483 }
484
4da01f49
TC
485 $this->getDoctrine()
486 ->getRepository('WallabagCoreBundle:Entry')
a0e1eafc 487 ->removeTags($this->getUser()->getId(), $tags);
4da01f49 488
ac8cf632
JB
489 $this->cleanOrphanTag($tags);
490
a0e1eafc 491 $json = $this->get('serializer')->serialize($tags, 'json');
4da01f49 492
60faee00 493 return (new JsonResponse())->setJson($json);
4da01f49
TC
494 }
495
496 /**
a0e1eafc 497 * Permanently remove one tag from **every** entry.
4da01f49
TC
498 *
499 * @ApiDoc(
500 * requirements={
a0e1eafc 501 * {"name"="tag", "dataType"="integer", "requirement"="\w+", "description"="The tag"}
4da01f49
TC
502 * }
503 * )
504 *
60faee00 505 * @return JsonResponse
4da01f49 506 */
a0e1eafc 507 public function deleteTagAction(Tag $tag)
4da01f49
TC
508 {
509 $this->validateAuthentication();
510
4da01f49
TC
511 $this->getDoctrine()
512 ->getRepository('WallabagCoreBundle:Entry')
a0e1eafc 513 ->removeTag($this->getUser()->getId(), $tag);
4da01f49 514
ac8cf632
JB
515 $this->cleanOrphanTag($tag);
516
a0e1eafc 517 $json = $this->get('serializer')->serialize($tag, 'json');
4da01f49 518
60faee00 519 return (new JsonResponse())->setJson($json);
4da01f49
TC
520 }
521
351eb8d9
TC
522 /**
523 * Retrieve annotations for an entry.
524 *
525 * @ApiDoc(
526 * requirements={
527 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
528 * }
529 * )
530 *
1eea248b 531 * @param Entry $entry
b1e92f8c 532 *
1eea248b 533 * @return JsonResponse
351eb8d9
TC
534 */
535 public function getAnnotationsAction(Entry $entry)
536 {
351eb8d9
TC
537 $this->validateAuthentication();
538
aa474109 539 return $this->forward('WallabagAnnotationBundle:WallabagAnnotation:getAnnotations', [
0c271b9e
TC
540 'entry' => $entry,
541 ]);
351eb8d9
TC
542 }
543
544 /**
545 * Creates a new annotation.
546 *
351eb8d9
TC
547 * @ApiDoc(
548 * requirements={
549 * {"name"="ranges", "dataType"="array", "requirement"="\w+", "description"="The range array for the annotation"},
550 * {"name"="quote", "dataType"="string", "required"=false, "description"="Optional, quote for the annotation"},
551 * {"name"="text", "dataType"="string", "required"=true, "description"=""},
552 * }
553 * )
aa474109
JB
554 *
555 * @param Request $request
556 * @param Entry $entry
557 *
558 * @return JsonResponse
351eb8d9
TC
559 */
560 public function postAnnotationAction(Request $request, Entry $entry)
561 {
562 $this->validateAuthentication();
563
aa474109
JB
564 return $this->forward('WallabagAnnotationBundle:WallabagAnnotation:postAnnotation', [
565 'request' => $request,
566 'entry' => $entry,
567 ]);
351eb8d9
TC
568 }
569
570 /**
571 * Updates an annotation.
572 *
573 * @ApiDoc(
574 * requirements={
575 * {"name"="annotation", "dataType"="string", "requirement"="\w+", "description"="The annotation ID"}
576 * }
577 * )
578 *
579 * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation")
580 *
1eea248b 581 * @param Annotation $annotation
b1e92f8c
TC
582 * @param Request $request
583 *
1eea248b 584 * @return JsonResponse
351eb8d9
TC
585 */
586 public function putAnnotationAction(Annotation $annotation, Request $request)
587 {
351eb8d9
TC
588 $this->validateAuthentication();
589
aa474109
JB
590 return $this->forward('WallabagAnnotationBundle:WallabagAnnotation:putAnnotation', [
591 'annotation' => $annotation,
592 'request' => $request,
593 ]);
351eb8d9
TC
594 }
595
596 /**
597 * Removes an annotation.
598 *
599 * @ApiDoc(
600 * requirements={
601 * {"name"="annotation", "dataType"="string", "requirement"="\w+", "description"="The annotation ID"}
602 * }
603 * )
604 *
605 * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation")
606 *
1eea248b 607 * @param Annotation $annotation
b1e92f8c 608 *
1eea248b 609 * @return JsonResponse
351eb8d9
TC
610 */
611 public function deleteAnnotationAction(Annotation $annotation)
612 {
351eb8d9
TC
613 $this->validateAuthentication();
614
aa474109
JB
615 return $this->forward('WallabagAnnotationBundle:WallabagAnnotation:deleteAnnotation', [
616 'annotation' => $annotation,
617 ]);
351eb8d9
TC
618 }
619
2b477030 620 /**
6f8310b4
TC
621 * Retrieve version number.
622 *
623 * @ApiDoc()
2b477030 624 *
60faee00 625 * @return JsonResponse
2b477030
V
626 */
627 public function getVersionAction()
628 {
629 $version = $this->container->getParameter('wallabag_core.version');
630
631 $json = $this->get('serializer')->serialize($version, 'json');
632
60faee00 633 return (new JsonResponse())->setJson($json);
2b477030 634 }
769e19dc 635
ac8cf632
JB
636 /**
637 * Remove orphan tag in case no entries are associated to it.
638 *
639 * @param Tag|array $tags
640 */
641 private function cleanOrphanTag($tags)
642 {
643 if (!is_array($tags)) {
644 $tags = [$tags];
645 }
646
647 $em = $this->getDoctrine()->getManager();
648
649 foreach ($tags as $tag) {
650 if (count($tag->getEntries()) === 0) {
651 $em->remove($tag);
652 }
653 }
654
655 $em->flush();
656 }
657
769e19dc
J
658 /**
659 * Validate that the first id is equal to the second one.
4346a860 660 * If not, throw exception. It means a user try to access information from an other user.
769e19dc 661 *
4346a860 662 * @param int $requestUserId User id from the requested source
769e19dc 663 */
fcb1fba5 664 private function validateUserAccess($requestUserId)
769e19dc 665 {
18f8f32f 666 $user = $this->get('security.token_storage')->getToken()->getUser();
fcb1fba5
NL
667 if ($requestUserId != $user->getId()) {
668 throw $this->createAccessDeniedException('Access forbidden. Entry user id: '.$requestUserId.', logged user id: '.$user->getId());
769e19dc
J
669 }
670 }
7df80cb3 671}