Spaces:
No application file
No application file
namespace Mautic\CampaignBundle\Executioner\Event; | |
use Doctrine\Common\Collections\ArrayCollection; | |
use Mautic\CampaignBundle\Entity\Event; | |
use Mautic\CampaignBundle\Entity\LeadEventLog; | |
use Mautic\CampaignBundle\EventCollector\Accessor\Event\AbstractEventAccessor; | |
use Mautic\CampaignBundle\EventCollector\Accessor\Event\DecisionAccessor; | |
use Mautic\CampaignBundle\Executioner\Dispatcher\DecisionDispatcher; | |
use Mautic\CampaignBundle\Executioner\Exception\CannotProcessEventException; | |
use Mautic\CampaignBundle\Executioner\Exception\DecisionNotApplicableException; | |
use Mautic\CampaignBundle\Executioner\Logger\EventLogger; | |
use Mautic\CampaignBundle\Executioner\Result\EvaluatedContacts; | |
use Mautic\LeadBundle\Entity\Lead; | |
class DecisionExecutioner implements EventInterface | |
{ | |
public const TYPE = 'decision'; | |
public function __construct( | |
private EventLogger $eventLogger, | |
private DecisionDispatcher $dispatcher | |
) { | |
} | |
/** | |
* @param mixed $passthrough | |
* @param string|null $channel | |
* @param int|null $channelId | |
* | |
* @throws CannotProcessEventException | |
* @throws DecisionNotApplicableException | |
*/ | |
public function evaluateForContact(DecisionAccessor $config, Event $event, Lead $contact, $passthrough = null, $channel = null, $channelId = null): void | |
{ | |
if (Event::TYPE_DECISION !== $event->getEventType()) { | |
throw new CannotProcessEventException('Cannot process event ID '.$event->getId().' as a decision.'); | |
} | |
$log = $this->eventLogger->buildLogEntry($event, $contact); | |
$log->setChannel($channel); | |
$log->setChannelId($channelId); | |
$decisionEvent = $this->dispatcher->dispatchRealTimeEvent($config, $log, $passthrough); | |
if (!$decisionEvent->wasDecisionApplicable()) { | |
throw new DecisionNotApplicableException('evaluation failed'); | |
} | |
$this->eventLogger->persistLog($log); | |
} | |
/** | |
* @throws CannotProcessEventException | |
*/ | |
public function execute(AbstractEventAccessor $config, ArrayCollection $logs): EvaluatedContacts | |
{ | |
\assert($config instanceof DecisionAccessor); | |
$evaluatedContacts = new EvaluatedContacts(); | |
$failedLogs = []; | |
/** @var LeadEventLog $log */ | |
foreach ($logs as $log) { | |
if (Event::TYPE_DECISION !== $log->getEvent()->getEventType()) { | |
throw new CannotProcessEventException('Event ID '.$log->getEvent()->getId().' is not a decision'); | |
} | |
try { | |
/* @var DecisionAccessor $config */ | |
$this->dispatchEvent($config, $log); | |
$evaluatedContacts->pass($log->getLead()); | |
// Update the date triggered timestamp | |
$log->setDateTriggered(new \DateTime()); | |
} catch (DecisionNotApplicableException) { | |
// Fail the contact but remove the log from being processed upstream | |
// active/positive/green path while letting the InactiveExecutioner handle the inactive/negative/red paths | |
$failedLogs[] = $log; | |
$evaluatedContacts->fail($log->getLead()); | |
} | |
} | |
$this->dispatcher->dispatchDecisionResultsEvent($config, $logs, $evaluatedContacts); | |
// Remove the logs | |
foreach ($failedLogs as $log) { | |
$logs->removeElement($log); | |
} | |
return $evaluatedContacts; | |
} | |
/** | |
* @throws DecisionNotApplicableException | |
*/ | |
private function dispatchEvent(DecisionAccessor $config, LeadEventLog $log): void | |
{ | |
$decisionEvent = $this->dispatcher->dispatchEvaluationEvent($config, $log); | |
if (!$decisionEvent->wasDecisionApplicable()) { | |
throw new DecisionNotApplicableException('evaluation failed'); | |
} | |
} | |
} | |