![]() 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/EmailBundle/MonitoredEmail/Processor/ |
<?php namespace Mautic\EmailBundle\MonitoredEmail\Processor; use Doctrine\ORM\EntityNotFoundException; use Mautic\CoreBundle\Helper\EmailAddressHelper; use Mautic\EmailBundle\EmailEvents; use Mautic\EmailBundle\Entity\EmailReply; use Mautic\EmailBundle\Entity\Stat; use Mautic\EmailBundle\Event\EmailReplyEvent; use Mautic\EmailBundle\Model\EmailStatModel; use Mautic\EmailBundle\MonitoredEmail\Exception\ReplyNotFound; use Mautic\EmailBundle\MonitoredEmail\Message; use Mautic\EmailBundle\MonitoredEmail\Processor\Reply\Parser; use Mautic\EmailBundle\MonitoredEmail\Search\ContactFinder; use Mautic\LeadBundle\Model\LeadModel; use Mautic\LeadBundle\Tracker\ContactTracker; use Psr\Log\LoggerInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; class Reply implements ProcessorInterface { public function __construct( private EmailStatModel $emailStatModel, private ContactFinder $contactFinder, private LeadModel $leadModel, private EventDispatcherInterface $dispatcher, private LoggerInterface $logger, private ContactTracker $contactTracker, private EmailAddressHelper $addressHelper ) { } public function process(Message $message): void { $this->logger->debug('MONITORED EMAIL: Processing message ID '.$message->id.' for a reply'); try { $parser = new Parser($message); $repliedEmail = $parser->parse(); } catch (ReplyNotFound) { // No hash found so bail as we won't consider this a reply $this->logger->debug('MONITORED EMAIL: No hash ID found in the email body'); return; } $hashId = $repliedEmail->getStatHash(); $result = $this->contactFinder->findByHash($hashId); if (!$stat = $result->getStat()) { // No stat found so bail as we won't consider this a reply $this->logger->debug('MONITORED EMAIL: Stat not found'); return; } // A stat has been found so let's compare to the From address for the contact to prevent false positives $possibleFromEmails = $this->addressHelper->getVariations($stat->getLead()->getEmail()); $fromEmail = $this->addressHelper->cleanEmail($repliedEmail->getFromAddress()); if (!in_array($fromEmail, $possibleFromEmails)) { // We can't reliably assume this email was from the originating contact $this->logger->debug('MONITORED EMAIL: '.implode(', ', $possibleFromEmails).' != '.$fromEmail.' so cannot confirm match'); return; } $this->createReply($stat, $message->id); $this->dispatchEvent($stat); if (null !== $stat->getLead()) { $this->leadModel->getRepository()->detachEntity($stat->getLead()); } $this->emailStatModel->getRepository()->detachEntity($stat); } /** * @param string $trackingHash * @param string $messageId */ public function createReplyByHash($trackingHash, $messageId): void { /** @var Stat|null $stat */ $stat = $this->emailStatModel->getRepository()->findOneBy(['trackingHash' => $trackingHash]); if (null === $stat) { throw new EntityNotFoundException("Email Stat with tracking hash {$trackingHash} was not found"); } $stat->setIsRead(true); if (null === $stat->getDateRead()) { $stat->setDateRead(new \DateTime()); } $this->createReply($stat, $messageId); $contact = $stat->getLead(); if ($contact) { $this->dispatchEvent($stat); } } /** * @param string $messageId */ protected function createReply(Stat $stat, $messageId) { $replies = $stat->getReplies()->filter( fn (EmailReply $reply): bool => $reply->getMessageId() === $messageId ); if (!$replies->count()) { $emailReply = new EmailReply($stat, $messageId); $stat->addReply($emailReply); $this->emailStatModel->saveEntity($stat); } } private function dispatchEvent(Stat $stat): void { if ($this->dispatcher->hasListeners(EmailEvents::EMAIL_ON_REPLY)) { $this->contactTracker->setTrackedContact($stat->getLead()); $event = new EmailReplyEvent($stat); $this->dispatcher->dispatch($event, EmailEvents::EMAIL_ON_REPLY); unset($event); } } }