diff options
Diffstat (limited to 'src/Wallabag/ApiBundle/Controller/EntryRestController.php')
-rw-r--r-- | src/Wallabag/ApiBundle/Controller/EntryRestController.php | 419 |
1 files changed, 322 insertions, 97 deletions
diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php index 54c1747c..09b73ccb 100644 --- a/src/Wallabag/ApiBundle/Controller/EntryRestController.php +++ b/src/Wallabag/ApiBundle/Controller/EntryRestController.php | |||
@@ -5,6 +5,7 @@ namespace Wallabag\ApiBundle\Controller; | |||
5 | use Hateoas\Configuration\Route; | 5 | use Hateoas\Configuration\Route; |
6 | use Hateoas\Representation\Factory\PagerfantaFactory; | 6 | use Hateoas\Representation\Factory\PagerfantaFactory; |
7 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; | 7 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; |
8 | use Symfony\Component\HttpKernel\Exception\HttpException; | ||
8 | use Symfony\Component\HttpFoundation\Request; | 9 | use Symfony\Component\HttpFoundation\Request; |
9 | use Symfony\Component\HttpFoundation\JsonResponse; | 10 | use Symfony\Component\HttpFoundation\JsonResponse; |
10 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | 11 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; |
@@ -41,12 +42,10 @@ class EntryRestController extends WallabagRestController | |||
41 | ->getRepository('WallabagCoreBundle:Entry') | 42 | ->getRepository('WallabagCoreBundle:Entry') |
42 | ->findByUrlAndUserId($url, $this->getUser()->getId()); | 43 | ->findByUrlAndUserId($url, $this->getUser()->getId()); |
43 | 44 | ||
44 | $results[$url] = false === $res ? false : true; | 45 | $results[$url] = $res instanceof Entry ? $res->getId() : false; |
45 | } | 46 | } |
46 | 47 | ||
47 | $json = $this->get('serializer')->serialize($results, 'json'); | 48 | return $this->sendResponse($results); |
48 | |||
49 | return (new JsonResponse())->setJson($json); | ||
50 | } | 49 | } |
51 | 50 | ||
52 | // let's see if it is a simple url? | 51 | // let's see if it is a simple url? |
@@ -60,11 +59,9 @@ class EntryRestController extends WallabagRestController | |||
60 | ->getRepository('WallabagCoreBundle:Entry') | 59 | ->getRepository('WallabagCoreBundle:Entry') |
61 | ->findByUrlAndUserId($url, $this->getUser()->getId()); | 60 | ->findByUrlAndUserId($url, $this->getUser()->getId()); |
62 | 61 | ||
63 | $exists = false === $res ? false : true; | 62 | $exists = $res instanceof Entry ? $res->getId() : false; |
64 | |||
65 | $json = $this->get('serializer')->serialize(['exists' => $exists], 'json'); | ||
66 | 63 | ||
67 | return (new JsonResponse())->setJson($json); | 64 | return $this->sendResponse(['exists' => $exists]); |
68 | } | 65 | } |
69 | 66 | ||
70 | /** | 67 | /** |
@@ -125,9 +122,7 @@ class EntryRestController extends WallabagRestController | |||
125 | ) | 122 | ) |
126 | ); | 123 | ); |
127 | 124 | ||
128 | $json = $this->get('serializer')->serialize($paginatedCollection, 'json'); | 125 | return $this->sendResponse($paginatedCollection); |
129 | |||
130 | return (new JsonResponse())->setJson($json); | ||
131 | } | 126 | } |
132 | 127 | ||
133 | /** | 128 | /** |
@@ -146,9 +141,7 @@ class EntryRestController extends WallabagRestController | |||
146 | $this->validateAuthentication(); | 141 | $this->validateAuthentication(); |
147 | $this->validateUserAccess($entry->getUser()->getId()); | 142 | $this->validateUserAccess($entry->getUser()->getId()); |
148 | 143 | ||
149 | $json = $this->get('serializer')->serialize($entry, 'json'); | 144 | return $this->sendResponse($entry); |
150 | |||
151 | return (new JsonResponse())->setJson($json); | ||
152 | } | 145 | } |
153 | 146 | ||
154 | /** | 147 | /** |
@@ -174,74 +167,152 @@ class EntryRestController extends WallabagRestController | |||
174 | } | 167 | } |
175 | 168 | ||
176 | /** | 169 | /** |
177 | * Create an entry. | 170 | * Handles an entries list and delete URL. |
178 | * | 171 | * |
179 | * @ApiDoc( | 172 | * @ApiDoc( |
180 | * parameters={ | 173 | * parameters={ |
181 | * {"name"="url", "dataType"="string", "required"=true, "format"="http://www.test.com/article.html", "description"="Url for the entry."}, | 174 | * {"name"="urls", "dataType"="string", "required"=true, "format"="A JSON array of urls [{'url': 'http://...'}, {'url': 'http://...'}]", "description"="Urls (as an array) to delete."} |
182 | * {"name"="title", "dataType"="string", "required"=false, "description"="Optional, we'll get the title from the page."}, | ||
183 | * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."}, | ||
184 | * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already starred"}, | ||
185 | * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already archived"}, | ||
186 | * } | 175 | * } |
187 | * ) | 176 | * ) |
188 | * | 177 | * |
189 | * @return JsonResponse | 178 | * @return JsonResponse |
190 | */ | 179 | */ |
191 | public function postEntriesAction(Request $request) | 180 | public function deleteEntriesListAction(Request $request) |
192 | { | 181 | { |
193 | $this->validateAuthentication(); | 182 | $this->validateAuthentication(); |
194 | 183 | ||
195 | $url = $request->request->get('url'); | 184 | $urls = json_decode($request->query->get('urls', [])); |
196 | $title = $request->request->get('title'); | ||
197 | $isArchived = $request->request->get('archive'); | ||
198 | $isStarred = $request->request->get('starred'); | ||
199 | 185 | ||
200 | $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($url, $this->getUser()->getId()); | 186 | if (empty($urls)) { |
187 | return $this->sendResponse([]); | ||
188 | } | ||
201 | 189 | ||
202 | if (false === $entry) { | 190 | $results = []; |
203 | $entry = new Entry($this->getUser()); | 191 | |
204 | try { | 192 | // handle multiple urls |
205 | $entry = $this->get('wallabag_core.content_proxy')->updateEntry( | 193 | foreach ($urls as $key => $url) { |
206 | $entry, | 194 | $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId( |
207 | $url | 195 | $url, |
208 | ); | 196 | $this->getUser()->getId() |
209 | } catch (\Exception $e) { | 197 | ); |
210 | $this->get('logger')->error('Error while saving an entry', [ | 198 | |
211 | 'exception' => $e, | 199 | $results[$key]['url'] = $url; |
212 | 'entry' => $entry, | 200 | |
213 | ]); | 201 | if (false !== $entry) { |
214 | $entry->setUrl($url); | 202 | $em = $this->getDoctrine()->getManager(); |
203 | $em->remove($entry); | ||
204 | $em->flush(); | ||
205 | |||
206 | // entry deleted, dispatch event about it! | ||
207 | $this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry)); | ||
215 | } | 208 | } |
216 | } | ||
217 | 209 | ||
218 | if (!is_null($title)) { | 210 | $results[$key]['entry'] = $entry instanceof Entry ? true : false; |
219 | $entry->setTitle($title); | ||
220 | } | 211 | } |
221 | 212 | ||
222 | $tags = $request->request->get('tags', ''); | 213 | return $this->sendResponse($results); |
223 | if (!empty($tags)) { | 214 | } |
224 | $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags); | 215 | |
216 | /** | ||
217 | * Handles an entries list and create URL. | ||
218 | * | ||
219 | * @ApiDoc( | ||
220 | * parameters={ | ||
221 | * {"name"="urls", "dataType"="string", "required"=true, "format"="A JSON array of urls [{'url': 'http://...'}, {'url': 'http://...'}]", "description"="Urls (as an array) to create."} | ||
222 | * } | ||
223 | * ) | ||
224 | * | ||
225 | * @return JsonResponse | ||
226 | * | ||
227 | * @throws HttpException When limit is reached | ||
228 | */ | ||
229 | public function postEntriesListAction(Request $request) | ||
230 | { | ||
231 | $this->validateAuthentication(); | ||
232 | |||
233 | $urls = json_decode($request->query->get('urls', [])); | ||
234 | |||
235 | $limit = $this->container->getParameter('wallabag_core.api_limit_mass_actions'); | ||
236 | |||
237 | if (count($urls) > $limit) { | ||
238 | throw new HttpException(400, 'API limit reached'); | ||
225 | } | 239 | } |
226 | 240 | ||
227 | if (!is_null($isStarred)) { | 241 | $results = []; |
228 | $entry->setStarred((bool) $isStarred); | 242 | if (empty($urls)) { |
243 | return $this->sendResponse($results); | ||
229 | } | 244 | } |
230 | 245 | ||
231 | if (!is_null($isArchived)) { | 246 | // handle multiple urls |
232 | $entry->setArchived((bool) $isArchived); | 247 | foreach ($urls as $key => $url) { |
248 | $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId( | ||
249 | $url, | ||
250 | $this->getUser()->getId() | ||
251 | ); | ||
252 | |||
253 | $results[$key]['url'] = $url; | ||
254 | |||
255 | if (false === $entry) { | ||
256 | $entry = new Entry($this->getUser()); | ||
257 | |||
258 | $this->get('wallabag_core.content_proxy')->updateEntry($entry, $url); | ||
259 | } | ||
260 | |||
261 | $em = $this->getDoctrine()->getManager(); | ||
262 | $em->persist($entry); | ||
263 | $em->flush(); | ||
264 | |||
265 | $results[$key]['entry'] = $entry instanceof Entry ? $entry->getId() : false; | ||
266 | |||
267 | // entry saved, dispatch event about it! | ||
268 | $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); | ||
233 | } | 269 | } |
234 | 270 | ||
235 | $em = $this->getDoctrine()->getManager(); | 271 | return $this->sendResponse($results); |
236 | $em->persist($entry); | 272 | } |
237 | $em->flush(); | ||
238 | 273 | ||
239 | // entry saved, dispatch event about it! | 274 | /** |
240 | $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); | 275 | * Create an entry. |
276 | * | ||
277 | * If you want to provide the HTML content (which means wallabag won't fetch it from the url), you must provide `content`, `title` & `url` fields **non-empty**. | ||
278 | * Otherwise, content will be fetched as normal from the url and values will be overwritten. | ||
279 | * | ||
280 | * @ApiDoc( | ||
281 | * parameters={ | ||
282 | * {"name"="url", "dataType"="string", "required"=true, "format"="http://www.test.com/article.html", "description"="Url for the entry."}, | ||
283 | * {"name"="title", "dataType"="string", "required"=false, "description"="Optional, we'll get the title from the page."}, | ||
284 | * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."}, | ||
285 | * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already starred"}, | ||
286 | * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already archived"}, | ||
287 | * {"name"="content", "dataType"="string", "required"=false, "description"="Content of the entry"}, | ||
288 | * {"name"="language", "dataType"="string", "required"=false, "description"="Language of the entry"}, | ||
289 | * {"name"="preview_picture", "dataType"="string", "required"=false, "description"="Preview picture of the entry"}, | ||
290 | * {"name"="published_at", "dataType"="datetime|integer", "format"="YYYY-MM-DDTHH:II:SS+TZ or a timestamp", "required"=false, "description"="Published date of the entry"}, | ||
291 | * {"name"="authors", "dataType"="string", "format"="Name Firstname,author2,author3", "required"=false, "description"="Authors of the entry"}, | ||
292 | * } | ||
293 | * ) | ||
294 | * | ||
295 | * @return JsonResponse | ||
296 | */ | ||
297 | public function postEntriesAction(Request $request) | ||
298 | { | ||
299 | $this->validateAuthentication(); | ||
300 | |||
301 | $url = $request->request->get('url'); | ||
241 | 302 | ||
242 | $json = $this->get('serializer')->serialize($entry, 'json'); | 303 | $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId( |
304 | $url, | ||
305 | $this->getUser()->getId() | ||
306 | ); | ||
243 | 307 | ||
244 | return (new JsonResponse())->setJson($json); | 308 | if (false === $entry) { |
309 | $entry = new Entry($this->getUser()); | ||
310 | $entry->setUrl($url); | ||
311 | } | ||
312 | |||
313 | $this->upsertEntry($entry, $request); | ||
314 | |||
315 | return $this->sendResponse($entry); | ||
245 | } | 316 | } |
246 | 317 | ||
247 | /** | 318 | /** |
@@ -256,6 +327,11 @@ class EntryRestController extends WallabagRestController | |||
256 | * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."}, | 327 | * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."}, |
257 | * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="archived the entry."}, | 328 | * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="archived the entry."}, |
258 | * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="starred the entry."}, | 329 | * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="starred the entry."}, |
330 | * {"name"="content", "dataType"="string", "required"=false, "description"="Content of the entry"}, | ||
331 | * {"name"="language", "dataType"="string", "required"=false, "description"="Language of the entry"}, | ||
332 | * {"name"="preview_picture", "dataType"="string", "required"=false, "description"="Preview picture of the entry"}, | ||
333 | * {"name"="published_at", "dataType"="datetime|integer", "format"="YYYY-MM-DDTHH:II:SS+TZ or a timestamp", "required"=false, "description"="Published date of the entry"}, | ||
334 | * {"name"="authors", "dataType"="string", "format"="Name Firstname,author2,author3", "required"=false, "description"="Authors of the entry"}, | ||
259 | * } | 335 | * } |
260 | * ) | 336 | * ) |
261 | * | 337 | * |
@@ -266,33 +342,9 @@ class EntryRestController extends WallabagRestController | |||
266 | $this->validateAuthentication(); | 342 | $this->validateAuthentication(); |
267 | $this->validateUserAccess($entry->getUser()->getId()); | 343 | $this->validateUserAccess($entry->getUser()->getId()); |
268 | 344 | ||
269 | $title = $request->request->get('title'); | 345 | $this->upsertEntry($entry, $request, true); |
270 | $isArchived = $request->request->get('archive'); | ||
271 | $isStarred = $request->request->get('starred'); | ||
272 | 346 | ||
273 | if (!is_null($title)) { | 347 | return $this->sendResponse($entry); |
274 | $entry->setTitle($title); | ||
275 | } | ||
276 | |||
277 | if (!is_null($isArchived)) { | ||
278 | $entry->setArchived((bool) $isArchived); | ||
279 | } | ||
280 | |||
281 | if (!is_null($isStarred)) { | ||
282 | $entry->setStarred((bool) $isStarred); | ||
283 | } | ||
284 | |||
285 | $tags = $request->request->get('tags', ''); | ||
286 | if (!empty($tags)) { | ||
287 | $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags); | ||
288 | } | ||
289 | |||
290 | $em = $this->getDoctrine()->getManager(); | ||
291 | $em->flush(); | ||
292 | |||
293 | $json = $this->get('serializer')->serialize($entry, 'json'); | ||
294 | |||
295 | return (new JsonResponse())->setJson($json); | ||
296 | } | 348 | } |
297 | 349 | ||
298 | /** | 350 | /** |
@@ -313,7 +365,7 @@ class EntryRestController extends WallabagRestController | |||
313 | $this->validateUserAccess($entry->getUser()->getId()); | 365 | $this->validateUserAccess($entry->getUser()->getId()); |
314 | 366 | ||
315 | try { | 367 | try { |
316 | $entry = $this->get('wallabag_core.content_proxy')->updateEntry($entry, $entry->getUrl()); | 368 | $this->get('wallabag_core.content_proxy')->updateEntry($entry, $entry->getUrl()); |
317 | } catch (\Exception $e) { | 369 | } catch (\Exception $e) { |
318 | $this->get('logger')->error('Error while saving an entry', [ | 370 | $this->get('logger')->error('Error while saving an entry', [ |
319 | 'exception' => $e, | 371 | 'exception' => $e, |
@@ -335,9 +387,7 @@ class EntryRestController extends WallabagRestController | |||
335 | // entry saved, dispatch event about it! | 387 | // entry saved, dispatch event about it! |
336 | $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); | 388 | $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); |
337 | 389 | ||
338 | $json = $this->get('serializer')->serialize($entry, 'json'); | 390 | return $this->sendResponse($entry); |
339 | |||
340 | return (new JsonResponse())->setJson($json); | ||
341 | } | 391 | } |
342 | 392 | ||
343 | /** | 393 | /** |
@@ -363,9 +413,7 @@ class EntryRestController extends WallabagRestController | |||
363 | // entry deleted, dispatch event about it! | 413 | // entry deleted, dispatch event about it! |
364 | $this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry)); | 414 | $this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry)); |
365 | 415 | ||
366 | $json = $this->get('serializer')->serialize($entry, 'json'); | 416 | return $this->sendResponse($entry); |
367 | |||
368 | return (new JsonResponse())->setJson($json); | ||
369 | } | 417 | } |
370 | 418 | ||
371 | /** | 419 | /** |
@@ -384,9 +432,7 @@ class EntryRestController extends WallabagRestController | |||
384 | $this->validateAuthentication(); | 432 | $this->validateAuthentication(); |
385 | $this->validateUserAccess($entry->getUser()->getId()); | 433 | $this->validateUserAccess($entry->getUser()->getId()); |
386 | 434 | ||
387 | $json = $this->get('serializer')->serialize($entry->getTags(), 'json'); | 435 | return $this->sendResponse($entry->getTags()); |
388 | |||
389 | return (new JsonResponse())->setJson($json); | ||
390 | } | 436 | } |
391 | 437 | ||
392 | /** | 438 | /** |
@@ -410,16 +456,14 @@ class EntryRestController extends WallabagRestController | |||
410 | 456 | ||
411 | $tags = $request->request->get('tags', ''); | 457 | $tags = $request->request->get('tags', ''); |
412 | if (!empty($tags)) { | 458 | if (!empty($tags)) { |
413 | $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags); | 459 | $this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $tags); |
414 | } | 460 | } |
415 | 461 | ||
416 | $em = $this->getDoctrine()->getManager(); | 462 | $em = $this->getDoctrine()->getManager(); |
417 | $em->persist($entry); | 463 | $em->persist($entry); |
418 | $em->flush(); | 464 | $em->flush(); |
419 | 465 | ||
420 | $json = $this->get('serializer')->serialize($entry, 'json'); | 466 | return $this->sendResponse($entry); |
421 | |||
422 | return (new JsonResponse())->setJson($json); | ||
423 | } | 467 | } |
424 | 468 | ||
425 | /** | 469 | /** |
@@ -444,8 +488,189 @@ class EntryRestController extends WallabagRestController | |||
444 | $em->persist($entry); | 488 | $em->persist($entry); |
445 | $em->flush(); | 489 | $em->flush(); |
446 | 490 | ||
447 | $json = $this->get('serializer')->serialize($entry, 'json'); | 491 | return $this->sendResponse($entry); |
492 | } | ||
493 | |||
494 | /** | ||
495 | * Handles an entries list delete tags from them. | ||
496 | * | ||
497 | * @ApiDoc( | ||
498 | * parameters={ | ||
499 | * {"name"="list", "dataType"="string", "required"=true, "format"="A JSON array of urls [{'url': 'http://...','tags': 'tag1, tag2'}, {'url': 'http://...','tags': 'tag1, tag2'}]", "description"="Urls (as an array) to handle."} | ||
500 | * } | ||
501 | * ) | ||
502 | * | ||
503 | * @return JsonResponse | ||
504 | */ | ||
505 | public function deleteEntriesTagsListAction(Request $request) | ||
506 | { | ||
507 | $this->validateAuthentication(); | ||
508 | |||
509 | $list = json_decode($request->query->get('list', [])); | ||
510 | |||
511 | if (empty($list)) { | ||
512 | return $this->sendResponse([]); | ||
513 | } | ||
514 | |||
515 | // handle multiple urls | ||
516 | $results = []; | ||
517 | |||
518 | foreach ($list as $key => $element) { | ||
519 | $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId( | ||
520 | $element->url, | ||
521 | $this->getUser()->getId() | ||
522 | ); | ||
523 | |||
524 | $results[$key]['url'] = $element->url; | ||
525 | $results[$key]['entry'] = $entry instanceof Entry ? $entry->getId() : false; | ||
526 | |||
527 | $tags = $element->tags; | ||
528 | |||
529 | if (false !== $entry && !(empty($tags))) { | ||
530 | $tags = explode(',', $tags); | ||
531 | foreach ($tags as $label) { | ||
532 | $label = trim($label); | ||
533 | |||
534 | $tag = $this->getDoctrine() | ||
535 | ->getRepository('WallabagCoreBundle:Tag') | ||
536 | ->findOneByLabel($label); | ||
537 | |||
538 | if (false !== $tag) { | ||
539 | $entry->removeTag($tag); | ||
540 | } | ||
541 | } | ||
542 | |||
543 | $em = $this->getDoctrine()->getManager(); | ||
544 | $em->persist($entry); | ||
545 | $em->flush(); | ||
546 | } | ||
547 | } | ||
548 | |||
549 | return $this->sendResponse($results); | ||
550 | } | ||
551 | |||
552 | /** | ||
553 | * Handles an entries list and add tags to them. | ||
554 | * | ||
555 | * @ApiDoc( | ||
556 | * parameters={ | ||
557 | * {"name"="list", "dataType"="string", "required"=true, "format"="A JSON array of urls [{'url': 'http://...','tags': 'tag1, tag2'}, {'url': 'http://...','tags': 'tag1, tag2'}]", "description"="Urls (as an array) to handle."} | ||
558 | * } | ||
559 | * ) | ||
560 | * | ||
561 | * @return JsonResponse | ||
562 | */ | ||
563 | public function postEntriesTagsListAction(Request $request) | ||
564 | { | ||
565 | $this->validateAuthentication(); | ||
566 | |||
567 | $list = json_decode($request->query->get('list', [])); | ||
568 | |||
569 | if (empty($list)) { | ||
570 | return $this->sendResponse([]); | ||
571 | } | ||
572 | |||
573 | $results = []; | ||
574 | |||
575 | // handle multiple urls | ||
576 | foreach ($list as $key => $element) { | ||
577 | $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId( | ||
578 | $element->url, | ||
579 | $this->getUser()->getId() | ||
580 | ); | ||
581 | |||
582 | $results[$key]['url'] = $element->url; | ||
583 | $results[$key]['entry'] = $entry instanceof Entry ? $entry->getId() : false; | ||
584 | |||
585 | $tags = $element->tags; | ||
586 | |||
587 | if (false !== $entry && !(empty($tags))) { | ||
588 | $this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $tags); | ||
589 | |||
590 | $em = $this->getDoctrine()->getManager(); | ||
591 | $em->persist($entry); | ||
592 | $em->flush(); | ||
593 | } | ||
594 | } | ||
595 | |||
596 | return $this->sendResponse($results); | ||
597 | } | ||
598 | |||
599 | /** | ||
600 | * Shortcut to send data serialized in json. | ||
601 | * | ||
602 | * @param mixed $data | ||
603 | * | ||
604 | * @return JsonResponse | ||
605 | */ | ||
606 | private function sendResponse($data) | ||
607 | { | ||
608 | $json = $this->get('serializer')->serialize($data, 'json'); | ||
448 | 609 | ||
449 | return (new JsonResponse())->setJson($json); | 610 | return (new JsonResponse())->setJson($json); |
450 | } | 611 | } |
612 | |||
613 | /** | ||
614 | * Update or Insert a new entry. | ||
615 | * | ||
616 | * @param Entry $entry | ||
617 | * @param Request $request | ||
618 | * @param bool $disableContentUpdate If we don't want the content to be update by fetching the url (used when patching instead of posting) | ||
619 | */ | ||
620 | private function upsertEntry(Entry $entry, Request $request, $disableContentUpdate = false) | ||
621 | { | ||
622 | $title = $request->request->get('title'); | ||
623 | $tags = $request->request->get('tags', []); | ||
624 | $isArchived = $request->request->get('archive'); | ||
625 | $isStarred = $request->request->get('starred'); | ||
626 | $content = $request->request->get('content'); | ||
627 | $language = $request->request->get('language'); | ||
628 | $picture = $request->request->get('preview_picture'); | ||
629 | $publishedAt = $request->request->get('published_at'); | ||
630 | $authors = $request->request->get('authors', ''); | ||
631 | |||
632 | try { | ||
633 | $this->get('wallabag_core.content_proxy')->updateEntry( | ||
634 | $entry, | ||
635 | $entry->getUrl(), | ||
636 | [ | ||
637 | 'title' => !empty($title) ? $title : $entry->getTitle(), | ||
638 | 'html' => !empty($content) ? $content : $entry->getContent(), | ||
639 | 'url' => $entry->getUrl(), | ||
640 | 'language' => !empty($language) ? $language : $entry->getLanguage(), | ||
641 | 'date' => !empty($publishedAt) ? $publishedAt : $entry->getPublishedAt(), | ||
642 | // faking the open graph preview picture | ||
643 | 'open_graph' => [ | ||
644 | 'og_image' => !empty($picture) ? $picture : $entry->getPreviewPicture(), | ||
645 | ], | ||
646 | 'authors' => is_string($authors) ? explode(',', $authors) : $entry->getPublishedBy(), | ||
647 | ], | ||
648 | $disableContentUpdate | ||
649 | ); | ||
650 | } catch (\Exception $e) { | ||
651 | $this->get('logger')->error('Error while saving an entry', [ | ||
652 | 'exception' => $e, | ||
653 | 'entry' => $entry, | ||
654 | ]); | ||
655 | } | ||
656 | |||
657 | if (!is_null($isArchived)) { | ||
658 | $entry->setArchived((bool) $isArchived); | ||
659 | } | ||
660 | |||
661 | if (!is_null($isStarred)) { | ||
662 | $entry->setStarred((bool) $isStarred); | ||
663 | } | ||
664 | |||
665 | if (!empty($tags)) { | ||
666 | $this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $tags); | ||
667 | } | ||
668 | |||
669 | $em = $this->getDoctrine()->getManager(); | ||
670 | $em->persist($entry); | ||
671 | $em->flush(); | ||
672 | |||
673 | // entry saved, dispatch event about it! | ||
674 | $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); | ||
675 | } | ||
451 | } | 676 | } |