From 5bf1b9d8bd3acf5d38549f935945e1425b9c07fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 30 Dec 2021 02:10:35 +0100 Subject: [PATCH] send system notification on period confirmation --- .../ChillMainBundle/Entity/Notification.php | 26 ++++++- .../Notification/NotificationPresence.php | 15 +++- .../Templating/NotificationTwigExtension.php | 9 +++ .../NotificationTwigExtensionRuntime.php | 10 ++- .../Repository/NotificationRepository.php | 28 +++---- ...extension_list_notifications_for.html.twig | 6 +- .../migrations/Version20211230003532.php | 38 +++++++++ .../Workflow/WorkflowEventSubscriber.php | 77 +++++++++++++++++++ .../accompanying_course_designation.md.twig | 12 +++ .../Workflow/WorkflowEventSubscriberTest.php | 22 ++++++ .../config/services/accompanyingPeriod.yaml | 6 ++ .../translations/messages.fr.yml | 7 ++ 12 files changed, 233 insertions(+), 23 deletions(-) create mode 100644 src/Bundle/ChillMainBundle/migrations/Version20211230003532.php create mode 100644 src/Bundle/ChillPersonBundle/AccompanyingPeriod/Workflow/WorkflowEventSubscriber.php create mode 100644 src/Bundle/ChillPersonBundle/Resources/views/Notification/accompanying_course_designation.md.twig create mode 100644 src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/Workflow/WorkflowEventSubscriberTest.php diff --git a/src/Bundle/ChillMainBundle/Entity/Notification.php b/src/Bundle/ChillMainBundle/Entity/Notification.php index bf7aac4b3..e566a8d78 100644 --- a/src/Bundle/ChillMainBundle/Entity/Notification.php +++ b/src/Bundle/ChillMainBundle/Entity/Notification.php @@ -74,9 +74,14 @@ class Notification implements TrackUpdateInterface /** * @ORM\ManyToOne(targetEntity=User::class) - * @ORM\JoinColumn(nullable=false) + * @ORM\JoinColumn(nullable=true) */ - private User $sender; + private ?User $sender = null; + + /** + * @ORM\Column(type="text", options={"default": ""}) + */ + private string $title = ''; /** * @ORM\ManyToMany(targetEntity=User::class) @@ -179,6 +184,11 @@ class Notification implements TrackUpdateInterface return $this->sender; } + public function getTitle(): string + { + return $this->title; + } + public function getUnreadBy(): Collection { return $this->unreadBy; @@ -199,6 +209,11 @@ class Notification implements TrackUpdateInterface return !$this->unreadBy->contains($user); } + public function isSystem(): bool + { + return null === $this->sender; + } + public function markAsReadBy(User $user): self { return $this->removeUnreadBy($user); @@ -299,6 +314,13 @@ class Notification implements TrackUpdateInterface return $this; } + public function setTitle(string $title): Notification + { + $this->title = $title; + + return $this; + } + public function setUpdatedAt(DateTimeInterface $datetime): self { $this->updatedAt = $datetime; diff --git a/src/Bundle/ChillMainBundle/Notification/NotificationPresence.php b/src/Bundle/ChillMainBundle/Notification/NotificationPresence.php index e003a5afc..afb6eba19 100644 --- a/src/Bundle/ChillMainBundle/Notification/NotificationPresence.php +++ b/src/Bundle/ChillMainBundle/Notification/NotificationPresence.php @@ -1,5 +1,14 @@ security = $security; diff --git a/src/Bundle/ChillMainBundle/Notification/Templating/NotificationTwigExtension.php b/src/Bundle/ChillMainBundle/Notification/Templating/NotificationTwigExtension.php index 529da2bc1..115adf06b 100644 --- a/src/Bundle/ChillMainBundle/Notification/Templating/NotificationTwigExtension.php +++ b/src/Bundle/ChillMainBundle/Notification/Templating/NotificationTwigExtension.php @@ -1,5 +1,14 @@ $notifications, ]); } - } diff --git a/src/Bundle/ChillMainBundle/Repository/NotificationRepository.php b/src/Bundle/ChillMainBundle/Repository/NotificationRepository.php index 755b5f2dd..68c6b8be6 100644 --- a/src/Bundle/ChillMainBundle/Repository/NotificationRepository.php +++ b/src/Bundle/ChillMainBundle/Repository/NotificationRepository.php @@ -134,9 +134,17 @@ final class NotificationRepository implements ObjectRepository } /** - * @param string $relatedEntityClass - * @param int $relatedEntityId - * @param User $user + * @param mixed|null $limit + * @param mixed|null $offset + * + * @return Notification[] + */ + public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array + { + return $this->repository->findBy($criteria, $orderBy, $limit, $offset); + } + + /** * @return array|Notification[] */ public function findNotificationAsAddresseeByRelatedEntityAndUser(string $relatedEntityClass, int $relatedEntityId, User $user): array @@ -150,23 +158,11 @@ final class NotificationRepository implements ObjectRepository ->andWhere($qb->expr()->isMemberOf(':user', 'n.addressees')) ->setParameter('relatedEntityClass', $relatedEntityClass) ->setParameter('relatedEntityId', $relatedEntityId) - ->setParameter('user', $user) - ; + ->setParameter('user', $user); return $qb->getQuery()->getResult(); } - /** - * @param mixed|null $limit - * @param mixed|null $offset - * - * @return Notification[] - */ - public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array - { - return $this->repository->findBy($criteria, $orderBy, $limit, $offset); - } - public function findOneBy(array $criteria, ?array $orderBy = null): ?Notification { return $this->repository->findOneBy($criteria, $orderBy); diff --git a/src/Bundle/ChillMainBundle/Resources/views/Notification/extension_list_notifications_for.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Notification/extension_list_notifications_for.html.twig index db6aa5d13..5e5d1dba8 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Notification/extension_list_notifications_for.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Notification/extension_list_notifications_for.html.twig @@ -1,7 +1,11 @@
{% for notification in notifications %}
-
{{ 'notification.you were notified by %sender%'|trans({'%sender%': notification.sender|chill_entity_render_string }) }}
+ {% if not notification.isSystem %} +
{{ 'notification.you were notified by %sender%'|trans({'%sender%': notification.sender|chill_entity_render_string }) }}
+ {% else %} +
{{ 'notification.you were notified by system'|trans }}
+ {% endif %}
  • diff --git a/src/Bundle/ChillMainBundle/migrations/Version20211230003532.php b/src/Bundle/ChillMainBundle/migrations/Version20211230003532.php new file mode 100644 index 000000000..20d75749c --- /dev/null +++ b/src/Bundle/ChillMainBundle/migrations/Version20211230003532.php @@ -0,0 +1,38 @@ +addSql('ALTER TABLE chill_main_notification DROP title'); + $this->addSql('ALTER TABLE chill_main_notification ALTER sender_id SET NOT NULL'); + $this->addSql('ALTER TABLE chill_main_notification ALTER updatedAt DROP NOT NULL'); + } + + public function getDescription(): string + { + return 'Add title and allow system notification (sender is null)'; + } + + public function up(Schema $schema): void + { + $this->addSql('ALTER TABLE chill_main_notification ADD title TEXT DEFAULT \'\' NOT NULL'); + $this->addSql('ALTER TABLE chill_main_notification ALTER sender_id DROP NOT NULL'); + $this->addSql('UPDATE chill_main_notification set updatedat="date"'); + $this->addSql('ALTER TABLE chill_main_notification ALTER updatedat SET NOT NULL'); + } +} diff --git a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Workflow/WorkflowEventSubscriber.php b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Workflow/WorkflowEventSubscriber.php new file mode 100644 index 000000000..d49cc8c0a --- /dev/null +++ b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Workflow/WorkflowEventSubscriber.php @@ -0,0 +1,77 @@ +security = $security; + $this->translator = $translator; + $this->engine = $engine; + $this->em = $em; + } + + public static function getSubscribedEvents() + { + return [ + 'workflow.accompanying_period_lifecycle.entered' => [ + 'onStateEntered', + ], + ]; + } + + public function onStateEntered(EnteredEvent $enteredEvent): void + { + if ($enteredEvent->getMarking()->has(AccompanyingPeriod::STEP_CONFIRMED)) { + $this->onPeriodConfirmed($enteredEvent->getSubject()); + } + } + + private function onPeriodConfirmed(AccompanyingPeriod $period) + { + if ($period->getUser() instanceof User + && $period->getUser() !== $this->security->getUser()) { + $notification = new Notification(); + $notification + ->setRelatedEntityId($period->getId()) + ->setRelatedEntityClass(AccompanyingPeriod::class) + ->setTitle($this->translator->trans('period_notification.period designated_subject')) + ->setMessage($this->engine->render( + '@ChillPerson/Notification/accompanying_course_designation.md.twig', + [ + 'accompanyingCourse' => $period, + ] + )) + ->addAddressee($period->getUser()); + $this->em->persist($notification); + } + } +} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Notification/accompanying_course_designation.md.twig b/src/Bundle/ChillPersonBundle/Resources/views/Notification/accompanying_course_designation.md.twig new file mode 100644 index 000000000..515f57b0c --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/Notification/accompanying_course_designation.md.twig @@ -0,0 +1,12 @@ +{{ 'period_notification.You are designated to a new period.'|trans }} + +{{ 'period_notification.See it online'|trans }}: {{ path('chill_person_accompanying_course_index', {'accompanying_period_id': accompanyingCourse.id}, true) }} + +{{ 'period_notification.Persons are'|trans }}: + +{% for p in accompanyingCourse.getCurrentParticipations %} +* {{ p.person|chill_entity_render_string }} +{% endfor %} + +{{ 'period_notification.Social issues are'|trans }}: {% for s in accompanyingCourse.socialIssues %}{{ s|chill_entity_render_string }}{% if not loop.last %}, {% endif %}{% endfor %}. + diff --git a/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/Workflow/WorkflowEventSubscriberTest.php b/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/Workflow/WorkflowEventSubscriberTest.php new file mode 100644 index 000000000..8867872d3 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/Workflow/WorkflowEventSubscriberTest.php @@ -0,0 +1,22 @@ +