]> git.immae.eu Git - github/wallabag/wallabag.git/blame - src/Wallabag/CoreBundle/Controller/EntryController.php
Merge pull request #1879 from wallabag/v2-tag-field-position
[github/wallabag/wallabag.git] / src / Wallabag / CoreBundle / Controller / EntryController.php
CommitLineData
9d50517c
NL
1<?php
2
ad4d1caa 3namespace Wallabag\CoreBundle\Controller;
9d50517c 4
619cc453 5use Pagerfanta\Adapter\DoctrineORMAdapter;
671a2b88 6use Pagerfanta\Exception\OutOfRangeCurrentPageException;
619cc453 7use Pagerfanta\Pagerfanta;
9d50517c
NL
8use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
9use Symfony\Bundle\FrameworkBundle\Controller\Controller;
163eae0b 10use Symfony\Component\HttpFoundation\Request;
2863bf2a 11use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
be463487 12use Wallabag\CoreBundle\Entity\Entry;
b0b893ea 13use Wallabag\CoreBundle\Form\Type\EntryFilterType;
619cc453
JB
14use Wallabag\CoreBundle\Form\Type\EditEntryType;
15use Wallabag\CoreBundle\Form\Type\NewEntryType;
9d50517c
NL
16
17class EntryController extends Controller
18{
880a0e1c
NL
19 /**
20 * @param Entry $entry
21 */
22 private function updateEntry(Entry $entry)
23 {
24 try {
25 $entry = $this->get('wallabag_core.content_proxy')->updateEntry($entry, $entry->getUrl());
26 $em = $this->getDoctrine()->getManager();
27 $em->persist($entry);
28 $em->flush();
29 } catch (\Exception $e) {
30 return false;
31 }
32
33 return true;
34 }
35
b84a8055 36 /**
3d2b2d62
J
37 * @param Request $request
38 *
053b9568 39 * @Route("/new-entry", name="new_entry")
3d2b2d62 40 *
b84a8055
NL
41 * @return \Symfony\Component\HttpFoundation\Response
42 */
053b9568 43 public function addEntryFormAction(Request $request)
b84a8055 44 {
3b815d2d 45 $entry = new Entry($this->getUser());
b84a8055 46
5c895a7f 47 $form = $this->createForm(NewEntryType::class, $entry);
b84a8055
NL
48
49 $form->handleRequest($request);
50
51 if ($form->isValid()) {
5a4bbcc9 52 // check for existing entry, if it exists, redirect to it with a message
78833672 53 $existingEntry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($entry->getUrl(), $this->getUser()->getId());
dda57bb9 54
5a4bbcc9 55 if (false !== $existingEntry) {
dda57bb9
NL
56 $this->get('session')->getFlashBag()->add(
57 'notice',
4204a06b 58 $this->get('translator')->trans('flashes.entry.notice.entry_already_saved', array('%date%' => $existingEntry->getCreatedAt()->format('d-m-Y')))
dda57bb9
NL
59 );
60
a0d6ccc5 61 return $this->redirect($this->generateUrl('view', array('id' => $existingEntry->getId())));
dda57bb9
NL
62 }
63
880a0e1c 64 $this->updateEntry($entry);
b84a8055
NL
65 $this->get('session')->getFlashBag()->add(
66 'notice',
4204a06b 67 'flashes.entry.notice.entry_saved'
b84a8055
NL
68 );
69
70 return $this->redirect($this->generateUrl('homepage'));
71 }
72
053b9568 73 return $this->render('WallabagCoreBundle:Entry:new_form.html.twig', array(
b84a8055
NL
74 'form' => $form->createView(),
75 ));
76 }
77
880a0e1c
NL
78 /**
79 * @param Request $request
80 *
81 * @Route("/bookmarklet", name="bookmarklet")
82 *
83 * @return \Symfony\Component\HttpFoundation\Response
84 */
5f8a7857 85 public function addEntryViaBookmarkletAction(Request $request)
880a0e1c
NL
86 {
87 $entry = new Entry($this->getUser());
88 $entry->setUrl($request->get('url'));
89 $this->updateEntry($entry);
90
91 return $this->redirect($this->generateUrl('homepage'));
92 }
93
053b9568 94 /**
053b9568
NL
95 * @Route("/new", name="new")
96 *
97 * @return \Symfony\Component\HttpFoundation\Response
98 */
4d0ec0e7 99 public function addEntryAction()
053b9568
NL
100 {
101 return $this->render('WallabagCoreBundle:Entry:new.html.twig');
102 }
103
82d6d9cb
JB
104 /**
105 * Edit an entry content.
106 *
107 * @param Request $request
108 * @param Entry $entry
109 *
110 * @Route("/edit/{id}", requirements={"id" = "\d+"}, name="edit")
111 *
112 * @return \Symfony\Component\HttpFoundation\Response
113 */
114 public function editEntryAction(Request $request, Entry $entry)
115 {
116 $this->checkUserAction($entry);
117
5c895a7f 118 $form = $this->createForm(EditEntryType::class, $entry);
82d6d9cb
JB
119
120 $form->handleRequest($request);
121
122 if ($form->isValid()) {
123 $em = $this->getDoctrine()->getManager();
124 $em->persist($entry);
125 $em->flush();
126
127 $this->get('session')->getFlashBag()->add(
128 'notice',
4204a06b 129 'flashes.entry.notice.entry_updated'
82d6d9cb
JB
130 );
131
132 return $this->redirect($this->generateUrl('view', array('id' => $entry->getId())));
133 }
134
135 return $this->render('WallabagCoreBundle:Entry:edit.html.twig', array(
136 'form' => $form->createView(),
137 ));
138 }
139
89659c9e
NL
140 /**
141 * Shows all entries for current user.
142 *
143 * @param Request $request
144 * @param int $page
145 *
146 * @Route("/all/list/{page}", name="all", defaults={"page" = "1"})
147 *
148 * @return \Symfony\Component\HttpFoundation\Response
149 */
150 public function showAllAction(Request $request, $page)
151 {
2b7a4889 152 return $this->showEntries('all', $request, $page);
89659c9e
NL
153 }
154
9d50517c 155 /**
4346a860 156 * Shows unread entries for current user.
163eae0b 157 *
26864574
NL
158 * @param Request $request
159 * @param int $page
160 *
9fb6ac83 161 * @Route("/unread/list/{page}", name="unread", defaults={"page" = "1"})
3d2b2d62 162 *
163eae0b 163 * @return \Symfony\Component\HttpFoundation\Response
9d50517c 164 */
26864574 165 public function showUnreadAction(Request $request, $page)
9d50517c 166 {
5c072d2b
NL
167 // load the quickstart if no entry in database
168 if ($page == 1 && $this->get('wallabag_core.entry_repository')->countAllEntriesByUsername($this->getUser()->getId()) == 0) {
169 return $this->redirect($this->generateUrl('quickstart'));
170 }
171
0ab7404f 172 return $this->showEntries('unread', $request, $page);
9d50517c 173 }
bd9f0815
NL
174
175 /**
4346a860 176 * Shows read entries for current user.
163eae0b 177 *
26864574
NL
178 * @param Request $request
179 * @param int $page
180 *
9fb6ac83 181 * @Route("/archive/list/{page}", name="archive", defaults={"page" = "1"})
3d2b2d62 182 *
163eae0b 183 * @return \Symfony\Component\HttpFoundation\Response
bd9f0815 184 */
26864574 185 public function showArchiveAction(Request $request, $page)
bd9f0815 186 {
0ab7404f
JB
187 return $this->showEntries('archive', $request, $page);
188 }
189
190 /**
191 * Shows starred entries for current user.
192 *
193 * @param Request $request
194 * @param int $page
195 *
196 * @Route("/starred/list/{page}", name="starred", defaults={"page" = "1"})
197 *
198 * @return \Symfony\Component\HttpFoundation\Response
199 */
200 public function showStarredAction(Request $request, $page)
201 {
202 return $this->showEntries('starred', $request, $page);
203 }
26864574 204
0ab7404f
JB
205 /**
206 * Global method to retrieve entries depending on the given type
207 * It returns the response to be send.
208 *
209 * @param string $type Entries type: unread, starred or archive
210 * @param Request $request
211 * @param int $page
212 *
213 * @return \Symfony\Component\HttpFoundation\Response
214 */
215 private function showEntries($type, Request $request, $page)
216 {
5c072d2b 217 $repository = $this->get('wallabag_core.entry_repository');
0ab7404f
JB
218
219 switch ($type) {
220 case 'starred':
221 $qb = $repository->getBuilderForStarredByUser($this->getUser()->getId());
222 break;
223
224 case 'archive':
225 $qb = $repository->getBuilderForArchiveByUser($this->getUser()->getId());
226 break;
227
228 case 'unread':
229 $qb = $repository->getBuilderForUnreadByUser($this->getUser()->getId());
230 break;
231
2b7a4889
NL
232 case 'all':
233 $qb = $repository->getBuilderForAllByUser($this->getUser()->getId());
234 break;
235
0ab7404f
JB
236 default:
237 throw new \InvalidArgumentException(sprintf('Type "%s" is not implemented.', $type));
238 }
239
1d76102a 240 $form = $this->createForm(EntryFilterType::class);
9fb6ac83 241
26864574
NL
242 if ($request->query->has($form->getName())) {
243 // manually bind values from the request
244 $form->submit($request->query->get($form->getName()));
245
246 // build the query from the given form object
0ab7404f 247 $this->get('lexik_form_filter.query_builder_updater')->addFilterConditions($form, $qb);
26864574
NL
248 }
249
0ab7404f 250 $pagerAdapter = new DoctrineORMAdapter($qb->getQuery());
26864574
NL
251 $entries = new Pagerfanta($pagerAdapter);
252
48ffc5a4 253 $entries->setMaxPerPage($this->getUser()->getConfig()->getItemsPerPage());
671a2b88
ML
254 try {
255 $entries->setCurrentPage($page);
256 } catch (OutOfRangeCurrentPageException $e) {
257 if ($page > 1) {
258 return $this->redirect($this->generateUrl($type, array('page' => $entries->getNbPages())), 302);
259 }
260 }
bd9f0815
NL
261
262 return $this->render(
ad4d1caa 263 'WallabagCoreBundle:Entry:entries.html.twig',
9fb6ac83 264 array(
8ce32af6
JB
265 'form' => $form->createView(),
266 'entries' => $entries,
267 'currentPage' => $page,
9fb6ac83 268 )
bd9f0815 269 );
bd9f0815
NL
270 }
271
272 /**
4346a860 273 * Shows entry content.
163eae0b 274 *
3d2b2d62
J
275 * @param Entry $entry
276 *
bd9f0815 277 * @Route("/view/{id}", requirements={"id" = "\d+"}, name="view")
3d2b2d62 278 *
163eae0b 279 * @return \Symfony\Component\HttpFoundation\Response
bd9f0815 280 */
be463487 281 public function viewAction(Entry $entry)
bd9f0815 282 {
3d2b2d62
J
283 $this->checkUserAction($entry);
284
bd9f0815 285 return $this->render(
ad4d1caa 286 'WallabagCoreBundle:Entry:entry.html.twig',
bd9f0815
NL
287 array('entry' => $entry)
288 );
163eae0b
NL
289 }
290
831b02aa
JB
291 /**
292 * Reload an entry.
293 * Refetch content from the website and make it readable again.
294 *
295 * @param Entry $entry
296 *
297 * @Route("/reload/{id}", requirements={"id" = "\d+"}, name="reload_entry")
298 *
299 * @return \Symfony\Component\HttpFoundation\RedirectResponse
300 */
301 public function reloadAction(Entry $entry)
302 {
303 $this->checkUserAction($entry);
304
4204a06b 305 $message = 'flashes.entry.notice.entry_reloaded';
831b02aa 306 if (false === $this->updateEntry($entry)) {
4204a06b 307 $message = 'flashes.entry.notice.entry_reload_failed';
831b02aa
JB
308 }
309
310 $this->get('session')->getFlashBag()->add(
311 'notice',
312 $message
313 );
314
315 return $this->redirect($this->generateUrl('view', array('id' => $entry->getId())));
316 }
317
163eae0b 318 /**
4346a860 319 * Changes read status for an entry.
163eae0b 320 *
3d2b2d62
J
321 * @param Request $request
322 * @param Entry $entry
323 *
163eae0b 324 * @Route("/archive/{id}", requirements={"id" = "\d+"}, name="archive_entry")
3d2b2d62 325 *
163eae0b
NL
326 * @return \Symfony\Component\HttpFoundation\RedirectResponse
327 */
be463487 328 public function toggleArchiveAction(Request $request, Entry $entry)
163eae0b 329 {
3d2b2d62
J
330 $this->checkUserAction($entry);
331
163eae0b
NL
332 $entry->toggleArchive();
333 $this->getDoctrine()->getManager()->flush();
334
4204a06b
JB
335 $message = 'flashes.entry.notice.entry_unarchived';
336 if ($entry->isArchived()) {
337 $message = 'flashes.entry.notice.entry_archived';
338 }
339
163eae0b
NL
340 $this->get('session')->getFlashBag()->add(
341 'notice',
4204a06b 342 $message
163eae0b
NL
343 );
344
345 return $this->redirect($request->headers->get('referer'));
346 }
347
348 /**
4346a860 349 * Changes favorite status for an entry.
163eae0b 350 *
3d2b2d62
J
351 * @param Request $request
352 * @param Entry $entry
353 *
163eae0b 354 * @Route("/star/{id}", requirements={"id" = "\d+"}, name="star_entry")
3d2b2d62 355 *
163eae0b
NL
356 * @return \Symfony\Component\HttpFoundation\RedirectResponse
357 */
be463487 358 public function toggleStarAction(Request $request, Entry $entry)
163eae0b 359 {
3d2b2d62
J
360 $this->checkUserAction($entry);
361
163eae0b
NL
362 $entry->toggleStar();
363 $this->getDoctrine()->getManager()->flush();
364
4204a06b
JB
365 $message = 'flashes.entry.notice.entry_unstarred';
366 if ($entry->isStarred()) {
367 $message = 'flashes.entry.notice.entry_starred';
368 }
369
163eae0b
NL
370 $this->get('session')->getFlashBag()->add(
371 'notice',
4204a06b 372 $message
163eae0b
NL
373 );
374
375 return $this->redirect($request->headers->get('referer'));
376 }
377
378 /**
2863bf2a 379 * Deletes entry and redirect to the homepage or the last viewed page.
163eae0b 380 *
16a3d04c 381 * @param Entry $entry
3d2b2d62 382 *
163eae0b 383 * @Route("/delete/{id}", requirements={"id" = "\d+"}, name="delete_entry")
3d2b2d62 384 *
163eae0b
NL
385 * @return \Symfony\Component\HttpFoundation\RedirectResponse
386 */
18d5f454 387 public function deleteEntryAction(Request $request, Entry $entry)
163eae0b 388 {
3d2b2d62
J
389 $this->checkUserAction($entry);
390
2863bf2a
JB
391 // generates the view url for this entry to check for redirection later
392 // to avoid redirecting to the deleted entry. Ugh.
393 $url = $this->generateUrl(
394 'view',
395 array('id' => $entry->getId()),
396 UrlGeneratorInterface::ABSOLUTE_URL
397 );
398
1d147791
NL
399 $em = $this->getDoctrine()->getManager();
400 $em->remove($entry);
401 $em->flush();
163eae0b
NL
402
403 $this->get('session')->getFlashBag()->add(
404 'notice',
4204a06b 405 'flashes.entry.notice.entry_deleted'
163eae0b 406 );
bd9f0815 407
2863bf2a 408 // don't redirect user to the deleted entry
e82160e5 409 return $this->redirect($url !== $request->headers->get('referer') ? $request->headers->get('referer') : $this->generateUrl('homepage'));
bd9f0815 410 }
3d2b2d62
J
411
412 /**
4346a860 413 * Check if the logged user can manage the given entry.
3d2b2d62
J
414 *
415 * @param Entry $entry
416 */
417 private function checkUserAction(Entry $entry)
418 {
419 if ($this->getUser()->getId() != $entry->getUser()->getId()) {
82d6d9cb 420 throw $this->createAccessDeniedException('You can not access this entry.');
3d2b2d62
J
421 }
422 }
9d50517c 423}