This commit is contained in:
yuri
2015-09-09 17:03:37 +03:00
parent 81335454fd
commit 62eb54d853
10 changed files with 351 additions and 27 deletions
+5 -1
View File
@@ -131,7 +131,7 @@ class Sender
return $this;
}
public function send(Email $email, $params = array(), &$message = null)
public function send(Email $email, $params = array(), &$message = null, $attachmetList = [])
{
$message = new Message();
$config = $this->config;
@@ -220,6 +220,10 @@ class Sender
$attachmentCollection = $email->get('attachments');
$attachmentInlineCollection = $email->getInlineAttachments();
foreach ($attachmetList as $attachment) {
$attachmentCollection[] = $attachment;
}
if (!empty($attachmentCollection)) {
foreach ($attachmentCollection as $a) {
$fileName = 'data/upload/' . $a->id;
@@ -0,0 +1,28 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://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/.
************************************************************************/
namespace Espo\Modules\Crm\Entities;
class EmailQueueItem extends \Espo\Core\ORM\Entity
{
}
@@ -0,0 +1,59 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://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/.
************************************************************************/
namespace Espo\Modules\Crm\Jobs;
use \Espo\Core\Exceptions;
class ProcessMassEmail extends \Espo\Core\Jobs\Base
{
public function run()
{
$service = $this->getServiceFactory()->create('MassEmail');
$massEmailList = $this->getEntityManager()->getRepository('MassEmail')->where(array(
'status' => 'Pending',
'startAt<=' => date('Y-m-d H:i:s')
))->find();
foreach ($massEmailList as $massEmail) {
try {
$service->createQueue($massEmail);
} catch (\Exception $e) {
$GLOBALS['log']->error('Job ProcessMassEmail#createQueue '.$massEmail->id.': [' . $e->getCode() . '] ' .$e->getMessage());
}
}
$massEmailList = $this->getEntityManager()->getRepository('MassEmail')->where(array(
'status' => 'In Process'
))->find();
foreach ($massEmailList as $massEmail) {
try {
$service->processSending($massEmail);
} catch (\Exception $e) {
$GLOBALS['log']->error('Job ProcessMassEmail#processSending '.$massEmail->id.': [' . $e->getCode() . '] ' .$e->getMessage());
}
}
return true;
}
}
@@ -26,7 +26,8 @@
"Pending": "Pending",
"In Process": "In Process",
"Complete": "Complete",
"Canceled": "Canceled"
"Canceled": "Canceled",
"Failed": "Failed"
}
},
"labels": {
@@ -0,0 +1,7 @@
{
"options": {
"job": {
"ProcessMassEmail": "Send Mass Emails"
}
}
}
@@ -15,7 +15,7 @@
"default": 0
},
"target": {
"type": "linkTarget",
"type": "linkParent",
"readOnly": true
},
"sentAt": {
@@ -28,6 +28,18 @@ use \Espo\ORM\Entity;
class MassEmail extends \Espo\Services\Record
{
const MAX_ATTEMPT_COUNT = 3;
protected function init()
{
$this->dependencies[] = 'container';
}
protected function getMailSender()
{
return $this->getInjection('container')->get('mailSender');
}
protected function beforeCreate(Entity $entity, array $data = array())
{
parent::beforeCreate($entity, $data);
@@ -35,5 +47,200 @@ class MassEmail extends \Espo\Services\Record
throw new Forbidden();
}
}
public function createQueue(Entity $massEmail)
{
$existingQueueItemList = $this->getEntityManager()->getRepository('EmailQueueItem')->where(array(
'status' => ['Pending', 'Failed'],
'massEmailId' => $massEmail->id
))->find();
foreach ($existingQueueItemList as $existingQueueItem) {
$this->getEntityManager()->getMapper('RDB')->deleteFromDb('EmailQueueItem', $existingQueueItem->id);
}
$targetHash = array();
$entityList = [];
$targetListCollection = $massEmail->get('targetLists');
foreach ($targetListCollection as $targetList) {
$accountList = $targetList->get('accounts');
foreach ($accountList as $account) {
$hashId = $account->getEntityType() . '-'. $account->id;
if (!empty($targetHash[$hashId])) {
continue;
}
$entityList[] = $account;
$targetHash[$hashId] = true;
}
$contactList = $targetList->get('contacts');
foreach ($contactList as $contact) {
$hashId = $contact->getEntityType() . '-'. $contact->id;
if (!empty($targetHash[$hashId])) {
continue;
}
$entityList[] = $contact;
$targetHash[$hashId] = true;
}
$leadList = $targetList->get('leads');
foreach ($leadList as $lead) {
$hashId = $lead->getEntityType() . '-'. $lead->id;
if (!empty($targetHash[$hashId])) {
continue;
}
$entityList[] = $lead;
$targetHash[$hashId] = true;
}
$userList = $targetList->get('users');
foreach ($userList as $user) {
$hashId = $user->getEntityType() . '-'. $user->id;
if (!empty($targetHash[$hashId])) {
continue;
}
$entityList[] = $user;
$targetHash[$hashId] = true;
}
}
foreach ($entityList as $target) {
$queueItem = $this->getEntityManager()->getEntity('EmailQueueItem');
$queueItem->set(array(
'massEmailId' => $massEmail->id,
'status' => 'Pending',
'targetId' => $target->id,
'targetType' => $target->getEntityType()
));
$this->getEntityManager()->saveEntity($queueItem);
}
$massEmail->set('status', 'In Process');
if (empty($entityList)) {
$massEmail->set('status', 'Complete');
}
$this->getEntityManager()->saveEntity($massEmail);
}
protected function setFailed(Entity $massEmail)
{
$massEmail->set('status', 'Failed');
$this->getEntityManager()->saveEntity($massEmail);
$queueItemList = $this->getEntityManager()->getRepository('EmailQueueItem')->where(array(
'status' => 'Pending',
'massEmailId' => $massEmail->id
))->find();
foreach ($queueItemList as $queueItem) {
$queueItem->set('status', 'Failed');
$this->getEntityManager()->saveEntity($queueItem);
}
}
public function processSending(Entity $massEmail)
{
$queueItemList = $this->getEntityManager()->getRepository('EmailQueueItem')->where(array(
'status' => 'Pending',
'massEmailId' => $massEmail->id
))->find();
$templateId = $massEmail->get('emailTemplateId');
if (!$templateId) {
$this->setFailed($massEmail);
return;
}
$emailTemplate = $this->getEntityManager()->getEntity('EmailTemplate', $templateId);
if (!$emailTemplate) {
$this->setFailed($massEmail);
return;
}
$attachmetList = $emailTemplate->get('attachmets');
foreach ($queueItemList as $queueItem) {
$this->sendQueueItem($queueItem, $massEmail, $emailTemplate, $attachmetList);
}
$countLeft = $this->getEntityManager()->getRepository('EmailQueueItem')->where(array(
'status' => 'Pending',
'massEmailId' => $massEmail->id
))->count();
if ($countLeft == 0) {
$massEmail->set('status', 'Complete');
$this->getEntityManager()->saveEntity($massEmail);
}
}
protected function sendQueueItem(Entity $queueItem, Entity $massEmail, Entity $emailTemplate, $attachmetList = [])
{
$target = $this->getEntityManager()->getEntity($queueItem->get('targetType'), $queueItem->get('targetId'));
if (!$target || !$target->id || !$target->get('emailAddress')) {
$queueItem->set('status', 'Failed');
$this->getEntityManager()->saveEntity($queueItem);
return;
}
$templateParams = array(
'parent' => $target
);
$emailData = $this->getEmailTemplateService()->parseTemplate($emailTemplate, $templateParams);
print_r($emailData);
return;
$email = $this->getEntityManager()->getEntity('Email');
$email->set($emailData);
$emailAddress = $target->get('emailAddress');
if (empty($emailAddress)) {
return false;
}
$email->set('to', $emailAddress);
$params = array();
if ($massEmail->get('fromAddress')) {
$email->set('from', $massEmail->get('fromAddress'));
}
if ($massEmail->get('replyToAddress')) {
$email->set('replyToAddress', $massEmail->get('replyToAddress'));
}
if ($massEmail->get('fromName')) {
$params['fromName'] = $massEmail->get('fromName');
}
if ($massEmail->get('replyToName')) {
$params['replyToName'] = $massEmail->get('replyToName');
}
try {
$attemptCount = $queueItem->get('attemptCount');
$attemptCount++;
$queueItem->set('attemptCount', $attemptCount);
$message = false;
$this->getMailSender()->useGlobal()->send($email, $params, $message, $attachmetList);
$queueItem->set('status', 'Sent');
$queueItem->set('sentAt', date('Y-m-d H:i:s'));
$this->getEntityManager()->saveEntity($queueItem);
} catch (\Exception $e) {
if ($queueItem->get('attemptCount') >= self::MAX_ATTEMPT_COUNT) {
$queueItem->set('status', 'Failed');
}
$this->getEntityManager()->saveEntity($queueItem);
$GLOBALS['log']->error('MassEmail#sendQueueItem: [' . $e->getCode() . '] ' .$e->getMessage());
return false;
}
return true;
}
protected function getEmailTemplateService()
{
if (!$this->emailTemplateService) {
$this->emailTemplateService = $this->getServiceFactory()->create('EmailTemplate');
}
return $this->emailTemplateService;
}
}
+1 -1
View File
@@ -95,7 +95,7 @@ class EntityManager
protected function getMapperClassName($name)
{
$className = null;
switch ($name) {
case 'RDB':
$platform = $this->params['platform'];
+35 -23
View File
@@ -48,20 +48,15 @@ class EmailTemplate extends Record
return $this->injections['dateTime'];
}
public function parse($id, array $params = array(), $copyAttachments = false)
public function parseTemplate(Entity $emailTemplate, array $params = array(), $copyAttachments = false)
{
$emailTemplate = $this->getEntity($id);
if (empty($emailTemplate)) {
throw new NotFound();
}
$entityList = array();
$entityHash = array();
if (!empty($params['entityHash']) && is_array($params['entityHash'])) {
$entityList = $params['entityHash'];
$entityHash = $params['entityHash'];
}
if (!isset($entityList['User'])) {
$entityList['User'] = $this->getUser();
if (!isset($entityHash['User'])) {
$entityHash['User'] = $this->getUser();
}
if (!empty($params['emailAddress'])) {
@@ -73,33 +68,40 @@ class EmailTemplate extends Record
if ($entity) {
if ($entity instanceof Person) {
$entityList['Person'] = $entity;
$entityHash['Person'] = $entity;
}
if (empty($entityList[$entity->getEntityType()])) {
$entityList[$entity->getEntityType()] = $entity;
if (empty($entityHash[$entity->getEntityType()])) {
$entityHash[$entity->getEntityType()] = $entity;
}
}
}
if (!empty($params['parentId']) && !empty($params['parentType'])) {
$parent = $this->getEntityManager()->getEntity($params['parentType'], $params['parentId']);
if (!empty($parent)) {
$entityList[$params['parentType']] = $parent;
$entityList['Parent'] = $parent;
if (empty($entityList['Person']) && ($parent instanceof Person)) {
$entityList['Person'] = $parent;
if (empty($params['parent'])) {
if (!empty($params['parentId']) && !empty($params['parentType'])) {
$parent = $this->getEntityManager()->getEntity($params['parentType'], $params['parentId']);
if ($parent) {
$params['parent'] = $parent;
}
}
}
if (!empty($params['parent'])) {
$parent = $params['parent'];
$entityHash[$parent->getEntityType()] = $parent;
$entityHash['Parent'] = $parent;
if (empty($entityHash['Person']) && ($parent instanceof Person)) {
$entityHash['Person'] = $parent;
}
}
$subject = $emailTemplate->get('subject');
$body = $emailTemplate->get('body');
foreach ($entityList as $type => $entity) {
foreach ($entityHash as $type => $entity) {
$subject = $this->parseText($type, $entity, $subject);
}
foreach ($entityList as $type => $entity) {
foreach ($entityHash as $type => $entity) {
$body = $this->parseText($type, $entity, $body);
}
@@ -139,6 +141,16 @@ class EmailTemplate extends Record
);
}
public function parse($id, array $params = array(), $copyAttachments = false)
{
$emailTemplate = $this->getEntity($id);
if (empty($emailTemplate)) {
throw new NotFound();
}
return $this->parseTemplate($emailTemplate, $params, $copyAttachments);
}
protected function parseText($type, Entity $entity, $text)
{
$fieldList = array_keys($entity->getFields());
+6
View File
@@ -54,6 +54,12 @@ return array(
'status' => 'Active',
'scheduling' => '1 1 * * 0',
),
4 => array(
'name' => 'Send Mass Emails',
'job' => 'ProcessMassEmail',
'status' => 'Active',
'scheduling' => '0 2-5 * * *',
),
),
);