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