From 11824adda45dbf2bffba618c2cf7fbde0c684fa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Sat, 25 Dec 2021 22:41:25 +0100 Subject: [PATCH] notification: create --- .../ActivityNotificationRenderer.php | 3 +- .../Controller/NotificationController.php | 97 +++++++++++++++++-- .../ChillMainBundle/Entity/Notification.php | 3 +- .../ChillMainBundle/Form/NotificationType.php | 41 ++++++++ .../Exception/NotificationHandlerNotFound.php | 18 ++++ .../NotificationHandlerInterface.php | 16 +++ .../NotificationHandlerManager.php | 26 ++--- .../views/Notification/create.html.twig | 25 +++++ ...AccompanyingPeriodNotificationRenderer.php | 3 +- .../views/AccompanyingCourse/index.html.twig | 4 + 10 files changed, 210 insertions(+), 26 deletions(-) create mode 100644 src/Bundle/ChillMainBundle/Form/NotificationType.php create mode 100644 src/Bundle/ChillMainBundle/Notification/Exception/NotificationHandlerNotFound.php create mode 100644 src/Bundle/ChillMainBundle/Notification/NotificationHandlerInterface.php create mode 100644 src/Bundle/ChillMainBundle/Resources/views/Notification/create.html.twig diff --git a/src/Bundle/ChillActivityBundle/Notification/ActivityNotificationRenderer.php b/src/Bundle/ChillActivityBundle/Notification/ActivityNotificationRenderer.php index f7f19e3f1..2d3d333d9 100644 --- a/src/Bundle/ChillActivityBundle/Notification/ActivityNotificationRenderer.php +++ b/src/Bundle/ChillActivityBundle/Notification/ActivityNotificationRenderer.php @@ -13,8 +13,9 @@ namespace Chill\ActivityBundle\Notification; use Chill\ActivityBundle\Entity\Activity; use Chill\MainBundle\Entity\Notification; +use Chill\MainBundle\Notification\NotificationHandlerInterface; -final class ActivityNotificationRenderer +final class ActivityNotificationRenderer implements NotificationHandlerInterface { public function getTemplate() { diff --git a/src/Bundle/ChillMainBundle/Controller/NotificationController.php b/src/Bundle/ChillMainBundle/Controller/NotificationController.php index 8ce15e6a4..19d5142ca 100644 --- a/src/Bundle/ChillMainBundle/Controller/NotificationController.php +++ b/src/Bundle/ChillMainBundle/Controller/NotificationController.php @@ -11,41 +11,118 @@ declare(strict_types=1); namespace Chill\MainBundle\Controller; -use Chill\MainBundle\Notification\NotificationRenderer; +use Chill\MainBundle\Entity\Notification; +use Chill\MainBundle\Entity\User; +use Chill\MainBundle\Form\NotificationType; +use Chill\MainBundle\Notification\Exception\NotificationHandlerNotFound; +use Chill\MainBundle\Notification\NotificationHandlerManager; use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Repository\NotificationRepository; +use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Security; +use Symfony\Contracts\Translation\TranslatorInterface; /** * @Route("/{_locale}/notification") */ class NotificationController extends AbstractController { - private Security $security; + private EntityManagerInterface $em; + + private NotificationHandlerManager $notificationHandlerManager; + private NotificationRepository $notificationRepository; - private NotificationRenderer $notificationRenderer; + private PaginatorFactory $paginatorFactory; + private Security $security; + + private TranslatorInterface $translator; + public function __construct( + EntityManagerInterface $em, Security $security, NotificationRepository $notificationRepository, - NotificationRenderer $notificationRenderer, - PaginatorFactory $paginatorFactory + NotificationHandlerManager $notificationHandlerManager, + PaginatorFactory $paginatorFactory, + TranslatorInterface $translator ) { + $this->em = $em; $this->security = $security; $this->notificationRepository = $notificationRepository; - $this->notificationRenderer = $notificationRenderer; + $this->notificationHandlerManager = $notificationHandlerManager; $this->paginatorFactory = $paginatorFactory; + $this->translator = $translator; } /** - * @Route("/show", name="chill_main_notification_show") + * @Route("/create", name="chill_main_notification_create") */ - public function showAction(): Response + public function createAction(Request $request): Response { + $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); + + if (!$this->security->getUser() instanceof User) { + throw new AccessDeniedHttpException('You must be authenticated and a user to create a notification'); + } + + if (!$request->query->has('entityClass')) { + throw new BadRequestHttpException('Missing entityClass parameter'); + } + + if (!$request->query->has('entityId')) { + throw new BadRequestHttpException('missing entityId parameter'); + } + + $notification = new Notification(); + $notification + ->setRelatedEntityClass($request->query->get('entityClass')) + ->setRelatedEntityId($request->query->getInt('entityId')) + ->setSender($this->security->getUser()); + + try { + $handler = $this->notificationHandlerManager->getHandler($notification); + } catch (NotificationHandlerNotFound $e) { + throw new BadRequestHttpException('no handler for this notification'); + } + + $form = $this->createForm(NotificationType::class, $notification); + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $this->em->persist($notification); + $this->em->flush(); + + $this->addFlash('success', $this->translator->trans('notification.Notification created')); + + if ($request->query->has('returnPath')) { + return new RedirectResponse($request->query->get('returnPath')); + } + + return $this->redirectToRoute('chill_main_homepage'); + } + + return $this->render('@ChillMain/Notification/create.html.twig', [ + 'form' => $form->createView(), + 'handler' => $handler, + 'notification' => $notification, + ]); + } + + /** + * @Route("/my", name="chill_main_notification_my") + */ + public function myAction(): Response + { + $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); $currentUser = $this->security->getUser(); $notificationsNbr = $this->notificationRepository->countAllForAttendee(($currentUser)); @@ -61,8 +138,8 @@ class NotificationController extends AbstractController foreach ($notifications as $notification) { $data = [ - 'template' => $this->notificationRenderer->getTemplate($notification), - 'template_data' => $this->notificationRenderer->getTemplateData($notification), + 'template' => $this->notificationHandlerManager->getTemplate($notification), + 'template_data' => $this->notificationHandlerManager->getTemplateData($notification), 'notification' => $notification, ]; $templateData[] = $data; diff --git a/src/Bundle/ChillMainBundle/Entity/Notification.php b/src/Bundle/ChillMainBundle/Entity/Notification.php index bfcdf1ee6..a9b576f1f 100644 --- a/src/Bundle/ChillMainBundle/Entity/Notification.php +++ b/src/Bundle/ChillMainBundle/Entity/Notification.php @@ -53,7 +53,7 @@ class Notification /** * @ORM\Column(type="json") */ - private array $read; + private array $read = []; /** * @ORM\Column(type="string", length=255) @@ -74,6 +74,7 @@ class Notification public function __construct() { $this->addressees = new ArrayCollection(); + $this->setDate(new DateTimeImmutable()); } public function addAddressee(User $addressee): self diff --git a/src/Bundle/ChillMainBundle/Form/NotificationType.php b/src/Bundle/ChillMainBundle/Form/NotificationType.php new file mode 100644 index 000000000..af884dfbb --- /dev/null +++ b/src/Bundle/ChillMainBundle/Form/NotificationType.php @@ -0,0 +1,41 @@ +add('addressees', EntityType::class, [ + 'class' => User::class, + 'choice_label' => 'label', + 'multiple' => true, + ]) + ->add('message', ChillTextareaType::class, [ + 'required' => false, + ]); + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefault('class', Notification::class); + } +} diff --git a/src/Bundle/ChillMainBundle/Notification/Exception/NotificationHandlerNotFound.php b/src/Bundle/ChillMainBundle/Notification/Exception/NotificationHandlerNotFound.php new file mode 100644 index 000000000..00add5f4f --- /dev/null +++ b/src/Bundle/ChillMainBundle/Notification/Exception/NotificationHandlerNotFound.php @@ -0,0 +1,18 @@ +renderers[] = $activityNotificationRenderer; } - public function getTemplate(Notification $notification) - { - return $this->getRenderer($notification)->getTemplate(); - } - - public function getTemplateData(Notification $notification) - { - return $this->getRenderer($notification)->getTemplateData($notification); - } - - private function getRenderer(Notification $notification) + public function getHandler(Notification $notification): NotificationHandlerInterface { foreach ($this->renderers as $renderer) { if ($renderer->supports($notification)) { @@ -49,6 +39,16 @@ final class NotificationHandlerManager } } - throw new Exception('No renderer for ' . $notification); + throw new NotificationHandlerNotFound(); + } + + public function getTemplate(Notification $notification) + { + return $this->getHandler($notification)->getTemplate(); + } + + public function getTemplateData(Notification $notification) + { + return $this->getHandler($notification)->getTemplateData($notification); } } diff --git a/src/Bundle/ChillMainBundle/Resources/views/Notification/create.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Notification/create.html.twig new file mode 100644 index 000000000..a6a52acf7 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Resources/views/Notification/create.html.twig @@ -0,0 +1,25 @@ +{% extends "@ChillMain/layout.html.twig" %} + +{% block content %} +
+
+ {% include handler.template(notification) with handler.templateData(notification) %} + + {{ form_start(form, { 'attr': { 'id': 'notification' }}) }} + + {{ form_row(form.addressees) }} + {{ form_row(form.message) }} + + {{ form_end(form) }} + + +
+
+{% endblock %} diff --git a/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodNotificationRenderer.php b/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodNotificationRenderer.php index c67c3d8a8..934f3f1c0 100644 --- a/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodNotificationRenderer.php +++ b/src/Bundle/ChillPersonBundle/Notification/AccompanyingPeriodNotificationRenderer.php @@ -12,9 +12,10 @@ declare(strict_types=1); namespace Chill\PersonBundle\Notification; use Chill\MainBundle\Entity\Notification; +use Chill\MainBundle\Notification\NotificationHandlerInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; -final class AccompanyingPeriodNotificationRenderer +final class AccompanyingPeriodNotificationRenderer implements NotificationHandlerInterface { public function getTemplate() { diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/index.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/index.html.twig index 39e924d18..2ced8f611 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/index.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/index.html.twig @@ -108,6 +108,10 @@ {% endif %} +
+ {{ 'notification.Notify'|trans }} +
+ {% if accompanyingCourse.requestorPerson is not null or accompanyingCourse.requestorThirdParty is not null %}
{% if accompanyingCourse.requestorPerson is not null %}