mirror of
https://github.com/the-djmaze/snappymail.git
synced 2025-11-06 05:20:25 +08:00
Revamp the FullNameHash system for better readable urls
And reduce the folders caching footprint. And it reduces server load.
This commit is contained in:
parent
76627ae2f6
commit
3a61bb3e5a
10 changed files with 90 additions and 78 deletions
|
|
@ -657,20 +657,20 @@ class AppUser extends AbstractApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} sFullNameHash
|
* @param {string} sFullName
|
||||||
* @param {boolean} bExpanded
|
* @param {boolean} bExpanded
|
||||||
*/
|
*/
|
||||||
setExpandedFolder(sFullNameHash, bExpanded) {
|
setExpandedFolder(sFullName, bExpanded) {
|
||||||
let aExpandedList = Local.get(ClientSideKeyName.ExpandedFolders);
|
let aExpandedList = Local.get(ClientSideKeyName.ExpandedFolders);
|
||||||
if (!isArray(aExpandedList)) {
|
if (!isArray(aExpandedList)) {
|
||||||
aExpandedList = [];
|
aExpandedList = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bExpanded) {
|
if (bExpanded) {
|
||||||
if (!aExpandedList.includes(sFullNameHash))
|
if (!aExpandedList.includes(sFullName))
|
||||||
aExpandedList.push(sFullNameHash);
|
aExpandedList.push(sFullName);
|
||||||
} else {
|
} else {
|
||||||
aExpandedList = aExpandedList.filter(value => value !== sFullNameHash);
|
aExpandedList = aExpandedList.filter(value => value !== sFullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Local.set(ClientSideKeyName.ExpandedFolders, aExpandedList);
|
Local.set(ClientSideKeyName.ExpandedFolders, aExpandedList);
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,6 @@ import { isArray } from 'Common/Utils';
|
||||||
|
|
||||||
let FOLDERS_CACHE = {},
|
let FOLDERS_CACHE = {},
|
||||||
FOLDERS_NAME_CACHE = {},
|
FOLDERS_NAME_CACHE = {},
|
||||||
FOLDERS_HASH_CACHE = {},
|
|
||||||
FOLDERS_UID_NEXT_CACHE = {},
|
|
||||||
MESSAGE_FLAGS_CACHE = {},
|
MESSAGE_FLAGS_CACHE = {},
|
||||||
NEW_MESSAGE_CACHE = {},
|
NEW_MESSAGE_CACHE = {},
|
||||||
REQUESTED_MESSAGE_CACHE = {},
|
REQUESTED_MESSAGE_CACHE = {},
|
||||||
|
|
@ -17,8 +15,6 @@ export const
|
||||||
clearCache = () => {
|
clearCache = () => {
|
||||||
FOLDERS_CACHE = {};
|
FOLDERS_CACHE = {};
|
||||||
FOLDERS_NAME_CACHE = {};
|
FOLDERS_NAME_CACHE = {};
|
||||||
FOLDERS_HASH_CACHE = {};
|
|
||||||
FOLDERS_UID_NEXT_CACHE = {};
|
|
||||||
MESSAGE_FLAGS_CACHE = {};
|
MESSAGE_FLAGS_CACHE = {};
|
||||||
NEW_MESSAGE_CACHE = {};
|
NEW_MESSAGE_CACHE = {};
|
||||||
REQUESTED_MESSAGE_CACHE = {};
|
REQUESTED_MESSAGE_CACHE = {};
|
||||||
|
|
@ -89,9 +85,10 @@ export const
|
||||||
* @param {string} folderFullName
|
* @param {string} folderFullName
|
||||||
* @param {?FolderModel} folder
|
* @param {?FolderModel} folder
|
||||||
*/
|
*/
|
||||||
setFolder = (folderHash, folderFullName, folder) => {
|
setFolder = folder => {
|
||||||
FOLDERS_CACHE[folderFullName] = folder;
|
folder.hash = '';
|
||||||
FOLDERS_NAME_CACHE[folderHash] = folderFullName;
|
FOLDERS_CACHE[folder.fullName] = folder;
|
||||||
|
FOLDERS_NAME_CACHE[folder.fullNameHash] = folder.fullName;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -99,37 +96,35 @@ export const
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
getFolderHash = folderFullName =>
|
getFolderHash = folderFullName =>
|
||||||
folderFullName && FOLDERS_HASH_CACHE[folderFullName] ? FOLDERS_HASH_CACHE[folderFullName] : '',
|
FOLDERS_CACHE[folderFullName] ? FOLDERS_CACHE[folderFullName].hash : '',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} folderFullName
|
* @param {string} folderFullName
|
||||||
* @param {string} folderHash
|
* @param {string} folderHash
|
||||||
*/
|
*/
|
||||||
setFolderHash = (folderFullName, folderHash) =>
|
setFolderHash = (folderFullName, folderHash) =>
|
||||||
folderFullName && (FOLDERS_HASH_CACHE[folderFullName] = folderHash),
|
FOLDERS_CACHE[folderFullName] && (FOLDERS_CACHE[folderFullName].hash = folderHash),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} folderFullName
|
* @param {string} folderFullName
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
getFolderUidNext = folderFullName =>
|
getFolderUidNext = folderFullName =>
|
||||||
folderFullName && FOLDERS_UID_NEXT_CACHE[folderFullName]
|
FOLDERS_CACHE[folderFullName] ? FOLDERS_CACHE[folderFullName].uidNext : 0,
|
||||||
? FOLDERS_UID_NEXT_CACHE[folderFullName]
|
|
||||||
: '',
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} folderFullName
|
* @param {string} folderFullName
|
||||||
* @param {string} uidNext
|
* @param {string} uidNext
|
||||||
*/
|
*/
|
||||||
setFolderUidNext = (folderFullName, uidNext) =>
|
setFolderUidNext = (folderFullName, uidNext) =>
|
||||||
FOLDERS_UID_NEXT_CACHE[folderFullName] = uidNext,
|
FOLDERS_CACHE[folderFullName] && (FOLDERS_CACHE[folderFullName].uidNext = uidNext),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} folderFullName
|
* @param {string} folderFullName
|
||||||
* @returns {?FolderModel}
|
* @returns {?FolderModel}
|
||||||
*/
|
*/
|
||||||
getFolderFromCacheList = folderFullName =>
|
getFolderFromCacheList = folderFullName =>
|
||||||
folderFullName && FOLDERS_CACHE[folderFullName] ? FOLDERS_CACHE[folderFullName] : null,
|
FOLDERS_CACHE[folderFullName] ? FOLDERS_CACHE[folderFullName] : null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} folderFullName
|
* @param {string} folderFullName
|
||||||
|
|
@ -156,9 +151,7 @@ export class MessageFlagsCache
|
||||||
* @returns {?Array}
|
* @returns {?Array}
|
||||||
*/
|
*/
|
||||||
static getFor(folderFullName, uid) {
|
static getFor(folderFullName, uid) {
|
||||||
return MESSAGE_FLAGS_CACHE[folderFullName] && MESSAGE_FLAGS_CACHE[folderFullName][uid]
|
return MESSAGE_FLAGS_CACHE[folderFullName] && MESSAGE_FLAGS_CACHE[folderFullName][uid];
|
||||||
? MESSAGE_FLAGS_CACHE[folderFullName][uid]
|
|
||||||
: null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
2
dev/External/User/ko.js
vendored
2
dev/External/User/ko.js
vendored
|
|
@ -132,7 +132,7 @@ ko.bindingHandlers.dropmessages = {
|
||||||
if (folder && folder.collapsed()) {
|
if (folder && folder.collapsed()) {
|
||||||
dragTimer.start(() => {
|
dragTimer.start(() => {
|
||||||
folder.collapsed(false);
|
folder.collapsed(false);
|
||||||
rl.app.setExpandedFolder(folder.fullNameHash, true);
|
rl.app.setExpandedFolder(folder.fullName, true);
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { AbstractCollectionModel } from 'Model/AbstractCollection';
|
import { AbstractCollectionModel } from 'Model/AbstractCollection';
|
||||||
|
|
||||||
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
|
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
|
||||||
import { isArray, getKeyByValue, forEachObjectEntry } from 'Common/Utils';
|
import { isArray, getKeyByValue, forEachObjectEntry, b64EncodeJSONSafe } from 'Common/Utils';
|
||||||
import { ClientSideKeyName, FolderType, FolderMetadataKeys } from 'Common/EnumsUser';
|
import { ClientSideKeyName, FolderType, FolderMetadataKeys } from 'Common/EnumsUser';
|
||||||
import * as Cache from 'Common/Cache';
|
import * as Cache from 'Common/Cache';
|
||||||
import { Settings, SettingsGet } from 'Common/Globals';
|
import { Settings, SettingsGet } from 'Common/Globals';
|
||||||
|
|
@ -79,7 +79,7 @@ export class FolderCollectionModel extends AbstractCollectionModel
|
||||||
oCacheFolder.type(FolderType.Inbox);
|
oCacheFolder.type(FolderType.Inbox);
|
||||||
Cache.setFolderInboxName(oFolder.FullName);
|
Cache.setFolderInboxName(oFolder.FullName);
|
||||||
}
|
}
|
||||||
Cache.setFolder(oCacheFolder.fullNameHash, oFolder.FullName, oCacheFolder);
|
Cache.setFolder(oCacheFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (1 < type) {
|
if (1 < type) {
|
||||||
|
|
@ -88,7 +88,7 @@ export class FolderCollectionModel extends AbstractCollectionModel
|
||||||
|
|
||||||
oCacheFolder.collapsed(!expandedFolders
|
oCacheFolder.collapsed(!expandedFolders
|
||||||
|| !isArray(expandedFolders)
|
|| !isArray(expandedFolders)
|
||||||
|| !expandedFolders.includes(oCacheFolder.fullNameHash));
|
|| !expandedFolders.includes(oCacheFolder.fullName));
|
||||||
|
|
||||||
if (oFolder.Extended) {
|
if (oFolder.Extended) {
|
||||||
if (oFolder.Extended.Hash) {
|
if (oFolder.Extended.Hash) {
|
||||||
|
|
@ -180,7 +180,6 @@ export class FolderModel extends AbstractModel {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.fullName = '';
|
this.fullName = '';
|
||||||
this.fullNameHash = '';
|
|
||||||
this.delimiter = '';
|
this.delimiter = '';
|
||||||
this.deep = 0;
|
this.deep = 0;
|
||||||
this.expires = 0;
|
this.expires = 0;
|
||||||
|
|
@ -188,6 +187,9 @@ export class FolderModel extends AbstractModel {
|
||||||
|
|
||||||
this.exists = true;
|
this.exists = true;
|
||||||
|
|
||||||
|
// this.hash = '';
|
||||||
|
// this.uidNext = 0;
|
||||||
|
|
||||||
this.addObservables({
|
this.addObservables({
|
||||||
name: '',
|
name: '',
|
||||||
type: FolderType.User,
|
type: FolderType.User,
|
||||||
|
|
@ -218,6 +220,14 @@ export class FolderModel extends AbstractModel {
|
||||||
this.actionBlink = ko.observable(false).extend({ falseTimeout: 1000 });
|
this.actionBlink = ko.observable(false).extend({ falseTimeout: 1000 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For url safe '/#/mailbox/...' path
|
||||||
|
*/
|
||||||
|
get fullNameHash() {
|
||||||
|
return this.fullName.replace(/[^a-z0-9._-]+/giu, b64EncodeJSONSafe);
|
||||||
|
// return /^[a-z0-9._-]+$/iu.test(this.fullName) ? this.fullName : b64EncodeJSONSafe(this.fullName);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @static
|
* @static
|
||||||
* @param {FetchJsonFolder} json
|
* @param {FetchJsonFolder} json
|
||||||
|
|
|
||||||
|
|
@ -135,10 +135,11 @@ export class MailBoxUserScreen extends AbstractScreen {
|
||||||
|
|
||||||
return [
|
return [
|
||||||
[/^([^/]*)$/, { normalize_: fNormS }],
|
[/^([^/]*)$/, { normalize_: fNormS }],
|
||||||
[/^([a-zA-Z0-9~]+)\/(.+)\/?$/, { normalize_: (request, vals) =>
|
// Regex the fullNameHash
|
||||||
|
[/^([a-zA-Z0-9.~_-]+)\/(.+)\/?$/, { normalize_: (request, vals) =>
|
||||||
[folder(request, vals), 1, decodeURI(pString(vals[1]))]
|
[folder(request, vals), 1, decodeURI(pString(vals[1]))]
|
||||||
}],
|
}],
|
||||||
[/^([a-zA-Z0-9~]+)\/p([1-9][0-9]*)(?:\/(.+)\/?)?$/, { normalize_: fNormS }]
|
[/^([a-zA-Z0-9.~_-]+)\/p([1-9][0-9]*)(?:\/(.+)\/?)?$/, { normalize_: fNormS }]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { ClientSideKeyName, FolderMetadataKeys } from 'Common/EnumsUser';
|
||||||
import { Settings } from 'Common/Globals';
|
import { Settings } from 'Common/Globals';
|
||||||
import { getNotification } from 'Common/Translator';
|
import { getNotification } from 'Common/Translator';
|
||||||
|
|
||||||
import { removeFolderFromCacheList } from 'Common/Cache';
|
import { setFolder, removeFolderFromCacheList } from 'Common/Cache';
|
||||||
import { Capa } from 'Common/Enums';
|
import { Capa } from 'Common/Enums';
|
||||||
import { defaultOptionsAfterRender } from 'Common/Utils';
|
import { defaultOptionsAfterRender } from 'Common/Utils';
|
||||||
import { initOnStartOrLangChange, i18n } from 'Common/Translator';
|
import { initOnStartOrLangChange, i18n } from 'Common/Translator';
|
||||||
|
|
@ -71,18 +71,28 @@ export class FoldersUserSettings /*extends AbstractViewSettings*/ {
|
||||||
|
|
||||||
if (nameToEdit && folder.name() !== nameToEdit) {
|
if (nameToEdit && folder.name() !== nameToEdit) {
|
||||||
Local.set(ClientSideKeyName.FoldersLashHash, '');
|
Local.set(ClientSideKeyName.FoldersLashHash, '');
|
||||||
|
Remote
|
||||||
rl.app.foldersPromisesActionHelper(
|
.post('FolderRename', FolderUserStore.foldersRenaming, {
|
||||||
Remote.post('FolderRename', FolderUserStore.foldersRenaming, {
|
|
||||||
Folder: folder.fullName,
|
Folder: folder.fullName,
|
||||||
NewFolderName: nameToEdit
|
NewFolderName: nameToEdit
|
||||||
}),
|
})
|
||||||
Notification.CantRenameFolder
|
.then(data => {
|
||||||
);
|
folder.name(nameToEdit/*data.Name*/);
|
||||||
|
if (folder.subFolders.length) {
|
||||||
|
Remote.foldersReloadWithTimeout();
|
||||||
|
// rename all subfolders folder.delimiter
|
||||||
|
} else {
|
||||||
removeFolderFromCacheList(folder.fullName);
|
removeFolderFromCacheList(folder.fullName);
|
||||||
|
data = data.Result;
|
||||||
folder.name(nameToEdit);
|
folder.fullName = data.FullName;
|
||||||
|
setFolder(folder);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
FolderUserStore.folderListError(
|
||||||
|
getNotification(error.code, '', Notification.CantRenameFolder)
|
||||||
|
+ '.\n' + error.message);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
folder.edited(false);
|
folder.edited(false);
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ export class MailFolderList extends AbstractViewLeft {
|
||||||
const folder = ko.dataFor(el);
|
const folder = ko.dataFor(el);
|
||||||
if (folder) {
|
if (folder) {
|
||||||
const collapsed = folder.collapsed();
|
const collapsed = folder.collapsed();
|
||||||
rl.app.setExpandedFolder(folder.fullNameHash, collapsed);
|
rl.app.setExpandedFolder(folder.fullName, collapsed);
|
||||||
|
|
||||||
folder.collapsed(!collapsed);
|
folder.collapsed(!collapsed);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
@ -151,7 +151,7 @@ export class MailFolderList extends AbstractViewLeft {
|
||||||
folder = item && ko.dataFor(item);
|
folder = item && ko.dataFor(item);
|
||||||
if (folder) {
|
if (folder) {
|
||||||
const collapsed = folder.collapsed();
|
const collapsed = folder.collapsed();
|
||||||
rl.app.setExpandedFolder(folder.fullNameHash, collapsed);
|
rl.app.setExpandedFolder(folder.fullName, collapsed);
|
||||||
folder.collapsed(!collapsed);
|
folder.collapsed(!collapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1361,22 +1361,43 @@ class MailClient
|
||||||
*/
|
*/
|
||||||
public function FolderMove(string $sPrevFolderFullName, string $sNextFolderFullNameInUtf, bool $bSubscribeOnMove = true) : self
|
public function FolderMove(string $sPrevFolderFullName, string $sNextFolderFullNameInUtf, bool $bSubscribeOnMove = true) : self
|
||||||
{
|
{
|
||||||
return $this->folderModify($sPrevFolderFullName, $sNextFolderFullNameInUtf, false, $bSubscribeOnMove);
|
if (!$this->oImapClient->FolderHierarchyDelimiter($sPrevFolderFullName)) {
|
||||||
|
// TODO: Translate
|
||||||
|
throw new Exceptions\RuntimeException('Cannot move non-existent folder.');
|
||||||
|
}
|
||||||
|
return $this->folderModify($sPrevFolderFullName, $sNextFolderFullNameInUtf, $bSubscribeOnMove);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
|
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function FolderRename(string $sPrevFolderFullName, string $sNewTopFolderNameInUtf, bool $bSubscribeOnRename = true) : self
|
public function FolderRename(string $sPrevFolderFullName, string $sNewTopFolderNameInUtf, bool $bSubscribeOnRename = true) : string
|
||||||
{
|
{
|
||||||
return $this->folderModify($sPrevFolderFullName, $sNewTopFolderNameInUtf, true, $bSubscribeOnRename);
|
$sDelimiter = $this->oImapClient->FolderHierarchyDelimiter($sPrevFolderFullName);
|
||||||
|
if (!$sDelimiter) {
|
||||||
|
// TODO: Translate
|
||||||
|
throw new Exceptions\RuntimeException('Cannot rename non-existent folder.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (\strlen($sDelimiter) && false !== \strpos($sNewTopFolderNameInUtf, $sDelimiter)) {
|
||||||
|
// TODO: Translate
|
||||||
|
throw new Exceptions\RuntimeException('New folder name contains delimiter.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$iLast = \strrpos($sPrevFolderFullName, $sDelimiter);
|
||||||
|
$sNewFolderFullName = (false === $iLast ? '' : \substr($sPrevFolderFullName, 0, $iLast + 1))
|
||||||
|
. $sNewTopFolderNameInUtf;
|
||||||
|
|
||||||
|
$this->folderModify($sPrevFolderFullName, $sNewFolderFullName, $bSubscribeOnRename);
|
||||||
|
|
||||||
|
return $sNewFolderFullName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
|
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
|
||||||
* @throws \MailSo\Base\Exceptions\RuntimeException
|
* @throws \MailSo\Base\Exceptions\RuntimeException
|
||||||
*/
|
*/
|
||||||
protected function folderModify(string $sPrevFolderFullName, string $sNewFolderFullName, bool $bRename, bool $bSubscribeOnModify) : self
|
protected function folderModify(string $sPrevFolderFullName, string $sNewFolderFullName, bool $bSubscribe) : self
|
||||||
{
|
{
|
||||||
if (!\strlen($sPrevFolderFullName) || !\strlen($sNewFolderFullName))
|
if (!\strlen($sPrevFolderFullName) || !\strlen($sNewFolderFullName))
|
||||||
{
|
{
|
||||||
|
|
@ -1384,7 +1405,7 @@ class MailClient
|
||||||
}
|
}
|
||||||
|
|
||||||
$aSubscribeFolders = array();
|
$aSubscribeFolders = array();
|
||||||
if ($bSubscribeOnModify)
|
if ($bSubscribe)
|
||||||
{
|
{
|
||||||
$aSubscribeFolders = $this->oImapClient->FolderSubscribeList($sPrevFolderFullName, '*');
|
$aSubscribeFolders = $this->oImapClient->FolderSubscribeList($sPrevFolderFullName, '*');
|
||||||
foreach ($aSubscribeFolders as /* @var $oFolder \MailSo\Imap\Folder */ $oFolder)
|
foreach ($aSubscribeFolders as /* @var $oFolder \MailSo\Imap\Folder */ $oFolder)
|
||||||
|
|
@ -1393,27 +1414,6 @@ class MailClient
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($bRename)
|
|
||||||
{
|
|
||||||
$sDelimiter = $this->oImapClient->FolderHierarchyDelimiter($sPrevFolderFullName);
|
|
||||||
if (!$sDelimiter)
|
|
||||||
{
|
|
||||||
// TODO: Translate
|
|
||||||
throw new Exceptions\RuntimeException('Cannot '.($bRename?'rename':'move').' non-existent folder.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$iLast = \strrpos($sPrevFolderFullName, $sDelimiter);
|
|
||||||
|
|
||||||
if (\strlen($sDelimiter) && false !== \strpos($sNewFolderFullName, $sDelimiter))
|
|
||||||
{
|
|
||||||
// TODO: Translate
|
|
||||||
throw new Exceptions\RuntimeException('New folder name contains delimiter.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$sNewFolderFullName = (false === $iLast ? '' : \substr($sPrevFolderFullName, 0, $iLast + 1))
|
|
||||||
. $sNewFolderFullName;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->oImapClient->FolderRename($sPrevFolderFullName, $sNewFolderFullName);
|
$this->oImapClient->FolderRename($sPrevFolderFullName, $sNewFolderFullName);
|
||||||
|
|
||||||
foreach ($aSubscribeFolders as /* @var $oFolder \MailSo\Imap\Folder */ $oFolder)
|
foreach ($aSubscribeFolders as /* @var $oFolder \MailSo\Imap\Folder */ $oFolder)
|
||||||
|
|
|
||||||
|
|
@ -320,11 +320,12 @@ trait Folders
|
||||||
{
|
{
|
||||||
$this->initMailClientConnection();
|
$this->initMailClientConnection();
|
||||||
|
|
||||||
|
$sName = $this->GetActionParam('NewFolderName', '');
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
$this->MailClient()->FolderRename(
|
$sFullName = $this->MailClient()->FolderRename(
|
||||||
$this->GetActionParam('Folder', ''),
|
$this->GetActionParam('Folder', ''),
|
||||||
$this->GetActionParam('NewFolderName', ''),
|
$sName,
|
||||||
!!$this->Config()->Get('labs', 'use_imap_list_subscribe', true)
|
!!$this->Config()->Get('labs', 'use_imap_list_subscribe', true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -333,7 +334,11 @@ trait Folders
|
||||||
throw new ClientException(Notifications::CantRenameFolder, $oException);
|
throw new ClientException(Notifications::CantRenameFolder, $oException);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->TrueResponse(__FUNCTION__);
|
// FolderInformation(string $sFolderName, int $iPrevUidNext = 0, array $aUids = array())
|
||||||
|
return $this->DefaultResponse(__FUNCTION__, array(
|
||||||
|
'Name' => $sName,
|
||||||
|
'FullName' => $sFullName,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -139,12 +139,6 @@ trait Response
|
||||||
return $bResult;
|
return $bResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function hashFolderFullName(string $sFolderFullName) : string
|
|
||||||
{
|
|
||||||
// return \strspn(\mb_strtolower($sFolderFullName), ':/#?') ? \md5($sFolderFullName) : $sFolderFullName;
|
|
||||||
return \preg_match('/^[a-z0-9]+$/iu', $sFolderFullName) ? $sFolderFullName : \md5($sFolderFullName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $mResponse
|
* @param mixed $mResponse
|
||||||
*
|
*
|
||||||
|
|
@ -382,7 +376,6 @@ trait Response
|
||||||
return \array_merge(
|
return \array_merge(
|
||||||
$mResponse->jsonSerialize(),
|
$mResponse->jsonSerialize(),
|
||||||
array(
|
array(
|
||||||
'FullNameHash' => $this->hashFolderFullName($mResponse->FullName()),
|
|
||||||
'Checkable' => \in_array($mResponse->FullName(), $this->aCheckableFolder),
|
'Checkable' => \in_array($mResponse->FullName(), $this->aCheckableFolder),
|
||||||
'Extended' => $aExtended,
|
'Extended' => $aExtended,
|
||||||
'SubFolders' => $this->responseObject($mResponse->SubFolders(), $sParent, $aParameters)
|
'SubFolders' => $this->responseObject($mResponse->SubFolders(), $sParent, $aParameters)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue