Skip to content

Commit

Permalink
Merge pull request cypht-org#622 from josaphatim/folder-subscription
Browse files Browse the repository at this point in the history
Added subscription to folders
  • Loading branch information
kroky authored Feb 26, 2024
2 parents ddf1dce + a029114 commit 3be69f2
Show file tree
Hide file tree
Showing 11 changed files with 272 additions and 39 deletions.
2 changes: 1 addition & 1 deletion modules/advanced_search/site.js
Original file line number Diff line number Diff line change
Expand Up @@ -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('<i class="bi bi-file-minus-fill"></i>');
if (detail) {
Hm_Ajax.request(
[{'name': 'hm_ajax_hook', 'value': 'ajax_imap_folder_expand'},
Expand Down
28 changes: 18 additions & 10 deletions modules/imap/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 = '<ul class="inner_list">';
$manage = $output_mod->get('imap_folder_manage_link');
foreach ($folders as $folder_name => $folder) {
Expand All @@ -124,23 +124,31 @@ function format_imap_folder_section($folders, $id, $output_mod) {
$results .= '<i class="bi bi-folder2-open"></i> ';
}
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&amp;list_path='.
urlencode('imap_'.$id.'_'.$output_mod->html_safe($folder_name)).'"';
}
if (strlen($output_mod->html_safe($folder['basename']))>15) {
$results .= '<a data-id="imap_'.$id.'_'.$output_mod->html_safe($folder_name).
'" href="?page=message_list&amp;list_path='.
urlencode('imap_'.$id.'_'.$output_mod->html_safe($folder_name)).
'"title="'.$output_mod->html_safe($folder['basename']).
$results .= '<a ' . $attrs .
' title="'.$output_mod->html_safe($folder['basename']).
'">'.substr($output_mod->html_safe($folder['basename']),0,15).'...</a>';
}
else{
$results .= '<a data-id="imap_'.$id.'_'.$output_mod->html_safe($folder_name).
'" href="?page=message_list&amp;list_path='.
urlencode('imap_'.$id.'_'.$output_mod->html_safe($folder_name)).
'">'.$output_mod->html_safe($folder['basename']).'</a>';
else {
$results .= '<a ' . $attrs. '>'.$output_mod->html_safe($folder['basename']).'</a>';
}
}
else {
$results .= $output_mod->html_safe($folder['basename']);
}
if ($with_input) {
$results .= '<input type="checkbox" value="1" class="folder_subscription" id="'.$output_mod->html_safe($folder_name).'" name="'.$folder_name.'" '.($folder['subscribed']? 'checked="checked"': '').($folder['special']? ' disabled="disabled"': '').' />';
}
$results .= '<span class="unread_count unread_imap_'.$id.'_'.$output_mod->html_safe($folder_name).'"></span></li>';
}
if ($manage) {
Expand Down
9 changes: 8 additions & 1 deletion modules/imap/handler_modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -721,23 +721,30 @@ 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)) {
$msgs = $imap->get_folder_list_by_level(hex2bin($folder));
$only_subscribed = $this->user_config->get('only_subscribed_folders_setting', false);
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]);
}
$this->cache->set('imap_folders_'.$path, $msgs);
$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']));
Expand Down
61 changes: 51 additions & 10 deletions modules/imap/hm-imap.php
Original file line number Diff line number Diff line change
Expand Up @@ -427,14 +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 */
$folder = $this->utf7_decode($vals[(count($vals) - 1)]);
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;
}

Expand Down Expand Up @@ -486,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;
Expand Down Expand Up @@ -518,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)) {
Expand Down Expand Up @@ -685,6 +699,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 -------------------------- */

/**
Expand Down Expand Up @@ -2127,18 +2154,32 @@ 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_input = false) {
$result = array();
$folders = $this->get_mailbox_list(false, $level, '%');
$folders = $this->get_mailbox_list($only_subscribed, $level, '%');
foreach ($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'],
'clickable' => !$with_input,
);
if ($with_input) {
$result[$name]['special'] = $folder['special'];
}
}
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;
}
Expand Down
5 changes: 3 additions & 2 deletions modules/imap/output_modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -765,8 +765,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);
}
}
Expand Down Expand Up @@ -1110,7 +1111,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 = '<span class="tooltip_restore" restore_aria_label="Restore default value"><img alt="Refresh" class="refresh_list reset_default_value_checkbox" src="'.Hm_Image_Sources::$refresh.'" /></span>';
$reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-repeat refresh_list reset_default_value_checkbox"></i></span>';
}
$res = '<tr class="general_setting"><td><label class="form-check-label" for="auto_advance_email">'.
$this->trans('Show next email instead of your inbox after performing action (delete, archive, move, etc)').'</label></td>'.
Expand Down
2 changes: 2 additions & 0 deletions modules/imap/site.css
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,5 @@
.fade-in {
animation-name: fadeIn;
}


2 changes: 1 addition & 1 deletion modules/imap/site.js
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,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('<i class="bi bi-file-minus-fill"></i>');
if (detail) {
Hm_Ajax.request(
[{'name': 'hm_ajax_hook', 'value': 'ajax_imap_folder_expand'},
Expand Down
109 changes: 107 additions & 2 deletions modules/imap_folders/modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -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']);
}
}
}
Expand All @@ -335,14 +336,52 @@ 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 (imap_authed($imap)) {
$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);
}
}
}
}

/**
* 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
*/
class Hm_Output_folders_server_select extends Hm_Output_Module {
protected function output() {
$server_id = $this->get('folder_server', '');
$res = '<div class="folders_page mt-4 row mb-4"><div class="col-lg-5 col-sm-12"><form id="form_folder_imap" method="get">';
$res .= '<input type="hidden" name="page" value="folders" />';
$res .= '<input type="hidden" name="page" value="'.$this->get('page', 'folders').'" />';
$res .= '<div class="form-floating"><select class="form-select" id="imap_server_folder" name="imap_server_id">';
$res .= '<option ';
if (empty($server_id)) {
Expand Down Expand Up @@ -653,7 +692,44 @@ protected function output() {
</div>
</div>';

return $res;
$res .= '</div>';
}
}

class Hm_Output_folders_folder_subscription extends Hm_Output_Module {
protected function output() {
if ($this->get('only_subscribed_folders_setting', 0) && ($server = $this->get('folder_server')) !== NULL) {
$res = '<div class="folder_row"><a href="#" class="subscribe_parent_folder" style="display:none;">';
$res .= $this->trans('Select Folder').'</a><span class="subscribe_parent"></span></div>';
$res .= '<ul class="folders subscribe_parent_folder_select"><li class="subscribe_title"></li></ul>';
$res .= '<input type="hidden" value="" id="subscribe_parent" />';
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_folder_subscription_button extends Hm_Output_Module {
protected function output() {
if ($this->get('only_subscribed_folders_setting', 0)) {
$server = $this->get('folder_server');
$results = '<div class="folder_subscription_btn"><a href="?page=folders_subscription';
$results .= !is_null($server)? '&imap_server_id='.$server: '';
$results .= '" title="'.$this->trans('Folders subscription').'"><i class="bi bi-gear-fill account_icon float-end"></i> ';
$results .= '</a></div>';
return $results;
}
}
}

Expand Down Expand Up @@ -691,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 = '<div class="content_title">'.$this->trans('Folders subscription').'</div>';
return $res;
}
}

/**
* @subpackage imap_folders/output
*/
Expand Down Expand Up @@ -720,6 +806,25 @@ 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 = '';
$reset = '';
$settings = $this->get('user_settings', array());
if (array_key_exists('only_subscribed_folders', $settings) && $settings['only_subscribed_folders']) {
$checked = ' checked="checked"';
$reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-repeat refresh_list reset_default_value_checkbox"></i></span>';
}
return '<tr class="general_setting"><td><label for="only_subscribed_folders">'.
$this->trans('Showing subscribed folders only').'</label></td>'.
'<td><input type="checkbox" '.$checked.' id="only_subscribed_folders" name="only_subscribed_folders" value="1" class="form-check-input" />'.$reset.'</td></tr>';
}
}

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)) {
Expand Down
Loading

0 comments on commit 3be69f2

Please sign in to comment.