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