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