X-Git-Url: https://vcs.fsf.org/?p=squirrelmail.git;a=blobdiff_plain;f=src%2Fread_body.php;h=e3637b8727358efe870eda245f2ce3e9c2fa15b4;hp=12be8adb7243584afa4b78b9c1b8a4df73ad8f23;hb=HEAD;hpb=8949acd68dc6459372ef79823c88c0fbf2ae4e23 diff --git a/src/read_body.php b/src/read_body.php index 12be8adb..9e8bb97a 100644 --- a/src/read_body.php +++ b/src/read_body.php @@ -6,9 +6,9 @@ * This file is used for reading the msgs array and displaying * the resulting emails in the right frame. * - * @copyright © 1999-2007 The SquirrelMail Project Team + * @copyright 1999-2022 The SquirrelMail Project Team * @license http://opensource.org/licenses/gpl-license.php GNU Public License - * @version $Id$ + * @version $Id: read_body.php 14845 2020-01-07 08:09:34Z pdontthink $ * @package squirrelmail */ @@ -37,7 +37,7 @@ require_once(SM_PATH . 'functions/compose.php'); * and sorted msgs array and return the index of the next message * * @param int $passed_id The current message UID - * @return the index of the next valid message from the array + * @return the index of the next valid message from the array or -1 if there is no next message */ function findNextMessage($uidset,$passed_id='backwards') { if (!is_array($uidset)) { @@ -59,7 +59,7 @@ function findNextMessage($uidset,$passed_id='backwards') { * and sorted msgs array and return the index of the previous message * * @param int $passed_id The current message UID - * @return the index of the next valid message from the array + * @return the index of the previous valid message from the array or -1 if there is no previous message */ function findPreviousMessage($uidset, $passed_id) { @@ -145,7 +145,10 @@ function SendMDN ( $mailbox, $passed_id, $message, $imapConnection) { $content_type->properties['charset']=$default_charset; } $rfc822_header->content_type = $content_type; - $rfc822_header->to[] = $header->dnt; + if (!empty($header->dnt)) + $rfc822_header->to[] = $header->dnt; + else + $rfc822_header->to[] = $header->dsn; $rfc822_header->subject = _("Read:") . ' ' . decodeHeader($header->subject,true,false); $idents = get_identities(); @@ -206,7 +209,7 @@ function SendMDN ( $mailbox, $passed_id, $message, $imapConnection) { if ($special_encoding) { $mime_header->encoding = $special_encoding; } else { - $mime_header->encoding = 'us-ascii'; + $mime_header->encoding = '7bit'; } if ($default_charset) { $mime_header->parameters['charset'] = $default_charset; @@ -230,7 +233,7 @@ function SendMDN ( $mailbox, $passed_id, $message, $imapConnection) { $mime_header = new MessageHeader; $mime_header->type0 = 'message'; $mime_header->type1 = 'disposition-notification'; - $mime_header->encoding = 'us-ascii'; + $mime_header->encoding = '7bit'; $part2->mime_header = $mime_header; $composeMessage = new Message(); @@ -273,7 +276,7 @@ function SendMDN ( $mailbox, $passed_id, $message, $imapConnection) { if (! empty($deliver->dlv_server_msg)) { $msg.= "\n" . _("Server replied:") . ' ' . $deliver->dlv_ret_nr . ' ' . - nl2br(htmlspecialchars($deliver->dlv_server_msg)); + nl2br(sm_encode_html_special_chars($deliver->dlv_server_msg)); } plain_error_message($msg); } else { @@ -358,7 +361,7 @@ function formatRecipientString($recipients, $item ) { $a[] = array( // note: decodeHeader is htmlsafe by default 'Name' => decodeHeader($r->getAddress(false)), - 'Email' => htmlspecialchars($r->getEmail()), + 'Email' => sm_encode_html_special_chars($r->getEmail()), 'Full' => decodeHeader($r->getAddress(true)) ); } @@ -410,7 +413,9 @@ function formatEnvheader($aMailbox, $passed_id, $passed_ent_id, $message, if ($default_use_mdn) { if ($mdn_user_support) { - if ($header->dnt) { + // We are generous to the sender because DSNs are commonly ignored by servers and + // technically offering a return receipt in the MUA for a DSN is overstepping the RFCs + if ($header->dnt || $header->dnt) { $mdn_url = $PHP_SELF; $mdn_url = set_url_var($mdn_url, 'mailbox', urlencode($mailbox)); $mdn_url = set_url_var($mdn_url, 'passed_id', $passed_id); @@ -459,19 +464,27 @@ function formatEnvheader($aMailbox, $passed_id, $passed_ent_id, $message, /** * Format message toolbar * - * @param array $aMailbox Current mailbox information array - * @param int $passed_id UID of current message - * @param int $passed_ent_id Id of entity within message - * @param object $message Current message object - * @param object $mbx_response + * @param array $aMailbox Current mailbox information array + * @param int $passed_id UID of current message + * @param int $passed_ent_id Id of entity within message + * @param object $message Current message object + * @param void $removedVar This parameter is no longer used, but remains + * so as not to break this function's prototype + * (OPTIONAL) + * @param boolean $nav_on_top When TRUE, the menubar is being constructed + * for use at the top of the page, otherwise it + * will be used for page bottom (OPTIONAL; + * default = TRUE) */ -function formatMenubar($aMailbox, $passed_id, $passed_ent_id, $message, $removedVar, $nav_on_top = TRUE) { +function formatMenubar($aMailbox, $passed_id, $passed_ent_id, $message, + $removedVar=FALSE, $nav_on_top=TRUE) { + global $base_uri, $draft_folder, $where, $what, $sort, $startMessage, $PHP_SELF, $save_as_draft, $enable_forward_as_attachment, $imapConnection, $lastTargetMailbox, $delete_prev_next_display, $show_copy_buttons, $compose_new_win, $compose_width, $compose_height, - $oTemplate; + $oTemplate, $return_to_message_list_after_move; //FIXME cleanup argument list, use $aMailbox where possible $mailbox = $aMailbox['NAME']; @@ -546,7 +559,8 @@ function formatMenubar($aMailbox, $passed_id, $passed_ent_id, $message, $removed '&mailbox='.$urlMailbox.'&sort='.$sort. '&startMessage='.$startMessage.'&show_more=0'. "&where=$where&what=$what" . - '&delete_id='.$passed_id; + '&delete_id='.$passed_id . + '&smtoken='.sm_generate_security_token(); } if ($next >= 0) { @@ -554,7 +568,8 @@ function formatMenubar($aMailbox, $passed_id, $passed_ent_id, $message, $removed '&mailbox='.$urlMailbox.'&sort='.$sort. '&startMessage='.$startMessage.'&show_more=0'. "&where=$where&what=$what" . - '&delete_id='.$passed_id; + '&delete_id='.$passed_id . + '&smtoken='.sm_generate_security_token(); } } } @@ -620,8 +635,8 @@ function formatMenubar($aMailbox, $passed_id, $passed_ent_id, $message, $removed // If Draft folder - create Resume link $resume_draft = $edit_as_new = false; - if (($mailbox == $draft_folder) && ($save_as_draft)) { - $resume_draft = true; 'smaction_draft'; + if (isDraftMailbox($mailbox) && ($save_as_draft)) { + $resume_draft = true; } else if (handleAsSent($mailbox)) { $edit_as_new = true; } @@ -630,16 +645,24 @@ function formatMenubar($aMailbox, $passed_id, $passed_ent_id, $message, $removed $oTemplate->assign('mailboxes', sqimap_mailbox_option_array($imapConnection)); if (in_array('\\deleted', $aMailbox['PERMANENTFLAGS'],true)) { - $delete_url = $base_uri . "src/$where"; $oTemplate->assign('can_be_deleted', true); - $oTemplate->assign('move_delete_form_action', $base_uri.'src/'.$where); + // force return-to-message-list if this is the only message in the folder + if ($return_to_message_list_after_move || ($next < 0 && $prev < 0)) + $oTemplate->assign('move_delete_form_action', $base_uri.'src/'.$where); + else + $oTemplate->assign('move_delete_form_action', $base_uri.'src/read_body.php'); $oTemplate->assign('delete_form_extra', addHidden('mailbox', $aMailbox['NAME'])."\n" . addHidden('msg[0]', $passed_id)."\n" . + // only need when $return_to_message_list_after_move is off + addHidden('passed_id', ($next >= 0 ? $next : $prev))."\n" . addHidden('startMessage', $startMessage)."\n" ); if (!(isset($passed_ent_id) && $passed_ent_id)) { $oTemplate->assign('can_be_moved', true); $oTemplate->assign('move_form_extra', addHidden('mailbox', $aMailbox['NAME'])."\n" . - addHidden('msg[0]', $passed_id)."\n" ); + addHidden('msg[0]', $passed_id)."\n" . + // only need when $return_to_message_list_after_move is off + addHidden('passed_id', ($next >= 0 ? $next : $prev))."\n" . + addHidden('startMessage', $startMessage)."\n" ); $oTemplate->assign('last_move_target', isset($lastTargetMailbox) && !empty($lastTargetMailbox) ? $lastTargetMailbox : ''); $oTemplate->assign('can_be_copied', $show_copy_buttons==1); } else { @@ -658,12 +681,23 @@ function formatMenubar($aMailbox, $passed_id, $passed_ent_id, $message, $removed $oTemplate->assign('can_be_copied', false); } - // access keys... + // access keys... only add to the top menubar, because adding + // them twice makes them less functional (press access key, *then* + // press to make it work) // - global $accesskey_read_msg_reply, $accesskey_read_msg_reply_all, - $accesskey_read_msg_forward, $accesskey_read_msg_as_attach, - $accesskey_read_msg_delete, $accesskey_read_msg_bypass_trash, - $accesskey_read_msg_move_to, $accesskey_read_msg_move; + if ($nav_on_top) { + global $accesskey_read_msg_reply, $accesskey_read_msg_reply_all, + $accesskey_read_msg_forward, $accesskey_read_msg_as_attach, + $accesskey_read_msg_delete, $accesskey_read_msg_bypass_trash, + $accesskey_read_msg_move, $accesskey_read_msg_move_to, + $accesskey_read_msg_copy; + } else { + $accesskey_read_msg_reply = $accesskey_read_msg_reply_all = + $accesskey_read_msg_forward = $accesskey_read_msg_as_attach = + $accesskey_read_msg_delete = $accesskey_read_msg_bypass_trash = + $accesskey_read_msg_move = $accesskey_read_msg_move_to = + $accesskey_read_msg_copy = 'NONE'; + } $oTemplate->assign('accesskey_read_msg_reply', $accesskey_read_msg_reply); $oTemplate->assign('accesskey_read_msg_reply_all', $accesskey_read_msg_reply_all); $oTemplate->assign('accesskey_read_msg_forward', $accesskey_read_msg_forward); @@ -672,6 +706,7 @@ function formatMenubar($aMailbox, $passed_id, $passed_ent_id, $message, $removed $oTemplate->assign('accesskey_read_msg_bypass_trash', $accesskey_read_msg_bypass_trash); $oTemplate->assign('accesskey_read_msg_move_to', $accesskey_read_msg_move_to); $oTemplate->assign('accesskey_read_msg_move', $accesskey_read_msg_move); + $oTemplate->assign('accesskey_read_msg_copy', $accesskey_read_msg_copy); global $null; do_hook('read_body_menu', $null); @@ -907,6 +942,21 @@ if ( sqgetGlobalVar('delete_id', $delete_id, SQ_GET) ) { handleMessageListForm($imapConnection,$aMailbox,$sButton='setDeleted', array($delete_id)); } +/** + * or delete button... why is handleMessageListForm (per above) conditional anway? + */ +if ( sqgetGlobalVar('delete', $ignore, SQ_POST) ) { + $sError = handleMessageListForm($imapConnection,$aMailbox); +} + +/** + * or move button... why is handleMessageListForm (per above) conditional anway? + */ +if ( sqgetGlobalVar('moveButton', $ignore, SQ_POST) ) { + $sError = handleMessageListForm($imapConnection,$aMailbox); + sqgetGlobalVar('targetMailbox', $lastTargetMailbox, SQ_POST); +} + /** * $message contains all information about the message * including header and body @@ -945,6 +995,14 @@ if (isset($passed_ent_id) && $passed_ent_id) { } $header = $message->header; +// gmail does not mark messages as read when retrieving the message body +// even though RFC 3501, section 6.4.5 (FETCH Command) says: +// "The \Seen flag is implicitly set; if this causes the flags to change, +// they SHOULD be included as part of the FETCH responses." +// +if ($imap_server_type == 'gmail') { + sqimap_toggle_flag($imapConnection, array($passed_id), '\\Seen', true, true); +} /****************************************/ /* Block for handling incoming url vars */