![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/mautic.corals.io/app/bundles/LeadBundle/Model/ |
<?php namespace Mautic\LeadBundle\Model; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\PersistentCollection; use Mautic\CoreBundle\Model\MauticModelInterface; use Mautic\LeadBundle\Entity\DoNotContact as DNC; use Mautic\LeadBundle\Entity\DoNotContactRepository; use Mautic\LeadBundle\Entity\Lead; class DoNotContact implements MauticModelInterface { public function __construct( protected LeadModel $leadModel, protected DoNotContactRepository $dncRepo ) { } /** * Remove a Lead's DNC entry based on channel. * * @param int $contactId * @param string $channel * @param bool|true $persist * @param int|null $reason */ public function removeDncForContact($contactId, $channel, $persist = true, $reason = null): bool { $contact = $this->leadModel->getEntity($contactId); /** @var DNC $dnc */ foreach ($contact->getDoNotContact() as $dnc) { if ($dnc->getChannel() === $channel) { // Skip if reason doesn't match // Some integrations (Sugar CRM) can use both reasons (unsubscribed, bounced) if ($reason && $dnc->getReason() != $reason) { continue; } $contact->removeDoNotContactEntry($dnc); if ($persist) { $this->leadModel->saveEntity($contact); } return true; } } return false; } /** * Create a DNC entry for a lead. * * @param Lead|int|null $contactId * @param string|mixed[] $channel If an array with an ID, use the structure ['email' => 123] * @param string $comments * @param int $reason Must be a class constant from the DoNotContact class * @param bool $persist * @param bool $checkCurrentStatus * @param bool $allowUnsubscribeOverride * * @return bool|DNC If a DNC entry is added or updated, returns the DoNotContact object. If a DNC is already present * and has the specified reason, nothing is done and this returns false */ public function addDncForContact( $contactId, $channel, $reason = DNC::BOUNCED, $comments = '', $persist = true, $checkCurrentStatus = true, $allowUnsubscribeOverride = false ) { $dnc = null; $contact = $this->leadModel->getEntity($contactId); if (null === $contact) { // Contact not found, nothing to do return false; } // if !$checkCurrentStatus, assume is contactable due to already being validated $isContactable = ($checkCurrentStatus) ? $this->isContactable($contact, $channel) : DNC::IS_CONTACTABLE; /** @var ArrayCollection<int, DNC> $dncEntities */ $dncEntities = new ArrayCollection(); // If they don't have a DNC entry yet if (DNC::IS_CONTACTABLE === $isContactable) { $dnc = $dncEntities[] = $this->createDncRecord($contact, $channel, $reason, $comments); } elseif ($isContactable !== $reason) { // Or if the given reason is different than the stated reason $dncEntities = $contact->getDoNotContact(); foreach ($dncEntities as $dnc) { // Only update if the contact did not unsubscribe themselves or if the code forces it $allowOverride = ($allowUnsubscribeOverride || DNC::UNSUBSCRIBED !== $dnc->getReason()); // Only update if the contact did not unsubscribe themselves if ($allowOverride && $dnc->getChannel() === $channel) { // Note the outdated entry for listeners $contact->removeDoNotContactEntry($dnc); // Update the entry with the latest $this->updateDncRecord($dnc, $contact, $channel, $reason, $comments); break; } } } if (null !== $dnc && $persist) { // Use model saveEntity to trigger events for DNC change $this->leadModel->saveEntity($contact); $this->dncRepo->detachEntities($dncEntities->toArray()); // need to force a collection to load items in the next call. $collection = $contact->getDoNotContact(); if ($collection instanceof PersistentCollection) { $collection->setInitialized(false); } } return $dnc; } /** * @param string $channel * * @return int * * @see DNC This method can return boolean false, so be * sure to always compare the return value against * the class constants of DoNotContact */ public function isContactable(Lead $contact, $channel) { if (is_array($channel)) { $channel = key($channel); } $dncEntries = $this->dncRepo->getEntriesByLeadAndChannel($contact, $channel); // If the lead has no entries in the DNC table, we're good to go if (empty($dncEntries)) { return DNC::IS_CONTACTABLE; } foreach ($dncEntries as $dnc) { if (DNC::IS_CONTACTABLE !== $dnc->getReason()) { return $dnc->getReason(); } } return DNC::IS_CONTACTABLE; } public function createDncRecord(Lead $contact, $channel, $reason, $comments = null): DNC { $dnc = new DNC(); if (is_array($channel)) { $channelId = reset($channel); $channel = key($channel); $dnc->setChannelId((int) $channelId); } $dnc->setChannel($channel); $dnc->setReason($reason); $dnc->setLead($contact); $dnc->setDateAdded(new \DateTime()); $dnc->setComments($comments); $contact->addDoNotContactEntry($dnc); return $dnc; } public function updateDncRecord(DNC $dnc, Lead $contact, $channel, $reason, $comments = null): void { // Update the DNC entry $dnc->setChannel($channel); $dnc->setReason($reason); $dnc->setLead($contact); $dnc->setDateAdded(new \DateTime()); $dnc->setComments($comments); // Re-add the entry to the lead $contact->addDoNotContactEntry($dnc); } /** * @return DoNotContactRepository */ public function getDncRepo() { return $this->dncRepo; } }