mirror of
https://github.com/espocrm/espocrm.git
synced 2026-06-28 23:16:03 +00:00
email account 5
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 . '"'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -91,6 +91,7 @@ return array (
|
||||
'disableExport' => false,
|
||||
'assignmentEmailNotifications' => false,
|
||||
'assignmentEmailNotificationsEntityList' => array('Lead', 'Opportunity', 'Task', 'Case'),
|
||||
'emailMessageMaxSize' => 10,
|
||||
'isInstalled' => false,
|
||||
);
|
||||
|
||||
|
||||
@@ -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"}
|
||||
]
|
||||
]
|
||||
},
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
"selectTemplate": "Select Template",
|
||||
"fromEmailAddress": "From Address",
|
||||
"toEmailAddresses": "To Address",
|
||||
"emailAddress": "Email Address"
|
||||
"emailAddress": "Email Address",
|
||||
"deliveryDate": "Delivery Date"
|
||||
},
|
||||
"links": {
|
||||
},
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
"password": "Password",
|
||||
"port": "Port",
|
||||
"monitoredFolders": "Monitored Folders",
|
||||
"ssl": "SSL"
|
||||
"ssl": "SSL",
|
||||
"fetchSince": "Fetch Since"
|
||||
},
|
||||
"links": {
|
||||
},
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
[
|
||||
{"name":"name"},
|
||||
{"name":"status"}
|
||||
],
|
||||
[
|
||||
{"name":"fetchSince"}
|
||||
]
|
||||
]
|
||||
},
|
||||
|
||||
@@ -105,6 +105,10 @@
|
||||
"dateSent": {
|
||||
"type": "datetime"
|
||||
},
|
||||
"deliveryDate": {
|
||||
"type": "datetime",
|
||||
"readOnly": true
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "datetime",
|
||||
"readOnly": true
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user