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

Map new message identifiers to all existing entries (from the Tags repository & the client message cache storage) of the same message when it is moved #1388

Merged
merged 5 commits into from
Nov 27, 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
11 changes: 11 additions & 0 deletions modules/core/js_modules/Hm_MessagesStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,17 @@ class Hm_MessagesStore {
}
return false;
}

removeRow(uid) {
const rows = Object.entries(this.rows);
const row = this.#getRowByUid(uid);
if (row) {
const newRows = rows.filter((_, i) => i !== row.index);
this.rows = Object.fromEntries(newRows);
this.#saveToLocalStorage();
}

}

#fetch(hideLoadingState = false) {
return new Promise((resolve, reject) => {
Expand Down
13 changes: 8 additions & 5 deletions modules/core/js_modules/utils/sortable.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,14 @@ function handleMessagesDragAndDrop() {
{'name': 'imap_move_to', 'value': targetFolder},
{'name': 'imap_move_page', 'value': page},
{'name': 'imap_move_action', 'value': 'move'}],
(res) =>{
for (const index in res.move_count) {
$('.'+Hm_Utils.clean_selector(res.move_count[index])).remove();
select_imap_folder(getListPathParam());
}
async (res) =>{
const store = new Hm_MessagesStore(getListPathParam(), Hm_Utils.get_url_page_number());
await store.load(false, true, true);
const moveResponses = Object.values(res['move_responses']);
moveResponses.forEach((response) => {
store.removeRow(response.oldUid);
});
display_imap_mailbox(store.rows, store.links, getListPathParam());
}
);

Expand Down
2 changes: 1 addition & 1 deletion modules/core/navigation/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ function showRoutingToast() {
}

function hideRoutingToast() {
window.routingToast.hide();
window.routingToast?.hide();
window.routingToast = null;
}

Expand Down
66 changes: 51 additions & 15 deletions modules/imap/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -875,7 +875,8 @@ function imap_refresh_oauth2_token($server, $config) {
*/
if (!hm_exists('imap_move_same_server')) {
function imap_move_same_server($ids, $action, $hm_cache, $dest_path, $screen_emails=false) {
$moved = array();
$moved = [];
$responses = [];
$keys = array_keys($ids);
$server_id = array_pop($keys);
$cache = Hm_IMAP_List::get_cache($hm_cache, $server_id);
Expand All @@ -888,22 +889,40 @@ function imap_move_same_server($ids, $action, $hm_cache, $dest_path, $screen_ema
$email = current(array_column(process_address_fld($imap->get_message_headers($msg)['From']), "email"));
$uids = $imap->search('ALL', false, array(array('FROM', $email)));
foreach ($uids as $uid) {
if ($imap->message_action(mb_strtoupper($action), $uid, hex2bin($dest_path[2]))) {
$result = $imap->message_action(mb_strtoupper($action), $uid, hex2bin($dest_path[2]));
if ($result['status']) {
$response = $result['responses'][0];
$responses[] = [
'oldUid' => $uid,
'newUid' => $response['newUid'],
'oldFolder' => hex2bin($folder),
'newFolder' => hex2bin($dest_path[2]),
'oldServer' => $server_id,
];
$moved[] = sprintf('imap_%s_%s_%s', $server_id, $uid, $folder);
}
}
}
} else {
if ($imap->message_action(mb_strtoupper($action), $msgs, hex2bin($dest_path[2]))) {
foreach ($msgs as $msg) {
$result = $imap->message_action(mb_strtoupper($action), $msgs, hex2bin($dest_path[2]));
if ($result['status']) {
foreach ($msgs as $index => $msg) {
$response = $result['responses'][$index];
$moved[] = sprintf('imap_%s_%s_%s', $server_id, $msg, $folder);
$responses[] = [
'oldUid' => $msg,
'newUid' => $response['newUid'],
'oldFolder' => hex2bin($folder),
'newFolder' => hex2bin($dest_path[2]),
'oldServer' => $server_id,
];
}
}
}

}
}
return $moved;
return ['moved' => $moved, 'responses' => $responses];
}}

/**
Expand All @@ -917,7 +936,8 @@ function imap_move_same_server($ids, $action, $hm_cache, $dest_path, $screen_ema
*/
if (!hm_exists('imap_move_different_server')) {
function imap_move_different_server($ids, $action, $dest_path, $hm_cache) {
$moved = array();
$moved = [];
$responses = [];
$cache = Hm_IMAP_List::get_cache($hm_cache, $dest_path[1]);
$dest_imap = Hm_IMAP_List::connect($dest_path[1], $cache);
if ($dest_imap) {
Expand Down Expand Up @@ -945,21 +965,31 @@ function imap_move_different_server($ids, $action, $dest_path, $hm_cache) {
}
if ($dest_imap->append_start(hex2bin($dest_path[2]), mb_strlen($msg), $seen)) {
$dest_imap->append_feed($msg."\r\n");
if ($dest_imap->append_end()) {
$uid = $dest_imap->append_end();
if ($uid) {
if ($action == 'move') {
if ($imap->message_action('DELETE', array($msg_id))) {
$deleteResult = $imap->message_action('DELETE', array($msg_id));
if ($deleteResult['status']) {
$imap->message_action('EXPUNGE', array($msg_id));
}
}
$moved[] = sprintf('imap_%s_%s_%s', $server_id, $msg_id, $folder);
$responses[] = [
'oldUid' => $msg_id,
'newUid' => $uid,
'oldFolder' => hex2bin($folder),
'newFolder' => hex2bin($dest_path[2]),
'oldServer' => $server_id,
'newServer' => $dest_path[1],
];
}
}
}
}
}
}
}
return $moved;
return ['moved' => $moved, 'responses' => $responses];
}}

/**
Expand Down Expand Up @@ -1329,9 +1359,12 @@ function snooze_message($imap, $msg_id, $folder, $snooze_tag) {
if ($imap->select_mailbox($snooze_folder) && $imap->append_start($snooze_folder, mb_strlen($msg))) {
$imap->append_feed($msg."\r\n");
if ($imap->append_end()) {
if ($imap->select_mailbox($folder) && $imap->message_action('DELETE', array($msg_id))) {
$imap->message_action('EXPUNGE', array($msg_id));
$res = true;
if ($imap->select_mailbox($folder)) {
$deleteResult = $imap->message_action('DELETE', array($msg_id));
if ($deleteResult['status']) {
$imap->message_action('EXPUNGE', array($msg_id));
$res = true;
}
}
}
}
Expand All @@ -1341,9 +1374,12 @@ function snooze_message($imap, $msg_id, $folder, $snooze_tag) {
if ($imap->select_mailbox($original_folder) && $imap->append_start($original_folder, mb_strlen($msg))) {
$imap->append_feed($msg."\r\n");
if ($imap->append_end()) {
if ($imap->select_mailbox($snooze_folder) && $imap->message_action('DELETE', array($msg_id))) {
$imap->message_action('EXPUNGE', array($msg_id));
$res = true;
if ($imap->select_mailbox($snooze_folder)) {
$deleteResult = $imap->message_action('DELETE', array($msg_id));
if ($deleteResult['status']) {
$imap->message_action('EXPUNGE', array($msg_id));
$res = true;
}
}
}
}
Expand Down
31 changes: 20 additions & 11 deletions modules/imap/handler_modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -270,12 +270,17 @@ public function process() {
list($msg_ids, $dest_path, $same_server_ids, $other_server_ids) = process_move_to_arguments($form);
$moved = array();
if (count($same_server_ids) > 0) {
$moved = array_merge($moved, imap_move_same_server($same_server_ids, $form['imap_move_action'], $this->cache, $dest_path, $screen));
$action = imap_move_same_server($same_server_ids, $form['imap_move_action'], $this->cache, $dest_path, $screen);
$moved = array_merge($moved, $action['moved']);
}
if (count($other_server_ids) > 0) {
$moved = array_merge($moved, imap_move_different_server($other_server_ids, $form['imap_move_action'], $dest_path, $this->cache));
$action = imap_move_different_server($other_server_ids, $form['imap_move_action'], $dest_path, $this->cache);
$moved = array_merge($moved, $action['moved']);

}
if (count($moved) > 0) {
$this->out('move_responses', $action['responses']);
}
if (count($moved) > 0 && count($moved) == count($msg_ids)) {
if ($form['imap_move_action'] == 'move') {
if ($screen) {
Expand Down Expand Up @@ -702,7 +707,7 @@ public function process() {
if ($imap->append_start($folder, mb_strlen($msg))) {
$imap->append_feed($msg."\r\n");
if ($imap->append_end()) {
if ($imap->message_action('DELETE', array($uid))) {
if ($imap->message_action('DELETE', array($uid))['status']) {
$imap->message_action('EXPUNGE', array($uid));
Hm_Msgs::add('Attachment deleted');
$this->out('redirect_url', '?page=message_list&list_path='.$this->request->get['list_path']);
Expand Down Expand Up @@ -995,12 +1000,13 @@ public function process() {
if ($imap->select_mailbox(hex2bin($form['folder']))) {
$this->out('folder_status', array('imap_'.$form['imap_server_id'].'_'.$form['folder'] => $imap->folder_state));
if ($trash_folder && $trash_folder != hex2bin($form['folder'])) {
if ($imap->message_action('MOVE', array($form['imap_msg_uid']), $trash_folder)) {
$moveResult = $imap->message_action('MOVE', array($form['imap_msg_uid']), $trash_folder);
if ($moveResult['status']) {
$del_result = true;
}
}
else {
if ($imap->message_action('DELETE', array($form['imap_msg_uid']))) {
if ($imap->message_action('DELETE', array($form['imap_msg_uid']))['status']) {
$del_result = true;
$imap->message_action('EXPUNGE', array($form['imap_msg_uid']));
}
Expand Down Expand Up @@ -1080,8 +1086,11 @@ public function process() {
}

/* try to move the message */
if (!$errors && $imap->message_action('MOVE', array($form['imap_msg_uid']), $archive_folder)) {
Hm_Msgs::add("Message archived");
if (!$errors) {
$moveResult = $imap->message_action('MOVE', array($form['imap_msg_uid']), $archive_folder);
if ($moveResult['status']) {
Hm_Msgs::add("Message archived");
}
}
else {
Hm_Msgs::add('ERRAn error occurred archiving the message');
Expand Down Expand Up @@ -1113,7 +1122,7 @@ public function process() {
else {
$cmd = 'FLAG';
}
if ($imap->message_action($cmd, array($form['imap_msg_uid']))) {
if ($imap->message_action($cmd, array($form['imap_msg_uid']))['status']) {
$flag_result = true;
}
}
Expand Down Expand Up @@ -1256,7 +1265,7 @@ public function process() {
$status['imap_'.$server.'_'.$folder] = $imap->folder_state;

if ($form['action_type'] == 'delete' && $trash_folder && $trash_folder != hex2bin($folder)) {
if (!$imap->message_action('MOVE', $uids, $trash_folder)) {
if (!$imap->message_action('MOVE', $uids, $trash_folder)['status']) {
$errs++;
}
else {
Expand All @@ -1274,7 +1283,7 @@ public function process() {
$imap->create_mailbox($archive_folder);
}
}
if (!$imap->message_action('MOVE', $uids, $archive_folder)) {
if (!$imap->message_action('MOVE', $uids, $archive_folder)['status']) {
$errs++;
}
else {
Expand All @@ -1284,7 +1293,7 @@ public function process() {
}
}
else {
if (!$imap->message_action(mb_strtoupper($form['action_type']), $uids)) {
if (!$imap->message_action(mb_strtoupper($form['action_type']), $uids)['status']) {
$errs++;
}
else {
Expand Down
39 changes: 31 additions & 8 deletions modules/imap/hm-imap.php
Original file line number Diff line number Diff line change
Expand Up @@ -1731,7 +1731,9 @@ public function create_mailbox($mailbox) {
public function message_action($action, $uids, $mailbox=false, $keyword=false) {
$status = false;
$command = false;
$uid_strings = array();
$uid_strings = [];
$responses = [];
$parseResponseFn = function($response) {};
if (is_array($uids)) {
if (count($uids) > 1000) {
while (count($uids) > 1000) {
Expand All @@ -1751,7 +1753,7 @@ public function message_action($action, $uids, $mailbox=false, $keyword=false) {
foreach ($uid_strings as $uid_string) {
if ($uid_string) {
if (!$this->is_clean($uid_string, 'uid_list')) {
return false;
break;
}
}
switch ($action) {
Expand Down Expand Up @@ -1791,20 +1793,35 @@ public function message_action($action, $uids, $mailbox=false, $keyword=false) {
break;
case 'COPY':
if (!$this->is_clean($mailbox, 'mailbox')) {
return false;
break;
}
$command = "UID COPY $uid_string \"".$this->utf7_encode($mailbox)."\"\r\n";
break;
case 'MOVE':
if (!$this->is_clean($mailbox, 'mailbox')) {
return false;
break;
}

$parseResponseFn = function($response) use ($uid_string, &$responses) {
if (strpos($uid_string, ',') !== false) {
preg_match('/.*COPYUID \d+ (\d+[:|,]\d+) (\d+[:|,]\d+).*/', $response[0], $matches);
$oldUids = preg_split('/[:|,]/', $matches[1]);
$newUids = preg_split('/[:|,]/', $matches[2]);
foreach ($oldUids as $key => $oldUid) {
$responses[] = ['oldUid' => $oldUid, 'newUid' => $newUids[$key]];
}
} else {
preg_match('/.*COPYUID \d+ (\d+) (\d+).*/', $response[0], $matches);
$responses[] = ['oldUid' => $matches[1], 'newUid' => $matches[2]];
}
};

if ($this->is_supported('MOVE')) {
$command = "UID MOVE $uid_string \"".$this->utf7_encode($mailbox)."\"\r\n";
}
else {
if ($this->message_action('COPY', $uids, $mailbox, $keyword)) {
if ($this->message_action('DELETE', $uids, $mailbox, $keyword)) {
if ($this->message_action('COPY', $uids, $mailbox, $keyword)['status']) {
if ($this->message_action('DELETE', $uids, $mailbox, $keyword)['status']) {
$command = "EXPUNGE\r\n";
}
}
Expand All @@ -1817,6 +1834,7 @@ public function message_action($action, $uids, $mailbox=false, $keyword=false) {
$status = $this->check_response($res);
}
if ($status) {
$parseResponseFn($res);
if (is_array($this->selected_mailbox)) {
$this->bust_cache($this->selected_mailbox['name']);
}
Expand All @@ -1825,7 +1843,8 @@ public function message_action($action, $uids, $mailbox=false, $keyword=false) {
}
}
}
return $status;

return ['status' => $status, 'responses' => $responses];
}

/**
Expand Down Expand Up @@ -1873,7 +1892,11 @@ public function append_feed($string) {
*/
public function append_end() {
$result = $this->get_response(false, true);
return $this->check_response($result, true);
$uid = $result[0][5];
if ($this->check_response($result, true)) {
return $uid;
}
return false;
}

/* ------------------ HELPERS ------------------------------------------ */
Expand Down
1 change: 1 addition & 0 deletions modules/imap/setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@
'auto_advance_email_enabled' => array(FILTER_VALIDATE_BOOLEAN, false),
'do_not_flag_as_read_on_open' => array(FILTER_VALIDATE_BOOLEAN, false),
'ajax_imap_folders_permissions' => array(FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY),
'move_responses' => array(FILTER_DEFAULT, FILTER_REQUIRE_ARRAY),
),

'allowed_get' => array(
Expand Down
Loading
Loading