chrisbryan17's picture
Upload folder using huggingface_hub
d2897cd verified
<?php
namespace Mautic\CampaignBundle\Executioner\Logger;
use Doctrine\Common\Collections\ArrayCollection;
use Mautic\CampaignBundle\Entity\Event;
use Mautic\CampaignBundle\Entity\LeadEventLog;
use Mautic\CampaignBundle\Entity\LeadEventLogRepository;
use Mautic\CampaignBundle\Entity\LeadRepository;
use Mautic\CampaignBundle\EventCollector\Accessor\Event\AbstractEventAccessor;
use Mautic\CampaignBundle\Helper\ChannelExtractor;
use Mautic\CampaignBundle\Model\SummaryModel;
use Mautic\CoreBundle\Helper\IpLookupHelper;
use Mautic\LeadBundle\Entity\Lead;
use Mautic\LeadBundle\Tracker\ContactTracker;
class EventLogger
{
private ArrayCollection $persistQueue;
private ArrayCollection $logs;
private array $contactRotations = [];
/**
* @var int
*/
private $lastUsedCampaignIdToFetchRotation;
public function __construct(
private IpLookupHelper $ipLookupHelper,
private ContactTracker $contactTracker,
private LeadEventLogRepository $leadEventLogRepository,
private LeadRepository $leadRepository,
private SummaryModel $summaryModel
) {
$this->persistQueue = new ArrayCollection();
$this->logs = new ArrayCollection();
}
public function queueToPersist(LeadEventLog $log): void
{
$this->persistQueue->add($log);
if ($this->persistQueue->count() >= 20) {
$this->persistPendingAndInsertIntoLogStack();
}
}
public function persistLog(LeadEventLog $log): void
{
$this->leadEventLogRepository->saveEntity($log);
$this->summaryModel->updateSummary([$log]);
}
/**
* @param bool $isInactiveEvent
*/
public function buildLogEntry(Event $event, Lead $contact = null, $isInactiveEvent = false): LeadEventLog
{
$log = new LeadEventLog();
if (!defined('MAUTIC_CAMPAIGN_SYSTEM_TRIGGERED')) {
$log->setIpAddress($this->ipLookupHelper->getIpAddress());
}
$log->setEvent($event);
$log->setCampaign($event->getCampaign());
if (null === $contact) {
$contact = $this->contactTracker->getContact();
}
$log->setLead($contact);
if ($isInactiveEvent) {
$log->setNonActionPathTaken(true);
}
$log->setDateTriggered(new \DateTime());
$log->setSystemTriggered(defined('MAUTIC_CAMPAIGN_SYSTEM_TRIGGERED'));
if (isset($this->contactRotations[$contact->getId()]) && ($this->lastUsedCampaignIdToFetchRotation === $event->getCampaign()->getId())) {
$log->setRotation($this->contactRotations[$contact->getId()]['rotation']);
} else {
// Likely a single contact handle such as decision processing
$rotations = $this->leadRepository->getContactRotations([$contact->getId()], $event->getCampaign()->getId());
$rotationVal = isset($rotations[$contact->getId()]) ? $rotations[$contact->getId()]['rotation'] : 1;
$log->setRotation($rotationVal);
}
return $log;
}
/**
* Persist the queue, clear the entities from memory, and reset the queue.
*
* @return ArrayCollection
*/
public function persistQueuedLogs()
{
$this->persistPendingAndInsertIntoLogStack();
$logs = clone $this->logs;
$this->logs->clear();
return $logs;
}
public function persistCollection(ArrayCollection $collection): self
{
if (!$collection->count()) {
return $this;
}
$this->leadEventLogRepository->saveEntities($collection->getValues());
$this->summaryModel->updateSummary($collection->getValues());
return $this;
}
public function clearCollection(ArrayCollection $collection): self
{
$this->leadEventLogRepository->detachEntities($collection->getValues());
return $this;
}
public function extractContactsFromLogs(ArrayCollection $logs): ArrayCollection
{
$contacts = new ArrayCollection();
/** @var LeadEventLog $log */
foreach ($logs as $log) {
$contact = $log->getLead();
$contacts->set($contact->getId(), $contact);
}
return $contacts;
}
/**
* @param bool $isInactiveEntry
*
* @return ArrayCollection
*/
public function fetchRotationAndGenerateLogsFromContacts(Event $event, AbstractEventAccessor $config, ArrayCollection $contacts, $isInactiveEntry = false)
{
$this->hydrateContactRotationsForNewLogs($contacts->getKeys(), $event->getCampaign()->getId());
return $this->generateLogsFromContacts($event, $config, $contacts, $isInactiveEntry);
}
/**
* @param bool $isInactiveEntry
*
* @return ArrayCollection
*/
public function generateLogsFromContacts(Event $event, AbstractEventAccessor $config, ArrayCollection $contacts, $isInactiveEntry)
{
$isDecision = Event::TYPE_DECISION === $event->getEventType();
// Ensure each contact has a log entry to prevent them from being picked up again prematurely
foreach ($contacts as $contact) {
if (isset($this->contactRotations[$contact->getId()]) && $this->contactRotations[$contact->getId()]['manually_removed']) {
continue;
}
$log = $this->buildLogEntry($event, $contact, $isInactiveEntry);
$log->setIsScheduled(false);
$log->setDateTriggered(new \DateTime());
ChannelExtractor::setChannel($log, $event, $config);
if ($isDecision) {
// Do not pre-persist decision logs as they must be evaluated first
$this->logs->add($log);
} else {
$this->queueToPersist($log);
}
}
return $this->persistQueuedLogs();
}
/**
* @param int $campaignId
*/
public function hydrateContactRotationsForNewLogs(array $contactIds, $campaignId): void
{
$this->contactRotations = $this->leadRepository->getContactRotations($contactIds, $campaignId);
$this->lastUsedCampaignIdToFetchRotation = $campaignId;
}
private function persistPendingAndInsertIntoLogStack(): void
{
if (!$this->persistQueue->count()) {
return;
}
$this->leadEventLogRepository->saveEntities($this->persistQueue->getValues());
// Push them into the logs ArrayCollection to be used later.
/** @var LeadEventLog $log */
foreach ($this->persistQueue as $log) {
$this->logs->set($log->getId(), $log);
}
$this->persistQueue->clear();
}
public function getSummaryModel(): SummaryModel
{
return $this->summaryModel;
}
}