From 206d26fac529e59bde733fba3248df47c0a861f2 Mon Sep 17 00:00:00 2001 From: Josaphat Imani Date: Sat, 17 Sep 2022 16:41:01 +0100 Subject: [PATCH 1/4] Added subscription to folders --- modules/imap/hm-imap.php | 38 +++++++++++++++++- modules/imap_folders/modules.php | 67 ++++++++++++++++++++++++++++++++ modules/imap_folders/setup.php | 17 +++++++- modules/imap_folders/site.css | 14 +++++++ modules/imap_folders/site.js | 16 ++++++++ 5 files changed, 150 insertions(+), 2 deletions(-) diff --git a/modules/imap/hm-imap.php b/modules/imap/hm-imap.php index 481aee2740..8e84ccddd7 100644 --- a/modules/imap/hm-imap.php +++ b/modules/imap/hm-imap.php @@ -685,6 +685,19 @@ public function get_mailbox_status($mailbox, $args=array('UNSEEN', 'UIDVALIDITY' return $attributes; } + /** + * Subscribe/Unsubscribe folder + * @param string $mailbox IMAP mailbox to check + * @param string $action boolean + * @return boolean failure or success + */ + public function mailbox_subscription($mailbox, $action) { + $command = ($action? 'SUBSCRIBE': 'UNSUBSCRIBE').' "'.$this->utf7_encode($mailbox).'"'."\r\n"; + $this->send_command($command); + $response = $this->get_response(false, true); + return $this->check_response($response, true); + } + /* ------------------ SELECTED STATE COMMANDS -------------------------- */ /** @@ -2129,7 +2142,7 @@ public function get_mailbox_page($mailbox, $sort, $rev, $filter, $offset=0, $lim */ public function get_folder_list_by_level($level='') { $result = array(); - $folders = $this->get_mailbox_list(false, $level, '%'); + $folders = $this->get_mailbox_list(true, $level, '%'); foreach ($folders as $name => $folder) { $result[$name] = array( 'delim' => $folder['delim'], @@ -2142,6 +2155,29 @@ public function get_folder_list_by_level($level='') { } return $result; } + + /** + * return all the folders with subscribed attribute + * @return array list of folders + */ + public function get_mailbox_list_with_subscription() { + $result = array(); + $all_folders = $this->get_mailbox_list(); + $subscribed_folders = array_column($this->get_mailbox_list(true), 'basename'); + foreach ($all_folders as $name => $folder) { + $result[$name] = array( + 'name' => $folder['name'], + 'delim' => $folder['delim'], + 'basename' => $folder['basename'], + 'children' => $folder['has_kids'], + 'noselect' => $folder['noselect'], + 'id' => bin2hex($folder['basename']), + 'name_parts' => $folder['name_parts'], + 'subscribed' => in_array($folder['basename'], $subscribed_folders) + ); + } + return $result; + } } } diff --git a/modules/imap_folders/modules.php b/modules/imap_folders/modules.php index c5df4710e3..0b1bb4f782 100644 --- a/modules/imap_folders/modules.php +++ b/modules/imap_folders/modules.php @@ -335,6 +335,31 @@ public function process() { } } +/** + * @subpackage imap_folders/handler + */ +class Hm_Handler_process_imap_folder_subscription extends Hm_Handler_Module { + public function process() { + list($success, $form) = $this->process_form(array('folder', 'subscription_state')); + if ($success) { + $imap_server_id = $this->request->get['imap_server_id']; + $cache = Hm_IMAP_List::get_cache($this->cache, $imap_server_id); + $imap = Hm_IMAP_List::connect($imap_server_id, $cache); + if (is_object($imap) && $imap->get_state() == 'authenticated') { + $folder = hex2bin($form['folder']); + $success = $imap->mailbox_subscription($folder, $form['subscription_state']); + if ($success) { + Hm_Msgs::add(sprintf('%s to %s', $form['subscription_state']? 'Subscribed': 'Unsubscribed', $folder)); + $this->cache->del('imap_folders_imap_'.$imap_server_id.'_'); + } else { + Hm_Msgs::add(sprintf('ERRAn error occurred %s to %s', $form['subscription_state']? 'subscribing': 'unsubscribing', $folder)); + } + $this->out('imap_folder_subscription', $success); + } + } + } +} + /** * @subpackage imap_folders/output */ @@ -572,6 +597,31 @@ protected function output() { } } +/** + * @subpackage imap_folders/output + */ +class Hm_Output_folders_folder_subscription extends Hm_Output_Module { + protected function output() { + if (($server = $this->get('folder_server')) === NULL) { + return; + } + $imap = Hm_IMAP_List::connect($server, false); + $folders = $imap->get_mailbox_list_with_subscription(); + $results = ''; + return $results; + } +} + /** * @subpackage imap_folders/output */ @@ -653,6 +703,23 @@ protected function output() { '; + $res .= ''; + } +} + +class Hm_Output_folders_actions_content_start extends Hm_Output_Module { + protected function output() { + $res = '
'; + return $res; + } +} + +/** + * @subpackage imap_folders/output + */ +class Hm_Output_folders_actions_content_end extends Hm_Output_Module { + protected function output() { + $res = '
'; return $res; } } diff --git a/modules/imap_folders/setup.php b/modules/imap_folders/setup.php index 66e979d412..a8c12b758c 100644 --- a/modules/imap_folders/setup.php +++ b/modules/imap_folders/setup.php @@ -18,9 +18,11 @@ add_handler('folders', 'special_folders', true, 'imap_folders', 'folders_server_id', 'after'); add_output('folders', 'folders_content_start', true, 'imap_folders', 'content_section_start', 'after'); add_output('folders', 'folders_server_select', true, 'imap_folders', 'folders_content_start', 'after'); +add_output('folders', 'folders_actions_content_start', true, 'imap_folders', 'folders_folder_subscription', 'after'); add_output('folders', 'folders_create_dialog', true, 'imap_folders', 'folders_server_select', 'after'); add_output('folders', 'folders_rename_dialog', true, 'imap_folders', 'folders_create_dialog', 'after'); add_output('folders', 'folders_delete_dialog', true, 'imap_folders', 'folders_rename_dialog', 'after'); +add_output('folders', 'folders_actions_content_end', true, 'imap_folders', 'folders_archive_dialog', 'after'); add_handler('ajax_imap_folder_expand', 'add_folder_manage_link', true, 'imap_folders', 'imap_folder_expand', 'after'); @@ -30,6 +32,7 @@ add_output('folders', 'folders_archive_dialog', true, 'imap_folders', 'folders_sent_dialog', 'after'); add_output('folders', 'folders_draft_dialog', true, 'imap_folders', 'folders_archive_dialog', 'after'); add_output('folders', 'folders_junk_dialog', true, 'imap_folders', 'folders_draft_dialog', 'after'); +add_output('folders', 'folders_folder_subscription', true, 'imap_folders', 'folders_server_select', 'after'); add_handler('compose', 'special_folders', true, 'imap_folders', 'load_user_data', 'after'); @@ -51,6 +54,12 @@ add_handler('ajax_imap_folders_create', 'imap_bust_cache', true, 'imap', 'process_folder_create', 'after'); add_handler('ajax_imap_folders_create', 'close_session_early', true, 'core', 'imap_bust_cache', 'after'); +setup_base_ajax_page('ajax_imap_folders_create', 'core'); +add_handler('ajax_imap_folders_create', 'load_imap_servers_from_config', true, 'imap', 'load_user_data', 'after'); +add_handler('ajax_imap_folders_create', 'process_folder_create', true, 'imap_folders', 'load_imap_servers_from_config', 'after'); +add_handler('ajax_imap_folders_create', 'imap_bust_cache', true, 'imap', 'process_folder_create', 'after'); +add_handler('ajax_imap_folders_create', 'close_session_early', true, 'core', 'imap_bust_cache', 'after'); + setup_base_ajax_page('ajax_imap_clear_special_folder', 'core'); add_handler('ajax_imap_clear_special_folder', 'load_imap_servers_from_config', true, 'imap', 'load_user_data', 'after'); add_handler('ajax_imap_clear_special_folder', 'process_clear_special_folder', true, 'imap_folders', 'load_imap_servers_from_config', 'after'); @@ -66,6 +75,11 @@ add_handler('ajax_imap_accept_special_folders', 'process_accept_special_folders', true, 'imap_folders', 'load_imap_servers_from_config', 'after'); add_handler('ajax_imap_accept_special_folders', 'save_user_data', true, 'core', 'process_special_folders', 'after'); +setup_base_ajax_page('ajax_imap_folder_subscription', 'core'); +add_handler('ajax_imap_folder_subscription', 'load_imap_servers_from_config', true, 'imap', 'load_user_data', 'after'); +add_handler('ajax_imap_folder_subscription', 'process_imap_folder_subscription', true, 'imap_folders', 'load_imap_servers_from_config', 'after'); +add_handler('ajax_imap_folder_subscription', 'save_user_data', true, 'core', 'process_special_folder', 'after'); + add_handler('ajax_hm_folders', 'imap_folder_check', true, 'imap_folders', 'load_user_data', 'after'); add_output('ajax_hm_folders', 'folders_page_link', true, 'imap_folders', 'settings_menu_end', 'before'); @@ -77,7 +91,8 @@ 'ajax_imap_folders_rename', 'ajax_imap_special_folder', 'ajax_imap_clear_special_folder', - 'ajax_imap_accept_special_folders' + 'ajax_imap_accept_special_folders', + 'ajax_imap_folder_subscription' ), 'allowed_output' => array( 'imap_folders_success' => array(FILTER_VALIDATE_INT, false), diff --git a/modules/imap_folders/site.css b/modules/imap_folders/site.css index 2ea2004d31..014483508b 100644 --- a/modules/imap_folders/site.css +++ b/modules/imap_folders/site.css @@ -9,3 +9,17 @@ #draft_val, #sent_val, #trash_val, #junk_val { padding-left: 20px; } .manage_folder_icon { vertical-align: -3px; opacity: .3 } .manage_folder_link { color: #999 !important; } + +.folders_subscription { width: 100%; display: inline-block; } +.folders_subscription input { float: right; } +.folder_actions { width: 100%; display: inline-block; vertical-align: top; margin-left: 1%; } + +@media (min-width: 687px) { + .folders_subscription { width: 30% } + .folder_actions { width: 65%; } +} + +@media (min-width: 1201px) { + .folders_subscription { width: 25% } + .folder_actions { width: 72%; } +} diff --git a/modules/imap_folders/site.js b/modules/imap_folders/site.js index 7d33448a35..bd030f90c2 100644 --- a/modules/imap_folders/site.js +++ b/modules/imap_folders/site.js @@ -214,6 +214,20 @@ var assign_special_folder = function(id, folder, type, callback) { ); }; +var folder_subscribe = function(name, state) { + Hm_Ajax.request( + [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_folder_subscription'}, + {'name': 'subscription_state', 'value': state}, + {'name': 'folder', 'value': name}], + function(res) { + if (!res.imap_folder_subscription) { + var el = $('#'+name); + el.prop('checked', !el.prop('checked')); + } + } + ); +}; + var folder_page_create = function() { var par = $('#create_parent').val(); var folder = $('#create_value').val().trim(); @@ -273,4 +287,6 @@ $(function() { $('#clear_sent_folder').on("click", function() { clear_special_folder('sent'); return false; }); $('#clear_archive_folder').on("click", function() { clear_special_folder('archive'); return false; }); $('#clear_draft_folder').on("click", function() { clear_special_folder("draft"); return false; }); + + $('.folder_subscription').on("change", function() { folder_subscribe(this.id, $('#'+this.id).is(':checked')); return false; }); }); From f404fd6df045cf35ee141a3634544bb11c9f353e Mon Sep 17 00:00:00 2001 From: Josaphat Imani Date: Sat, 24 Sep 2022 12:45:06 +0100 Subject: [PATCH 2/4] Put subscription to folders to separate page --- modules/imap/functions.php | 3 + modules/imap/handler_modules.php | 7 ++- modules/imap/hm-imap.php | 38 +++++-------- modules/imap_folders/modules.php | 98 ++++++++++++++++++++++---------- modules/imap_folders/setup.php | 41 +++++++------ modules/imap_folders/site.css | 6 +- modules/imap_folders/site.js | 28 ++++++--- 7 files changed, 135 insertions(+), 86 deletions(-) diff --git a/modules/imap/functions.php b/modules/imap/functions.php index 1648d9f4b8..c2a8809db5 100644 --- a/modules/imap/functions.php +++ b/modules/imap/functions.php @@ -141,6 +141,9 @@ function format_imap_folder_section($folders, $id, $output_mod) { else { $results .= $output_mod->html_safe($folder['basename']); } + if (isset($folder['subscribed'])) { + $results .= ''; + } $results .= ''; } if ($manage) { diff --git a/modules/imap/handler_modules.php b/modules/imap/handler_modules.php index 6dc9019674..f77f2d16d7 100644 --- a/modules/imap/handler_modules.php +++ b/modules/imap/handler_modules.php @@ -730,7 +730,12 @@ public function process() { $cache = Hm_IMAP_List::get_cache($this->cache, $form['imap_server_id']); $imap = Hm_IMAP_List::connect($form['imap_server_id'], $cache); if (imap_authed($imap)) { - $msgs = $imap->get_folder_list_by_level(hex2bin($folder)); + $only_subscribed = $this->user_config->get('only_subscribed_folders_setting', false); + $with_subscription = isset($this->request->post['subscription_state']) && $this->request->post['subscription_state']; + if ($with_subscription) { + $only_subscribed = false; + } + $msgs = $imap->get_folder_list_by_level(hex2bin($folder), $only_subscribed, $with_subscription); if (isset($msgs[$folder])) { unset($msgs[$folder]); } diff --git a/modules/imap/hm-imap.php b/modules/imap/hm-imap.php index 8e84ccddd7..d268e68142 100644 --- a/modules/imap/hm-imap.php +++ b/modules/imap/hm-imap.php @@ -431,7 +431,11 @@ public function get_mailbox_list($lsub=false, $mailbox='', $keyword='*') { $check_for_new = false; /* full folder name, includes an absolute path of parent folders */ - $folder = $this->utf7_decode($vals[(count($vals) - 1)]); + if ($vals[(count($vals) - 1)] == ')' && $lsub) { + $folder = $this->utf7_decode($vals[6]); + } else { + $folder = $this->utf7_decode($vals[(count($vals) - 1)]); + } /* sometimes LIST responses have dupes */ if (isset($folders[$folder]) || !$folder) { @@ -2140,31 +2144,10 @@ public function get_mailbox_page($mailbox, $sort, $rev, $filter, $offset=0, $lim * @param string $level mailbox name or empty string for the top level * @return array list of matching folders */ - public function get_folder_list_by_level($level='') { + public function get_folder_list_by_level($level='', $only_subscribed=false, $with_subscription_state = false) { $result = array(); - $folders = $this->get_mailbox_list(true, $level, '%'); + $folders = $this->get_mailbox_list($only_subscribed, $level, '%'); foreach ($folders as $name => $folder) { - $result[$name] = array( - 'delim' => $folder['delim'], - 'basename' => $folder['basename'], - 'children' => $folder['has_kids'], - 'noselect' => $folder['noselect'], - 'id' => bin2hex($folder['basename']), - 'name_parts' => $folder['name_parts'], - ); - } - return $result; - } - - /** - * return all the folders with subscribed attribute - * @return array list of folders - */ - public function get_mailbox_list_with_subscription() { - $result = array(); - $all_folders = $this->get_mailbox_list(); - $subscribed_folders = array_column($this->get_mailbox_list(true), 'basename'); - foreach ($all_folders as $name => $folder) { $result[$name] = array( 'name' => $folder['name'], 'delim' => $folder['delim'], @@ -2173,9 +2156,14 @@ public function get_mailbox_list_with_subscription() { 'noselect' => $folder['noselect'], 'id' => bin2hex($folder['basename']), 'name_parts' => $folder['name_parts'], - 'subscribed' => in_array($folder['basename'], $subscribed_folders) ); } + if ($with_subscription_state) { + $subscribed_folders = array_column($this->get_mailbox_list(true), 'name'); + foreach ($result as $key => $folder) { + $result[$key]['subscribed'] = in_array($folder['name'], $subscribed_folders); + } + } return $result; } } diff --git a/modules/imap_folders/modules.php b/modules/imap_folders/modules.php index 0b1bb4f782..1a99a0a3bd 100644 --- a/modules/imap_folders/modules.php +++ b/modules/imap_folders/modules.php @@ -360,6 +360,19 @@ public function process() { } } +/** + * Process input from the folder subscription setting in the settings page + * @subpackage imap/handler + */ +class Hm_Handler_process_only_subscribed_folders_setting extends Hm_Handler_Module { + public function process() { + function only_subscribed_folders_setting_callback($val) { + return $val; + } + process_site_setting('only_subscribed_folders', $this, 'only_subscribed_folders_setting_callback', false, true); + } +} + /** * @subpackage imap_folders/output */ @@ -597,31 +610,6 @@ protected function output() { } } -/** - * @subpackage imap_folders/output - */ -class Hm_Output_folders_folder_subscription extends Hm_Output_Module { - protected function output() { - if (($server = $this->get('folder_server')) === NULL) { - return; - } - $imap = Hm_IMAP_List::connect($server, false); - $folders = $imap->get_mailbox_list_with_subscription(); - $results = ''; - return $results; - } -} - /** * @subpackage imap_folders/output */ @@ -707,20 +695,41 @@ protected function output() { } } -class Hm_Output_folders_actions_content_start extends Hm_Output_Module { +class Hm_Output_folders_folder_subscription extends Hm_Output_Module { protected function output() { - $res = '
'; - return $res; + if ($this->get('only_subscribed_folders_setting', 0) && ($server = $this->get('folder_server')) !== NULL) { + $res = ''; + $res .= ''; + $res .= ''; + return $res; + } + } +} + +/** + * @subpackage imap_folders/handler + */ +class Hm_Handler_get_only_subscribed_folders_setting extends Hm_Handler_Module { + public function process() { + $this->out('only_subscribed_folders_setting', $this->user_config->get('only_subscribed_folders_setting', 0)); } } /** * @subpackage imap_folders/output */ -class Hm_Output_folders_actions_content_end extends Hm_Output_Module { +class Hm_Output_folders_folder_subscription_button extends Hm_Output_Module { protected function output() { - $res = '
'; - return $res; + if ($this->get('only_subscribed_folders_setting', 0)) { + $server = $this->get('folder_server'); + $results = ''; + return $results; + } } } @@ -758,6 +767,16 @@ protected function output() { } } +/** + * @subpackage imap_folders/output + */ +class Hm_Output_folders_subscription_content_start extends Hm_Output_Module { + protected function output() { + $res = '
'.$this->trans('Folders subscription').'
'; + return $res; + } +} + /** * @subpackage imap_folders/output */ @@ -787,6 +806,23 @@ protected function output() { } } +/** + * Option to enable/disable showing only subscribed folders + * @subpackage imap/output + */ +class Hm_Output_imap_only_subscribed_folders_setting extends Hm_Output_Module { + protected function output() { + $checked = ''; + $settings = $this->get('user_settings', array()); + if (array_key_exists('only_subscribed_folders', $settings) && $settings['only_subscribed_folders']) { + $checked = ' checked="checked"'; + } + return ''. + ''; + } +} + if (!hm_exists('get_sieve_linked_mailbox')) { function get_sieve_linked_mailbox ($imap_account, $module) { if (!$module->module_is_supported('sievefilters') && $module->user_config->get('enable_sieve_filter_setting', true)) { diff --git a/modules/imap_folders/setup.php b/modules/imap_folders/setup.php index a8c12b758c..26560055fa 100644 --- a/modules/imap_folders/setup.php +++ b/modules/imap_folders/setup.php @@ -17,14 +17,14 @@ add_handler('folders', 'folders_server_id', true, 'imap_folders', 'load_user_data', 'after'); add_handler('folders', 'special_folders', true, 'imap_folders', 'folders_server_id', 'after'); add_output('folders', 'folders_content_start', true, 'imap_folders', 'content_section_start', 'after'); -add_output('folders', 'folders_server_select', true, 'imap_folders', 'folders_content_start', 'after'); -add_output('folders', 'folders_actions_content_start', true, 'imap_folders', 'folders_folder_subscription', 'after'); +add_output('folders', 'folders_server_select', true, 'imap_folders', 'folders_folder_subscription_button', 'after'); add_output('folders', 'folders_create_dialog', true, 'imap_folders', 'folders_server_select', 'after'); add_output('folders', 'folders_rename_dialog', true, 'imap_folders', 'folders_create_dialog', 'after'); add_output('folders', 'folders_delete_dialog', true, 'imap_folders', 'folders_rename_dialog', 'after'); -add_output('folders', 'folders_actions_content_end', true, 'imap_folders', 'folders_archive_dialog', 'after'); +add_output('folders', 'folders_folder_subscription_button', true, 'imap_folders', 'folders_content_start', 'after'); add_handler('ajax_imap_folder_expand', 'add_folder_manage_link', true, 'imap_folders', 'imap_folder_expand', 'after'); +add_handler('folders', 'get_only_subscribed_folders_setting', true, 'imap_folders'); // Commented out during development add_output('folders', 'folders_trash_dialog', true, 'imap_folders', 'folders_delete_dialog', 'after'); @@ -54,12 +54,6 @@ add_handler('ajax_imap_folders_create', 'imap_bust_cache', true, 'imap', 'process_folder_create', 'after'); add_handler('ajax_imap_folders_create', 'close_session_early', true, 'core', 'imap_bust_cache', 'after'); -setup_base_ajax_page('ajax_imap_folders_create', 'core'); -add_handler('ajax_imap_folders_create', 'load_imap_servers_from_config', true, 'imap', 'load_user_data', 'after'); -add_handler('ajax_imap_folders_create', 'process_folder_create', true, 'imap_folders', 'load_imap_servers_from_config', 'after'); -add_handler('ajax_imap_folders_create', 'imap_bust_cache', true, 'imap', 'process_folder_create', 'after'); -add_handler('ajax_imap_folders_create', 'close_session_early', true, 'core', 'imap_bust_cache', 'after'); - setup_base_ajax_page('ajax_imap_clear_special_folder', 'core'); add_handler('ajax_imap_clear_special_folder', 'load_imap_servers_from_config', true, 'imap', 'load_user_data', 'after'); add_handler('ajax_imap_clear_special_folder', 'process_clear_special_folder', true, 'imap_folders', 'load_imap_servers_from_config', 'after'); @@ -75,17 +69,29 @@ add_handler('ajax_imap_accept_special_folders', 'process_accept_special_folders', true, 'imap_folders', 'load_imap_servers_from_config', 'after'); add_handler('ajax_imap_accept_special_folders', 'save_user_data', true, 'core', 'process_special_folders', 'after'); +add_handler('ajax_hm_folders', 'imap_folder_check', true, 'imap_folders', 'load_user_data', 'after'); +add_output('ajax_hm_folders', 'folders_page_link', true, 'imap_folders', 'settings_menu_end', 'before'); + +add_handler('settings', 'process_only_subscribed_folders_setting', true, 'imap', 'date', 'after'); +add_output('settings', 'imap_only_subscribed_folders_setting', true, 'imap', 'original_folder_setting', 'after'); + +setup_base_page('folders_subscription', 'core'); +add_handler('folders_subscription', 'folders_server_id', true, 'imap_folders', 'load_user_data', 'after'); +add_handler('folders_subscription', 'special_folders', true, 'imap_folders', 'folders_server_id', 'after'); +add_handler('folders_subscription', 'get_only_subscribed_folders_setting', true, 'imap_folders'); +add_output('folders_subscription', 'folders_subscription_content_start', true, 'imap_folders', 'content_section_start', 'after'); +add_output('folders_subscription', 'folders_server_select', true, 'imap_folders', 'folders_subscription_content_start', 'after'); +add_output('folders_subscription', 'folders_folder_subscription', true, 'imap_folders', 'folders_server_select', 'after'); + setup_base_ajax_page('ajax_imap_folder_subscription', 'core'); add_handler('ajax_imap_folder_subscription', 'load_imap_servers_from_config', true, 'imap', 'load_user_data', 'after'); add_handler('ajax_imap_folder_subscription', 'process_imap_folder_subscription', true, 'imap_folders', 'load_imap_servers_from_config', 'after'); add_handler('ajax_imap_folder_subscription', 'save_user_data', true, 'core', 'process_special_folder', 'after'); -add_handler('ajax_hm_folders', 'imap_folder_check', true, 'imap_folders', 'load_user_data', 'after'); -add_output('ajax_hm_folders', 'folders_page_link', true, 'imap_folders', 'settings_menu_end', 'before'); - return array( 'allowed_pages' => array( 'folders', + 'folders_subscription', 'ajax_imap_folders_delete', 'ajax_imap_folders_create', 'ajax_imap_folders_rename', @@ -100,9 +106,12 @@ ), 'allowed_get' => array(), 'allowed_post' => array( - 'parent' => FILTER_DEFAULT, - 'new_folder' => FILTER_DEFAULT, - 'special_folder_type' => FILTER_DEFAULT, - 'imap_service_name' => FILTER_DEFAULT + 'parent' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, + 'new_folder' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, + 'special_folder_type' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, + 'imap_service_name' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, + 'subscription_state' => FILTER_VALIDATE_BOOLEAN, + 'folder' => FILTER_VALIDATE_BOOLEAN, + 'only_subscribed_folders' => FILTER_VALIDATE_BOOLEAN, ) ); diff --git a/modules/imap_folders/site.css b/modules/imap_folders/site.css index 014483508b..3d9d0558cc 100644 --- a/modules/imap_folders/site.css +++ b/modules/imap_folders/site.css @@ -10,16 +10,14 @@ .manage_folder_icon { vertical-align: -3px; opacity: .3 } .manage_folder_link { color: #999 !important; } -.folders_subscription { width: 100%; display: inline-block; } +.folder_subscription_btn { position: absolute; right: 20px; top: 20px; } +.folders_subscription { padding-left: 10px; width: 100%; display: inline-block; } .folders_subscription input { float: right; } -.folder_actions { width: 100%; display: inline-block; vertical-align: top; margin-left: 1%; } @media (min-width: 687px) { .folders_subscription { width: 30% } - .folder_actions { width: 65%; } } @media (min-width: 1201px) { .folders_subscription { width: 25% } - .folder_actions { width: 72%; } } diff --git a/modules/imap_folders/site.js b/modules/imap_folders/site.js index bd030f90c2..52d91cdafb 100644 --- a/modules/imap_folders/site.js +++ b/modules/imap_folders/site.js @@ -1,6 +1,6 @@ 'use strict'; -var folder_page_folder_list = function(container, title, link_class, target, id_dest) { +var folder_page_folder_list = function(container, title, link_class, target, id_dest, subscription = false) { var id = $('#imap_server_folder').val(); var folder_location = $('.'+container); $('li', folder_location).not('.'+title).remove(); @@ -9,7 +9,7 @@ var folder_page_folder_list = function(container, title, link_class, target, id_ $('.imap_folder_link', folders).addClass(link_class).removeClass('imap_folder_link'); folder_location.prepend(folders); folder_location.show(); - $('.'+link_class, folder_location).on("click", function() { return expand_folders_page_list($(this).data('target'), container, link_class, target, id_dest); }); + $('.'+link_class, folder_location).on("click", function() { return expand_folders_page_list($(this).data('target'), container, link_class, target, id_dest, subscription); }); $('a', folder_location).not('.'+link_class).not('.close').off('click'); $('a', folder_location).not('.'+link_class).not('.close').on("click", function() { set_folders_page_value($(this).data('id'), container, target, id_dest); return false; }); $('.close', folder_location).on("click", function() { @@ -22,8 +22,7 @@ var folder_page_folder_list = function(container, title, link_class, target, id_ return false; }; - -var expand_folders_page_list = function(path, container, link_class, target, id_dest) { +var expand_folders_page_list = function(path, container, link_class, target, id_dest, lsub) { var detail = Hm_Utils.parse_folder_path(path, 'imap'); var list = $('.imap_'+detail.server_id+'_'+Hm_Utils.clean_selector(detail.folder), $('.'+container)); if ($('li', list).length === 0) { @@ -32,7 +31,8 @@ var expand_folders_page_list = function(path, container, link_class, target, id_ Hm_Ajax.request( [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_folder_expand'}, {'name': 'imap_server_id', 'value': detail.server_id}, - {'name': 'folder', 'value': detail.folder}], + {'name': 'folder', 'value': detail.folder}, + {'name': 'subscription_state', 'value': lsub}], function(res) { if (res.imap_expanded_folder_path) { var folder_location = $('.'+container); @@ -41,9 +41,12 @@ var expand_folders_page_list = function(path, container, link_class, target, id_ $('.'+Hm_Utils.clean_selector(res.imap_expanded_folder_path), folder_location).append(folders); $('.imap_folder_link', folder_location).addClass(link_class).removeClass('imap_folder_link'); $('.'+link_class, folder_location).off('click'); - $('.'+link_class, folder_location).on("click", function() { return expand_folders_page_list($(this).data('target'), container, link_class, target, id_dest); }); + $('.'+link_class, folder_location).on("click", function() { return expand_folders_page_list($(this).data('target'), container, link_class, target, id_dest, lsub); }); $('a', folder_location).not('.'+link_class).not('.close').off('click'); $('a', folder_location).not('.'+link_class).not('.close').on("click", function() { set_folders_page_value($(this).data('id'), container, target, id_dest); return false; }); + if (lsub) { + $('.folder_subscription').on("change", function() { folder_subscribe(this.id, $('#'+this.id).is(':checked')); return false; }); + } } } ); @@ -223,6 +226,8 @@ var folder_subscribe = function(name, state) { if (!res.imap_folder_subscription) { var el = $('#'+name); el.prop('checked', !el.prop('checked')); + } else { + Hm_Folders.reload_folders(true); } } ); @@ -258,12 +263,19 @@ var folder_page_create = function() { }; $(function() { - if (hm_page_name() == 'folders') { + if (hm_page_name() == 'folders' || hm_page_name() == 'folders_subscription') { $('#imap_server_folder').on("change", function() { $(this).parent().parent().submit(); }); + } + if (hm_page_name() == 'folders') { $('.settings_subtitle').on("click", function() { return Hm_Utils.toggle_page_section($(this).data('target')); }); } + if (hm_page_name() == 'folders_subscription') { + $('.subscribe_parent_folder').on("click", function() { return folder_page_folder_list('subscribe_parent_folder_select', 'suscribe_title', 'imap_parent_folder_link', '', 'subscribe_parent', true); }); + $('.subscribe_parent_folder').trigger('click'); + $('.imap_parent_folder_link').trigger('click'); + } $('.select_parent_folder').on("click", function() { return folder_page_folder_list('parent_folder_select', 'parent_title', 'imap_parent_folder_link', 'selected_parent', 'create_parent'); }); $('.select_rename_folder').on("click", function() { return folder_page_folder_list('rename_folder_select', 'rename_title', 'imap_rename_folder_link', 'selected_rename', 'rename_source'); }); $('.select_delete_folder').on("click", function() { return folder_page_folder_list('delete_folder_select', 'delete_title', 'imap_delete_folder_link', 'selected_delete', 'delete_source'); }); @@ -287,6 +299,4 @@ $(function() { $('#clear_sent_folder').on("click", function() { clear_special_folder('sent'); return false; }); $('#clear_archive_folder').on("click", function() { clear_special_folder('archive'); return false; }); $('#clear_draft_folder').on("click", function() { clear_special_folder("draft"); return false; }); - - $('.folder_subscription').on("change", function() { folder_subscribe(this.id, $('#'+this.id).is(':checked')); return false; }); }); From c2037d9b4ba6115a0a25e87fde9c2bc4070c8dcd Mon Sep 17 00:00:00 2001 From: Josaphat Imani Date: Tue, 19 Dec 2023 13:21:44 +0200 Subject: [PATCH 3/4] Fixed issues related to subscribed children/unsubscribed parent --- modules/imap/functions.php | 29 ++++++++++++++---------- modules/imap/handler_modules.php | 4 +++- modules/imap/hm-imap.php | 39 +++++++++++++++++++++++--------- modules/imap/output_modules.php | 5 ++-- modules/imap/site.css | 2 ++ modules/imap_folders/modules.php | 7 +++--- modules/imap_folders/setup.php | 10 ++++---- modules/imap_folders/site.js | 3 ++- 8 files changed, 64 insertions(+), 35 deletions(-) diff --git a/modules/imap/functions.php b/modules/imap/functions.php index c2a8809db5..fceaaaf87b 100644 --- a/modules/imap/functions.php +++ b/modules/imap/functions.php @@ -111,7 +111,7 @@ function prepare_imap_message_list($msgs, $mod, $type) { * @return string */ if (!hm_exists('format_imap_folder_section')) { -function format_imap_folder_section($folders, $id, $output_mod) { +function format_imap_folder_section($folders, $id, $output_mod, $with_input = false) { $results = '
    '; $manage = $output_mod->get('imap_folder_manage_link'); foreach ($folders as $folder_name => $folder) { @@ -124,25 +124,30 @@ function format_imap_folder_section($folders, $id, $output_mod) { $results .= ' '; } if (!$folder['noselect']) { + if (!$folder['clickable']) { + $attrs = 'tabindex="0"'; + if (!$with_input && isset($folder['subscribed']) && !$folder['subscribed']) { + $attrs .= ' class="folder-disabled"'; + } + } else { + $attrs = 'data-id="imap_'.$id.'_'.$output_mod->html_safe($folder_name). + '" href="?page=message_list&list_path='. + urlencode('imap_'.$id.'_'.$output_mod->html_safe($folder_name)).'"'; + } if (strlen($output_mod->html_safe($folder['basename']))>15) { - $results .= 'html_safe($folder['basename']). '">'.substr($output_mod->html_safe($folder['basename']),0,15).'...'; } - else{ - $results .= ''.$output_mod->html_safe($folder['basename']).''; + else { + $results .= ''.$output_mod->html_safe($folder['basename']).''; } } else { $results .= $output_mod->html_safe($folder['basename']); } - if (isset($folder['subscribed'])) { - $results .= ''; + if ($with_input) { + $results .= ''; } $results .= ''; } diff --git a/modules/imap/handler_modules.php b/modules/imap/handler_modules.php index f77f2d16d7..360687b643 100644 --- a/modules/imap/handler_modules.php +++ b/modules/imap/handler_modules.php @@ -721,17 +721,18 @@ public function process() { $prefetched[] = $form['imap_server_id']; $this->session->set('imap_prefetched_ids', array_unique($prefetched, SORT_NUMERIC)); } + $with_subscription = isset($this->request->post['subscription_state']) && $this->request->post['subscription_state']; if ($page_cache) { $this->out('imap_expanded_folder_data', $page_cache); $this->out('imap_expanded_folder_id', $form['imap_server_id']); $this->out('imap_expanded_folder_path', $path); + $this->out('with_input', $with_subscription); return; } $cache = Hm_IMAP_List::get_cache($this->cache, $form['imap_server_id']); $imap = Hm_IMAP_List::connect($form['imap_server_id'], $cache); if (imap_authed($imap)) { $only_subscribed = $this->user_config->get('only_subscribed_folders_setting', false); - $with_subscription = isset($this->request->post['subscription_state']) && $this->request->post['subscription_state']; if ($with_subscription) { $only_subscribed = false; } @@ -743,6 +744,7 @@ public function process() { $this->out('imap_expanded_folder_data', $msgs); $this->out('imap_expanded_folder_id', $form['imap_server_id']); $this->out('imap_expanded_folder_path', $path); + $this->out('with_input', $with_subscription); } else { Hm_Msgs::add(sprintf('ERRCould not authenticate to the selected %s server (%s)', $imap->server_type, $this->user_config->get('imap_servers')[$form['imap_server_id']]['user'])); diff --git a/modules/imap/hm-imap.php b/modules/imap/hm-imap.php index d268e68142..6c592881a9 100644 --- a/modules/imap/hm-imap.php +++ b/modules/imap/hm-imap.php @@ -427,18 +427,19 @@ public function get_mailbox_list($lsub=false, $mailbox='', $keyword='*') { $can_have_kids = true; $has_kids = false; $marked = false; + $special = false; $folder_sort_by = 'ARRIVAL'; $check_for_new = false; /* full folder name, includes an absolute path of parent folders */ - if ($vals[(count($vals) - 1)] == ')' && $lsub) { - $folder = $this->utf7_decode($vals[6]); + if ($lsub && in_array("\HasChildren", $vals)) { + $folder = $this->utf7_decode($vals[array_search(".", $vals) + 1]); } else { $folder = $this->utf7_decode($vals[(count($vals) - 1)]); } /* sometimes LIST responses have dupes */ - if (isset($folders[$folder]) || !$folder) { + if (isset($folders[$folder]) || !$folder || $folder === '*') { continue; } @@ -490,7 +491,6 @@ public function get_mailbox_list($lsub=false, $mailbox='', $keyword='*') { /* special use mailbox extension */ if ($this->is_supported('SPECIAL-USE')) { - $special = false; foreach ($this->special_use_mailboxes as $name => $value) { if (stristr($flags, $name)) { $special = $name; @@ -522,12 +522,22 @@ public function get_mailbox_list($lsub=false, $mailbox='', $keyword='*') { /* store the results in the big folder list struct */ if (strtolower($folder) == 'inbox') { $inbox = true; + $special = true; } - $folders[$folder] = array('parent' => $parent, 'delim' => $delim, 'name' => $folder, - 'name_parts' => $folder_parts, 'basename' => $base_name, - 'realname' => $folder, 'namespace' => $namespace, 'marked' => $marked, - 'noselect' => $no_select, 'can_have_kids' => $can_have_kids, - 'has_kids' => $has_kids); + $folders[$folder] = array( + 'parent' => $parent, + 'delim' => $delim, + 'name' => $folder, + 'name_parts' => $folder_parts, + 'basename' => $base_name, + 'realname' => $folder, + 'namespace' => $namespace, + 'marked' => $marked, + 'noselect' => $no_select, + 'can_have_kids' => $can_have_kids, + 'has_kids' => $has_kids, + 'special' => (bool) $special + ); /* store a parent list used below */ if ($parent && !in_array($parent, $parents)) { @@ -2144,7 +2154,7 @@ public function get_mailbox_page($mailbox, $sort, $rev, $filter, $offset=0, $lim * @param string $level mailbox name or empty string for the top level * @return array list of matching folders */ - public function get_folder_list_by_level($level='', $only_subscribed=false, $with_subscription_state = false) { + public function get_folder_list_by_level($level='', $only_subscribed=false, $with_input = false) { $result = array(); $folders = $this->get_mailbox_list($only_subscribed, $level, '%'); foreach ($folders as $name => $folder) { @@ -2156,12 +2166,19 @@ public function get_folder_list_by_level($level='', $only_subscribed=false, $wit 'noselect' => $folder['noselect'], 'id' => bin2hex($folder['basename']), 'name_parts' => $folder['name_parts'], + 'clickable' => !$with_input, ); + if ($with_input) { + $result[$name]['special'] = $folder['special']; + } } - if ($with_subscription_state) { + if ($only_subscribed || $with_input) { $subscribed_folders = array_column($this->get_mailbox_list(true), 'name'); foreach ($result as $key => $folder) { $result[$key]['subscribed'] = in_array($folder['name'], $subscribed_folders); + if (!$with_input) { + $result[$key]['clickable'] = $result[$key]['subscribed']; + } } } return $result; diff --git a/modules/imap/output_modules.php b/modules/imap/output_modules.php index 2d476ed885..1f354b0e78 100644 --- a/modules/imap/output_modules.php +++ b/modules/imap/output_modules.php @@ -764,8 +764,9 @@ class Hm_Output_filter_expanded_folder_data extends Hm_Output_Module { protected function output() { $res = ''; $folder_data = $this->get('imap_expanded_folder_data', array()); + $with_input = $this->get('with_input', false); if (!empty($folder_data)) { - $res .= format_imap_folder_section($folder_data, $this->get('imap_expanded_folder_id'), $this); + $res .= format_imap_folder_section($folder_data, $this->get('imap_expanded_folder_id'), $this, $with_input); $this->out('imap_expanded_folder_formatted', $res); } } @@ -1109,7 +1110,7 @@ protected function output() { if (!array_key_exists('auto_advance_email', $settings) || (array_key_exists('auto_advance_email', $settings) && $settings['auto_advance_email'])) { $checked = ' checked="checked"'; } else { - $reset = 'Refresh'; + $reset = ''; } $res = ''. diff --git a/modules/imap/site.css b/modules/imap/site.css index c8df1bc772..9322d1b9b4 100644 --- a/modules/imap/site.css +++ b/modules/imap/site.css @@ -198,3 +198,5 @@ .fade-in { animation-name: fadeIn; } + + diff --git a/modules/imap_folders/modules.php b/modules/imap_folders/modules.php index 1a99a0a3bd..0b3cbb8a74 100644 --- a/modules/imap_folders/modules.php +++ b/modules/imap_folders/modules.php @@ -725,8 +725,7 @@ protected function output() { $server = $this->get('folder_server'); $results = ''; return $results; } @@ -813,13 +812,15 @@ protected function output() { class Hm_Output_imap_only_subscribed_folders_setting extends Hm_Output_Module { protected function output() { $checked = ''; + $reset = ''; $settings = $this->get('user_settings', array()); if (array_key_exists('only_subscribed_folders', $settings) && $settings['only_subscribed_folders']) { $checked = ' checked="checked"'; + $reset = ''; } return ''. - ''; + ''.$reset.''; } } diff --git a/modules/imap_folders/setup.php b/modules/imap_folders/setup.php index 26560055fa..5bafd10490 100644 --- a/modules/imap_folders/setup.php +++ b/modules/imap_folders/setup.php @@ -106,12 +106,12 @@ ), 'allowed_get' => array(), 'allowed_post' => array( - 'parent' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, - 'new_folder' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, - 'special_folder_type' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, - 'imap_service_name' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, + 'parent' => FILTER_DEFAULT, + 'new_folder' => FILTER_DEFAULT, + 'special_folder_type' => FILTER_DEFAULT, + 'imap_service_name' => FILTER_DEFAULT, 'subscription_state' => FILTER_VALIDATE_BOOLEAN, - 'folder' => FILTER_VALIDATE_BOOLEAN, + 'folder' => FILTER_DEFAULT, 'only_subscribed_folders' => FILTER_VALIDATE_BOOLEAN, ) ); diff --git a/modules/imap_folders/site.js b/modules/imap_folders/site.js index 52d91cdafb..1bb0ea154e 100644 --- a/modules/imap_folders/site.js +++ b/modules/imap_folders/site.js @@ -223,10 +223,11 @@ var folder_subscribe = function(name, state) { {'name': 'subscription_state', 'value': state}, {'name': 'folder', 'value': name}], function(res) { + var el = $('#'+name); if (!res.imap_folder_subscription) { - var el = $('#'+name); el.prop('checked', !el.prop('checked')); } else { + el.prev().toggleClass('folder-disabled'); Hm_Folders.reload_folders(true); } } From a0291148b449b493aa6d22a1a48257d7f44d8eb2 Mon Sep 17 00:00:00 2001 From: Josaphat Imani Date: Wed, 21 Feb 2024 13:28:30 +0200 Subject: [PATCH 4/4] Fixed redirection to folders page or home --- modules/advanced_search/site.js | 2 +- modules/imap/site.js | 2 +- modules/imap_folders/modules.php | 7 ++++--- modules/imap_folders/setup.php | 3 ++- modules/imap_folders/site.js | 11 ++++++++--- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/modules/advanced_search/site.js b/modules/advanced_search/site.js index 0591788a71..eb467682b5 100644 --- a/modules/advanced_search/site.js +++ b/modules/advanced_search/site.js @@ -150,7 +150,7 @@ var expand_adv_folder_list = function(path) { var detail = Hm_Utils.parse_folder_path(path, 'imap'); var list = $('.imap_'+detail.server_id+'_'+Hm_Utils.clean_selector(detail.folder), $('.adv_folder_list')); if ($('li', list).length === 0) { - $('.expand_link', list).html('-'); + $('.expand_link', list).html(''); if (detail) { Hm_Ajax.request( [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_folder_expand'}, diff --git a/modules/imap/site.js b/modules/imap/site.js index cef2e8c61f..a101bf9afb 100644 --- a/modules/imap/site.js +++ b/modules/imap/site.js @@ -1016,7 +1016,7 @@ var expand_imap_move_to_folders = function(path, context) { var detail = Hm_Utils.parse_folder_path(path, 'imap'); var list = $('.imap_'+detail.server_id+'_'+Hm_Utils.clean_selector(detail.folder), $('.move_to_location')); if ($('li', list).length === 0) { - $('.expand_link', list).html('-'); + $('.expand_link', list).html(''); if (detail) { Hm_Ajax.request( [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_folder_expand'}, diff --git a/modules/imap_folders/modules.php b/modules/imap_folders/modules.php index 0b3cbb8a74..e8cc04b923 100644 --- a/modules/imap_folders/modules.php +++ b/modules/imap_folders/modules.php @@ -322,6 +322,7 @@ public function process() { if (array_key_exists('imap_server_id', $this->request->get)) { var_dump($this->request->get['imap_server_id']); $this->out('folder_server', $this->request->get['imap_server_id']); + $this->out('page', $this->request->get['page']); } } } @@ -345,7 +346,7 @@ public function process() { $imap_server_id = $this->request->get['imap_server_id']; $cache = Hm_IMAP_List::get_cache($this->cache, $imap_server_id); $imap = Hm_IMAP_List::connect($imap_server_id, $cache); - if (is_object($imap) && $imap->get_state() == 'authenticated') { + if (imap_authed($imap)) { $folder = hex2bin($form['folder']); $success = $imap->mailbox_subscription($folder, $form['subscription_state']); if ($success) { @@ -380,7 +381,7 @@ class Hm_Output_folders_server_select extends Hm_Output_Module { protected function output() { $server_id = $this->get('folder_server', ''); $res = '
    '; - $res .= ''; + $res .= ''; $res .= '
    '; return $res; } diff --git a/modules/imap_folders/setup.php b/modules/imap_folders/setup.php index 5bafd10490..8f769bf14a 100644 --- a/modules/imap_folders/setup.php +++ b/modules/imap_folders/setup.php @@ -102,7 +102,8 @@ ), 'allowed_output' => array( 'imap_folders_success' => array(FILTER_VALIDATE_INT, false), - 'imap_special_name' => array(FILTER_DEFAULT, false) + 'imap_special_name' => array(FILTER_DEFAULT, false), + 'imap_folder_subscription' => array(FILTER_DEFAULT, false), ), 'allowed_get' => array(), 'allowed_post' => array( diff --git a/modules/imap_folders/site.js b/modules/imap_folders/site.js index 1bb0ea154e..8fd8e21988 100644 --- a/modules/imap_folders/site.js +++ b/modules/imap_folders/site.js @@ -26,7 +26,7 @@ var expand_folders_page_list = function(path, container, link_class, target, id_ var detail = Hm_Utils.parse_folder_path(path, 'imap'); var list = $('.imap_'+detail.server_id+'_'+Hm_Utils.clean_selector(detail.folder), $('.'+container)); if ($('li', list).length === 0) { - $('.expand_link', list).html('-'); + $('.expand_link', list).html(''); if (detail) { Hm_Ajax.request( [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_folder_expand'}, @@ -273,9 +273,14 @@ $(function() { $('.settings_subtitle').on("click", function() { return Hm_Utils.toggle_page_section($(this).data('target')); }); } if (hm_page_name() == 'folders_subscription') { - $('.subscribe_parent_folder').on("click", function() { return folder_page_folder_list('subscribe_parent_folder_select', 'suscribe_title', 'imap_parent_folder_link', '', 'subscribe_parent', true); }); + $('.subscribe_parent_folder').on("click", function() { return folder_page_folder_list('subscribe_parent_folder_select', 'subscribe_title', 'imap_parent_folder_link', '', 'subscribe_parent', true); }); $('.subscribe_parent_folder').trigger('click'); - $('.imap_parent_folder_link').trigger('click'); + $($('.subscribe_parent_folder_select .imap_parent_folder_link')[0]).trigger('click'); + const selected_imap_server = $('#imap_server_folder').val(); + const email_folder_server = $(`.email_folders .imap_${selected_imap_server}_ .inner_list`); + if (email_folder_server && $(email_folder_server[0]).children().length) { + $($('.subscribe_parent_folder_select .imap_parent_folder_link')[0]).trigger('click'); + } } $('.select_parent_folder').on("click", function() { return folder_page_folder_list('parent_folder_select', 'parent_title', 'imap_parent_folder_link', 'selected_parent', 'create_parent'); }); $('.select_rename_folder').on("click", function() { return folder_page_folder_list('rename_folder_select', 'rename_title', 'imap_rename_folder_link', 'selected_rename', 'rename_source'); });