email account 5

This commit is contained in:
Yuri Kuznetsov
2014-08-28 17:15:44 +03:00
parent 1853f4f113
commit e1355acda1
13 changed files with 197 additions and 85 deletions

View File

@@ -8,9 +8,12 @@ class Importer
{
private $entityManager;
public function __construct($entityManager)
private $fileManager;
public function __construct($entityManager, $fileManager)
{
$this->entityManager = $entityManager;
$this->fileManager = $fileManager;
}
protected function getEntityManager()
@@ -18,6 +21,11 @@ class Importer
return $this->entityManager;
}
protected function getFileManager()
{
return $this->fileManager;
}
public function importMessage($message, $userId, $teamsIds = array())
{
try {
@@ -49,10 +57,19 @@ class Importer
return false;
}
$dt = new \DateTime($message->date);
if ($dt) {
$dateSent = $dt->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i:s');
$email->set('dateSent', $dateSent);
if (isset($message->date)) {
$dt = new \DateTime($message->date);
if ($dt) {
$dateSent = $dt->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i:s');
$email->set('dateSent', $dateSent);
}
}
if (isset($message->deliveryDate)) {
$dt = new \DateTime($message->deliveryDate);
if ($dt) {
$deliveryDate = $dt->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i:s');
$email->set('deliveryDate', $deliveryDate);
}
}
$inlineIds = array();
@@ -111,8 +128,6 @@ class Importer
$type = strtok($part->contentType, ';');
$encoding = null;
// TODO do not import if size exceeds limit
switch ($type) {
case 'text/plain':
$content = $this->getContentFromPart($part);
@@ -153,17 +168,23 @@ class Importer
$attachment = $this->getEntityManager()->getEntity('Attachment');
$attachment->set('name', $fileName);
$attachment->set('type', $type);
$attachment->set('role', 'Inline Attachment');
$this->getEntityManager()->saveEntity($attachment);
$path = 'data/upload/' . $attachment->id;
if ($disposition == 'inline') {
$attachment->set('role', 'Inline Attachment');
} else {
$attachment->set('role', 'Attachment');
}
if ($encoding == 'base64') {
$content = base64_decode($content);
}
// TODO store size
$this->getFileManager()->putContents($path, $content);
$attachment->set('size', strlen($content));
$this->getEntityManager()->saveEntity($attachment);
$path = 'data/upload/' . $attachment->id;
$this->getFileManager()->putContents($path, $content);
if ($disposition == 'attachment') {
$attachmentsIds = $email->get('attachmentsIds');
@@ -173,9 +194,7 @@ class Importer
$inlineIds[$contentId] = $attachment->id;
}
}
} catch (\Exception $e){
// TODO log
}
} catch (\Exception $e) {}
}
protected function getContentFromPart($part)

View File

@@ -256,6 +256,12 @@ class Sender
try {
$this->transport->send($message);
$headers = $message->getHeaders();
if ($headers->has('messageId')) {
$email->set('messageId', $headers->get('messageId')->getId());
}
$email->set('status', 'Sent');
$email->set('dateSent', date("Y-m-d H:i:s"));
} catch (\Exception $e) {

View File

@@ -6,8 +6,14 @@ class Imap extends \Zend\Mail\Storage\Imap
{
public function getIdsFromUID($uid)
{
$uid = intval($lastUID) + 1;
$uid = intval($uid) + 1;
return $this->protocol->search(array('UID ' . $uid . ':*'));
}
public function getIdsFromDate($date)
{
return $this->protocol->search(array('SINCE "' . $date . '"'));
}
}

View File

@@ -91,6 +91,7 @@ return array (
'disableExport' => false,
'assignmentEmailNotifications' => false,
'assignmentEmailNotificationsEntityList' => array('Lead', 'Opportunity', 'Task', 'Case'),
'emailMessageMaxSize' => 10,
'isInstalled' => false,
);

View File

@@ -22,13 +22,10 @@
{"name":"host"},{"name":"ssl"}
],
[
{"name":"port"},false
{"name":"port"},{"name":"username"}
],
[
{"name":"monitoredFolders"},{"name":"username"}
],
[
{"name":"trashFolder"},{"name":"password"}
{"name":"monitoredFolders"},{"name":"password"}
]
]
},

View File

@@ -33,10 +33,9 @@
"default": "INBOX",
"view": "Crm:InboundEmail.Fields.Folders"
},
"trashFolder": {
"type": "varchar",
"required": true,
"view": "Crm:InboundEmail.Fields.Folder"
"fetchData": {
"type": "text",
"readOnly": true
},
"assignToUser": {
"type": "link",

View File

@@ -72,17 +72,7 @@ class InboundEmail extends \Espo\Services\Record
protected function getMailSender()
{
return $this->injections['mailSender'];
}
protected function findFolder($storage, $path)
{
$arr = explode('/', $path);
$pointer = $storage->getFolders();
foreach ($arr as $folderName) {
$pointer = $pointer->$folderName;
}
return $pointer;
}
}
public function getFolders($params)
{
@@ -123,7 +113,9 @@ class InboundEmail extends \Espo\Services\Record
throw new Error();
}
$importer = new \Espo\Core\Mail\Importer($this->getEntityManager());
$importer = new \Espo\Core\Mail\Importer($this->getEntityManager(), $this->getFileManager());
$maxSize = $this->getConfig()->get('emailMessageMaxSize');
$teamId = $inboundEmail->get('teamId');
$userId = $this->getUser()->id;
@@ -131,6 +123,17 @@ class InboundEmail extends \Espo\Services\Record
$userId = $inboundEmail->get('assignToUserId');
}
$fetchData = json_decode($inboundEmail->get('fetchData'), true);
if (empty($fetchData)) {
$fetchData = array();
}
if (!array_key_exists('lastUID', $fetchData)) {
$fetchData['lastUID'] = array();
}
if (!array_key_exists('lastUID', $fetchData)) {
$fetchData['lastDate'] = array();
}
$imapParams = array(
'host' => $inboundEmail->get('host'),
'port' => $inboundEmail->get('port'),
@@ -142,18 +145,7 @@ class InboundEmail extends \Espo\Services\Record
$imapParams['ssl'] = 'SSL';
}
$storage = new \Zend\Mail\Storage\Imap($imapParams);
$trash = null;
$trashFolder = $inboundEmail->get('trashFolder');
if (empty($trashFolder)) {
$trashFolder = 'INBOX.Trash';
}
try {
$trash = $this->findFolder($storage, $trashFolder);
} catch (\Exception $e) {
throw new Error("No trash folder '{$trashFolder}' found for Inbound Email {$id}");
}
$storage = new \Espo\Core\Mail\Storage\Imap($imapParams);
$monitoredFolders = $inboundEmail->get('monitoredFolders');
if (empty($monitoredFolders)) {
@@ -161,15 +153,41 @@ class InboundEmail extends \Espo\Services\Record
}
$monitoredFoldersArr = explode(',', $monitoredFolders);
foreach ($monitoredFoldersArr as $path) {
$toRemove = array();
$path = trim($path);
foreach ($monitoredFoldersArr as $folder) {
$folder = trim($folder);
$storage->selectFolder($folder);
$folder = $this->findFolder($storage, $path);
$storage->selectFolder($folder);
$lastUID = 0;
$lastDate = 0;
if (!empty($fetchData['lastUID'][$folder])) {
$lastUID = $fetchData['lastUID'][$folder];
}
if (!empty($fetchData['lastDate'][$folder])) {
$lastDate = $fetchData['lastDate'][$folder];
}
$ids = $storage->getIdsFromUID($lastUID);
if ((count($ids) == 1) && !empty($lastUID)) {
if ($storage->getUniqueId($ids[0]) == $lastUID) {
continue;
}
}
$k = 0;
foreach ($ids as $i => $id) {
if ($k == count($ids) - 1) {
$lastUID = $storage->getUniqueId($id);
}
if ($maxSize) {
if ($storage->getSize($id) > $maxSize * 1024 * 1024) {
continue;
}
}
$message = $storage->getMessage($id);
$k = 0;
foreach ($storage as $number => $message) {
$email = $importer->importMessage($message, $userId, array($teamId));
if ($email) {
@@ -183,19 +201,30 @@ class InboundEmail extends \Espo\Services\Record
}
}
if ($k == count($ids) - 1) {
if ($message) {
$dt = new \DateTime($message->date);
if ($dt) {
$dateSent = $dt->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i:s');
$lastDate = $dateSent;
}
}
}
if ($k == self::PORTION_LIMIT - 1) {
$lastUID = $storage->getUniqueId($id);
break;
}
$k++;
}
if ($trash) {
while ($k) {
$storage->moveMessage(1, $trash);
$k--;
}
}
$fetchData['lastUID'][$folder] = $lastUID;
$fetchData['lastDate'][$folder] = $lastDate;
$inboundEmail->set('fetchData', json_encode($fetchData));
$this->getEntityManager()->saveEntity($inboundEmail);
}
return true;
}

View File

@@ -15,7 +15,8 @@
"selectTemplate": "Select Template",
"fromEmailAddress": "From Address",
"toEmailAddresses": "To Address",
"emailAddress": "Email Address"
"emailAddress": "Email Address",
"deliveryDate": "Delivery Date"
},
"links": {
},

View File

@@ -7,7 +7,8 @@
"password": "Password",
"port": "Port",
"monitoredFolders": "Monitored Folders",
"ssl": "SSL"
"ssl": "SSL",
"fetchSince": "Fetch Since"
},
"links": {
},

View File

@@ -5,6 +5,9 @@
[
{"name":"name"},
{"name":"status"}
],
[
{"name":"fetchSince"}
]
]
},

View File

@@ -105,6 +105,10 @@
"dateSent": {
"type": "datetime"
},
"deliveryDate": {
"type": "datetime",
"readOnly": true
},
"createdAt": {
"type": "datetime",
"readOnly": true

View File

@@ -33,8 +33,13 @@
"default": "INBOX",
"view": "EmailAccount.Fields.Folders"
},
"fetchSince": {
"type": "date",
"required": true
},
"fetchData": {
"type": "text"
"type": "text",
"readOnly": true
},
"createdAt": {
"type": "datetime",

View File

@@ -35,6 +35,16 @@ class EmailAccount extends Record
const PORTION_LIMIT = 10;
protected function init()
{
$this->dependencies[] = 'fileManager';
}
protected function getFileManager()
{
return $this->injections['fileManager'];
}
public function getFolders($params)
{
$password = $params['password'];
@@ -74,7 +84,9 @@ class EmailAccount extends Record
throw new Error();
}
$importer = new \Espo\Core\Mail\Importer($this->getEntityManager());
$importer = new \Espo\Core\Mail\Importer($this->getEntityManager(), $this->getFileManager());
$maxSize = $this->getConfig()->get('emailMessageMaxSize');
$user = $this->getEntityManager()->getEntity('User', $emailAccount->get('assignedUserId'));
@@ -83,11 +95,11 @@ class EmailAccount extends Record
}
$userId = $user->id;
$teamId = $user->get('defaultTeam');
$teamId = $user->get('defaultTeam');
$fetchData = json_decode($emailAccount->get('fetchData'), true);
if (empty($fetchData)) {
$fetchData = array();
$fetchData = array();
}
if (!array_key_exists('lastUID', $fetchData)) {
$fetchData['lastUID'] = array();
@@ -107,7 +119,7 @@ class EmailAccount extends Record
$imapParams['ssl'] = 'SSL';
}
$storage = new \Espo\Core\Mail\Storage\Imap($imapParams);
$storage = new \Espo\Core\Mail\Storage\Imap($imapParams);
$monitoredFolders = $emailAccount->get('monitoredFolders');
if (empty($monitoredFolders)) {
@@ -116,12 +128,9 @@ class EmailAccount extends Record
$monitoredFoldersArr = explode(',', $monitoredFolders);
foreach ($monitoredFoldersArr as $folder) {
$folder = trim($folder);
$folder = trim($folder);
$storage->selectFolder($folder);
// TODO fetch from last date
$lastUID = 0;
$lastDate = 0;
if (!empty($fetchData['lastUID'][$folder])) {
@@ -131,26 +140,58 @@ class EmailAccount extends Record
$lastDate = $fetchData['lastDate'][$folder];
}
$ids = $storage->getIdsFromUID();
if (!empty($lastUID)) {
$ids = $storage->getIdsFromUID($lastUID);
} else {
$dt = new \DateTime($emailAccount->get('fetchSince'));
if ($dt) {
$ids = $storage->getIdsFromDate($dt->format('d-M-Y'));
} else {
return false;
}
}
$k = 0;
foreach ($ids as $i => $id) {
$message = $storage->getMessage($id);
if ((count($ids) == 1) && !empty($lastUID)) {
if ($storage->getUniqueId($ids[0]) == $lastUID) {
continue;
}
}
$k = 0;
foreach ($ids as $i => $id) {
if ($k == count($ids) - 1) {
$lastUID = $storage->getUniqueId($id);
}
if ($maxSize) {
if ($storage->getSize($id) > $maxSize * 1024 * 1024) {
continue;
}
}
$message = $storage->getMessage($id);
$importer->importMessage($message, $userId, array($teamId));
$email = $importer->importMessage($message, $userId, array($teamId));
if ($k == count($ids) - 1) {
$lastUID = $storage->getUniqueId($id);
$lastDate = $message->date;
if ($message) {
$dt = new \DateTime($message->date);
if ($dt) {
$dateSent = $dt->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i:s');
$lastDate = $dateSent;
}
}
}
if ($k == self::PORTION_LIMIT - 1) {
$lastUID = $storage->getUniqueId($id);
break;
}
$k++;
}
$fetchData['lastUID'][$folder] = $lastUID;
$fetchData['lastDate'][$folder] = $lastDate;