Skip to content

Commit

Permalink
Allow performing a search operation in all folders (#1337)
Browse files Browse the repository at this point in the history
* WIP: Allow searching in all folders for a given imap seerver

* The frontend fetches data from all folders

* Keep all lists displayed when searching across multiple maiboxes
  • Loading branch information
mercihabam authored Nov 12, 2024
1 parent 3b3d5f2 commit 1141475
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 14 deletions.
25 changes: 21 additions & 4 deletions modules/advanced_search/modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,6 @@ public function process() {
if (!imap_authed($imap)) {
return;
}
if (!$imap->select_mailbox($this->folder)) {
return;
}
if ($charset) {
$imap->search_charset = $charset;
}
Expand All @@ -93,11 +90,31 @@ public function process() {
$params[] = array($target, $term);
}
}
$this->out('imap_search_results', $this->imap_search($flags, $imap, $params, $limit));

if ($this->request->post['all_folders']) {
$msg_list = $this->all_folders_search($imap, $flags, $params, $limit);
} else if (!$imap->select_mailbox($this->folder)) {
return;
} else {
$msg_list = $this->imap_search($flags, $imap, $params, $limit);
}
$this->out('imap_search_results', $msg_list);
$this->out('folder_status', $imap->folder_state);
$this->out('imap_server_ids', array($this->imap_id));
}

private function all_folders_search($imap, $flags, $params, $limit) {
$folders = $imap->get_mailbox_list();
$msg_list = array();
foreach ($folders as $folder) {
$this->folder = $folder['name'];
$imap->select_mailbox($this->folder);
$msgs = $this->imap_search($flags, $imap, $params, $limit);
$msg_list = array_merge($msg_list, $msgs);
}
return $msg_list;
}

private function imap_search($flags, $imap, $params, $limit) {
$msg_list = array();
$exclude_deleted = true;
Expand Down
1 change: 1 addition & 0 deletions modules/advanced_search/setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@
'adv_flags' => array('filter' => FILTER_DEFAULT, 'flags' => FILTER_REQUIRE_ARRAY),
'adv_terms' => array('filter' => FILTER_DEFAULT, 'flags' => FILTER_REQUIRE_ARRAY),
'adv_targets' => array('filter' => FILTER_DEFAULT, 'flags' => FILTER_REQUIRE_ARRAY),
'all_folders' => FILTER_VALIDATE_BOOLEAN,
)
);
1 change: 0 additions & 1 deletion modules/advanced_search/site.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
.adv_controls { margin-left: 25px; display: none; }
.adv_folder_list { width: 400px; }
.adv_source_list { margin-top: 10px; line-height: 150%; }
.adv_source_list img { margin-right: 10px; }
.adv_expand_all { display: none; }
Expand Down
58 changes: 49 additions & 9 deletions modules/advanced_search/site.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,15 @@ var expand_adv_folder = function(res) {
}
};

$(document).on("change", "input#all_folders", function() {
const folderLi = $(this).closest('li');
if ($(this).is(':checked')) {
folderLi.find('a').attr('disabled', 'disabled');
} else {
folderLi.find('a').removeAttr('disabled');
}
});

var adv_select_imap_folder = function(el) {
var close = $(globals.close_html);
close.addClass('close_adv_folders ms-2');
Expand All @@ -96,6 +105,19 @@ var adv_select_imap_folder = function(el) {
$(el).after(close);
list_container.show();
folders.show();

folders.find('li').each(function() {
const wrapper = $('<div class="d-flex justify-content-between"></div>');
$(this).wrapInner(wrapper);
const allFoldersCheckbox = `
<span class="form-check">
<label class="form-check-label" for="all_folders">All Folders</label>
<input class="form-check-input" type="checkbox" id="all_folders">
</span>
`;
wrapper.append(allFoldersCheckbox);
})

$('.imap_folder_link', folders).addClass('adv_folder_link').removeClass('imap_folder_link');
$('.adv_folder_list').html(folders.html());

Expand Down Expand Up @@ -188,15 +210,27 @@ var adv_expand_sections = function() {
}

var get_adv_sources = function() {
var sources = [];
var selected_sources = $('div', $('.adv_source_list'));
const sources = [];

const searchInAllFolders = $('.adv_folder_list li input:checked')
searchInAllFolders.each(function() {
const li = $(this).closest('li');
sources.push({'source': li.attr('class'), 'label': li.find('a').text()});
});


const selected_sources = $('div', $('.adv_source_list'));
if (!selected_sources) {
return sources;
}
selected_sources.each(function() {
sources.push({'source': this.className, 'label': $(this).text()});
const source = this.className;
const mailboxSource = source.split('_').slice(0, 2).join('_');
if (!sources.find(s => s.source.indexOf(mailboxSource) > -1)) {
sources.push({'source': source, 'label': $('a', $(this)).text()});
}
});
return sources;
return [sources, searchInAllFolders.length > 0];
};

var get_adv_terms = function() {
Expand Down Expand Up @@ -294,7 +328,7 @@ var process_advanced_search = function() {
Hm_Notices.show([err_msg('You must enter at least one search term')]);
return;
}
var sources = get_adv_sources();
const [sources, allFolders] = get_adv_sources();
if (sources.length == 0) {
Hm_Notices.show([err_msg('You must select at least one source')]);
return;
Expand All @@ -315,7 +349,7 @@ var process_advanced_search = function() {
search_summary({ 'terms': terms, 'targets': targets, 'sources': sources,
'times': times, 'other': other });

send_requests(build_adv_search_requests(terms, sources, targets, times, other));
send_requests(build_adv_search_requests(terms, sources, targets, times, other), allFolders);
};

var save_search_details = function(terms, sources, targets, times, other) {
Expand Down Expand Up @@ -350,7 +384,7 @@ var adv_group_vals = function(data, type) {
return groups;
};

var send_requests = function(requests) {
var send_requests = function(requests, allFolders) {
var request;
$('tr', Hm_Utils.tbody()).remove();
Hm_Utils.save_to_local_storage('formatted_advanced_search_data', '');
Expand All @@ -366,6 +400,7 @@ var send_requests = function(requests) {
{'name': 'adv_end', 'value': request['time']['to']},
{'name': 'adv_source_limit', 'value': request['other']['limit']},
{'name': 'adv_charset', 'value': request['other']['charset']},
{'name': 'all_folders', 'value': allFolders}
];

for (var i=0, len=request['terms'].length; i < len; i++) {
Expand All @@ -380,18 +415,23 @@ var send_requests = function(requests) {
Hm_Ajax.request(
params,
function(res) {
var detail = Hm_Utils.parse_folder_path(request['source'], 'imap');
// HACK. As we are sending multiple requests (each source a request), let's keep a snapshot of the last message list before updating the view
let tableRows = Hm_Utils.rows();
Hm_Message_List.update(res.formatted_message_list);
if (Hm_Utils.rows().length > 0) {
$('.adv_controls').show();
$('.core_msg_control').off('click');
$('.core_msg_control').on("click", function() { return Hm_Message_List.message_action($(this).data('action')); });
Hm_Message_List.set_checkbox_callback();
if (typeof check_select_for_imap !== 'undefined') {
check_select_for_imap();
}
}
Hm_Message_List.check_empty_list();

// prepend the previous message list
if (n !== 0) {
Hm_Utils.tbody().prepend(tableRows);
}
},
[],
false,
Expand Down
6 changes: 6 additions & 0 deletions modules/core/site.css
Original file line number Diff line number Diff line change
Expand Up @@ -1405,3 +1405,9 @@ body {
margin-bottom: 1rem;
padding-left: 1rem;
}

a[disabled] {
cursor: default;
pointer-events: none;
opacity: 0.6;
}

0 comments on commit 1141475

Please sign in to comment.