From eb1611cbe67499690ac9be1c78f5ec899e9997d0 Mon Sep 17 00:00:00 2001 From: christer kahasha <62720246+christer77@users.noreply.github.com> Date: Fri, 13 Sep 2024 12:02:37 +0200 Subject: [PATCH] [ENH]message list: Preview of message when viewing message list --- modules/core/message_list_functions.php | 14 ++- modules/imap/functions.php | 9 +- modules/imap/handler_modules.php | 11 +++ modules/imap/hm-imap.php | 91 ++++++++++++++++--- modules/imap/site.js | 2 +- modules/smtp/modules.php | 2 +- .../modules/core/message_list_functions.php | 4 +- 7 files changed, 109 insertions(+), 24 deletions(-) diff --git a/modules/core/message_list_functions.php b/modules/core/message_list_functions.php index eac7e95a2f..3a2960d6f9 100644 --- a/modules/core/message_list_functions.php +++ b/modules/core/message_list_functions.php @@ -295,15 +295,23 @@ function checkbox_callback($vals, $style, $output_mod) { if (!hm_exists('subject_callback')) { function subject_callback($vals, $style, $output_mod) { $img = ''; + $preview_msg = ''; + $subject = ''; if (count($vals) == 4 && $vals[3]) { $img = ''; } - $subject = $output_mod->html_safe($vals[0]); + if (is_array($vals[0])) { + $preview_msg = $output_mod->html_safe($vals[0]['preview_msg']); + $subject = $output_mod->html_safe($vals[0]['subject']); + } else { + $subject = $output_mod->html_safe($vals[0]); + } + $hl_subject = preg_replace("/^(\[[^\]]+\])/", '$1', $subject); if ($style == 'news') { - return sprintf('
'. $preview_msg .'
'. $preview_msg .'
"; var_dump($msg); die; $msg['server_id'] = $form['imap_server_id']; $msg['server_name'] = $details['name']; $msg['folder'] = $form['folder']; + // $uid = $msg['uid']; + // $part = true; + // $max = 87; + // $msg_struct = $imap->get_message_structure($uid); + // $struct = $imap->search_bodystructure($msg_struct, array('imap_part_number' => $part)); + // $msg_struct_current = array_shift($struct); + // $msg_text = $imap->get_message_content($uid, $part, $max, $msg_struct_current); + // // $msg['preview_msg'] = "xxxxxxx"; + // $msg['preview_msg'] = $msg_text; $msgs[] = $msg; } if ($imap->selected_mailbox) { @@ -2191,3 +2201,4 @@ function process_move_messages_in_screen_email_enabled_callback($val) { return $ process_site_setting('move_messages_in_screen_email', $this, 'process_move_messages_in_screen_email_enabled_callback', true, true); } } + diff --git a/modules/imap/hm-imap.php b/modules/imap/hm-imap.php index 26fb8cfe78..0f76d01eed 100644 --- a/modules/imap/hm-imap.php +++ b/modules/imap/hm-imap.php @@ -761,7 +761,7 @@ public function poll() { * @param bool $raw flag to disable decoding header values * @return array list of headers and values for the specified uids */ - public function get_message_list($uids, $raw=false) { + public function get_message_list($uids, $raw=false, $include_preview = false) { if (is_array($uids)) { sort($uids); $sorted_string = implode(',', $uids); @@ -776,7 +776,11 @@ public function get_message_list($uids, $raw=false) { if ($this->is_supported( 'X-GM-EXT-1' )) { $command .= 'X-GM-MSGID X-GM-THRID X-GM-LABELS '; } - $command .= "BODY.PEEK[HEADER.FIELDS (SUBJECT X-AUTO-BCC FROM DATE CONTENT-TYPE X-PRIORITY TO LIST-ARCHIVE REFERENCES MESSAGE-ID X-SNOOZED)])\r\n"; + $command .= "BODY.PEEK[HEADER.FIELDS (SUBJECT X-AUTO-BCC FROM DATE CONTENT-TYPE X-PRIORITY TO LIST-ARCHIVE REFERENCES MESSAGE-ID X-SNOOZED)]"; + // if ($include_preview) { + $command .= " BODY[TEXT]"; + // } + $command .= ")\r\n"; $cache_command = $command.(string)$raw; $cache = $this->check_cache($cache_command); if ($cache !== false) { @@ -789,6 +793,7 @@ public function get_message_list($uids, $raw=false) { $junk = array('X-AUTO-BCC', 'MESSAGE-ID', 'REFERENCES', 'X-SNOOZED', 'LIST-ARCHIVE', 'SUBJECT', 'FROM', 'CONTENT-TYPE', 'TO', '(', ')', ']', 'X-PRIORITY', 'DATE'); $flds = array('x-auto-bcc' => 'x_auto_bcc', 'message-id' => 'message_id', 'references' => 'references', 'x-snoozed' => 'x_snoozed', 'list-archive' => 'list_archive', 'date' => 'date', 'from' => 'from', 'to' => 'to', 'subject' => 'subject', 'content-type' => 'content_type', 'x-priority' => 'x_priority'); $headers = array(); + foreach ($res as $n => $vals) { if (isset($vals[0]) && $vals[0] == '*') { $uid = 0; @@ -810,23 +815,66 @@ public function get_message_list($uids, $raw=false) { $x_auto_bcc = ''; $x_snoozed = ''; $count = count($vals); + $preview_msg = ''; for ($i=0;$i<$count;$i++) { - if ($vals[$i] == 'BODY[HEADER.FIELDS') { - $i++; - while(isset($vals[$i]) && in_array(mb_strtoupper($vals[$i]), $junk)) { + + if ($vals[$i] == 'BODY[HEADER.FIELDS' || $vals[$i] == 'BODY[TEXT') { + if ($vals[$i] == 'BODY[HEADER.FIELDS') { + $i++; - } - $last_header = false; - $lines = explode("\r\n", $vals[$i]); - foreach ($lines as $line) { - $header = mb_strtolower(mb_substr($line, 0, mb_strpos($line, ':'))); - if (!$header || (!isset($flds[$header]) && $last_header)) { - ${$flds[$last_header]} .= str_replace("\t", " ", $line); + while(isset($vals[$i]) && in_array(mb_strtoupper($vals[$i]), $junk)) { + $i++; + } + $last_header = false; + $lines = explode("\r\n", $vals[$i]); + foreach ($lines as $line) { + $header = mb_strtolower(mb_substr($line, 0, mb_strpos($line, ':'))); + if (!$header || (!isset($flds[$header]) && $last_header)) { + ${$flds[$last_header]} .= str_replace("\t", " ", $line); + } + elseif (isset($flds[$header])) { + ${$flds[$header]} = mb_substr($line, (mb_strpos($line, ':') + 1)); + $last_header = $header; + } + } + } else { + + $i++; + $res = ''; + while(isset($vals[$i])) { + + if ($vals[$i] != ']') { + $res = trim(preg_replace("/\s*\)$/", '', $vals[$i])); + break; + } + $i++; + } + + $message_part = 0; + $struct = true; + $full_struct = $this->get_message_structure($uid); + $part_struct = $this->search_bodystructure( $full_struct, array('imap_part_number' => $message_part)); + if (isset($part_struct[$message_part])) { + $struct = $part_struct[$message_part]; } - elseif (isset($flds[$header])) { - ${$flds[$header]} = mb_substr($line, (mb_strpos($line, ':') + 1)); - $last_header = $header; + + if (is_array($struct)) { + if (isset($struct['encoding']) && $struct['encoding']) { + if (mb_strtolower($struct['encoding']) == 'quoted-printable') { + $res = quoted_printable_decode($res); + } + elseif (mb_strtolower($struct['encoding']) == 'base64') { + $res = base64_decode($res); + } + } + if (isset($struct['attributes']['charset']) && $struct['attributes']['charset']) { + if ($struct['attributes']['charset'] != 'us-ascii') { + $res = mb_convert_encoding($res, 'UTF-8', $struct['attributes']['charset']); + } + } } + $preview_msg = $res; + } } elseif (isset($tags[mb_strtoupper($vals[$i])])) { @@ -846,6 +894,7 @@ public function get_message_list($uids, $raw=false) { } } } + if ($uid) { $cset = ''; if (mb_stristr($content_type, 'charset=')) { @@ -860,6 +909,10 @@ public function get_message_list($uids, $raw=false) { 'references' => $references, 'message_id' => $message_id, 'x_auto_bcc' => $x_auto_bcc, 'x_snoozed' => $x_snoozed); + if (! empty($preview_msg)) { + $headers[$uid]['preview_msg'] = $preview_msg; + } + if ($raw) { $headers[$uid] = array_map('trim', $headers[$uid]); } @@ -867,6 +920,7 @@ public function get_message_list($uids, $raw=false) { $headers[$uid] = array_map(array($this, 'decode_fld'), $headers[$uid]); } + } } } @@ -2184,6 +2238,13 @@ public function get_mailbox_page($mailbox, $sort, $rev, $filter, $offset=0, $lim $headers = $this->get_message_list($uids); foreach($uids as $uid) { if (isset($headers[$uid])) { + // $part = true; + // $max = 3000; + // $msg_struct = $this->get_message_structure($uid); + // $struct = $this->search_bodystructure($msg_struct, array('imap_part_number' => $part)); + // $msg_struct_current = array_shift($struct); + // $msg_text = $this->get_message_content($uid, $part, $max, $msg_struct_current); + // $headers[$uid]['preview_msg'] = $msg_text; $result[$uid] = $headers[$uid]; } } diff --git a/modules/imap/site.js b/modules/imap/site.js index 5017f139dc..0723c1e1a7 100644 --- a/modules/imap/site.js +++ b/modules/imap/site.js @@ -1378,7 +1378,7 @@ var add_email_in_contact_trusted = function(list_email) { } ); } - }; +}; $('.screen-email-unlike').on("click", function() { imap_screen_email(); return false; }); diff --git a/modules/smtp/modules.php b/modules/smtp/modules.php index e82b7587db..43af24048a 100644 --- a/modules/smtp/modules.php +++ b/modules/smtp/modules.php @@ -2027,7 +2027,7 @@ function get_outbound_msg_detail($post, $draft, $body_type) { } if (array_key_exists('compose_in_reply_to', $post)) { $in_reply_to = $post['compose_in_reply_to']; - $draft['draft_in_reply_to'] = $post['compose_in_reply_to']; + $draft['draft_in_reply_to'] = $pzost['compose_in_reply_to']; } if ($body_type == 2) { $converter = new GithubFlavoredMarkdownConverter([ diff --git a/tests/phpunit/modules/core/message_list_functions.php b/tests/phpunit/modules/core/message_list_functions.php index f27acb3ffb..38919e29c4 100644 --- a/tests/phpunit/modules/core/message_list_functions.php +++ b/tests/phpunit/modules/core/message_list_functions.php @@ -80,8 +80,8 @@ public function test_checkbox_callback() { */ public function test_subject_callback() { $mod = new Hm_Output_Test(array('foo' => 'bar', 'bar' => 'foo'), array('bar')); - $this->assertEquals('', subject_callback(array('foo', 'bar', array()), 'email', $mod)); - $this->assertEquals('', subject_callback(array('foo', 'bar', array(), 'code'), 'news', $mod)); + $this->assertEquals(' ', subject_callback(array('foo', 'bar', array()), 'email', $mod)); + $this->assertEquals('', subject_callback(array('foo', 'bar', array(), 'code'), 'news', $mod)); } /** * @preserveGlobalState disabled