ref
This commit is contained in:
@@ -229,11 +229,10 @@ class Binding implements BindingProcessor
|
||||
'Espo\\Core\\Sms\\SenderFactory'
|
||||
);
|
||||
|
||||
$binder
|
||||
->bindImplementation(
|
||||
'Espo\\Core\\Authentication\\Jwt\\KeyFactory',
|
||||
'Espo\\Core\\Authentication\\Jwt\\DefaultKeyFactory'
|
||||
);
|
||||
$binder->bindImplementation(
|
||||
'Espo\\Core\\Authentication\\Jwt\\KeyFactory',
|
||||
'Espo\\Core\\Authentication\\Jwt\\DefaultKeyFactory'
|
||||
);
|
||||
|
||||
$binder
|
||||
->for('Espo\\Core\\Authentication\\Oidc\\TokenValidator')
|
||||
|
||||
@@ -44,19 +44,17 @@ use Espo\Entities\Attachment;
|
||||
use Espo\Entities\Email;
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
use Laminas\{
|
||||
Mime\Message as MimeMessage,
|
||||
Mime\Part as MimePart,
|
||||
Mime\Mime as Mime,
|
||||
Mail\Header\Sender as SenderHeader,
|
||||
Mail\Header\MessageId as MessageIdHeader,
|
||||
Mail\Header\ContentType as ContentTypeHeader,
|
||||
Mail\Message,
|
||||
Mail\Transport\SmtpOptions,
|
||||
Mail\Transport\Envelope,
|
||||
Mail\Transport\Smtp as SmtpTransport,
|
||||
Mail\Protocol\Exception\RuntimeException as ProtocolRuntimeException,
|
||||
};
|
||||
use Laminas\Mail\Header\ContentType as ContentTypeHeader;
|
||||
use Laminas\Mail\Header\MessageId as MessageIdHeader;
|
||||
use Laminas\Mail\Header\Sender as SenderHeader;
|
||||
use Laminas\Mail\Message;
|
||||
use Laminas\Mail\Protocol\Exception\RuntimeException as ProtocolRuntimeException;
|
||||
use Laminas\Mail\Transport\Envelope;
|
||||
use Laminas\Mail\Transport\Smtp as SmtpTransport;
|
||||
use Laminas\Mail\Transport\SmtpOptions;
|
||||
use Laminas\Mime\Message as MimeMessage;
|
||||
use Laminas\Mime\Mime as Mime;
|
||||
use Laminas\Mime\Part as MimePart;
|
||||
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Modules\Crm;
|
||||
|
||||
use Espo\Core\Binding\Binder;
|
||||
use Espo\Core\Binding\BindingProcessor;
|
||||
|
||||
class Binding implements BindingProcessor
|
||||
{
|
||||
public function process(Binder $binder): void
|
||||
{
|
||||
$binder->bindImplementation(
|
||||
'Espo\\Modules\\Crm\\Tools\\MassEmail\\MessageHeadersPreparator',
|
||||
'Espo\\Modules\\Crm\\Tools\\MassEmail\\DefaultMessageHeadersPreparator'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Modules\Crm\Tools\MassEmail;
|
||||
|
||||
use Espo\Core\Mail\Mail\Header\XQueueItemId;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\Modules\Crm\Tools\MassEmail\MessagePreparator\Data;
|
||||
use Laminas\Mail\Headers;
|
||||
|
||||
class DefaultMessageHeadersPreparator implements MessageHeadersPreparator
|
||||
{
|
||||
private Config $config;
|
||||
|
||||
public function __construct(Config $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function prepare(Headers $headers, Data $data): void
|
||||
{
|
||||
$id = $data->getId();
|
||||
|
||||
$header = new XQueueItemId();
|
||||
$header->setId($id);
|
||||
|
||||
$headers->addHeader($header);
|
||||
$headers->addHeaderLine('Precedence', 'bulk');
|
||||
|
||||
if (!$this->config->get('massEmailDisableMandatoryOptOutLink')) {
|
||||
$optOutUrl = $this->getSiteUrl() . '?entryPoint=unsubscribe&id=' . $id;
|
||||
|
||||
$headers->addHeaderLine('List-Unsubscribe', '<' . $optOutUrl . '>');
|
||||
}
|
||||
}
|
||||
|
||||
private function getSiteUrl(): string
|
||||
{
|
||||
return
|
||||
$this->config->get('massEmailSiteUrl') ??
|
||||
$this->config->get('siteUrl');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Modules\Crm\Tools\MassEmail;
|
||||
|
||||
use Espo\Modules\Crm\Tools\MassEmail\MessagePreparator\Data;
|
||||
use Laminas\Mail\Headers;
|
||||
|
||||
/**
|
||||
* Applies additional headers to a mass email message.
|
||||
*/
|
||||
interface MessageHeadersPreparator
|
||||
{
|
||||
public function prepare(Headers $headers, Data $data): void;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Modules\Crm\Tools\MassEmail\MessagePreparator;
|
||||
|
||||
use Espo\Core\Mail\SenderParams;
|
||||
|
||||
class Data
|
||||
{
|
||||
private string $id;
|
||||
private SenderParams $senderParams;
|
||||
|
||||
public function __construct(
|
||||
string $id,
|
||||
SenderParams $senderParams
|
||||
) {
|
||||
$this->id = $id;
|
||||
$this->senderParams = $senderParams;
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getSenderParams(): SenderParams
|
||||
{
|
||||
return $this->senderParams;
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,7 @@ use Espo\Core\Mail\Exceptions\NoSmtp;
|
||||
use Espo\Core\Mail\SenderParams;
|
||||
use Espo\Core\Mail\SmtpParams;
|
||||
use Espo\Entities\Attachment;
|
||||
use Espo\Modules\Crm\Tools\MassEmail\MessagePreparator\Data;
|
||||
use Espo\ORM\Collection;
|
||||
use Laminas\Mail\Message;
|
||||
|
||||
@@ -43,7 +44,6 @@ use Espo\Entities\EmailAddress;
|
||||
|
||||
use Espo\Core\Exceptions\Error;
|
||||
use Espo\Core\Mail\EmailSender;
|
||||
use Espo\Core\Mail\Mail\Header\XQueueItemId;
|
||||
use Espo\Core\Mail\Sender;
|
||||
use Espo\Core\ORM\EntityManager;
|
||||
use Espo\Core\Utils\Config;
|
||||
@@ -76,6 +76,7 @@ class SendingProcessor
|
||||
private AccountFactory $accountFactory;
|
||||
private CampaignService $campaignService;
|
||||
private EmailTemplateService $emailTemplateService;
|
||||
private MessageHeadersPreparator $headersPreparator;
|
||||
|
||||
public function __construct(
|
||||
Config $config,
|
||||
@@ -85,7 +86,8 @@ class SendingProcessor
|
||||
Log $log,
|
||||
AccountFactory $accountFactory,
|
||||
CampaignService $campaignService,
|
||||
EmailTemplateService $emailTemplateService
|
||||
EmailTemplateService $emailTemplateService,
|
||||
MessageHeadersPreparator $headersPreparator
|
||||
) {
|
||||
$this->config = $config;
|
||||
$this->entityManager = $entityManager;
|
||||
@@ -95,6 +97,7 @@ class SendingProcessor
|
||||
$this->accountFactory = $accountFactory;
|
||||
$this->campaignService = $campaignService;
|
||||
$this->emailTemplateService = $emailTemplateService;
|
||||
$this->headersPreparator = $headersPreparator;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -288,6 +291,7 @@ class SendingProcessor
|
||||
|
||||
$emailData['body'] = $body;
|
||||
|
||||
/** @var Email $email */
|
||||
$email = $this->entityManager
|
||||
->getRDBRepositoryByClass(Email::class)
|
||||
->getNew();
|
||||
@@ -300,57 +304,44 @@ class SendingProcessor
|
||||
return null;
|
||||
}
|
||||
|
||||
$email->set('to', $emailAddress);
|
||||
$email->addToAddress($emailAddress);
|
||||
|
||||
if ($massEmail->getFromAddress()) {
|
||||
$email->set('from', $massEmail->getFromAddress());
|
||||
$email->setFromAddress($massEmail->getFromAddress());
|
||||
}
|
||||
|
||||
if ($massEmail->getReplyToAddress()) {
|
||||
$email->set('replyTo', $massEmail->getReplyToAddress());
|
||||
$replyToAddress = $massEmail->getReplyToAddress();
|
||||
|
||||
if ($replyToAddress) {
|
||||
$email->addReplyToAddress($replyToAddress);
|
||||
}
|
||||
|
||||
return $email;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Refactor. Use composition with an interface.
|
||||
*/
|
||||
protected function prepareQueueItemMessage(
|
||||
private function prepareQueueItemMessage(
|
||||
EmailQueueItem $queueItem,
|
||||
Sender $sender,
|
||||
Message $message,
|
||||
SenderParams $senderParams
|
||||
): SenderParams {
|
||||
): void {
|
||||
|
||||
$header = new XQueueItemId();
|
||||
$header->setId($queueItem->getId());
|
||||
$id = $queueItem->getId();
|
||||
|
||||
$message->getHeaders()->addHeader($header);
|
||||
$message->getHeaders()->addHeaderLine('Precedence', 'bulk');
|
||||
$this->headersPreparator->prepare($message->getHeaders(), new Data($id, $senderParams));
|
||||
|
||||
if (!$this->config->get('massEmailDisableMandatoryOptOutLink')) {
|
||||
$optOutUrl = $this->getSiteUrl() . '?entryPoint=unsubscribe&id=' . $queueItem->getId();
|
||||
|
||||
$message->getHeaders()->addHeaderLine('List-Unsubscribe', '<' . $optOutUrl . '>');
|
||||
}
|
||||
|
||||
$fromAddress =
|
||||
$senderParams->getFromAddress() ??
|
||||
$this->config->get('outboundEmailFromAddress');
|
||||
$fromAddress = $senderParams->getFromAddress();
|
||||
|
||||
if (
|
||||
$this->config->get('massEmailVerp') &&
|
||||
$fromAddress &&
|
||||
strpos($fromAddress, '@')
|
||||
) {
|
||||
$bounceAddress = explode('@', $fromAddress)[0] . '+bounce-qid-' . $queueItem->getId() .
|
||||
$bounceAddress = explode('@', $fromAddress)[0] . '+bounce-qid-' . $id .
|
||||
'@' . explode('@', $fromAddress)[1];
|
||||
|
||||
$sender->withEnvelopeOptions(['from' => $bounceAddress]);
|
||||
}
|
||||
|
||||
return $senderParams;
|
||||
}
|
||||
|
||||
private function setFailed(MassEmail $massEmail): void
|
||||
@@ -464,6 +455,11 @@ class SendingProcessor
|
||||
);
|
||||
}
|
||||
|
||||
$senderParams = $senderParams->withFromAddress(
|
||||
$massEmail->getFromAddress() ??
|
||||
$this->config->get('outboundEmailFromAddress')
|
||||
);
|
||||
|
||||
if ($massEmail->getFromName()) {
|
||||
$senderParams = $senderParams->withFromName($massEmail->getFromName());
|
||||
}
|
||||
@@ -486,7 +482,7 @@ class SendingProcessor
|
||||
|
||||
$message = new Message();
|
||||
|
||||
$senderParams = $this->prepareQueueItemMessage($queueItem, $sender, $message, $senderParams);
|
||||
$this->prepareQueueItemMessage($queueItem, $sender, $message, $senderParams);
|
||||
|
||||
$sender
|
||||
->withParams($senderParams)
|
||||
@@ -539,6 +535,8 @@ class SendingProcessor
|
||||
|
||||
private function getSiteUrl(): string
|
||||
{
|
||||
return $this->config->get('massEmailSiteUrl') ?? $this->config->get('siteUrl');
|
||||
return
|
||||
$this->config->get('massEmailSiteUrl') ??
|
||||
$this->config->get('siteUrl');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user