email sending changes
This commit is contained in:
@@ -35,7 +35,8 @@ class MailSender extends Base
|
||||
{
|
||||
return new \Espo\Core\Mail\Sender(
|
||||
$this->getContainer()->get('config'),
|
||||
$this->getContainer()->get('entityManager')
|
||||
$this->getContainer()->get('entityManager'),
|
||||
$this->getContainer()->get('serviceFactory')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,16 +48,26 @@ class Sender
|
||||
|
||||
protected $entityManager;
|
||||
|
||||
protected $serviceFactory;
|
||||
|
||||
protected $transport;
|
||||
|
||||
protected $isGlobal = false;
|
||||
|
||||
protected $params = [];
|
||||
|
||||
public function __construct($config, $entityManager)
|
||||
private $systemInboundEmail = null;
|
||||
|
||||
private $inboundEmailService = null;
|
||||
|
||||
private $systemInboundEmailIsCached = false;
|
||||
|
||||
public function __construct($config, $entityManager, $serviceFactory = null)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->entityManager = $entityManager;
|
||||
$this->serviceFactory = $serviceFactory;
|
||||
|
||||
$this->useGlobal();
|
||||
}
|
||||
|
||||
@@ -86,6 +96,19 @@ class Sender
|
||||
public function useSmtp(array $params = []) : self
|
||||
{
|
||||
$this->isGlobal = false;
|
||||
$this->applySmtp($params);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function useGlobal()
|
||||
{
|
||||
$this->params = [];
|
||||
$this->isGlobal = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function applySmtp(array $params = [])
|
||||
{
|
||||
$this->params = $params;
|
||||
|
||||
$this->transport = new SmtpTransport();
|
||||
@@ -106,11 +129,12 @@ class Sender
|
||||
$options['connectionConfig'][$key] = $value;
|
||||
}
|
||||
|
||||
if ($params['auth']) {
|
||||
if (!empty($params['smtpAuthMechanism'])) {
|
||||
$smtpAuthMechanism = preg_replace("([\.]{2,})", '', $params['smtpAuthMechanism']);
|
||||
if (in_array($smtpAuthMechanism, ['login', 'crammd5', 'plain'])) {
|
||||
$options['connectionClass'] = $smtpAuthMechanism;
|
||||
if ($params['auth'] ?? false) {
|
||||
$authMechanism = $params['authMechanism'] ?? $params['smtpAuthMechanism'] ?? null;
|
||||
if ($authMechanism) {
|
||||
$authMechanism = preg_replace("([\.]{2,})", '', $params['authMechanism']);
|
||||
if (in_array($authMechanism, ['login', 'crammd5', 'plain'])) {
|
||||
$options['connectionClass'] = $authMechanism;
|
||||
} else {
|
||||
$options['connectionClass'] = 'login';
|
||||
}
|
||||
@@ -121,11 +145,12 @@ class Sender
|
||||
$options['connectionConfig']['password'] = $params['password'];
|
||||
}
|
||||
|
||||
if (!empty($params['smtpAuthClassName'])) {
|
||||
$options['connectionClass'] = $params['smtpAuthClassName'];
|
||||
$authClassName = $params['authClassName'] ?? $params['smtpAuthClassName'] ?? null;
|
||||
if ($authClassName) {
|
||||
$options['connectionClass'] = $authClassName;
|
||||
}
|
||||
|
||||
if ($params['security']) {
|
||||
if ($params['security'] ?? null) {
|
||||
$options['connectionConfig']['ssl'] = strtolower($params['security']);
|
||||
}
|
||||
|
||||
@@ -138,48 +163,68 @@ class Sender
|
||||
|
||||
$smtpOptions = new SmtpOptions($options);
|
||||
$this->transport->setOptions($smtpOptions);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function useGlobal()
|
||||
protected function applyGlobal()
|
||||
{
|
||||
$this->params = [];
|
||||
if ($this->isGlobal) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->transport = new SmtpTransport();
|
||||
|
||||
$config = $this->config;
|
||||
|
||||
$localHostName = $config->get('smtpLocalHostName', gethostname());
|
||||
if (!$config->get('smtpServer') && $config->get('outboundEmailFromAddress')) {
|
||||
$inboundEmail = $this->getSystemInboundEmail();
|
||||
if ($inboundEmail) {
|
||||
$service = $this->getInboundEmailService();
|
||||
if ($service) {
|
||||
$params = $service->getSmtpParamsFromAccount($inboundEmail);
|
||||
$this->applySmtp($params);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$options = [
|
||||
'name' => $localHostName,
|
||||
'host' => $config->get('smtpServer'),
|
||||
$this->applySmtp([
|
||||
'server' => $config->get('smtpServer'),
|
||||
'port' => $config->get('smtpPort'),
|
||||
'connection_config' => [],
|
||||
];
|
||||
if ($config->get('smtpAuth')) {
|
||||
$options['connection_class'] = $config->get('smtpAuthMechanism', 'login');
|
||||
$options['connection_config']['username'] = $config->get('smtpUsername');
|
||||
$options['connection_config']['password'] = $config->get('smtpPassword');
|
||||
}
|
||||
if ($config->get('smtpSecurity')) {
|
||||
$options['connection_config']['ssl'] = strtolower($config->get('smtpSecurity'));
|
||||
'auth' => $config->get('smtpAuth'),
|
||||
'authMechanism' => $config->get('smtpAuthMechanism', 'login'),
|
||||
'username' => $config->get('smtpUsername'),
|
||||
'password' => $config->get('smtpPassword'),
|
||||
'security' => $config->get('smtpSecurity'),
|
||||
]);
|
||||
}
|
||||
|
||||
protected function getSystemInboundEmail()
|
||||
{
|
||||
$address = $this->config->get('outboundEmailFromAddress');
|
||||
|
||||
if (!$this->systemInboundEmailIsCached && $address) {
|
||||
$this->systemInboundEmail = $this->getEntityManager()->getRepository('InboundEmail')->where([
|
||||
'status' => 'Active',
|
||||
'useSmtp' => true,
|
||||
'emailAddress' => $address,
|
||||
])->findOne();
|
||||
$this->systemInboundEmailIsCached = true;
|
||||
}
|
||||
|
||||
$smtpOptions = new SmtpOptions($options);
|
||||
$this->transport->setOptions($smtpOptions);
|
||||
return $this->systemInboundEmail;
|
||||
}
|
||||
|
||||
$this->isGlobal = true;
|
||||
protected function getInboundEmailService()
|
||||
{
|
||||
if (!$this->serviceFactory) return null;
|
||||
|
||||
return $this;
|
||||
if (!$this->inboundEmailService) {
|
||||
$this->inboundEmailService = $this->serviceFactory->create('InboundEmail');
|
||||
}
|
||||
|
||||
return $this->inboundEmailService;
|
||||
}
|
||||
|
||||
public function send(Email $email, ?array $params = [], $message = null, $attachmentList = [])
|
||||
{
|
||||
if ($this->isGlobal) {
|
||||
$this->applyGlobal();
|
||||
}
|
||||
|
||||
if (!$message) {
|
||||
$message = new Message();
|
||||
}
|
||||
|
||||
@@ -159,6 +159,8 @@
|
||||
}
|
||||
},
|
||||
"tooltips": {
|
||||
"outboundEmailFromAddress": "The system email address.",
|
||||
"smtpServer": "If empty, then Group Email Account with the corresponding email address will be used.",
|
||||
"busyRangesEntityList": "What will be taken into account when showing busy time ranges in scheduler & timeline.",
|
||||
"massEmailVerp": "Variable envelope return path. For better handling of bounced messages. Make sure that your SMTP provider supports it.",
|
||||
"recordsPerPage": "Number of records initially displayed in list views.",
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
[
|
||||
{
|
||||
"label": "Configuration",
|
||||
"rows": [
|
||||
[{"name": "outboundEmailFromAddress"}, {"name": "outboundEmailIsShared"}],
|
||||
[{"name": "outboundEmailFromName"}, {"name": "outboundEmailBccAddress"}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "SMTP",
|
||||
"rows": [
|
||||
@@ -8,13 +15,6 @@
|
||||
[{"name": "smtpPassword"}, false]
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Configuration",
|
||||
"rows": [
|
||||
[{"name": "outboundEmailFromAddress"}, {"name": "outboundEmailIsShared"}],
|
||||
[{"name": "outboundEmailFromName"}, {"name": "outboundEmailBccAddress"}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Mass Email",
|
||||
"rows": [
|
||||
|
||||
@@ -6,6 +6,12 @@
|
||||
"smtpPassword": {
|
||||
"internal": true
|
||||
},
|
||||
"imapHandler": {
|
||||
"internal": true
|
||||
},
|
||||
"smtpHandler": {
|
||||
"internal": true
|
||||
},
|
||||
"fetchData": {
|
||||
"readOnly": true
|
||||
}
|
||||
|
||||
@@ -119,6 +119,14 @@
|
||||
"options": ["login", "crammd5", "plain"],
|
||||
"default": "login"
|
||||
},
|
||||
"imapHandler": {
|
||||
"type": "varchar",
|
||||
"readOnly": true
|
||||
},
|
||||
"smtpHandler": {
|
||||
"type": "varchar",
|
||||
"readOnly": true
|
||||
},
|
||||
"createdBy": {
|
||||
"type": "link",
|
||||
"readOnly": true
|
||||
|
||||
@@ -92,10 +92,12 @@
|
||||
"outboundEmailFromAddress": {
|
||||
"type": "varchar",
|
||||
"default": "crm@example.com",
|
||||
"trim": true
|
||||
"trim": true,
|
||||
"tooltip": true
|
||||
},
|
||||
"smtpServer": {
|
||||
"type": "varchar"
|
||||
"type": "varchar",
|
||||
"tooltip": true
|
||||
},
|
||||
"smtpPort": {
|
||||
"type": "int",
|
||||
|
||||
@@ -209,10 +209,6 @@ class Email extends Record
|
||||
$inboundEmail = $inboundEmailService->findSharedAccountForUser($this->getUser(), $originalFromAddress);
|
||||
if ($inboundEmail) {
|
||||
$smtpParams = $inboundEmailService->getSmtpParamsFromAccount($inboundEmail);
|
||||
|
||||
if ($inboundEmail->get('smtpHandler')) {
|
||||
$this->applyGroupSmtpHandler($inboundEmail, $smtpParams);
|
||||
}
|
||||
}
|
||||
if ($smtpParams) {
|
||||
$emailSender->useSmtp($smtpParams);
|
||||
@@ -316,29 +312,13 @@ class Email extends Record
|
||||
}
|
||||
if (method_exists($handler, 'applyParams')) {
|
||||
$handler->applyParams($userId, $emailAddress, $params);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function applyGroupSmtpHandler(\Espo\Entities\InboundEmail $inboundEmail, array &$params)
|
||||
{
|
||||
$handlerClassName = $inboundEmail->get('smtpHandler');
|
||||
if (!$handlerClassName) return;
|
||||
|
||||
try {
|
||||
$handler = $this->getInjection('injectableFactory')->createByClassName($handlerClassName);
|
||||
} catch (\Throwable $e) {
|
||||
$GLOBALS['log']->error(
|
||||
"Send Email: Could not create Smtp Handler for inbound email {$inboundEmail->id}. Error: " . $e->getMessage()
|
||||
);
|
||||
}
|
||||
if (method_exists($handler, 'applyParams')) {
|
||||
$handler->applyParams($inboundEmail->id, $params);
|
||||
}
|
||||
}
|
||||
|
||||
public function validateEmailAddresses(\Espo\Entities\Email $entity)
|
||||
{
|
||||
$from = $entity->get('from');
|
||||
@@ -865,7 +845,7 @@ class Email extends Record
|
||||
if (empty($smtpParams['auth'])) {
|
||||
unset($smtpParams['username']);
|
||||
unset($smtpParams['password']);
|
||||
unset($smtpParams['smtpAuthMechanism']);
|
||||
unset($smtpParams['authMechanism']);
|
||||
}
|
||||
|
||||
$userId = $data['userId'] ?? null;
|
||||
@@ -885,19 +865,26 @@ class Email extends Record
|
||||
'to' => $data['emailAddress'],
|
||||
]);
|
||||
|
||||
if ($userId) {
|
||||
if ($fromAddress) {
|
||||
$this->applySmtpHandler($userId, $fromAddress, $smtpParams);
|
||||
}
|
||||
}
|
||||
|
||||
$type = $data['type'] ?? null;
|
||||
$id = $data['id'] ?? null;
|
||||
|
||||
if ($type === 'emailAccount' && $id) {
|
||||
$emailAccount = $this->getEntityManager()->getEntity('EmailAccount', $id);
|
||||
if ($emailAccount && $emailAccount->get('smtpHandler')) {
|
||||
$this->getServiceFactory()->create('EmailAccount')->applySmtpHandler($emailAccount, $smtpParams);
|
||||
}
|
||||
}
|
||||
|
||||
if ($type === 'inboundEmail' && $id) {
|
||||
$inboundEmail = $this->getEntityManager()->getEntity('InboundEmail', $id);
|
||||
if ($inboundEmail && $inboundEmail->get('smtpHandler')) {
|
||||
$this->applyGroupSmtpHandler($inboundEmail, $smtpParams);
|
||||
$this->getServiceFactory()->create('InboundEmail')->applySmtpHandler($inboundEmail, $smtpParams);
|
||||
}
|
||||
}
|
||||
|
||||
if ($userId) {
|
||||
if ($fromAddress) {
|
||||
$this->applySmtpHandler($userId, $fromAddress, $smtpParams);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -496,13 +496,33 @@ class EmailAccount extends Record
|
||||
if ($emailAccount->get('smtpAuth')) {
|
||||
$smtpParams['username'] = $emailAccount->get('smtpUsername');
|
||||
$smtpParams['password'] = $emailAccount->get('smtpPassword');
|
||||
$smtpParams['smtpAuthMechanism'] = $emailAccount->get('smtpAuthMechanism');
|
||||
$smtpParams['authMechanism'] = $emailAccount->get('smtpAuthMechanism');
|
||||
}
|
||||
if (array_key_exists('password', $smtpParams)) {
|
||||
$smtpParams['password'] = $this->getCrypt()->decrypt($smtpParams['password']);
|
||||
}
|
||||
|
||||
$this->applySmtpHandler($emailAccount, $smtpParams);
|
||||
|
||||
return $smtpParams;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public function applySmtpHandler(\Espo\Entities\EmailAccount $emailAccount, array &$params)
|
||||
{
|
||||
$handlerClassName = $emailAccount->get('smtpHandler');
|
||||
if (!$handlerClassName) return;
|
||||
|
||||
try {
|
||||
$handler = $this->getInjection('injectableFactory')->createByClassName($handlerClassName);
|
||||
} catch (\Throwable $e) {
|
||||
$GLOBALS['log']->error(
|
||||
"EmailAccount: Could not create Smtp Handler for account {$emailAccount->id}. Error: " . $e->getMessage()
|
||||
);
|
||||
}
|
||||
if (method_exists($handler, 'applyParams')) {
|
||||
$handler->applyParams($emailAccount->id, $params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -962,7 +962,7 @@ class InboundEmail extends \Espo\Services\Record
|
||||
$smtpParams['password'] = $emailAccount->get('smtpPassword');
|
||||
|
||||
if ($emailAccount->get('smtpAuth')) {
|
||||
$smtpParams['smtpAuthMechanism'] = $emailAccount->get('smtpAuthMechanism');
|
||||
$smtpParams['authMechanism'] = $emailAccount->get('smtpAuthMechanism');
|
||||
}
|
||||
|
||||
if ($emailAccount->get('fromName')) {
|
||||
@@ -974,8 +974,28 @@ class InboundEmail extends \Espo\Services\Record
|
||||
if (array_key_exists('password', $smtpParams) && is_string($smtpParams['password'])) {
|
||||
$smtpParams['password'] = $this->getCrypt()->decrypt($smtpParams['password']);
|
||||
}
|
||||
|
||||
$this->applySmtpHandler($emailAccount, $smtpParams);
|
||||
|
||||
return $smtpParams;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public function applySmtpHandler(\Espo\Entities\InboundEmail $emailAccount, array &$params)
|
||||
{
|
||||
$handlerClassName = $emailAccount->get('smtpHandler');
|
||||
if (!$handlerClassName) return;
|
||||
|
||||
try {
|
||||
$handler = $this->getInjection('injectableFactory')->createByClassName($handlerClassName);
|
||||
} catch (\Throwable $e) {
|
||||
$GLOBALS['log']->error(
|
||||
"InboundEmail: Could not create Smtp Handler for account {$emailAccount->id}. Error: " . $e->getMessage()
|
||||
);
|
||||
}
|
||||
if (method_exists($handler, 'applyParams')) {
|
||||
$handler->applyParams($emailAccount->id, $params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
Espo.define('views/email-account/fields/test-send', 'views/outbound-email/fields/test-send', function (Dep) {
|
||||
define('views/email-account/fields/test-send', 'views/outbound-email/fields/test-send', function (Dep) {
|
||||
|
||||
return Dep.extend({
|
||||
|
||||
@@ -55,7 +55,7 @@ Espo.define('views/email-account/fields/test-send', 'views/outbound-email/fields
|
||||
'security': this.model.get('smtpSecurity'),
|
||||
'username': this.model.get('smtpUsername'),
|
||||
'password': this.model.get('smtpPassword') || null,
|
||||
'smtpAuthMechanism': this.model.get('smtpAuthMechanism'),
|
||||
'authMechanism': this.model.get('smtpAuthMechanism'),
|
||||
'fromName': this.getUser().get('name'),
|
||||
'fromAddress': this.model.get('emailAddress'),
|
||||
'type': 'emailAccount',
|
||||
@@ -63,7 +63,7 @@ Espo.define('views/email-account/fields/test-send', 'views/outbound-email/fields
|
||||
'userId': this.model.get('assignedUserId'),
|
||||
};
|
||||
return data;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user