From dc0b500e78aae13349b848303302a213ed3a1e65 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Tue, 1 Apr 2014 19:27:07 +0200 Subject: Removed redundant default_folders config option (#1489737) Implemented IMAP SPECIAL-USE extension support [RFC6154] (#1487830) --- CHANGELOG | 2 + config/defaults.inc.php | 11 +-- installer/rcube_install.php | 14 --- plugins/archive/archive.js | 2 +- plugins/archive/archive.php | 21 ++-- program/include/rcmail.php | 17 +--- program/lib/Roundcube/rcube.php | 33 ++++++- program/lib/Roundcube/rcube_imap.php | 139 +++++++++++++++++++-------- program/lib/Roundcube/rcube_imap_generic.php | 38 ++++++-- program/lib/Roundcube/rcube_storage.php | 80 ++++++++++----- program/steps/settings/folders.inc | 23 +++-- program/steps/settings/func.inc | 19 ++-- program/steps/settings/save_prefs.inc | 28 +++--- 13 files changed, 260 insertions(+), 167 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 93f9b85b9..aaa7c8e93 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,8 @@ CHANGELOG Roundcube Webmail - Improve UI integration of ACL settings - Drop support for PHP < 5.3.7 - Set In-Reply-To and References for forwarded messages (#1489593) +- Removed redundant default_folders config option (#1489737) +- Implemented IMAP SPECIAL-USE extension support [RFC6154] (#1487830) - Fix directories check in Installer on Windows (#1489576) - Fix issue when default_addressbook option is set to integer value (#1489407) - Fix Opera > 15 detection (#1489562) diff --git a/config/defaults.inc.php b/config/defaults.inc.php index 8c9b96f1a..5c5fccb1e 100644 --- a/config/defaults.inc.php +++ b/config/defaults.inc.php @@ -561,20 +561,15 @@ $config['sent_mbox'] = 'Sent'; // NOTE: Use folder names with namespace prefix (INBOX. on Courier-IMAP) $config['trash_mbox'] = 'Trash'; -// display these folders separately in the mailbox list. -// these folders will also be displayed with localized names -// NOTE: Use folder names with namespace prefix (INBOX. on Courier-IMAP) -$config['default_folders'] = array('INBOX', 'Drafts', 'Sent', 'Junk', 'Trash'); - -// Disable localization of the default folder names listed above -$config['show_real_foldernames'] = false; - // automatically create the above listed default folders on first login $config['create_default_folders'] = false; // protect the default folders from renames, deletes, and subscription changes $config['protect_default_folders'] = true; +// Disable localization of the default folder names listed above +$config['show_real_foldernames'] = false; + // if in your system 0 quota means no limit set this option to true $config['quota_zero_as_unlimited'] = false; diff --git a/installer/rcube_install.php b/installer/rcube_install.php index 2fae3c5ca..b047156b5 100644 --- a/installer/rcube_install.php +++ b/installer/rcube_install.php @@ -42,7 +42,6 @@ class rcube_install 'addrbook_show_images' => 'show_images', 'imap_root' => 'imap_ns_personal', 'pagesize' => 'mail_pagesize', - 'default_imap_folders' => 'default_folders', 'top_posting' => 'reply_mode', 'keep_alive' => 'refresh_interval', 'min_keep_alive' => 'min_refresh_interval', @@ -228,19 +227,6 @@ class rcube_install else if ($prop == 'smtp_pass' && !empty($_POST['_smtp_user_u'])) { $value = '%p'; } - else if ($prop == 'default_folders') { - $value = array(); - foreach ($this->config['default_folders'] as $_folder) { - switch ($_folder) { - case 'Drafts': $_folder = $this->config['drafts_mbox']; break; - case 'Sent': $_folder = $this->config['sent_mbox']; break; - case 'Junk': $_folder = $this->config['junk_mbox']; break; - case 'Trash': $_folder = $this->config['trash_mbox']; break; - } - if (!in_array($_folder, $value)) - $value[] = $_folder; - } - } else if (is_bool($default)) { $value = (bool)$value; } diff --git a/plugins/archive/archive.js b/plugins/archive/archive.js index 813033401..c0d074cf9 100644 --- a/plugins/archive/archive.js +++ b/plugins/archive/archive.js @@ -1,6 +1,6 @@ /** * Archive plugin script - * @version 2.1 + * @version 2.2 */ function rcmail_archive(prop) diff --git a/plugins/archive/archive.php b/plugins/archive/archive.php index a0fd2efa9..8c0a89d96 100644 --- a/plugins/archive/archive.php +++ b/plugins/archive/archive.php @@ -6,22 +6,22 @@ * Plugin that adds a new button to the mailbox toolbar * to move messages to a (user selectable) archive folder. * - * @version 2.1 + * @version 2.2 * @license GNU GPLv3+ * @author Andre Rodier, Thomas Bruederli, Aleksander Machniak */ class archive extends rcube_plugin { - public $task = 'mail|settings'; - function init() { $rcmail = rcmail::get_instance(); - // There is no "Archived flags" - // $GLOBALS['IMAP_FLAGS']['ARCHIVED'] = 'Archive'; + // register special folder type + rcube_storage::$folder_types[] = 'archive'; + if ($rcmail->task == 'mail' && ($rcmail->action == '' || $rcmail->action == 'show') - && ($archive_folder = $rcmail->config->get('archive_mbox'))) { + && ($archive_folder = $rcmail->config->get('archive_mbox')) + ) { $skin_path = $this->local_skin_path(); if (is_file($this->home . "/$skin_path/archive.css")) $this->include_stylesheet("$skin_path/archive.css"); @@ -48,12 +48,6 @@ class archive extends rcube_plugin // set env variables for client $rcmail->output->set_env('archive_folder', $archive_folder); $rcmail->output->set_env('archive_type', $rcmail->config->get('archive_type','')); - - // add archive folder to the list of default mailboxes - if (($default_folders = $rcmail->config->get('default_folders')) && !in_array($archive_folder, $default_folders)) { - $default_folders[] = $archive_folder; - $rcmail->config->set('default_folders', $default_folders); - } } else if ($rcmail->task == 'mail') { // handler for ajax request @@ -99,7 +93,7 @@ class archive extends rcube_plugin return true; } else if (!empty($item['folders'])) if ($this->_mod_folder_name($list[$idx]['folders'], $folder, $new_name)) - return true; + return true; } return false; } @@ -286,7 +280,6 @@ class archive extends rcube_plugin function save_prefs($args) { if ($args['section'] == 'folders') { - $args['prefs']['archive_mbox'] = rcube_utils::get_input_value('_archive_mbox', rcube_utils::INPUT_POST); $args['prefs']['archive_type'] = rcube_utils::get_input_value('_archive_type', rcube_utils::INPUT_POST); return $args; } diff --git a/program/include/rcmail.php b/program/include/rcmail.php index 0fe5dbcf3..9e57a8e19 100644 --- a/program/include/rcmail.php +++ b/program/include/rcmail.php @@ -644,10 +644,8 @@ class rcmail extends rcube // fix some old settings according to namespace prefix $this->fix_namespace_settings($user); - // create default folders on login - if ($this->config->get('create_default_folders')) { - $storage->create_default_folders(); - } + // set/create special folders + $this->set_special_folders(); // clear all mailboxes related cache(s) $storage->clear_cache('mailboxes', true); @@ -927,14 +925,6 @@ class rcmail extends rcube } } - if (!empty($prefs['default_folders'])) { - foreach ($prefs['default_folders'] as $idx => $name) { - if ($name != 'INBOX' && !preg_match($regexp, $name)) { - $prefs['default_folders'][$idx] = $prefix.$name; - } - } - } - if (!empty($prefs['search_mods'])) { $folders = array(); foreach ($prefs['search_mods'] as $idx => $value) { @@ -1646,14 +1636,13 @@ class rcmail extends rcube public function localize_folderpath($path) { $protect_folders = $this->config->get('protect_default_folders'); - $default_folders = (array) $this->config->get('default_folders'); $delimiter = $this->storage->get_hierarchy_delimiter(); $path = explode($delimiter, $path); $result = array(); foreach ($path as $idx => $dir) { $directory = implode($delimiter, array_slice($path, 0, $idx+1)); - if ($protect_folders && in_array($directory, $default_folders)) { + if ($protect_folders && $this->storage->is_special_folder($directory)) { unset($result); $result[] = $this->localize_foldername($directory); } diff --git a/program/lib/Roundcube/rcube.php b/program/lib/Roundcube/rcube.php index 69d95f023..4ff0a00d7 100644 --- a/program/lib/Roundcube/rcube.php +++ b/program/lib/Roundcube/rcube.php @@ -420,9 +420,6 @@ class rcube $storage->set_charset($this->config->get('default_charset', RCUBE_CHARSET)); - if ($default_folders = $this->config->get('default_folders')) { - $storage->set_default_folders($default_folders); - } if (isset($_SESSION['mbox'])) { $storage->set_folder($_SESSION['mbox']); } @@ -432,6 +429,36 @@ class rcube } + /** + * Set special folders type association. + * This must be done AFTER connecting to the server! + */ + protected function set_special_folders() + { + $storage = $this->get_storage(); + $folders = $storage->get_special_folders(true); + $prefs = array(); + + // check SPECIAL-USE flags on IMAP folders + foreach ($folders as $type => $folder) { + $idx = $type . '_mbox'; + if ($folder !== $this->config->get($idx)) { + $prefs[$idx] = $folder; + } + } + + // Some special folders differ, update user preferences + if (!empty($prefs) && $this->user) { + $this->user->save_prefs($prefs); + } + + // create default folders (on login) + if ($this->config->get('create_default_folders')) { + $storage->create_default_folders(); + } + } + + /** * Create session object and start the session. */ diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php index 432227091..628338a44 100644 --- a/program/lib/Roundcube/rcube_imap.php +++ b/program/lib/Roundcube/rcube_imap.php @@ -2365,19 +2365,7 @@ class rcube_imap extends rcube_storage return false; } - // make sure folder exists - if ($to_mbox != 'INBOX' && !$this->folder_exists($to_mbox)) { - if (in_array($to_mbox, $this->default_folders)) { - if (!$this->create_folder($to_mbox, true)) { - return false; - } - } - else { - return false; - } - } - - $config = rcube::get_instance()->config; + $config = rcube::get_instance()->config; $to_trash = $to_mbox == $config->get('trash_mbox'); // flag messages as read before moving them @@ -2448,18 +2436,6 @@ class rcube_imap extends rcube_storage return false; } - // make sure folder exists - if ($to_mbox != 'INBOX' && !$this->folder_exists($to_mbox)) { - if (in_array($to_mbox, $this->default_folders)) { - if (!$this->create_folder($to_mbox, true)) { - return false; - } - } - else { - return false; - } - } - // copy messages $copied = $this->conn->copy($uids, $from_mbox, $to_mbox); @@ -2975,16 +2951,17 @@ class rcube_imap extends rcube_storage * * @param string $folder New folder name * @param boolean $subscribe True if the new folder should be subscribed + * @param string $type Optional folder type (junk, trash, drafts, sent, archive) * * @return boolean True on success */ - public function create_folder($folder, $subscribe=false) + public function create_folder($folder, $subscribe = false, $type = null) { if (!$this->check_connection()) { return false; } - $result = $this->conn->createFolder($folder); + $result = $this->conn->createFolder($folder, $type ? array("\\" . ucfirst($type)) : null); // try to subscribe it if ($result) { @@ -3109,19 +3086,84 @@ class rcube_imap extends rcube_storage /** - * Create all folders specified as default + * Detect special folder associations stored in storage backend */ - public function create_default_folders() + public function get_special_folders($forced = false) { - // create default folders if they do not exist - foreach ($this->default_folders as $folder) { - if (!$this->folder_exists($folder)) { - $this->create_folder($folder, true); + $result = parent::get_special_folders(); + + if (isset($this->icache['special-use'])) { + return array_merge($result, $this->icache['special-use']); + } + + if (!$forced || !$this->get_capability('SPECIAL-USE')) { + return $result; + } + + if (!$this->check_connection()) { + return $result; + } + + $types = array_map(function($value) { return "\\" . ucfirst($value); }, rcube_storage::$folder_types); + $special = array(); + + // request \Subscribed flag in LIST response as performance improvement for folder_exists() + $folders = $this->conn->listMailboxes('', '*', array('SUBSCRIBED'), array('SPECIAL-USE')); + + foreach ($folders as $folder) { + if ($flags = $this->conn->data['LIST'][$folder]) { + foreach ($types as $type) { + if (in_array($type, $flags)) { + $type = strtolower(substr($type, 1)); + $special[$type] = $folder; + } + } } - else if (!$this->folder_exists($folder, true)) { - $this->subscribe($folder); + } + + $this->icache['special-use'] = $special; + unset($this->icache['special-folders']); + + return array_merge($result, $special); + } + + + /** + * Set special folder associations stored in storage backend + */ + public function set_special_folders($specials) + { + if (!$this->get_capability('SPECIAL-USE') || !$this->get_capability('METADATA')) { + return false; + } + + if (!$this->check_connection()) { + return false; + } + + $folders = $this->get_special_folders(true); + $old = (array) $this->icache['special-use']; + + foreach ($specials as $type => $folder) { + if (in_array($type, rcube_storage::$folder_types)) { + $old_folder = $old[$type]; + if ($old_folder !== $folder) { + // unset old-folder metadata + if ($old_folder !== null) { + $this->delete_metadata($old_folder, array('/private/specialuse')); + } + // set new folder metadata + if ($folder) { + $this->set_metadata($folder, array('/private/specialuse' => "\\" . ucfirst($type))); + } + } } } + + $this->icache['special-use'] = $specials; + unset($this->icache['special-folders']); + + return true; } @@ -3133,13 +3175,13 @@ class rcube_imap extends rcube_storage * * @return boolean TRUE or FALSE */ - public function folder_exists($folder, $subscription=false) + public function folder_exists($folder, $subscription = false) { if ($folder == 'INBOX') { return true; } - $key = $subscription ? 'subscribed' : 'existing'; + $key = $subscription ? 'subscribed' : 'existing'; if (is_array($this->icache[$key]) && in_array($folder, $this->icache[$key])) { return true; @@ -3150,10 +3192,24 @@ class rcube_imap extends rcube_storage } if ($subscription) { - $a_folders = $this->conn->listSubscribed('', $folder); + // It's possible we already called LIST command, check LIST data + if (!empty($this->conn->data['LIST']) && !empty($this->conn->data['LIST'][$folder]) + && in_array('\\Subscribed', $this->conn->data['LIST'][$folder]) + ) { + $a_folders = array($folder); + } + else { + $a_folders = $this->conn->listSubscribed('', $folder); + } } else { - $a_folders = $this->conn->listMailboxes('', $folder); + // It's possible we already called LIST command, check LIST data + if (!empty($this->conn->data['LIST']) && isset($this->conn->data['LIST'][$folder])) { + $a_folders = array($folder); + } + else { + $a_folders = $this->conn->listMailboxes('', $folder); + } } if (is_array($a_folders) && in_array($folder, $a_folders)) { @@ -3364,7 +3420,7 @@ class rcube_imap extends rcube_storage $options['name'] = $folder; $options['attributes'] = $this->folder_attributes($folder, true); $options['namespace'] = $this->folder_namespace($folder); - $options['special'] = in_array($folder, $this->default_folders); + $options['special'] = $this->is_special_folder($folder); // Set 'noselect' flag if (is_array($options['attributes'])) { @@ -3902,6 +3958,7 @@ class rcube_imap extends rcube_storage $a_out = $a_defaults = $folders = array(); $delimiter = $this->get_hierarchy_delimiter(); + $specials = array_merge(array('INBOX'), array_values($this->get_special_folders())); // find default folders and skip folders starting with '.' foreach ($a_folders as $folder) { @@ -3909,7 +3966,7 @@ class rcube_imap extends rcube_storage continue; } - if (!$skip_default && ($p = array_search($folder, $this->default_folders)) !== false && !$a_defaults[$p]) { + if (!$skip_default && ($p = array_search($folder, $specials)) !== false && !$a_defaults[$p]) { $a_defaults[$p] = $folder; } else { diff --git a/program/lib/Roundcube/rcube_imap_generic.php b/program/lib/Roundcube/rcube_imap_generic.php index 4f5707924..f45694dd0 100644 --- a/program/lib/Roundcube/rcube_imap_generic.php +++ b/program/lib/Roundcube/rcube_imap_generic.php @@ -1191,13 +1191,20 @@ class rcube_imap_generic * Folder creation (CREATE) * * @param string $mailbox Mailbox name + * @param array $types Optional folder types (RFC 6154) * * @return bool True on success, False on error */ - function createFolder($mailbox) + function createFolder($mailbox, $types = null) { - $result = $this->execute('CREATE', array($this->escape($mailbox)), - self::COMMAND_NORESPONSE); + $args = array($this->escape($mailbox)); + + // RFC 6154: CREATE-SPECIAL-USE + if (!empty($types) && $this->getCapability('CREATE-SPECIAL-USE')) { + $args[] = '(USE (' . implode(' ', $types) . '))'; + } + + $result = $this->execute('CREATE', $args, self::COMMAND_NORESPONSE); return ($result == self::ERROR_OK); } @@ -1293,10 +1300,12 @@ class rcube_imap_generic * @param string $ref Reference name * @param string $mailbox Mailbox name * @param bool $subscribed Enables returning subscribed mailboxes only - * @param array $status_opts List of STATUS options (RFC5819: LIST-STATUS) - * Possible: MESSAGES, RECENT, UIDNEXT, UIDVALIDITY, UNSEEN + * @param array $status_opts List of STATUS options + * (RFC5819: LIST-STATUS: MESSAGES, RECENT, UIDNEXT, UIDVALIDITY, UNSEEN) + * or RETURN options (RFC5258: LIST_EXTENDED: SUBSCRIBED, CHILDREN) * @param array $select_opts List of selection options (RFC5258: LIST-EXTENDED) - * Possible: SUBSCRIBED, RECURSIVEMATCH, REMOTE + * Possible: SUBSCRIBED, RECURSIVEMATCH, REMOTE, + * SPECIAL-USE (RFC6154) * * @return array List of mailboxes or hash of options if $status_ops argument * is non-empty. @@ -1309,6 +1318,7 @@ class rcube_imap_generic } $args = array(); + $rets = array(); if (!empty($select_opts) && $this->getCapability('LIST-EXTENDED')) { $select_opts = (array) $select_opts; @@ -1319,11 +1329,21 @@ class rcube_imap_generic $args[] = $this->escape($ref); $args[] = $this->escape($mailbox); + if (!empty($status_opts) && $this->getCapability('LIST-EXTENDED')) { + $rets = array_intersect($status_opts, array('SUBSCRIBED', 'CHILDREN')); + } + if (!empty($status_opts) && $this->getCapability('LIST-STATUS')) { - $status_opts = (array) $status_opts; - $lstatus = true; + $status_opts = array_intersect($status_opts, array('MESSAGES', 'RECENT', 'UIDNEXT', 'UIDVALIDITY', 'UNSEEN')); + + if (!empty($status_opts)) { + $lstatus = true; + $rets[] = 'STATUS (' . implode(' ', $status_opts) . ')'; + } + } - $args[] = 'RETURN (STATUS (' . implode(' ', $status_opts) . '))'; + if (!empty($rets)) { + $args[] = 'RETURN (' . implode(' ', $rets) . ')'; } list($code, $response) = $this->execute($subscribed ? 'LSUB' : 'LIST', $args); diff --git a/program/lib/Roundcube/rcube_storage.php b/program/lib/Roundcube/rcube_storage.php index c09f05328..69d6d2fae 100644 --- a/program/lib/Roundcube/rcube_storage.php +++ b/program/lib/Roundcube/rcube_storage.php @@ -35,9 +35,15 @@ abstract class rcube_storage */ public $conn; + /** + * List of supported special folder types + * + * @var array + */ + public static $folder_types = array('drafts', 'sent', 'junk', 'trash'); + protected $folder = 'INBOX'; protected $default_charset = 'ISO-8859-1'; - protected $default_folders = array('INBOX'); protected $search_set; protected $options = array('auth_type' => 'check'); protected $page_size = 10; @@ -166,24 +172,6 @@ abstract class rcube_storage } - /** - * This list of folders will be listed above all other folders - * - * @param array $arr Indexed list of folder names - */ - public function set_default_folders($arr) - { - if (is_array($arr)) { - $this->default_folders = $arr; - - // add inbox if not included - if (!in_array('INBOX', $this->default_folders)) { - array_unshift($this->default_folders, 'INBOX'); - } - } - } - - /** * Set internal folder reference. * All operations will be perfomed on this folder. @@ -858,15 +846,59 @@ abstract class rcube_storage */ public function create_default_folders() { + $rcube = rcube::get_instance(); + // create default folders if they do not exist - foreach ($this->default_folders as $folder) { - if (!$this->folder_exists($folder)) { - $this->create_folder($folder, true); + foreach (self::$folder_types as $type) { + if ($folder = $rcube->config->get($type . '_mbox')) { + if (!$this->folder_exists($folder)) { + $this->create_folder($folder, true, $type); + } + else if (!$this->folder_exists($folder, true)) { + $this->subscribe($folder); + } } - else if (!$this->folder_exists($folder, true)) { - $this->subscribe($folder); + } + } + + + /** + * Check if specified folder is a special folder + */ + public function is_special_folder($name) + { + return $name == 'INBOX' || in_array($name, $this->get_special_folders()); + } + + + /** + * Return configured special folders + */ + public function get_special_folders($forced = false) + { + // getting config might be expensive, store special folders in memory + if (!isset($this->icache['special-folders'])) { + $rcube = rcube::get_instance(); + $this->icache['special-folders'] = array(); + + foreach (self::$folder_types as $type) { + if ($folder = $rcube->config->get($type . '_mbox')) { + $this->icache['special-folders'][$type] = $folder; + } } } + + return $this->icache['special-folders']; + } + + + /** + * Set special folder associations stored in backend + */ + public function set_special_folders($specials) + { + // should be overriden by storage class if backend supports special folders (SPECIAL-USE) + unset($this->icache['special-folders']); } diff --git a/program/steps/settings/folders.inc b/program/steps/settings/folders.inc index b09ea03ce..1bcfb4cfc 100644 --- a/program/steps/settings/folders.inc +++ b/program/steps/settings/folders.inc @@ -45,7 +45,7 @@ if ($RCMAIL->action == 'subscribe') { if ($result) { // Handle subscription of protected folder (#1487656) if ($RCMAIL->config->get('protect_default_folders') - && in_array($mbox, (array)$RCMAIL->config->get('default_folders')) + && $STORAGE->is_special_folder($mbox) ) { $OUTPUT->command('disable_subscription', $mbox); } @@ -221,16 +221,15 @@ function rcube_subscription_form($attrib) // get folders from server $STORAGE->clear_cache('mailboxes', true); - $a_unsubscribed = $STORAGE->list_folders(); - $a_subscribed = $STORAGE->list_folders_subscribed('', '*', null, null, true); // unsorted - $delimiter = $STORAGE->get_hierarchy_delimiter(); - $namespace = $STORAGE->get_namespace(); - $a_js_folders = array(); - $seen = array(); - $list_folders = array(); - - $default_folders = (array) $RCMAIL->config->get('default_folders'); + $a_unsubscribed = $STORAGE->list_folders(); + $a_subscribed = $STORAGE->list_folders_subscribed('', '*', null, null, true); // unsorted + $delimiter = $STORAGE->get_hierarchy_delimiter(); + $namespace = $STORAGE->get_namespace(); + $special_folders = array_flip(array_merge(array('inbox' => 'INBOX'), $STORAGE->get_special_folders())); $protect_default = $RCMAIL->config->get('protect_default_folders'); + $a_js_folders = array(); + $seen = array(); + $list_folders = array(); // pre-process folders list foreach ($a_unsubscribed as $i => $folder) { @@ -291,7 +290,7 @@ function rcube_subscription_form($attrib) $idx = $i + 1; $sub_key = array_search($folder['id'], $a_subscribed); $subscribed = $sub_key !== false; - $protected = $protect_default && in_array($folder['id'], $default_folders); + $protected = $protect_default && isset($special_folders[$folder['id']]); $noselect = false; $classes = array($i%2 ? 'even' : 'odd'); @@ -368,7 +367,7 @@ function rcube_subscription_form($attrib) $OUTPUT->add_gui_object('subscriptionlist', $attrib['id']); $OUTPUT->set_env('subscriptionrows', $a_js_folders); - $OUTPUT->set_env('defaultfolders', $default_folders); + $OUTPUT->set_env('defaultfolders', array_keys($special_folders)); $OUTPUT->set_env('delimiter', $delimiter); return $form_start . $table->show($attrib) . $form_end; diff --git a/program/steps/settings/func.inc b/program/steps/settings/func.inc index 307be8c8e..47efa5a70 100644 --- a/program/steps/settings/func.inc +++ b/program/steps/settings/func.inc @@ -1035,7 +1035,8 @@ function rcmail_user_prefs($current = null) } // Configure special folders - if (!isset($no_override['default_folders']) && $current) { + $set = array('drafts_mbox', 'sent_mbox', 'junk_mbox', 'trash_mbox'); + if ($current && count(array_intersect($no_override, $set)) < 4) { $select = $RCMAIL->folder_selector(array( 'noselection' => '---', 'realnames' => true, @@ -1043,10 +1044,10 @@ function rcmail_user_prefs($current = null) 'folder_filter' => 'mail', 'folder_rights' => 'w', )); - } - // #1486114, #1488279, #1489219 - $onchange = "if ($(this).val() == 'INBOX') $(this).val('')"; + // #1486114, #1488279, #1489219 + $onchange = "if ($(this).val() == 'INBOX') $(this).val('')"; + } if (!isset($no_override['drafts_mbox'])) { if (!$current) { @@ -1287,13 +1288,11 @@ function rcmail_update_folder_row($name, $oldname=null, $subscribe=false, $class { global $RCMAIL, $OUTPUT; - $default_folders = (array) $RCMAIL->config->get('default_folders'); $protect_folders = $RCMAIL->config->get('protect_default_folders'); - - $storage = $RCMAIL->get_storage(); - $delimiter = $storage->get_hierarchy_delimiter(); - $name_utf8 = rcube_charset::convert($name, 'UTF7-IMAP'); - $protected = $protect_folders && in_array($name, $default_folders); + $storage = $RCMAIL->get_storage(); + $delimiter = $storage->get_hierarchy_delimiter(); + $name_utf8 = rcube_charset::convert($name, 'UTF7-IMAP'); + $protected = $protect_folders && $storage->is_special_folder($name); $foldersplit = explode($delimiter, $storage->mod_folder($name)); $level = count($foldersplit) - 1; diff --git a/program/steps/settings/save_prefs.inc b/program/steps/settings/save_prefs.inc index f71eee39a..7a17f21f4 100644 --- a/program/steps/settings/save_prefs.inc +++ b/program/steps/settings/save_prefs.inc @@ -121,12 +121,12 @@ case 'server': case 'folders': $a_user_prefs = array( 'show_real_foldernames' => isset($_POST['_show_real_foldernames']) ? true : false, - 'drafts_mbox' => rcube_utils::get_input_value('_drafts_mbox', rcube_utils::INPUT_POST, true), - 'sent_mbox' => rcube_utils::get_input_value('_sent_mbox', rcube_utils::INPUT_POST, true), - 'junk_mbox' => rcube_utils::get_input_value('_junk_mbox', rcube_utils::INPUT_POST, true), - 'trash_mbox' => rcube_utils::get_input_value('_trash_mbox', rcube_utils::INPUT_POST, true), ); + foreach (rcube_storage::$folder_types as $type) { + $a_user_prefs[$type . '_mbox'] = rcube_utils::get_input_value('_' . $type . '_mbox', rcube_utils::INPUT_POST, true); + }; + break; } @@ -191,21 +191,15 @@ case 'addressbook': break; case 'folders': - // special handling for 'default_folders' - if (in_array('default_folders', (array)$CONFIG['dont_override'])) { - foreach (array('drafts_mbox','sent_mbox','junk_mbox','trash_mbox') as $p) { - $a_user_prefs[$p] = $CONFIG[$p]; - } - } - else { - $a_user_prefs['default_folders'] = array('INBOX'); - foreach (array('drafts_mbox','sent_mbox','junk_mbox','trash_mbox') as $p) { - if ($a_user_prefs[$p]) { - $a_user_prefs['default_folders'][] = $a_user_prefs[$p]; - } - } + $storage = $RCMAIL->get_storage(); + $specials = array(); + + foreach (rcube_storage::$folder_types as $type) { + $specials[$type] = $a_user_prefs[$type . '_mbox']; } + $storage->set_special_folders($specials); + break; } -- cgit v1.2.3