Spaces:
No application file
No application file
declare(strict_types=1); | |
namespace Mautic\EmailBundle\Helper; | |
use Mautic\CoreBundle\Helper\CoreParametersHelper; | |
use Mautic\EmailBundle\Entity\Email; | |
use Mautic\EmailBundle\Helper\DTO\AddressDTO; | |
use Mautic\EmailBundle\Helper\Exception\OwnerNotFoundException; | |
use Mautic\EmailBundle\Helper\Exception\TokenNotFoundOrEmptyException; | |
use Mautic\LeadBundle\Entity\LeadRepository; | |
class FromEmailHelper | |
{ | |
/** | |
* @var array<int,mixed[]> | |
*/ | |
private array $owners = []; | |
private ?AddressDTO $defaultFrom = null; | |
/** | |
* @var mixed[]|null | |
*/ | |
private ?array $lastOwner = null; | |
public function __construct(private CoreParametersHelper $coreParametersHelper, private LeadRepository $leadRepository) | |
{ | |
} | |
public function setDefaultFrom(AddressDTO $from): void | |
{ | |
$this->defaultFrom = $from; | |
} | |
/** | |
* @param mixed[] $contact | |
*/ | |
public function getFromAddressConsideringOwner(AddressDTO $address, array $contact = null, Email $email = null): AddressDTO | |
{ | |
// Reset last owner | |
$this->lastOwner = null; | |
// Check for token | |
if ($address->isEmailTokenized() || $address->isNameTokenized()) { | |
return $this->getEmailFromToken($address, $contact, true, $email); | |
} | |
if (!$contact) { | |
return $address; | |
} | |
try { | |
return $this->getFromEmailAsOwner($contact, $email); | |
} catch (OwnerNotFoundException) { | |
return $this->getFrom($email); | |
} | |
} | |
/** | |
* @param mixed[] $contact | |
*/ | |
public function getFromAddressDto(AddressDTO $address, array $contact = null, Email $email = null): AddressDTO | |
{ | |
// Reset last owner | |
$this->lastOwner = null; | |
// Check for token | |
if ($address->isEmailTokenized() || $address->isNameTokenized()) { | |
return $this->getEmailFromToken($address, $contact, false, $email); | |
} | |
return $address; | |
} | |
/** | |
* @return mixed[] | |
* | |
* @throws OwnerNotFoundException | |
*/ | |
public function getContactOwner(int $userId, Email $email = null): array | |
{ | |
// Reset last owner | |
$this->lastOwner = null; | |
if ($email) { | |
if (!$email->getUseOwnerAsMailer()) { | |
throw new OwnerNotFoundException("mailer_is_owner is not enabled for this email ({$email->getId()})"); | |
} | |
} elseif (!$this->coreParametersHelper->get('mailer_is_owner')) { | |
throw new OwnerNotFoundException('mailer_is_owner is not enabled in global configuration'); | |
} | |
if (isset($this->owners[$userId])) { | |
return $this->lastOwner = $this->owners[$userId]; | |
} | |
if ($owner = $this->leadRepository->getLeadOwner($userId)) { | |
$this->owners[$userId] = $this->lastOwner = $owner; | |
return $owner; | |
} | |
throw new OwnerNotFoundException(); | |
} | |
public function getSignature(): string | |
{ | |
if (!$this->lastOwner) { | |
return ''; | |
} | |
return $this->replaceSignatureTokens($this->lastOwner); | |
} | |
/** | |
* @param mixed[] $owner | |
*/ | |
private function replaceSignatureTokens(array $owner): string | |
{ | |
$signature = nl2br($owner['signature'] ?? ''); | |
$signature = str_replace('|FROM_NAME|', $owner['first_name'].' '.$owner['last_name'], $signature); | |
foreach ($owner as $key => $value) { | |
$token = sprintf('|USER_%s|', strtoupper($key)); | |
$signature = str_replace($token, (string) $value, (string) $signature); | |
} | |
return $signature; | |
} | |
private function getFrom(?Email $email): AddressDTO | |
{ | |
if ($email && $email->getFromAddress()) { | |
return new AddressDTO($email->getFromAddress(), $email->getFromName()); | |
} | |
return $this->getDefaultFrom(); | |
} | |
private function getDefaultFrom(): AddressDTO | |
{ | |
if ($this->defaultFrom) { | |
return $this->defaultFrom; | |
} | |
return $this->getSystemDefaultFrom(); | |
} | |
private function getSystemDefaultFrom(): AddressDTO | |
{ | |
$email = $this->coreParametersHelper->get('mailer_from_email'); | |
$name = $this->coreParametersHelper->get('mailer_from_name') ?: null; | |
return new AddressDTO($email, $name); | |
} | |
/** | |
* @param mixed[] $contact | |
*/ | |
private function getEmailFromToken(AddressDTO $address, array $contact = null, bool $asOwner = true, Email $email = null): AddressDTO | |
{ | |
try { | |
if (!$contact) { | |
throw new TokenNotFoundOrEmptyException(); | |
} | |
$name = $address->isNameTokenized() ? $address->getNameTokenValue($contact) : $address->getName(); | |
} catch (TokenNotFoundOrEmptyException) { | |
$name = $this->defaultFrom ? $this->defaultFrom->getName() : $this->getSystemDefaultFrom()->getName(); | |
} | |
try { | |
if (!$contact) { | |
throw new TokenNotFoundOrEmptyException(); | |
} | |
$emailAddress = $address->isEmailTokenized() ? $address->getEmailTokenValue($contact) : $address->getEmail(); | |
return new AddressDTO($emailAddress, $name); | |
} catch (TokenNotFoundOrEmptyException) { | |
if ($contact && $asOwner) { | |
try { | |
return $this->getFromEmailAsOwner($contact, $email); | |
} catch (OwnerNotFoundException) { | |
} | |
} | |
return $this->getDefaultFrom(); | |
} | |
} | |
/** | |
* @param mixed[] $contact | |
* | |
* @throws OwnerNotFoundException | |
*/ | |
private function getFromEmailAsOwner(array $contact, Email $email = null): AddressDTO | |
{ | |
if (empty($contact['owner_id'])) { | |
throw new OwnerNotFoundException(); | |
} | |
$owner = $this->getContactOwner((int) $contact['owner_id'], $email); | |
$ownerEmail = $owner['email']; | |
$ownerName = sprintf('%s %s', $owner['first_name'], $owner['last_name']); | |
// Decode apostrophes and other special characters | |
$ownerName = trim(html_entity_decode($ownerName, ENT_QUOTES)); | |
return new AddressDTO($ownerEmail, $ownerName); | |
} | |
} | |