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