SuiteCRM-Core/include/Imap/Imap2Handler.php

1325 lines
35 KiB
PHP
Raw Normal View History

Squashed 'public/legacy/' changes from 60ccef0448..81ce7933fd 81ce7933fd SuiteCRM 7.13.0 Release 595d2bd92b Fix saveDropDown getting called statically a70c5d1b99 Fix message deletion after auto import f57b5ede02 Fix Inbound Email allow_outbound_group_usage filtering 9d38016f59 Remove external_oauth_providers config d5b4f0025c Remove provider field from ExternalOAuthConnection d457827c7d Change ExternalOAuthProvider to use open visibility by default for group records 3a51437d3a Add null check b49d6b79a0 Fix Inbound email tests 277f2c91cb Set default on inbound emails 261dae81c1 Add group to OutboundEmailAccounts menu 3e9dbdd5de Fix ExternalOAuthConnection list view pagination and checkboxes 36cbb6a90c Fix ExternalOAuthProvider list view pagination and checkboxes fe5f0a10d6 Fix OutboundEmailAccounts list view pagination and checkboxes b9217a36e2 Fix InboundEmail list view pagination and checkboxes 83bd0024a6 Allow selecting group InboundEmails in folder management f6a9111b25 Fix inbound email relationship definition 07b3110f8a Filter listview email displayed accounts according to preferences 6c49df527a Remove code that auto-selects a group email none is selected 243a0276af Fix preferences mail folder management dropdown e7838f0bd4 Fix owner field definition in OutboundEmailAccounts db9a52a27d Fix bounce mailbox type not being properly set 14d43e1efa Fix compose emails not sending f9e3677db8 Add optional connection string to InboundEmail module cef8b2bdb6 Allow setting placeholder for varchar on editview b2d669a022 Fix group_id not being saved properly on InboundEmail 8d25cc19d8 Fix: From not populating fae3d7b629 Fix folders not clearing subscription a8e9eba917 Fix signatures not being editable after being created 1762704a28 Fix menu label in ExternalOAuthConnections module e97ddb6af0 Fix inbound_emails_external_oauth_connections relationship 2cbebdd5a9 Replace External Oauth Provider sugar_config with module 89f2cee005 Add admin menu entry for ExternalOAuthProviders dbe91ffe26 Add External providers to ExternalOAuthConnector menu 63b944e033 Add ExternalOAuthProvider module 214f0d9008 Rename ExternalOAuthProvider to ExternalOAuthProviderConnector 972356fa90 Add stringmap field c701e4c6d5 Add json_decode smarty modifier 49024376be Update Travis build to remove php 7.3 test runs c23f0e57ac Update Minimum php version to php 7.4 b5914d782e Fix #9670 - Disabling the user profile option about notification of assignments does not work c2f260e477 Clear caches used by Inline Edition 89de5b620f Fix #99568: Ignore int length when comparing vardefs in newer MySQL versions fb50e2250e ElasticSearch Indexing batch error handling 32af678e4f Fix #9473 - Missing item "Survey" in campainglog_activity_type_dom a12f4f37be Fix #9638 - Elasticsearch issue with accented characters d85d72996d Fix #9499 - Add View Survey Responses Menu item dcd3ea1091 Fix #9574 - Update method to static for module renaming c56a5b2188 Fix #9646 - Display TinyMCE in step 4 of the campaigns form wizard d99439aca1 Fix #9717 - Security Suite Record Group selector doesn't appear when duplicating records ea0b42469a Add new ACL access logic hooks be0dec47dc Refactor module access query for extendability 8361cceb60 fix #9802 - Diagnostic checkboxes 44e4f47cca SuiteCRM 7.13.0-beta Release 0d6fef782e Fix #9839 - Make Inbound Email not auditable c0b93a5d2a Fix #9839 - Align Inbound and Outbound email menu labels 3883c2cb7e Fix #9839 - Inbound email assignment fields save and detail display 0a4fbfa2a9 Fix #9839 - Inbound email filters not displaying 6fefdd79a0 Fix #9839 - OutboundEmailAccounts list filtering 3dcab78053 Fix #9839 - Hide sort fields in search modal if none is sortable 95d099d3b4 Fix #9839 - Always sort emails by date received aff7965abd Fix #9839 - Add showing sort direction when field is not manually sortable e3f7d02a65 Fix #9839 - Use previously selected email mailbox when using the navigation links 01c96bf15c Fix #9839 - Add Imap2Handler to use imap2 lib d8dee51d94 Fix #9839 - Move email list retrieval from InboundEmail to ImapHandler f798b9af4a Fix #9839 - Update InboundEmail calls to mailparser to send 2nd argument 68a8fa97dd Fix #9839 - Move stream validity check to ImapHandlers fb4f1c81ec Fix #9839 - Fix InboundEmail pagination totals dc26951a35 Fix #9839 - Use previously selected email mailbox when using the navigation links cca80e945b Fix #9839 - Move case macro input to Case module settings admin menu 0fb1075aa2 Fix #9839 - Fix undefined error in listview displayEmptyDataMessages 990e98e4bc Fix #9839 - Add support to test oauth connection in InboundEmail 7259c9ce79 Fix #9839 - Allow refreshing ExternalOAuthConnection tokens 49c5c0ee09 Fix #9839 - Make ExternalOAuthConnection sensitive fields db_encrypted 17bbeb3683 Fix #9839 - Allow admins to list Group and personal ExternalOAuthConnection 0f559a6223 Fix #9839 - Allow encrypting fields on db by setting db_encrypted 471792d75f Fix #9839 - Apply acl and group check filtering to OutboundEmailAccounts 093f08f27b Fix #9839 - Apply acl and group check filtering to InboundEmail decdd27b23 Fix #9839 - Apply acl and group check filtering to ExternalOAuthConnection 584e40cfb3 Fix #9839 - Add user acl group action check 07c5b9f021 Fix #9839 - Show no-data message on empty OutboundEmailAccounts listview b857e4feab Fix #9839 - Show no-data message on empty ExternalOAuthConnection listview 9b6a7c4fcf Fix #9839 - Validate required fields on InboundEmail folder selection 0755e4bc7e Fix #9839 - Mark fields required when changing authType in InboundEmail 55123f4d70 Fix #9839 - Show no-data message on empty InboundEmail listview 059d112349 Fix #9839 - Fix InboundEmail save a656abd069 Fix #9839 - Make getUserRoleNames a static method ae49f130a9 Fix #9839 - Add is-value-set data to password field 2964fcbebc Fix #9839 - Add option to disable listview empty data messages a5794343cb Fix #9839 - Add ExternalOAuthConnection link to admin menu 215413931c Fix #9839 - Align mail related menu entries ee9e98741d Fix #9839 - Always keep write-only fields in OutboundEmailAccounts 4e0551e9f0 Fix #9839 - Disable massupdate and export in OutboundEmailAccounts bulk actions bbf351ee5e Fix #9839 - Disable massupdate and export in InboundEmail bulkactions 6871295c66 Fix #9839 - Allow selecting auth type in InboundEmail module 9befcd0ae6 Fix #9839 - Add ExternalOAuthConnection entrypoints 2cee6f1d67 Fix #9839 - Add ExternalOAuthConnection module 70025d5b66 Fix #9839 - Add write-only display option to text fields 25e2443850 Fix #9839 - Add write-only display option to varchar fields 6be8a334b1 Fix #9839 - Allow creating personal outbound email accounts 8bff1fb237 Fix #9839 - Align Outbound email accounts views with Inbound e396b7373c Fix #9839 - Allow admin to create personal inbound accounts for users 284d0eca76 Fix #9839 - Align inbound email and outbound email list views 186d8e41e4 Fix #9839 - Add Security Groups subpanel to Outbound email accounts c07f43decb Fix #9839 - Add Security Groups subpanel to Inbound email accounts 87c9eee413 Fix #9839 - Add access checks to personal outbound email accounts 2f76e6a5f5 Fix #9839 - Add access checks to personal inbound email accounts 88adc8135b Fix #9839 - Remove email account configuration from User Settings 33feb0b1c2 Fix #9839 - Allow setting personal InboundEmail signatures 4cb0fd99aa Fix #9839 - Allow setting personal InboundEmail as default b8cc31d8dd Fix #9839 - Add security groups to OutboundEmailAccounts 70a0daba51 Fix #9839 - Tidy OutboundEmailAccounts view definitions ca171a4460 Fix #9839 - Remove email_provider_chooser from OutboundEmailAccounts f8a6105618 Fix #9839 - Add menu definition to OutboundEmailAccounts 7d6cfd6c6c Fix #9839 - Load InboundEmail stored_options into fields on load f18ec84b47 Fix #9839 - Adjust InboundEmail save to use new fields 54bfb4f72c Fix #9839 - Remove InboundEmail legacy custom views 69d008671e Fix #9839 - Add new menu entries to InboundEmail d01a196f3b Fix #9839 - Add js code for inboundEmail 701498d007 Fix #9839 - Add standard view definitions to InboundEmail b5870531ba Fix #9839 - Add fields for stored_options in InboundEmail 8c57b07591 Fix #9839 - Add inbound and outbound email menu links to Users module a8bc647662 Fix #9839 - Add combinescripts smarty plugin e4db0fbfd4 Fix #9839 - Add writeonly display mode for password fields 1cc85c2dbf Fix #9839 - Add readonly display mode for enum fields git-subtree-dir: public/legacy git-subtree-split: 81ce7933fd9cecc378154ed4eac7eaab5ec1f139
2022-12-21 11:44:57 +00:00
<?php
/**
*
* SugarCRM Community Edition is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
*
* SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd.
* Copyright (C) 2011 - 2022 SalesAgility Ltd.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program 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 Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
* reasonably feasible for technical reasons, the Appropriate Legal Notices must
* display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM".
*/
use Javanile\Imap2\Connection;
use Javanile\Imap2\Errors;
use Javanile\Imap2\Functions;
use Javanile\Imap2\rcube_result_index;
if (!defined('sugarEntry') || !sugarEntry) {
die('Not A Valid Entry Point');
}
require_once __DIR__ . '/ImapHandlerInterface.php';
/**
* ImapHandler
* Wrapper class for functions of imap2 lib
*/
class Imap2Handler implements ImapHandlerInterface
{
/**
*
* @var LoggerManager
*/
protected $logger;
/**
*
* @var mixed|boolean
*/
protected $stream;
/**
*
* @var bool
*/
protected $logErrors;
/**
*
* @var bool
*/
protected $logCalls;
/**
*
* @var string
*/
protected $charset;
/**
*
* @param bool $logErrors
* @param bool $logCalls
* @param null $charset
*/
public function __construct($logErrors = true, $logCalls = true, $charset = null)
{
$this->logCall(__FUNCTION__, func_get_args());
$this->logErrors = $logErrors;
$this->logCalls = $logCalls;
$this->logger = LoggerManager::getLogger();
$this->charset = $charset;
}
/**
*
* @param mixed $stream
* @param bool $validate
*/
protected function setStream($stream, $validate = true)
{
if ($validate && !is_a($stream, Connection::class)) {
$this->logger->warn('ImapHandler trying to set a non valid resource az stream.');
}
$this->stream = $stream;
}
/**
*
* @param bool $validate
* @return resource
*/
protected function getStream($validate = true)
{
if ($validate && !is_a($this->stream, Connection::class)) {
$this->logger->fatal('ImapHandler trying to use a non valid resource stream.');
}
return $this->stream;
}
/**
*
* @param array|string $errors
*/
protected function log($errors)
{
if (empty($this->logger)) {
return;
}
if (is_string($errors)) {
$this->log([$errors]);
} elseif (!empty($errors) && $this->logErrors) {
foreach ($errors as $error) {
if ($error) {
$this->logger->fatal('An Imap error detected: ' . json_encode($error));
}
}
}
}
/**
*
* @param string $func
* @param array $args
*/
protected function logCall($func, $args)
{
if ($this->logCalls) {
$this->logger->debug('IMAP wrapper called: ' . __CLASS__ . "::$func(" . json_encode($args) . ')');
}
}
/**
*
* @param string $func
* @param mixed $ret
*/
protected function logReturn($func, $ret)
{
if ($this->logCalls) {
$this->logger->debug('IMAP wrapper return: ' . __CLASS__ . "::$func(...) => " . json_encode($ret));
}
}
/**
*
* @return boolean
*/
public function close()
{
$this->logCall(__FUNCTION__, func_get_args());
try {
$ret = imap2_close($this->getStream());
} catch (Throwable $e) {
$ret = false;
}
if (!$ret) {
Squashed 'public/legacy/' changes from 60ccef0448..81ce7933fd 81ce7933fd SuiteCRM 7.13.0 Release 595d2bd92b Fix saveDropDown getting called statically a70c5d1b99 Fix message deletion after auto import f57b5ede02 Fix Inbound Email allow_outbound_group_usage filtering 9d38016f59 Remove external_oauth_providers config d5b4f0025c Remove provider field from ExternalOAuthConnection d457827c7d Change ExternalOAuthProvider to use open visibility by default for group records 3a51437d3a Add null check b49d6b79a0 Fix Inbound email tests 277f2c91cb Set default on inbound emails 261dae81c1 Add group to OutboundEmailAccounts menu 3e9dbdd5de Fix ExternalOAuthConnection list view pagination and checkboxes 36cbb6a90c Fix ExternalOAuthProvider list view pagination and checkboxes fe5f0a10d6 Fix OutboundEmailAccounts list view pagination and checkboxes b9217a36e2 Fix InboundEmail list view pagination and checkboxes 83bd0024a6 Allow selecting group InboundEmails in folder management f6a9111b25 Fix inbound email relationship definition 07b3110f8a Filter listview email displayed accounts according to preferences 6c49df527a Remove code that auto-selects a group email none is selected 243a0276af Fix preferences mail folder management dropdown e7838f0bd4 Fix owner field definition in OutboundEmailAccounts db9a52a27d Fix bounce mailbox type not being properly set 14d43e1efa Fix compose emails not sending f9e3677db8 Add optional connection string to InboundEmail module cef8b2bdb6 Allow setting placeholder for varchar on editview b2d669a022 Fix group_id not being saved properly on InboundEmail 8d25cc19d8 Fix: From not populating fae3d7b629 Fix folders not clearing subscription a8e9eba917 Fix signatures not being editable after being created 1762704a28 Fix menu label in ExternalOAuthConnections module e97ddb6af0 Fix inbound_emails_external_oauth_connections relationship 2cbebdd5a9 Replace External Oauth Provider sugar_config with module 89f2cee005 Add admin menu entry for ExternalOAuthProviders dbe91ffe26 Add External providers to ExternalOAuthConnector menu 63b944e033 Add ExternalOAuthProvider module 214f0d9008 Rename ExternalOAuthProvider to ExternalOAuthProviderConnector 972356fa90 Add stringmap field c701e4c6d5 Add json_decode smarty modifier 49024376be Update Travis build to remove php 7.3 test runs c23f0e57ac Update Minimum php version to php 7.4 b5914d782e Fix #9670 - Disabling the user profile option about notification of assignments does not work c2f260e477 Clear caches used by Inline Edition 89de5b620f Fix #99568: Ignore int length when comparing vardefs in newer MySQL versions fb50e2250e ElasticSearch Indexing batch error handling 32af678e4f Fix #9473 - Missing item "Survey" in campainglog_activity_type_dom a12f4f37be Fix #9638 - Elasticsearch issue with accented characters d85d72996d Fix #9499 - Add View Survey Responses Menu item dcd3ea1091 Fix #9574 - Update method to static for module renaming c56a5b2188 Fix #9646 - Display TinyMCE in step 4 of the campaigns form wizard d99439aca1 Fix #9717 - Security Suite Record Group selector doesn't appear when duplicating records ea0b42469a Add new ACL access logic hooks be0dec47dc Refactor module access query for extendability 8361cceb60 fix #9802 - Diagnostic checkboxes 44e4f47cca SuiteCRM 7.13.0-beta Release 0d6fef782e Fix #9839 - Make Inbound Email not auditable c0b93a5d2a Fix #9839 - Align Inbound and Outbound email menu labels 3883c2cb7e Fix #9839 - Inbound email assignment fields save and detail display 0a4fbfa2a9 Fix #9839 - Inbound email filters not displaying 6fefdd79a0 Fix #9839 - OutboundEmailAccounts list filtering 3dcab78053 Fix #9839 - Hide sort fields in search modal if none is sortable 95d099d3b4 Fix #9839 - Always sort emails by date received aff7965abd Fix #9839 - Add showing sort direction when field is not manually sortable e3f7d02a65 Fix #9839 - Use previously selected email mailbox when using the navigation links 01c96bf15c Fix #9839 - Add Imap2Handler to use imap2 lib d8dee51d94 Fix #9839 - Move email list retrieval from InboundEmail to ImapHandler f798b9af4a Fix #9839 - Update InboundEmail calls to mailparser to send 2nd argument 68a8fa97dd Fix #9839 - Move stream validity check to ImapHandlers fb4f1c81ec Fix #9839 - Fix InboundEmail pagination totals dc26951a35 Fix #9839 - Use previously selected email mailbox when using the navigation links cca80e945b Fix #9839 - Move case macro input to Case module settings admin menu 0fb1075aa2 Fix #9839 - Fix undefined error in listview displayEmptyDataMessages 990e98e4bc Fix #9839 - Add support to test oauth connection in InboundEmail 7259c9ce79 Fix #9839 - Allow refreshing ExternalOAuthConnection tokens 49c5c0ee09 Fix #9839 - Make ExternalOAuthConnection sensitive fields db_encrypted 17bbeb3683 Fix #9839 - Allow admins to list Group and personal ExternalOAuthConnection 0f559a6223 Fix #9839 - Allow encrypting fields on db by setting db_encrypted 471792d75f Fix #9839 - Apply acl and group check filtering to OutboundEmailAccounts 093f08f27b Fix #9839 - Apply acl and group check filtering to InboundEmail decdd27b23 Fix #9839 - Apply acl and group check filtering to ExternalOAuthConnection 584e40cfb3 Fix #9839 - Add user acl group action check 07c5b9f021 Fix #9839 - Show no-data message on empty OutboundEmailAccounts listview b857e4feab Fix #9839 - Show no-data message on empty ExternalOAuthConnection listview 9b6a7c4fcf Fix #9839 - Validate required fields on InboundEmail folder selection 0755e4bc7e Fix #9839 - Mark fields required when changing authType in InboundEmail 55123f4d70 Fix #9839 - Show no-data message on empty InboundEmail listview 059d112349 Fix #9839 - Fix InboundEmail save a656abd069 Fix #9839 - Make getUserRoleNames a static method ae49f130a9 Fix #9839 - Add is-value-set data to password field 2964fcbebc Fix #9839 - Add option to disable listview empty data messages a5794343cb Fix #9839 - Add ExternalOAuthConnection link to admin menu 215413931c Fix #9839 - Align mail related menu entries ee9e98741d Fix #9839 - Always keep write-only fields in OutboundEmailAccounts 4e0551e9f0 Fix #9839 - Disable massupdate and export in OutboundEmailAccounts bulk actions bbf351ee5e Fix #9839 - Disable massupdate and export in InboundEmail bulkactions 6871295c66 Fix #9839 - Allow selecting auth type in InboundEmail module 9befcd0ae6 Fix #9839 - Add ExternalOAuthConnection entrypoints 2cee6f1d67 Fix #9839 - Add ExternalOAuthConnection module 70025d5b66 Fix #9839 - Add write-only display option to text fields 25e2443850 Fix #9839 - Add write-only display option to varchar fields 6be8a334b1 Fix #9839 - Allow creating personal outbound email accounts 8bff1fb237 Fix #9839 - Align Outbound email accounts views with Inbound e396b7373c Fix #9839 - Allow admin to create personal inbound accounts for users 284d0eca76 Fix #9839 - Align inbound email and outbound email list views 186d8e41e4 Fix #9839 - Add Security Groups subpanel to Outbound email accounts c07f43decb Fix #9839 - Add Security Groups subpanel to Inbound email accounts 87c9eee413 Fix #9839 - Add access checks to personal outbound email accounts 2f76e6a5f5 Fix #9839 - Add access checks to personal inbound email accounts 88adc8135b Fix #9839 - Remove email account configuration from User Settings 33feb0b1c2 Fix #9839 - Allow setting personal InboundEmail signatures 4cb0fd99aa Fix #9839 - Allow setting personal InboundEmail as default b8cc31d8dd Fix #9839 - Add security groups to OutboundEmailAccounts 70a0daba51 Fix #9839 - Tidy OutboundEmailAccounts view definitions ca171a4460 Fix #9839 - Remove email_provider_chooser from OutboundEmailAccounts f8a6105618 Fix #9839 - Add menu definition to OutboundEmailAccounts 7d6cfd6c6c Fix #9839 - Load InboundEmail stored_options into fields on load f18ec84b47 Fix #9839 - Adjust InboundEmail save to use new fields 54bfb4f72c Fix #9839 - Remove InboundEmail legacy custom views 69d008671e Fix #9839 - Add new menu entries to InboundEmail d01a196f3b Fix #9839 - Add js code for inboundEmail 701498d007 Fix #9839 - Add standard view definitions to InboundEmail b5870531ba Fix #9839 - Add fields for stored_options in InboundEmail 8c57b07591 Fix #9839 - Add inbound and outbound email menu links to Users module a8bc647662 Fix #9839 - Add combinescripts smarty plugin e4db0fbfd4 Fix #9839 - Add writeonly display mode for password fields 1cc85c2dbf Fix #9839 - Add readonly display mode for enum fields git-subtree-dir: public/legacy git-subtree-split: 81ce7933fd9cecc378154ed4eac7eaab5ec1f139
2022-12-21 11:44:57 +00:00
$this->log('IMAP close error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @return array
*/
public function getAlerts()
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_alerts();
$this->log($ret);
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @return resource|boolean
*/
public function getConnection()
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = $this->getStream();
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @return array
*/
public function getErrors()
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_errors();
$this->log($ret);
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @return string|boolean
*/
public function getLastError()
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_last_error();
$this->log($ret);
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param string $ref
* @param string $pattern
* @return array
*/
public function getMailboxes($ref, $pattern)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_getmailboxes($this->getStream(), $ref, $pattern);
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @return boolean
*/
public function isAvailable()
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = function_exists('imap2_open') && function_exists('imap2_timeout');
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param string $mailbox
* @param string $username
* @param string $password
* @param int $options
* @param int $n_retries
* @param array|null $params
* @return resource|boolean
*/
public function open($mailbox, $username, $password, $options = 0, $n_retries = 0, $params = null)
{
$this->logCall(__FUNCTION__, func_get_args());
$mbh = Connection::open($mailbox, $username, $password, $options, $n_retries, $params);
Squashed 'public/legacy/' changes from 60ccef0448..81ce7933fd 81ce7933fd SuiteCRM 7.13.0 Release 595d2bd92b Fix saveDropDown getting called statically a70c5d1b99 Fix message deletion after auto import f57b5ede02 Fix Inbound Email allow_outbound_group_usage filtering 9d38016f59 Remove external_oauth_providers config d5b4f0025c Remove provider field from ExternalOAuthConnection d457827c7d Change ExternalOAuthProvider to use open visibility by default for group records 3a51437d3a Add null check b49d6b79a0 Fix Inbound email tests 277f2c91cb Set default on inbound emails 261dae81c1 Add group to OutboundEmailAccounts menu 3e9dbdd5de Fix ExternalOAuthConnection list view pagination and checkboxes 36cbb6a90c Fix ExternalOAuthProvider list view pagination and checkboxes fe5f0a10d6 Fix OutboundEmailAccounts list view pagination and checkboxes b9217a36e2 Fix InboundEmail list view pagination and checkboxes 83bd0024a6 Allow selecting group InboundEmails in folder management f6a9111b25 Fix inbound email relationship definition 07b3110f8a Filter listview email displayed accounts according to preferences 6c49df527a Remove code that auto-selects a group email none is selected 243a0276af Fix preferences mail folder management dropdown e7838f0bd4 Fix owner field definition in OutboundEmailAccounts db9a52a27d Fix bounce mailbox type not being properly set 14d43e1efa Fix compose emails not sending f9e3677db8 Add optional connection string to InboundEmail module cef8b2bdb6 Allow setting placeholder for varchar on editview b2d669a022 Fix group_id not being saved properly on InboundEmail 8d25cc19d8 Fix: From not populating fae3d7b629 Fix folders not clearing subscription a8e9eba917 Fix signatures not being editable after being created 1762704a28 Fix menu label in ExternalOAuthConnections module e97ddb6af0 Fix inbound_emails_external_oauth_connections relationship 2cbebdd5a9 Replace External Oauth Provider sugar_config with module 89f2cee005 Add admin menu entry for ExternalOAuthProviders dbe91ffe26 Add External providers to ExternalOAuthConnector menu 63b944e033 Add ExternalOAuthProvider module 214f0d9008 Rename ExternalOAuthProvider to ExternalOAuthProviderConnector 972356fa90 Add stringmap field c701e4c6d5 Add json_decode smarty modifier 49024376be Update Travis build to remove php 7.3 test runs c23f0e57ac Update Minimum php version to php 7.4 b5914d782e Fix #9670 - Disabling the user profile option about notification of assignments does not work c2f260e477 Clear caches used by Inline Edition 89de5b620f Fix #99568: Ignore int length when comparing vardefs in newer MySQL versions fb50e2250e ElasticSearch Indexing batch error handling 32af678e4f Fix #9473 - Missing item "Survey" in campainglog_activity_type_dom a12f4f37be Fix #9638 - Elasticsearch issue with accented characters d85d72996d Fix #9499 - Add View Survey Responses Menu item dcd3ea1091 Fix #9574 - Update method to static for module renaming c56a5b2188 Fix #9646 - Display TinyMCE in step 4 of the campaigns form wizard d99439aca1 Fix #9717 - Security Suite Record Group selector doesn't appear when duplicating records ea0b42469a Add new ACL access logic hooks be0dec47dc Refactor module access query for extendability 8361cceb60 fix #9802 - Diagnostic checkboxes 44e4f47cca SuiteCRM 7.13.0-beta Release 0d6fef782e Fix #9839 - Make Inbound Email not auditable c0b93a5d2a Fix #9839 - Align Inbound and Outbound email menu labels 3883c2cb7e Fix #9839 - Inbound email assignment fields save and detail display 0a4fbfa2a9 Fix #9839 - Inbound email filters not displaying 6fefdd79a0 Fix #9839 - OutboundEmailAccounts list filtering 3dcab78053 Fix #9839 - Hide sort fields in search modal if none is sortable 95d099d3b4 Fix #9839 - Always sort emails by date received aff7965abd Fix #9839 - Add showing sort direction when field is not manually sortable e3f7d02a65 Fix #9839 - Use previously selected email mailbox when using the navigation links 01c96bf15c Fix #9839 - Add Imap2Handler to use imap2 lib d8dee51d94 Fix #9839 - Move email list retrieval from InboundEmail to ImapHandler f798b9af4a Fix #9839 - Update InboundEmail calls to mailparser to send 2nd argument 68a8fa97dd Fix #9839 - Move stream validity check to ImapHandlers fb4f1c81ec Fix #9839 - Fix InboundEmail pagination totals dc26951a35 Fix #9839 - Use previously selected email mailbox when using the navigation links cca80e945b Fix #9839 - Move case macro input to Case module settings admin menu 0fb1075aa2 Fix #9839 - Fix undefined error in listview displayEmptyDataMessages 990e98e4bc Fix #9839 - Add support to test oauth connection in InboundEmail 7259c9ce79 Fix #9839 - Allow refreshing ExternalOAuthConnection tokens 49c5c0ee09 Fix #9839 - Make ExternalOAuthConnection sensitive fields db_encrypted 17bbeb3683 Fix #9839 - Allow admins to list Group and personal ExternalOAuthConnection 0f559a6223 Fix #9839 - Allow encrypting fields on db by setting db_encrypted 471792d75f Fix #9839 - Apply acl and group check filtering to OutboundEmailAccounts 093f08f27b Fix #9839 - Apply acl and group check filtering to InboundEmail decdd27b23 Fix #9839 - Apply acl and group check filtering to ExternalOAuthConnection 584e40cfb3 Fix #9839 - Add user acl group action check 07c5b9f021 Fix #9839 - Show no-data message on empty OutboundEmailAccounts listview b857e4feab Fix #9839 - Show no-data message on empty ExternalOAuthConnection listview 9b6a7c4fcf Fix #9839 - Validate required fields on InboundEmail folder selection 0755e4bc7e Fix #9839 - Mark fields required when changing authType in InboundEmail 55123f4d70 Fix #9839 - Show no-data message on empty InboundEmail listview 059d112349 Fix #9839 - Fix InboundEmail save a656abd069 Fix #9839 - Make getUserRoleNames a static method ae49f130a9 Fix #9839 - Add is-value-set data to password field 2964fcbebc Fix #9839 - Add option to disable listview empty data messages a5794343cb Fix #9839 - Add ExternalOAuthConnection link to admin menu 215413931c Fix #9839 - Align mail related menu entries ee9e98741d Fix #9839 - Always keep write-only fields in OutboundEmailAccounts 4e0551e9f0 Fix #9839 - Disable massupdate and export in OutboundEmailAccounts bulk actions bbf351ee5e Fix #9839 - Disable massupdate and export in InboundEmail bulkactions 6871295c66 Fix #9839 - Allow selecting auth type in InboundEmail module 9befcd0ae6 Fix #9839 - Add ExternalOAuthConnection entrypoints 2cee6f1d67 Fix #9839 - Add ExternalOAuthConnection module 70025d5b66 Fix #9839 - Add write-only display option to text fields 25e2443850 Fix #9839 - Add write-only display option to varchar fields 6be8a334b1 Fix #9839 - Allow creating personal outbound email accounts 8bff1fb237 Fix #9839 - Align Outbound email accounts views with Inbound e396b7373c Fix #9839 - Allow admin to create personal inbound accounts for users 284d0eca76 Fix #9839 - Align inbound email and outbound email list views 186d8e41e4 Fix #9839 - Add Security Groups subpanel to Outbound email accounts c07f43decb Fix #9839 - Add Security Groups subpanel to Inbound email accounts 87c9eee413 Fix #9839 - Add access checks to personal outbound email accounts 2f76e6a5f5 Fix #9839 - Add access checks to personal inbound email accounts 88adc8135b Fix #9839 - Remove email account configuration from User Settings 33feb0b1c2 Fix #9839 - Allow setting personal InboundEmail signatures 4cb0fd99aa Fix #9839 - Allow setting personal InboundEmail as default b8cc31d8dd Fix #9839 - Add security groups to OutboundEmailAccounts 70a0daba51 Fix #9839 - Tidy OutboundEmailAccounts view definitions ca171a4460 Fix #9839 - Remove email_provider_chooser from OutboundEmailAccounts f8a6105618 Fix #9839 - Add menu definition to OutboundEmailAccounts 7d6cfd6c6c Fix #9839 - Load InboundEmail stored_options into fields on load f18ec84b47 Fix #9839 - Adjust InboundEmail save to use new fields 54bfb4f72c Fix #9839 - Remove InboundEmail legacy custom views 69d008671e Fix #9839 - Add new menu entries to InboundEmail d01a196f3b Fix #9839 - Add js code for inboundEmail 701498d007 Fix #9839 - Add standard view definitions to InboundEmail b5870531ba Fix #9839 - Add fields for stored_options in InboundEmail 8c57b07591 Fix #9839 - Add inbound and outbound email menu links to Users module a8bc647662 Fix #9839 - Add combinescripts smarty plugin e4db0fbfd4 Fix #9839 - Add writeonly display mode for password fields 1cc85c2dbf Fix #9839 - Add readonly display mode for enum fields git-subtree-dir: public/legacy git-subtree-split: 81ce7933fd9cecc378154ed4eac7eaab5ec1f139
2022-12-21 11:44:57 +00:00
$this->setStream($mbh);
if (empty($mbh) || !is_a($mbh, Connection::class)) {
$this->log([
'IMAP open error: ' . imap2_last_error(),
'IMAP open error | debug data',
'ImapHandler:open: ' . $mailbox,
'ImapHandler:open: ' . $username,
'ImapHandler:open: password is empty: ' . (empty($password) ? 'yes' : 'no'),
'ImapHandler:open: ' . $options,
'IMAP open error | debug data end '
]);
}
if (!$this->getStream()) {
$this->log('IMAP open error:' . imap2_last_error());
}
$this->logReturn(__FUNCTION__, $this->getStream());
return $this->getStream();
}
/**
*
* @return boolean
*/
public function ping()
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_ping($this->getStream());
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param string $mailbox
* @param int $options
* @param int $n_retries
* @return boolean
*/
public function reopen($mailbox, $options = 0, $n_retries = 0)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_reopen($this->getStream(), $mailbox, $options, $n_retries);
if (!$ret) {
$this->log('IMAP reopen error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param int $timeout_type
* @param int $timeout
* @return mixed
*/
public function setTimeout($timeout_type, $timeout = -1)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_timeout($timeout_type, $timeout);
if (!$ret) {
$this->log('IMAP set timeout error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
* Execute callback and check IMAP errors for retry
* @param callback $callback
* @param string|null $charset
* @return array
*/
protected function executeImapCmd($callback, $charset = null)
{
// Default to class charset if none is specified
$emailCharset = !empty($charset) ? $charset : $this->charset;
$ret = false;
try {
$ret = $callback($emailCharset);
// catch if we have BADCHARSET as exception is not thrown
if (empty($ret) || $ret === false) {
$err = imap2_last_error();
if (strpos($err, 'BADCHARSET')) {
imap2_errors();
throw new Exception($err);
}
}
} catch (Exception $e) {
if (strpos($e, ' [BADCHARSET (US-ASCII)]')) {
LoggerManager::getLogger()->debug("Encoding changed dynamically from {$emailCharset} to US-ASCII");
$emailCharset = 'US-ASCII';
$this->charset = $emailCharset;
$ret = $callback($emailCharset);
}
}
return $ret;
}
/**
*
* @param int $criteria
* @param int $reverse
* @param int $options
* @param string $search_criteria
* @param string $charset
* @return array
*/
public function sort($criteria, $reverse, $options = 0, $search_criteria = null, $charset = null)
{
$this->logCall(__FUNCTION__, func_get_args());
$call = function ($charset) use ($criteria, $reverse, $options, $search_criteria) {
if (!$this->isValidStream($this->getStream())) {
return false;
}
$client = $this->getStream()->getClient();
$result = $client->sort($this->getStream()->getMailboxName(), $criteria, $search_criteria,
$options & SE_UID);
if (empty($result->count())) {
$this->log('IMAP sort: empty result');
return false;
}
$messages = $result->get();
foreach ($messages as &$message) {
$message = is_numeric($message) ? (int)$message : $message;
}
return $messages;
};
$ret = $this->executeImapCmd($call, $charset);
if (!$ret) {
$this->log('IMAP sort error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param int $uid
* @return int
*/
public function getMessageNo($uid)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_msgno($this->getStream(), $uid);
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param int $msg_number
* @param int $fromLength
* @param int $subjectLength
* @param string $defaultHost
* @return bool|object Returns FALSE on error or, if successful, the information in an object
*/
public function getHeaderInfo($msg_number, $fromLength = 0, $subjectLength = 0, $defaultHost = null)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_headerinfo($this->getStream(), $msg_number, $fromLength, $subjectLength, $defaultHost);
if (!$ret) {
$this->log('IMAP get header info error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param int $msg_number
* @param int $options
* @return string
*/
public function fetchHeader($msg_number, $options = 0)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_fetchheader($this->getStream(), $msg_number, $options);
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param string $mailbox
* @param string $message
* @param string $options
* @param string $internal_date
* @return bool
*/
public function append($mailbox, $message, $options = null, $internal_date = null)
{
$this->logCall(__FUNCTION__, func_get_args());
// ..to evolve a warning about an invalid internal date format
// BUG at: https://github.com/php/php-src/blob/master/ext/imap/php_imap.c#L1357
// -->
if (null === $internal_date) {
$ret = imap2_append($this->getStream(), $mailbox, $message, $options);
} else {
$ret = imap2_append($this->getStream(), $mailbox, $message, $options, $internal_date);
}
if (!$ret) {
$this->log('IMAP append error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param int $msg_number
* @return int
*/
public function getUid($msg_number)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_uid($this->getStream(), $msg_number);
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
* @return bool
*/
public function expunge()
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_expunge($this->getStream());
if (!$ret) {
$this->log('IMAP expunge error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
* @return object|bool Returns FALSE on failure.
*/
public function check()
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_check($this->getStream());
if (!$ret) {
$this->log('IMAP check error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param string $sequence
* @param string $flag
* @param int $options
* @return bool Returns TRUE on success or FALSE on failure.
*/
public function clearFlagFull($sequence, $flag, $options = 0)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_clearflag_full($this->getStream(), $sequence, $flag, $options);
if (!$ret) {
$this->log('IMAP clearFlagFull error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param string $mailbox
* @return bool Returns TRUE on success or FALSE on failure.
*/
public function createMailbox($mailbox)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_createmailbox($this->getStream(), $mailbox);
if (!$ret) {
$this->log('IMAP createMailbox error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param int $msg_number
* @param int $options
* @return bool Returns TRUE.
*/
public function delete($msg_number, $options = 0)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_delete($this->getStream(), $msg_number, $options);
if (!$ret) {
$this->log('IMAP delete error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param string $mailbox
* @return bool Returns TRUE on success or FALSE on failure.
*/
public function deleteMailbox($mailbox)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_deletemailbox($this->getStream(), $mailbox);
if (!$ret) {
$this->log('IMAP deleteMailbox error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param int $msg_number
* @param string $section
* @param int $options
* @return string
*/
public function fetchBody($msg_number, $section, $options = 0)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = $this->internalFetchBody($this->getStream(), $msg_number, $section, $options);
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
* Override to the imap2_fetch_body function
* @param $imap
* @param $messageNum
* @param $section
* @param $flags
* @return false|mixed|null
*/
protected function internalFetchBody($imap, $messageNum, $section, $flags = 0)
{
if (!$this->isValidStream($imap)) {
return Errors::invalidImapConnection(debug_backtrace(), 1, false);
}
$client = $imap->getClient();
$isUid = (bool)($flags & FT_UID);
$query = ['BODY[' . $section . ']'];
if ($isUid) {
$query[] = 'UID';
}
$messages = $client->fetch($imap->getMailboxName(), $messageNum, $isUid, $query);
if (empty($messages)) {
trigger_error(Errors::badMessageNumber(debug_backtrace(), 1), E_USER_WARNING);
return false;
}
$targetMessage = null;
if ($isUid) {
foreach ($messages as $message) {
if (!empty($message->uid) && ((int)$messageNum === (int)$message->uid)) {
$targetMessage = $message;
break;
}
}
} else {
$targetMessage = $messages[$messageNum];
}
if (empty($targetMessage)) {
return null;
}
if ($section) {
return $targetMessage->bodypart[$section];
}
return $targetMessage->body;
}
/**
*
* @param string $sequence
* @param int $options
* @return array
*/
public function fetchOverview($sequence, $options = 0)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = $this->fetchList($sequence, $options);
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param int $msg_number
* @param int $options
* @return object
*/
public function fetchStructure($msg_number, $options = 0)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_fetchstructure($this->getStream(), $msg_number, $options);
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param int $msg_number
* @param int $options
* @return string
*/
public function getBody($msg_number, $options)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_body($this->getStream(), $msg_number, $options);
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
* @return int|bool Return the number of messages in the current mailbox, as an integer, or FALSE on error.
*/
public function getNumberOfMessages()
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_num_msg($this->getStream());
if (!$ret) {
$this->log('IMAP getNumberOfMessages error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param string $mailbox
* @param int $options
* @return object
*/
public function getStatus($mailbox, $options)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_status($this->getStream(), $mailbox, $options);
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param string $msgList
* @param string $mailbox
* @param int $options
* @return bool Returns TRUE on success or FALSE on failure.
*/
public function mailCopy($msgList, $mailbox, $options = 0)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_mail_copy($this->getStream(), $msgList, $mailbox, $options);
if (!$ret) {
$this->log('IMAP mailCopy error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param string $msgList
* @param string $mailbox
* @param int $options
* @return bool Returns TRUE on success or FALSE on failure.
*/
public function mailMove($msgList, $mailbox, $options = 0)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_mail_move($this->getStream(), $msgList, $mailbox, $options);
if (!$ret) {
$this->log('IMAP mailMove error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param string $text
* @return array
*/
public function mimeHeaderDecode($text)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_mime_header_decode($text);
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param string $old_mbox
* @param string $new_mbox
* @return bool Returns TRUE on success or FALSE on failure.
*/
public function renameMailbox($old_mbox, $new_mbox)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_renamemailbox($this->getStream(), $old_mbox, $new_mbox);
if (!$ret) {
$this->log('IMAP renameMailbox error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param string $headers
* @param string $defaultHost
* @return object
*/
public function rfc822ParseHeaders($headers, $defaultHost = 'UNKNOWN')
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_rfc822_parse_headers($headers, $defaultHost);
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param string $criteria
* @param int $options
* @param string $charset
* @return array|bool Return FALSE if it does not understand the search criteria or no messages have been found.
*/
public function search($criteria, $options = SE_FREE, $charset = null)
{
$this->logCall(__FUNCTION__, func_get_args());
$call = function ($charset) use ($criteria, $options) {
return imap2_search($this->getStream(), $criteria, $options, $charset);
};
$ret = $this->executeImapCmd($call, $charset);
if (!$ret) {
$this->log('IMAP search error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param string $sequence
* @param string $flag
* @param int $options
* @return bool Returns TRUE on success or FALSE on failure.
*/
public function setFlagFull($sequence, $flag, $options = NIL)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_setflag_full($this->getStream(), $sequence, $flag, $options);
if (!$ret) {
$this->log('IMAP setFlagFull error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param string $mailbox
* @return bool Returns TRUE on success or FALSE on failure.
*/
public function subscribe($mailbox)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_subscribe($this->getStream(), $mailbox);
if (!$ret) {
$this->log('IMAP subscribe error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param string $mailbox
* @return bool Returns TRUE on success or FALSE on failure.
*/
public function unsubscribe($mailbox)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_unsubscribe($this->getStream(), $mailbox);
if (!$ret) {
$this->log('IMAP unsubscribe error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param string $data
* @return string|bool FALSE if text contains invalid modified UTF-7 sequence or text contains a character that is not part of ISO-8859-1 character set.
*/
public function utf7Encode($data)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_utf7_decode($data);
if (!$ret) {
$this->log('IMAP utf7Encode error');
}
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
*
* @param string $mime_encoded_text
* @return string
*/
public function utf8($mime_encoded_text)
{
$this->logCall(__FUNCTION__, func_get_args());
$ret = imap2_utf8($mime_encoded_text);
$this->logReturn(__FUNCTION__, $ret);
return $ret;
}
/**
* @param $stream
* @return bool
*/
public function isValidStream($stream): bool
{
return is_a($stream, Connection::class);
}
/**
* Fetch list of emails. Overrides imap2_fetch_override function
* @param string $sequence
* @param int $options
* @param bool $retrieveStructure
* @return array|mixed
*/
protected function fetchList(string $sequence, int $options = 0, bool $retrieveStructure = false)
{
if (!$this->isValidStream($this->getStream())) {
return Errors::invalidImapConnection(debug_backtrace(), 1, false);
}
$client = $this->getStream()->getClient();
$bodyRequest = 'BODY.PEEK[HEADER.FIELDS (SUBJECT FROM TO CC REPLYTO MESSAGEID DATE SIZE REFERENCES)]';
$query = [
$bodyRequest,
'UID',
'FLAGS',
'INTERNALDATE',
'RFC822.SIZE',
'ENVELOPE',
'RFC822.HEADER'
];
if ($retrieveStructure === true) {
$query[] = 'BODYSTRUCTURE';
}
$useUid = $options & FT_UID;
$messages = $client->fetch($this->getStream()->getMailboxName(), $sequence, $useUid, $query);
$overview = [];
foreach ($messages as $message) {
$messageEntry = (object)[
'subject' => $message->envelope[1],
'from' => Functions::writeAddressFromEnvelope($message->envelope[2]),
'to' => $message->get('to'),
'date' => $message->date,
'message_id' => $message->envelope[9],
'references' => $message->references,
'in_reply_to' => $message->envelope[8],
'size' => $message->size,
'uid' => $message->uid,
'msgno' => $message->id,
'recent' => (int)($message->flags['RECENT'] ?? 0),
'flagged' => (int)($message->flags['FLAGGED'] ?? 0),
'answered' => (int)($message->flags['ANSWERED'] ?? 0),
'deleted' => (int)($message->flags['DELETED'] ?? 0),
'seen' => (int)($message->flags['SEEN'] ?? 0),
'draft' => (int)($message->flags['DRAFT'] ?? 0),
'udate' => strtotime($message->internaldate),
'bodystructure' => $message->bodystructure ?? '',
];
if (empty($messageEntry->subject)) {
unset($messageEntry->subject);
}
if (empty($messageEntry->references)) {
unset($messageEntry->references);
}
if (empty($messageEntry->in_reply_to)) {
unset($messageEntry->in_reply_to);
}
if (empty($messageEntry->to)) {
unset($messageEntry->to);
}
$indexField = (int)$message->id;
if ($useUid) {
$indexField = (int)$message->uid;
}
$overview[$indexField] = $messageEntry;
}
return $overview;
}
/**
* Fetch list of emails. Overrides imap2_fetch_override function
* @param string $sequence
* @param int $options
* @return array|mixed
*/
protected function fetchListWithStructure(string $sequence, int $options = 0)
{
return $this->fetchList($sequence, $options, true);
}
/**
* @param string $field
* @param int $start
* @param int $end
* @param $messageSet
* @param bool $returnUid
* @return array|false
*/
protected function getSortedMessageIds(
string $field = 'ARRIVAL',
int $start = 1,
int $end = 1,
$messageSet = null,
bool $returnUid = true
) {
if (!$this->isValidStream($this->getStream())) {
return [];
}
$client = $this->getStream()->getClient();
if ($messageSet === null && $client->getCapability('SORT') !== false) {
$result = $client->sort($this->getStream()->getMailboxName(), 'REVERSE ' . $field, "$start:$end",
$returnUid, 'UTF-8');
if (empty($result) || empty($result->count())) {
return [];
}
$ids = $result->get();
} else {
$ids = $this->getAllIdsSorted($field, $returnUid, $messageSet);
if (!empty($ids)) {
$ids = array_slice($ids, $start - 1, $end);
}
}
return $ids;
}
/**
* @inheritDoc
*/
public function getMessageList(
?string $filterCriteria,
$sortCriteria,
$sortOrder,
int $offset,
int $pageSize,
array &$mailboxInfo,
array $columns
): array {
$uids = null;
if (!empty($filterCriteria)) {
// Filtered case and other sorting cases
// Returns an array of msgno's which are sorted and filtered
$emailSortedHeaders = $this->search(
$filterCriteria,
SE_UID,
);
if ($emailSortedHeaders === false) {
return [];
}
$lastSequenceNumber = $mailboxInfo['Nmsgs'] = count($emailSortedHeaders);
// paginate
if ($offset === "end") {
$offset = $lastSequenceNumber - $pageSize;
} elseif ($offset <= 0) {
$offset = 0;
}
$pageOffSet = $offset + 1;
$pageLast = $pageOffSet + $pageSize;
if (!empty($emailSortedHeaders) && is_array($emailSortedHeaders)) {
$uids = $this->getSortedMessageIds('ARRIVAL', $pageOffSet, $pageLast, $emailSortedHeaders);
}
if (empty($uids)) {
return [];
}
}
$shouldFetchAttachments = isset($columns['has_attachment']) && !empty($columns['has_attachment']);
$fetchMethod = 'fetchList';
if ($shouldFetchAttachments === true) {
$fetchMethod = 'fetchListWithStructure';
}
$emailHeaders = [];
if ($uids === null) {
$totalMsgs = $this->getNumberOfMessages();
$mailboxInfo['Nmsgs'] = $totalMsgs;
if ($offset > (int)$totalMsgs) {
$offset = 0;
}
$pageOffSet = $offset + 1;
$pageLast = $pageOffSet + $pageSize;
$sequence = "$pageOffSet:$pageLast";
$sorteUids = $this->getSortedMessageIds('ARRIVAL', $pageOffSet, $pageLast, '');
Squashed 'public/legacy/' changes from 60ccef0448..81ce7933fd 81ce7933fd SuiteCRM 7.13.0 Release 595d2bd92b Fix saveDropDown getting called statically a70c5d1b99 Fix message deletion after auto import f57b5ede02 Fix Inbound Email allow_outbound_group_usage filtering 9d38016f59 Remove external_oauth_providers config d5b4f0025c Remove provider field from ExternalOAuthConnection d457827c7d Change ExternalOAuthProvider to use open visibility by default for group records 3a51437d3a Add null check b49d6b79a0 Fix Inbound email tests 277f2c91cb Set default on inbound emails 261dae81c1 Add group to OutboundEmailAccounts menu 3e9dbdd5de Fix ExternalOAuthConnection list view pagination and checkboxes 36cbb6a90c Fix ExternalOAuthProvider list view pagination and checkboxes fe5f0a10d6 Fix OutboundEmailAccounts list view pagination and checkboxes b9217a36e2 Fix InboundEmail list view pagination and checkboxes 83bd0024a6 Allow selecting group InboundEmails in folder management f6a9111b25 Fix inbound email relationship definition 07b3110f8a Filter listview email displayed accounts according to preferences 6c49df527a Remove code that auto-selects a group email none is selected 243a0276af Fix preferences mail folder management dropdown e7838f0bd4 Fix owner field definition in OutboundEmailAccounts db9a52a27d Fix bounce mailbox type not being properly set 14d43e1efa Fix compose emails not sending f9e3677db8 Add optional connection string to InboundEmail module cef8b2bdb6 Allow setting placeholder for varchar on editview b2d669a022 Fix group_id not being saved properly on InboundEmail 8d25cc19d8 Fix: From not populating fae3d7b629 Fix folders not clearing subscription a8e9eba917 Fix signatures not being editable after being created 1762704a28 Fix menu label in ExternalOAuthConnections module e97ddb6af0 Fix inbound_emails_external_oauth_connections relationship 2cbebdd5a9 Replace External Oauth Provider sugar_config with module 89f2cee005 Add admin menu entry for ExternalOAuthProviders dbe91ffe26 Add External providers to ExternalOAuthConnector menu 63b944e033 Add ExternalOAuthProvider module 214f0d9008 Rename ExternalOAuthProvider to ExternalOAuthProviderConnector 972356fa90 Add stringmap field c701e4c6d5 Add json_decode smarty modifier 49024376be Update Travis build to remove php 7.3 test runs c23f0e57ac Update Minimum php version to php 7.4 b5914d782e Fix #9670 - Disabling the user profile option about notification of assignments does not work c2f260e477 Clear caches used by Inline Edition 89de5b620f Fix #99568: Ignore int length when comparing vardefs in newer MySQL versions fb50e2250e ElasticSearch Indexing batch error handling 32af678e4f Fix #9473 - Missing item "Survey" in campainglog_activity_type_dom a12f4f37be Fix #9638 - Elasticsearch issue with accented characters d85d72996d Fix #9499 - Add View Survey Responses Menu item dcd3ea1091 Fix #9574 - Update method to static for module renaming c56a5b2188 Fix #9646 - Display TinyMCE in step 4 of the campaigns form wizard d99439aca1 Fix #9717 - Security Suite Record Group selector doesn't appear when duplicating records ea0b42469a Add new ACL access logic hooks be0dec47dc Refactor module access query for extendability 8361cceb60 fix #9802 - Diagnostic checkboxes 44e4f47cca SuiteCRM 7.13.0-beta Release 0d6fef782e Fix #9839 - Make Inbound Email not auditable c0b93a5d2a Fix #9839 - Align Inbound and Outbound email menu labels 3883c2cb7e Fix #9839 - Inbound email assignment fields save and detail display 0a4fbfa2a9 Fix #9839 - Inbound email filters not displaying 6fefdd79a0 Fix #9839 - OutboundEmailAccounts list filtering 3dcab78053 Fix #9839 - Hide sort fields in search modal if none is sortable 95d099d3b4 Fix #9839 - Always sort emails by date received aff7965abd Fix #9839 - Add showing sort direction when field is not manually sortable e3f7d02a65 Fix #9839 - Use previously selected email mailbox when using the navigation links 01c96bf15c Fix #9839 - Add Imap2Handler to use imap2 lib d8dee51d94 Fix #9839 - Move email list retrieval from InboundEmail to ImapHandler f798b9af4a Fix #9839 - Update InboundEmail calls to mailparser to send 2nd argument 68a8fa97dd Fix #9839 - Move stream validity check to ImapHandlers fb4f1c81ec Fix #9839 - Fix InboundEmail pagination totals dc26951a35 Fix #9839 - Use previously selected email mailbox when using the navigation links cca80e945b Fix #9839 - Move case macro input to Case module settings admin menu 0fb1075aa2 Fix #9839 - Fix undefined error in listview displayEmptyDataMessages 990e98e4bc Fix #9839 - Add support to test oauth connection in InboundEmail 7259c9ce79 Fix #9839 - Allow refreshing ExternalOAuthConnection tokens 49c5c0ee09 Fix #9839 - Make ExternalOAuthConnection sensitive fields db_encrypted 17bbeb3683 Fix #9839 - Allow admins to list Group and personal ExternalOAuthConnection 0f559a6223 Fix #9839 - Allow encrypting fields on db by setting db_encrypted 471792d75f Fix #9839 - Apply acl and group check filtering to OutboundEmailAccounts 093f08f27b Fix #9839 - Apply acl and group check filtering to InboundEmail decdd27b23 Fix #9839 - Apply acl and group check filtering to ExternalOAuthConnection 584e40cfb3 Fix #9839 - Add user acl group action check 07c5b9f021 Fix #9839 - Show no-data message on empty OutboundEmailAccounts listview b857e4feab Fix #9839 - Show no-data message on empty ExternalOAuthConnection listview 9b6a7c4fcf Fix #9839 - Validate required fields on InboundEmail folder selection 0755e4bc7e Fix #9839 - Mark fields required when changing authType in InboundEmail 55123f4d70 Fix #9839 - Show no-data message on empty InboundEmail listview 059d112349 Fix #9839 - Fix InboundEmail save a656abd069 Fix #9839 - Make getUserRoleNames a static method ae49f130a9 Fix #9839 - Add is-value-set data to password field 2964fcbebc Fix #9839 - Add option to disable listview empty data messages a5794343cb Fix #9839 - Add ExternalOAuthConnection link to admin menu 215413931c Fix #9839 - Align mail related menu entries ee9e98741d Fix #9839 - Always keep write-only fields in OutboundEmailAccounts 4e0551e9f0 Fix #9839 - Disable massupdate and export in OutboundEmailAccounts bulk actions bbf351ee5e Fix #9839 - Disable massupdate and export in InboundEmail bulkactions 6871295c66 Fix #9839 - Allow selecting auth type in InboundEmail module 9befcd0ae6 Fix #9839 - Add ExternalOAuthConnection entrypoints 2cee6f1d67 Fix #9839 - Add ExternalOAuthConnection module 70025d5b66 Fix #9839 - Add write-only display option to text fields 25e2443850 Fix #9839 - Add write-only display option to varchar fields 6be8a334b1 Fix #9839 - Allow creating personal outbound email accounts 8bff1fb237 Fix #9839 - Align Outbound email accounts views with Inbound e396b7373c Fix #9839 - Allow admin to create personal inbound accounts for users 284d0eca76 Fix #9839 - Align inbound email and outbound email list views 186d8e41e4 Fix #9839 - Add Security Groups subpanel to Outbound email accounts c07f43decb Fix #9839 - Add Security Groups subpanel to Inbound email accounts 87c9eee413 Fix #9839 - Add access checks to personal outbound email accounts 2f76e6a5f5 Fix #9839 - Add access checks to personal inbound email accounts 88adc8135b Fix #9839 - Remove email account configuration from User Settings 33feb0b1c2 Fix #9839 - Allow setting personal InboundEmail signatures 4cb0fd99aa Fix #9839 - Allow setting personal InboundEmail as default b8cc31d8dd Fix #9839 - Add security groups to OutboundEmailAccounts 70a0daba51 Fix #9839 - Tidy OutboundEmailAccounts view definitions ca171a4460 Fix #9839 - Remove email_provider_chooser from OutboundEmailAccounts f8a6105618 Fix #9839 - Add menu definition to OutboundEmailAccounts 7d6cfd6c6c Fix #9839 - Load InboundEmail stored_options into fields on load f18ec84b47 Fix #9839 - Adjust InboundEmail save to use new fields 54bfb4f72c Fix #9839 - Remove InboundEmail legacy custom views 69d008671e Fix #9839 - Add new menu entries to InboundEmail d01a196f3b Fix #9839 - Add js code for inboundEmail 701498d007 Fix #9839 - Add standard view definitions to InboundEmail b5870531ba Fix #9839 - Add fields for stored_options in InboundEmail 8c57b07591 Fix #9839 - Add inbound and outbound email menu links to Users module a8bc647662 Fix #9839 - Add combinescripts smarty plugin e4db0fbfd4 Fix #9839 - Add writeonly display mode for password fields 1cc85c2dbf Fix #9839 - Add readonly display mode for enum fields git-subtree-dir: public/legacy git-subtree-split: 81ce7933fd9cecc378154ed4eac7eaab5ec1f139
2022-12-21 11:44:57 +00:00
$sequence = implode(',', $sorteUids);
$mailList = $this->$fetchMethod($sequence, FT_UID);
$emailHeaders = [];
foreach ($sorteUids as $id) {
$emailHeaders[] = $mailList[(int)$id];
}
} elseif (is_array($uids)) {
$mailList = $this->$fetchMethod(implode(',', $uids), FT_UID);
$emailHeaders = [];
foreach ($uids as $id) {
$emailHeaders[] = $mailList[(int)$id];
}
}
$emailHeaders = json_decode(json_encode($emailHeaders), true);
if ($shouldFetchAttachments === true) {
// get attachment status
foreach ($emailHeaders as $i => $emailHeader) {
$emailHeaders[$i]['has_attachment'] = false;
if (empty($emailHeader['bodystructure']) || !is_array($emailHeader['bodystructure'])) {
continue;
}
if (!is_array($emailHeader['bodystructure'][0])) {
continue;
}
$emailHeaders[$i]['has_attachment'] = $this->bodyStructureHasAttachment($emailHeader['bodystructure']);
}
}
return $emailHeaders;
}
/**
* Check if body structure has attachment
* @param $structure
* @return bool
*/
protected function bodyStructureHasAttachment($structure): bool
{
if (empty($structure) || !is_array($structure)) {
return false;
}
foreach ($structure as $item) {
if (!is_array($item)) {
continue;
}
if ($this->isAttachmentPart($item) === true) {
return true;
}
}
return false;
}
/**
* check if it is an attachment part
* @param array $item
* @return bool
*/
protected function isAttachmentPart(array $item): bool
{
foreach ($item as $subItem) {
if (!is_array($subItem)) {
continue;
}
$subItemType = $subItem[0] ?? '';
if ($subItemType === 'attachment') {
return true;
}
}
return false;
}
/**
* Get sorted ids by specified field
* @param string $field
* @param bool $returnUid
* @param null $messageSet
* @return array
*/
protected function getAllIdsSorted(string $field = 'ARRIVAL', bool $returnUid = true, $messageSet = null): array
{
$client = $this->getStream()->getClient();
if (empty($messageSet)) {
$messageSet = '1:*';
}
$result = $client->index($this->getStream()->getMailboxName(), $messageSet, $field, true, $returnUid,
$returnUid);
if (empty($result) || empty($result->count())) {
return [];
}
$ids = $result->get();
return array_reverse($ids);
}
}