* Mail: fix creating a folder on level of inbox gave an error (if imap server supports it)

This commit is contained in:
Ralf Becker 2020-06-08 11:59:32 +02:00
parent 15ced22755
commit a0760f6b96
3 changed files with 36 additions and 52 deletions

View File

@ -409,7 +409,7 @@ class Mail
if (is_null($_reuseCache)) $_reuseCache = $_restoreSession; if (is_null($_reuseCache)) $_reuseCache = $_restoreSession;
if (!empty($_displayCharset)) self::$displayCharset = $_displayCharset; if (!empty($_displayCharset)) self::$displayCharset = $_displayCharset;
// not nummeric, we assume we only want an empty class object // not nummeric, we assume we only want an empty class object
if (!is_numeric($_profileID)) return true; if (!is_numeric($_profileID)) return;
if ($_restoreSession) if ($_restoreSession)
{ {
//error_log(__METHOD__." Session restore ".function_backtrace()); //error_log(__METHOD__." Session restore ".function_backtrace());
@ -792,7 +792,8 @@ class Mail
function getDefaultIdentity() function getDefaultIdentity()
{ {
// retrieve the signature accociated with the identity // retrieve the signature accociated with the identity
$id = $this->getIdentitiesWithAccounts($_accountData=array()); $_accountData=array();
$id = $this->getIdentitiesWithAccounts($_accountData);
foreach(Mail\Account::identities($_accountData[$this->profileID] ? foreach(Mail\Account::identities($_accountData[$this->profileID] ?
$this->profileID : $_accountData[$id],false,'ident_id') as $accountData) $this->profileID : $_accountData[$id],false,'ident_id') as $accountData)
{ {
@ -804,7 +805,7 @@ class Mail
* getIdentitiesWithAccounts * getIdentitiesWithAccounts
* *
* @param array reference to pass all identities back * @param array reference to pass all identities back
* @return the default Identity (active) or 0 * @return int the default Identity (active) or 0
*/ */
function getIdentitiesWithAccounts(&$identities) function getIdentitiesWithAccounts(&$identities)
{ {
@ -1197,7 +1198,7 @@ class Mail
* @param ignoreStatusCache bool ignore the cache used for counters * @param ignoreStatusCache bool ignore the cache used for counters
* @param basicInfoOnly bool retrieve only names and stuff returned by getMailboxes * @param basicInfoOnly bool retrieve only names and stuff returned by getMailboxes
* @param fetchSubscribedInfo bool fetch Subscribed Info on folder * @param fetchSubscribedInfo bool fetch Subscribed Info on folder
* @return array * @return array|false
*/ */
function getFolderStatus($_folderName,$ignoreStatusCache=false,$basicInfoOnly=false,$fetchSubscribedInfo=true) function getFolderStatus($_folderName,$ignoreStatusCache=false,$basicInfoOnly=false,$fetchSubscribedInfo=true)
{ {
@ -1215,13 +1216,7 @@ class Mail
} }
if (isset($folderInfoCache[$_folderName]) && $ignoreStatusCache==false && $basicInfoOnly) return $folderInfoCache[$_folderName]; if (isset($folderInfoCache[$_folderName]) && $ignoreStatusCache==false && $basicInfoOnly) return $folderInfoCache[$_folderName];
$retValue = array(); $retValue = array();
$retValue['subscribed'] = false;
/*
if(!$icServer = Mail\Account::read($this->profileID)) {
if (self::$debug) error_log(__METHOD__." no Server found for Folder:".$_folderName);
return false;
}
*/
//error_log(__METHOD__.' ('.__LINE__.') '.$_folderName.' '.array2string(array_keys($folderInfoCache))); //error_log(__METHOD__.' ('.__LINE__.') '.$_folderName.' '.array2string(array_keys($folderInfoCache)));
// does the folder exist??? // does the folder exist???
if (is_null($folderInfoCache) || !isset($folderInfoCache[$_folderName])) if (is_null($folderInfoCache) || !isset($folderInfoCache[$_folderName]))
@ -1267,14 +1262,7 @@ class Mail
} }
if (!is_array($folderInfo)) if (!is_array($folderInfo))
{ {
// no folder info, but there is a status returned for the folder: something is wrong, try to cope with it return false;
$folderInfo = is_array($folderInfo)?$folderInfo:array('HIERACHY_DELIMITER'=>$this->getHierarchyDelimiter(),
'ATTRIBUTES' => '');
if (!isset($folderInfo['HIERACHY_DELIMITER']) || empty($folderInfo['HIERACHY_DELIMITER']) || (isset($folderInfo['delimiter']) && empty($folderInfo['delimiter'])))
{
//error_log(__METHOD__.' ('.__LINE__.') '.array2string($folderInfo));
$folderInfo['HIERACHY_DELIMITER'] = $this->getHierarchyDelimiter();
}
} }
} }
#if(!is_array($folderInfo)) { #if(!is_array($folderInfo)) {
@ -1282,6 +1270,7 @@ class Mail
#} #}
$retValue['delimiter'] = (isset($folderInfo['HIERACHY_DELIMITER']) && $folderInfo['HIERACHY_DELIMITER']?$folderInfo['HIERACHY_DELIMITER']:$folderInfo['delimiter']); $retValue['delimiter'] = (isset($folderInfo['HIERACHY_DELIMITER']) && $folderInfo['HIERACHY_DELIMITER']?$folderInfo['HIERACHY_DELIMITER']:$folderInfo['delimiter']);
$retValue['attributes'] = (isset($folderInfo['ATTRIBUTES']) && $folderInfo['ATTRIBUTES']?$folderInfo['ATTRIBUTES']:$folderInfo['attributes']); $retValue['attributes'] = (isset($folderInfo['ATTRIBUTES']) && $folderInfo['ATTRIBUTES']?$folderInfo['ATTRIBUTES']:$folderInfo['attributes']);
$retValue['subscribed'] = $folderInfo['SUBSCRIBED'] ?? $folderInfo['subscribed'] ?? false;
$shortNameParts = explode($retValue['delimiter'], $_folderName); $shortNameParts = explode($retValue['delimiter'], $_folderName);
$retValue['shortName'] = array_pop($shortNameParts); $retValue['shortName'] = array_pop($shortNameParts);
$retValue['displayName'] = $_folderName; $retValue['displayName'] = $_folderName;
@ -5074,7 +5063,7 @@ class Mail
static function &getdisplayableBody(&$mailClass, $bodyParts, $preserveHTML = false, $useTidy = true) static function &getdisplayableBody(&$mailClass, $bodyParts, $preserveHTML = false, $useTidy = true)
{ {
$message=''; $message='';
for($i=0; $i<count($bodyParts); $i++) for($i=0, $cnt=count($bodyParts); $i < $cnt; $i++)
{ {
if (!isset($bodyParts[$i]['body'])) { if (!isset($bodyParts[$i]['body'])) {
$bodyParts[$i]['body'] = self::getdisplayableBody($mailClass, $bodyParts[$i], $preserveHTML, $useTidy); $bodyParts[$i]['body'] = self::getdisplayableBody($mailClass, $bodyParts[$i], $preserveHTML, $useTidy);
@ -5139,7 +5128,8 @@ class Mail
if (!$preserveHTML) if (!$preserveHTML)
{ {
// filter only the 'body', as we only want that part, if we throw away the html // filter only the 'body', as we only want that part, if we throw away the html
preg_match('`(<htm.+?<body[^>]*>)(.+?)(</body>.*?</html>)`ims', $newBody, $matches=array()); $matches = array();
preg_match('`(<htm.+?<body[^>]*>)(.+?)(</body>.*?</html>)`ims', $newBody, $matches);
if ($matches[2]) if ($matches[2])
{ {
$hasOther = true; $hasOther = true;
@ -5150,7 +5140,8 @@ class Mail
else else
{ {
// htmLawed filter only the 'body' // htmLawed filter only the 'body'
preg_match('`(<htm.+?<body[^>]*>)(.+?)(</body>.*?</html>)`ims', $newBody, $matches=array()); $matches = array();
preg_match('`(<htm.+?<body[^>]*>)(.+?)(</body>.*?</html>)`ims', $newBody, $matches);
if ($matches[2]) if ($matches[2])
{ {
$hasOther = true; $hasOther = true;
@ -5515,8 +5506,8 @@ class Mail
*/ */
static function &getStyles($_bodyParts) static function &getStyles($_bodyParts)
{ {
$style = ''; $style = $ret = '';
if (empty($_bodyParts)) return ""; if (empty($_bodyParts)) return $ret;
foreach((array)$_bodyParts as $singleBodyPart) { foreach((array)$_bodyParts as $singleBodyPart) {
if (!isset($singleBodyPart['body'])) { if (!isset($singleBodyPart['body'])) {
$singleBodyPart['body'] = self::getStyles($singleBodyPart); $singleBodyPart['body'] = self::getStyles($singleBodyPart);
@ -6565,7 +6556,8 @@ class Mail
$mergeobj = new Contacts\Merge(); $mergeobj = new Contacts\Merge();
if (empty($mimetype)) $mimetype = (strlen(strip_tags($content)) == strlen($content) ?'text/plain':'text/html'); if (empty($mimetype)) $mimetype = (strlen(strip_tags($content)) == strlen($content) ?'text/plain':'text/html');
$rv = $mergeobj->merge_string($content,$ids,$err='',$mimetype, array(), self::$displayCharset); $err = '';
$rv = $mergeobj->merge_string($content,$ids,$err, $mimetype, array(), self::$displayCharset);
if (empty($rv) && !empty($content) && !empty($err)) $rv = $content; if (empty($rv) && !empty($content) && !empty($err)) $rv = $content;
if (!empty($err) && !empty($content) && !empty($ids)) error_log(__METHOD__.' ('.__LINE__.') '.' Merge failed for Ids:'.array2string($ids).' ContentType:'.$mimetype.' Content:'.$content.' Reason:'.array2string($err)); if (!empty($err) && !empty($content) && !empty($ids)) error_log(__METHOD__.' ('.__LINE__.') '.' Merge failed for Ids:'.array2string($ids).' ContentType:'.$mimetype.' Content:'.$content.' Reason:'.array2string($err));
return $rv; return $rv;

View File

@ -554,6 +554,11 @@ class Imap extends Horde_Imap_Client_Socket implements Imap\Iface
} }
} }
/**
* Attribute returned for Horde_Imap_Client::MBOX_ALL_SUBSCRIBED if mailbox is subscribed
*/
const SUBSCRIBED_ATTRIBUTE = '\\subscribed';
/** /**
* getStatus * getStatus
* *
@ -563,7 +568,7 @@ class Imap extends Horde_Imap_Client_Socket implements Imap\Iface
*/ */
function getStatus($mailbox, $ignoreStatusCache=false) function getStatus($mailbox, $ignoreStatusCache=false)
{ {
$mailboxes = $this->listMailboxes($mailbox,Horde_Imap_Client::MBOX_ALL,array( $mailboxes = $this->listMailboxes($mailbox,Horde_Imap_Client::MBOX_ALL_SUBSCRIBED, array(
'attributes'=>true, 'attributes'=>true,
'children'=>true, //child info 'children'=>true, //child info
'delimiter'=>true, 'delimiter'=>true,
@ -588,6 +593,7 @@ class Imap extends Horde_Imap_Client_Socket implements Imap\Iface
} }
$_status['HIERACHY_DELIMITER'] = $_status['delimiter'] = ($box['delimiter']?$box['delimiter']:$this->getDelimiter('personal')); $_status['HIERACHY_DELIMITER'] = $_status['delimiter'] = ($box['delimiter']?$box['delimiter']:$this->getDelimiter('personal'));
$_status['ATTRIBUTES'] = $box['attributes']; $_status['ATTRIBUTES'] = $box['attributes'];
$_status['SUBSCRIBED'] = in_array(self::SUBSCRIBED_ATTRIBUTE, $box['attributes']);
//error_log(__METHOD__.__LINE__.$k.'->'.array2string($_status)); //error_log(__METHOD__.__LINE__.$k.'->'.array2string($_status));
return $_status; return $_status;
} }
@ -651,35 +657,18 @@ class Imap extends Horde_Imap_Client_Socket implements Imap\Iface
unset($options['children']); unset($options['children']);
unset($options['special_use']); unset($options['special_use']);
} }
$mailboxes = $this->listMailboxes($searchstring,Horde_Imap_Client::MBOX_ALL, $options); $mailboxes = $this->listMailboxes($searchstring,Horde_Imap_Client::MBOX_ALL_SUBSCRIBED, $options);
//$mboxes = new Horde_Imap_Client_Mailbox_List($mailboxes); //$mboxes = new Horde_Imap_Client_Mailbox_List($mailboxes);
//_debug_array($mboxes->count()); //_debug_array($mboxes->count());
foreach ((array)$mailboxes as $k => $box) foreach ((array)$mailboxes as $k => $box)
{ {
//error_log(__METHOD__.__LINE__.' Box:'.$k.'->'.array2string($box)); //error_log(__METHOD__.__LINE__.' Box:'.$k.'->'.array2string($box));
$ret[$k]=array('MAILBOX'=>$k,'ATTRIBUTES'=>$box['attributes'],'delimiter'=>($box['delimiter']?$box['delimiter']:$this->getDelimiter('personal')),'SUBSCRIBED'=>true); $ret[$k] = [
} 'MAILBOX' => $k,
// for unknown reasons on ALL, UNSUBSCRIBED are not returned 'ATTRIBUTES' => $box['attributes'],
//always fetch unsubscribed, think about only fetching it when $options['attributes'] is set 'delimiter' => $box['delimiter'] ? $box['delimiter'] : $this->getDelimiter('personal'),
//but then allMailboxes are not all, .... 'SUBSCRIBED' => in_array(self::SUBSCRIBED_ATTRIBUTE, $box['attributes']),
//if (!empty($mailbox) && !isset($ret[$mailbox])) ];
{
$unsub_mailboxes = $this->listMailboxes($searchstring,Horde_Imap_Client::MBOX_UNSUBSCRIBED, $options);
//$mboxes = new Horde_Imap_Client_Mailbox_List($mailboxes);
//_debug_array($mboxes->count());
//error_log(__METHOD__.__LINE__.' '.$mailbox.':'.count((array)$mailboxes).'->'.function_backtrace());
foreach ((array)$unsub_mailboxes as $k =>$box)
{
//error_log(__METHOD__.__LINE__.' Box:'.$k.' already In?'.array_key_exists($k,$boxexists).'->'.array2string($box));
if(!array_key_exists($k,$ret))
{
$ret[$k]=array('MAILBOX'=>$k,'ATTRIBUTES'=>$box['attributes'],'delimiter'=>($box['delimiter']?$box['delimiter']:$this->getDelimiter('personal')),'SUBSCRIBED'=>false);
}
else
{
$ret[$k]['SUBSCRIBED'] = false;
}
}
} }
return $ret; return $ret;
} }

View File

@ -4093,7 +4093,10 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
$counter++; $counter++;
if (!$p_no_delimiter) if (!$p_no_delimiter)
{ {
$status = $this->mail_bo->getFolderStatus($new,false, true, true); // we first test below INBOX, because testing just the name wrongly reports it as subscribed
// for servers not allowing to create folders parallel to INBOX
$status = $this->mail_bo->getFolderStatus('INBOX'.$delimiter.$new,false, true, true) ?:
$this->mail_bo->getFolderStatus($new,false, true, true);
if (!$status['subscribed']) if (!$status['subscribed'])
{ {
try try