Skip to content
Draft
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
1 change: 1 addition & 0 deletions language/en.php
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@
'Move' => false,
'Move to ...' => false,
'Copy to ...' => false,
'Restore' => false,
'Removed non-IMAP messages from selection. They cannot be moved or copied' => false,
'Messages moved' => false,
'Messages copied' => false,
Expand Down
7 changes: 6 additions & 1 deletion modules/core/message_list_functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -415,14 +415,19 @@ function icon_callback($vals, $style, $output_mod) {
if (!hm_exists('message_controls')) {
function message_controls($output_mod) {
$txt = '';
$controls = ['read', 'unread', 'flag', 'unflag', 'delete', 'archive', 'junk'];
$controls = ['read', 'unread', 'flag', 'unflag', 'delete', 'archive', 'junk', 'restore'];
$controls = array_filter($controls, function($val) use ($output_mod) {
if (in_array($val, [$output_mod->get('list_path', ''), strtolower($output_mod->get('core_msg_control_folder', ''))])) {
return false;
}
if ($val == 'flag' && $output_mod->get('list_path', '') == 'flagged') {
return false;
}
$is_trash_folder = $output_mod->get('is_trash_folder', false);

if ($val == 'restore' && !$is_trash_folder) {
return false;
}
return true;
});

Expand Down
10 changes: 10 additions & 0 deletions modules/imap/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -1668,3 +1668,13 @@ function is_imap_archive_folder($server_id, $user_config, $current_folder) {

return false;
}}

if (!hm_exists('is_imap_trash_folder')) {
function is_imap_trash_folder($handler, $server_id, $folder) {
$specials = get_special_folders($handler, $server_id);
if (array_key_exists('trash', $specials) && $specials['trash']) {
return $specials['trash'] === $folder;
}
return false;
}
}
61 changes: 59 additions & 2 deletions modules/imap/handler_modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,9 @@ public function process() {
if (array_key_exists(strtolower($folder), $spcial_folders)) {
$this->out('core_msg_control_folder', $spcial_folders[strtolower($folder)]);
}

$this->out('is_trash_folder', is_imap_trash_folder($this, $parts[1], $folder));

if (!empty($details)) {
if (array_key_exists('folder_label', $this->request->get)) {
$folder = $this->request->get['folder_label'];
Expand Down Expand Up @@ -1138,7 +1141,7 @@ class Hm_Handler_imap_message_action extends Hm_Handler_Module {
public function process() {
list($success, $form) = $this->process_form(array('action_type', 'message_ids'));
if ($success) {
if (in_array($form['action_type'], array('delete', 'read', 'unread', 'flag', 'unflag', 'archive', 'junk'))) {
if (in_array($form['action_type'], array('delete', 'read', 'unread', 'flag', 'unflag', 'archive', 'junk', 'restore'))) {
$ids = process_imap_message_ids($form['message_ids']);
$errs = 0;
$msgs = 0;
Expand Down Expand Up @@ -1196,6 +1199,9 @@ private function perform_action($mailbox, $action_type, $uids, $folder, $special
$moved = array();
$folder_name = hex2bin($folder);
$special_folder = $this->get_special_folder($action_type, $specials, $server_details);
if ($action_type == "restore" && !$special_folder) {
$special_folder = 'INBOX';
}

if ($special_folder && $special_folder != $folder_name) {
if ($this->user_config->get('original_folder_setting', false)) {
Expand Down Expand Up @@ -1225,7 +1231,7 @@ private function perform_action($mailbox, $action_type, $uids, $folder, $special
}

$folderNotFoundError = false;
if (!$special_folder && $action_type != 'read' && $action_type != 'unread' && $action_type != 'flag' && $action_type != 'unflag') {
if (!$special_folder && $action_type != 'read' && $action_type != 'unread' && $action_type != 'flag' && $action_type != 'unflag' && $action_type != 'restore') {
Hm_Msgs::add(sprintf('No %s folder configured for %s. Please go to <a href="?page=folders&imap_server_id=%s">Folders seetting</a> and configure one', $action_type, $server_details['name'], $server_details['id']), empty($moved) ? 'danger' : 'warning');
$folderNotFoundError = true;
}
Expand Down Expand Up @@ -1254,6 +1260,8 @@ private function get_special_folder($action_type, $specials, $server_details) {
$folder = $specials['archive'];
} elseif ($action_type == 'junk' && array_key_exists('junk', $specials)) {
$folder = $specials['junk'];
} elseif ($action_type == 'restore') {
$folder = $specials['inbox'];
}
return $folder;
}
Expand Down Expand Up @@ -1996,6 +2004,7 @@ public function process() {
$this->session->set(sprintf('reply_details_imap_%s_%s_%s', $form['imap_server_id'], $form['folder'], $form['imap_msg_uid']),
array('ts' => time(), 'msg_struct' => $msg_struct_current, 'msg_text' => ($save_reply_text ? $msg_text : ''), 'msg_headers' => $msg_headers));
}
$this->out('is_trash_folder', is_imap_trash_folder($this, $form['imap_server_id'], hex2bin($form['folder'])));
}
}
}
Expand Down Expand Up @@ -2177,3 +2186,51 @@ function process_ceo_amount_limit_callback($val) { return $val; }
process_site_setting('ceo_rate_limit', $this, 'process_ceo_amount_limit_callback');
}
}

/**
* Restore a message from trash to inbox
* @subpackage imap/handler
*/
class Hm_Handler_imap_restore_message extends Hm_Handler_Module {
public function process() {
list($success, $form) = $this->process_form(array('imap_msg_uid', 'imap_server_id', 'folder'));

if (!$success) {
return;
}

$restore_result = false;
$inbox_folder = 'INBOX';
$form_folder = hex2bin($form['folder']);
$errors = 0;
$status = false;
$mailbox = Hm_IMAP_List::get_connected_mailbox($form['imap_server_id'], $this->cache);
if ($mailbox && $mailbox->authed()) {
$inbox_exists = count($mailbox->get_folder_status($inbox_folder));
if (!$inbox_exists) {
Hm_Msgs::add('INBOX folder does not exist', 'danger');
$errors++;
}

if (!$errors) {
$result = $mailbox->message_action($form_folder, 'MOVE', array($form['imap_msg_uid']), $inbox_folder);
$status = $result['status'] ?? false;
}

$this->out('folder_status', array('imap_'.$form['imap_server_id'].'_'.$form['folder'] => $mailbox->get_folder_state()));
} else {
Hm_Msgs::add('Unable to connect to IMAP server', 'danger');
$errors++;
}

if ($status) {
$restore_result = true;
Hm_Msgs::add('Message restored to inbox');
} else {
Hm_Msgs::add('An error occurred restoring the message', 'danger');
}

$this->save_hm_msgs();
$this->out('restore_result', $restore_result);
}
}
1 change: 1 addition & 0 deletions modules/imap/hm-imap.php
Original file line number Diff line number Diff line change
Expand Up @@ -1908,6 +1908,7 @@ public function message_action($action, $uids, $mailbox=false, $keyword=false) {
$command = "UID STORE $uid_string +FLAGS (\Deleted)\r\n";
break;
case 'UNDELETE':
case 'RESTORE':
$command = "UID STORE $uid_string -FLAGS (\Deleted)\r\n";
break;
case 'CUSTOM':
Expand Down
4 changes: 4 additions & 0 deletions modules/imap/output_modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,10 @@ protected function output() {
$txt .= '<a class="archive_link hlink text-decoration-none btn btn-sm btn-outline-secondary" id="archive_message" href="#">'.$this->trans('Archive').'</a>';
}

if ($this->get('is_trash_folder')) {
$txt .= '<a class="restore_link hlink text-decoration-none btn btn-sm btn-outline-secondary" id="restore_message" href="#">'.$this->trans('Restore').'</a>';
}

if($this->get('tags')){
$txt .= tags_dropdown($this);
}
Expand Down
9 changes: 9 additions & 0 deletions modules/imap/setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,14 @@
add_handler('ajax_imap_archive_message', 'close_session_early', true, 'core');
add_handler('ajax_imap_archive_message', 'imap_archive_message', true);

/* restore message callback */
setup_base_ajax_page('ajax_imap_restore_message', 'core');
add_handler('ajax_imap_restore_message', 'message_list_type', true, 'core');
add_handler('ajax_imap_restore_message', 'imap_message_list_type', true);
add_handler('ajax_imap_restore_message', 'load_imap_servers_from_config', true);
add_handler('ajax_imap_restore_message', 'imap_oauth2_token_check', true);
add_handler('ajax_imap_restore_message', 'close_session_early', true, 'core');
add_handler('ajax_imap_restore_message', 'imap_restore_message', true);

/* ajax message action callback */
add_handler('ajax_message_action', 'load_imap_servers_from_config', true, 'imap', 'load_user_data', 'after');
Expand Down Expand Up @@ -312,6 +320,7 @@
'ajax_imap_junk',
'message_source',
'ajax_share_folders',
'ajax_imap_restore_message',
),

'allowed_output' => array(
Expand Down
36 changes: 36 additions & 0 deletions modules/imap/site.js
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,7 @@ var imap_message_view_finished = function(msg_uid, detail, listParent, skip_link
$('#move_message').on("click", function(e) { return imap_move_copy(e, 'move', 'message');});
$('#copy_message').on("click", function(e) { return imap_move_copy(e, 'copy', 'message');});
$('#archive_message').on("click", function(e) { return imap_archive_message();});
$('#restore_message').on("click", function(e) { return imap_restore_message(e);});
$('#unread_message').on("click", function() { return imap_unread_message(msg_uid, detail);});
$('#block_sender').on("click", function(e) {
e.preventDefault();
Expand Down Expand Up @@ -1334,6 +1335,41 @@ var imap_archive_message = function(state, supplied_uid, supplied_detail) {
return false;
};

var imap_restore_message = function(e, supplied_uid, supplied_detail) {
e.preventDefault();
var uid = getMessageUidParam();
var detail = Hm_Utils.parse_folder_path(getListPathParam(), 'imap');
if (supplied_uid) {
uid = supplied_uid;
}
if (supplied_detail) {
detail = supplied_detail;
}
if (detail && uid) {
Hm_Ajax.request(
[{'name': 'hm_ajax_hook', 'value': 'ajax_imap_restore_message'},
{'name': 'imap_msg_uid', 'value': uid},
{'name': 'imap_server_id', 'value': detail.server_id},
{'name': 'folder', 'value': detail.folder}],
function(res) {
if (res.restore_result) {
if (hm_list_parent() == 'message') {
if (hm_auto_advance_email_enabled()) {
Hm_Utils.redirect("?page=message_list&list_path="+getListPathParam());
} else if (hm_list_parent() == 'search') {
Hm_Utils.redirect("?page=search&list_path="+hm_list_parent());
} else {
Hm_Utils.redirect("?page=message_list&list_path="+hm_list_parent());
}
}
}
}
);

}
return false;
};

var imap_show_add_contact_popup = function() {
var popup = document.getElementById("contact_popup");
popup.classList.toggle("show");
Expand Down
Loading