email sending changes

This commit is contained in:
Yuri Kuznetsov
2020-03-30 16:15:22 +03:00
parent ff627dd7dc
commit 068eff9c94
11 changed files with 172 additions and 81 deletions
+2 -1
View File
@@ -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')
);
}
}
+81 -36
View File
@@ -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",
+16 -29
View File
@@ -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);
}
}
+21 -1
View File
@@ -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);
}
}
}
+21 -1
View File
@@ -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;
}
});
},
});
});