Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added subscription to folders #622

Merged
merged 4 commits into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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');
kroky marked this conversation as resolved.
Show resolved Hide resolved
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 @@ -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);
}
}
Expand Down Expand Up @@ -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 = '<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 @@ -198,3 +198,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 @@ -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('<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