diff options
author | Aleksander Machniak <alec@alec.pl> | 2017-09-18 11:15:51 +0300 |
---|---|---|
committer | Aleksander Machniak <alec@alec.pl> | 2017-09-18 11:15:51 +0300 |
commit | 83fe734460b1543c5dad0e158d7489c9acf88772 (patch) | |
tree | c85ffe62aa2bc4eee870eb9cca3b29fe8c041c73 /program/steps/mail/show.inc | |
parent | 27377e29dc7fb5a57d0a071440203e56c41693e9 (diff) |
Move some functions from func.inc to show.inc where they belong to.
Add MessageSummary object for message template.
Diffstat (limited to 'program/steps/mail/show.inc')
-rw-r--r-- | program/steps/mail/show.inc | 422 |
1 files changed, 421 insertions, 1 deletions
diff --git a/program/steps/mail/show.inc b/program/steps/mail/show.inc index 8ab3e5ad8..c8dbdb50a 100644 --- a/program/steps/mail/show.inc +++ b/program/steps/mail/show.inc @@ -150,9 +150,13 @@ if ($uid) { $OUTPUT->add_handlers(array( - 'messageattachments' => 'rcmail_message_attachments', 'mailboxname' => 'rcmail_mailbox_name_display', + 'messageattachments' => 'rcmail_message_attachments', 'messageobjects' => 'rcmail_message_objects', + 'messagesummary' => 'rcmail_message_summary', + 'messageheaders' => 'rcmail_message_headers', + 'messagefullheaders' => 'rcmail_message_full_headers', + 'messagebody' => 'rcmail_message_body', 'contactphoto' => 'rcmail_message_contactphoto', )); @@ -335,6 +339,7 @@ function rcmail_message_contactphoto($attrib) '_task' => 'addressbook', '_action' => 'photo', '_email' => $MESSAGE->sender['mailto'], + '_error' => strpos($placeholder, 'blank.gif') === false ? 1 : null, )); $attrib['onerror'] = "this.src = '$placeholder'; this.onerror = null"; @@ -345,3 +350,418 @@ function rcmail_message_contactphoto($attrib) return html::img(array('src' => $photo_img, 'alt' => $RCMAIL->gettext('contactphoto')) + $attrib); } + +/** + * Returns table with message headers + */ +function rcmail_message_headers($attrib, $headers=null) +{ + global $MESSAGE, $PRINT_MODE, $RCMAIL; + static $sa_attrib; + + // keep header table attrib + if (is_array($attrib) && !$sa_attrib && !$attrib['valueof']) { + $sa_attrib = $attrib; + } + else if (!is_array($attrib) && is_array($sa_attrib)) { + $attrib = $sa_attrib; + } + + if (!isset($MESSAGE)) { + return false; + } + + // get associative array of headers object + if (!$headers) { + $headers_obj = $MESSAGE->headers; + $headers = get_object_vars($MESSAGE->headers); + } + else if (is_object($headers)) { + $headers_obj = $headers; + $headers = get_object_vars($headers_obj); + } + else { + $headers_obj = rcube_message_header::from_array($headers); + } + + // show these headers + $standard_headers = array('subject', 'from', 'sender', 'to', 'cc', 'bcc', 'replyto', + 'mail-reply-to', 'mail-followup-to', 'date', 'priority'); + $exclude_headers = $attrib['exclude'] ? explode(',', $attrib['exclude']) : array(); + $output_headers = array(); + + foreach ($standard_headers as $hkey) { + if ($headers[$hkey]) { + $value = $headers[$hkey]; + } + else if ($headers['others'][$hkey]) { + $value = $headers['others'][$hkey]; + } + else if (!$attrib['valueof']) { + continue; + } + + if (in_array($hkey, $exclude_headers)) { + continue; + } + + $ishtml = false; + $header_title = $RCMAIL->gettext(preg_replace('/(^mail-|-)/', '', $hkey)); + + if ($hkey == 'date') { + $header_value = $RCMAIL->format_date($value, + $PRINT_MODE ? $RCMAIL->config->get('date_long', 'x') : null); + } + else if ($hkey == 'priority') { + if ($value) { + $header_value = html::span('prio' . $value, rcube::Q(rcmail_localized_priority($value))); + $ishtml = true; + } + else { + continue; + } + } + else if ($hkey == 'replyto') { + if ($headers['replyto'] != $headers['from']) { + $header_value = rcmail_address_string($value, $attrib['max'], true, + $attrib['addicon'], $headers['charset'], $header_title); + $ishtml = true; + } + else { + continue; + } + } + else if ($hkey == 'mail-reply-to') { + if ($headers['mail-replyto'] != $headers['replyto'] + && $headers['replyto'] != $headers['from'] + ) { + $header_value = rcmail_address_string($value, $attrib['max'], true, + $attrib['addicon'], $headers['charset'], $header_title); + $ishtml = true; + } + else { + continue; + } + } + else if ($hkey == 'sender') { + if ($headers['sender'] != $headers['from']) { + $header_value = rcmail_address_string($value, $attrib['max'], true, + $attrib['addicon'], $headers['charset'], $header_title); + $ishtml = true; + } + else { + continue; + } + } + else if ($hkey == 'mail-followup-to') { + $header_value = rcmail_address_string($value, $attrib['max'], true, + $attrib['addicon'], $headers['charset'], $header_title); + $ishtml = true; + } + else if (in_array($hkey, array('from', 'to', 'cc', 'bcc'))) { + $header_value = rcmail_address_string($value, $attrib['max'], true, + $attrib['addicon'], $headers['charset'], $header_title); + $ishtml = true; + } + else if ($hkey == 'subject' && empty($value)) { + $header_value = $RCMAIL->gettext('nosubject'); + } + else { + $value = is_array($value) ? implode(' ', $value) : $value; + $header_value = trim(rcube_mime::decode_header($value, $headers['charset'])); + } + + $output_headers[$hkey] = array( + 'title' => $header_title, + 'value' => $header_value, + 'raw' => $value, + 'html' => $ishtml, + ); + } + + $plugin = $RCMAIL->plugins->exec_hook('message_headers_output', array( + 'output' => $output_headers, + 'headers' => $headers_obj, + 'exclude' => $exclude_headers, // readonly + 'folder' => $MESSAGE->folder, // readonly + 'uid' => $MESSAGE->uid, // readonly + )); + + // single header value is requested + if (!empty($attrib['valueof'])) { + $row = $plugin['output'][$attrib['valueof']]; + return $row['html'] ? $row['value'] : rcube::Q($row['value']); + } + + // compose html table + $table = new html_table(array('cols' => 2)); + + foreach ($plugin['output'] as $hkey => $row) { + $val = $row['html'] ? $row['value'] : rcube::Q($row['value']); + + $table->add(array('class' => 'header-title'), rcube::Q($row['title'])); + $table->add(array('class' => 'header '.$hkey), $val); + } + + return $table->show($attrib); +} + +/** + * Returns element with "From|To <sender|recipient> on <date>" + */ +function rcmail_message_summary($attrib) +{ + global $MESSAGE, $RCMAIL; + + if (!isset($MESSAGE) || empty($MESSAGE->headers)) { + return; + } + + $header = rcmail_message_list_smart_column_name(); + $label = 'shortheader' . $header; + $date = $RCMAIL->format_date($MESSAGE->headers->date, $RCMAIL->config->get('date_long', 'x')); + $user = $MESSAGE->headers->$header; + + if (!$user && $header == 'to') { + $user = $MESSAGE->headers->cc; + } + if (!$user && $header == 'to') { + $user = $MESSAGE->headers->bcc; + } + + $vars[$header] = rcmail_address_string($user, 1, true, $attrib['addicon'], $MESSAGE->headers->charset); + $vars['date'] = html::span('text-nowrap', $date); + + if (empty($user)) { + $label = 'shortheaderdate'; + } + + $out = html::span(null, $RCMAIL->gettext(array('name' => $label, 'vars' => $vars))); + + return html::div($attrib, $out); +} + +/** + * Convert Priority header value into a localized string + */ +function rcmail_localized_priority($value) +{ + global $RCMAIL; + + $labels_map = array( + '1' => 'highest', + '2' => 'high', + '3' => 'normal', + '4' => 'low', + '5' => 'lowest', + ); + + if ($value && $labels_map[$value]) { + return $RCMAIL->gettext($labels_map[$value]); + } + + return ''; +} + +/** + * Returns block to show full message headers + */ +function rcmail_message_full_headers($attrib) +{ + global $OUTPUT, $RCMAIL; + + $html = html::div(array('id' => "all-headers", 'class' => "all", 'style' => 'display:none'), + html::div(array('id' => 'headers-source'), '')); + $html .= html::div(array( + 'class' => "more-headers show-headers", + 'onclick' => "return ".rcmail_output::JS_OBJECT_NAME.".command('show-headers','',this)", + 'title' => $RCMAIL->gettext('togglefullheaders') + ), ''); + + $OUTPUT->add_gui_object('all_headers_row', 'all-headers'); + $OUTPUT->add_gui_object('all_headers_box', 'headers-source'); + + return html::div($attrib, $html); +} + +/** + * Handler for the 'messagebody' GUI object + * + * @param array Named parameters + * @return string HTML content showing the message body + */ +function rcmail_message_body($attrib) +{ + global $OUTPUT, $MESSAGE, $RCMAIL, $REMOTE_OBJECTS; + + if (!is_array($MESSAGE->parts) && empty($MESSAGE->body)) { + return ''; + } + + if (!$attrib['id']) + $attrib['id'] = 'rcmailMsgBody'; + + $safe_mode = $MESSAGE->is_safe || intval($_GET['_safe']); + $out = ''; + $part_no = 0; + + $header_attrib = array(); + foreach ($attrib as $attr => $value) { + if (preg_match('/^headertable([a-z]+)$/i', $attr, $regs)) { + $header_attrib[$regs[1]] = $value; + } + } + + if (!empty($MESSAGE->parts)) { + foreach ($MESSAGE->parts as $part) { + if ($part->type == 'headers') { + $out .= html::div('message-partheaders', rcmail_message_headers(count($header_attrib) ? $header_attrib : null, $part->headers)); + } + else if ($part->type == 'content') { + // unsupported (e.g. encrypted) + if ($part->realtype) { + if ($part->realtype == 'multipart/encrypted' || $part->realtype == 'application/pkcs7-mime') { + if (!empty($_SESSION['browser_caps']['pgpmime']) && ($pgp_mime_part = $MESSAGE->get_multipart_encrypted_part())) { + $out .= html::span('part-notice', $RCMAIL->gettext('externalmessagedecryption')); + $OUTPUT->set_env('pgp_mime_part', $pgp_mime_part->mime_id); + $OUTPUT->set_env('pgp_mime_container', '#' . $attrib['id']); + $OUTPUT->add_label('loadingdata'); + } + + if (!$MESSAGE->encrypted_part) { + $out .= html::span('part-notice', $RCMAIL->gettext('encryptedmessage')); + } + } + continue; + } + else if (!$part->size) { + continue; + } + + // Check if we have enough memory to handle the message in it + // #1487424: we need up to 10x more memory than the body + else if (!rcube_utils::mem_check($part->size * 10)) { + $out .= html::span('part-notice', $RCMAIL->gettext('messagetoobig'). ' ' + . html::a('?_task=mail&_action=get&_download=1&_uid='.$MESSAGE->uid.'&_part='.$part->mime_id + .'&_mbox='. urlencode($MESSAGE->folder), $RCMAIL->gettext('download'))); + continue; + } + + // fetch part body + $body = $MESSAGE->get_part_body($part->mime_id, true); + + // message is cached but not exists (#1485443), or other error + if ($body === false) { + rcmail_message_error($MESSAGE->uid); + } + + $plugin = $RCMAIL->plugins->exec_hook('message_body_prefix', + array('part' => $part, 'prefix' => '')); + + // Set attributes of the part container + $container_class = $part->ctype_secondary == 'html' ? 'message-htmlpart' : 'message-part'; + $container_id = $container_class . (++$part_no); + $container_attrib = array('class' => $container_class, 'id' => $container_id); + + // Assign container ID to a global variable for use in rcmail_washtml_link_callback() + $GLOBALS['rcmail_html_container_id'] = $container_id; + + // Parse the part content for display + $body = rcmail_print_body($body, $part, array('safe' => $safe_mode, 'plain' => !$RCMAIL->config->get('prefer_html'))); + + // check if the message body is PGP encrypted + if (strpos($body, '-----BEGIN PGP MESSAGE-----') !== false) { + $OUTPUT->set_env('is_pgp_content', '#' . $container_id); + } + + if ($part->ctype_secondary == 'html') { + $body = rcmail_html4inline($body, $container_id, 'rcmBody', $container_attrib, $safe_mode); + } + + $out .= html::div($container_attrib, $plugin['prefix'] . $body); + } + } + } + else { + // Check if we have enough memory to handle the message in it + // #1487424: we need up to 10x more memory than the body + if (!rcube_utils::mem_check(strlen($MESSAGE->body) * 10)) { + $out .= html::span('part-notice', $RCMAIL->gettext('messagetoobig'). ' ' + . html::a('?_task=mail&_action=get&_download=1&_uid='.$MESSAGE->uid.'&_part=0' + .'&_mbox='. urlencode($MESSAGE->folder), $RCMAIL->gettext('download'))); + } + else { + $plugin = $RCMAIL->plugins->exec_hook('message_body_prefix', + array('part' => $MESSAGE, 'prefix' => '')); + + $out .= html::div('message-part', + $plugin['prefix'] . rcmail_plain_body($MESSAGE->body)); + } + } + + // list images after mail body + if ($RCMAIL->config->get('inline_images', true) && !empty($MESSAGE->attachments)) { + $thumbnail_size = $RCMAIL->config->get('image_thumbnail_size', 240); + $client_mimetypes = (array)$RCMAIL->config->get('client_mimetypes'); + + foreach ($MESSAGE->attachments as $attach_prop) { + // skip inline images + if ($attach_prop->content_id && $attach_prop->disposition == 'inline') { + continue; + } + + // Content-Type: image/*... + if ($mimetype = rcmail_part_image_type($attach_prop)) { + // display thumbnails + if ($thumbnail_size) { + $supported = in_array($mimetype, $client_mimetypes); + $show_link = array( + 'href' => $MESSAGE->get_part_url($attach_prop->mime_id, false), + 'onclick' => sprintf( + 'return %s.command(\'load-attachment\',\'%s\',this)', + rcmail_output::JS_OBJECT_NAME, + $attach_prop->mime_id) + ); + + $out .= html::p(array('class' => 'image-attachment', 'style' => $supported ? '' : 'display:none'), + html::a($show_link + array('class' => 'image-link', 'style' => sprintf('width:%dpx', $thumbnail_size)), + html::img(array( + 'class' => 'image-thumbnail', + 'src' => $MESSAGE->get_part_url($attach_prop->mime_id, 'image') . '&_thumb=1', + 'title' => $attach_prop->filename, + 'alt' => $attach_prop->filename, + 'style' => sprintf('max-width:%dpx; max-height:%dpx', $thumbnail_size, $thumbnail_size), + 'onload' => $supported ? '' : '$(this).parents(\'p.image-attachment\').show()', + )) + ) . + html::span('image-filename', rcube::Q($attach_prop->filename)) . + html::span('image-filesize', rcube::Q($RCMAIL->message_part_size($attach_prop))) . + html::span('attachment-links', + ($supported ? html::a($show_link, $RCMAIL->gettext('showattachment')) . ' ' : '') . + html::a($show_link['href'] . '&_download=1', $RCMAIL->gettext('download')) + ) . + html::br(array('style' => 'clear:both')) + ); + } + else { + $out .= html::tag('fieldset', 'image-attachment', + html::tag('legend', 'image-filename', rcube::Q($attach_prop->filename)) . + html::p(array('align' => 'center'), + html::img(array( + 'src' => $MESSAGE->get_part_url($attach_prop->mime_id, 'image'), + 'title' => $attach_prop->filename, + 'alt' => $attach_prop->filename, + ))) + ); + } + } + } + } + + // tell client that there are blocked remote objects + if ($REMOTE_OBJECTS && !$safe_mode) { + $OUTPUT->set_env('blockedobjects', true); + } + + return html::div($attrib, $out); +} |