diff --git a/modules/core/message_list_functions.php b/modules/core/message_list_functions.php index 95b5586b2..f4fca6172 100644 --- a/modules/core/message_list_functions.php +++ b/modules/core/message_list_functions.php @@ -392,6 +392,7 @@ function message_controls($output_mod) { '
  • '.$output_mod->trans('Unflag').'
  • '. '
  • '.$output_mod->trans('Delete').'
  • '. '
  • '.$output_mod->trans('Archive').'
  • '. + '
  • '.$output_mod->trans('Junk').'
  • '. ''. ''. ''.$output_mod->trans('Read').''. @@ -399,7 +400,8 @@ function message_controls($output_mod) { ''.$output_mod->trans('Flag').''. ''.$output_mod->trans('Unflag').''. ''.$output_mod->trans('Delete').''. - ''.$output_mod->trans('Archive').''; + ''.$output_mod->trans('Archive').''. + ''.$output_mod->trans('Junk').''; if ($output_mod->get('msg_controls_extra')) { $res .= $output_mod->get('msg_controls_extra'); diff --git a/modules/imap/handler_modules.php b/modules/imap/handler_modules.php index 2a45df943..903addf82 100644 --- a/modules/imap/handler_modules.php +++ b/modules/imap/handler_modules.php @@ -1113,12 +1113,12 @@ public function process() { */ class Hm_Handler_imap_message_action extends Hm_Handler_Module { /** - * Read, unread, delete, flag, or unflag a set of message uids + * Read, unread, delete, flag, unflag, archive, or mark as junk a set of message uids */ 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'))) { + if (in_array($form['action_type'], array('delete', 'read', 'unread', 'flag', 'unflag', 'archive', 'junk'))) { $ids = process_imap_message_ids($form['message_ids']); $errs = 0; $msgs = 0; @@ -1126,77 +1126,23 @@ public function process() { $status = array(); foreach ($ids as $server => $folders) { $specials = get_special_folders($this, $server); - $trash_folder = false; - $archive_folder = false; $mailbox = Hm_IMAP_List::get_connected_mailbox($server, $this->cache); if ($mailbox && $mailbox->authed()) { $server_details = $this->user_config->get('imap_servers')[$server]; - if ($form['action_type'] == 'delete') { - if (array_key_exists('trash', $specials)) { - if ($specials['trash']) { - $trash_folder = $specials['trash']; - } elseif ($mailbox->is_imap()) { - Hm_Msgs::add(sprintf('ERRNo trash folder configured for %s', $server_details['name'])); - } - } - } - if ($form['action_type'] == 'archive') { - if(array_key_exists('archive', $specials)) { - if($specials['archive']) { - $archive_folder = $specials['archive']; - } elseif ($mailbox->is_imap()) { - Hm_Msgs::add(sprintf('ERRNo archive folder configured for %s', $server_details['name'])); - } - } - } - foreach ($folders as $folder => $uids) { - $status['imap_'.$server.'_'.$folder] = $imap->folder_state; - - if ($mailbox->is_imap() && $form['action_type'] == 'delete' && $trash_folder && $trash_folder != hex2bin($folder)) { - if (! $mailbox->message_action(hex2bin($folder), 'MOVE', $uids, $trash_folder)['status']) { - $errs++; - } - else { - foreach ($uids as $uid) { - $moved[] = sprintf("imap_%s_%s_%s", $server, $uid, $folder); - } - } - } - elseif ($mailbox->is_imap() && $form['action_type'] == 'archive' && $archive_folder && $archive_folder != hex2bin($folder)) { - /* path according to original option setting */ - if ($this->user_config->get('original_folder_setting', false)) { - $archive_folder .= '/' . hex2bin($folder); - $dest_path_exists = count($mailbox->get_folder_status($archive_folder)); - if (!$dest_path_exists) { - $mailbox->create_folder($archive_folder); - } - } - if (! $mailbox->message_action(hex2bin($folder), 'MOVE', $uids, $archive_folder)['status']) { - $errs++; - } - else { - foreach ($uids as $uid) { - $moved[] = sprintf("imap_%s_%s_%s", $server, $uid, $folder); - } - } - } - else { - if (! $mailbox->message_action(hex2bin($folder), mb_strtoupper($form['action_type']), $uids)['status']) { - $errs++; - } - else { - $msgs += count($uids); - if ($form['action_type'] == 'delete') { - $mailbox->message_action(hex2bin($folder), 'EXPUNGE', $uids); - } - } + $status['imap_'.$server.'_'.$folder] = $mailbox->get_folder_state(); + $action_result = $this->perform_action($mailbox, $form['action_type'], $uids, $folder, $specials, $server_details); + if ($action_result['error']) { + $errs++; + } else { + $msgs += count($uids); + $moved = array_merge($moved, $action_result['moved']); } } } } if ($errs > 0) { - Hm_Msgs::add(sprintf('ERRAn error occurred trying to %s some messages!', $form['action_type'], $server)); + Hm_Msgs::add(sprintf('ERRAn error occurred trying to %s some messages!', $form['action_type'])); } $this->out('move_count', $moved); if (count($status) > 0) { @@ -1205,6 +1151,53 @@ public function process() { } } } + + private function perform_action($mailbox, $action_type, $uids, $folder, $specials, $server_details) { + $error = false; + $moved = array(); + $folder_name = hex2bin($folder); + $special_folder = $this->get_special_folder($action_type, $specials, $server_details); + + if ($special_folder && $special_folder != $folder_name) { + if ($this->user_config->get('original_folder_setting', false)) { + $special_folder .= '/' . $folder_name; + if (!count($mailbox->get_folder_status($special_folder))) { + $mailbox->create_folder($special_folder); + } + } + if (!$mailbox->message_action($folder_name, 'MOVE', $uids, $special_folder)['status']) { + $error = true; + } else { + foreach ($uids as $uid) { + $moved[] = sprintf("imap_%s_%s_%s", $server_details['id'], $uid, $folder); + } + } + } else { + if (!$mailbox->message_action($folder_name, mb_strtoupper($action_type), $uids)['status']) { + $error = true; + } else { + if ($action_type == 'delete') { + $mailbox->message_action($folder_name, 'EXPUNGE', $uids); + } + } + } + return ['error' => $error, 'moved' => $moved]; + } + + private function get_special_folder($action_type, $specials, $server_details) { + $folder = false; + if ($action_type == 'delete' && array_key_exists('trash', $specials)) { + $folder = $specials['trash']; + } elseif ($action_type == 'archive' && array_key_exists('archive', $specials)) { + $folder = $specials['archive']; + } elseif ($action_type == 'junk' && array_key_exists('junk', $specials)) { + $folder = $specials['junk']; + } + if (!$folder && $action_type != 'read' && $action_type != 'unread' && $action_type != 'flag' && $action_type != 'unflag') { + Hm_Msgs::add(sprintf('ERRNo %s folder configured for %s', $action_type, $server_details['name'])); + } + return $folder; + } } /** diff --git a/modules/imap/hm-imap.php b/modules/imap/hm-imap.php index 9d50ad435..f6284a64f 100644 --- a/modules/imap/hm-imap.php +++ b/modules/imap/hm-imap.php @@ -1775,6 +1775,9 @@ public function message_action($action, $uids, $mailbox=false, $keyword=false) { case 'ARCHIVE': $command = "UID STORE $uid_string +FLAGS (\Archive)\r\n"; break; + case 'JUNK': + $command = "UID STORE $uid_string +FLAGS (\Junk)\r\n"; + break; case 'FLAG': $command = "UID STORE $uid_string +FLAGS (\Flagged)\r\n"; break; diff --git a/tests/phpunit/modules/core/message_list_functions.php b/tests/phpunit/modules/core/message_list_functions.php index 6c67482c7..c23c69ee4 100644 --- a/tests/phpunit/modules/core/message_list_functions.php +++ b/tests/phpunit/modules/core/message_list_functions.php @@ -107,7 +107,7 @@ public function test_icon_callback() { */ public function test_message_controls() { $mod = new Hm_Output_Test(array('msg_controls_extra' => 'foo', 'foo' => 'bar', 'bar' => 'foo'), array('bar')); - $this->assertEquals('
    ReadUnreadFlagUnflagDeleteArchivefoo
    ', message_controls($mod)); + $this->assertEquals('
    ReadUnreadFlagUnflagDeleteArchiveJunkfoo
    ', message_controls($mod)); } /** * @preserveGlobalState disabled @@ -133,7 +133,7 @@ public function test_list_sources() { */ public function test_list_controls() { $this->assertEquals('
    foobazbar
    -
    +
    foobazbar
    foobazbar
    ', list_controls('foo', 'bar', 'baz')); diff --git a/tests/phpunit/modules/core/output_modules.php b/tests/phpunit/modules/core/output_modules.php index 370bcc2f2..4e098371b 100644 --- a/tests/phpunit/modules/core/output_modules.php +++ b/tests/phpunit/modules/core/output_modules.php @@ -27,7 +27,7 @@ public function test_search_from_folder_list() { public function test_search_content_start() { $test = new Output_Test('search_content_start', 'core'); $res = $test->run(); - $this->assertEquals(array('
    Search'), $res->output_response); + $this->assertEquals(array('
    Search'), $res->output_response); } /** * @preserveGlobalState disabled @@ -1105,14 +1105,14 @@ public function test_home_password_dialogs() { public function test_message_list_heading() { $test = new Output_Test('message_list_heading', 'core'); $res = $test->run(); - $this->assertEquals(array('
    + $this->assertEquals(array('
    Sources
    '), $res->output_response); $test->handler_response = array('custom_list_controls' => 'foo'); $res = $test->run(); - $this->assertEquals(array('
    foo
    + $this->assertEquals(array('
    foo
    foo
    @@ -1126,7 +1126,7 @@ public function test_message_list_heading() {
    Sources
    '), $res->output_response); $test->handler_response = array('list_path' => 'combined_inbox'); $res = $test->run(); - $this->assertEquals(array('
    + $this->assertEquals(array('