src/Aqarmap/Bundle/NotificationBundle/NotificationSubscriber.php line 55

  1. <?php
  2. namespace Aqarmap\Bundle\NotificationBundle;
  3. use Doctrine\ORM\EntityManagerInterface;
  4. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  5. use Symfony\Contracts\Translation\TranslatorInterface;
  6. use Twig\Environment;
  7. class NotificationSubscriber implements EventSubscriberInterface
  8. {
  9. /**
  10. * [$action description].
  11. */
  12. public string $action;
  13. /**
  14. * Create a notification subscriber instance.
  15. */
  16. public function __construct(public NotificationManager $manager, private readonly Environment $templating, private readonly TranslatorInterface $translator, private readonly EntityManagerInterface $entityManager)
  17. {
  18. }
  19. /**
  20. * Register the listeners for the subscriber.
  21. */
  22. public static function getSubScribedEvents(): array
  23. {
  24. $path = __DIR__.'/Types';
  25. $events = [];
  26. $AllFileIterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path));
  27. $PhpFileIterator = new \RegexIterator($AllFileIterator, '/^.+\.php$/i', \RecursiveRegexIterator::GET_MATCH);
  28. foreach ($PhpFileIterator as $file => $object) {
  29. $file = pathinfo((string) $file);
  30. $event = strtolower((string) preg_replace('~(?<=\\w)([A-Z])~', '.$1', $file['filename']));
  31. $events[$event] = 'handle';
  32. }
  33. return $events;
  34. }
  35. /**
  36. * Handel notification.
  37. *
  38. * @throws \ReflectionException
  39. */
  40. public function handle(NotificationInterface $notification): void
  41. {
  42. $notification
  43. ->manager($this->manager)
  44. ->twig($this->templating)
  45. ->translator($this->translator);
  46. // force sending a particular channel
  47. if ($notification->isForce) {
  48. $notificationHandler = $this->manager->getHandler($notification);
  49. if (
  50. !($notification->forceSend ?? false)
  51. && $notificationHandler
  52. && method_exists($notification, $notificationHandler)
  53. ) {
  54. $notification->$notificationHandler();
  55. return;
  56. }
  57. $this->send($notification, $notification->channel);
  58. return;
  59. }
  60. if ($notification->getChannel()) {
  61. $this->hasChannel($notification, $notification->getChannel())
  62. ? $this->queue($notification, $notification->getChannel())
  63. : $this->send($notification, $notification->getChannel());
  64. return;
  65. }
  66. foreach ($this->manager->getChannel($notification) as $channel) {
  67. $this->hasChannel($notification, $channel)
  68. ? $this->queue($notification, $channel)
  69. : $this->send($notification, $channel);
  70. }
  71. }
  72. /**
  73. * Send notification.
  74. *
  75. * @param string $channel
  76. *
  77. * @throws Exceptions\DriverNotFoundException
  78. */
  79. public function send(NotificationInterface $notification, $channel): void
  80. {
  81. $notifiables = $notification->getNotifiables();
  82. if (!\count($notifiables)) {
  83. $notifiables = $notification->getUsers();
  84. }
  85. foreach ($notifiables as $user) {
  86. if (!$user->isEnabled()) {
  87. continue;
  88. }
  89. $user = $notification->to($user);
  90. $this->manager->send($user, $notification, $channel);
  91. }
  92. $this->entityManager->flush();
  93. }
  94. /**
  95. * Queue notification.
  96. *
  97. * @param string $channel
  98. *
  99. * @throws \ReflectionException
  100. */
  101. public function queue(NotificationInterface $notification, $channel): void
  102. {
  103. $message = [
  104. 'event' => strtolower(
  105. (string) preg_replace(
  106. '~(?<=\\w)([A-Z])~',
  107. '.$1',
  108. (new \ReflectionClass($notification))->getShortName()
  109. )
  110. ),
  111. 'class' => (new \ReflectionClass($notification))->getName(),
  112. 'entity' => (new \ReflectionClass($notification->getSubject()))->getName(),
  113. 'id' => $notification->getSubject()->getId(),
  114. 'channel' => $channel,
  115. 'sent_at' => date('d-m-Y \@ h:i A'),
  116. ];
  117. $this->manager->queue(json_encode($message), $notification->getHandoverDetails());
  118. }
  119. /**
  120. * Check that notification has channel.
  121. *
  122. * @throws \ReflectionException
  123. */
  124. public function hasChannel(NotificationInterface $notification, $channel): bool
  125. {
  126. return \in_array($channel, $this->manager->getQueue($notification));
  127. }
  128. }