diff --git a/dev/App/User.js b/dev/App/User.js index fc02d013b..c099c8f32 100644 --- a/dev/App/User.js +++ b/dev/App/User.js @@ -299,8 +299,8 @@ class AppUser extends AbstractApp { } ]); } else if (oMoveFolder) { - this.messagesMoveHelper(sFromFolderFullNameRaw, oMoveFolder.fullNameRaw, aUidForRemove); - MessageUserStore.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove, oMoveFolder.fullNameRaw); + this.messagesMoveHelper(sFromFolderFullNameRaw, oMoveFolder.fullName, aUidForRemove); + MessageUserStore.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove, oMoveFolder.fullName); } } @@ -317,12 +317,12 @@ class AppUser extends AbstractApp { if (oFromFolder && oToFolder) { if (undefined === bCopy ? false : !!bCopy) { - this.messagesCopyHelper(oFromFolder.fullNameRaw, oToFolder.fullNameRaw, aUidForMove); + this.messagesCopyHelper(oFromFolder.fullName, oToFolder.fullName, aUidForMove); } else { - this.messagesMoveHelper(oFromFolder.fullNameRaw, oToFolder.fullNameRaw, aUidForMove); + this.messagesMoveHelper(oFromFolder.fullName, oToFolder.fullName, aUidForMove); } - MessageUserStore.removeMessagesFromList(oFromFolder.fullNameRaw, aUidForMove, oToFolder.fullNameRaw, bCopy); + MessageUserStore.removeMessagesFromList(oFromFolder.fullName, aUidForMove, oToFolder.fullName, bCopy); return true; } } @@ -487,12 +487,12 @@ class AppUser extends AbstractApp { folderFromCache.messageCountUnread(result.MessageUnseenCount); if (unreadCountChange) { - MessageFlagsCache.clearFolder(folderFromCache.fullNameRaw); + MessageFlagsCache.clearFolder(folderFromCache.fullName); } if (result.Flags.length) { result.Flags.forEach(flags => - MessageFlagsCache.storeByFolderAndUid(folderFromCache.fullNameRaw, flags.Uid.toString(), [ + MessageFlagsCache.storeByFolderAndUid(folderFromCache.fullName, flags.Uid.toString(), [ !!flags.IsUnseen, !!flags.IsFlagged, !!flags.IsAnswered, @@ -505,15 +505,15 @@ class AppUser extends AbstractApp { } MessageUserStore.initUidNextAndNewMessages( - folderFromCache.fullNameRaw, + folderFromCache.fullName, result.UidNext, result.NewMessages ); if (!hash || unreadCountChange || result.Hash !== hash) { - if (folderFromCache.fullNameRaw === FolderUserStore.currentFolderFullNameRaw()) { + if (folderFromCache.fullName === FolderUserStore.currentFolderFullNameRaw()) { this.reloadMessageList(); - } else if (getFolderInboxName() === folderFromCache.fullNameRaw) { + } else if (getFolderInboxName() === folderFromCache.fullName) { Remote.messageList(null, {Folder: getFolderInboxName()}, true); } } @@ -551,17 +551,17 @@ class AppUser extends AbstractApp { folder.messageCountUnread(item.MessageUnseenCount); if (unreadCountChange) { - MessageFlagsCache.clearFolder(folder.fullNameRaw); + MessageFlagsCache.clearFolder(folder.fullName); } if (!hash || item.Hash !== hash) { - if (folder.fullNameRaw === FolderUserStore.currentFolderFullNameRaw()) { + if (folder.fullName === FolderUserStore.currentFolderFullNameRaw()) { this.reloadMessageList(); } } else if (unreadCountChange - && folder.fullNameRaw === FolderUserStore.currentFolderFullNameRaw() + && folder.fullName === FolderUserStore.currentFolderFullNameRaw() && MessageUserStore.list.length) { - this.folderInformation(folder.fullNameRaw, MessageUserStore.list()); + this.folderInformation(folder.fullName, MessageUserStore.list()); } } }); diff --git a/dev/Common/UtilsUser.js b/dev/Common/UtilsUser.js index 684646803..0fe05ac5e 100644 --- a/dev/Common/UtilsUser.js +++ b/dev/Common/UtilsUser.js @@ -200,14 +200,14 @@ folderListOptionsBuilder = ( folders.forEach(oItem => { if (showUnsubscribed || oItem.hasSubscriptions() || !oItem.exists) { aResult.push({ - id: oItem.fullNameRaw, + id: oItem.fullName, name: sDeepPrefix.repeat(oItem.deep) + fRenameCallback(oItem), system: false, disabled: !bNoSelectSelectable && ( !oItem.selectable() || - aDisabled.includes(oItem.fullNameRaw) || + aDisabled.includes(oItem.fullName) || fDisableCallback(oItem)) }); } diff --git a/dev/External/User/ko.js b/dev/External/User/ko.js index 89c4c99ec..f88139997 100644 --- a/dev/External/User/ko.js +++ b/dev/External/User/ko.js @@ -145,7 +145,7 @@ ko.bindingHandlers.dropmessages = { if ('messages' === getDragAction(e) && ['move','copy'].includes(e.dataTransfer.effectAllowed)) { let data = dragData.data; if (folder && data && data.folder && isArray(data.uids)) { - rl.app.moveMessagesToFolder(data.folder, data.uids, folder.fullNameRaw, data.copy && e.ctrlKey); + rl.app.moveMessagesToFolder(data.folder, data.uids, folder.fullName, data.copy && e.ctrlKey); } } }); diff --git a/dev/Model/FolderCollection.js b/dev/Model/FolderCollection.js index 325b73b35..4c63a83dd 100644 --- a/dev/Model/FolderCollection.js +++ b/dev/Model/FolderCollection.js @@ -69,7 +69,7 @@ export class FolderCollectionModel extends AbstractCollectionModel } return super.reviveFromJson(object, oFolder => { - let oCacheFolder = Cache.getFolderFromCacheList(oFolder.FullNameRaw); + let oCacheFolder = Cache.getFolderFromCacheList(oFolder.FullName); if (oCacheFolder) { oFolder.SubFolders = FolderCollectionModel.reviveFromJson(oFolder.SubFolders); @@ -79,14 +79,14 @@ export class FolderCollectionModel extends AbstractCollectionModel if (!oCacheFolder) return null; - if (1 == SystemFolders.indexOf(oFolder.FullNameRaw)) { + if (1 == SystemFolders.indexOf(oFolder.FullName)) { oCacheFolder.type(FolderType.Inbox); - Cache.setFolderInboxName(oFolder.FullNameRaw); + Cache.setFolderInboxName(oFolder.FullName); } - Cache.setFolder(oCacheFolder.fullNameHash, oFolder.FullNameRaw, oCacheFolder); + Cache.setFolder(oCacheFolder.fullNameHash, oFolder.FullName, oCacheFolder); } - let type = SystemFolders.indexOf(oFolder.FullNameRaw); + let type = SystemFolders.indexOf(oFolder.FullName); if (1 < type) { oCacheFolder.type(type); } @@ -97,7 +97,7 @@ export class FolderCollectionModel extends AbstractCollectionModel if (oFolder.Extended) { if (oFolder.Extended.Hash) { - Cache.setFolderHash(oCacheFolder.fullNameRaw, oFolder.Extended.Hash); + Cache.setFolderHash(oCacheFolder.fullName, oFolder.Extended.Hash); } if (null != oFolder.Extended.MessageCount) { @@ -196,7 +196,6 @@ export class FolderModel extends AbstractModel { super(); this.fullName = ''; - this.fullNameRaw = ''; this.fullNameHash = ''; this.delimiter = ''; this.namespace = ''; @@ -244,7 +243,7 @@ export class FolderModel extends AbstractModel { static reviveFromJson(json) { const folder = super.reviveFromJson(json); if (folder) { - folder.deep = json.FullNameRaw.split(folder.delimiter).length - 1; + folder.deep = json.FullName.split(folder.delimiter).length - 1; let type = (folder.metadata[FolderMetadataKeys.KolabFolderType] || folder.metadata[FolderMetadataKeys.KolabFolderTypeShared] diff --git a/dev/Remote/User/Fetch.js b/dev/Remote/User/Fetch.js index 8dab58ff6..b82a96e9e 100644 --- a/dev/Remote/User/Fetch.js +++ b/dev/Remote/User/Fetch.js @@ -19,10 +19,19 @@ import { AbstractFetchRemote } from 'Remote/AbstractFetch'; import { FolderCollectionModel } from 'Model/FolderCollection'; -const urlSafeJSON = data => btoa(JSON.stringify(data)) +// unescape(encodeURIComponent()) makes the UTF-16 DOMString to an UTF-8 string +const urlSafeJSON = data => btoa(unescape(encodeURIComponent(JSON.stringify(data)))) .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=+$/, ''); +/* Withous deprecated 'unescape': +const urlSafeJSON = data => btoa(encodeURIComponent(JSON.stringify(data)).replace( + /%([0-9A-F]{2})/g, (match, p1) => String.fromCharCode('0x' + p1) + )) + .replace(/\+/g, '-') + .replace(/\//g, '_') + .replace(/=+$/, ''); +*/ class RemoteUserFetch extends AbstractFetchRemote { diff --git a/dev/Settings/User/Folders.js b/dev/Settings/User/Folders.js index 6fd2df70b..70a94b09d 100644 --- a/dev/Settings/User/Folders.js +++ b/dev/Settings/User/Folders.js @@ -73,11 +73,11 @@ export class FoldersUserSettings /*extends AbstractViewSettings*/ { Local.set(ClientSideKeyName.FoldersLashHash, ''); rl.app.foldersPromisesActionHelper( - Remote.folderRename(folder.fullNameRaw, nameToEdit), + Remote.folderRename(folder.fullName, nameToEdit), Notification.CantRenameFolder ); - removeFolderFromCacheList(folder.fullNameRaw); + removeFolderFromCacheList(folder.fullName); folder.name(nameToEdit); } @@ -120,11 +120,11 @@ export class FoldersUserSettings /*extends AbstractViewSettings*/ { // rl.app.foldersPromisesActionHelper Remote.abort('Folders') - .folderDelete(folderToRemove.fullNameRaw) + .folderDelete(folderToRemove.fullName) .then( () => { folderToRemove.selectable(false) - removeFolderFromCacheList(folderToRemove.fullNameRaw); + removeFolderFromCacheList(folderToRemove.fullName); FolderUserStore.folderList(FolderUserStore.folderList.filter(folder => folder !== folderToRemove)); }, error => { @@ -143,20 +143,20 @@ export class FoldersUserSettings /*extends AbstractViewSettings*/ { toggleFolderKolabType(folder, event) { let type = event.target.value; // TODO: append '.default' ? - Remote.folderSetMetadata(null, folder.fullNameRaw, FolderMetadataKeys.KolabFolderType, type); + Remote.folderSetMetadata(null, folder.fullName, FolderMetadataKeys.KolabFolderType, type); folder.kolabType(type); } toggleFolderSubscription(folder) { let subscribe = !folder.subscribed(); Local.set(ClientSideKeyName.FoldersLashHash, ''); - Remote.folderSetSubscribe(null, folder.fullNameRaw, subscribe); + Remote.folderSetSubscribe(null, folder.fullName, subscribe); folder.subscribed(subscribe); } toggleFolderCheckable(folder) { let checkable = !folder.checkable(); - Remote.folderSetCheckable(null, folder.fullNameRaw, checkable); + Remote.folderSetCheckable(null, folder.fullName, checkable); folder.checkable(checkable); } } diff --git a/dev/Stores/User/Folder.js b/dev/Stores/User/Folder.js index 5b8e89bb0..dac855601 100644 --- a/dev/Stores/User/Folder.js +++ b/dev/Stores/User/Folder.js @@ -58,7 +58,7 @@ export const FolderUserStore = new class { draftFolderNotEnabled: () => !self.draftFolder() || UNUSED_OPTION_VALUE === self.draftFolder(), - currentFolderFullNameRaw: () => (self.currentFolder() ? self.currentFolder().fullNameRaw : ''), + currentFolderFullNameRaw: () => (self.currentFolder() ? self.currentFolder().fullName : ''), currentFolderFullName: () => (self.currentFolder() ? self.currentFolder().fullName : ''), currentFolderFullNameHash: () => (self.currentFolder() ? self.currentFolder().fullNameHash : ''), @@ -136,7 +136,7 @@ export const FolderUserStore = new class { timeout > folder.expires && (folder.isSystemFolder() || (folder.subscribed() && (folder.checkable() || !bDisplaySpecSetting))) ) { - timeouts.push([folder.expires, folder.fullNameRaw]); + timeouts.push([folder.expires, folder.fullName]); } if (folder && folder.subFolders.length) { diff --git a/dev/Stores/User/Message.js b/dev/Stores/User/Message.js index 74feb058b..53bb6d6e0 100644 --- a/dev/Stores/User/Message.js +++ b/dev/Stores/User/Message.js @@ -308,7 +308,7 @@ export const MessageUserStore = new class { } if (toFolder) { - if (trashFolder === toFolder.fullNameRaw || spamFolder === toFolder.fullNameRaw) { + if (trashFolder === toFolder.fullName || spamFolder === toFolder.fullName) { unseenCount = 0; } @@ -661,13 +661,13 @@ export const MessageUserStore = new class { if (null != collection.MessageUnseenCount) { if (pInt(folder.messageCountUnread()) !== pInt(collection.MessageUnseenCount)) { unreadCountChange = true; - MessageFlagsCache.clearFolder(folder.fullNameRaw); + MessageFlagsCache.clearFolder(folder.fullName); } folder.messageCountUnread(collection.MessageUnseenCount); } - this.initUidNextAndNewMessages(folder.fullNameRaw, collection.UidNext, collection.NewMessages); + this.initUidNextAndNewMessages(folder.fullName, collection.UidNext, collection.NewMessages); } this.listCount(iCount); @@ -688,7 +688,7 @@ export const MessageUserStore = new class { clearNewMessageCache(); if (folder && (cached || unreadCountChange || SettingsUserStore.useThreads())) { - rl.app.folderInformation(folder.fullNameRaw, collection); + rl.app.folderInformation(folder.fullName, collection); } } else { this.listCount(0); diff --git a/dev/View/Popup/FolderClear.js b/dev/View/Popup/FolderClear.js index 1db705213..78a291659 100644 --- a/dev/View/Popup/FolderClear.js +++ b/dev/View/Popup/FolderClear.js @@ -52,7 +52,7 @@ class FolderClearPopupView extends AbstractViewPopup { folderToClear.messageCountAll(0); folderToClear.messageCountUnread(0); - setFolderHash(folderToClear.fullNameRaw, ''); + setFolderHash(folderToClear.fullName, ''); Remote.folderClear(iError => { this.clearingProcess(false); @@ -62,7 +62,7 @@ class FolderClearPopupView extends AbstractViewPopup { rl.app.reloadMessageList(true); this.cancelCommand(); } - }, folderToClear.fullNameRaw); + }, folderToClear.fullName); } } diff --git a/dev/View/Popup/FolderCreate.js b/dev/View/Popup/FolderCreate.js index 91df1cc3f..ba4505182 100644 --- a/dev/View/Popup/FolderCreate.js +++ b/dev/View/Popup/FolderCreate.js @@ -30,7 +30,7 @@ class FolderCreatePopupView extends AbstractViewPopup { oItem => oItem ? (oItem.isSystemFolder() ? oItem.name() + ' ' + oItem.manageFolderSystemName() : oItem.name()) : '', FolderUserStore.namespace - ? item => FolderUserStore.namespace !== item.fullNameRaw.substr(0, FolderUserStore.namespace.length) + ? item => FolderUserStore.namespace !== item.fullName.substr(0, FolderUserStore.namespace.length) : null, true ) diff --git a/dev/View/User/MailBox/FolderList.js b/dev/View/User/MailBox/FolderList.js index 9ea8f1d42..d4197c14c 100644 --- a/dev/View/User/MailBox/FolderList.js +++ b/dev/View/User/MailBox/FolderList.js @@ -88,7 +88,7 @@ export class MailFolderList extends AbstractViewLeft { rl.app.moveMessagesToFolder( FolderUserStore.currentFolderFullNameRaw(), MessageUserStore.listCheckedOrSelectedUidsWithSubMails(), - folder.fullNameRaw, + folder.fullName, event.ctrlKey ); } else { @@ -96,8 +96,8 @@ export class MailFolderList extends AbstractViewLeft { MessageUserStore.message(null); } - if (folder.fullNameRaw === FolderUserStore.currentFolderFullNameRaw()) { - setFolderHash(folder.fullNameRaw, ''); + if (folder.fullName === FolderUserStore.currentFolderFullNameRaw()) { + setFolderHash(folder.fullName, ''); } rl.route.setHash( diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Base/Utils.php b/snappymail/v/0.0.0/app/libraries/MailSo/Base/Utils.php index 24d7fd965..130bb237c 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Base/Utils.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Base/Utils.php @@ -1374,239 +1374,16 @@ END; public static function Utf7ModifiedToUtf8(string $sStr) : string { - $aArray = array(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,62, 63,-1,-1,-1,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9, - 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, - 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1); - - $sResult = ''; - $bError = false; - $iLen = \strlen($sStr); - - for ($iIndex = 0; $iLen > 0; $iIndex++, $iLen--) - { - $sChar = $sStr[$iIndex]; - if ($sChar == '&') - { - $iIndex++; - $iLen--; - - $sChar = isset($sStr[$iIndex]) ? $sStr[$iIndex] : null; - if ($sChar === null) - { - break; - } - - if ($iLen && $sChar == '-') - { - $sResult .= '&'; - continue; - } - - $iCh = 0; - $iK = 10; - for (; $iLen > 0; $iIndex++, $iLen--) - { - $sChar = $sStr[$iIndex]; - - $iB = $aArray[\ord($sChar)]; - if ((\ord($sChar) & 0x80) || $iB == -1) - { - break; - } - - if ($iK > 0) - { - $iCh |= $iB << $iK; - $iK -= 6; - } - else - { - $iCh |= $iB >> (-$iK); - if ($iCh < 0x80) - { - if (0x20 <= $iCh && $iCh < 0x7f) - { - return $bError; - } - - $sResult .= \chr($iCh); - } - else if ($iCh < 0x800) - { - $sResult .= \chr(0xc0 | ($iCh >> 6)); - $sResult .= \chr(0x80 | ($iCh & 0x3f)); - } - else - { - $sResult .= \chr(0xe0 | ($iCh >> 12)); - $sResult .= \chr(0x80 | (($iCh >> 6) & 0x3f)); - $sResult .= \chr(0x80 | ($iCh & 0x3f)); - } - - $iCh = ($iB << (16 + $iK)) & 0xffff; - $iK += 10; - } - } - - if (($iCh || $iK < 6) || - (!$iLen || $sChar != '-') || - ($iLen > 2 && '&' === $sStr[$iIndex+1] && '-' !== $sStr[$iIndex+2])) - { - return $bError; - } - } - else if (\ord($sChar) < 0x20 || \ord($sChar) >= 0x7f) - { - return $bError; - } - else - { - $sResult .= $sChar; - } - } - - return $sResult; + return \is_callable('imap_mutf7_to_utf8') + ? \imap_mutf7_to_utf8($sStr) + : \mb_convert_encoding($sStr, 'UTF-8', 'UTF7-IMAP'); } public static function Utf8ToUtf7Modified(string $sStr) : string { - $sArray = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S', - 'T','U','V','W','X','Y','Z', 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', - 'p','q','r','s','t','u','v','w','x','y','z', '0','1','2','3','4','5','6','7','8','9','+',','); - - $sLen = \strlen($sStr); - $bIsB = false; - $iIndex = $iN = 0; - $sReturn = ''; - $bError = false; - $iCh = $iB = $iK = 0; - - while ($sLen) - { - $iC = \ord($sStr[$iIndex]); - if ($iC < 0x80) - { - $iCh = $iC; - $iN = 0; - } - else if ($iC < 0xc2) - { - return $bError; - } - else if ($iC < 0xe0) - { - $iCh = $iC & 0x1f; - $iN = 1; - } - else if ($iC < 0xf0) - { - $iCh = $iC & 0x0f; - $iN = 2; - } - else if ($iC < 0xf8) - { - $iCh = $iC & 0x07; - $iN = 3; - } - else if ($iC < 0xfc) - { - $iCh = $iC & 0x03; - $iN = 4; - } - else if ($iC < 0xfe) - { - $iCh = $iC & 0x01; - $iN = 5; - } - else - { - return $bError; - } - - $iIndex++; - $sLen--; - - if ($iN > $sLen) - { - return $bError; - } - - for ($iJ = 0; $iJ < $iN; $iJ++) - { - $iO = \ord($sStr[$iIndex+$iJ]); - if (($iO & 0xc0) != 0x80) - { - return $bError; - } - - $iCh = ($iCh << 6) | ($iO & 0x3f); - } - - if ($iN > 1 && !($iCh >> ($iN * 5 + 1))) - { - return $bError; - } - - $iIndex += $iN; - $sLen -= $iN; - - if ($iCh < 0x20 || $iCh >= 0x7f) - { - if (!$bIsB) - { - $sReturn .= '&'; - $bIsB = true; - $iB = 0; - $iK = 10; - } - - if ($iCh & ~0xffff) - { - $iCh = 0xfffe; - } - - $sReturn .= $sArray[($iB | $iCh >> $iK)]; - $iK -= 6; - for (; $iK >= 0; $iK -= 6) - { - $sReturn .= $sArray[(($iCh >> $iK) & 0x3f)]; - } - - $iB = ($iCh << (-$iK)) & 0x3f; - $iK += 16; - } - else - { - if ($bIsB) - { - if ($iK > 10) - { - $sReturn .= $sArray[$iB]; - } - $sReturn .= '-'; - $bIsB = false; - } - - $sReturn .= \chr($iCh); - if ('&' === \chr($iCh)) - { - $sReturn .= '-'; - } - } - } - - if ($bIsB) - { - if ($iK > 10) - { - $sReturn .= $sArray[$iB]; - } - - $sReturn .= '-'; - } - - return $sReturn; + return \is_callable('imap_utf8_to_mutf7') + ? \imap_utf8_to_mutf7($sStr) + : \mb_convert_encoding($sStr, 'UTF7-IMAP', 'UTF-8'); } public static function FunctionExistsAndEnabled($mFunctionNameOrNames) : bool diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/Metadata.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/Metadata.php index 6aaa7b0e9..dacc310e8 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/Metadata.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/Metadata.php @@ -45,7 +45,7 @@ trait Metadata for ($i = 0; $i < $c; $i += 2) { $aMetadata[$oResponse->ResponseList[3][$i]] = $oResponse->ResponseList[3][$i+1]; } - $aReturn[$oResponse->ResponseList[2]] = $aMetadata; + $aReturn[$this->toUTF8($oResponse->ResponseList[2])] = $aMetadata; } } } catch (\Throwable $e) { @@ -75,7 +75,7 @@ trait Metadata } } - $arguments[] = $this->EscapeString($sFolderName); + $arguments[] = $this->EscapeFolderName($sFolderName); $arguments[] = '(' . \implode(' ', \array_map([$this, 'EscapeString'], $aEntries)) . ')'; @@ -118,7 +118,7 @@ trait Metadata throw new \MailSo\Base\Exceptions\InvalidArgumentException("Wrong argument for SETMETADATA command"); } - $arguments = [$this->EscapeString($sFolderName)]; + $arguments = [$this->EscapeFolderName($sFolderName)]; \array_walk($aEntries, function(&$v, $k){ $v = $this->EscapeString($k) . ' ' . $this->EscapeString($v); diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/Quota.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/Quota.php index 9915d751b..8fe235e71 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/Quota.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/Quota.php @@ -29,7 +29,7 @@ trait Quota public function Quota(string $sRootName = '') : ?array { return $this->IsSupported('QUOTA') - ? $this->SendRequestGetResponse("GETQUOTA {$this->EscapeString($sRootName)}")->getQuotaResult() + ? $this->getQuotaResult($this->SendRequestGetResponse("GETQUOTA {$this->EscapeFolderName($sRootName)}")) : null; } @@ -42,7 +42,45 @@ trait Quota public function QuotaRoot(string $sFolderName = 'INBOX') : ?array { return $this->IsSupported('QUOTA') - ? $this->SendRequestGetResponse("GETQUOTAROOT {$this->EscapeString($sFolderName)}")->getQuotaResult() + ? $this->getQuotaResult($this->SendRequestGetResponse("GETQUOTAROOT {$this->EscapeFolderName($sFolderName)}")) : null; } + + private function getQuotaResult(\MailSo\Imap\ResponseCollection $oResponseCollection) : array + { + $aReturn = array(0, 0); + foreach ($oResponseCollection as $oResponse) { + if (Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType + && 'QUOTA' === $oResponse->StatusOrIndex + && \is_array($oResponse->ResponseList) + && isset($oResponse->ResponseList[3]) + && \is_array($oResponse->ResponseList[3]) + && 2 < \count($oResponse->ResponseList[3]) + && 'STORAGE' === \strtoupper($oResponse->ResponseList[3][0]) + && \is_numeric($oResponse->ResponseList[3][1]) + && \is_numeric($oResponse->ResponseList[3][2]) + ) + { + $aReturn = array( + (int) $oResponse->ResponseList[3][1], + (int) $oResponse->ResponseList[3][2], + 0, + 0 + ); + + if (5 < \count($oResponse->ResponseList[3]) + && 'MESSAGE' === \strtoupper($oResponse->ResponseList[3][3]) + && \is_numeric($oResponse->ResponseList[3][4]) + && \is_numeric($oResponse->ResponseList[3][5]) + ) + { + $aReturn[2] = (int) $oResponse->ResponseList[3][4]; + $aReturn[3] = (int) $oResponse->ResponseList[3][5]; + } + } + } + + return $aReturn; + } + } diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Folder.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Folder.php index dc25071a8..2ebf45564 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Folder.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Folder.php @@ -23,12 +23,7 @@ class Folder /** * @var string */ - private $sNameRaw; - - /** - * @var string - */ - private $sFullNameRaw; + private $sFullName; /** * @var string @@ -48,15 +43,20 @@ class Folder /** * @throws \MailSo\Base\Exceptions\InvalidArgumentException */ - function __construct(string $sFullNameRaw, string $sDelimiter = null, array $aFlags = array()) + function __construct(string $sFullName, string $sDelimiter = null, array $aFlags = array()) { - if (!\strlen($sFullNameRaw)) { + if (!\strlen($sFullName)) { throw new \MailSo\Base\Exceptions\InvalidArgumentException; } - $this->sFullNameRaw = $sFullNameRaw; - + $this->sFullName = $sFullName; $this->setDelimiter($sDelimiter); $this->setFlags($aFlags); +/* + if (\in_array('\\noutf8', $this->aFlagsLowerCase)) { + } + if (\in_array('\\utf8only', $this->aFlagsLowerCase)) { + } +*/ } public function setFlags(array $aFlags) : void @@ -67,22 +67,21 @@ class Folder public function setDelimiter(?string $sDelimiter) : void { $this->sDelimiter = $sDelimiter; - if ($sDelimiter) { - $aNames = \explode($this->sDelimiter, $this->sFullNameRaw); - $this->sNameRaw = \end($aNames); - } else { - $this->sNameRaw = $this->sFullNameRaw; + } + + public function Name() : string + { + $sNameRaw = $this->sFullName; + if ($this->sDelimiter) { + $aNames = \explode($this->sDelimiter, $sNameRaw); + return \end($aNames); } + return $sNameRaw; } - public function NameRaw() : string + public function FullName() : string { - return $this->sNameRaw; - } - - public function FullNameRaw() : string - { - return $this->sFullNameRaw; + return $this->sFullName; } public function Delimiter() : ?string @@ -102,7 +101,7 @@ class Folder public function IsInbox() : bool { - return 'INBOX' === \strtoupper($this->sFullNameRaw) || \in_array('\\inbox', $this->aFlagsLowerCase); + return 'INBOX' === \strtoupper($this->sFullName) || \in_array('\\inbox', $this->aFlagsLowerCase); } /** diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ImapClient.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ImapClient.php index e71e23ca3..489281ee7 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ImapClient.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ImapClient.php @@ -66,6 +66,11 @@ class ImapClient extends \MailSo\Net\NetClient */ public $__FORCE_SELECT_ON_EXAMINE__ = false; + /** + * @var bool + */ + private $UTF8 = false; + function __construct() { \ini_set('xdebug.max_nesting_level', 500); @@ -248,11 +253,12 @@ class ImapClient extends \MailSo\Net\NetClient if ($this->IsSupported('IMAP4rev2')) { $this->SendRequestGetResponse('ENABLE', array('IMAP4rev1')); } - // TODO: RFC 6855 - if ($this->IsSupported('UTF8=ONLY')) { +*/ + // RFC 6855 || RFC 5738 + $this->UTF8 = $this->IsSupported('UTF8=ONLY') || $this->IsSupported('UTF8=ACCEPT'); + if ($this->UTF8) { $this->SendRequestGetResponse('ENABLE', array('UTF8=ACCEPT')); } -*/ } catch (Exceptions\NegativeResponseException $oException) { @@ -377,7 +383,7 @@ class ImapClient extends \MailSo\Net\NetClient public function FolderCreate(string $sFolderName) : self { $this->SendRequestGetResponse('CREATE', - array($this->EscapeString($sFolderName))); + array($this->EscapeFolderName($sFolderName))); return $this; } @@ -391,7 +397,7 @@ class ImapClient extends \MailSo\Net\NetClient // Uncomment will work issue #124 ? // $this->selectOrExamineFolder($sFolderName, true); $this->SendRequestGetResponse('DELETE', - array($this->EscapeString($sFolderName))); + array($this->EscapeFolderName($sFolderName))); // $this->FolderCheck(); // $this->FolderUnSelect(); return $this; @@ -405,7 +411,7 @@ class ImapClient extends \MailSo\Net\NetClient public function FolderSubscribe(string $sFolderName) : self { $this->SendRequestGetResponse('SUBSCRIBE', - array($this->EscapeString($sFolderName))); + array($this->EscapeFolderName($sFolderName))); return $this; } @@ -417,7 +423,7 @@ class ImapClient extends \MailSo\Net\NetClient public function FolderUnSubscribe(string $sFolderName) : self { $this->SendRequestGetResponse('UNSUBSCRIBE', - array($this->EscapeString($sFolderName))); + array($this->EscapeFolderName($sFolderName))); return $this; } @@ -429,8 +435,8 @@ class ImapClient extends \MailSo\Net\NetClient public function FolderRename(string $sOldFolderName, string $sNewFolderName) : self { $this->SendRequestGetResponse('RENAME', array( - $this->EscapeString($sOldFolderName), - $this->EscapeString($sNewFolderName))); + $this->EscapeFolderName($sOldFolderName), + $this->EscapeFolderName($sNewFolderName))); return $this; } @@ -465,8 +471,14 @@ class ImapClient extends \MailSo\Net\NetClient $bReselect = true; $this->FolderUnSelect(); } - $aResult = $this->SendRequestGetResponse('STATUS', array($this->EscapeString($sFolderName), $aStatusItems)) - ->getStatusFolderInformationResult(); + + $oResponseCollection = $this->SendRequestGetResponse('STATUS', array($this->EscapeFolderName($sFolderName), $aStatusItems)); + $oInfo = new FolderInformation($sFolderName, false); + foreach ($oResponseCollection as $oResponse) { + $oInfo->setStatusFromResponse($oResponse); + } + $aResult = $oInfo->getStatusItems(); + if ($bReselect) { $this->selectOrExamineFolder($sFolderName, $bWritable, false); } @@ -502,7 +514,7 @@ class ImapClient extends \MailSo\Net\NetClient } } - $aParameters[] = $this->EscapeString($sParentFolderName); + $aParameters[] = $this->EscapeFolderName($sParentFolderName); $aParameters[] = $this->EscapeString(\strlen(\trim($sListPattern)) ? $sListPattern : '*'); // RFC 5819 @@ -529,7 +541,11 @@ class ImapClient extends \MailSo\Net\NetClient $aReturnParams[] = 'STATUS'; $aReturnParams[] = $aL; } - +/* + if ($this->UTF8) { + $aReturnParams[] = 'UTF8'; // 'UTF8ONLY'; + } +*/ if ($aReturnParams) { $aParameters[] = 'RETURN'; $aParameters[] = $aReturnParams; @@ -540,7 +556,7 @@ class ImapClient extends \MailSo\Net\NetClient if ($bPassthru) { $this->streamResponse(); } else { - $aReturn = $this->getResponse()->getFoldersResult($sCmd); + $aReturn = $this->getResponse()->getFoldersResult($sCmd, $this); } // RFC 5464 @@ -549,15 +565,15 @@ class ImapClient extends \MailSo\Net\NetClient $aMetadata = $this->getAllMetadata(); if ($aMetadata) { foreach ($aReturn as $oFolder) { - if (isset($aMetadata[$oFolder->FullNameRaw()])) { - $oFolder->SetAllMetadata($aMetadata[$oFolder->FullNameRaw()]); + if (isset($aMetadata[$oFolder->FullName()])) { + $oFolder->SetAllMetadata($aMetadata[$oFolder->FullName()]); } } } else { foreach ($aReturn as $oFolder) { try { $oFolder->SetAllMetadata( - $this->getMetadata($oFolder->FullNameRaw(), ['/shared', '/private'], ['DEPTH'=>'infinity']) + $this->getMetadata($oFolder->FullName(), ['/shared', '/private'], ['DEPTH'=>'infinity']) ); } catch (\Throwable $e) { // Ignore error @@ -602,7 +618,7 @@ class ImapClient extends \MailSo\Net\NetClient */ public function FolderHierarchyDelimiter(string $sFolderName = '') : ?string { - $oResponse = $this->SendRequestGetResponse('LIST', ['""', $this->EscapeString($sFolderName)]); + $oResponse = $this->SendRequestGetResponse('LIST', ['""', $this->EscapeFolderName($sFolderName)]); return ('LIST' === $oResponse[0]->ResponseList[1]) ? $oResponse[0]->ResponseList[3] : null; } @@ -628,18 +644,57 @@ class ImapClient extends \MailSo\Net\NetClient throw new \MailSo\Base\Exceptions\InvalidArgumentException; } - $aParams = array($this->EscapeString($sFolderName)); + $aSelectParams = array(); /* if ($this->IsSupported('CONDSTORE')) { - $aParams[] = ['CONDSTORE']; + $aSelectParams[] = 'CONDSTORE'; + } + if ($this->UTF8) { + $aSelectParams[] = 'UTF8'; } */ + + $aParams = array( + $this->EscapeFolderName($sFolderName) + ); + if ($aSelectParams) { + $aParams[] = $aSelectParams; + } + /** * IMAP4rev2 SELECT/EXAMINE are now required to return an untagged LIST response. */ - $this->oCurrentFolderInfo = $this->SendRequestGetResponse($bIsWritable ? 'SELECT' : 'EXAMINE', - $aParams) - ->getCurrentFolderInformation($sFolderName, $bIsWritable); + $oResponseCollection = $this->SendRequestGetResponse($bIsWritable ? 'SELECT' : 'EXAMINE', $aParams); + $oResult = new FolderInformation($sFolderName, $bIsWritable); + foreach ($oResponseCollection as $oResponse) { + if (Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType) { + if (!$oResult->setStatusFromResponse($oResponse)) { + // OK untagged responses + if (\is_array($oResponse->OptionalResponse)) { + $key = $oResponse->OptionalResponse[0]; + if (\count($oResponse->OptionalResponse) > 1) { + if ('PERMANENTFLAGS' === $key && \is_array($oResponse->OptionalResponse[1])) { + $oResult->PermanentFlags = $oResponse->OptionalResponse[1]; + } + } else if ('READ-ONLY' === $key) { +// $oResult->IsWritable = false; + } else if ('READ-WRITE' === $key) { +// $oResult->IsWritable = true; + } else if ('NOMODSEQ' === $key) { + // https://datatracker.ietf.org/doc/html/rfc4551#section-3.1.2 + } + } + + // untagged responses + else if (\count($oResponse->ResponseList) > 2 + && 'FLAGS' === $oResponse->ResponseList[1] + && \is_array($oResponse->ResponseList[2])) { + $oResult->Flags = $oResponse->ResponseList[2]; + } + } + } + } + $this->oCurrentFolderInfo = $oResult; return $this; } @@ -885,7 +940,7 @@ class ImapClient extends \MailSo\Net\NetClient } $this->SendRequestGetResponse($bIndexIsUid ? 'UID COPY' : 'COPY', - array($sIndexRange, $this->EscapeString($sToFolder))); + array($sIndexRange, $this->EscapeFolderName($sToFolder))); return $this; } @@ -911,7 +966,7 @@ class ImapClient extends \MailSo\Net\NetClient } $this->SendRequestGetResponse($bIndexIsUid ? 'UID MOVE' : 'MOVE', - array($sIndexRange, $this->EscapeString($sToFolder))); + array($sIndexRange, $this->EscapeFolderName($sToFolder))); return $this; } @@ -972,7 +1027,7 @@ class ImapClient extends \MailSo\Net\NetClient */ public function MessageAppendStream(string $sFolderName, $rMessageAppendStream, int $iStreamSize, array $aAppendFlags = null, int &$iUid = null, int $iDateTime = 0) : self { - $aData = array($this->EscapeString($sFolderName), $aAppendFlags); + $aData = array($this->EscapeFolderName($sFolderName), $aAppendFlags); if (0 < $iDateTime) { $aData[] = $this->EscapeString(\gmdate('d-M-Y H:i:s', $iDateTime).' +0000'); @@ -1239,4 +1294,14 @@ class ImapClient extends \MailSo\Net\NetClient return 'UNKNOWN'; } + public function EscapeFolderName(string $sFolderName) : string + { + return $this->EscapeString($this->UTF8 ? $sFolderName : \MailSo\Base\Utils::Utf8ToUtf7Modified($sFolderName)); + } + + public function toUTF8(string $sText) : string + { + return $this->UTF8 ? $sText : \MailSo\Base\Utils::Utf7ModifiedToUtf8($sText); + } + } diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/NamespaceResult.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/NamespaceResult.php index d66d3d1e3..e0e74a9ab 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/NamespaceResult.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/NamespaceResult.php @@ -20,42 +20,32 @@ class NamespaceResult /** * @var string */ - private $sPersonal; + private $sPersonal = ''; /** * @var string */ - private $sPersonalDelimiter; + private $sPersonalDelimiter = ''; /** * @var string */ - private $sOtherUser; + private $sOtherUser = ''; /** * @var string */ - private $sOtherUserDelimiter; + private $sOtherUserDelimiter = ''; /** * @var string */ - private $sShared; + private $sShared = ''; /** * @var string */ - private $sSharedDelimiter; - - function __construct() - { - $this->sPersonal = ''; - $this->sPersonalDelimiter = ''; - $this->sOtherUser = ''; - $this->sOtherUserDelimiter = ''; - $this->sShared = ''; - $this->sSharedDelimiter = ''; - } + private $sSharedDelimiter = ''; public function InitByImapResponse(\MailSo\Imap\Response $oImapResponse) : self { @@ -103,8 +93,4 @@ class NamespaceResult return $this->sPersonal; } - public function GetPersonalNamespaceDelimiter() : string - { - return $this->sPersonalDelimiter; - } } diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ResponseCollection.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ResponseCollection.php index f0af06e70..ba517200a 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ResponseCollection.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ResponseCollection.php @@ -88,7 +88,7 @@ class ResponseCollection extends \MailSo\Base\Collection return $aReturn; } - public function getFoldersResult(string $sStatus) : array + public function getFoldersResult(string $sStatus, ImapClient $oImapClient) : array { $aReturn = array(); @@ -99,7 +99,7 @@ class ResponseCollection extends \MailSo\Base\Collection continue; } if ('STATUS' === $oResponse->StatusOrIndex && isset($oResponse->ResponseList[2])) { - $sFullNameRaw = $oResponse->ResponseList[2]; + $sFullNameRaw = $oImapClient->toUTF8($oResponse->ResponseList[2]); if (!isset($aReturn[$sFullNameRaw])) { $aReturn[$sFullNameRaw] = new Folder($sFullNameRaw); } @@ -108,14 +108,14 @@ class ResponseCollection extends \MailSo\Base\Collection else if ($sStatus === $oResponse->StatusOrIndex && 5 == \count($oResponse->ResponseList)) { try { - $sFullNameRaw = $oResponse->ResponseList[4]; + $sFullNameRaw = $oImapClient->toUTF8($oResponse->ResponseList[4]); /** * $oResponse->ResponseList[0] = * * $oResponse->ResponseList[1] = LIST (all) | LSUB (subscribed) * $oResponse->ResponseList[2] = Flags * $oResponse->ResponseList[3] = Delimiter - * $oResponse->ResponseList[4] = FullNameRaw + * $oResponse->ResponseList[4] = FullName */ if (!isset($aReturn[$sFullNameRaw])) { $oFolder = new Folder($sFullNameRaw, @@ -220,45 +220,6 @@ class ResponseCollection extends \MailSo\Base\Collection return $aReturn; } - /** - * Called by selectOrExamineFolder - */ - public function getCurrentFolderInformation(string $sFolderName, bool $bIsWritable) : FolderInformation - { - $oResult = new FolderInformation($sFolderName, $bIsWritable); - foreach ($this as $oResponse) { - if (Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType) { - if (!$oResult->setStatusFromResponse($oResponse)) { - // OK untagged responses - if (\is_array($oResponse->OptionalResponse)) { - $key = $oResponse->OptionalResponse[0]; - if (\count($oResponse->OptionalResponse) > 1) { - if ('PERMANENTFLAGS' === $key && \is_array($oResponse->OptionalResponse[1])) { - $oResult->PermanentFlags = $oResponse->OptionalResponse[1]; - } - } else if ('READ-ONLY' === $key) { -// $oResult->IsWritable = false; - } else if ('READ-WRITE' === $key) { -// $oResult->IsWritable = true; - } else if ('NOMODSEQ' === $key) { - // https://datatracker.ietf.org/doc/html/rfc4551#section-3.1.2 - } - } - - // untagged responses - else if (\count($oResponse->ResponseList) > 2) { - if ('FLAGS' === $oResponse->ResponseList[1] && \is_array($oResponse->ResponseList[2])) - { - $oResult->Flags = $oResponse->ResponseList[2]; - } - } - } - } - } - - return $oResult; - } - public function getNamespaceResult() : NamespaceResult { foreach ($this as $oResponse) { @@ -273,43 +234,6 @@ class ResponseCollection extends \MailSo\Base\Collection throw new Exceptions\ResponseException; } - public function getQuotaResult() : array - { - $aReturn = array(0, 0); - foreach ($this as $oResponse) { - if (Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType - && 'QUOTA' === $oResponse->StatusOrIndex - && \is_array($oResponse->ResponseList) - && isset($oResponse->ResponseList[3]) - && \is_array($oResponse->ResponseList[3]) - && 2 < \count($oResponse->ResponseList[3]) - && 'STORAGE' === \strtoupper($oResponse->ResponseList[3][0]) - && \is_numeric($oResponse->ResponseList[3][1]) - && \is_numeric($oResponse->ResponseList[3][2]) - ) - { - $aReturn = array( - (int) $oResponse->ResponseList[3][1], - (int) $oResponse->ResponseList[3][2], - 0, - 0 - ); - - if (5 < \count($oResponse->ResponseList[3]) - && 'MESSAGE' === \strtoupper($oResponse->ResponseList[3][3]) - && \is_numeric($oResponse->ResponseList[3][4]) - && \is_numeric($oResponse->ResponseList[3][5]) - ) - { - $aReturn[2] = (int) $oResponse->ResponseList[3][4]; - $aReturn[3] = (int) $oResponse->ResponseList[3][5]; - } - } - } - - return $aReturn; - } - public function getSimpleESearchOrESortResult(string $sRequestTag, bool $bReturnUid) : array { $aResult = array(); @@ -340,15 +264,6 @@ class ResponseCollection extends \MailSo\Base\Collection return $aResult; } - public function getStatusFolderInformationResult() : array - { - $oInfo = new FolderInformation('', false); - foreach ($this as $oResponse) { - $oInfo->setStatusFromResponse($oResponse); - } - return $oInfo->getStatusItems(); - } - /** * @param mixed $mValue * diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Responses/ACL.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Responses/ACL.php index a00f5c771..e8ef1674d 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Responses/ACL.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Responses/ACL.php @@ -3,7 +3,7 @@ /* * This file is part of MailSo. * - * (c) 2014 Usenko Timur + * (c) 2021 DJMaze * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Traits/Status.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Traits/Status.php index d3be7187b..8e0833c70 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Traits/Status.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Traits/Status.php @@ -112,10 +112,10 @@ trait Status * EXAMINE https://datatracker.ietf.org/doc/html/rfc3501#section-6.3.2 * STATUS https://datatracker.ietf.org/doc/html/rfc3501#section-6.3.10 * - * getCurrentFolderInformation + * selectOrExamineFolder * ResponseList[2] => EXISTS | RECENT * OptionalResponse[0] => UNSEEN - * getStatusFolderInformationResult + * FolderStatus * OptionalResponse[0] => HIGHESTMODSEQ * ResponseList[1] => STATUS * getFoldersResult LIST-EXTENDED diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Folder.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Folder.php index 5de1f4344..9ad7571d2 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Folder.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Folder.php @@ -20,16 +20,6 @@ use MailSo\Imap\Enumerations\MetadataKeys; */ class Folder implements \JsonSerializable { - /** - * @var string - */ - private $sParentFullNameRaw; - - /** - * @var int - */ - private $iNestingLevel; - /** * @var bool */ @@ -48,7 +38,7 @@ class Folder implements \JsonSerializable /** * @var \MailSo\Mail\FolderCollection */ - private $oSubFolders; + private $oSubFolders = null; /** * @throws \MailSo\Base\Exceptions\InvalidArgumentException @@ -56,18 +46,6 @@ class Folder implements \JsonSerializable function __construct(\MailSo\Imap\Folder $oImapFolder, bool $bSubscribed = true, bool $bExists = true) { $this->oImapFolder = $oImapFolder; - $this->oSubFolders = null; - - $aNames = \explode($this->oImapFolder->Delimiter(), $this->oImapFolder->FullNameRaw()); - $this->iNestingLevel = \count($aNames); - - $this->sParentFullNameRaw = ''; - if (1 < $this->iNestingLevel) - { - \array_pop($aNames); - $this->sParentFullNameRaw = \implode($this->oImapFolder->Delimiter(), $aNames); - } - $this->bSubscribed = $bSubscribed || \in_array('\\subscribed', $oImapFolder->FlagsLowerCase()); $this->bExists = $bExists; } @@ -84,16 +62,12 @@ class Folder implements \JsonSerializable public function Name() : string { - return \MailSo\Base\Utils::ConvertEncoding($this->NameRaw(), - \MailSo\Base\Enumerations\Charset::UTF_7_IMAP, - \MailSo\Base\Enumerations\Charset::UTF_8); + return $this->oImapFolder->Name(); } public function FullName() : string { - return \MailSo\Base\Utils::ConvertEncoding($this->FullNameRaw(), - \MailSo\Base\Enumerations\Charset::UTF_7_IMAP, - \MailSo\Base\Enumerations\Charset::UTF_8); + return $this->oImapFolder->FullName(); } public function NameRaw() : string @@ -101,23 +75,6 @@ class Folder implements \JsonSerializable return $this->oImapFolder->NameRaw(); } - public function FullNameRaw() : string - { - return $this->oImapFolder->FullNameRaw(); - } - - public function ParentFullName() : string - { - return \MailSo\Base\Utils::ConvertEncoding($this->sParentFullNameRaw, - \MailSo\Base\Enumerations\Charset::UTF_7_IMAP, - \MailSo\Base\Enumerations\Charset::UTF_8); - } - - public function ParentFullNameRaw() : string - { - return $this->sParentFullNameRaw; - } - public function Delimiter() : string { return $this->oImapFolder->Delimiter(); @@ -188,7 +145,7 @@ class Folder implements \JsonSerializable switch (true) { - case \in_array('\\inbox', $aFlags) || 'INBOX' === \strtoupper($this->FullNameRaw()): + case \in_array('\\inbox', $aFlags) || 'INBOX' === \strtoupper($this->FullName()): return FolderType::INBOX; case \in_array('\\sent', $aFlags): @@ -221,7 +178,7 @@ class Folder implements \JsonSerializable return FolderType::ALL; // TODO -// case 'Templates' === $this->FullNameRaw(): +// case 'Templates' === $this->FullName(): // return FolderType::TEMPLATES; } @@ -287,7 +244,7 @@ class Folder implements \JsonSerializable 'MessageUnseenCount' => (int) $aStatus['UNSEEN'], 'UidNext' => (int) $aStatus['UIDNEXT'], // 'Hash' => $this->MailClient()->GenerateFolderHash( -// $this->FullNameRaw(), $aStatus['MESSAGES'], $aStatus['UIDNEXT'], +// $this->FullName(), $aStatus['MESSAGES'], $aStatus['UIDNEXT'], // empty($aStatus['HIGHESTMODSEQ']) ? 0 : $aStatus['HIGHESTMODSEQ']) ); } @@ -296,7 +253,6 @@ class Folder implements \JsonSerializable '@Object' => 'Object/Folder', 'Name' => $this->Name(), 'FullName' => $this->FullName(), - 'FullNameRaw' => $this->FullNameRaw(), 'Delimiter' => (string) $this->Delimiter(), // 'HasVisibleSubFolders' => $this->HasVisibleSubFolders(), 'Subscribed' => $this->bSubscribed, diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/FolderCollection.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/FolderCollection.php index 99dcacc64..0693c485a 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/FolderCollection.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/FolderCollection.php @@ -57,7 +57,7 @@ class FolderCollection extends \MailSo\Base\Collection $mResult = null; foreach ($this as $oFolder) { - if ($oFolder->FullNameRaw() === $sFullNameRaw) + if ($oFolder->FullName() === $sFullNameRaw) { $mResult = $oFolder; break; @@ -119,7 +119,7 @@ class FolderCollection extends \MailSo\Base\Collection { foreach ($this as $oItemFolder) { - if (0 === \strpos($oMailFolder->FullNameRaw(), $oItemFolder->FullNameRaw().$oItemFolder->Delimiter())) + if (0 === \strpos($oMailFolder->FullName(), $oItemFolder->FullName().$oItemFolder->Delimiter())) { $oItemFolder->SubFolders(true)->AddWithPositionSearch($oMailFolder); return; diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php index 900d576c0..da406f385 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php @@ -1219,7 +1219,7 @@ class MailClient $aImapSubscribedFoldersHelper = array(); foreach ($aSubscribedFolders as /* @var $oImapFolder \MailSo\Imap\Folder */ $oImapFolder) { - $aImapSubscribedFoldersHelper[] = $oImapFolder->FullNameRaw(); + $aImapSubscribedFoldersHelper[] = $oImapFolder->FullName(); } } catch (\Throwable $oException) @@ -1253,13 +1253,13 @@ class MailClient foreach ($aFolders as /* @var $oImapFolder \MailSo\Imap\Folder */ $oImapFolder) { $oMailFolder = new Folder($oImapFolder, - ($bUseListSubscribeStatus && (null === $aImapSubscribedFoldersHelper || \in_array($oImapFolder->FullNameRaw(), $aImapSubscribedFoldersHelper))) + ($bUseListSubscribeStatus && (null === $aImapSubscribedFoldersHelper || \in_array($oImapFolder->FullName(), $aImapSubscribedFoldersHelper))) || $oImapFolder->IsInbox() ); if ($oImapFolder->IsInbox()) { - $sINBOX = $oMailFolder->FullNameRaw(); + $sINBOX = $oMailFolder->FullName(); } - $aSortedByLenImapFolders[$oMailFolder->FullNameRaw()] = $oMailFolder; + $aSortedByLenImapFolders[$oMailFolder->FullName()] = $oMailFolder; } // Add NonExistent folders @@ -1267,7 +1267,7 @@ class MailClient foreach ($aSortedByLenImapFolders as /* @var $oMailFolder Folder */ $oMailFolder) { $sDelimiter = $oMailFolder->Delimiter(); - $aFolderExplode = \explode($sDelimiter, $oMailFolder->FullNameRaw()); + $aFolderExplode = \explode($sDelimiter, $oMailFolder->FullName()); if (1 < \count($aFolderExplode)) { @@ -1418,7 +1418,7 @@ class MailClient $aSubscribeFolders = $this->oImapClient->FolderSubscribeList($sPrevFolderFullNameRaw, '*'); foreach ($aSubscribeFolders as /* @var $oFolder \MailSo\Imap\Folder */ $oFolder) { - $this->oImapClient->FolderUnSubscribe($oFolder->FullNameRaw()); + $this->oImapClient->FolderUnSubscribe($oFolder->FullName()); } } @@ -1442,7 +1442,7 @@ class MailClient foreach ($aSubscribeFolders as /* @var $oFolder \MailSo\Imap\Folder */ $oFolder) { - $sFolderFullNameRawForResubscrine = $oFolder->FullNameRaw(); + $sFolderFullNameRawForResubscrine = $oFolder->FullName(); if (0 === \strpos($sFolderFullNameRawForResubscrine, $sPrevFolderFullNameRaw)) { $sNewFolderFullNameRawForResubscrine = $sNewFolderFullNameRaw. diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Folders.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Folders.php index 81ad26c76..32364fdda 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Folders.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Folders.php @@ -460,7 +460,7 @@ trait Folders { foreach ($oFolders as $oFolder) { - $aResult[] = $oFolder->FullNameRaw()."|". + $aResult[] = $oFolder->FullName()."|". implode("|", $oFolder->FlagsLowerCase()).($oFolder->IsSubscribed() ? '1' : '0'); $oSub = $oFolder->SubFolders(); @@ -492,7 +492,7 @@ trait Folders FolderType::ARCHIVE ))) { - $aResult[$iFolderType] = $oFolder->FullNameRaw(); + $aResult[$iFolderType] = $oFolder->FullName(); } } @@ -524,7 +524,7 @@ trait Folders FolderType::ARCHIVE ))) { - $aResult[$iFolderType] = $oFolder->FullNameRaw(); + $aResult[$iFolderType] = $oFolder->FullName(); } } } diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Response.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Response.php index 25cd6eb1c..b1e942fd4 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Response.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Response.php @@ -373,7 +373,7 @@ trait Response 'MessageUnseenCount' => (int) $aStatus['UNSEEN'], 'UidNext' => (int) $aStatus['UIDNEXT'], 'Hash' => $this->MailClient()->GenerateFolderHash( - $mResponse->FullNameRaw(), $aStatus['MESSAGES'], $aStatus['UIDNEXT'], + $mResponse->FullName(), $aStatus['MESSAGES'], $aStatus['UIDNEXT'], empty($aStatus['HIGHESTMODSEQ']) ? 0 : $aStatus['HIGHESTMODSEQ']) ); } @@ -394,8 +394,8 @@ trait Response return \array_merge( $mResponse->jsonSerialize(), array( - 'FullNameHash' => $this->hashFolderFullName($mResponse->FullNameRaw(), $mResponse->FullName()), - 'Checkable' => \in_array($mResponse->FullNameRaw(), $this->aCheckableFolder), + 'FullNameHash' => $this->hashFolderFullName($mResponse->FullName(), $mResponse->FullName()), + 'Checkable' => \in_array($mResponse->FullName(), $this->aCheckableFolder), 'Extended' => $aExtended, 'SubFolders' => $this->responseObject($mResponse->SubFolders(), $sParent, $aParameters) )