Spaces:
No application file
No application file
| namespace Mautic\CampaignBundle\Executioner\Dispatcher; | |
| use Doctrine\Common\Collections\ArrayCollection; | |
| use Mautic\CampaignBundle\CampaignEvents; | |
| use Mautic\CampaignBundle\Entity\Event; | |
| use Mautic\CampaignBundle\Entity\LeadEventLog; | |
| use Mautic\CampaignBundle\Event\ExecutedBatchEvent; | |
| use Mautic\CampaignBundle\Event\ExecutedEvent; | |
| use Mautic\CampaignBundle\Event\FailedEvent; | |
| use Mautic\CampaignBundle\Event\PendingEvent; | |
| use Mautic\CampaignBundle\EventCollector\Accessor\Event\AbstractEventAccessor; | |
| use Mautic\CampaignBundle\EventCollector\Accessor\Event\ActionAccessor; | |
| use Mautic\CampaignBundle\Executioner\Dispatcher\Exception\LogNotProcessedException; | |
| use Mautic\CampaignBundle\Executioner\Dispatcher\Exception\LogPassedAndFailedException; | |
| use Mautic\CampaignBundle\Executioner\Scheduler\EventScheduler; | |
| use Psr\Log\LoggerInterface; | |
| use Symfony\Component\EventDispatcher\EventDispatcherInterface; | |
| class ActionDispatcher | |
| { | |
| public function __construct( | |
| private EventDispatcherInterface $dispatcher, | |
| private LoggerInterface $logger, | |
| private EventScheduler $scheduler, | |
| private LegacyEventDispatcher $legacyDispatcher | |
| ) { | |
| } | |
| /** | |
| * @throws LogNotProcessedException | |
| * @throws LogPassedAndFailedException | |
| */ | |
| public function dispatchEvent(ActionAccessor $config, Event $event, ArrayCollection $logs, PendingEvent $pendingEvent = null): PendingEvent | |
| { | |
| if (!$pendingEvent) { | |
| $pendingEvent = new PendingEvent($config, $event, $logs); | |
| } | |
| // this if statement can be removed when legacy dispatcher is removed | |
| if ($customEvent = $config->getBatchEventName()) { | |
| $this->dispatcher->dispatch($pendingEvent, $customEvent); | |
| $success = $pendingEvent->getSuccessful(); | |
| $failed = $pendingEvent->getFailures(); | |
| $this->validateProcessedLogs($logs, $success, $failed); | |
| if ($success) { | |
| $this->dispatchExecutedEvent($config, $event, $success); | |
| } | |
| if ($failed) { | |
| $this->dispatchFailedEvent($config, $failed); | |
| } | |
| // Dispatch legacy ON_EVENT_EXECUTION event for BC | |
| $this->legacyDispatcher->dispatchExecutionEvents($config, $success, $failed); | |
| } | |
| // Execute BC eventName or callback. Or support case where the listener has been converted to batchEventName but still wants to execute | |
| // eventName for BC support for plugins that could be listening to it's own custom event. | |
| $this->legacyDispatcher->dispatchCustomEvent($config, $logs, $customEvent, $pendingEvent); | |
| return $pendingEvent; | |
| } | |
| private function dispatchExecutedEvent(AbstractEventAccessor $config, Event $event, ArrayCollection $logs): void | |
| { | |
| if (!$logs->count()) { | |
| return; | |
| } | |
| foreach ($logs as $log) { | |
| $this->dispatcher->dispatch( | |
| new ExecutedEvent($config, $log), | |
| CampaignEvents::ON_EVENT_EXECUTED | |
| ); | |
| } | |
| $this->dispatcher->dispatch( | |
| new ExecutedBatchEvent($config, $event, $logs), | |
| CampaignEvents::ON_EVENT_EXECUTED_BATCH | |
| ); | |
| } | |
| private function dispatchFailedEvent(AbstractEventAccessor $config, ArrayCollection $logs): void | |
| { | |
| if (!$logs->count()) { | |
| return; | |
| } | |
| /** @var LeadEventLog $log */ | |
| foreach ($logs as $log) { | |
| $this->logger->debug( | |
| 'CAMPAIGN: '.ucfirst($log->getEvent()->getEventType() ?? 'unknown event').' ID# '.$log->getEvent()->getId().' for contact ID# '.$log->getLead()->getId() | |
| ); | |
| $this->dispatcher->dispatch( | |
| new FailedEvent($config, $log), | |
| CampaignEvents::ON_EVENT_FAILED | |
| ); | |
| } | |
| $this->scheduler->rescheduleFailures($logs); | |
| } | |
| /** | |
| * @throws LogNotProcessedException | |
| * @throws LogPassedAndFailedException | |
| */ | |
| private function validateProcessedLogs(ArrayCollection $pending, ArrayCollection $success, ArrayCollection $failed): void | |
| { | |
| foreach ($pending as $log) { | |
| if (!$success->contains($log) && !$failed->contains($log)) { | |
| throw new LogNotProcessedException($log); | |
| } | |
| if ($success->contains($log) && $failed->contains($log)) { | |
| throw new LogPassedAndFailedException($log); | |
| } | |
| } | |
| } | |
| } | |