From 7f699602655aaa9d90bbf5a76cf33f84837d444b Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Mon, 15 May 2017 11:12:33 +0200 Subject: start work on user-shares Signed-off-by: Thomas Citharel --- .../CoreBundle/Controller/ShareController.php | 156 +++++++++++++++++++++ src/Wallabag/CoreBundle/Entity/Notification.php | 1 + src/Wallabag/CoreBundle/Entity/Share.php | 139 ++++++++++++++++++ 3 files changed, 296 insertions(+) create mode 100644 src/Wallabag/CoreBundle/Controller/ShareController.php create mode 100644 src/Wallabag/CoreBundle/Entity/Share.php diff --git a/src/Wallabag/CoreBundle/Controller/ShareController.php b/src/Wallabag/CoreBundle/Controller/ShareController.php new file mode 100644 index 00000000..bd1246c7 --- /dev/null +++ b/src/Wallabag/CoreBundle/Controller/ShareController.php @@ -0,0 +1,156 @@ +getUser() !== $this->getUser()) { + throw new AccessDeniedException("You can't share this entry"); + } + + if ($destination === $this->getUser()) { + throw new InvalidArgumentException("You can't share entries to yourself"); + } + + $share = new Share(); + $share->setUserOrigin($this->getUser()) + ->setEntry($entry) + ->setUserDestination($destination); + + $em = $this->getDoctrine()->getManager(); + $em->persist($share); + $em->flush(); + + $accept = new YesAction($this->generateUrl('share-entry-user-accept', ['share' => $share->getId()])); + + $deny = new NoAction($this->generateUrl('share-entry-user-refuse', ['share' => $share->getId()])); + + $notification = new Notification($destination); + $notification->setType(Notification::TYPE_SHARE) + ->setTitle($this->get('translator')->trans('share.notification.new.title')) + ->addAction($accept) + ->addAction($deny); + + $em->persist($notification); + $em->flush(); + + $this->redirectToRoute('view', ['id' => $entry->getId()]); + } + + /** + * @Route("/share-user/accept/{share}", name="share-entry-user-accept") + * + * @param Share $share + * @return RedirectResponse + * @throws AccessDeniedException + */ + public function acceptShareAction(Share $share) + { + if ($share->getUserDestination() !== $this->getUser()) { + throw new AccessDeniedException("You can't accept this entry"); + } + + $entry = new Entry($this->getUser()); + $entry->setUrl($share->getEntry()->getUrl()); + + $em = $this->getDoctrine()->getManager(); + + if (false === $this->checkIfEntryAlreadyExists($entry)) { + $this->updateEntry($entry); + + $em->persist($entry); + $em->flush(); + + // entry saved, dispatch event about it! + $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); + } + + $em->remove($share); + $em->flush(); // we keep the previous flush above in case the event dispatcher would lead in using the saved entry + + return $this->redirect($this->generateUrl('homepage')); + } + + /** + * @Route("/share-user/refuse/{share}", name="share-entry-user-refuse") + * + * @param Share $share + * @return RedirectResponse + */ + public function refuseShareAction(Share $share) + { + $em = $this->getDoctrine()->getManager(); + $em->remove($share); + $em->flush(); + + return $this->redirect($this->generateUrl('homepage')); + } + + /** + * Fetch content and update entry. + * In case it fails, entry will return to avod loosing the data. + * + * @param Entry $entry + * @param string $prefixMessage Should be the translation key: entry_saved or entry_reloaded + * + * @return Entry + */ + private function updateEntry(Entry $entry, $prefixMessage = 'entry_saved') + { + // put default title in case of fetching content failed + $entry->setTitle('No title found'); + + $message = 'flashes.entry.notice.'.$prefixMessage; + + try { + $entry = $this->get('wallabag_core.content_proxy')->updateEntry($entry, $entry->getUrl()); + } catch (\Exception $e) { + $this->get('logger')->error('Error while saving an entry', [ + 'exception' => $e, + 'entry' => $entry, + ]); + + $message = 'flashes.entry.notice.'.$prefixMessage.'_failed'; + } + + $this->get('session')->getFlashBag()->add('notice', $message); + + return $entry; + } + + /** + * Check for existing entry, if it exists, redirect to it with a message. + * + * @param Entry $entry + * + * @return Entry|bool + */ + private function checkIfEntryAlreadyExists(Entry $entry) + { + return $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($entry->getUrl(), $this->getUser()->getId()); + } +} diff --git a/src/Wallabag/CoreBundle/Entity/Notification.php b/src/Wallabag/CoreBundle/Entity/Notification.php index e1c1b449..26e39800 100644 --- a/src/Wallabag/CoreBundle/Entity/Notification.php +++ b/src/Wallabag/CoreBundle/Entity/Notification.php @@ -77,6 +77,7 @@ class Notification implements NotificationInterface { const TYPE_ADMIN = 0; const TYPE_USER = 1; const TYPE_RELEASE = 2; + const TYPE_SHARE = 3; public function __construct(User $user = null) { diff --git a/src/Wallabag/CoreBundle/Entity/Share.php b/src/Wallabag/CoreBundle/Entity/Share.php new file mode 100644 index 00000000..d1db5eb0 --- /dev/null +++ b/src/Wallabag/CoreBundle/Entity/Share.php @@ -0,0 +1,139 @@ +accepted = false; + } + + /** + * @return int + */ + public function getId() + { + return $this->id; + } + + /** + * @return User + */ + public function getUserOrigin() + { + return $this->userOrigin; + } + + /** + * @param User $userOrigin + * @return Share + */ + public function setUserOrigin(User $userOrigin) + { + $this->userOrigin = $userOrigin; + return $this; + } + + /** + * @return User + */ + public function getUserDestination() + { + return $this->userDestination; + } + + /** + * @param User $userDestination + * @return Share + */ + public function setUserDestination(User $userDestination) + { + $this->userDestination = $userDestination; + return $this; + } + + /** + * @return bool + */ + public function isAccepted() + { + return $this->accepted; + } + + /** + * @param bool $accepted + * @return Share + */ + public function setAccepted($accepted) + { + $this->accepted = $accepted; + return $this; + } + + /** + * @return Entry + */ + public function getEntry() + { + return $this->entry; + } + + /** + * @param Entry $entry + * @return Share + */ + public function setEntry(Entry $entry) + { + $this->entry = $entry; + return $this; + } +} -- cgit v1.2.3