src/Domain/Notification/Subscriber/NotificationEventSubscriber.php line 68

Open in your IDE?
  1. <?php
  2. namespace App\Domain\Notification\Subscriber;
  3. use App\Application\Interfaces\CollectivityRelated;
  4. use App\Domain\Notification\Dictionary\NotificationModuleDictionary;
  5. use App\Domain\Notification\Event\ConformiteTraitementNeedsAIPDEvent;
  6. use App\Domain\Notification\Event\LateActionEvent;
  7. use App\Domain\Notification\Event\LateRequestEvent;
  8. use App\Domain\Notification\Event\LateSurveyEvent;
  9. use App\Domain\Notification\Event\NoLoginEvent;
  10. use App\Domain\Notification\Model\Notification;
  11. use App\Domain\Notification\Model\NotificationUser;
  12. use App\Domain\Notification\Serializer\NotificationNormalizer;
  13. use App\Domain\Registry\Model\ConformiteTraitement\ConformiteTraitement;
  14. use App\Domain\User\Dictionary\UserMoreInfoDictionary;
  15. use App\Domain\User\Model\Collectivity;
  16. use App\Domain\User\Model\User;
  17. use App\Domain\User\Repository\User as UserRepository;
  18. use App\Infrastructure\ORM\Notification\Repository\Notification as NotificationRepository;
  19. use App\Infrastructure\ORM\Notification\Repository\NotificationUser as NotificationUserRepository;
  20. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  21. use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
  22. use Symfony\Contracts\Translation\TranslatorInterface;
  23. /**
  24.  * This event subscriber creates notification for things that are trigerred by a cron job.
  25.  */
  26. class NotificationEventSubscriber implements EventSubscriberInterface
  27. {
  28.     protected NotificationRepository $notificationRepository;
  29.     protected NotificationUserRepository $notificationUserRepository;
  30.     protected NotificationNormalizer $normalizer;
  31.     protected UserRepository $userRepository;
  32.     protected TranslatorInterface $translator;
  33.     protected string $requestDays;
  34.     protected string $surveyDays;
  35.     public function __construct(
  36.         NotificationRepository $notificationRepository,
  37.         NotificationUserRepository $notificationUserRepository,
  38.         NotificationNormalizer $normalizer,
  39.         UserRepository $userRepository,
  40.         TranslatorInterface $translator,
  41.         string $requestDays,
  42.         string $surveyDays,
  43.     ) {
  44.         $this->notificationRepository     $notificationRepository;
  45.         $this->notificationUserRepository $notificationUserRepository;
  46.         $this->normalizer                 $normalizer;
  47.         $this->userRepository             $userRepository;
  48.         $this->translator                 $translator;
  49.         $this->requestDays                $requestDays;
  50.         $this->surveyDays                 $surveyDays;
  51.     }
  52.     public static function getSubscribedEvents()
  53.     {
  54.         return [
  55.             LateActionEvent::class                    => 'onLateAction',
  56.             LateRequestEvent::class                   => 'onLateRequest',
  57.             NoLoginEvent::class                       => 'onNoLogin',
  58.             LateSurveyEvent::class                    => 'onLateSurvey',
  59.             ConformiteTraitementNeedsAIPDEvent::class => 'onNeedsAIPD',
  60.         ];
  61.     }
  62.     public function onNeedsAIPD(ConformiteTraitementNeedsAIPDEvent $event)
  63.     {
  64.         $conformite $event->getConformiteTraitement();
  65.         $collectivity $conformite->getTraitement()->getCollectivity();
  66.         $existing     $this->notificationRepository->findBy([
  67.             'module'       => 'notification.modules.aipd',
  68.             'collectivity' => $collectivity,
  69.             'action'       => 'notifications.actions.treatment_needs_aipd',
  70.             'name'         => $conformite->__toString(),
  71.         ]);
  72.         if ($existing && count($existing)) {
  73.             return;
  74.         }
  75.         $norm  $this->normalizer->normalize($conformitenullself::normalizerOptions());
  76.         $users $this->userRepository->findNonDpoUsersForCollectivity($collectivity);
  77.         $notification = new Notification();
  78.         $notification->setModule('notification.modules.aipd');
  79.         $notification->setCollectivity($collectivity);
  80.         $notification->setAction('notifications.actions.treatment_needs_aipd');
  81.         $notification->setName($conformite->__toString());
  82.         $notification->setObject((object) $norm);
  83.         $notification->setDpo(true);
  84.         $notification->setSubject('');
  85.         // $this->notificationRepository->insert($notification);
  86.         $nus $this->notificationUserRepository->saveUsers($notification$users);
  87.         $notification->setNotificationUsers($nus);
  88.         $this->notificationRepository->insert($notification);
  89.         $this->saveEmailNotificationForDPOs($notification$conformite);
  90.     }
  91.     /**
  92.      * Indice de maturité non réalisé depuis plus de...
  93.      *
  94.      * @throws \Symfony\Component\Serializer\Exception\ExceptionInterface
  95.      */
  96.     public function onLateSurvey(LateSurveyEvent $event)
  97.     {
  98.         $survey   $event->getSurvey();
  99.         $existing $this->notificationRepository->findBy([
  100.             'module'       => 'notification.modules.maturity',
  101.             'collectivity' => $survey->getCollectivity(),
  102.             'action'       => 'notifications.actions.late_survey',
  103.             'name'         => $survey->__toString(),
  104.         ]);
  105.         if ($existing && count($existing)) {
  106.             return;
  107.         }
  108.         $norm $this->normalizer->normalize($surveynullself::normalizerOptions());
  109.         $users $this->userRepository->findNonDpoUsersForCollectivity($survey->getCollectivity());
  110.         $notification = new Notification();
  111.         $notification->setModule('notification.modules.maturity');
  112.         $notification->setCollectivity($survey->getCollectivity());
  113.         $notification->setAction('notifications.actions.late_survey');
  114.         $notification->setName($survey->__toString());
  115.         $notification->setObject((object) $norm);
  116.         $notification->setDpo(true);
  117.         $notification->setSubject($this->translator->trans('notifications.subject.late_survey', ['%days%' => $this->surveyDays]));
  118.         $nus $this->notificationUserRepository->saveUsers($notification$users);
  119.         $notification->setNotificationUsers($nus);
  120.         $this->notificationRepository->insert($notification);
  121.     }
  122.     /**
  123.      * Action planifiée en retard.
  124.      *
  125.      * @throws \Symfony\Component\Serializer\Exception\ExceptionInterface
  126.      */
  127.     public function onLateAction(LateActionEvent $event)
  128.     {
  129.         $action   $event->getMesurement();
  130.         $existing $this->notificationRepository->findBy([
  131.             'module'       => 'notification.modules.' NotificationModuleDictionary::ACTION_PLAN,
  132.             'collectivity' => $action->getCollectivity(),
  133.             'action'       => 'notifications.actions.late_action',
  134.             'name'         => $action->getName(),
  135.         ]);
  136.         if ($existing && count($existing)) {
  137.             return;
  138.         }
  139.         $norm $this->normalizer->normalize($actionnullself::normalizerOptions());
  140.         $users        $this->userRepository->findNonDpoUsersForCollectivity($action->getCollectivity());
  141.         $notification = new Notification();
  142.         $notification->setModule('notification.modules.' NotificationModuleDictionary::ACTION_PLAN);
  143.         $notification->setCollectivity($action->getCollectivity());
  144.         $notification->setAction('notifications.actions.late_action');
  145.         $notification->setName($action->getName());
  146.         $notification->setObject((object) $norm);
  147.         $notification->setDpo(true);
  148.         $ob   $notification->getObject();
  149.         $date \DateTime::createFromFormat(DATE_ATOM$ob->planificationDate)->format('d/m/Y');
  150.         $notification->setSubject($this->translator->trans('notifications.subject.late_action', ['%date%' => $date]));
  151.         $nus $this->notificationUserRepository->saveUsers($notification$users);
  152.         $notification->setNotificationUsers($nus);
  153.         $this->notificationRepository->insert($notification);
  154.         // Send email to référent opérationnel
  155.         $this->saveEmailNotificationForRefOp($notification$action);
  156.     }
  157.     public function onLateRequest(LateRequestEvent $event)
  158.     {
  159.         $request  $event->getRequest();
  160.         $existing $this->notificationRepository->findBy([
  161.             'module'       => 'notification.modules.request',
  162.             'collectivity' => $request->getCollectivity(),
  163.             'action'       => 'notifications.actions.late_request',
  164.             'name'         => $request->__toString(),
  165.         ]);
  166.         if ($existing && count($existing)) {
  167.             return;
  168.         }
  169.         $norm $this->normalizer->normalize($requestnullself::normalizerOptions());
  170.         $users $this->userRepository->findNonDpoUsersForCollectivity($request->getCollectivity());
  171.         $notification = new Notification();
  172.         $notification->setModule('notification.modules.request');
  173.         $notification->setCollectivity($request->getCollectivity());
  174.         $notification->setAction('notifications.actions.late_request');
  175.         $notification->setName($request->__toString());
  176.         $notification->setObject((object) $norm);
  177.         $notification->setDpo(true);
  178.         $notification->setSubject($this->translator->trans('notifications.subject.late_request', ['%days%' => $this->requestDays]));
  179.         $nus $this->notificationUserRepository->saveUsers($notification$users);
  180.         $notification->setNotificationUsers($nus);
  181.         $this->notificationRepository->insert($notification);
  182.         // Send email to référent opérationnel and responsable de traitement
  183.         $this->saveEmailNotificationForRefOp($notification$request);
  184.         $this->saveEmailNotificationForRespTrait($notification$request);
  185.     }
  186.     public function onNoLogin(NoLoginEvent $event)
  187.     {
  188.         // Send email to référent opérationnel
  189.         // Add notification for DPD
  190.         $user     $event->getUser();
  191.         $existing $this->notificationRepository->findBy([
  192.             'module'       => 'notification.modules.user',
  193.             'collectivity' => $user->getCollectivity(),
  194.             'action'       => 'notifications.actions.no_login',
  195.             'name'         => $user->getFullName(),
  196.         ]);
  197.         if (count($existing)) {
  198.             return;
  199.         }
  200.         $notification = new Notification();
  201.         $notification->setModule('notification.modules.user');
  202.         $notification->setCollectivity($user->getCollectivity());
  203.         $notification->setAction('notifications.actions.no_login');
  204.         $notification->setName($user->getFullName());
  205.         // $notification->setCreatedBy($user);
  206.         $notification->setObject((object) $this->normalizer->normalize($usernullself::normalizerOptions()));
  207.         $notification->setDpo(true);
  208.         $notification->setSubject($this->translator->trans('notifications.subject.no_login'));
  209.         $this->notificationRepository->insert($notification);
  210.         $this->saveEmailNotificationForRefOp($notification$user);
  211.         // If no NotificationUser, this means the notification is for all DPOs
  212.         // The emails will be sent with notifications:send command to all users that have a unsent NotificationUser with an email address
  213.     }
  214.     private function saveEmailNotificationForRefOp(Notification $notificationCollectivityRelated $object)
  215.     {
  216.         // Get referent operationnels for this collectivity
  217.         $refs $object->getCollectivity()->getUsers()->filter(function (User $u) {
  218.             $mi $u->getMoreInfos();
  219.             return $mi && isset($mi[UserMoreInfoDictionary::MOREINFO_OPERATIONNAL]) && $mi[UserMoreInfoDictionary::MOREINFO_OPERATIONNAL];
  220.         });
  221.         if (=== $refs->count()) {
  222.             // No ref OP, get from collectivity
  223.             if ($object->getCollectivity() && $object->getCollectivity()->getReferent()) {
  224.                 if ($object->getCollectivity()->getReferent()->getNotification()) {
  225.                     $refs = [$object->getCollectivity()->getReferent()->getMail()];
  226.                 }
  227.             }
  228.         }
  229.         // Add notification with email address for the référents
  230.         $this->saveEmailNotifications($notification$refs);
  231.     }
  232.     private function saveEmailNotificationForRespTrait(Notification $notificationCollectivityRelated $object)
  233.     {
  234.         // Get referent operationnels for this collectivity
  235.         $refs $object->getCollectivity()->getUsers()->filter(function (User $u) {
  236.             $mi $u->getMoreInfos();
  237.             return $mi && isset($mi[UserMoreInfoDictionary::MOREINFO_TREATMENT]) && $mi[UserMoreInfoDictionary::MOREINFO_TREATMENT];
  238.         });
  239.         if (=== $refs->count()) {
  240.             // No ref OP, get from collectivity
  241.             if ($object->getCollectivity() && $object->getCollectivity()->getLegalManager()) {
  242.                 if ($object->getCollectivity()->getLegalManager()->getNotification()) {
  243.                     $refs = [$object->getCollectivity()->getLegalManager()->getMail()];
  244.                 }
  245.             }
  246.         }
  247.         $this->saveEmailNotifications($notification$refs);
  248.     }
  249.     private function saveEmailNotificationForDPOs(Notification $notificationConformiteTraitement $object)
  250.     {
  251.         // TODO envoyer à tous les ADMINS + MOREINFO_DPD
  252.         // Get DPOs
  253.         $t            $object->getTraitement();
  254.         $collectivity $t->getCollectivity();
  255.         $refs         $collectivity->getUsers()->filter(function (User $u) use ($collectivity) {
  256.             $mi $u->getMoreInfos();
  257.             $refColIds = [];
  258.             /** @var Collectivity $col */
  259.             foreach ($u->getCollectivitesReferees() as $col) {
  260.                 $refColIds[] = $col->getId()->toString();
  261.             }
  262.             return in_array('ROLE_ADMIN'$u->getRoles())
  263.                 || (in_array('ROLE_REFERENT'$u->getRoles()) && in_array($collectivity->getId()->toString(), $refColIds))
  264.                 || ($mi && isset($mi[UserMoreInfoDictionary::MOREINFO_DPD]) && $mi[UserMoreInfoDictionary::MOREINFO_DPD]);
  265.         });
  266.         // Also get DPOs from collectivity
  267.         if ($collectivity->getDpo()) {
  268.             if ($collectivity->getDpo()->getNotification()) {
  269.                 $refs[] = $t->getCollectivity()->getDpo()->getMail();
  270.             }
  271.         }
  272.         $this->saveEmailNotifications($notification$refs);
  273.     }
  274.     private function saveEmailNotifications(Notification $notification$refs)
  275.     {
  276.         // Add notification with email address for the référents
  277.         foreach ($refs as $ref) {
  278.             $nu = new NotificationUser();
  279.             if (is_object($ref) && User::class === get_class($ref)) {
  280.                 $nu->setMail($ref->getEmail());
  281.                 $nu->setUser($ref);
  282.             } elseif (method_exists($ref'getEmail')) {
  283.                 $nu->setMail($ref->getEmail());
  284.             } elseif (str_contains((string) $ref'@')) {
  285.                 // Only add it if it contains an '@'
  286.                 $nu->setMail((string) $ref);
  287.             }
  288.             $nu->setToken(sha1($notification->getName() . microtime() . $nu->getMail()));
  289.             $nu->setNotification($notification);
  290.             $nu->setActive(false);
  291.             $nu->setSent(false);
  292.             $this->notificationUserRepository->persist($nu);
  293.         }
  294.     }
  295.     public static function normalizerOptions(): array
  296.     {
  297.         return [
  298.             AbstractObjectNormalizer::ENABLE_MAX_DEPTH           => true,
  299.             AbstractObjectNormalizer::CIRCULAR_REFERENCE_LIMIT   => 1,
  300.             AbstractObjectNormalizer::CIRCULAR_REFERENCE_HANDLER => function ($o) {
  301.                 return NotificationNormalizer::getObjectSimpleValue($o);
  302.             },
  303.             AbstractObjectNormalizer::MAX_DEPTH_HANDLER => function ($o) {
  304.                 if (is_iterable($o)) {
  305.                     $d = [];
  306.                     foreach ($o as $item) {
  307.                         $d[] = NotificationNormalizer::getObjectSimpleValue($item);
  308.                     }
  309.                     return $d;
  310.                 }
  311.                 return NotificationNormalizer::getObjectSimpleValue($o);
  312.             },
  313.         ];
  314.     }
  315. }