Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F224593
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
45 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/program/include/rcube_shared.inc b/program/include/rcube_shared.inc
index e740aeaa3..af5eb1fda 100644
--- a/program/include/rcube_shared.inc
+++ b/program/include/rcube_shared.inc
@@ -1,590 +1,590 @@
<?php
/*
+-----------------------------------------------------------------------+
| rcube_shared.inc |
| |
| This file is part of the RoundCube PHP suite |
| Copyright (C) 2005-2007, RoundCube Dev. - Switzerland |
| Licensed under the GNU GPL |
| |
| CONTENTS: |
| Shared functions and classes used in PHP projects |
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
$Id$
*/
/**
* RoundCube shared functions
*
* @package Core
*/
/**
* Send HTTP headers to prevent caching this page
*/
function send_nocacheing_headers()
{
if (headers_sent())
return;
header("Expires: ".gmdate("D, d M Y H:i:s")." GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: private, no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
header("Pragma: no-cache");
// We need to set the following headers to make downloads work using IE in HTTPS mode.
if (isset($_SERVER['HTTPS'])) {
header('Pragma: ');
header('Cache-Control: ');
}
}
/**
* Send header with expire date 30 days in future
*
* @param int Expiration time in seconds
*/
function send_future_expire_header($offset=2600000)
{
if (headers_sent())
return;
header("Expires: ".gmdate("D, d M Y H:i:s", mktime()+$offset)." GMT");
header("Cache-Control: max-age=$offset");
header("Pragma: ");
}
/**
* Check request for If-Modified-Since and send an according response.
* This will terminate the current script if headers match the given values
*
* @param int Modified date as unix timestamp
* @param string Etag value for caching
*/
function send_modified_header($mdate, $etag=null, $skip_check=false)
{
if (headers_sent())
return;
$iscached = false;
$etag = $etag ? "\"$etag\"" : null;
if (!$skip_check)
{
if ($_SERVER['HTTP_IF_MODIFIED_SINCE'] && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $mdate)
$iscached = true;
if ($etag)
$iscached = ($_SERVER['HTTP_IF_NONE_MATCH'] == $etag);
}
if ($iscached)
header("HTTP/1.x 304 Not Modified");
else
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $mdate)." GMT");
header("Cache-Control: max-age=0");
header("Expires: ");
header("Pragma: ");
if ($etag)
header("Etag: $etag");
if ($iscached)
{
ob_end_clean();
exit;
}
}
/**
* Returns whether an $str is a reserved word for any of the version of Javascript or ECMAScript
* @param str String to check
* @return boolean True if $str is a reserver word, False if not
*/
function is_js_reserved_word($str)
{
return in_array($str, array(
// ECMASript ver 4 reserved words
'as','break','case','catch','class','const','continue',
'default','delete','do','else','export','extends','false','finally','for','function',
'if','import','in','instanceof','is','namespace','new','null','package','private',
'public','return','super','switch','this','throw','true','try','typeof','use','var',
'void','while','with',
// ECMAScript ver 4 future reserved words
'abstract','debugger','enum','goto','implements','interface','native','protected',
'synchronized','throws','transient','volatile',
// special meaning in some contexts
'get','set',
// were reserved in ECMAScript ver 3
'boolean','byte','char','double','final','float','int','long','short','static'
));
}
/**
* Convert a variable into a javascript object notation
*
* @param mixed Input value
* @return string Serialized JSON string
*/
function json_serialize($var)
{
if (is_object($var))
$var = get_object_vars($var);
if (is_array($var))
{
// empty array
if (!sizeof($var))
return '[]';
else
{
$keys_arr = array_keys($var);
$is_assoc = $have_numeric = 0;
for ($i=0; $i<sizeof($keys_arr); ++$i)
{
if (is_numeric($keys_arr[$i]))
$have_numeric = 1;
if (!is_numeric($keys_arr[$i]) || $keys_arr[$i] != $i)
$is_assoc = 1;
if ($is_assoc && $have_numeric)
break;
}
$brackets = $is_assoc ? '{}' : '[]';
$pairs = array();
foreach ($var as $key => $value)
{
// enclose key with quotes if it is not variable-name conform
if (!ereg("^[_a-zA-Z]{1}[_a-zA-Z0-9]*$", $key) || is_js_reserved_word($key))
$key = "'$key'";
$pairs[] = sprintf("%s%s", $is_assoc ? "$key:" : '', json_serialize($value));
}
return $brackets{0} . implode(',', $pairs) . $brackets{1};
}
}
else if (is_numeric($var) && strval(intval($var)) === strval($var))
return $var;
else if (is_bool($var))
return $var ? '1' : '0';
else
return "'".JQ($var)."'";
}
/**
* Function to convert an array to a javascript array
* Actually an alias function for json_serialize()
* @deprecated
*/
function array2js($arr, $type='')
{
return json_serialize($arr);
}
/**
* Similar function as in_array() but case-insensitive
*
* @param mixed Needle value
* @param array Array to search in
* @return boolean True if found, False if not
*/
function in_array_nocase($needle, $haystack)
{
foreach ($haystack as $value)
- if (strtolower($needle)===strtolower($value))
+ if (rc_strtolower($needle)===rc_strtolower($value))
return true;
return false;
}
/**
* Find out if the string content means TRUE or FALSE
*
* @param string Input value
* @return boolean Imagine what!
*/
function get_boolean($str)
{
$str = strtolower($str);
if(in_array($str, array('false', '0', 'no', 'nein', ''), TRUE))
return FALSE;
else
return TRUE;
}
/**
* Parse a human readable string for a number of bytes
*
* @param string Input string
* @return int Number of bytes
*/
function parse_bytes($str)
{
if (is_numeric($str))
return intval($str);
if (preg_match('/([0-9]+)([a-z])/i', $str, $regs))
{
$bytes = floatval($regs[1]);
switch (strtolower($regs[2]))
{
case 'g':
$bytes *= 1073741824;
break;
case 'm':
$bytes *= 1048576;
break;
case 'k':
$bytes *= 1024;
break;
}
}
return intval($bytes);
}
/**
* Create a human readable string for a number of bytes
*
* @param int Number of bytes
* @return string Byte string
*/
function show_bytes($bytes)
{
if ($bytes > 1073741824)
{
$gb = $bytes/1073741824;
$str = sprintf($gb>=10 ? "%d " : "%.1f ", $gb) . rcube_label('GB');
}
else if ($bytes > 1048576)
{
$mb = $bytes/1048576;
$str = sprintf($mb>=10 ? "%d " : "%.1f ", $mb) . rcube_label('MB');
}
else if ($bytes > 1024)
$str = sprintf("%d ", round($bytes/1024)) . rcube_label('KB');
else
$str = sprintf('%d ', $bytes) . rcube_label('B');
return $str;
}
/**
* Convert paths like ../xxx to an absolute path using a base url
*
* @param string Relative path
* @param string Base URL
* @return string Absolute URL
*/
function make_absolute_url($path, $base_url)
{
$host_url = $base_url;
$abs_path = $path;
// check if path is an absolute URL
if (preg_match('/^[fhtps]+:\/\//', $path))
return $path;
// cut base_url to the last directory
if (strpos($base_url, '/')>7)
{
$host_url = substr($base_url, 0, strpos($base_url, '/'));
$base_url = substr($base_url, 0, strrpos($base_url, '/'));
}
// $path is absolute
if ($path{0}=='/')
$abs_path = $host_url.$path;
else
{
// strip './' because its the same as ''
$path = preg_replace('/^\.\//', '', $path);
if (preg_match_all('/\.\.\//', $path, $matches, PREG_SET_ORDER))
foreach ($matches as $a_match)
{
if (strrpos($base_url, '/'))
$base_url = substr($base_url, 0, strrpos($base_url, '/'));
$path = substr($path, 3);
}
$abs_path = $base_url.'/'.$path;
}
return $abs_path;
}
/**
* Wrapper function for strlen
*/
function rc_strlen($str)
{
if (function_exists('mb_strlen'))
return mb_strlen($str);
else
return strlen($str);
}
/**
* Wrapper function for strtolower
*/
function rc_strtolower($str)
{
if (function_exists('mb_strtolower'))
return mb_strtolower($str);
else
return strtolower($str);
}
/**
* Wrapper function for substr
*/
function rc_substr($str, $start, $len=null)
{
if (function_exists('mb_substr'))
return mb_substr($str, $start, $len);
else
return substr($str, $start, $len);
}
/**
* Wrapper function for strpos
*/
function rc_strpos($haystack, $needle, $offset=0)
{
if (function_exists('mb_strpos'))
return mb_strpos($haystack, $needle, $offset);
else
return strpos($haystack, $needle, $offset);
}
/**
* Wrapper function for strrpos
*/
function rc_strrpos($haystack, $needle, $offset=0)
{
if (function_exists('mb_strrpos'))
return mb_strrpos($haystack, $needle, $offset);
else
return strrpos($haystack, $needle, $offset);
}
/**
* Read a specific HTTP request header
*
* @access static
* @param string $name Header name
* @return mixed Header value or null if not available
*/
function rc_request_header($name)
{
if (function_exists('getallheaders'))
{
$hdrs = array_change_key_case(getallheaders(), CASE_UPPER);
$key = strtoupper($name);
}
else
{
$key = 'HTTP_' . strtoupper(strtr($name, '-', '_'));
$hdrs = array_change_key_case($_SERVER, CASE_UPPER);
}
return $hdrs[$key];
}
/**
* Replace the middle part of a string with ...
* if it is longer than the allowed length
*
* @param string Input string
* @param int Max. length
* @param string Replace removed chars with this
* @return string Abbreviated string
*/
function abbreviate_string($str, $maxlength, $place_holder='...')
{
$length = rc_strlen($str);
$first_part_length = floor($maxlength/2) - rc_strlen($place_holder);
if ($length > $maxlength)
{
$second_starting_location = $length - $maxlength + $first_part_length + 1;
$str = rc_substr($str, 0, $first_part_length) . $place_holder . rc_substr($str, $second_starting_location, $length);
}
return $str;
}
/**
* Make sure the string ends with a slash
*/
function slashify($str)
{
return unslashify($str).'/';
}
/**
* Remove slash at the end of the string
*/
function unslashify($str)
{
return preg_replace('/\/$/', '', $str);
}
/**
* Delete all files within a folder
*
* @param string Path to directory
* @return boolean True on success, False if directory was not found
*/
function clear_directory($dir_path)
{
$dir = @opendir($dir_path);
if(!$dir) return FALSE;
while ($file = readdir($dir))
if (strlen($file)>2)
unlink("$dir_path/$file");
closedir($dir);
return TRUE;
}
/**
* Create a unix timestamp with a specified offset from now
*
* @param string String representation of the offset (e.g. 20min, 5h, 2days)
* @param int Factor to multiply with the offset
* @return int Unix timestamp
*/
function get_offset_time($offset_str, $factor=1)
{
if (preg_match('/^([0-9]+)\s*([smhdw])/i', $offset_str, $regs))
{
$amount = (int)$regs[1];
$unit = strtolower($regs[2]);
}
else
{
$amount = (int)$offset_str;
$unit = 's';
}
$ts = mktime();
switch ($unit)
{
case 'w':
$amount *= 7;
case 'd':
$amount *= 24;
case 'h':
$amount *= 60;
case 'm':
$amount *= 60;
case 's':
$ts += $amount * $factor;
}
return $ts;
}
/**
* A method to guess the mime_type of an attachment.
*
* @param string $path Path to the file.
* @param string $failover Mime type supplied for failover.
*
* @return string
* @author Till Klampaeckel <till@php.net>
* @see http://de2.php.net/manual/en/ref.fileinfo.php
* @see http://de2.php.net/mime_content_type
*/
function rc_mime_content_type($path, $failover = 'application/octet-stream')
{
$mime_type = null;
$mime_magic = rcmail::get_instance()->config->get('mime_magic');
if (!extension_loaded('fileinfo')) {
@dl('fileinfo.' . PHP_SHLIB_SUFFIX);
}
if (function_exists('finfo_open')) {
if ($finfo = finfo_open(FILEINFO_MIME, $mime_magic)) {
$mime_type = finfo_file($finfo, $path);
finfo_close($finfo);
}
}
if (!$mime_type && function_exists('mime_content_type')) {
$mime_type = mime_content_type($path);
}
if (!$mime_type) {
$mime_type = $failover;
}
return $mime_type;
}
/**
* A method to guess encoding of a string.
*
* @param string $string String.
* @param string $failover Default result for failover.
*
* @return string
*/
function rc_detect_encoding($string, $failover='')
{
if (!function_exists('mb_detect_encoding')) {
return $failover;
}
// FIXME: the order is important, because sometimes
// iso string is detected as euc-jp and etc.
$enc = array(
'SJIS', 'BIG5', 'GB2312', 'UTF-8',
'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4',
'ISO-8859-5', 'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9',
'ISO-8859-10', 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'ISO-8859-16',
'WINDOWS-1252', 'WINDOWS-1251', 'EUC-JP', 'EUC-TW', 'KOI8-R',
'ISO-2022-KR', 'ISO-2022-JP'
);
$result = mb_detect_encoding($string, join(',', $enc));
return $result ? $result : $failover;
}
?>
diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc
index efc979023..df6f1ffae 100644
--- a/program/steps/mail/compose.inc
+++ b/program/steps/mail/compose.inc
@@ -1,963 +1,963 @@
<?php
/*
+-----------------------------------------------------------------------+
| program/steps/mail/compose.inc |
| |
| This file is part of the RoundCube Webmail client |
| Copyright (C) 2005-2008, RoundCube Dev. - Switzerland |
| Licensed under the GNU GPL |
| |
| PURPOSE: |
| Compose a new mail message with all headers and attachments |
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
$Id$
*/
// define constants for message compose mode
define('RCUBE_COMPOSE_REPLY', 0x0106);
define('RCUBE_COMPOSE_FORWARD', 0x0107);
define('RCUBE_COMPOSE_DRAFT', 0x0108);
// remove an attachment
if ($RCMAIL->action=='remove-attachment' && preg_match('/^rcmfile([0-9]+)$/', $_POST['_file'], $regs))
{
$id = $regs[1];
if (is_array($_SESSION['compose']['attachments'][$id]))
{
@unlink($_SESSION['compose']['attachments'][$id]['path']);
unset($_SESSION['compose']['attachments'][$id]);
$OUTPUT->command('remove_from_attachment_list', "rcmfile$id");
$OUTPUT->send();
}
exit;
}
if ($RCMAIL->action=='display-attachment' && preg_match('/^rcmfile([0-9]+)$/', $_GET['_file'], $regs))
{
$id = $regs[1];
if (is_array($_SESSION['compose']['attachments'][$id]))
{
$apath = $_SESSION['compose']['attachments'][$id]['path'];
header('Content-Type: ' . $_SESSION['compose']['attachments'][$id]['mimetype']);
header('Content-Length: ' . filesize($apath));
readfile($apath);
}
exit;
}
$MESSAGE_FORM = NULL;
$MESSAGE = NULL;
// Nothing below is called during message composition, only at "new/forward/reply/draft" initialization or
// if a compose-ID is given (i.e. when the compose step is opened in a new window/tab).
// Since there are many ways to leave the compose page improperly, it seems necessary to clean-up an old
// compose when a "new/forward/reply/draft" is called - otherwise the old session attachments will appear
if (!is_array($_SESSION['compose']) || $_SESSION['compose']['id'] != get_input_value('_id', RCUBE_INPUT_GET))
{
rcmail_compose_cleanup();
$_SESSION['compose'] = array('id' => uniqid(rand()), 'param' => array_map('strip_tags', $_GET));
// process values like "mailto:foo@bar.com?subject=new+message&cc=another"
if ($_SESSION['compose']['param']['_to']) {
$mailto = explode('?', $_SESSION['compose']['param']['_to']);
if (count($mailto) > 1) {
$_SESSION['compose']['param']['_to'] = $mailto[0];
parse_str($mailto[1], $query);
foreach ($query as $f => $val)
$_SESSION['compose']['param']["_$f"] = $val;
}
}
// redirect to a unique URL with all parameters stored in session
$OUTPUT->redirect(array('_action' => 'compose', '_id' => $_SESSION['compose']['id']));
}
// add some labels to client
$OUTPUT->add_label('nosubject', 'nosenderwarning', 'norecipientwarning', 'nosubjectwarning', 'nobodywarning', 'notsentwarning', 'savingmessage', 'sendingmessage', 'messagesaved', 'converting');
// add config parameters to client script
if (!empty($CONFIG['drafts_mbox'])) {
$OUTPUT->set_env('drafts_mailbox', $CONFIG['drafts_mbox']);
$OUTPUT->set_env('draft_autosave', $CONFIG['draft_autosave']);
}
// set current mailbox in client environment
$OUTPUT->set_env('mailbox', $IMAP->get_mailbox_name());
// get reference message and set compose mode
if ($msg_uid = $_SESSION['compose']['param']['_reply_uid'])
$compose_mode = RCUBE_COMPOSE_REPLY;
else if ($msg_uid = $_SESSION['compose']['param']['_forward_uid'])
$compose_mode = RCUBE_COMPOSE_FORWARD;
else if ($msg_uid = $_SESSION['compose']['param']['_draft_uid'])
$compose_mode = RCUBE_COMPOSE_DRAFT;
if (!empty($msg_uid))
{
// similar as in program/steps/mail/show.inc
$MESSAGE = new rcube_message($msg_uid);
if (!empty($MESSAGE->headers->charset))
$IMAP->set_charset($MESSAGE->headers->charset);
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);
if (!empty($_SESSION['compose']['param']['_all']))
$MESSAGE->reply_all = 1;
}
else if ($compose_mode == RCUBE_COMPOSE_DRAFT)
{
if($MESSAGE->headers->in_reply_to)
{
// TODO: how to get reply_uid/forward_uid value, maybe we must set X-Reply-UID/X-Forward-UID
// $_SESSION['compose']['reply_uid'] = ?
// $_SESSION['compose']['forward_uid'] = ?
$_SESSION['compose']['reply_msgid'] = '<'.$MESSAGE->headers->in_reply_to.'>';
}
$_SESSION['compose']['references'] = $MESSAGE->headers->references;
}
else if ($compose_mode == RCUBE_COMPOSE_FORWARD)
{
$_SESSION['compose']['forward_uid'] = $msg_uid;
}
}
/****** compose mode functions ********/
function rcmail_compose_headers($attrib)
{
global $IMAP, $MESSAGE, $DB, $compose_mode;
static $sa_recipients = array();
list($form_start, $form_end) = get_form_tags($attrib);
$out = '';
$part = strtolower($attrib['part']);
switch ($part)
{
case 'from':
return rcmail_compose_header_from($attrib);
case 'to':
$fname = '_to';
$header = 'to';
// we have a set of recipients stored is session
if (($mailto_id = $_SESSION['compose']['param']['_mailto']) && $_SESSION['mailto'][$mailto_id])
$fvalue = urldecode($_SESSION['mailto'][$mailto_id]);
case 'cc':
if (!$fname)
{
$fname = '_cc';
$header = 'cc';
}
case 'bcc':
if (!$fname)
{
$fname = '_bcc';
$header = 'bcc';
}
$allow_attrib = array('id', 'class', 'style', 'cols', 'rows', 'tabindex');
$field_type = 'html_textarea';
break;
case 'replyto':
case 'reply-to':
$fname = '_replyto';
$allow_attrib = array('id', 'class', 'style', 'size', 'tabindex');
$field_type = 'html_inputfield';
break;
}
if ($fname && !empty($_POST[$fname]))
$fvalue = get_input_value($fname, RCUBE_INPUT_POST, TRUE);
else if ($fname && !$fvalue && !empty($_SESSION['compose']['param'][$fname]))
$fvalue = $_SESSION['compose']['param'][$fname];
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;
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))
{
if ($v = $MESSAGE->headers->to)
$fvalue .= $v;
if ($v = $MESSAGE->headers->cc)
$fvalue .= (!empty($fvalue) ? ', ' : '') . $v;
}
// split recipients and put them back together in a unique way
if (!empty($fvalue))
{
$to_addresses = $IMAP->decode_address_list($fvalue);
$fvalue = '';
foreach ($to_addresses as $addr_part)
{
if (!empty($addr_part['mailto'])
&& !in_array($addr_part['mailto'], $sa_recipients)
&& (!$MESSAGE->compose_from
- || !in_array($addr_part['mailto'], $MESSAGE->compose_from)
+ || !in_array_nocase($addr_part['mailto'], $MESSAGE->compose_from)
|| count($to_addresses)==1)) // allow reply to yourself
{
$fvalue .= (strlen($fvalue) ? ', ':'').$addr_part['string'];
$sa_recipients[] = $addr_part['mailto'];
}
}
}
}
else if ($header && $compose_mode == RCUBE_COMPOSE_DRAFT)
{
// get drafted headers
if ($header=='to' && !empty($MESSAGE->headers->to))
$fvalue = $MESSAGE->get_header('to');
if ($header=='cc' && !empty($MESSAGE->headers->cc))
$fvalue = $MESSAGE->get_header('cc');
if ($header=='bcc' && !empty($MESSAGE->headers->bcc))
$fvalue = $MESSAGE->get_header('bcc');
}
if ($fname && $field_type)
{
// pass the following attributes to the form class
$field_attrib = array('name' => $fname, 'spellcheck' => 'false');
foreach ($attrib as $attr => $value)
if (in_array($attr, $allow_attrib))
$field_attrib[$attr] = $value;
// create teaxtarea object
$input = new $field_type($field_attrib);
$out = $input->show($fvalue);
}
if ($form_start)
$out = $form_start.$out;
return $out;
}
function rcmail_compose_header_from($attrib)
{
global $IMAP, $MESSAGE, $DB, $USER, $OUTPUT, $compose_mode;
// pass the following attributes to the form class
$field_attrib = array('name' => '_from');
foreach ($attrib as $attr => $value)
if (in_array($attr, array('id', 'class', 'style', 'size', 'tabindex')))
$field_attrib[$attr] = $value;
// extract all recipients of the reply-message
$a_recipients = array();
if ($compose_mode == RCUBE_COMPOSE_REPLY && is_object($MESSAGE->headers))
{
$MESSAGE->compose_from = array();
$a_to = $IMAP->decode_address_list($MESSAGE->headers->to);
foreach ($a_to as $addr)
{
if (!empty($addr['mailto']))
$a_recipients[] = rc_strtolower($addr['mailto']);
}
if (!empty($MESSAGE->headers->cc))
{
$a_cc = $IMAP->decode_address_list($MESSAGE->headers->cc);
foreach ($a_cc as $addr)
{
if (!empty($addr['mailto']))
$a_recipients[] = rc_strtolower($addr['mailto']);
}
}
}
// get this user's identities
$sql_result = $USER->list_identities();
if ($DB->num_rows($sql_result))
{
$from_id = 0;
$a_signatures = array();
$field_attrib['onchange'] = JS_OBJECT_NAME.".change_identity(this)";
$select_from = new html_select($field_attrib);
while ($sql_arr = $DB->fetch_assoc($sql_result))
{
$identity_id = $sql_arr['identity_id'];
$select_from->add(format_email_recipient($sql_arr['email'], $sql_arr['name']), $identity_id);
// add signature to array
if (!empty($sql_arr['signature']))
{
$a_signatures[$identity_id]['text'] = $sql_arr['signature'];
$a_signatures[$identity_id]['is_html'] = ($sql_arr['html_signature'] == 1) ? true : false;
if ($a_signatures[$identity_id]['is_html'])
{
$h2t = new html2text($a_signatures[$identity_id]['text'], false, false);
$plainTextPart = $h2t->get_text();
$a_signatures[$identity_id]['plain_text'] = trim(html_entity_decode($plainTextPart, ENT_NOQUOTES, 'UTF-8'));
}
}
if ($compose_mode == RCUBE_COMPOSE_REPLY && is_array($MESSAGE->compose_from))
$MESSAGE->compose_from[] = $sql_arr['email'];
if (empty($_POST['_from']))
{
// set draft's identity
if ($compose_mode == RCUBE_COMPOSE_DRAFT && strstr($MESSAGE->headers->from, $sql_arr['email']))
$from_id = $sql_arr['identity_id'];
// set identity if it's one of the reply-message recipients (with prio for default identity)
else if (in_array(rc_strtolower($sql_arr['email']), $a_recipients) && (empty($from_id) || $sql_arr['standard']))
$from_id = $sql_arr['identity_id'];
}
}
// overwrite identity selection with post parameter
if (!empty($_POST['_from']))
$from_id = get_input_value('_from', RCUBE_INPUT_POST);
$out = $select_from->show($from_id);
// add signatures to client
$OUTPUT->set_env('signatures', $a_signatures);
}
else
{
$input_from = new html_inputfield($field_attrib);
$out = $input_from->show($_POST['_from']);
}
if ($form_start)
$out = $form_start.$out;
return $out;
}
function rcmail_compose_body($attrib)
{
global $RCMAIL, $CONFIG, $OUTPUT, $MESSAGE, $compose_mode;
list($form_start, $form_end) = get_form_tags($attrib);
unset($attrib['form']);
if (empty($attrib['id']))
$attrib['id'] = 'rcmComposeMessage';
$attrib['name'] = '_message';
if ($CONFIG['htmleditor'])
$isHtml = true;
else
$isHtml = false;
$body = '';
// 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 = $MESSAGE->first_html_part();
$isHtml = true;
}
else
{
$body = $MESSAGE->first_text_part();
$isHtml = false;
}
// 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);
if ($isHtml) {
// replace cid with href in inline images links
foreach ((array)$_SESSION['compose']['attachments'] as $pid => $attachment) {
if ($attachment['content_id']) {
$body = str_replace('cid:'. $attachment['content_id'],
$OUTPUT->app->comm_path.'&_action=display-attachment&_file=rcmfile'.$pid, $body);
}
}
}
}
else if (!empty($_SESSION['compose']['param']['_body']))
{
$body = $_SESSION['compose']['param']['_body'];
}
$lang = $tinylang = strtolower(substr($_SESSION['language'], 0, 2));
if (!file_exists(INSTALL_PATH . 'program/js/tiny_mce/langs/'.$tinylang.'.js'))
$tinylang = 'en';
$OUTPUT->include_script('tiny_mce/tiny_mce.js');
$OUTPUT->include_script("editor.js");
$OUTPUT->add_script('rcmail_editor_init("$__skin_path", "'.JQ($tinylang).'", '.intval($CONFIG['enable_spellcheck']).');');
$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) : ''));
$out .= $saveid->show();
$drafttoggle = new html_hiddenfield(array('name' => '_draft', 'value' => 'yes'));
$out .= $drafttoggle->show();
$msgtype = new html_hiddenfield(array('name' => '_is_html', 'value' => ($isHtml?"1":"0")));
$out .= $msgtype->show();
// If desired, set this textarea to be editable by TinyMCE
if ($isHtml) $attrib['class'] = 'mce_editor';
$textarea = new html_textarea($attrib);
$out .= $textarea->show($body);
$out .= $form_end ? "\n$form_end" : '';
// include GoogieSpell
if (!empty($CONFIG['enable_spellcheck'])) {
$spellcheck_langs = (array)$RCMAIL->config->get('spellcheck_languages', array('da'=>'Dansk', 'de'=>'Deutsch', 'en' => 'English', 'es'=>'Español', 'fr'=>'Français', 'it'=>'Italiano', 'nl'=>'Nederlands', 'pl'=>'Polski', 'pt'=>'Português', 'fi'=>'Suomi', 'sv'=>'Svenska'));
if (!$spellcheck_langs[$lang])
$lang = 'en';
$editor_lang_set = array();
foreach ($spellcheck_langs as $key => $name) {
$editor_lang_set[] = ($key == $lang ? '+' : '') . JQ($name).'='.JQ($key);
}
$OUTPUT->include_script('googiespell.js');
$OUTPUT->add_script(sprintf(
"var googie = new GoogieSpell('\$__skin_path/images/googiespell/','%s&_action=spell&lang=');\n".
"googie.lang_chck_spell = \"%s\";\n".
"googie.lang_rsm_edt = \"%s\";\n".
"googie.lang_close = \"%s\";\n".
"googie.lang_revert = \"%s\";\n".
"googie.lang_no_error_found = \"%s\";\n".
"googie.setLanguages(%s);\n".
"googie.setCurrentLanguage('%s');\n".
"googie.decorateTextarea('%s');\n".
"%s.set_env('spellcheck', googie);",
$RCMAIL->comm_path,
JQ(Q(rcube_label('checkspelling'))),
JQ(Q(rcube_label('resumeediting'))),
JQ(Q(rcube_label('close'))),
JQ(Q(rcube_label('revertto'))),
JQ(Q(rcube_label('nospellerrors'))),
json_serialize($spellcheck_langs),
$lang,
$attrib['id'],
JS_OBJECT_NAME), 'foot');
$OUTPUT->add_label('checking');
$OUTPUT->set_env('spellcheck_langs', join(',', $editor_lang_set));
}
$out .= "\n".'<iframe name="savetarget" src="program/blank.gif" style="width:0;height:0;border:none;visibility:hidden;"></iframe>';
return $out;
}
function rcmail_create_reply_body($body, $bodyIsHtml)
{
global $IMAP, $MESSAGE, $OUTPUT;
if (! $bodyIsHtml)
{
// try to remove the signature
if (($sp = strrpos($body, '-- ')) !== false && ($sp == 0 || $body{$sp-1} == "\n"))
{
if ($body{$sp+3}==' ' || $body{$sp+3}=="\n" || $body{$sp+3}=="\r")
$body = substr($body, 0, max(0, $sp-1));
}
// soft-wrap message first
$body = rcmail_wrap_quoted($body, 75);
$body = rtrim($body, "\r\n");
if ($body) {
// split body into single lines
$a_lines = preg_split('/\r?\n/', $body);
// add > to each line
for($n=0; $n<sizeof($a_lines); $n++) {
if (strpos($a_lines[$n], '>')===0)
$a_lines[$n] = '>'.$a_lines[$n];
else
$a_lines[$n] = '> '.$a_lines[$n];
}
$body = join("\n", $a_lines);
}
// add title line(s)
$prefix = wordwrap(sprintf("On %s, %s wrote:\n",
$MESSAGE->headers->date,
$MESSAGE->get_header('from')), 76);
$suffix = '';
}
else
{
$prefix = sprintf("On %s, %s wrote:<br />\n",
$MESSAGE->headers->date,
htmlspecialchars(Q($MESSAGE->get_header('from'), 'replace'), ENT_COMPAT, $OUTPUT->get_charset()));
$prefix .= '<blockquote type="cite" style="padding-left:5px; border-left:#1010ff 2px solid; margin-left:5px; width:100%">';
$suffix = "</blockquote>";
rcmail_write_inline_attachments($MESSAGE);
}
return $prefix.$body.$suffix;
}
function rcmail_create_forward_body($body, $bodyIsHtml)
{
global $IMAP, $MESSAGE, $OUTPUT;
if (!$bodyIsHtml)
{
$prefix = "\n\n\n-------- Original Message --------\n";
$prefix .= 'Subject: ' . $MESSAGE->subject . "\n";
$prefix .= 'Date: ' . $MESSAGE->headers->date . "\n";
$prefix .= 'From: ' . $MESSAGE->get_header('from') . "\n";
$prefix .= 'To: ' . $MESSAGE->get_header('to') . "\n";
if ($MESSAGE->headers->replyto && $MESSAGE->headers->replyto != $MESSAGE->headers->from)
$prefix .= 'Reply-To: ' . $MESSAGE->get_header('replyto') . "\n";
$prefix .= "\n";
}
else
{
$prefix = sprintf(
"<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>",
Q($MESSAGE->subject),
Q($MESSAGE->headers->date),
htmlspecialchars(Q($MESSAGE->get_header('from'), 'replace'), ENT_COMPAT, $OUTPUT->get_charset(), true),
htmlspecialchars(Q($MESSAGE->get_header('to'), 'replace'), ENT_COMPAT, $OUTPUT->get_charset(), true));
if ($MESSAGE->headers->replyto && $MESSAGE->headers->replyto != $MESSAGE->headers->from)
$prefix .= sprintf("<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">Reply-To: </th><td>%s</td></tr>",
htmlspecialchars(Q($MESSAGE->get_header('replyto'), 'replace'), ENT_COMPAT, $OUTPUT->get_charset(), true));
$prefix .= "</tbody></table><br>";
}
// add attachments
if (!isset($_SESSION['compose']['forward_attachments']) && is_array($MESSAGE->mime_parts))
rcmail_write_compose_attachments($MESSAGE, $bodyIsHtml);
return $prefix.$body;
}
function rcmail_create_draft_body($body, $bodyIsHtml)
{
global $MESSAGE;
/**
* add attachments
* sizeof($MESSAGE->mime_parts can be 1 - e.g. attachment, but no text!
*/
if (!isset($_SESSION['compose']['forward_attachments'])
&& is_array($MESSAGE->mime_parts)
&& count($MESSAGE->mime_parts) > 0)
rcmail_write_compose_attachments($MESSAGE, $bodyIsHtml);
return $body;
}
function rcmail_write_compose_attachments(&$message, $bodyIsHtml)
{
foreach ((array)$message->mime_parts as $pid => $part)
{
if (($part->ctype_primary != 'message' || !$bodyIsHtml) &&
($part->disposition=='attachment' || $part->disposition=='inline' || $part->headers['content-id']
|| (empty($part->disposition) && $part->filename)))
{
if ($attachment = rcmail_save_attachment($message, $pid))
$_SESSION['compose']['attachments'][] = $attachment;
}
}
$_SESSION['compose']['forward_attachments'] = true;
}
function rcmail_write_inline_attachments(&$message)
{
foreach ((array)$message->mime_parts as $pid => $part)
{
if ($part->content_id && $part->filename)
{
if ($attachment = rcmail_save_attachment($message, $pid))
$_SESSION['compose']['attachments'][] = $attachment;
}
}
}
function rcmail_save_attachment(&$message, $pid)
{
global $RCMAIL;
$temp_dir = unslashify($RCMAIL->config->get('temp_dir'));
$tmp_path = tempnam($temp_dir, 'rcmAttmnt');
$part = $message->mime_parts[$pid];
if ($fp = fopen($tmp_path, 'w'))
{
$message->get_part_content($pid, $fp);
fclose($fp);
return array(
'mimetype' => $part->ctype_primary . '/' . $part->ctype_secondary,
'name' => $part->filename,
'path' => $tmp_path,
'content_id' => $part->content_id
);
}
}
function rcmail_compose_subject($attrib)
{
global $MESSAGE, $compose_mode;
list($form_start, $form_end) = get_form_tags($attrib);
unset($attrib['form']);
$attrib['name'] = '_subject';
$attrib['spellcheck'] = 'true';
$textfield = new html_inputfield($attrib);
$subject = '';
// use subject from post
if (isset($_POST['_subject'])) {
$subject = get_input_value('_subject', RCUBE_INPUT_POST, TRUE);
}
// create a reply-subject
else if ($compose_mode == RCUBE_COMPOSE_REPLY) {
if (eregi('^re:', $MESSAGE->subject))
$subject = $MESSAGE->subject;
else
$subject = 'Re: '.$MESSAGE->subject;
}
// create a forward-subject
else if ($compose_mode == RCUBE_COMPOSE_FORWARD) {
if (eregi('^fwd:', $MESSAGE->subject))
$subject = $MESSAGE->subject;
else
$subject = 'Fwd: '.$MESSAGE->subject;
}
// creeate a draft-subject
else if ($compose_mode == RCUBE_COMPOSE_DRAFT) {
$subject = $MESSAGE->subject;
}
else if (!empty($_SESSION['compose']['param']['_subject'])) {
$subject = $_SESSION['compose']['param']['_subject'];
}
$out = $form_start ? "$form_start\n" : '';
$out .= $textfield->show($subject);
$out .= $form_end ? "\n$form_end" : '';
return $out;
}
function rcmail_compose_attachment_list($attrib)
{
global $OUTPUT, $CONFIG;
// add ID if not given
if (!$attrib['id'])
$attrib['id'] = 'rcmAttachmentList';
$out = "\n";
if (is_array($_SESSION['compose']['attachments']))
{
if ($attrib['deleteicon'])
$button = html::img(array(
'src' => $CONFIG['skin_path'] . $attrib['deleteicon'],
'alt' => rcube_label('delete'),
'style' => "padding-right:2px;vertical-align:middle"));
else
$button = Q(rcube_label('delete'));
foreach ($_SESSION['compose']['attachments'] as $id => $a_prop)
{
if (empty($a_prop))
continue;
$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']);
return html::tag('ul', $attrib, $out, html::$common_attrib);
}
function rcmail_compose_attachment_form($attrib)
{
global $OUTPUT;
// add ID if not given
if (!$attrib['id'])
$attrib['id'] = 'rcmUploadbox';
$button = new html_inputfield(array('type' => 'button', 'class' => 'button'));
$out = html::div($attrib,
$OUTPUT->form_tag(array('name' => 'form', 'method' => 'post', 'enctype' => 'multipart/form-data'),
html::div(null, rcmail_compose_attachment_field(array())) .
html::div('hint', rcube_label(array('name' => 'maxuploadsize', 'vars' => array('size' => show_bytes(parse_bytes(ini_get('upload_max_filesize'))))))) .
html::div('buttons',
$button->show(rcube_label('close'), array('onclick' => "document.getElementById('$attrib[id]').style.visibility='hidden'")) . ' ' .
$button->show(rcube_label('upload'), array('onclick' => JS_OBJECT_NAME . ".command('send-attachment', this.form)"))
)
)
);
$OUTPUT->add_gui_object('uploadbox', $attrib['id']);
return $out;
}
function rcmail_compose_attachment_field($attrib)
{
$attrib['type'] = 'file';
$attrib['name'] = '_attachments[]';
$field = new html_inputfield($attrib);
return $field->show();
}
function rcmail_priority_selector($attrib)
{
global $MESSAGE;
list($form_start, $form_end) = get_form_tags($attrib);
unset($attrib['form']);
$attrib['name'] = '_priority';
$selector = new html_select($attrib);
$selector->add(array(rcube_label('lowest'),
rcube_label('low'),
rcube_label('normal'),
rcube_label('high'),
rcube_label('highest')),
array(5, 4, 0, 2, 1));
$sel = isset($_POST['_priority']) ? $_POST['_priority'] : intval($MESSAGE->headers->priority);
$out = $form_start ? "$form_start\n" : '';
$out .= $selector->show($sel);
$out .= $form_end ? "\n$form_end" : '';
return $out;
}
function rcmail_receipt_checkbox($attrib)
{
global $MESSAGE, $compose_mode;
list($form_start, $form_end) = get_form_tags($attrib);
unset($attrib['form']);
if (!isset($attrib['id']))
$attrib['id'] = 'receipt';
$attrib['name'] = '_receipt';
$attrib['value'] = '1';
$checkbox = new html_checkbox($attrib);
$out = $form_start ? "$form_start\n" : '';
$out .= $checkbox->show(
$compose_mode == RCUBE_COMPOSE_DRAFT && $MESSAGE->headers->mdn_to ? 1 : 0);
$out .= $form_end ? "\n$form_end" : '';
return $out;
}
function rcmail_editor_selector($attrib)
{
global $CONFIG, $MESSAGE, $compose_mode;
$choices = array(
'html' => 'htmltoggle',
'plain' => 'plaintoggle'
);
// determine whether HTML or plain text should be checked
$useHtml = $CONFIG['htmleditor'] ? true : false;
if ($compose_mode)
$useHtml = ($useHtml && $MESSAGE->has_html_part());
$selector = '';
$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;
$selector .= $radio->show($chosenvalue, $attrib) . html::label($attrib['id'], Q(rcube_label($text)));
}
return $selector;
}
function rcmail_store_target_selection($attrib)
{
$attrib['name'] = '_store_target';
$select = rcmail_mailbox_select(array_merge($attrib, array('noselection' => '- '.rcube_label('dontsave').' -')));
return $select->show(rcmail::get_instance()->config->get('sent_mbox'), $attrib);
}
function get_form_tags($attrib)
{
global $RCMAIL, $MESSAGE_FORM;
$form_start = '';
if (!strlen($MESSAGE_FORM))
{
$hiddenfields = new html_hiddenfield(array('name' => '_task', 'value' => $RCMAIL->task));
$hiddenfields->add(array('name' => '_action', 'value' => 'send'));
$form_start = empty($attrib['form']) ? $RCMAIL->output->form_tag(array('name' => "form", 'method' => "post")) : '';
$form_start .= $hiddenfields->show();
}
$form_end = (strlen($MESSAGE_FORM) && !strlen($attrib['form'])) ? '</form>' : '';
$form_name = !empty($attrib['form']) ? $attrib['form'] : 'form';
if (!strlen($MESSAGE_FORM))
$RCMAIL->output->add_gui_object('messageform', $form_name);
$MESSAGE_FORM = $form_name;
return array($form_start, $form_end);
}
// register UI objects
$OUTPUT->add_handlers(array(
'composeheaders' => 'rcmail_compose_headers',
'composesubject' => 'rcmail_compose_subject',
'composebody' => 'rcmail_compose_body',
'composeattachmentlist' => 'rcmail_compose_attachment_list',
'composeattachmentform' => 'rcmail_compose_attachment_form',
'composeattachment' => 'rcmail_compose_attachment_field',
'priorityselector' => 'rcmail_priority_selector',
'editorselector' => 'rcmail_editor_selector',
'receiptcheckbox' => 'rcmail_receipt_checkbox',
'storetarget' => 'rcmail_store_target_selection',
));
/****** get contacts for this user and add them to client scripts ********/
$CONTACTS = new rcube_contacts($DB, $USER->ID);
$CONTACTS->set_pagesize(1000);
$a_contacts = array();
if ($result = $CONTACTS->list_records())
{
while ($sql_arr = $result->iterate())
if ($sql_arr['email'])
$a_contacts[] = format_email_recipient($sql_arr['email'], $sql_arr['name']);
}
if (!empty($CONFIG['ldap_public']) && is_array($CONFIG['ldap_public']))
{
/* LDAP autocompletion */
foreach ($CONFIG['ldap_public'] as $ldapserv_config)
{
if ($ldapserv_config['fuzzy_search'] != 1 ||
$ldapserv_config['global_search'] != 1)
{
continue;
}
$LDAP = new rcube_ldap($ldapserv_config);
$LDAP->connect();
$LDAP->set_pagesize(1000);
$results = $LDAP->search($ldapserv_config['mail_field'], "");
for ($i = 0; $i < $results->count; $i++)
{
if ($results->records[$i]['email'] != '')
{
$email = $results->records[$i]['email'];
$name = $results->records[$i]['name'];
$a_contacts[] = format_email_recipient($email, $name);
}
}
$LDAP->close();
}
}
if ($a_contacts)
{
$OUTPUT->set_env('contacts', $a_contacts);
}
$OUTPUT->send('compose');
?>
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Mar 1, 10:59 AM (6 h, 14 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
166778
Default Alt Text
(45 KB)
Attached To
Mode
R3 roundcubemail
Attached
Detach File
Event Timeline
Log In to Comment