From 9c44356d5afa5434dd7f43db514160fea4bfbdcc Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Mon, 31 May 2021 12:25:51 +0300 Subject: [PATCH] email account monitored folders as array --- .../metadata/entityDefs/EmailAccount.json | 9 ++- .../metadata/entityDefs/InboundEmail.json | 9 ++- application/Espo/Services/EmailAccount.php | 6 +- application/Espo/Services/InboundEmail.php | 6 +- .../src/views/email-account/fields/folders.js | 79 ++++++++++++++++--- .../src/views/inbound-email/fields/folders.js | 17 +--- upgrades/6.2/scripts/AfterUpgrade.php | 48 +++++++++++ 7 files changed, 132 insertions(+), 42 deletions(-) diff --git a/application/Espo/Resources/metadata/entityDefs/EmailAccount.json b/application/Espo/Resources/metadata/entityDefs/EmailAccount.json index 803f15eed9..a44cc72488 100644 --- a/application/Espo/Resources/metadata/entityDefs/EmailAccount.json +++ b/application/Espo/Resources/metadata/entityDefs/EmailAccount.json @@ -41,11 +41,12 @@ "type": "password" }, "monitoredFolders": { - "type": "varchar", - "default": "INBOX", + "type": "array", + "default": ["INBOX"], + "options": ["INBOX"], "view": "views/email-account/fields/folders", - "tooltip": true, - "maxLength": 1024 + "displayAsList": true, + "noEmptyString": true }, "sentFolder": { "type": "varchar", diff --git a/application/Espo/Resources/metadata/entityDefs/InboundEmail.json b/application/Espo/Resources/metadata/entityDefs/InboundEmail.json index f4723dde46..7e248de00a 100644 --- a/application/Espo/Resources/metadata/entityDefs/InboundEmail.json +++ b/application/Espo/Resources/metadata/entityDefs/InboundEmail.json @@ -40,11 +40,12 @@ "type": "password" }, "monitoredFolders": { - "type": "varchar", - "default": "INBOX", + "type": "array", + "default": ["INBOX"], + "options": ["INBOX"], "view": "views/inbound-email/fields/folders", - "tooltip": true, - "maxLength": 1024 + "displayAsList": true, + "noEmptyString": true }, "fetchSince": { "type": "date" diff --git a/application/Espo/Services/EmailAccount.php b/application/Espo/Services/EmailAccount.php index 93b0f58908..93e178d53e 100644 --- a/application/Espo/Services/EmailAccount.php +++ b/application/Espo/Services/EmailAccount.php @@ -367,12 +367,10 @@ class EmailAccount extends Record implements $monitoredFolders = $emailAccount->get('monitoredFolders'); if (empty($monitoredFolders)) { - throw new Error(); + throw new Error("No monitored folders for email account."); } - $monitoredFoldersArr = explode(',', $monitoredFolders); - - foreach ($monitoredFoldersArr as $folder) { + foreach ($monitoredFolders as $folder) { $folder = mb_convert_encoding(trim($folder), 'UTF7-IMAP', 'UTF-8'); $portionLimit = $this->getConfig()->get('personalEmailMaxPortionSize', self::PORTION_LIMIT); diff --git a/application/Espo/Services/InboundEmail.php b/application/Espo/Services/InboundEmail.php index 7b261b11fb..442ed8c885 100644 --- a/application/Espo/Services/InboundEmail.php +++ b/application/Espo/Services/InboundEmail.php @@ -255,12 +255,10 @@ class InboundEmail extends RecordService implements $monitoredFolders = $emailAccount->get('monitoredFolders'); if (empty($monitoredFolders)) { - $monitoredFolders = 'INBOX'; + $monitoredFolders = ['INBOX']; } - $monitoredFoldersArr = explode(',', $monitoredFolders); - - foreach ($monitoredFoldersArr as $folder) { + foreach ($monitoredFolders as $folder) { $folder = mb_convert_encoding(trim($folder), 'UTF7-IMAP', 'UTF-8'); $portionLimit = $this->config->get('inboundEmailMaxPortionSize', self::PORTION_LIMIT); diff --git a/client/src/views/email-account/fields/folders.js b/client/src/views/email-account/fields/folders.js index 05ba7473ff..29d76bcd28 100644 --- a/client/src/views/email-account/fields/folders.js +++ b/client/src/views/email-account/fields/folders.js @@ -26,24 +26,81 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/email-account/fields/folders', 'views/email-account/fields/folder', function (Dep) { +define('views/email-account/fields/folders', 'views/fields/array', function (Dep) { return Dep.extend({ - addFolder: function (folder) { - var value = this.$element.val(); + getFoldersUrl: 'EmailAccount/action/getFolders', - var folders = []; + fetchFolders: function () { + return new Promise(function (resolve) { + var data = { + host: this.model.get('host'), + port: this.model.get('port'), + security: this.model.get('security'), + username: this.model.get('username'), + emailAddress: this.model.get('emailAddress'), + userId: this.model.get('assignedUserId'), + }; - if (value != '') { - folders = value.split(','); - } + if (this.model.has('password')) { + data.password = this.model.get('password'); + } + else { + if (!this.model.isNew()) { + data.id = this.model.id; + } + } - if (!~folders.indexOf(folder)) { - folders.push(folder); - } + Espo.Ajax.postRequest(this.getFoldersUrl, data) + .then( + function (folders) { + resolve(folders); + }.bind(this) + ) + .fail( + function (xhr) { + Espo.Ui.error(this.translate('couldNotConnectToImap', 'messages', 'EmailAccount')); + + xhr.errorIsHandled = true; + + resolve(["INBOX"]); + }.bind(this) + ); + }.bind(this)); + }, + + actionAddItem: function () { + Espo.Ui.notify(this.translate('loading', 'messages')); + + this.fetchFolders() + .then( + function (options) { + Espo.Ui.notify(false); + + this.createView( 'addModal', this.addItemModalView, {options: options}) + .then( + function (view) { + view.render(); + + view.once('add', function (item) { + this.addValue(item); + + view.close(); + }.bind(this)); + + view.once('add-mass', function (items) { + items.forEach(function (item) { + this.addValue(item); + }.bind(this)); + + view.close(); + }.bind(this)); + }.bind(this) + ); + }.bind(this) + ); - this.$element.val(folders.join(',')); }, }); }); diff --git a/client/src/views/inbound-email/fields/folders.js b/client/src/views/inbound-email/fields/folders.js index 0543ceb713..46a29bed4f 100644 --- a/client/src/views/inbound-email/fields/folders.js +++ b/client/src/views/inbound-email/fields/folders.js @@ -26,24 +26,11 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/inbound-email/fields/folders', 'views/inbound-email/fields/folder', function (Dep) { +define('views/inbound-email/fields/folders', 'views/email-account/fields/folders', function (Dep) { return Dep.extend({ - addFolder: function (folder) { - var value = this.$element.val(); + getFoldersUrl: 'InboundEmail/action/getFolders', - var folders = []; - - if (value != '') { - folders = value.split(','); - } - - if (!~folders.indexOf(folder)) { - folders.push(folder); - } - - this.$element.val(folders.join(',')); - }, }); }); diff --git a/upgrades/6.2/scripts/AfterUpgrade.php b/upgrades/6.2/scripts/AfterUpgrade.php index 5a310bde36..d7d19a5b3a 100644 --- a/upgrades/6.2/scripts/AfterUpgrade.php +++ b/upgrades/6.2/scripts/AfterUpgrade.php @@ -32,6 +32,8 @@ use Espo\Core\Utils\Metadata; use Espo\Core\Utils\File\Manager as FileManager; use Espo\Core\Utils\Json; +use Espo\ORM\EntityManager; + class AfterUpgrade { public function run(Container $container): void @@ -43,6 +45,9 @@ class AfterUpgrade $this->updateEventMetadata($container->get('metadata'), $container->get('fileManager')); $this->updatePersonMetadata($container->get('metadata'), $container->get('fileManager')); $this->updateCompanyMetadata($container->get('metadata'), $container->get('fileManager')); + + $this->migrateEmailAccountFolders('EmailAccount', $container->get('entityManager')); + $this->migrateEmailAccountFolders('InboundEmail', $container->get('entityManager')); } protected function updateTemplates($entityManager) @@ -160,4 +165,47 @@ class AfterUpgrade $metadata->save(); } } + + private function migrateEmailAccountFolders(string $entityType, EntityManager $entityManager): void + { + $selectQuery = $entityManager->getQueryBuilder() + ->select() + ->from($entityType) + ->select(['id', 'monitoredFolders']) + ->build(); + + $sth = $entityManager->getQueryExecutor()->execute($selectQuery); + + $dataList = []; + + while ($row = $sth->fetch()) { + $dataList[] = [ + 'id' => $row['id'], + 'folders' => $row['monitoredFolders'] ?? '', + ]; + } + + foreach ($dataList as $item) { + $id = $item['id']; + $foldersString = $item['folders']; + + $folders = array_map( + function (string $item): string { + return trim($item); + }, + explode(',', $foldersString) + ); + + $foldersJsonString = json_encode($folders); + + $updateQuery = $entityManager->getQueryBuilder() + ->update() + ->in($entityType) + ->set(['monitoredFolders' => $foldersJsonString]) + ->where(['id' => $id]) + ->build(); + + $entityManager->getQueryExecutor()->execute($updateQuery); + } + } }