| | |
| | | $OUTPUT->set_env('delimiter', $delimiter); |
| | | $OUTPUT->set_env('threading', $threading); |
| | | $OUTPUT->set_env('threads', $threading || $RCMAIL->storage->get_capability('THREAD')); |
| | | $OUTPUT->set_env('reply_all_mode', (int) $RCMAIL->config->get('reply_all_mode')); |
| | | $OUTPUT->set_env('preview_pane_mark_read', $RCMAIL->config->get('preview_pane_mark_read', 0)); |
| | | if ($RCMAIL->storage->get_capability('QUOTA')) { |
| | | $OUTPUT->set_env('quota', true); |
| | |
| | | if (!$OUTPUT->ajax_call) |
| | | $OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash', |
| | | 'movingmessage', 'copyingmessage', 'deletingmessage', 'markingmessage', |
| | | 'copy', 'move', 'quota'); |
| | | 'copy', 'move', 'quota', 'replyall', 'replylist', 'importwait'); |
| | | |
| | | $pagetitle = $RCMAIL->localize_foldername($RCMAIL->storage->mod_folder($mbox_name), true); |
| | | $pagetitle = str_replace($delimiter, " \xC2\xBB ", $pagetitle); |
| | | |
| | | $OUTPUT->set_pagetitle($pagetitle); |
| | | } |
| | | |
| | | // register UI objects |
| | | $OUTPUT->add_handlers(array( |
| | | 'mailboxlist' => 'rcmail_mailbox_list', |
| | | 'messages' => 'rcmail_message_list', |
| | | 'messagecountdisplay' => 'rcmail_messagecount_display', |
| | | 'quotadisplay' => 'rcmail_quota_display', |
| | | 'mailboxname' => 'rcmail_mailbox_name_display', |
| | | 'messageheaders' => 'rcmail_message_headers', |
| | | 'messagefullheaders' => 'rcmail_message_full_headers', |
| | | 'messagebody' => 'rcmail_message_body', |
| | | 'messagecontentframe' => 'rcmail_messagecontent_frame', |
| | | 'messageimportform' => 'rcmail_message_import_form', |
| | | 'searchfilter' => 'rcmail_search_filter', |
| | | 'searchform' => array($OUTPUT, 'search_form'), |
| | | )); |
| | | |
| | | // register action aliases |
| | | $RCMAIL->register_action_map(array( |
| | | 'refresh' => 'check_recent.inc', |
| | | 'preview' => 'show.inc', |
| | | 'print' => 'show.inc', |
| | | 'move' => 'move_del.inc', |
| | | 'delete' => 'move_del.inc', |
| | | 'send' => 'sendmail.inc', |
| | | 'expunge' => 'folders.inc', |
| | | 'purge' => 'folders.inc', |
| | | 'remove-attachment' => 'attachments.inc', |
| | | 'display-attachment' => 'attachments.inc', |
| | | 'upload' => 'attachments.inc', |
| | | 'group-expand' => 'autocomplete.inc', |
| | | )); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns 'to' if current folder is configured Sent or Drafts |
| | |
| | | $sent_mbox = $RCMAIL->config->get('sent_mbox'); |
| | | $drafts_mbox = $RCMAIL->config->get('drafts_mbox'); |
| | | |
| | | if (strpos($mbox.$delim, $sent_mbox.$delim) === 0 || strpos($mbox.$delim, $drafts_mbox.$delim) === 0) { |
| | | if ((strpos($mbox.$delim, $sent_mbox.$delim) === 0 || strpos($mbox.$delim, $drafts_mbox.$delim) === 0) |
| | | && strtoupper($mbox) != 'INBOX' |
| | | ) { |
| | | return 'to'; |
| | | } |
| | | |
| | |
| | | $message->set_safe(true); |
| | | } |
| | | } |
| | | |
| | | $RCMAIL->plugins->exec_hook('message_check_safe', array('message' => $message)); |
| | | break; |
| | | |
| | | case 2: // always |
| | |
| | | $value = $headers[$hkey]; |
| | | else if ($headers['others'][$hkey]) |
| | | $value = $headers['others'][$hkey]; |
| | | else |
| | | else if (!$attrib['valueof']) |
| | | continue; |
| | | |
| | | if (in_array($hkey, $exclude_headers)) |
| | |
| | | { |
| | | global $RCMAIL; |
| | | |
| | | // Support unicode/punycode in top-level domain part |
| | | $EMAIL_PATTERN = '([a-z0-9][a-z0-9\-\.\+\_]*@[^&@"\'.][^@&"\']*\\.([^\\x00-\\x40\\x5b-\\x60\\x7b-\\x7f]{2,}|xn--[a-z0-9]{2,}))'; |
| | | |
| | | $tag = strtolower($matches[1]); |
| | | $attrib = parse_attrib_string($matches[2]); |
| | | $end = '>'; |
| | |
| | | $attrib['href'] = $RCMAIL->url(array('task' => 'utils', 'action' => 'modcss', 'u' => $tempurl, 'c' => $GLOBALS['rcmail_html_container_id'])); |
| | | $end = ' />'; |
| | | } |
| | | else if (preg_match('/^mailto:'.$EMAIL_PATTERN.'(\?[^"\'>]+)?/i', $attrib['href'], $mailto)) { |
| | | $attrib['href'] = $mailto[0]; |
| | | $attrib['onclick'] = sprintf( |
| | | "return %s.command('compose','%s',this)", |
| | | JS_OBJECT_NAME, |
| | | JQ($mailto[1].$mailto[3])); |
| | | else if (preg_match('/^mailto:(.+)/i', $attrib['href'], $mailto)) { |
| | | list($mailto, $url) = explode('?', html_entity_decode($mailto[1], ENT_QUOTES, 'UTF-8'), 2); |
| | | |
| | | $url = urldecode($url); |
| | | $mailto = urldecode($mailto); |
| | | $addresses = rcube_mime::decode_address_list($mailto, null, true); |
| | | $mailto = array(); |
| | | |
| | | // do sanity checks on recipients |
| | | foreach ($addresses as $idx => $addr) { |
| | | if (rcube_utils::check_email($addr['mailto'], false)) { |
| | | $addresses[$idx] = $addr['mailto']; |
| | | $mailto[] = $addr['string']; |
| | | } |
| | | else { |
| | | unset($addresses[$idx]); |
| | | } |
| | | } |
| | | |
| | | if (!empty($addresses)) { |
| | | $attrib['href'] = 'mailto:' . implode(',', $addresses); |
| | | $attrib['onclick'] = sprintf( |
| | | "return %s.command('compose','%s',this)", |
| | | JS_OBJECT_NAME, |
| | | JQ(implode(',', $mailto) . ($url ? "?$url" : ''))); |
| | | } |
| | | else { |
| | | $attrib['href'] = '#NOP'; |
| | | $attrib['onclick'] = ''; |
| | | } |
| | | } |
| | | else if (empty($attrib['href']) && !$attrib['name']) { |
| | | $attrib['href'] = './#NOP'; |
| | |
| | | $mailto = rcube_idn_to_utf8($mailto); |
| | | |
| | | if ($PRINT_MODE) { |
| | | $out .= ($out ? ', ' : '') . sprintf('%s <%s>', Q($name), $mailto); |
| | | // for printing we display all addresses |
| | | continue; |
| | | $address = sprintf('%s <%s>', Q($name), Q($mailto)); |
| | | } |
| | | else if ($valid) { |
| | | if ($linked) { |
| | | $attrs = array( |
| | | 'href' => 'mailto:' . $mailto, |
| | | 'onclick' => sprintf("return %s.command('compose','%s',this)", JS_OBJECT_NAME, JQ($mailto)), |
| | | 'onclick' => sprintf("return %s.command('compose','%s',this)", JS_OBJECT_NAME, JQ(format_email_recipient($mailto, $name))), |
| | | 'class' => "rcmContactAddress", |
| | | ); |
| | | |
| | |
| | | } |
| | | |
| | | if ($moreadrs) { |
| | | if ($PRINT_MODE) { |
| | | $out .= ' ' . html::a(array( |
| | | 'href' => '#more', |
| | | 'class' => 'morelink', |
| | | 'onclick' => '$(this).hide().next().show()', |
| | | ), Q(rcube_label(array('name' => 'andnmore', 'vars' => array('nr' => $moreadrs))))) . |
| | | html::span(array('style' => 'display:none'), join(', ', $allvalues)); |
| | | } |
| | | else { |
| | | $out .= ' ' . html::a(array( |
| | | 'href' => '#more', |
| | | 'class' => 'morelink', |
| | |
| | | JQ($title)) |
| | | ), |
| | | Q(rcube_label(array('name' => 'andnmore', 'vars' => array('nr' => $moreadrs))))); |
| | | } |
| | | } |
| | | |
| | | return $out; |
| | |
| | | /** |
| | | * Wrap text to a given number of characters per line |
| | | * but respect the mail quotation of replies messages (>). |
| | | * Finally add another quotation level by prpending the lines |
| | | * Finally add another quotation level by prepending the lines |
| | | * with > |
| | | * |
| | | * @param string Text to wrap |
| | | * @param int The line width |
| | | * @param int The line width |
| | | * @return string The wrapped text |
| | | */ |
| | | function rcmail_wrap_and_quote($text, $length = 72) |
| | |
| | | $line = '>' . rtrim($line); |
| | | else if (mb_strlen($line) > $max) { |
| | | $newline = ''; |
| | | foreach(explode("\n", rc_wordwrap($line, $length - 2)) as $l) { |
| | | foreach (explode("\n", rc_wordwrap($line, $length - 2)) as $l) { |
| | | if (strlen($l)) |
| | | $newline .= '> ' . $l . "\n"; |
| | | else |
| | |
| | | } |
| | | |
| | | return $info; |
| | | } |
| | | |
| | | |
| | | function rcmail_message_part_controls($attrib) |
| | | { |
| | | global $MESSAGE, $RCMAIL; |
| | | |
| | | $part = asciiwords(get_input_value('_part', RCUBE_INPUT_GPC)); |
| | | if (!is_object($MESSAGE) || !is_array($MESSAGE->parts) || !($_GET['_uid'] && $_GET['_part']) || !$MESSAGE->mime_parts[$part]) |
| | | return ''; |
| | | |
| | | $part = $MESSAGE->mime_parts[$part]; |
| | | $table = new html_table(array('cols' => 3)); |
| | | |
| | | $filename = rcmail_attachment_name($part); |
| | | |
| | | if (!empty($filename)) { |
| | | $table->add('title', Q(rcube_label('filename'))); |
| | | $table->add('header', Q($filename)); |
| | | $table->add('download-link', html::a(array('href' => './?'.str_replace('_frame=', '_download=', $_SERVER['QUERY_STRING'])), Q(rcube_label('download')))); |
| | | } |
| | | |
| | | $table->add('title', Q(rcube_label('filesize'))); |
| | | $table->add('header', Q($RCMAIL->message_part_size($part))); |
| | | |
| | | return $table->show($attrib); |
| | | } |
| | | |
| | | |
| | | function rcmail_message_part_frame($attrib) |
| | | { |
| | | global $MESSAGE; |
| | | |
| | | $part = $MESSAGE->mime_parts[asciiwords(get_input_value('_part', RCUBE_INPUT_GPC))]; |
| | | $ctype_primary = strtolower($part->ctype_primary); |
| | | |
| | | $attrib['src'] = './?' . str_replace('_frame=', ($ctype_primary=='text' ? '_embed=' : '_preload='), $_SERVER['QUERY_STRING']); |
| | | |
| | | return html::iframe($attrib); |
| | | } |
| | | |
| | | |
| | |
| | | $a_to = rcube_mime::decode_address_list($MESSAGE->headers->to, null, true, $MESSAGE->headers->charset); |
| | | foreach ($a_to as $addr) { |
| | | if (!empty($addr['mailto'])) { |
| | | $a_recipients[] = format_email($addr['mailto']); |
| | | $a_recipients[] = strtolower($addr['mailto']); |
| | | $a_names[] = $addr['name']; |
| | | } |
| | | } |
| | |
| | | $a_cc = rcube_mime::decode_address_list($MESSAGE->headers->cc, null, true, $MESSAGE->headers->charset); |
| | | foreach ($a_cc as $addr) { |
| | | if (!empty($addr['mailto'])) { |
| | | $a_recipients[] = format_email($addr['mailto']); |
| | | $a_recipients[] = strtolower($addr['mailto']); |
| | | $a_names[] = $addr['name']; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | $from_idx = null; |
| | | $found_idx = null; |
| | | $default_identity = 0; // default identity is always first on the list |
| | | // decode From: address |
| | | $from = rcube_mime::decode_address_list($MESSAGE->headers->from, null, true, $MESSAGE->headers->charset); |
| | | $from = array_shift($from); |
| | | $from['mailto'] = strtolower($from['mailto']); |
| | | |
| | | $from_idx = null; |
| | | $found_idx = array('to' => null, 'from' => null); |
| | | $check_from = in_array($compose_mode, array('draft', 'edit', 'reply')); |
| | | |
| | | // Select identity |
| | | foreach ($identities as $idx => $ident) { |
| | | // use From header |
| | | if (in_array($compose_mode, array('draft', 'edit'))) { |
| | | if ($MESSAGE->headers->from == $ident['ident']) { |
| | | // use From: header when in edit/draft or reply-to-self |
| | | if ($check_from && $from['mailto'] == strtolower($ident['email_ascii'])) { |
| | | // remember first matching identity address |
| | | if ($found_idx['from'] === null) { |
| | | $found_idx['from'] = $idx; |
| | | } |
| | | // match identity name |
| | | if ($from['name'] && $ident['name'] && $from['name'] == $ident['name']) { |
| | | $from_idx = $idx; |
| | | break; |
| | | } |
| | | } |
| | | // reply to yourself |
| | | else if ($compose_mode == 'reply' && $MESSAGE->headers->from == $ident['ident']) { |
| | | $from_idx = $idx; |
| | | break; |
| | | } |
| | | // use replied message recipients |
| | | else if (($found = array_search($ident['email_ascii'], $a_recipients)) !== false) { |
| | | if ($found_idx === null) { |
| | | $found_idx = $idx; |
| | | // use replied/forwarded message recipients |
| | | else if (($found = array_search(strtolower($ident['email_ascii']), $a_recipients)) !== false) { |
| | | // remember first matching identity address |
| | | if ($found_idx['to'] === null) { |
| | | $found_idx['to'] = $idx; |
| | | } |
| | | // match identity name |
| | | if ($a_names[$found] && $ident['name'] && $a_names[$found] == $ident['name']) { |
| | |
| | | } |
| | | } |
| | | |
| | | // If matching by name+address doesn't found any matches, get first found address (identity) |
| | | // If matching by name+address didn't find any matches, |
| | | // get first found identity (address) if any |
| | | if ($from_idx === null) { |
| | | $from_idx = $found_idx; |
| | | $from_idx = $found_idx['from'] !== null ? $found_idx['from'] : $found_idx['to']; |
| | | } |
| | | |
| | | // Try Return-Path |
| | | if ($from_idx === null && ($return_path = $MESSAGE->headers->others['return-path'])) { |
| | | $return_path = array_map('strtolower', (array) $return_path); |
| | | |
| | | foreach ($identities as $idx => $ident) { |
| | | if (strpos($return_path, str_replace('@', '=', $ident['email_ascii']).'@') !== false) { |
| | | $from_idx = $idx; |
| | | break; |
| | | // Return-Path header contains an email address, but on some mailing list |
| | | // it can be e.g. <pear-dev-return-55250-local=domain.tld@lists.php.net> |
| | | // where local@domain.tld is the address we're looking for (#1489241) |
| | | $ident1 = strtolower($ident['email_ascii']); |
| | | $ident2 = str_replace('@', '=', $ident1); |
| | | $ident1 = '<' . $ident1 . '>'; |
| | | $ident2 = '-' . $ident2 . '@'; |
| | | |
| | | foreach ($return_path as $path) { |
| | | if ($path == $ident1 || stripos($path, $ident2)) { |
| | | $from_idx = $idx; |
| | | break 2; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Fallback using Delivered-To |
| | | if ($from_idx === null && ($delivered_to = $MESSAGE->headers->others['delivered-to'])) { |
| | | foreach ($identities as $idx => $ident) { |
| | | if (in_array($ident['email_ascii'], (array)$delivered_to)) { |
| | | $from_idx = $idx; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | // See identity_select plugin for example usage of this hook |
| | | $plugin = rcmail::get_instance()->plugins->exec_hook('identity_select', |
| | | array('message' => $MESSAGE, 'identities' => $identities, 'selected' => $from_idx)); |
| | | |
| | | // Fallback using Envelope-To |
| | | if ($from_idx === null && ($envelope_to = $MESSAGE->headers->others['envelope-to'])) { |
| | | foreach ($identities as $idx => $ident) { |
| | | if (in_array($ident['email_ascii'], (array)$envelope_to)) { |
| | | $from_idx = $idx; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | $selected = $plugin['selected']; |
| | | |
| | | return $identities[$from_idx !== null ? $from_idx : $default_identity]; |
| | | // default identity is always first on the list |
| | | return $identities[$selected !== null ? $selected : 0]; |
| | | } |
| | | |
| | | // Fixes some content-type names |
| | |
| | | $RCMAIL->output->send('messageerror'); |
| | | } |
| | | |
| | | // register UI objects |
| | | $OUTPUT->add_handlers(array( |
| | | 'mailboxlist' => 'rcmail_mailbox_list', |
| | | 'messages' => 'rcmail_message_list', |
| | | 'messagecountdisplay' => 'rcmail_messagecount_display', |
| | | 'quotadisplay' => 'rcmail_quota_display', |
| | | 'mailboxname' => 'rcmail_mailbox_name_display', |
| | | 'messageheaders' => 'rcmail_message_headers', |
| | | 'messagefullheaders' => 'rcmail_message_full_headers', |
| | | 'messagebody' => 'rcmail_message_body', |
| | | 'messagecontentframe' => 'rcmail_messagecontent_frame', |
| | | 'messagepartframe' => 'rcmail_message_part_frame', |
| | | 'messagepartcontrols' => 'rcmail_message_part_controls', |
| | | 'searchfilter' => 'rcmail_search_filter', |
| | | 'searchform' => array($OUTPUT, 'search_form'), |
| | | )); |
| | | function rcmail_message_import_form($attrib = array()) |
| | | { |
| | | global $OUTPUT; |
| | | |
| | | // register action aliases |
| | | $RCMAIL->register_action_map(array( |
| | | 'refresh' => 'check_recent.inc', |
| | | 'preview' => 'show.inc', |
| | | 'print' => 'show.inc', |
| | | 'moveto' => 'move_del.inc', |
| | | 'delete' => 'move_del.inc', |
| | | 'send' => 'sendmail.inc', |
| | | 'expunge' => 'folders.inc', |
| | | 'purge' => 'folders.inc', |
| | | 'remove-attachment' => 'attachments.inc', |
| | | 'display-attachment' => 'attachments.inc', |
| | | 'upload' => 'attachments.inc', |
| | | 'group-expand' => 'autocomplete.inc', |
| | | )); |
| | | // set defaults |
| | | $attrib += array('id' => 'rcmImportform', 'buttons' => 'yes'); |
| | | |
| | | // Get filesize, enable upload progress bar |
| | | $max_filesize = rcube_upload_init(); |
| | | |
| | | $button = new html_inputfield(array('type' => 'button')); |
| | | $fileinput = new html_inputfield(array( |
| | | 'type' => 'file', |
| | | 'name' => '_file[]', |
| | | 'multiple' => 'multiple', |
| | | 'accept' => ".eml, .mbox, message/rfc822, text/*", |
| | | )); |
| | | |
| | | $out = html::div($attrib, |
| | | $OUTPUT->form_tag(array('id' => $attrib['id'].'Frm', 'method' => 'post', 'enctype' => 'multipart/form-data'), |
| | | html::tag('input', array('type' => 'hidden', 'name' => '_unlock', 'value' => '')) . |
| | | html::div(null, $fileinput->show()) . |
| | | html::div('hint', rcube_label(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize)))) . |
| | | (get_boolean($attrib['buttons']) ? html::div('buttons', |
| | | $button->show(rcube_label('close'), array('class' => 'button', 'onclick' => "$('#$attrib[id]').hide()")) . ' ' . |
| | | $button->show(rcube_label('upload'), array('class' => 'button mainaction', 'onclick' => JS_OBJECT_NAME . ".command('import-messages', this.form)")) |
| | | ) : '') |
| | | ) |
| | | ); |
| | | |
| | | $OUTPUT->add_gui_object('importform', $attrib['id'].'Frm'); |
| | | return $out; |
| | | } |