aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Wallabag/CoreBundle/Controller/ShareController.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/Wallabag/CoreBundle/Controller/ShareController.php')
-rw-r--r--src/Wallabag/CoreBundle/Controller/ShareController.php165
1 files changed, 165 insertions, 0 deletions
diff --git a/src/Wallabag/CoreBundle/Controller/ShareController.php b/src/Wallabag/CoreBundle/Controller/ShareController.php
new file mode 100644
index 00000000..d6f83ebc
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Controller/ShareController.php
@@ -0,0 +1,165 @@
1<?php
2
3namespace Wallabag\CoreBundle\Controller;
4
5use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
6use Symfony\Bundle\FrameworkBundle\Controller\Controller;
7use Symfony\Component\HttpFoundation\RedirectResponse;
8use Symfony\Component\Security\Core\Exception\AccessDeniedException;
9use Symfony\Component\Security\Core\Exception\InvalidArgumentException;
10use Wallabag\CoreBundle\Entity\Entry;
11use Wallabag\CoreBundle\Entity\Notification;
12use Wallabag\CoreBundle\Entity\Share;
13use Wallabag\CoreBundle\Event\Activity\Actions\Entry\EntrySavedEvent;
14use Wallabag\CoreBundle\Event\Activity\Actions\Share\ShareAcceptedEvent;
15use Wallabag\CoreBundle\Event\Activity\Actions\Share\ShareCancelledEvent;
16use Wallabag\CoreBundle\Event\Activity\Actions\Share\ShareCreatedEvent;
17use Wallabag\CoreBundle\Event\Activity\Actions\Share\ShareDeniedEvent;
18use Wallabag\CoreBundle\Notifications\NoAction;
19use Wallabag\CoreBundle\Notifications\YesAction;
20use Wallabag\UserBundle\Entity\User;
21
22class ShareController extends Controller
23{
24 /**
25 * @Route("/share-user/{entry}/{destination}", name="share-entry-user", requirements={"entry" = "\d+", "destination" = "\d+"})
26 * @param Entry $entry
27 * @param User $destination
28 * @throws AccessDeniedException
29 * @throws InvalidArgumentException
30 */
31 public function shareEntryAction(Entry $entry, User $destination)
32 {
33
34 if ($entry->getUser() !== $this->getUser()) {
35 throw new AccessDeniedException("You can't share this entry");
36 }
37
38 if ($destination === $this->getUser()) {
39 throw new InvalidArgumentException("You can't share entries to yourself");
40 }
41
42 $share = new Share();
43 $share->setUserOrigin($this->getUser())
44 ->setEntry($entry)
45 ->setUserDestination($destination);
46
47 $em = $this->getDoctrine()->getManager();
48 $em->persist($share);
49 $em->flush();
50
51 $this->get('event_dispatcher')->dispatch(ShareCreatedEvent::NAME, new ShareCancelledEvent($share));
52
53 $accept = new YesAction($this->generateUrl('share-entry-user-accept', ['share' => $share->getId()]));
54
55 $deny = new NoAction($this->generateUrl('share-entry-user-refuse', ['share' => $share->getId()]));
56
57 $notification = new Notification($destination);
58 $notification->setType(Notification::TYPE_SHARE)
59 ->setTitle($this->get('translator')->trans('share.notification.new.title'))
60 ->addAction($accept)
61 ->addAction($deny);
62
63 $em->persist($notification);
64 $em->flush();
65
66 $this->redirectToRoute('view', ['id' => $entry->getId()]);
67 }
68
69 /**
70 * @Route("/share-user/accept/{share}", name="share-entry-user-accept")
71 *
72 * @param Share $share
73 * @return RedirectResponse
74 * @throws AccessDeniedException
75 */
76 public function acceptShareAction(Share $share)
77 {
78 if ($share->getUserDestination() !== $this->getUser()) {
79 throw new AccessDeniedException("You can't accept this entry");
80 }
81
82 $entry = new Entry($this->getUser());
83 $entry->setUrl($share->getEntry()->getUrl());
84
85 $em = $this->getDoctrine()->getManager();
86
87 if (false === $this->checkIfEntryAlreadyExists($entry)) {
88 $this->updateEntry($entry);
89
90 $em->persist($entry);
91 $em->flush();
92
93 $this->get('event_dispatcher')->dispatch(ShareAcceptedEvent::NAME, new ShareAcceptedEvent($share));
94
95 // entry saved, dispatch event about it!
96 $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
97 }
98
99 $em->remove($share);
100 $em->flush(); // we keep the previous flush above in case the event dispatcher would lead in using the saved entry
101
102 return $this->redirect($this->generateUrl('homepage'));
103 }
104
105 /**
106 * @Route("/share-user/refuse/{share}", name="share-entry-user-refuse")
107 *
108 * @param Share $share
109 * @return RedirectResponse
110 */
111 public function refuseShareAction(Share $share)
112 {
113 $em = $this->getDoctrine()->getManager();
114 $em->remove($share);
115 $em->flush();
116
117 $this->get('event_dispatcher')->dispatch(ShareDeniedEvent::NAME, new ShareDeniedEvent($share));
118
119 return $this->redirect($this->generateUrl('homepage'));
120 }
121
122 /**
123 * Fetch content and update entry.
124 * In case it fails, entry will return to avod loosing the data.
125 *
126 * @param Entry $entry
127 * @param string $prefixMessage Should be the translation key: entry_saved or entry_reloaded
128 *
129 * @return Entry
130 */
131 private function updateEntry(Entry $entry, $prefixMessage = 'entry_saved')
132 {
133 // put default title in case of fetching content failed
134 $entry->setTitle('No title found');
135
136 $message = 'flashes.entry.notice.'.$prefixMessage;
137
138 try {
139 $entry = $this->get('wallabag_core.content_proxy')->updateEntry($entry, $entry->getUrl());
140 } catch (\Exception $e) {
141 $this->get('logger')->error('Error while saving an entry', [
142 'exception' => $e,
143 'entry' => $entry,
144 ]);
145
146 $message = 'flashes.entry.notice.'.$prefixMessage.'_failed';
147 }
148
149 $this->get('session')->getFlashBag()->add('notice', $message);
150
151 return $entry;
152 }
153
154 /**
155 * Check for existing entry, if it exists, redirect to it with a message.
156 *
157 * @param Entry $entry
158 *
159 * @return Entry|bool
160 */
161 private function checkIfEntryAlreadyExists(Entry $entry)
162 {
163 return $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($entry->getUrl(), $this->getUser()->getId());
164 }
165}