diff options
-rw-r--r-- | program/include/html.php | 2 | ||||
-rw-r--r-- | program/include/rcube_imap.php | 30 | ||||
-rw-r--r-- | program/include/rcube_message.php | 399 | ||||
-rw-r--r-- | program/include/session.inc | 2 | ||||
-rw-r--r-- | program/steps/mail/compose.inc | 272 | ||||
-rw-r--r-- | program/steps/mail/func.inc | 228 | ||||
-rw-r--r-- | program/steps/mail/get.inc | 72 | ||||
-rw-r--r-- | program/steps/mail/show.inc | 120 |
8 files changed, 643 insertions, 482 deletions
diff --git a/program/include/html.php b/program/include/html.php index 6f602454c..d0ab97633 100644 --- a/program/include/html.php +++ b/program/include/html.php @@ -32,7 +32,7 @@ class html protected $allowed; protected $content; - protected static $common_attrib = array('id','class','style','title','align'); + public static $common_attrib = array('id','class','style','title','align'); public static $containers = array('div','span','p','h1','h2','h3','form','textarea'); public static $lc_tags = true; diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php index 1bf59b8dd..fa2845d5b 100644 --- a/program/include/rcube_imap.php +++ b/program/include/rcube_imap.php @@ -1180,36 +1180,6 @@ class rcube_imap /** - * Return a flat array with references to all parts, indexed by part numbers - * - * @param object rcube_message_part Message body structure - * @return Array with part number -> object pairs - */ - function get_mime_numbers(&$structure) - { - $a_parts = array(); - $this->_get_part_numbers($structure, $a_parts); - return $a_parts; - } - - - /** - * Helper method for recursive calls - * - * @access private - */ - function _get_part_numbers(&$part, &$a_parts) - { - if ($part->mime_id) - $a_parts[$part->mime_id] = &$part; - - if (is_array($part->parts)) - for ($i=0; $i<count($part->parts); $i++) - $this->_get_part_numbers($part->parts[$i], $a_parts); - } - - - /** * Fetch message body of a specific message from the server * * @param int Message UID diff --git a/program/include/rcube_message.php b/program/include/rcube_message.php new file mode 100644 index 000000000..174b1f314 --- /dev/null +++ b/program/include/rcube_message.php @@ -0,0 +1,399 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | program/include/rcube_message.php | + | | + | This file is part of the RoundCube Webmail client | + | Copyright (C) 2008, RoundCube Dev. - Switzerland | + | Licensed under the GNU GPL | + | | + | PURPOSE: | + | Logical representation of a mail message with all its data | + | and related functions | + +-----------------------------------------------------------------------+ + | Author: Thomas Bruederli <roundcube@gmail.com> | + +-----------------------------------------------------------------------+ + + $Id: rcube_imap.php 1344 2008-04-30 08:21:42Z thomasb $ + +*/ + + +/** + * Interface class for accessing an IMAP server + * + * This is a wrapper that implements the Iloha IMAP Library (IIL) + * + * @package Mail + * @author Thomas Bruederli <roundcube@gmail.com> + */ +class rcube_message +{ + private $app; + private $imap; + private $opt = array(); + private $inline_parts = array(); + private $parse_alternative = false; + + public $uid = null; + public $headers; + public $structure; + public $parts = array(); + public $mime_parts = array(); + public $attachments = array(); + public $subject = ''; + public $is_safe = false; + + + function __construct($uid) + { + $this->app = rcmail::get_instance(); + $this->imap = $this->app->imap; + + $this->uid = $uid; + $this->headers = $this->imap->get_headers($uid); + $this->subject = rcube_imap::decode_mime_string($this->headers->subject, $this->headers->charset); + + $this->is_safe = (intval($_GET['_safe']) || $_SESSION['safe_messages'][$uid]) ? true : false; + $_SESSION['safe_messages'][$uid] = $this->is_safe; + + $this->opt = array( + 'safe' => $this->is_safe, + 'prefer_html' => $this->app->config->get('prefer_html'), + 'get_url' => rcmail_url('get', array('_mbox' => $this->imap->get_mailbox_name(), '_uid' => $uid)) + ); + + if ($this->structure = $this->imap->get_structure($uid)) { + $this->parse_structure($this->structure); + $this->get_mime_numbers($this->structure); + } + else { + $this->body = $this->imap->get_body($uid); + } + } + + + /** + * Return a (decoded) message header + * + * @param string Header name + * @param bool Don't mime-decode the value + * @return string Header value + */ + public function get_header($name, $raw = false) + { + $value = $this->header->$name; + return $raw ? $value : $this->imap->decode_header($value); + } + + + /** + * Compose a valid URL for getting a message part + * + * @param string Part MIME-ID + * @return string URL or false if part does not exist + */ + public function get_part_url($mime_id) + { + if ($this->mime_parts[$mime_id]) + return $this->opt['get_url'] . "&_part=" . $mime_id; + else + return false; + } + + + /** + * Get content of a specific part of this message + * + * @param string Part MIME-ID + * @return string Part content + */ + public function get_part_content($mime_id) + { + if ($part = $this->mime_parts[$mime_id]) + return $this->imap->get_message_part($this->uid, $mime_id, $part); + else + return null; + } + + + /** + * Determine if the message contains a HTML part + * + * @return bool True if a HTML is available, False if not + */ + function has_html_part() + { + // check all message parts + foreach ($this->parts as $pid => $part) { + $mimetype = strtolower($part->ctype_primary . '/' . $part->ctype_secondary); + if ($mimetype == 'text/html') + return true; + } + + return false; + } + + /** + * Return the first HTML part of this message + * + * @return string HTML message part content + */ + function first_html_part() + { + $html_part = null; + + // check all message parts + foreach ($this->mime_parts as $mime_id => $part) { + $mimetype = strtolower($part->ctype_primary . '/' . $part->ctype_secondary); + if ($mimetype == 'text/html') { + $html_part = $this->imap->get_message_part($this->uid, $mime_id, $part); + } + } + + return $html_part; + } + + + /** + * Return the first text part of this message + * + * @return string Plain text message/part content + */ + function first_text_part() + { + // no message structure, return complete body + if (empty($this->parts)) + return $this->body; + + $out = null; + + // check all message parts + foreach ($this->mime_parts as $mime_id => $part) { + $mimetype = strtolower($part->ctype_primary . '/' . $part->ctype_secondary); + + if ($mimetype == 'text/plain') { + $out = $this->imap->get_message_part($this->uid, $mime_id, $part); + break; + } + else if ($mimetype == 'text/html') { + $html_part = $this->imap->get_message_part($this->uid, $mime_id, $part); + + // remove special chars encoding + $trans = array_flip(get_html_translation_table(HTML_ENTITIES)); + $html_part = strtr($html_part, $trans); + + // create instance of html2text class + $txt = new html2text($html_part); + $out = $txt->get_text(); + break; + } + } + + return $out; + } + + + /** + * Raad the message structure returend by the IMAP server + * and build flat lists of content parts and attachments + * + * @param object rcube_message_part Message structure node + * @param bool True when called recursively + */ + private function parse_structure($structure, $recursive = false) + { + $message_ctype_primary = strtolower($structure->ctype_primary); + $message_ctype_secondary = strtolower($structure->ctype_secondary); + + // show message headers + if ($recursive && is_array($structure->headers) && isset($structure->headers['subject'])) { + $c = new stdClass; + $c->type = 'headers'; + $c->headers = &$structure->headers; + $this->parts[] = $c; + } + + // print body if message doesn't have multiple parts + if ($message_ctype_primary == 'text' && !$recursive) { + $structure->type = 'content'; + $this->parts[] = &$structure; + } + // message contains alternative parts + else if ($message_ctype_primary == 'multipart' && ($message_ctype_secondary == 'alternative') && is_array($structure->parts)) { + // get html/plaintext parts + $plain_part = $html_part = $print_part = $related_part = null; + + foreach ($structure->parts as $p => $sub_part) { + $rel_parts = $attachmnts = null; + $sub_ctype_primary = strtolower($sub_part->ctype_primary); + $sub_ctype_secondary = strtolower($sub_part->ctype_secondary); + + // check if sub part is + if ($sub_ctype_primary=='text' && $sub_ctype_secondary=='plain') + $plain_part = $p; + else if ($sub_ctype_primary=='text' && $sub_ctype_secondary=='html') + $html_part = $p; + else if ($sub_ctype_primary=='text' && $sub_ctype_secondary=='enriched') + $enriched_part = $p; + else if ($sub_ctype_primary=='multipart' && ($sub_ctype_secondary=='related' || $sub_ctype_secondary=='mixed')) + $related_part = $p; + } + + // parse related part (alternative part could be in here) + if ($related_part !== null && !$this->parse_alternative) { + $this->parse_alternative = true; + $this->parse_structure($structure->parts[$related_part], true); + $this->parse_alternative = false; + + // if plain part was found, we should unset it if html is preferred + if ($this->opt['prefer_html'] && count($this->parts)) + $plain_part = null; + } + + // choose html/plain part to print + if ($html_part !== null && $this->opt['prefer_html']) { + $print_part = &$structure->parts[$html_part]; + } + else if ($enriched_part !== null) { + $print_part = &$structure->parts[$enriched_part]; + } + else if ($plain_part !== null) { + $print_part = &$structure->parts[$plain_part]; + } + + // add the right message body + if (is_object($print_part)) { + $print_part->type = 'content'; + $this->parts[] = $print_part; + } + // show plaintext warning + else if ($html_part !== nullL && empty($this->parts)) { + $c = new stdClass; + $c->type = 'content'; + $c->body = rcube_label('htmlmessage'); + $c->ctype_primary = 'text'; + $c->ctype_secondary = 'plain'; + + $this->parts[] = $c; + } + + // add html part as attachment + if ($html_part !== null && $structure->parts[$html_part] !== $print_part) { + $html_part = &$structure->parts[$html_part]; + $html_part->filename = rcube_label('htmlmessage'); + $html_part->mimetype = 'text/html'; + + $this->attachments[] = $html_part; + } + } + // this is an ecrypted message -> create a plaintext body with the according message + else if ($message_ctype_primary == 'multipart' && $message_ctype_secondary == 'encrypted') { + $p = new stdClass; + $p->type = 'content'; + $p->ctype_primary = 'text'; + $p->ctype_secondary = 'plain'; + $p->body = rcube_label('encryptedmessage'); + + $this->parts[] = $p; + } + // message contains multiple parts + else if (is_array($structure->parts) && !empty($structure->parts)) { + // iterate over parts + for ($i=0; $i < count($structure->parts); $i++) { + $mail_part = &$structure->parts[$i]; + $primary_type = strtolower($mail_part->ctype_primary); + $secondary_type = strtolower($mail_part->ctype_secondary); + + // multipart/alternative + if ($primary_type=='multipart') { + $this->parse_structure($mail_part, true); + } + // part text/[plain|html] OR message/delivery-status + else if (($primary_type == 'text' && ($secondary_type == 'plain' || $secondary_type == 'html') && $mail_part->disposition != 'attachment') || + ($primary_type == 'message' && ($secondary_type == 'delivery-status' || $secondary_type == 'disposition-notification'))) { + + // add text part if we're not in alternative mode or if it matches the prefs + if (!$this->parse_alternative || + ($secondary_type == 'html' && $this->opt['prefer_html']) || + ($secondary_type == 'plain' && !$this->opt['prefer_html'])) { + $mail_part->type = 'content'; + $this->parts[] = $mail_part; + } + + // list as attachment as well + if (!empty($mail_part->filename)) + $this->attachments[] = $mail_part; + } + // part message/* + else if ($primary_type=='message') { + $this->parse_structure($mail_part, true); + } + // ignore "virtual" protocol parts + else if ($primary_type == 'protocol') + continue; + + // part is file/attachment + else if ($mail_part->disposition == 'attachment' || $mail_part->disposition == 'inline' || + $mail_part->headers['content-id'] || (empty($mail_part->disposition) && $mail_part->filename)) { + // skip apple resource forks + if ($message_ctype_secondary == 'appledouble' && $secondary_type == 'applefile') + continue; + + // part belongs to a related message + if ($message_ctype_secondary == 'related' && $mail_part->headers['content-id']) { + $mail_part->content_id = preg_replace(array('/^</', '/>$/'), '', $mail_part->headers['content-id']); + $this->inline_parts[] = $mail_part; + } + // is regular attachment + else { + if (!$mail_part->filename) + $mail_part->filename = 'Part '.$mail_part->mime_id; + $this->attachments[] = $mail_part; + } + } + } + + // if this was a related part try to resolve references + if ($message_ctype_secondary == 'related' && sizeof($this->inline_objects)) { + $a_replaces = array(); + + foreach ($this->inline_parts as $inline_object) { + $a_replaces['cid:'.$inline_object->content_id] = htmlspecialchars(sprintf($this->opt['get_url'], $inline_object->mime_id)); + } + + // add replace array to each content part + // (will be applied later when part body is available) + for ($i=0; $i<count($a_return_parts); $i++) { + if ($a_return_parts[$i]->type=='content') + $a_return_parts[$i]->replaces = $a_replaces; + } + } + } + + // message is single part non-text + else if ($structure->filename) { + $this->attachments[] = $structure; + } + } + + + /** + * Fill aflat array with references to all parts, indexed by part numbers + * + * @param object rcube_message_part Message body structure + */ + private function get_mime_numbers(&$part) + { + if (strlen($part->mime_id)) + $this->mime_parts[$part->mime_id] = &$part; + + if (is_array($part->parts)) + for ($i=0; $i<count($part->parts); $i++) + $this->get_mime_numbers($part->parts[$i]); + } + + +} + diff --git a/program/include/session.inc b/program/include/session.inc index a789fd2d7..ef8eb2726 100644 --- a/program/include/session.inc +++ b/program/include/session.inc @@ -88,7 +88,7 @@ function sess_write($key, $vars) VALUES (?, ?, ?, ".$DB->now().", ".$DB->now().")", $key, $vars, - $_SERVER['REMOTE_ADDR']); + (string)$_SERVER['REMOTE_ADDR']); } return TRUE; diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc index 676b6b4be..d2a48abf3 100644 --- a/program/steps/mail/compose.inc +++ b/program/steps/mail/compose.inc @@ -5,7 +5,7 @@ | program/steps/mail/compose.inc | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland | + | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | @@ -85,24 +85,19 @@ else if ($msg_uid = get_input_value('_draft_uid', RCUBE_INPUT_GET)) if (!empty($msg_uid)) { // similar as in program/steps/mail/show.inc - $MESSAGE = array('UID' => $msg_uid); - $MESSAGE['headers'] = &$IMAP->get_headers($msg_uid); - $MESSAGE['structure'] = &$IMAP->get_structure($msg_uid); + $MESSAGE = new rcube_message($msg_uid); - if (!empty($MESSAGE['headers']->charset)) - $IMAP->set_charset($MESSAGE['headers']->charset); + if (!empty($MESSAGE->headers->charset)) + $IMAP->set_charset($MESSAGE->headers->charset); - $MESSAGE['subject'] = $IMAP->decode_header($MESSAGE['headers']->subject); - $MESSAGE['parts'] = $IMAP->get_mime_numbers($MESSAGE['structure']); - if ($compose_mode == RCUBE_COMPOSE_REPLY) { $_SESSION['compose']['reply_uid'] = $msg_uid; - $_SESSION['compose']['reply_msgid'] = $MESSAGE['headers']->messageID; - $_SESSION['compose']['references'] = trim($MESSAGE['headers']->references . " " . $MESSAGE['headers']->messageID); + $_SESSION['compose']['reply_msgid'] = $MESSAGE->headers->messageID; + $_SESSION['compose']['references'] = trim($MESSAGE->headers->references . " " . $MESSAGE->headers->messageID); if (!empty($_GET['_all'])) - $MESSAGE['reply_all'] = 1; + $MESSAGE->reply_all = 1; } else if ($compose_mode == RCUBE_COMPOSE_FORWARD) { @@ -173,19 +168,19 @@ function rcmail_compose_headers($attrib) else if ($header && $compose_mode == RCUBE_COMPOSE_REPLY) { // get recipent address(es) out of the message headers - if ($header=='to' && !empty($MESSAGE['headers']->replyto)) - $fvalue = $MESSAGE['headers']->replyto; + if ($header=='to' && !empty($MESSAGE->headers->replyto)) + $fvalue = $MESSAGE->headers->replyto; - else if ($header=='to' && !empty($MESSAGE['headers']->from)) - $fvalue = $MESSAGE['headers']->from; + else if ($header=='to' && !empty($MESSAGE->headers->from)) + $fvalue = $MESSAGE->headers->from; // add recipent of original message if reply to all - else if ($header=='cc' && !empty($MESSAGE['reply_all'])) + else if ($header=='cc' && !empty($MESSAGE->reply_all)) { - if ($v = $MESSAGE['headers']->to) + if ($v = $MESSAGE->headers->to) $fvalue .= $v; - if ($v = $MESSAGE['headers']->cc) + if ($v = $MESSAGE->headers->cc) $fvalue .= (!empty($fvalue) ? ', ' : '') . $v; } @@ -196,7 +191,7 @@ function rcmail_compose_headers($attrib) $fvalue = ''; foreach ($to_addresses as $addr_part) { - if (!empty($addr_part['mailto']) && !in_array($addr_part['mailto'], $sa_recipients) && (!$MESSAGE['FROM'] || !in_array($addr_part['mailto'], $MESSAGE['FROM']))) + if (!empty($addr_part['mailto']) && !in_array($addr_part['mailto'], $sa_recipients) && (!$MESSAGE->compose_from || !in_array($addr_part['mailto'], $MESSAGE->compose_from))) { $fvalue .= (strlen($fvalue) ? ', ':'').$addr_part['string']; $sa_recipients[] = $addr_part['mailto']; @@ -207,14 +202,14 @@ function rcmail_compose_headers($attrib) else if ($header && $compose_mode == RCUBE_COMPOSE_DRAFT) { // get drafted headers - if ($header=='to' && !empty($MESSAGE['headers']->to)) - $fvalue = $IMAP->decode_header($MESSAGE['headers']->to); + if ($header=='to' && !empty($MESSAGE->headers->to)) + $fvalue = $MESSAGE->get_header('to'); - if ($header=='cc' && !empty($MESSAGE['headers']->cc)) - $fvalue = $IMAP->decode_header($MESSAGE['headers']->cc); + if ($header=='cc' && !empty($MESSAGE->headers->cc)) + $fvalue = $MESSAGE->get_header('cc'); - if ($header=='bcc' && !empty($MESSAGE['headers']->bcc)) - $fvalue = $IMAP->decode_header($MESSAGE['headers']->bcc); + if ($header=='bcc' && !empty($MESSAGE->headers->bcc)) + $fvalue = $MESSAGE->get_header('bcc'); } @@ -241,7 +236,7 @@ function rcmail_compose_headers($attrib) function rcmail_compose_header_from($attrib) { - global $IMAP, $MESSAGE, $DB, $USER, $OUTPUT, $CONFIG, $compose_mode; + global $IMAP, $MESSAGE, $DB, $USER, $OUTPUT, $compose_mode; // pass the following attributes to the form class $field_attrib = array('name' => '_from'); @@ -251,20 +246,20 @@ function rcmail_compose_header_from($attrib) // extract all recipients of the reply-message $a_recipients = array(); - if ($compose_mode == RCUBE_COMPOSE_REPLY && is_object($MESSAGE['headers'])) + if ($compose_mode == RCUBE_COMPOSE_REPLY && is_object($MESSAGE->headers)) { - $MESSAGE['FROM'] = array(); + $MESSAGE->compose_from = array(); - $a_to = $IMAP->decode_address_list($MESSAGE['headers']->to); + $a_to = $IMAP->decode_address_list($MESSAGE->headers->to); foreach ($a_to as $addr) { if (!empty($addr['mailto'])) $a_recipients[] = $addr['mailto']; } - if (!empty($MESSAGE['headers']->cc)) + if (!empty($MESSAGE->headers->cc)) { - $a_cc = $IMAP->decode_address_list($MESSAGE['headers']->cc); + $a_cc = $IMAP->decode_address_list($MESSAGE->headers->cc); foreach ($a_cc as $addr) { if (!empty($addr['mailto'])) @@ -306,10 +301,10 @@ function rcmail_compose_header_from($attrib) if (in_array($sql_arr['email'], $a_recipients)) $from_id = $sql_arr['identity_id']; - if ($compose_mode == RCUBE_COMPOSE_REPLY && is_array($MESSAGE['FROM'])) - $MESSAGE['FROM'][] = $sql_arr['email']; + if ($compose_mode == RCUBE_COMPOSE_REPLY && is_array($MESSAGE->compose_from)) + $MESSAGE->compose_from[] = $sql_arr['email']; - if ($compose_mode == RCUBE_COMPOSE_DRAFT && strstr($MESSAGE['headers']->from, $sql_arr['email'])) + if ($compose_mode == RCUBE_COMPOSE_DRAFT && strstr($MESSAGE->headers->from, $sql_arr['email'])) $from_id = $sql_arr['identity_id']; } @@ -356,65 +351,36 @@ function rcmail_compose_body($attrib) // use posted message body if (!empty($_POST['_message'])) + { + $body = get_input_value('_message', RCUBE_INPUT_POST, true); + } + else if ($compose_mode) + { + if ($isHtml && $MESSAGE->has_html_part()) { - $body = get_input_value('_message', RCUBE_INPUT_POST, TRUE); - } - // compose reply-body - else if ($compose_mode == RCUBE_COMPOSE_REPLY) - { - $hasHtml = rcmail_has_html_part($MESSAGE['parts']); - if ($hasHtml && $CONFIG['htmleditor']) - { - $body = rcmail_first_html_part($MESSAGE); + $body = $MESSAGE->first_html_part(); $isHtml = true; - } - else - { - $body = rcmail_first_text_part($MESSAGE); - $isHtml = false; - } - - $body = rcmail_create_reply_body($body, $isHtml); } - // forward message body inline - else if ($compose_mode == RCUBE_COMPOSE_FORWARD) - { - $hasHtml = rcmail_has_html_part($MESSAGE['parts']); - if ($hasHtml && $CONFIG['htmleditor']) - { - $body = rcmail_first_html_part($MESSAGE); - $isHtml = true; - } else - { - $body = rcmail_first_text_part($MESSAGE); - $isHtml = false; - } - - $body = rcmail_create_forward_body($body, $isHtml); - } - else if ($compose_mode == RCUBE_COMPOSE_DRAFT) { - $hasHtml = rcmail_has_html_part($MESSAGE['parts']); - if ($hasHtml && $CONFIG['htmleditor']) - { - $body = rcmail_first_html_part($MESSAGE); - $isHtml = true; - } - else - { - $body = rcmail_first_text_part($MESSAGE); + $body = $MESSAGE->first_text_part(); $isHtml = false; - } - - $body = rcmail_create_draft_body($body, $isHtml); } + + // compose reply-body + if ($compose_mode == RCUBE_COMPOSE_REPLY) + $body = rcmail_create_reply_body($body, $isHtml); + // forward message body inline + else if ($compose_mode == RCUBE_COMPOSE_FORWARD) + $body = rcmail_create_forward_body($body, $isHtml); + // load draft message body + else if ($compose_mode == RCUBE_COMPOSE_DRAFT) + $body = rcmail_create_draft_body($body, $isHtml); + } $tinylang = substr($_SESSION['language'], 0, 2); if (!file_exists('program/js/tiny_mce/langs/'.$tinylang.'.js')) - { $tinylang = 'en'; - } $OUTPUT->include_script('tiny_mce/tiny_mce.js'); $OUTPUT->include_script("editor.js"); @@ -422,7 +388,7 @@ function rcmail_compose_body($attrib) $out = $form_start ? "$form_start\n" : ''; - $saveid = new html_hiddenfield(array('name' => '_draft_saveid', 'value' => $compose_mode==RCUBE_COMPOSE_DRAFT ? str_replace(array('<','>'), "", $MESSAGE['headers']->messageID) : '')); + $saveid = new html_hiddenfield(array('name' => '_draft_saveid', 'value' => $compose_mode==RCUBE_COMPOSE_DRAFT ? str_replace(array('<','>'), "", $MESSAGE->headers->messageID) : '')); $out .= $saveid->show(); $drafttoggle = new html_hiddenfield(array('name' => '_draft', 'value' => 'yes')); @@ -500,8 +466,8 @@ function rcmail_create_reply_body($body, $bodyIsHtml) // add title line $prefix = sprintf("\n\n\nOn %s, %s wrote:\n", - $MESSAGE['headers']->date, - $IMAP->decode_header($MESSAGE['headers']->from)); + $MESSAGE->headers->date, + $MESSAGE->get_header('from')); // try to remove the signature if ($sp = strrpos($body, '-- ')) @@ -513,12 +479,10 @@ function rcmail_create_reply_body($body, $bodyIsHtml) } else { - $prefix = sprintf("<br><br>On %s, %s wrote:<br><blockquote type=\"cite\" " . - "style=\"padding-left: 5px; border-left: #1010ff 2px solid; " . - "margin-left: 5px; width: 100%%\">", - $MESSAGE['headers']->date, - $IMAP->decode_header($MESSAGE['headers']->from)); - + $prefix = sprintf("<br /><br />On %s, %s wrote:<br />\n", + $MESSAGE->headers->date, + Q($MESSAGE->get_header('from'))); + $prefix .= '<blockquote type="cite" style="padding-left:5px; border-left:#1010ff 2px solid; margin-left:5px; width:100%">'; $suffix = "</blockquote>"; } @@ -530,35 +494,35 @@ function rcmail_create_forward_body($body, $bodyIsHtml) { global $IMAP, $MESSAGE; - if (! $bodyIsHtml) + if (!$bodyIsHtml) { // soft-wrap message first $body = wordwrap($body, 80); $prefix = sprintf("\n\n\n-------- Original Message --------\nSubject: %s\nDate: %s\nFrom: %s\nTo: %s\n\n", - $MESSAGE['subject'], - $MESSAGE['headers']->date, - $IMAP->decode_header($MESSAGE['headers']->from), - $IMAP->decode_header($MESSAGE['headers']->to)); + $MESSAGE->subject, + $MESSAGE->headers->date, + $MESSAGE->get_header('from'), + $MESSAGE->get_header('to')); } else { $prefix = sprintf( - "<br><br>-------- Original Message --------" . + "<br><br>-------- Original Message --------" . "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody>" . "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">Subject: </th><td>%s</td></tr>" . "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">Date: </th><td>%s</td></tr>" . "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">From: </th><td>%s</td></tr>" . "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">To: </th><td>%s</td></tr>" . "</tbody></table><br>", - Q($MESSAGE['subject']), - Q($MESSAGE['headers']->date), - Q($IMAP->decode_header($MESSAGE['headers']->from)), - Q($IMAP->decode_header($MESSAGE['headers']->to))); + Q($MESSAGE->subject), + Q($MESSAGE->headers->date), + Q($MESSAGE->get_header('from')), + Q($MESSAGE->get_header('to'))); } // add attachments - if (!isset($_SESSION['compose']['forward_attachments']) && is_array($MESSAGE['parts'])) + if (!isset($_SESSION['compose']['forward_attachments']) && is_array($MESSAGE->mime_parts)) rcmail_write_compose_attachments($MESSAGE); return $prefix.$body; @@ -567,15 +531,15 @@ function rcmail_create_forward_body($body, $bodyIsHtml) function rcmail_create_draft_body($body, $bodyIsHtml) { - global $IMAP, $MESSAGE; + global $MESSAGE; /** * add attachments - * sizeof($MESSAGE['parts'] can be 1 - e.g. attachment, but no text! + * sizeof($MESSAGE->mime_parts can be 1 - e.g. attachment, but no text! */ if (!isset($_SESSION['compose']['forward_attachments']) - && is_array($MESSAGE['parts']) - && count($MESSAGE['parts']) > 0) + && is_array($MESSAGE->mime_parts) + && count($MESSAGE->mime_parts) > 0) rcmail_write_compose_attachments($MESSAGE); return $body; @@ -584,14 +548,14 @@ function rcmail_create_draft_body($body, $bodyIsHtml) function rcmail_write_compose_attachments(&$message) { - global $IMAP, $CONFIG; + global $RCMAIL, $IMAP; - $temp_dir = unslashify($CONFIG['temp_dir']); + $temp_dir = unslashify($RCMAIL->config->get('temp_dir')); if (!is_array($_SESSION['compose']['attachments'])) $_SESSION['compose']['attachments'] = array(); - foreach ($message['parts'] as $pid => $part) + foreach ((array)$message->mime_parts as $pid => $part) { if ($part->ctype_primary != 'message' && ($part->disposition=='attachment' || $part->disposition=='inline' || $part->headers['content-id'] || @@ -600,7 +564,7 @@ function rcmail_write_compose_attachments(&$message) $tmp_path = tempnam($temp_dir, 'rcmAttmnt'); if ($fp = fopen($tmp_path, 'w')) { - fwrite($fp, $IMAP->get_message_part($message['UID'], $pid, $part->encoding)); + fwrite($fp, $message->get_part_content($pid)); fclose($fp); $_SESSION['compose']['attachments'][] = array( @@ -612,13 +576,13 @@ function rcmail_write_compose_attachments(&$message) } } - $_SESSION['compose']['forward_attachments'] = TRUE; + $_SESSION['compose']['forward_attachments'] = true; } function rcmail_compose_subject($attrib) { - global $CONFIG, $MESSAGE, $compose_mode; + global $MESSAGE, $compose_mode; list($form_start, $form_end) = get_form_tags($attrib); unset($attrib['form']); @@ -635,24 +599,24 @@ function rcmail_compose_subject($attrib) // create a reply-subject else if ($compose_mode == RCUBE_COMPOSE_REPLY) { - if (eregi('^re:', $MESSAGE['subject'])) - $subject = $MESSAGE['subject']; + if (eregi('^re:', $MESSAGE->subject)) + $subject = $MESSAGE->subject; else - $subject = 'Re: '.$MESSAGE['subject']; + $subject = 'Re: '.$MESSAGE->subject; } // create a forward-subject else if ($compose_mode == RCUBE_COMPOSE_FORWARD) { - if (eregi('^fwd:', $MESSAGE['subject'])) - $subject = $MESSAGE['subject']; + if (eregi('^fwd:', $MESSAGE->subject)) + $subject = $MESSAGE->subject; else - $subject = 'Fwd: '.$MESSAGE['subject']; + $subject = 'Fwd: '.$MESSAGE->subject; } // creeate a draft-subject else if ($compose_mode == RCUBE_COMPOSE_DRAFT) - $subject = $MESSAGE['subject']; + $subject = $MESSAGE->subject; $out = $form_start ? "$form_start\n" : ''; $out .= $textfield->show($subject); @@ -670,35 +634,30 @@ function rcmail_compose_attachment_list($attrib) if (!$attrib['id']) $attrib['id'] = 'rcmAttachmentList'; - // allow the following attributes to be added to the <ul> tag - $attrib_str = create_attrib_string($attrib, array('id', 'class', 'style')); - - $out = '<ul'. $attrib_str . ">\n"; + $out = "\n"; if (is_array($_SESSION['compose']['attachments'])) { if ($attrib['deleteicon']) - $button = sprintf('<img src="%s%s" alt="%s" border="0" style="padding-right:2px;vertical-align:middle" />', - $CONFIG['skin_path'], - $attrib['deleteicon'], - rcube_label('delete')); + $button = html::img(array( + 'src' => $CONFIG['skin_path'] . $attrib['deleteicon'], + 'alt' => rcube_label('delete'), + 'style' => "border:0;padding-right:2px;vertical-align:middle")); else - $button = rcube_label('delete'); + $button = Q(rcube_label('delete')); foreach ($_SESSION['compose']['attachments'] as $id => $a_prop) - $out .= sprintf('<li id="rcmfile%d"><a href="#delete" onclick="return %s.command(\'remove-attachment\',\'rcmfile%d\', this)" title="%s">%s</a>%s</li>', - $id, - JS_OBJECT_NAME, - $id, - Q(rcube_label('delete')), - $button, - Q($a_prop['name'])); + $out .= html::tag('li', array('id' => "rcmfile".$id), + html::a(array( + 'href' => "#delete", + 'title' => rcube_label('delete'), + 'onclick' => sprintf("return %s.command(\'remove-attachment\',\'rcmfile%d\', this)", JS_OBJECT_NAME, $id)), + $button) . Q($a_prop['name'])); } $OUTPUT->add_gui_object('attachmentlist', $attrib['id']); - $out .= '</ul>'; - return $out; + return html::tag('ul', $attrib, $out, html::$common_attrib); } @@ -752,7 +711,7 @@ function rcmail_priority_selector($attrib) rcube_label('highest')), array(5, 4, 0, 2, 1)); - $sel = isset($_POST['_priority']) ? $_POST['_priority'] : intval($MESSAGE['headers']->priority); + $sel = isset($_POST['_priority']) ? $_POST['_priority'] : intval($MESSAGE->headers->priority); $out = $form_start ? "$form_start\n" : ''; $out .= $selector->show($sel); @@ -777,7 +736,7 @@ function rcmail_receipt_checkbox($attrib) $checkbox = new html_checkbox($attrib); $out = $form_start ? "$form_start\n" : ''; - $out .= $checkbox->show($MESSAGE['headers']->mdn_to ? 1 : 0); + $out .= $checkbox->show($MESSAGE->headers->mdn_to ? 1 : 0); $out .= $form_end ? "\n$form_end" : ''; return $out; @@ -793,39 +752,20 @@ function rcmail_editor_selector($attrib) 'plain' => 'plaintoggle' ); - // determine whether HTML or plain text should be checked - if ($CONFIG['htmleditor']) - { - $useHtml = true; - } - else - { - $useHtml = false; - } + // determine whether HTML or plain text should be checked + $useHtml = $CONFIG['htmleditor'] ? true : false; - if ($compose_mode == RCUBE_COMPOSE_REPLY || - $compose_mode == RCUBE_COMPOSE_FORWARD || - $compose_mode == RCUBE_COMPOSE_DRAFT) - { - $hasHtml = rcmail_has_html_part($MESSAGE['parts']); - $useHtml = ($hasHtml && $CONFIG['htmleditor']); - } - - $chosenvalue = $useHtml ? 'html' : 'plain'; + if ($compose_mode) + $useHtml = ($useHtml && $MESSAGE->has_html_part()); $selector = ''; - - $attrib['name'] = '_editorSelect'; - $attrib['onclick'] = 'return rcmail_toggle_editor(this)'; + $chosenvalue = $useHtml ? 'html' : 'plain'; + $radio = new html_radiobutton(array('name' => '_editorSelect', 'onclick' => 'return rcmail_toggle_editor(this)')); foreach ($choices as $value => $text) { $attrib['id'] = '_' . $value; $attrib['value'] = $value; - $rb = new html_radiobutton($attrib); - $selector .= sprintf("%s<label for=\"%s\">%s</label>", - $rb->show($chosenvalue), - $attrib['id'], - rcube_label($text)); + $selector .= $radio->show($chosenvalue, $attrib) . html::label($attrib['id'], Q(rcube_label($text))); } return $selector; diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc index ec594bcd1..cbad9875c 100644 --- a/program/steps/mail/func.inc +++ b/program/steps/mail/func.inc @@ -5,7 +5,7 @@ | program/steps/mail/func.inc | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland | + | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | @@ -54,11 +54,6 @@ if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search } -// define url for getting message parts -if (strlen($_GET['_uid'])) - $GET_URL = rcmail_url('get', array('_mbox'=>$IMAP->get_mailbox_name(), '_uid'=>get_input_value('_uid', RCUBE_INPUT_GET))); - - // set current mailbox in client environment $OUTPUT->set_env('mailbox', $IMAP->get_mailbox_name()); $OUTPUT->set_env('quota', $IMAP->get_capability('quota')); @@ -475,10 +470,10 @@ function rcmail_get_messagecount_text($count=NULL, $page=NULL) { global $IMAP, $MESSAGE; - if (isset($MESSAGE['index'])) + if (isset($MESSAGE->index)) { return rcube_label(array('name' => 'messagenrof', - 'vars' => array('nr' => $MESSAGE['index']+1, + 'vars' => array('nr' => $MESSAGE->index+1, 'count' => $count!==NULL ? $count : $IMAP->messagecount()))); } @@ -959,7 +954,7 @@ function rcmail_message_headers($attrib, $headers=NULL) // get associative array of headers object if (!$headers) - $headers = is_object($MESSAGE['headers']) ? get_object_vars($MESSAGE['headers']) : $MESSAGE['headers']; + $headers = is_object($MESSAGE->headers) ? get_object_vars($MESSAGE->headers) : $MESSAGE->headers; $header_count = 0; @@ -997,15 +992,15 @@ function rcmail_message_headers($attrib, $headers=NULL) function rcmail_message_body($attrib) { - global $CONFIG, $OUTPUT, $MESSAGE, $IMAP, $GET_URL, $REMOTE_OBJECTS; + global $CONFIG, $OUTPUT, $MESSAGE, $IMAP, $REMOTE_OBJECTS; - if (!is_array($MESSAGE['parts']) && !$MESSAGE['body']) + if (!is_array($MESSAGE->parts) && empty($MESSAGE->body)) return ''; if (!$attrib['id']) $attrib['id'] = 'rcmailMsgBody'; - $safe_mode = $MESSAGE['is_safe'] || intval($_GET['_safe']); + $safe_mode = $MESSAGE->is_safe || intval($_GET['_safe']); $attrib_str = create_attrib_string($attrib, array('style', 'class', 'id')); $out = '<div '. $attrib_str . ">\n"; @@ -1014,33 +1009,20 @@ function rcmail_message_body($attrib) if (preg_match('/^headertable([a-z]+)$/i', $attr, $regs)) $header_attrib[$regs[1]] = $value; - - // this is an ecrypted message - // -> create a plaintext body with the according message - if (!sizeof($MESSAGE['parts']) && $MESSAGE['headers']->ctype=='multipart/encrypted') - { - $p = new stdClass; - $p->type = 'content'; - $p->ctype_primary = 'text'; - $p->ctype_secondary = 'plain'; - $p->body = rcube_label('encryptedmessage'); - $MESSAGE['parts'][0] = $p; - } - - if ($MESSAGE['parts']) + if (!empty($MESSAGE->parts)) { - foreach ($MESSAGE['parts'] as $i => $part) + foreach ($MESSAGE->parts as $i => $part) { - if ($part->type=='headers') + if ($part->type == 'headers') $out .= rcmail_message_headers(sizeof($header_attrib) ? $header_attrib : NULL, $part->headers); - else if ($part->type=='content') + else if ($part->type == 'content') { if (empty($part->ctype_parameters) || empty($part->ctype_parameters['charset'])) - $part->ctype_parameters['charset'] = $MESSAGE['headers']->charset; + $part->ctype_parameters['charset'] = $MESSAGE->headers->charset; // fetch part if not available if (!isset($part->body)) - $part->body = $IMAP->get_message_part($MESSAGE['UID'], $part->mime_id, $part); + $part->body = $MESSAGE->get_part_content($part->mime_id); $body = rcmail_print_body($part, $safe_mode, !$CONFIG['prefer_html']); $out .= '<div class="message-part">'; @@ -1055,25 +1037,26 @@ function rcmail_message_body($attrib) } } else - $out .= $MESSAGE['body']; + $out .= $MESSAGE->body; - $ctype_primary = strtolower($MESSAGE['structure']->ctype_primary); - $ctype_secondary = strtolower($MESSAGE['structure']->ctype_secondary); + $ctype_primary = strtolower($MESSAGE->structure->ctype_primary); + $ctype_secondary = strtolower($MESSAGE->structure->ctype_secondary); // list images after mail body - if (get_boolean($attrib['showimages']) && $ctype_primary=='multipart' && - !empty($MESSAGE['attachments']) && !strstr($message_body, '<html') && strlen($GET_URL)) - { - foreach ($MESSAGE['attachments'] as $attach_prop) - { - if (strpos($attach_prop->mimetype, 'image/')===0) - $out .= sprintf("\n<hr />\n<p align=\"center\"><img src=\"%s&_part=%s\" alt=\"%s\" title=\"%s\" /></p>\n", - htmlspecialchars($GET_URL), $attach_prop->mime_id, - $attach_prop->filename, - $attach_prop->filename); - } + if (get_boolean($attrib['showimages']) && $ctype_primary == 'multipart' && + !empty($MESSAGE->attachments) && !strstr($message_body, '<html')) { + foreach ($MESSAGE->attachments as $attach_prop) { + if (strpos($attach_prop->mimetype, 'image/') === 0) { + $out .= html::tag('hr') . html::p(array('align' => "center"), + html::img(array( + 'src' => $MESSAGE->get_part_url($attach_prop->mime_id), + 'title' => $attach_prop->filename, + 'alt' => $attach_prop->filename, + ))); + } } + } // tell client that there are blocked remote objects if ($REMOTE_OBJECTS && !$safe_mode) @@ -1193,91 +1176,6 @@ function rcmail_alter_html_link($tag, $attrs, $container_id) } -function rcmail_has_html_part($message_parts) -{ - if (!is_array($message_parts)) - return FALSE; - - // check all message parts - foreach ($message_parts as $pid => $part) - { - $mimetype = strtolower($part->ctype_primary.'/'.$part->ctype_secondary); - if ($mimetype=='text/html') - { - return TRUE; - } - } - - return FALSE; -} - -// return first HTML part of a message -function rcmail_first_html_part($message_struct) - { - global $IMAP; - - if (!is_array($message_struct['parts'])) - return FALSE; - - $html_part = NULL; - - // check all message parts - foreach ($message_struct['parts'] as $pid => $part) - { - $mimetype = strtolower($part->ctype_primary.'/'.$part->ctype_secondary); - if ($mimetype=='text/html') - { - $html_part = $IMAP->get_message_part($message_struct['UID'], $pid, $part); - } - } - - if ($html_part) - { - // remove special chars encoding - //$trans = array_flip(get_html_translation_table(HTML_ENTITIES)); - //$html_part = strtr($html_part, $trans); - - return $html_part; - } - - return FALSE; -} - - -// return first text part of a message -function rcmail_first_text_part($message_struct) - { - global $IMAP; - - if (empty($message_struct['parts'])) - return $message_struct['UID'] ? $IMAP->get_body($message_struct['UID']) : false; - - // check all message parts - foreach ($message_struct['parts'] as $pid => $part) - { - $mimetype = strtolower($part->ctype_primary.'/'.$part->ctype_secondary); - - if ($mimetype=='text/plain') - return $IMAP->get_message_part($message_struct['UID'], $pid, $part); - - else if ($mimetype=='text/html') - { - $html_part = $IMAP->get_message_part($message_struct['UID'], $pid, $part); - - // remove special chars encoding - $trans = array_flip(get_html_translation_table(HTML_ENTITIES)); - $html_part = strtr($html_part, $trans); - - // create instance of html2text class - $txt = new html2text($html_part); - return $txt->get_text(); - } - } - - return FALSE; - } - - // decode address string and re-format it as HTML links function rcmail_address_string($input, $max=NULL, $addicon=NULL) { @@ -1338,33 +1236,27 @@ function rcmail_address_string($input, $max=NULL, $addicon=NULL) function rcmail_message_part_controls() { - global $CONFIG, $IMAP, $MESSAGE; + global $MESSAGE; $part = asciiwords(get_input_value('_part', RCUBE_INPUT_GPC)); - if (!is_array($MESSAGE) || !is_array($MESSAGE['parts']) || !($_GET['_uid'] && $_GET['_part']) || !$MESSAGE['parts'][$part]) + if (!is_object($MESSAGE) || !is_array($MESSAGE->parts) || !($_GET['_uid'] && $_GET['_part']) || !$MESSAGE->mime_parts[$part]) return ''; - $part = $MESSAGE['parts'][$part]; - $attrib_str = create_attrib_string($attrib, array('id', 'class', 'style', 'cellspacing', 'cellpadding', 'border', 'summary')); - $out = '<table '. $attrib_str . ">\n"; + $part = $MESSAGE->mime_parts[$part]; + $table = new html_table(array('cols' => 3)); - if ($part->filename) - { - $out .= sprintf('<tr><td class="title">%s</td><td>%s</td><td>[<a href="./?%s">%s</a>]</tr>'."\n", - Q(rcube_label('filename')), - Q($part->filename), - str_replace('_frame=', '_download=', $_SERVER['QUERY_STRING']), - Q(rcube_label('download'))); - } - - if ($part->size) - $out .= sprintf('<tr><td class="title">%s</td><td>%s</td></tr>'."\n", - Q(rcube_label('filesize')), - show_bytes($part->size)); + if (!empty($part->filename)) { + $table->add('title', Q(rcube_label('filename'))); + $table->add(null, Q($part->filename)); + $table->add(null, '[' . html::a(str_replace('_frame=', '_download=', $_SERVER['QUERY_STRING']), Q(rcube_label('download'))) . ']'); + } - $out .= "\n</table>"; + if (!empty($part->size)) { + $table->add('title', Q(rcube_label('filesize'))); + $table->add(null, Q(show_bytes($part->size))); + } - return $out; + return $table->show($attrib); } @@ -1373,7 +1265,7 @@ function rcmail_message_part_frame($attrib) { global $MESSAGE; - $part = $MESSAGE['parts'][asciiwords(get_input_value('_part', RCUBE_INPUT_GPC))]; + $part = $MESSAGE->mime_parts[asciiwords(get_input_value('_part', RCUBE_INPUT_GPC))]; $ctype_primary = strtolower($part->ctype_primary); $attrib['src'] = Q('./?'.str_replace('_frame=', ($ctype_primary=='text' ? '_show=' : '_preload='), $_SERVER['QUERY_STRING'])); @@ -1407,8 +1299,8 @@ function rcmail_deliver_message(&$message, $from, $mailto) { global $CONFIG; - $headers = $message->headers(); $msg_body = $message->get(); + $headers = $message->headers(); // send thru SMTP server using custom SMTP library if ($CONFIG['smtp_server']) @@ -1468,16 +1360,14 @@ function rcmail_deliver_message(&$message, $from, $mailto) function rcmail_send_mdn($uid) { global $CONFIG, $USER, $IMAP; + + $message = new rcube_message($uid); - $message = array('UID' => $uid); - $message['headers'] = $IMAP->get_headers($message['UID']); - $message['subject'] = $IMAP->decode_header($message['headers']->subject); - - if ($message['headers']->mdn_to && !$message['headers']->mdn_sent) + if ($message->headers->mdn_to && !$message->headers->mdn_sent) { $identity = $USER->get_identity(); $sender = format_email_recipient($identity['email'], $identity['name']); - $recipient = array_shift($IMAP->decode_address_list($message['headers']->mdn_to)); + $recipient = array_shift($IMAP->decode_address_list($message->headers->mdn_to)); $mailto = $recipient['mailto']; $compose = new rcube_mail_mime(rcmail_header_delm()); @@ -1494,8 +1384,8 @@ function rcmail_send_mdn($uid) $headers = array( 'Date' => date('r'), 'From' => $sender, - 'To' => $message['headers']->mdn_to, - 'Subject' => rcube_label('receiptread') . ': ' . $message['subject'], + 'To' => $message->headers->mdn_to, + 'Subject' => rcube_label('receiptread') . ': ' . $message->subject, 'Message-ID' => sprintf('<%s@%s>', md5(uniqid('rcmail'.rand(),true)), rcmail_mail_domain($_SESSION['imap_host'])), 'X-Sender' => $identity['email'], 'Content-Type' => 'multipart/report; report-type=disposition-notification', @@ -1505,30 +1395,30 @@ function rcmail_send_mdn($uid) $headers['User-Agent'] = $CONFIG['useragent']; $body = rcube_label("yourmessage") . "\r\n\r\n" . - "\t" . rcube_label("to") . ': ' . rcube_imap::decode_mime_string($message['headers']->to, $message['headers']->charset) . "\r\n" . - "\t" . rcube_label("subject") . ': ' . $message['subject'] . "\r\n" . - "\t" . rcube_label("sent") . ': ' . format_date($message['headers']->date, $CONFIG['date_long']) . "\r\n" . + "\t" . rcube_label("to") . ': ' . rcube_imap::decode_mime_string($message->headers->to, $message->headers->charset) . "\r\n" . + "\t" . rcube_label("subject") . ': ' . $message->subject . "\r\n" . + "\t" . rcube_label("sent") . ': ' . format_date($message->headers->date, $CONFIG['date_long']) . "\r\n" . "\r\n" . rcube_label("receiptnote") . "\r\n"; $ua = !empty($CONFIG['useragent']) ? $CONFIG['useragent'] : "RoundCube Webmail (Version ".RCMAIL_VERSION.")"; $report = "Reporting-UA: $ua\r\n"; - if ($message['headers']->to) - $report .= "Original-Recipient: {$message['headers']->to}\r\n"; + if ($message->headers->to) + $report .= "Original-Recipient: {$message->headers->to}\r\n"; $report .= "Final-Recipient: rfc822; {$identity['email']}\r\n" . - "Original-Message-ID: {$message['headers']->messageID}\r\n" . + "Original-Message-ID: {$message->headers->messageID}\r\n" . "Disposition: manual-action/MDN-sent-manually; displayed\r\n"; - $compose->headers($headers, true); - $compose->setTXTBody($body); + $compose->headers($headers); + $compose->setTXTBody(wordwrap($body, 75, "\r\n")); $compose->addAttachment($report, 'message/disposition-notification', 'MDNPart2.txt', false, '7bit', 'inline'); $sent = rcmail_deliver_message($compose, $identity['email'], $mailto); if ($sent) { - $IMAP->set_flag($message['UID'], 'MDNSENT'); + $IMAP->set_flag($message->uid, 'MDNSENT'); return true; } } diff --git a/program/steps/mail/get.inc b/program/steps/mail/get.inc index 06c22ec64..4d7895269 100644 --- a/program/steps/mail/get.inc +++ b/program/steps/mail/get.inc @@ -5,7 +5,7 @@ | program/steps/mail/get.inc | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland | + | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | | | | PURPOSE: | @@ -23,8 +23,7 @@ require_once('Mail/mimeDecode.php'); // show loading page -if ($_GET['_preload']) - { +if (!empty($_GET['_preload'])) { $url = str_replace('&_preload=1', '', $_SERVER['REQUEST_URI']); $message = rcube_label('loadingdata'); @@ -34,29 +33,24 @@ if ($_GET['_preload']) $message . "\n</body>\n</html>"; exit; - } +} // similar code as in program/steps/mail/show.inc -if ($_GET['_uid']) - { - $MESSAGE = array('UID' => get_input_value('_uid', RCUBE_INPUT_GET)); - $MESSAGE['structure'] = $IMAP->get_structure($MESSAGE['UID']); - $MESSAGE['parts'] = $IMAP->get_mime_numbers($MESSAGE['structure']); - } +if (!empty($_GET['_uid'])) { + $RCMAIL->config->set('prefer_html', true); + $MESSAGE = new rcube_message(get_input_value('_uid', RCUBE_INPUT_GET)); +} // show part page -if ($_GET['_frame']) - { +if (!empty($_GET['_frame'])) { $OUTPUT->send('messagepart'); exit; - } +} -else if ($pid = get_input_value('_part', RCUBE_INPUT_GET)) - { - if ($part = $MESSAGE['parts'][$pid]) - { +else if ($pid = get_input_value('_part', RCUBE_INPUT_GET)) { + if ($part = $MESSAGE->mime_parts[$pid]) { $ctype_primary = strtolower($part->ctype_primary); $ctype_secondary = strtolower($part->ctype_secondary); $mimetype = sprintf('%s/%s', $ctype_primary, $ctype_secondary); @@ -67,25 +61,23 @@ else if ($pid = get_input_value('_part', RCUBE_INPUT_GET)) header("Content-Transfer-Encoding: binary"); // send download headers - if ($_GET['_download']) - { + if ($_GET['_download']) { header("Cache-Control: private", false); header("Content-Type: application/octet-stream"); - } + } else header("Content-Type: $mimetype"); // We need to set the following headers to make downloads work using IE in HTTPS mode. - if (isset($_SERVER['HTTPS'])) - { + if (isset($_SERVER['HTTPS'])) { header('Pragma: '); header('Cache-Control: '); - } + } // deliver part content - if ($ctype_primary=='text' && $ctype_secondary=='html') - { + if ($ctype_primary == 'text' && $ctype_secondary == 'html') { // we have to analyze the whole structure again to find inline objects + /* what was this good for again ? list($new_parts, $new_attachments) = rcmail_parse_message($MESSAGE['structure'], array('safe' => intval($_GET['_safe']), @@ -96,43 +88,33 @@ else if ($pid = get_input_value('_part', RCUBE_INPUT_GET)) for ($partix = 0; $partix < sizeof($all_parts); $partix++) if ($all_parts[$partix]->mime_id == $pid) $part = &$all_parts[$partix]; + */ // get part body if not available if (!$part->body) - $part->body = $IMAP->get_message_part($MESSAGE['UID'], $part->mime_id, $part); + $part->body = $MESSAGE->get_part_content($part->mime_id); $OUTPUT = new rcube_html_page(); - $OUTPUT->write(rcmail_print_body($part, intval($_GET['_safe']))); - } - else - { + $OUTPUT->write(rcmail_print_body($part, $MESSAGE->is_safe)); + } + else { header(sprintf('Content-Disposition: %s; filename="%s";', $_GET['_download'] ? 'attachment' : 'inline', $part->filename ? abbreviate_string($part->filename, 55) : "roundcube.$ctype_secondary")); // turn off output buffering and print part content - $IMAP->get_message_part($MESSAGE['UID'], $part->mime_id, $part, true); - } + $IMAP->get_message_part($MESSAGE->uid, $part->mime_id, $part, true); + } exit; - } } +} // print message -else - { - $ctype_primary = strtolower($MESSAGE['structure']->ctype_primary); - $ctype_secondary = strtolower($MESSAGE['structure']->ctype_secondary); - $mimetype = sprintf('%s/%s', $ctype_primary, $ctype_secondary); - +else { // send correct headers for content type header("Content-Type: text/html"); - $cont = ''; - list($MESSAGE['parts']) = rcmail_parse_message($MESSAGE['structure'], - array('safe' => intval($_GET['_safe']), - 'get_url' => $GET_URL.'&_part=%s')); - $cont = "<html>\n<head><title></title>\n</head>\n<body>"; $cont .= rcmail_message_body(array()); $cont .= "\n</body>\n</html>"; @@ -141,7 +123,7 @@ else $OUTPUT->write($cont); exit; - } +} // if we arrive here, the requested part was not found diff --git a/program/steps/mail/show.inc b/program/steps/mail/show.inc index daf2e0859..09849734e 100644 --- a/program/steps/mail/show.inc +++ b/program/steps/mail/show.inc @@ -22,79 +22,59 @@ $PRINT_MODE = $RCMAIL->action=='print' ? TRUE : FALSE; // similar code as in program/steps/mail/get.inc -if ($_GET['_uid']) - { - $MESSAGE = array('UID' => get_input_value('_uid', RCUBE_INPUT_GET)); - $MESSAGE['headers'] = $IMAP->get_headers($MESSAGE['UID']); +if ($_GET['_uid']) { + $MESSAGE = new rcube_message(get_input_value('_uid', RCUBE_INPUT_GET)); // set message charset as default - if (!empty($MESSAGE['headers']->charset)) - $IMAP->set_charset($MESSAGE['headers']->charset); + if (!empty($MESSAGE->headers->charset)) + $IMAP->set_charset($MESSAGE->headers->charset); // go back to list if message not found (wrong UID) - if (!$MESSAGE['headers']) - { + if (empty($MESSAGE->headers)) { $OUTPUT->show_message('messageopenerror', 'error'); if ($RCMAIL->action=='preview' && template_exists('messagepreview')) $OUTPUT->send('messagepreview'); - else - { + else { $RCMAIL->action = 'list'; return; - } } + } - // check if safe flag is set - if ($MESSAGE['is_safe'] = intval($_GET['_safe'])) - $_SESSION['safe_messages'][$MESSAGE['UID']] = true; - else if ($_SESSION['safe_messages'][$MESSAGE['UID']]) - $MESSAGE['is_safe'] = 1; - $mbox_name = $IMAP->get_mailbox_name(); // calculate Etag for this request - $etag = md5($MESSAGE['UID'].$mbox_name.session_id().intval($MESSAGE['headers']->mdn_sent).intval($MESSAGE['is_safe']).intval($PRINT_MODE)); + $etag = md5($MESSAGE->uid.$mbox_name.session_id().intval($MESSAGE->headers->mdn_sent).intval($MESSAGE->is_safe).intval($PRINT_MODE)); // allow caching, unless remote images are present - if ((bool)$MESSAGE['is_safe']) + if ((bool)$MESSAGE->is_safe) send_nocacheing_headers(); else if (empty($CONFIG['devel_mode'])) - send_modified_header($_SESSION['login_time'], $etag, !$MESSAGE['headers']->seen); + send_modified_header($_SESSION['login_time'], $etag, !$MESSAGE->headers->seen); - $MESSAGE['subject'] = $IMAP->decode_header($MESSAGE['headers']->subject); - $OUTPUT->set_pagetitle($MESSAGE['subject']); + $OUTPUT->set_pagetitle($MESSAGE->subject); - if ($MESSAGE['structure'] = $IMAP->get_structure($MESSAGE['UID'])) - list($MESSAGE['parts'], $MESSAGE['attachments']) = rcmail_parse_message( - $MESSAGE['structure'], - array('safe' => $MESSAGE['is_safe'], - 'prefer_html' => $CONFIG['prefer_html'], - 'get_url' => $GET_URL.'&_part=%s') - ); - else - $MESSAGE['body'] = $IMAP->get_body($MESSAGE['UID']); - // mark message as read - if (!$MESSAGE['headers']->seen) + if (!$MESSAGE->headers->seen) { - $marked = $IMAP->set_flag($MESSAGE['UID'], 'SEEN'); + $marked = $IMAP->set_flag($MESSAGE->uid, 'SEEN'); if($RCMAIL->action == 'preview' && $marked != -1) { $OUTPUT->command('set_unread_count_from_preview', $mbox_name, $IMAP->messagecount($mbox_name, 'UNSEEN'), ($mbox_name == 'INBOX')); - $OUTPUT->command('mark_as_read_from_preview', $MESSAGE['UID']); + $OUTPUT->command('mark_as_read_from_preview', $MESSAGE->uid); } } // give message uid to the client - $OUTPUT->set_env('uid', $MESSAGE['UID']); - $OUTPUT->set_env('safemode', $MESSAGE['is_safe']); + $OUTPUT->set_env('uid', $MESSAGE->uid); + $OUTPUT->set_env('safemode', $MESSAGE->is_safe); // check for unset disposition notification - if ($MESSAGE['headers']->mdn_to && !$MESSAGE['headers']->mdn_sent && $mbox_name != $CONFIG['drafts_mbox']) + if ($MESSAGE->headers->mdn_to && !$MESSAGE->headers->mdn_sent && + $mbox_name != $CONFIG['drafts_mbox'] && $mbox_name != $CONFIG['sent_mbox']) { if (intval($CONFIG['mdn_requests']) === 1) { - if (rcmail_send_mdn($MESSAGE['UID'])) + if (rcmail_send_mdn($MESSAGE->uid)) $OUTPUT->show_message('receiptsent', 'confirmation'); } else if (empty($CONFIG['mdn_requests'])) @@ -113,21 +93,21 @@ if ($_GET['_uid']) // Only if we use custom sorting $a_msg_index = $IMAP->message_index(NULL, $_SESSION['sort_col'], $_SESSION['sort_order']); - $MESSAGE['index'] = array_search((string)$MESSAGE['UID'], $a_msg_index, TRUE); - $prev = isset($a_msg_index[$MESSAGE['index']-1]) ? $a_msg_index[$MESSAGE['index']-1] : -1 ; + $MESSAGE->index = array_search((string)$MESSAGE->uid, $a_msg_index, TRUE); + $prev = isset($a_msg_index[$MESSAGE->index-1]) ? $a_msg_index[$MESSAGE->index-1] : -1 ; $first = count($a_msg_index)>0 ? $a_msg_index[0] : -1; - $next = isset($a_msg_index[$MESSAGE['index']+1]) ? $a_msg_index[$MESSAGE['index']+1] : -1 ; + $next = isset($a_msg_index[$MESSAGE->index+1]) ? $a_msg_index[$MESSAGE->index+1] : -1 ; $last = count($a_msg_index)>0 ? $a_msg_index[count($a_msg_index)-1] : -1; } else { // this assumes that we are sorted by date_DESC - $seq = $IMAP->get_id($MESSAGE['UID']); + $seq = $IMAP->get_id($MESSAGE->uid); $prev = $IMAP->get_uid($seq + 1); $first = $IMAP->get_uid($IMAP->messagecount()); $next = $IMAP->get_uid($seq - 1); $last = $IMAP->get_uid(1); - $MESSAGE['index'] = $IMAP->messagecount() - $seq; + $MESSAGE->index = $IMAP->messagecount() - $seq; } if ($prev > 0) @@ -143,35 +123,35 @@ if ($_GET['_uid']) function rcmail_message_attachments($attrib) - { - global $CONFIG, $OUTPUT, $PRINT_MODE, $MESSAGE, $GET_URL; +{ + global $PRINT_MODE, $MESSAGE; + + $out = $ol = ''; - if (sizeof($MESSAGE['attachments'])) - { - // allow the following attributes to be added to the <ul> tag - $attrib_str = create_attrib_string($attrib, array('style', 'class', 'id')); - $out = '<ul' . $attrib_str . ">\n"; - - foreach ($MESSAGE['attachments'] as $attach_prop) - { - if ($PRINT_MODE) - $out .= sprintf('<li>%s (%s)</li>'."\n", - $attach_prop->filename, - show_bytes($attach_prop->size)); - else - $out .= sprintf('<li><a href="%s&_part=%s" onclick="return %s.command(\'load-attachment\',{part:\'%s\', mimetype:\'%s\'},this)">%s</a></li>'."\n", - htmlspecialchars($GET_URL), - $attach_prop->mime_id, - JS_OBJECT_NAME, - $attach_prop->mime_id, - $attach_prop->mimetype, - $attach_prop->filename); + if (sizeof($MESSAGE->attachments)) { + foreach ($MESSAGE->attachments as $attach_prop) { + if ($PRINT_MODE) { + $ol .= html::tag('li', null, sprintf("%s (%s)", Q($attach_prop->filename), Q(show_bytes($attach_prop->size)))); } + else { + $ol .= html::tag('li', null, + html::a(array( + 'href' => $MESSAGE->get_part_url($attach_prop->mime_id), + 'onclick' => sprintf( + 'return %s.command(\'load-attachment\',{part:\'%s\', mimetype:\'%s\'},this)', + JS_OBJECT_NAME, + $attach_prop->mime_id, + $attach_prop->mimetype), + ), + Q($attach_prop->filename))); + } + } - $out .= "</ul>"; - return $out; - } - } + $out = html::tag('ul', $attrib, $ol, html::$common_attrib); + } + + return $out; +} |