- Merge devel-framework branch, resolved conflicts

pull/1/head
alecpl 12 years ago
parent ce64332e7a
commit 0c259682f6

@ -1,6 +1,17 @@
CHANGELOG Roundcube Webmail
===========================
- Roundcube Framework:
Add possibility to replace IMAP driver with custom class
Add IMAP auto-connection feature, improving performance with caching enabled
Replace imap_init hook with storage_init (with additional 'driver' argument)
Improved performance by caching IMAP server's capabilities in session
Unified global functions naming (rcube_ prefix)
Move global functions from main.inc and rcube_shared.inc into classes
Better classes separation
RELEASE 0.8-rc
----------------
- Set flexible width to login form fields (#1488418)
- Fix re-draw bug on list columns change in IE8 (#1487822)
- Allow mass-removal of addresses from a group (#1487748)

@ -34,7 +34,7 @@ function export_mailbox($mbox, $filename)
$IMAP->set_folder($mbox);
$index = $IMAP->index($mbox, null, 'ASC');
$count = $index->countMessages();
$count = $index->count();
$index = $index->get();
vputs("Getting message list of {$mbox}...");

@ -2,7 +2,7 @@
/*
+-------------------------------------------------------------------------+
| Roundcube Webmail IMAP Client |
| Version 0.8-svn |
| Version 0.9-svn |
| |
| Copyright (C) 2005-2012, The Roundcube Dev Team |
| |
@ -45,7 +45,7 @@ require_once 'program/include/iniset.php';
$RCMAIL = rcmail::get_instance();
// Make the whole PHP output non-cacheable (#1487797)
send_nocacheing_headers();
$RCMAIL->output->nocacheing_headers();
// turn on output buffering
ob_start();
@ -67,14 +67,14 @@ if ($err_str = $RCMAIL->db->is_error()) {
}
// error steps
if ($RCMAIL->action=='error' && !empty($_GET['_code'])) {
if ($RCMAIL->action == 'error' && !empty($_GET['_code'])) {
raise_error(array('code' => hexdec($_GET['_code'])), FALSE, TRUE);
}
// check if https is required (for login) and redirect if necessary
if (empty($_SESSION['user_id']) && ($force_https = $RCMAIL->config->get('force_https', false))) {
$https_port = is_bool($force_https) ? 443 : $force_https;
if (!rcube_https_check($https_port)) {
if (!rcube_ui::https_check($https_port)) {
$host = preg_replace('/:[0-9]+$/', '', $_SERVER['HTTP_HOST']);
$host .= ($https_port != 443 ? ':' . $https_port : '');
header('Location: https://' . $host . $_SERVER['REQUEST_URI']);
@ -89,15 +89,15 @@ $RCMAIL->action = $startup['action'];
// try to log in
if ($RCMAIL->task == 'login' && $RCMAIL->action == 'login') {
$request_valid = $_SESSION['temp'] && $RCMAIL->check_request(RCUBE_INPUT_POST, 'login');
$request_valid = $_SESSION['temp'] && $RCMAIL->check_request(rcube_ui::INPUT_POST, 'login');
// purge the session in case of new login when a session already exists
$RCMAIL->kill_session();
$auth = $RCMAIL->plugins->exec_hook('authenticate', array(
'host' => $RCMAIL->autoselect_host(),
'user' => trim(get_input_value('_user', RCUBE_INPUT_POST)),
'pass' => get_input_value('_pass', RCUBE_INPUT_POST, true,
'user' => trim(rcube_ui::get_input_value('_user', rcube_ui::INPUT_POST)),
'pass' => rcube_ui::get_input_value('_pass', rcube_ui::INPUT_POST, true,
$RCMAIL->config->get('password_charset', 'ISO-8859-1')),
'cookiecheck' => true,
'valid' => $request_valid,
@ -119,11 +119,11 @@ if ($RCMAIL->task == 'login' && $RCMAIL->action == 'login') {
$RCMAIL->session->set_auth_cookie();
// log successful login
rcmail_log_login();
$RCMAIL->log_login();
// restore original request parameters
$query = array();
if ($url = get_input_value('_url', RCUBE_INPUT_POST)) {
if ($url = rcube_ui::get_input_value('_url', rcube_ui::INPUT_POST)) {
parse_str($url, $query);
// prevent endless looping on login page
@ -149,7 +149,7 @@ if ($RCMAIL->task == 'login' && $RCMAIL->action == 'login') {
}
// end session (after optional referer check)
else if ($RCMAIL->task == 'logout' && isset($_SESSION['user_id']) && (!$RCMAIL->config->get('referer_check') || rcube_check_referer())) {
else if ($RCMAIL->task == 'logout' && isset($_SESSION['user_id']) && (!$RCMAIL->config->get('referer_check') || rcmail::check_referer())) {
$userdata = array(
'user' => $_SESSION['username'],
'host' => $_SESSION['storage_host'],
@ -172,7 +172,8 @@ else if ($RCMAIL->task != 'login' && $_SESSION['user_id'] && $RCMAIL->action !=
// not logged in -> show login page
if (empty($RCMAIL->user->ID)) {
// log session failures
if (($task = get_input_value('_task', RCUBE_INPUT_GPC)) && !in_array($task, array('login','logout')) && !$session_error && ($sess_id = $_COOKIE[ini_get('session.name')])) {
$task = rcube_ui::get_input_value('_task', rcube_ui::INPUT_GPC);
if ($task && !in_array($task, array('login','logout')) && !$session_error && ($sess_id = $_COOKIE[ini_get('session.name')])) {
$RCMAIL->session->log("Aborted session " . $sess_id . "; no valid session data found");
$session_error = true;
}
@ -208,7 +209,7 @@ else {
// check client X-header to verify request origin
if ($OUTPUT->ajax_call) {
if (rc_request_header('X-Roundcube-Request') != $RCMAIL->get_request_token() && !$RCMAIL->config->get('devel_mode')) {
if (rcube_request_header('X-Roundcube-Request') != $RCMAIL->get_request_token() && !$RCMAIL->config->get('devel_mode')) {
header('HTTP/1.1 403 Forbidden');
die("Invalid Request");
}
@ -220,7 +221,7 @@ else {
}
// check referer if configured
if (!$request_check_whitelist[$RCMAIL->action] && $RCMAIL->config->get('referer_check') && !rcube_check_referer()) {
if (!$request_check_whitelist[$RCMAIL->action] && $RCMAIL->config->get('referer_check') && !rcmail::check_referer()) {
raise_error(array(
'code' => 403,
'type' => 'php',

@ -53,6 +53,8 @@ $include_path .= ini_get('include_path');
set_include_path($include_path);
require_once 'utils.php';
require_once 'rcube_shared.inc';
// deprecated aliases (to be removed)
require_once 'main.inc';
session_start();

@ -45,26 +45,16 @@ function __autoload($classname)
include_once $filename. '.php';
}
/**
* Fake internal error handler to catch errors
*/
function raise_error($p)
{
$rci = rcube_install::get_instance();
$rci->raise_error($p);
}
/**
* Local callback function for PEAR errors
*/
function rcube_pear_error($err)
function __pear_error($err)
{
raise_error(array(
rcmail::raise_error(array(
'code' => $err->getCode(),
'message' => $err->getMessage(),
));
}
// set PEAR error handling (will also load the PEAR main class)
PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'rcube_pear_error');
PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, '__pear_error');

@ -55,7 +55,7 @@ function get_opt($aliases=array())
continue;
$args[$key] = preg_replace(array('/^["\']/', '/["\']$/'), '', $value);
if ($alias = $aliases[$key])
$args[$alias] = $args[$key];
}

@ -277,7 +277,7 @@ class html
$attrib_arr = array();
foreach ($attrib as $key => $value) {
// skip size if not numeric
if (($key=='size' && !is_numeric($value))) {
if ($key == 'size' && !is_numeric($value)) {
continue;
}
@ -297,17 +297,57 @@ class html
$attrib_arr[] = $key . '="' . $key . '"';
}
}
else if ($key=='value') {
$attrib_arr[] = $key . '="' . Q($value, 'strict', false) . '"';
}
else {
$attrib_arr[] = $key . '="' . Q($value) . '"';
$attrib_arr[] = $key . '="' . self::quote($value) . '"';
}
}
return count($attrib_arr) ? ' '.implode(' ', $attrib_arr) : '';
}
/**
* Convert a HTML attribute string attributes to an associative array (name => value)
*
* @param string Input string
* @return array Key-value pairs of parsed attributes
*/
public static function parse_attrib_string($str)
{
$attrib = array();
$regexp = '/\s*([-_a-z]+)=(["\'])??(?(2)([^\2]*)\2|(\S+?))/Ui';
preg_match_all($regexp, stripslashes($str), $regs, PREG_SET_ORDER);
// convert attributes to an associative array (name => value)
if ($regs) {
foreach ($regs as $attr) {
$attrib[strtolower($attr[1])] = html_entity_decode($attr[3] . $attr[4]);
}
}
return $attrib;
}
/**
* Replacing specials characters in html attribute value
*
* @param string $str Input string
*
* @return string The quoted string
*/
public static function quote($str)
{
$str = htmlspecialchars($str, ENT_COMPAT, RCMAIL_CHARSET);
// avoid douple quotation of &
// @TODO: get rid of it?
$str = preg_replace('/&([A-Za-z]{2,6}|#[0-9]{2,4});/', '&\\1;', $str);
return $str;
}
}
/**
* Class to create an HTML input field
*
@ -317,9 +357,11 @@ class html_inputfield extends html
{
protected $tagname = 'input';
protected $type = 'text';
protected $allowed = array('type','name','value','size','tabindex',
protected $allowed = array(
'type','name','value','size','tabindex',
'autocomplete','checked','onchange','onclick','disabled','readonly',
'spellcheck','results','maxlength','src','multiple','placeholder');
'spellcheck','results','maxlength','src','multiple','placeholder',
);
/**
* Object constructor
@ -517,11 +559,11 @@ class html_textarea extends html
}
if (!empty($value) && !preg_match('/mce_editor/', $this->attrib['class'])) {
$value = Q($value, 'strict', false);
$value = self::quote($value);
}
return self::tag($this->tagname, $this->attrib, $value,
array_merge(self::$common_attrib, $this->allowed));
array_merge(self::$common_attrib, $this->allowed));
}
}
@ -550,7 +592,7 @@ class html_select extends html
protected $options = array();
protected $allowed = array('name','size','tabindex','autocomplete',
'multiple','onchange','disabled','rel');
/**
* Add a new option to this drop-down
*
@ -591,8 +633,9 @@ class html_select extends html
'selected' => (in_array($option['value'], $select, true) ||
in_array($option['text'], $select, true)) ? 1 : null);
$this->content .= self::tag('option', $attr, Q($option['text']));
$this->content .= self::tag('option', $attr, self::quote($option['text']));
}
return parent::show();
}
}
@ -803,4 +846,3 @@ class html_table extends html
}
}

@ -40,7 +40,7 @@ foreach ($crit_opts as $optname => $optval) {
}
// application constants
define('RCMAIL_VERSION', '0.8-svn');
define('RCMAIL_VERSION', '0.9-svn');
define('RCMAIL_CHARSET', 'UTF-8');
define('JS_OBJECT_NAME', 'rcmail');
define('RCMAIL_START', microtime(true));
@ -53,11 +53,6 @@ if (!defined('RCMAIL_CONFIG_DIR')) {
define('RCMAIL_CONFIG_DIR', INSTALL_PATH . 'config');
}
// make sure path_separator is defined
if (!defined('PATH_SEPARATOR')) {
define('PATH_SEPARATOR', (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') ? ';' : ':');
}
// RC include folders MUST be included FIRST to avoid other
// possible not compatible libraries (i.e PEAR) to be included
// instead the ones provided by RC
@ -80,59 +75,14 @@ if (extension_loaded('mbstring')) {
@mb_regex_encoding(RCMAIL_CHARSET);
}
/**
* Use PHP5 autoload for dynamic class loading
*
* @todo Make Zend, PEAR etc play with this
* @todo Make our classes conform to a more straight forward CS.
*/
function rcube_autoload($classname)
{
$filename = preg_replace(
array(
'/MDB2_(.+)/',
'/Mail_(.+)/',
'/Net_(.+)/',
'/Auth_(.+)/',
'/^html_.+/',
'/^utf8$/',
),
array(
'MDB2/\\1',
'Mail/\\1',
'Net/\\1',
'Auth/\\1',
'html',
'utf8.class',
),
$classname
);
if ($fp = @fopen("$filename.php", 'r', true)) {
fclose($fp);
include_once("$filename.php");
return true;
}
return false;
}
// include global functions
require_once INSTALL_PATH . 'program/include/rcube_shared.inc';
// Register autoloader
spl_autoload_register('rcube_autoload');
/**
* Local callback function for PEAR errors
*/
function rcube_pear_error($err)
{
error_log(sprintf("%s (%s): %s",
$err->getMessage(),
$err->getCode(),
$err->getUserinfo()), 0);
}
// set PEAR error handling (will also load the PEAR main class)
PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'rcube_pear_error');
// include global functions
// backward compatybility (to be removed)
require_once INSTALL_PATH . 'program/include/main.inc';
require_once INSTALL_PATH . 'program/include/rcube_shared.inc';

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -211,11 +211,14 @@ abstract class rcube_addressbook
*/
public function validate(&$save_data, $autofix = false)
{
$rcmail = rcmail::get_instance();
// check validity of email addresses
foreach ($this->get_col_values('email', $save_data, true) as $email) {
if (strlen($email)) {
if (!check_email(rcube_idn_to_ascii($email))) {
$this->set_error(self::ERROR_VALIDATE, rcube_label(array('name' => 'emailformaterror', 'vars' => array('email' => $email))));
if (!$rcmail->check_email(rcube_idn_to_ascii($email))) {
$error = $rcmail->gettext(array('name' => 'emailformaterror', 'vars' => array('email' => $email)));
$this->set_error(self::ERROR_VALIDATE, $error);
return false;
}
}

@ -0,0 +1,110 @@
<?php
/*
+-----------------------------------------------------------------------+
| program/include/rcube_base_replacer.php |
| |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2005-2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
| See the README file for a full license statement. |
| |
| PURPOSE: |
| Provide basic functions for base URL replacement |
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
$Id$
*/
/**
* Helper class to turn relative urls into absolute ones
* using a predefined base
*
* @package Core
* @author Thomas Bruederli <roundcube@gmail.com>
*/
class rcube_base_replacer
{
private $base_url;
public function __construct($base)
{
$this->base_url = $base;
}
public function callback($matches)
{
return $matches[1] . '="' . self::absolute_url($matches[3], $this->base_url) . '"';
}
public function replace($body)
{
return preg_replace_callback(array(
'/(src|background|href)=(["\']?)([^"\'\s]+)(\2|\s|>)/Ui',
'/(url\s*\()(["\']?)([^"\'\)\s]+)(\2)\)/Ui',
),
array($this, 'callback'), $body);
}
/**
* Convert paths like ../xxx to an absolute path using a base url
*
* @param string $path Relative path
* @param string $base_url Base URL
*
* @return string Absolute URL
*/
public static function 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;
}
// check if path is a content-id scheme
if (strpos($path, 'cid:') === 0) {
return $path;
}
// cut base_url to the last directory
if (strrpos($base_url, '/') > 7) {
$host_url = substr($base_url, 0, strpos($base_url, '/', 7));
$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;
}
}

@ -66,7 +66,7 @@ class rcube_cache
*/
function __construct($type, $userid, $prefix='', $ttl=0, $packed=true)
{
$rcmail = rcmail::get_instance();
$rcmail = rcube::get_instance();
$type = strtolower($type);
if ($type == 'memcache') {
@ -197,7 +197,7 @@ class rcube_cache
{
if ($this->type == 'db' && $this->db) {
$this->db->query(
"DELETE FROM ".get_table_name('cache').
"DELETE FROM ".$this->db->table_name('cache').
" WHERE user_id = ?".
" AND cache_key LIKE ?".
" AND " . $this->db->unixtimestamp('created')." < ?",
@ -274,7 +274,7 @@ class rcube_cache
else {
$sql_result = $this->db->limitquery(
"SELECT cache_id, data, cache_key".
" FROM ".get_table_name('cache').
" FROM ".$this->db->table_name('cache').
" WHERE user_id = ?".
" AND cache_key = ?".
// for better performance we allow more records for one key
@ -330,7 +330,7 @@ class rcube_cache
// Remove NULL rows (here we don't need to check if the record exist)
if ($data == 'N;') {
$this->db->query(
"DELETE FROM ".get_table_name('cache').
"DELETE FROM ".$this->db->table_name('cache').
" WHERE user_id = ?".
" AND cache_key = ?",
$this->userid, $key);
@ -341,7 +341,7 @@ class rcube_cache
// update existing cache record
if ($key_exists) {
$result = $this->db->query(
"UPDATE ".get_table_name('cache').
"UPDATE ".$this->db->table_name('cache').
" SET created = ". $this->db->now().", data = ?".
" WHERE user_id = ?".
" AND cache_key = ?",
@ -352,7 +352,7 @@ class rcube_cache
// for better performance we allow more records for one key
// so, no need to check if record exist (see rcube_cache::read_record())
$result = $this->db->query(
"INSERT INTO ".get_table_name('cache').
"INSERT INTO ".$this->db->table_name('cache').
" (created, user_id, cache_key, data)".
" VALUES (".$this->db->now().", ?, ?, ?)",
$this->userid, $key, $data);
@ -416,7 +416,7 @@ class rcube_cache
}
$this->db->query(
"DELETE FROM ".get_table_name('cache').
"DELETE FROM ".$this->db->table_name('cache').
" WHERE user_id = ?" . $where,
$this->userid);
}

@ -85,11 +85,11 @@ class rcube_config
// fix default imap folders encoding
foreach (array('drafts_mbox', 'junk_mbox', 'sent_mbox', 'trash_mbox') as $folder)
$this->prop[$folder] = rcube_charset_convert($this->prop[$folder], RCMAIL_CHARSET, 'UTF7-IMAP');
$this->prop[$folder] = rcube_charset::convert($this->prop[$folder], RCMAIL_CHARSET, 'UTF7-IMAP');
if (!empty($this->prop['default_folders']))
foreach ($this->prop['default_folders'] as $n => $folder)
$this->prop['default_folders'][$n] = rcube_charset_convert($folder, RCMAIL_CHARSET, 'UTF7-IMAP');
$this->prop['default_folders'][$n] = rcube_charset::convert($folder, RCMAIL_CHARSET, 'UTF7-IMAP');
// set PHP error logging according to config
if ($this->prop['debug_level'] & 1) {
@ -186,7 +186,7 @@ class rcube_config
$result = $def;
}
$rcmail = rcmail::get_instance();
$rcmail = rcube::get_instance();
if ($name == 'timezone' && isset($this->prop['_timezone_value']))
$result = $this->prop['_timezone_value'];
@ -300,7 +300,7 @@ class rcube_config
{
// Bomb out if the requested key does not exist
if (!array_key_exists($key, $this->prop)) {
raise_error(array(
rcube::raise_error(array(
'code' => 500, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Request for unconfigured crypto key \"$key\""
@ -311,7 +311,7 @@ class rcube_config
// Bomb out if the configured key is not exactly 24 bytes long
if (strlen($key) != 24) {
raise_error(array(
rcube::raise_error(array(
'code' => 500, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Configured crypto key '$key' is not exactly 24 bytes long"
@ -335,7 +335,7 @@ class rcube_config
if ($delim == "\n" || $delim == "\r\n")
return $delim;
else
raise_error(array(
rcube::raise_error(array(
'code' => 500, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Invalid mail_header_delimiter setting"
@ -370,7 +370,7 @@ class rcube_config
$domain = $this->prop['mail_domain'][$host];
}
else if (!empty($this->prop['mail_domain']))
$domain = rcube_parse_host($this->prop['mail_domain']);
$domain = rcmail::parse_host($this->prop['mail_domain']);
if ($encode)
$domain = rcube_idn_to_ascii($domain);

@ -153,7 +153,7 @@ class rcube_contacts extends rcube_addressbook
$sql_filter = $search ? " AND " . $this->db->ilike('name', '%'.$search.'%') : '';
$sql_result = $this->db->query(
"SELECT * FROM ".get_table_name($this->db_groups).
"SELECT * FROM ".$this->db->table_name($this->db_groups).
" WHERE del<>1".
" AND user_id=?".
$sql_filter.
@ -178,7 +178,7 @@ class rcube_contacts extends rcube_addressbook
function get_group($group_id)
{
$sql_result = $this->db->query(
"SELECT * FROM ".get_table_name($this->db_groups).
"SELECT * FROM ".$this->db->table_name($this->db_groups).
" WHERE del<>1".
" AND contactgroup_id=?".
" AND user_id=?",
@ -214,7 +214,7 @@ class rcube_contacts extends rcube_addressbook
$length = $subset != 0 ? abs($subset) : $this->page_size;
if ($this->group_id)
$join = " LEFT JOIN ".get_table_name($this->db_groupmembers)." AS m".
$join = " LEFT JOIN ".$this->db->table_name($this->db_groupmembers)." AS m".
" ON (m.contact_id = c.".$this->primary_key.")";
$order_col = (in_array($this->sort_col, $this->table_cols) ? $this->sort_col : 'name');
@ -228,7 +228,7 @@ class rcube_contacts extends rcube_addressbook
$order_cols[] = 'c.email';
$sql_result = $this->db->limitquery(
"SELECT * FROM ".get_table_name($this->db_name)." AS c" .
"SELECT * FROM ".$this->db->table_name($this->db_name)." AS c" .
$join .
" WHERE c.del<>1" .
" AND c.user_id=?" .
@ -488,13 +488,13 @@ class rcube_contacts extends rcube_addressbook
private function _count()
{
if ($this->group_id)
$join = " LEFT JOIN ".get_table_name($this->db_groupmembers)." AS m".
$join = " LEFT JOIN ".$this->db->table_name($this->db_groupmembers)." AS m".
" ON (m.contact_id=c.".$this->primary_key.")";
// count contacts for this user
$sql_result = $this->db->query(
"SELECT COUNT(c.contact_id) AS rows".
" FROM ".get_table_name($this->db_name)." AS c".
" FROM ".$this->db->table_name($this->db_name)." AS c".
$join.
" WHERE c.del<>1".
" AND c.user_id=?".
@ -536,7 +536,7 @@ class rcube_contacts extends rcube_addressbook
return $assoc ? $first : $this->result;
$this->db->query(
"SELECT * FROM ".get_table_name($this->db_name).
"SELECT * FROM ".$this->db->table_name($this->db_name).
" WHERE contact_id=?".
" AND user_id=?".
" AND del<>1",
@ -568,8 +568,8 @@ class rcube_contacts extends rcube_addressbook
return $results;
$sql_result = $this->db->query(
"SELECT cgm.contactgroup_id, cg.name FROM " . get_table_name($this->db_groupmembers) . " AS cgm" .
" LEFT JOIN " . get_table_name($this->db_groups) . " AS cg ON (cgm.contactgroup_id = cg.contactgroup_id AND cg.del<>1)" .
"SELECT cgm.contactgroup_id, cg.name FROM " . $this->db->table_name($this->db_groupmembers) . " AS cgm" .
" LEFT JOIN " . $this->db->table_name($this->db_groups) . " AS cg ON (cgm.contactgroup_id = cg.contactgroup_id AND cg.del<>1)" .
" WHERE cgm.contact_id=?",
$id
);
@ -638,7 +638,7 @@ class rcube_contacts extends rcube_addressbook
if (!$existing->count && !empty($a_insert_cols)) {
$this->db->query(
"INSERT INTO ".get_table_name($this->db_name).
"INSERT INTO ".$this->db->table_name($this->db_name).
" (user_id, changed, del, ".join(', ', $a_insert_cols).")".
" VALUES (".intval($this->user_id).", ".$this->db->now().", 0, ".join(', ', $a_insert_values).")"
);
@ -676,7 +676,7 @@ class rcube_contacts extends rcube_addressbook
if (!empty($write_sql)) {
$this->db->query(
"UPDATE ".get_table_name($this->db_name).
"UPDATE ".$this->db->table_name($this->db_name).
" SET changed=".$this->db->now().", ".join(', ', $write_sql).
" WHERE contact_id=?".
" AND user_id=?".
@ -772,7 +772,7 @@ class rcube_contacts extends rcube_addressbook
// flag record as deleted (always)
$this->db->query(
"UPDATE ".get_table_name($this->db_name).
"UPDATE ".$this->db->table_name($this->db_name).
" SET del=1, changed=".$this->db->now().
" WHERE user_id=?".
" AND contact_id IN ($ids)",
@ -799,7 +799,7 @@ class rcube_contacts extends rcube_addressbook
// clear deleted flag
$this->db->query(
"UPDATE ".get_table_name($this->db_name).
"UPDATE ".$this->db->table_name($this->db_name).
" SET del=0, changed=".$this->db->now().
" WHERE user_id=?".
" AND contact_id IN ($ids)",
@ -819,7 +819,7 @@ class rcube_contacts extends rcube_addressbook
{
$this->cache = null;
$this->db->query("UPDATE ".get_table_name($this->db_name).
$this->db->query("UPDATE ".$this->db->table_name($this->db_name).
" SET del=1, changed=".$this->db->now().
" WHERE user_id = ?", $this->user_id);
@ -841,7 +841,7 @@ class rcube_contacts extends rcube_addressbook
$name = $this->unique_groupname($name);
$this->db->query(
"INSERT INTO ".get_table_name($this->db_groups).
"INSERT INTO ".$this->db->table_name($this->db_groups).
" (user_id, changed, name)".
" VALUES (".intval($this->user_id).", ".$this->db->now().", ".$this->db->quote($name).")"
);
@ -863,7 +863,7 @@ class rcube_contacts extends rcube_addressbook
{
// flag group record as deleted
$sql_result = $this->db->query(
"UPDATE ".get_table_name($this->db_groups).
"UPDATE ".$this->db->table_name($this->db_groups).
" SET del=1, changed=".$this->db->now().
" WHERE contactgroup_id=?".
" AND user_id=?",
@ -889,7 +889,7 @@ class rcube_contacts extends rcube_addressbook
$name = $this->unique_groupname($newname);
$sql_result = $this->db->query(
"UPDATE ".get_table_name($this->db_groups).
"UPDATE ".$this->db->table_name($this->db_groups).
" SET name=?, changed=".$this->db->now().
" WHERE contactgroup_id=?".
" AND user_id=?",
@ -917,7 +917,7 @@ class rcube_contacts extends rcube_addressbook
// get existing assignments ...
$sql_result = $this->db->query(
"SELECT contact_id FROM ".get_table_name($this->db_groupmembers).
"SELECT contact_id FROM ".$this->db->table_name($this->db_groupmembers).
" WHERE contactgroup_id=?".
" AND contact_id IN (".$this->db->array2list($ids, 'integer').")",
$group_id
@ -930,7 +930,7 @@ class rcube_contacts extends rcube_addressbook
foreach ($ids as $contact_id) {
$this->db->query(
"INSERT INTO ".get_table_name($this->db_groupmembers).
"INSERT INTO ".$this->db->table_name($this->db_groupmembers).
" (contactgroup_id, contact_id, created)".
" VALUES (?, ?, ".$this->db->now().")",
$group_id,
@ -960,7 +960,7 @@ class rcube_contacts extends rcube_addressbook
$ids = $this->db->array2list($ids, 'integer');
$sql_result = $this->db->query(
"DELETE FROM ".get_table_name($this->db_groupmembers).
"DELETE FROM ".$this->db->table_name($this->db_groupmembers).
" WHERE contactgroup_id=?".
" AND contact_id IN ($ids)",
$group_id
@ -983,7 +983,7 @@ class rcube_contacts extends rcube_addressbook
do {
$sql_result = $this->db->query(
"SELECT 1 FROM ".get_table_name($this->db_groups).
"SELECT 1 FROM ".$this->db->table_name($this->db_groups).
" WHERE del<>1".
" AND user_id=?".
" AND name=?",

@ -1,323 +0,0 @@
<?php
/*
+-----------------------------------------------------------------------+
| program/include/rcube_html_page.php |
| |
| This file is part of the Roundcube PHP suite |
| Copyright (C) 2005-2011 The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
| See the README file for a full license statement. |
| |
| CONTENTS: |
| Class to build XHTML page output |
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
$Id$
*/
/**
* Class for HTML page creation
*
* @package HTML
*/
class rcube_html_page
{
protected $scripts_path = '';
protected $script_files = array();
protected $css_files = array();
protected $scripts = array();
protected $charset = RCMAIL_CHARSET;
protected $default_template = "<html>\n<head><title></title></head>\n<body></body>\n</html>";
protected $title = '';
protected $header = '';
protected $footer = '';
protected $body = '';
protected $base_path = '';
/** Constructor */
public function __construct() {}
/**
* Link an external script file
*
* @param string File URL
* @param string Target position [head|foot]
*/
public function include_script($file, $position='head')
{
static $sa_files = array();
if (!preg_match('|^https?://|i', $file) && $file[0] != '/') {
$file = $this->scripts_path . $file;
if ($fs = @filemtime($file)) {
$file .= '?s=' . $fs;
}
}
if (in_array($file, $sa_files)) {
return;
}
$sa_files[] = $file;
if (!is_array($this->script_files[$position])) {
$this->script_files[$position] = array();
}
$this->script_files[$position][] = $file;
}
/**
* Add inline javascript code
*
* @param string JS code snippet
* @param string Target position [head|head_top|foot]
*/
public function add_script($script, $position='head')
{
if (!isset($this->scripts[$position])) {
$this->scripts[$position] = "\n" . rtrim($script);
}
else {
$this->scripts[$position] .= "\n" . rtrim($script);
}
}
/**
* Link an external css file
*
* @param string File URL
*/
public function include_css($file)
{
$this->css_files[] = $file;
}
/**
* Add HTML code to the page header
*
* @param string $str HTML code
*/
public function add_header($str)
{
$this->header .= "\n" . $str;
}
/**
* Add HTML code to the page footer
* To be added right befor </body>
*
* @param string $str HTML code
*/
public function add_footer($str)
{
$this->footer .= "\n" . $str;
}
/**
* Setter for page title
*
* @param string $t Page title
*/
public function set_title($t)
{
$this->title = $t;
}
/**
* Setter for output charset.
* To be specified in a meta tag and sent as http-header
*
* @param string $charset Charset
*/
public function set_charset($charset)
{
$this->charset = $charset;
}
/**
* Getter for output charset
*
* @return string Output charset
*/
public function get_charset()
{
return $this->charset;
}
/**
* Reset all saved properties
*/
public function reset()
{
$this->script_files = array();
$this->scripts = array();
$this->title = '';
$this->header = '';
$this->footer = '';
$this->body = '';
}
/**
* Process template and write to stdOut
*
* @param string HTML template
* @param string Base for absolute paths
*/
public function write($templ='', $base_path='')
{
$output = empty($templ) ? $this->default_template : trim($templ);
// set default page title
if (empty($this->title)) {
$this->title = 'Roundcube Mail';
}
// replace specialchars in content
$page_title = Q($this->title, 'show', FALSE);
$page_header = '';
$page_footer = '';
// include meta tag with charset
if (!empty($this->charset)) {
if (!headers_sent()) {
header('Content-Type: text/html; charset=' . $this->charset);
}
$page_header = '<meta http-equiv="content-type"';
$page_header.= ' content="text/html; charset=';
$page_header.= $this->charset . '" />'."\n";
}
// definition of the code to be placed in the document header and footer
if (is_array($this->script_files['head'])) {
foreach ($this->script_files['head'] as $file) {
$page_header .= html::script($file);
}
}
$head_script = $this->scripts['head_top'] . $this->scripts['head'];
if (!empty($head_script)) {
$page_header .= html::script(array(), $head_script);
}
if (!empty($this->header)) {
$page_header .= $this->header;
}
// put docready commands into page footer
if (!empty($this->scripts['docready'])) {
$this->add_script('$(document).ready(function(){ ' . $this->scripts['docready'] . "\n});", 'foot');
}
if (is_array($this->script_files['foot'])) {
foreach ($this->script_files['foot'] as $file) {
$page_footer .= html::script($file);
}
}
if (!empty($this->footer)) {
$page_footer .= $this->footer . "\n";
}
if (!empty($this->scripts['foot'])) {
$page_footer .= html::script(array(), $this->scripts['foot']);
}
// find page header
if ($hpos = stripos($output, '</head>')) {
$page_header .= "\n";
}
else {
if (!is_numeric($hpos)) {
$hpos = stripos($output, '<body');
}
if (!is_numeric($hpos) && ($hpos = stripos($output, '<html'))) {
while ($output[$hpos] != '>') {
$hpos++;
}
$hpos++;
}
$page_header = "<head>\n<title>$page_title</title>\n$page_header\n</head>\n";
}
// add page hader
if ($hpos) {
$output = substr_replace($output, $page_header, $hpos, 0);
}
else {
$output = $page_header . $output;
}
// add page footer
if (($fpos = strripos($output, '</body>')) || ($fpos = strripos($output, '</html>'))) {
$output = substr_replace($output, $page_footer."\n", $fpos, 0);
}
else {
$output .= "\n".$page_footer;
}
// add css files in head, before scripts, for speed up with parallel downloads
if (!empty($this->css_files) &&
(($pos = stripos($output, '<script ')) || ($pos = stripos($output, '</head>')))
) {
$css = '';
foreach ($this->css_files as $file) {
$css .= html::tag('link', array('rel' => 'stylesheet',
'type' => 'text/css', 'href' => $file, 'nl' => true));
}
$output = substr_replace($output, $css, $pos, 0);
}
$this->base_path = $base_path;
// correct absolute paths in images and other tags
// add timestamp to .js and .css filename
$output = preg_replace_callback(
'!(src|href|background)=(["\']?)([a-z0-9/_.-]+)(["\'\s>])!i',
array($this, 'file_callback'), $output);
// trigger hook with final HTML content to be sent
$hook = rcmail::get_instance()->plugins->exec_hook("send_page", array('content' => $output));
if (!$hook['abort']) {
if ($this->charset != RCMAIL_CHARSET) {
echo rcube_charset_convert($hook['content'], RCMAIL_CHARSET, $this->charset);
}
else {
echo $hook['content'];
}
}
}
/**
* Callback function for preg_replace_callback in write()
*
* @return string Parsed string
*/
private function file_callback($matches)
{
$file = $matches[3];
// correct absolute paths
if ($file[0] == '/') {
$file = $this->base_path . $file;
}
// add file modification timestamp
if (preg_match('/\.(js|css)$/', $file)) {
if ($fs = @filemtime($file)) {
$file .= '?s=' . $fs;
}
}
return $matches[1] . '=' . $matches[2] . $file . $matches[4];
}
}

@ -132,7 +132,7 @@ class rcube_imap extends rcube_storage
$this->options['ssl_mode'] = $use_ssl == 'imaps' ? 'ssl' : $use_ssl;
}
else if ($use_ssl) {
raise_error(array('code' => 403, 'type' => 'imap',
rcube::raise_error(array('code' => 403, 'type' => 'imap',
'file' => __FILE__, 'line' => __LINE__,
'message' => "OpenSSL not available"), true, false);
$port = 143;
@ -154,7 +154,7 @@ class rcube_imap extends rcube_storage
$attempt = 0;
do {
$data = rcmail::get_instance()->plugins->exec_hook('imap_connect',
$data = rcube::get_instance()->plugins->exec_hook('imap_connect',
array_merge($this->options, array('host' => $host, 'user' => $user,
'attempt' => ++$attempt)));
@ -185,9 +185,9 @@ class rcube_imap extends rcube_storage
else if ($this->conn->error) {
if ($pass && $user) {
$message = sprintf("Login failed for %s from %s. %s",
$user, rcmail_remote_ip(), $this->conn->error);
$user, rcmail::remote_ip(), $this->conn->error);
raise_error(array('code' => 403, 'type' => 'imap',
rcube::raise_error(array('code' => 403, 'type' => 'imap',
'file' => __FILE__, 'line' => __LINE__,
'message' => $message), true, false);
}
@ -457,7 +457,7 @@ class rcube_imap extends rcube_storage
return;
}
$config = rcmail::get_instance()->config;
$config = rcube::get_instance()->config;
$imap_personal = $config->get('imap_ns_personal');
$imap_other = $config->get('imap_ns_other');
$imap_shared = $config->get('imap_ns_shared');
@ -546,7 +546,7 @@ class rcube_imap extends rcube_storage
$folder = $this->folder;
}
return $this->messagecount($folder, $mode, $force, $status);
return $this->countmessages($folder, $mode, $force, $status);
}
@ -562,7 +562,7 @@ class rcube_imap extends rcube_storage
* @return int Number of messages
* @see rcube_imap::count()
*/
protected function messagecount($folder, $mode='ALL', $force=false, $status=true)
protected function countmessages($folder, $mode='ALL', $force=false, $status=true)
{
$mode = strtoupper($mode);
@ -834,8 +834,8 @@ class rcube_imap extends rcube_storage
* protected method for setting threaded messages flags:
* depth, has_children and unread_children
*
* @param array $headers Reference to headers array indexed by message UID
* @param rcube_imap_result $threads Threads data object
* @param array $headers Reference to headers array indexed by message UID
* @param rcube_result_thread $threads Threads data object
*
* @return array Message headers array indexed by message UID
*/
@ -1048,7 +1048,7 @@ class rcube_imap extends rcube_storage
if ($sort) {
// use this class for message sorting
$sorter = new rcube_header_sorter();
$sorter = new rcube_message_header_sorter();
$sorter->set_index($msgs);
$sorter->sort_headers($a_msg_headers);
}
@ -1075,7 +1075,7 @@ class rcube_imap extends rcube_storage
$old = $this->get_folder_stats($folder);
// refresh message count -> will update
$this->messagecount($folder, 'ALL', true);
$this->countmessages($folder, 'ALL', true);
$result = 0;
@ -1456,7 +1456,7 @@ class rcube_imap extends rcube_storage
foreach ($matches[1] as $m) {
$string_offset = $m[1] + strlen($m[0]) + 4; // {}\r\n
$string = substr($str, $string_offset - 1, $m[0]);
$string = rcube_charset_convert($string, $charset, $dest_charset);
$string = rcube_charset::convert($string, $charset, $dest_charset);
if ($string === false) {
continue;
}
@ -1498,7 +1498,7 @@ class rcube_imap extends rcube_storage
* @param string $folder Folder to read from
* @param bool $force True to skip cache
*
* @return rcube_mail_header Message headers
* @return rcube_message_header Message headers
*/
public function get_message_headers($uid, $folder = null, $force = false)
{
@ -1529,7 +1529,7 @@ class rcube_imap extends rcube_storage
* @param int $uid Message UID to fetch
* @param string $folder Folder to read from
*
* @return object rcube_mail_header Message data
* @return object rcube_message_header Message data
*/
public function get_message($uid, $folder = null)
{
@ -1948,7 +1948,7 @@ class rcube_imap extends rcube_storage
$charset = $this->struct_charset;
}
else {
$charset = rc_detect_encoding($filename_mime, $this->default_charset);
$charset = rcube_charset::detect($filename_mime, $this->default_charset);
}
$part->filename = rcube_mime::decode_mime_string($filename_mime, $charset);
@ -1960,7 +1960,7 @@ class rcube_imap extends rcube_storage
$filename_encoded = $fmatches[2];
}
$part->filename = rcube_charset_convert(urldecode($filename_encoded), $filename_charset);
$part->filename = rcube_charset::convert(urldecode($filename_encoded), $filename_charset);
}
}
@ -2039,7 +2039,7 @@ class rcube_imap extends rcube_storage
$o_part->charset = $this->default_charset;
}
}
$body = rcube_charset_convert($body, $o_part->charset);
$body = rcube_charset::convert($body, $o_part->charset);
}
}
@ -2227,7 +2227,7 @@ class rcube_imap extends rcube_storage
}
}
$config = rcmail::get_instance()->config;
$config = rcube::get_instance()->config;
$to_trash = $to_mbox == $config->get('trash_mbox');
// flag messages as read before moving them
@ -2510,7 +2510,7 @@ class rcube_imap extends rcube_storage
$a_defaults = $a_out = array();
// Give plugins a chance to provide a list of folders
$data = rcmail::get_instance()->plugins->exec_hook('storage_folders',
$data = rcube::get_instance()->plugins->exec_hook('storage_folders',
array('root' => $root, 'name' => $name, 'filter' => $filter, 'mode' => 'LSUB'));
if (isset($data['folders'])) {
@ -2521,7 +2521,7 @@ class rcube_imap extends rcube_storage
}
else {
// Server supports LIST-EXTENDED, we can use selection options
$config = rcmail::get_instance()->config;
$config = rcube::get_instance()->config;
// #1486225: Some dovecot versions returns wrong result using LIST-EXTENDED
if (!$config->get('imap_force_lsub') && $this->get_capability('LIST-EXTENDED')) {
// This will also set folder options, LSUB doesn't do that
@ -3530,7 +3530,7 @@ class rcube_imap extends rcube_storage
protected function get_cache_engine()
{
if ($this->caching && !$this->cache) {
$rcmail = rcmail::get_instance();
$rcmail = rcube::get_instance();
$ttl = $rcmail->config->get('message_cache_lifetime', '10d') - mktime();
$this->cache = $rcmail->get_cache('IMAP', $this->caching, $ttl);
}
@ -3589,8 +3589,9 @@ class rcube_imap extends rcube_storage
$this->mcache->expunge($ttl);
}
if ($this->cache)
if ($this->cache) {
$this->cache->expunge();
}
}
@ -3624,10 +3625,10 @@ class rcube_imap extends rcube_storage
protected function get_mcache_engine()
{
if ($this->messages_caching && !$this->mcache) {
$rcmail = rcmail::get_instance();
$rcmail = rcube::get_instance();
if ($dbh = $rcmail->get_dbh()) {
$this->mcache = new rcube_imap_cache(
$dbh, $this, $rcmail->user->ID, $this->options['skip_deleted']);
$dbh, $this, $rcmail->get_user_id(), $this->options['skip_deleted']);
}
}
@ -3691,7 +3692,7 @@ class rcube_imap extends rcube_storage
$a_defaults[$p] = $folder;
}
else {
$folders[$folder] = rcube_charset_convert($folder, 'UTF7-IMAP');
$folders[$folder] = rcube_charset::convert($folder, 'UTF7-IMAP');
}
}
@ -3851,7 +3852,7 @@ class rcube_imap extends rcube_storage
*/
public function debug_handler(&$imap, $message)
{
write_log('imap', $message);
rcmail::write_log('imap', $message);
}

@ -95,7 +95,7 @@ class rcube_imap_cache
{
$this->db = $db;
$this->imap = $imap;
$this->userid = (int)$userid;
$this->userid = $userid;
$this->skip_deleted = $skip_deleted;
}
@ -290,7 +290,7 @@ class rcube_imap_cache
* @param string $mailbox Folder name
* @param array $msgs Message UIDs
*
* @return array The list of messages (rcube_mail_header) indexed by UID
* @return array The list of messages (rcube_message_header) indexed by UID
*/
function get_messages($mailbox, $msgs = array())
{
@ -301,7 +301,7 @@ class rcube_imap_cache
// Fetch messages from cache
$sql_result = $this->db->query(
"SELECT uid, data, flags"
." FROM ".get_table_name('cache_messages')
." FROM ".$this->db->table_name('cache_messages')
." WHERE user_id = ?"
." AND mailbox = ?"
." AND uid IN (".$this->db->array2list($msgs, 'integer').")",
@ -348,7 +348,7 @@ class rcube_imap_cache
* from IMAP server
* @param bool $no_cache Enables internal cache usage
*
* @return rcube_mail_header Message data
* @return rcube_message_header Message data
*/
function get_message($mailbox, $uid, $update = true, $cache = true)
{
@ -362,7 +362,7 @@ class rcube_imap_cache
$sql_result = $this->db->query(
"SELECT flags, data"
." FROM ".get_table_name('cache_messages')
." FROM ".$this->db->table_name('cache_messages')
." WHERE user_id = ?"
." AND mailbox = ?"
." AND uid = ?",
@ -404,9 +404,9 @@ class rcube_imap_cache
/**
* Saves the message in cache.
*
* @param string $mailbox Folder name
* @param rcube_mail_header $message Message data
* @param bool $force Skips message in-cache existance check
* @param string $mailbox Folder name
* @param rcube_message_header $message Message data
* @param bool $force Skips message in-cache existance check
*/
function add_message($mailbox, $message, $force = false)
{
@ -430,7 +430,7 @@ class rcube_imap_cache
// here will work as select, assume row exist if affected_rows=0)
if (!$force) {
$res = $this->db->query(
"UPDATE ".get_table_name('cache_messages')
"UPDATE ".$this->db->table_name('cache_messages')
." SET flags = ?, data = ?, changed = ".$this->db->now()
." WHERE user_id = ?"
." AND mailbox = ?"
@ -444,7 +444,7 @@ class rcube_imap_cache
// insert new record
$this->db->query(
"INSERT INTO ".get_table_name('cache_messages')
"INSERT INTO ".$this->db->table_name('cache_messages')
." (user_id, mailbox, uid, flags, changed, data)"
." VALUES (?, ?, ?, ?, ".$this->db->now().", ?)",
$this->userid, $mailbox, (int) $message->uid, $flags, $msg);
@ -479,7 +479,7 @@ class rcube_imap_cache
}
$this->db->query(
"UPDATE ".get_table_name('cache_messages')
"UPDATE ".$this->db->table_name('cache_messages')
." SET changed = ".$this->db->now()
.", flags = flags ".($enabled ? "+ $idx" : "- $idx")
." WHERE user_id = ?"
@ -500,7 +500,7 @@ class rcube_imap_cache
{
if (!strlen($mailbox)) {
$this->db->query(
"DELETE FROM ".get_table_name('cache_messages')
"DELETE FROM ".$this->db->table_name('cache_messages')
." WHERE user_id = ?",
$this->userid);
}
@ -513,11 +513,11 @@ class rcube_imap_cache
}
$this->db->query(
"DELETE FROM ".get_table_name('cache_messages')
"DELETE FROM ".$this->db->table_name('cache_messages')
." WHERE user_id = ?"
." AND mailbox = ".$this->db->quote($mailbox)
." AND mailbox = ?"
.($uids !== null ? " AND uid IN (".$this->db->array2list((array)$uids, 'integer').")" : ""),
$this->userid);
$this->userid, $mailbox);
}
}
@ -536,17 +536,19 @@ class rcube_imap_cache
// otherwise use 'valid' flag to not loose HIGHESTMODSEQ value
if ($remove) {
$this->db->query(
"DELETE FROM ".get_table_name('cache_index')
." WHERE user_id = ".intval($this->userid)
.(strlen($mailbox) ? " AND mailbox = ".$this->db->quote($mailbox) : "")
"DELETE FROM ".$this->db->table_name('cache_index')
." WHERE user_id = ?"
.(strlen($mailbox) ? " AND mailbox = ".$this->db->quote($mailbox) : ""),
$this->userid
);
}
else {
$this->db->query(
"UPDATE ".get_table_name('cache_index')
"UPDATE ".$this->db->table_name('cache_index')
." SET valid = 0"
." WHERE user_id = ".intval($this->userid)
.(strlen($mailbox) ? " AND mailbox = ".$this->db->quote($mailbox) : "")
." WHERE user_id = ?"
.(strlen($mailbox) ? " AND mailbox = ".$this->db->quote($mailbox) : ""),
$this->userid
);
}
@ -569,9 +571,10 @@ class rcube_imap_cache
function remove_thread($mailbox = null)
{
$this->db->query(
"DELETE FROM ".get_table_name('cache_thread')
." WHERE user_id = ".intval($this->userid)
.(strlen($mailbox) ? " AND mailbox = ".$this->db->quote($mailbox) : "")
"DELETE FROM ".$this->db->table_name('cache_thread')
." WHERE user_id = ?"
.(strlen($mailbox) ? " AND mailbox = ".$this->db->quote($mailbox) : ""),
$this->userid
);
if (strlen($mailbox)) {
@ -628,7 +631,7 @@ class rcube_imap_cache
// Get index from DB
$sql_result = $this->db->query(
"SELECT data, valid"
." FROM ".get_table_name('cache_index')
." FROM ".$this->db->table_name('cache_index')
." WHERE user_id = ?"
." AND mailbox = ?",
$this->userid, $mailbox);
@ -665,7 +668,7 @@ class rcube_imap_cache
// Get thread from DB
$sql_result = $this->db->query(
"SELECT data"
." FROM ".get_table_name('cache_thread')
." FROM ".$this->db->table_name('cache_thread')
." WHERE user_id = ?"
." AND mailbox = ?",
$this->userid, $mailbox);
@ -709,7 +712,7 @@ class rcube_imap_cache
if ($exists) {
$sql_result = $this->db->query(
"UPDATE ".get_table_name('cache_index')
"UPDATE ".$this->db->table_name('cache_index')
." SET data = ?, valid = 1, changed = ".$this->db->now()
." WHERE user_id = ?"
." AND mailbox = ?",
@ -717,7 +720,7 @@ class rcube_imap_cache
}
else {
$sql_result = $this->db->query(
"INSERT INTO ".get_table_name('cache_index')
"INSERT INTO ".$this->db->table_name('cache_index')
." (user_id, mailbox, data, valid, changed)"
." VALUES (?, ?, ?, 1, ".$this->db->now().")",
$this->userid, $mailbox, $data);
@ -740,7 +743,7 @@ class rcube_imap_cache
if ($exists) {
$sql_result = $this->db->query(
"UPDATE ".get_table_name('cache_thread')
"UPDATE ".$this->db->table_name('cache_thread')
." SET data = ?, changed = ".$this->db->now()
." WHERE user_id = ?"
." AND mailbox = ?",
@ -748,7 +751,7 @@ class rcube_imap_cache
}
else {
$sql_result = $this->db->query(
"INSERT INTO ".get_table_name('cache_thread')
"INSERT INTO ".$this->db->table_name('cache_thread')
." (user_id, mailbox, data, changed)"
." VALUES (?, ?, ?, ".$this->db->now().")",
$this->userid, $mailbox, $data);
@ -956,7 +959,7 @@ class rcube_imap_cache
$uids = array();
$sql_result = $this->db->query(
"SELECT uid"
." FROM ".get_table_name('cache_messages')
." FROM ".$this->db->table_name('cache_messages')
." WHERE user_id = ?"
." AND mailbox = ?",
$this->userid, $mailbox);
@ -1003,7 +1006,7 @@ class rcube_imap_cache
}
$this->db->query(
"UPDATE ".get_table_name('cache_messages')
"UPDATE ".$this->db->table_name('cache_messages')
." SET flags = ?, changed = ".$this->db->now()
." WHERE user_id = ?"
." AND mailbox = ?"
@ -1058,7 +1061,7 @@ class rcube_imap_cache
*
* @param array $sql_arr Message row data
*
* @return rcube_mail_header Message object
* @return rcube_message_header Message object
*/
private function build_message($sql_arr)
{

@ -29,42 +29,9 @@
*/
/**
* Struct representing an e-mail message header
*
* @package Mail
* @author Aleksander Machniak <alec@alec.pl>
*/
class rcube_mail_header
{
public $id;
public $uid;
public $subject;
public $from;
public $to;
public $cc;
public $replyto;
public $in_reply_to;
public $date;
public $messageID;
public $size;
public $encoding;
public $charset;
public $ctype;
public $timestamp;
public $bodystructure;
public $internaldate;
public $references;
public $priority;
public $mdn_to;
public $others = array();
public $flags = array();
}
// for backward copat.
class rcube_mail_header extends rcube_message_header { }
// For backward compatibility with cached messages (#1486602)
class iilBasicHeader extends rcube_mail_header
{
}
/**
* PHP based wrapper class to connect to an IMAP server
@ -1545,8 +1512,6 @@ class rcube_imap_generic
*/
function sort($mailbox, $field, $add='', $return_uid=false, $encoding = 'US-ASCII')
{
require_once dirname(__FILE__) . '/rcube_result_index.php';
$field = strtoupper($field);
if ($field == 'INTERNALDATE') {
$field = 'ARRIVAL';
@ -1595,8 +1560,6 @@ class rcube_imap_generic
*/
function thread($mailbox, $algorithm='REFERENCES', $criteria='', $return_uid=false, $encoding='US-ASCII')
{
require_once dirname(__FILE__) . '/rcube_result_thread.php';
$old_sel = $this->selected;
if (!$this->select($mailbox)) {
@ -1635,8 +1598,6 @@ class rcube_imap_generic
*/
function search($mailbox, $criteria, $return_uid=false, $items=array())
{
require_once dirname(__FILE__) . '/rcube_result_index.php';
$old_sel = $this->selected;
if (!$this->select($mailbox)) {
@ -1696,8 +1657,6 @@ class rcube_imap_generic
function index($mailbox, $message_set, $index_field='', $skip_deleted=true,
$uidfetch=false, $return_uid=false)
{
require_once dirname(__FILE__) . '/rcube_result_index.php';
$msg_index = $this->fetchHeaderIndex($mailbox, $message_set,
$index_field, $skip_deleted, $uidfetch, $return_uid);
@ -2034,7 +1993,7 @@ class rcube_imap_generic
* @param string $mod_seq Modification sequence for CHANGEDSINCE (RFC4551) query
* @param bool $vanished Enables VANISHED parameter (RFC5162) for CHANGEDSINCE query
*
* @return array List of rcube_mail_header elements, False on error
* @return array List of rcube_message_header elements, False on error
* @since 0.6
*/
function fetch($mailbox, $message_set, $is_uid = false, $query_items = array(),
@ -2074,7 +2033,7 @@ class rcube_imap_generic
if (preg_match('/^\* ([0-9]+) FETCH/', $line, $m)) {
$id = intval($m[1]);
$result[$id] = new rcube_mail_header;
$result[$id] = new rcube_message_header;
$result[$id]->id = $id;
$result[$id]->subject = '';
$result[$id]->messageID = 'mid:' . $id;

@ -63,12 +63,11 @@ class rcube_ldap extends rcube_addressbook
/**
* Object constructor
*
* @param array LDAP connection properties
* @param boolean Enables debug mode
* @param string Current user mail domain name
* @param integer User-ID
* @param array $p LDAP connection properties
* @param boolean $debug Enables debug mode
* @param string $mail_domain Current user mail domain name
*/
function __construct($p, $debug=false, $mail_domain=NULL)
function __construct($p, $debug = false, $mail_domain = null)
{
$this->prop = $p;
@ -176,10 +175,10 @@ class rcube_ldap extends rcube_addressbook
*/
private function _connect()
{
global $RCMAIL;
$RCMAIL = rcmail::get_instance();
if (!function_exists('ldap_connect'))
raise_error(array('code' => 100, 'type' => 'ldap',
rcube::raise_error(array('code' => 100, 'type' => 'ldap',
'file' => __FILE__, 'line' => __LINE__,
'message' => "No ldap support in this installation of PHP"),
true, true);
@ -195,7 +194,7 @@ class rcube_ldap extends rcube_addressbook
foreach ($this->prop['hosts'] as $host)
{
$host = idn_to_ascii(rcube_parse_host($host));
$host = idn_to_ascii(rcmail::parse_host($host));
$hostname = $host.($this->prop['port'] ? ':'.$this->prop['port'] : '');
$this->_debug("C: Connect [$hostname] [{$this->prop['name']}]");
@ -225,7 +224,7 @@ class rcube_ldap extends rcube_addressbook
}
if (!is_resource($this->conn)) {
raise_error(array('code' => 100, 'type' => 'ldap',
rcube::raise_error(array('code' => 100, 'type' => 'ldap',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Could not connect to any LDAP server, last tried $hostname"), true);
@ -248,7 +247,7 @@ class rcube_ldap extends rcube_addressbook
}
// Get the pieces needed for variable replacement.
if ($fu = $RCMAIL->user->get_username())
if ($fu = $RCMAIL->get_user_name())
list($u, $d) = explode('@', $fu);
else
$d = $this->mail_domain;
@ -287,7 +286,7 @@ class rcube_ldap extends rcube_addressbook
if (!empty($this->prop['search_dn_default']))
$replaces['%dn'] = $this->prop['search_dn_default'];
else {
raise_error(array(
rcube::raise_error(array(
'code' => 100, 'type' => 'ldap',
'file' => __FILE__, 'line' => __LINE__,
'message' => "DN not found using LDAP search."), true);
@ -341,7 +340,7 @@ class rcube_ldap extends rcube_addressbook
}
if (!function_exists('ldap_sasl_bind')) {
raise_error(array('code' => 100, 'type' => 'ldap',
rcube::raise_error(array('code' => 100, 'type' => 'ldap',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Unable to bind: ldap_sasl_bind() not exists"),
true, true);
@ -367,7 +366,7 @@ class rcube_ldap extends rcube_addressbook
$this->_debug("S: ".ldap_error($this->conn));
raise_error(array(
rcube::raise_error(array(
'code' => ldap_errno($this->conn), 'type' => 'ldap',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Bind failed for authcid=$authc ".ldap_error($this->conn)),
@ -400,7 +399,7 @@ class rcube_ldap extends rcube_addressbook
$this->_debug("S: ".ldap_error($this->conn));
raise_error(array(
rcube::raise_error(array(
'code' => ldap_errno($this->conn), 'type' => 'ldap',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Bind failed for dn=$dn: ".ldap_error($this->conn)),
@ -1562,8 +1561,9 @@ class rcube_ldap extends rcube_addressbook
*/
private function _debug($str)
{
if ($this->debug)
write_log('ldap', $str);
if ($this->debug) {
rcmail::write_log('ldap', $str);
}
}

@ -59,10 +59,11 @@ class rcube_mdb2
* @param string $db_dsnw DSN for read/write operations
* @param string $db_dsnr Optional DSN for read only operations
*/
function __construct($db_dsnw, $db_dsnr='', $pconn=false)
public function __construct($db_dsnw, $db_dsnr='', $pconn=false)
{
if (empty($db_dsnr))
if (empty($db_dsnr)) {
$db_dsnr = $db_dsnw;
}
$this->db_dsnw = $db_dsnw;
$this->db_dsnr = $db_dsnr;
@ -88,7 +89,8 @@ class rcube_mdb2
'emulate_prepared' => $this->debug_mode,
'debug' => $this->debug_mode,
'debug_handler' => array($this, 'debug_handler'),
'portability' => MDB2_PORTABILITY_ALL ^ MDB2_PORTABILITY_EMPTY_TO_NULL);
'portability' => MDB2_PORTABILITY_ALL ^ MDB2_PORTABILITY_EMPTY_TO_NULL,
);
if ($this->db_provider == 'pgsql') {
$db_options['disable_smart_seqname'] = true;
@ -103,17 +105,19 @@ class rcube_mdb2
$this->db_error = true;
$this->db_error_msg = $dbh->getMessage();
raise_error(array('code' => 500, 'type' => 'db',
rcube::raise_error(array('code' => 500, 'type' => 'db',
'line' => __LINE__, 'file' => __FILE__,
'message' => $dbh->getUserInfo()), true, false);
}
else if ($this->db_provider == 'sqlite') {
$dsn_array = MDB2::parseDSN($dsn);
if (!filesize($dsn_array['database']) && !empty($this->sqlite_initials))
$this->_sqlite_create_database($dbh, $this->sqlite_initials);
if (!filesize($dsn_array['database']) && !empty($this->sqlite_initials)) {
$this->sqlite_create_database($dbh, $this->sqlite_initials);
}
}
else if ($this->db_provider!='mssql' && $this->db_provider!='sqlsrv')
else if ($this->db_provider != 'mssql' && $this->db_provider != 'sqlsrv') {
$dbh->setCharset('utf8');
}
return $dbh;
}
@ -123,9 +127,8 @@ class rcube_mdb2
* Connect to appropiate database depending on the operation
*
* @param string $mode Connection mode (r|w)
* @access public
*/
function db_connect($mode)
public function db_connect($mode)
{
// previous connection failed, don't attempt to connect again
if ($this->conn_failure) {
@ -157,10 +160,12 @@ class rcube_mdb2
$this->db_connected = !PEAR::isError($this->db_handle);
}
if ($this->db_connected)
if ($this->db_connected) {
$this->db_mode = $mode;
else
}
else {
$this->conn_failure = true;
}
}
@ -168,9 +173,8 @@ class rcube_mdb2
* Activate/deactivate debug mode
*
* @param boolean $dbg True if SQL queries should be logged
* @access public
*/
function set_debug($dbg = true)
public function set_debug($dbg = true)
{
$this->debug_mode = $dbg;
if ($this->db_connected) {
@ -184,9 +188,8 @@ class rcube_mdb2
* Getter for error state
*
* @param boolean True on error
* @access public
*/
function is_error()
public function is_error()
{
return $this->db_error ? $this->db_error_msg : false;
}
@ -196,9 +199,8 @@ class rcube_mdb2
* Connection state checker
*
* @param boolean True if in connected state
* @access public
*/
function is_connected()
public function is_connected()
{
return PEAR::isError($this->db_handle) ? false : $this->db_connected;
}
@ -208,7 +210,7 @@ class rcube_mdb2
* Is database replication configured?
* This returns true if dsnw != dsnr
*/
function is_replicated()
public function is_replicated()
{
return !empty($this->db_dsnr) && $this->db_dsnw != $this->db_dsnr;
}
@ -219,17 +221,18 @@ class rcube_mdb2
*
* @param string SQL query to execute
* @param mixed Values to be inserted in query
*
* @return number Query handle identifier
* @access public
*/
function query()
public function query()
{
$params = func_get_args();
$query = array_shift($params);
// Support one argument of type array, instead of n arguments
if (count($params) == 1 && is_array($params[0]))
if (count($params) == 1 && is_array($params[0])) {
$params = $params[0];
}
return $this->_query($query, 0, 0, $params);
}
@ -242,10 +245,10 @@ class rcube_mdb2
* @param number Offset for LIMIT statement
* @param number Number of rows for LIMIT statement
* @param mixed Values to be inserted in query
*
* @return number Query handle identifier
* @access public
*/
function limitquery()
public function limitquery()
{
$params = func_get_args();
$query = array_shift($params);
@ -274,17 +277,21 @@ class rcube_mdb2
$this->db_connect($mode);
// check connection before proceeding
if (!$this->is_connected())
if (!$this->is_connected()) {
return null;
}
if ($this->db_provider == 'sqlite')
$this->_sqlite_prepare();
if ($this->db_provider == 'sqlite') {
$this->sqlite_prepare();
}
if ($numrows || $offset)
if ($numrows || $offset) {
$result = $this->db_handle->setLimit($numrows,$offset);
}
if (empty($params))
if (empty($params)) {
$result = $mode == 'r' ? $this->db_handle->query($query) : $this->db_handle->exec($query);
}
else {
$params = (array)$params;
$q = $this->db_handle->prepare($query, null, $mode=='w' ? MDB2_PREPARE_MANIP : null);
@ -292,7 +299,7 @@ class rcube_mdb2
$this->db_error = true;
$this->db_error_msg = $q->userinfo;
raise_error(array('code' => 500, 'type' => 'db',
rcube::raise_error(array('code' => 500, 'type' => 'db',
'line' => __LINE__, 'file' => __FILE__,
'message' => $this->db_error_msg), true, false);
@ -315,17 +322,18 @@ class rcube_mdb2
*
* @param number $res_id Optional query handle identifier
* @return mixed Number of rows or false on failure
* @access public
*/
function num_rows($res_id=null)
public function num_rows($res_id=null)
{
if (!$this->db_connected)
if (!$this->db_connected) {
return false;
}
if ($result = $this->_get_result($res_id))
if ($result = $this->_get_result($res_id)) {
return $result->numRows();
else
return false;
}
return false;
}
@ -334,12 +342,12 @@ class rcube_mdb2
*
* @param number $res_id Optional query handle identifier
* @return mixed Number of rows or false on failure
* @access public
*/
function affected_rows($res_id = null)
public function affected_rows($res_id = null)
{
if (!$this->db_connected)
if (!$this->db_connected) {
return false;
}
return $this->_get_result($res_id);
}
@ -350,21 +358,24 @@ class rcube_mdb2
* For Postgres databases, a sequence name is required
*
* @param string $table Table name (to find the incremented sequence)
*
* @return mixed ID or false on failure
* @access public
*/
function insert_id($table = '')
public function insert_id($table = '')
{
if (!$this->db_connected || $this->db_mode == 'r')
if (!$this->db_connected || $this->db_mode == 'r') {
return false;
}
if ($table) {
if ($this->db_provider == 'pgsql')
if ($this->db_provider == 'pgsql') {
// find sequence name
$table = get_sequence_name($table);
else
$table = $this->sequence_name($table);
}
else {
// resolve table name
$table = get_table_name($table);
$table = $this->table_name($table);
}
}
$id = $this->db_handle->lastInsertID($table);
@ -378,10 +389,10 @@ class rcube_mdb2
* If no query handle is specified, the last query will be taken as reference
*
* @param number $res_id Optional query handle identifier
*
* @return mixed Array with col values or false on failure
* @access public
*/
function fetch_assoc($res_id=null)
public function fetch_assoc($res_id = null)
{
$result = $this->_get_result($res_id);
return $this->_fetch_row($result, MDB2_FETCHMODE_ASSOC);
@ -393,10 +404,10 @@ class rcube_mdb2
* If no query handle is specified, the last query will be taken as reference
*
* @param number $res_id Optional query handle identifier
*
* @return mixed Array with col values or false on failure
* @access public
*/
function fetch_array($res_id=null)
public function fetch_array($res_id = null)
{
$result = $this->_get_result($res_id);
return $this->_fetch_row($result, MDB2_FETCHMODE_ORDERED);
@ -408,13 +419,14 @@ class rcube_mdb2
*
* @param MDB2_Result_Common Query $result result handle
* @param number $mode Fetch mode identifier
* @return mixed Array with col values or false on failure
* @access private
*
* @return mixed Array with col values or false on failure
*/
private function _fetch_row($result, $mode)
{
if ($result === false || PEAR::isError($result) || !$this->is_connected())
if ($result === false || PEAR::isError($result) || !$this->is_connected()) {
return false;
}
return $result->fetchRow($mode);
}
@ -424,18 +436,19 @@ class rcube_mdb2
* Wrapper for the SHOW TABLES command
*
* @return array List of all tables of the current database
* @access public
* @since 0.4-beta
*/
function list_tables()
public function list_tables()
{
// get tables if not cached
if (!$this->tables) {
$this->db_handle->loadModule('Manager');
if (!PEAR::isError($result = $this->db_handle->listTables()))
if (!PEAR::isError($result = $this->db_handle->listTables())) {
$this->tables = $result;
else
}
else {
$this->tables = array();
}
}
return $this->tables;
@ -446,9 +459,10 @@ class rcube_mdb2
* Wrapper for SHOW COLUMNS command
*
* @param string Table name
*
* @return array List of table cols
*/
function list_cols($table)
public function list_cols($table)
{
$this->db_handle->loadModule('Manager');
if (!PEAR::isError($result = $this->db_handle->listTableFields($table))) {
@ -464,18 +478,20 @@ class rcube_mdb2
*
* @param mixed $input Value to quote
* @param string $type Type of data
*
* @return string Quoted/converted string for use in query
* @access public
*/
function quote($input, $type = null)
public function quote($input, $type = null)
{
// handle int directly for better performance
if ($type == 'integer')
if ($type == 'integer') {
return intval($input);
}
// create DB handle if not available
if (!$this->db_handle)
if (!$this->db_handle) {
$this->db_connect('r');
}
return $this->db_connected ? $this->db_handle->quote($input, $type) : addslashes($input);
}
@ -485,12 +501,12 @@ class rcube_mdb2
* Quotes a string so it can be safely used as a table or column name
*
* @param string $str Value to quote
*
* @return string Quoted string for use in query
* @deprecated Replaced by rcube_MDB2::quote_identifier
* @see rcube_mdb2::quote_identifier
* @access public
*/
function quoteIdentifier($str)
public function quoteIdentifier($str)
{
return $this->quote_identifier($str);
}
@ -500,13 +516,14 @@ class rcube_mdb2
* Quotes a string so it can be safely used as a table or column name
*
* @param string $str Value to quote
*
* @return string Quoted string for use in query
* @access public
*/
function quote_identifier($str)
public function quote_identifier($str)
{
if (!$this->db_handle)
if (!$this->db_handle) {
$this->db_connect('r');
}
return $this->db_connected ? $this->db_handle->quoteIdentifier($str) : $str;
}
@ -516,14 +533,15 @@ class rcube_mdb2
* Escapes a string
*
* @param string $str The string to be escaped
*
* @return string The escaped string
* @access public
* @since 0.1.1
*/
function escapeSimple($str)
public function escapeSimple($str)
{
if (!$this->db_handle)
if (!$this->db_handle) {
$this->db_connect('r');
}
return $this->db_handle->escape($str);
}
@ -533,9 +551,8 @@ class rcube_mdb2
* Return SQL function for current time and date
*
* @return string SQL function to use in query
* @access public
*/
function now()
public function now()
{
switch ($this->db_provider) {
case 'mssql':
@ -553,16 +570,18 @@ class rcube_mdb2
*
* @param array $arr Input array
* @param string $type Type of data
*
* @return string Comma-separated list of quoted values for use in query
* @access public
*/
function array2list($arr, $type = null)
public function array2list($arr, $type = null)
{
if (!is_array($arr))
if (!is_array($arr)) {
return $this->quote($arr, $type);
}
foreach ($arr as $idx => $item)
foreach ($arr as $idx => $item) {
$arr[$idx] = $this->quote($item, $type);
}
return implode(',', $arr);
}
@ -575,10 +594,11 @@ class rcube_mdb2
* of timestamp functions in Mysql (year 2038 problem)
*
* @param string $field Field name
*
* @return string SQL statement to use in query
* @deprecated
*/
function unixtimestamp($field)
public function unixtimestamp($field)
{
switch($this->db_provider) {
case 'pgsql':
@ -598,10 +618,10 @@ class rcube_mdb2
* Return SQL statement to convert from a unix timestamp
*
* @param string $timestamp Field name
*
* @return string SQL statement to use in query
* @access public
*/
function fromunixtime($timestamp)
public function fromunixtime($timestamp)
{
return date("'Y-m-d H:i:s'", $timestamp);
}
@ -612,13 +632,13 @@ class rcube_mdb2
*
* @param string $column Field name
* @param string $value Search value
*
* @return string SQL statement to use in query
* @access public
*/
function ilike($column, $value)
public function ilike($column, $value)
{
// TODO: use MDB2's matchPattern() function
switch($this->db_provider) {
switch ($this->db_provider) {
case 'pgsql':
return $this->quote_identifier($column).' ILIKE '.$this->quote($value);
default:
@ -626,20 +646,20 @@ class rcube_mdb2
}
}
/**
* Abstract SQL statement for value concatenation
*
* @return string SQL statement to be used in query
* @access public
*/
function concat(/* col1, col2, ... */)
public function concat(/* col1, col2, ... */)
{
$func = '';
$args = func_get_args();
if (is_array($args[0]))
$args = $args[0];
switch($this->db_provider) {
switch ($this->db_provider) {
case 'mysql':
case 'mysqli':
$func = 'CONCAT';
@ -661,20 +681,22 @@ class rcube_mdb2
* Encodes non-UTF-8 characters in string/array/object (recursive)
*
* @param mixed $input Data to fix
*
* @return mixed Properly UTF-8 encoded data
* @access public
*/
function encode($input)
public static function encode($input)
{
if (is_object($input)) {
foreach (get_object_vars($input) as $idx => $value)
$input->$idx = $this->encode($value);
foreach (get_object_vars($input) as $idx => $value) {
$input->$idx = self::encode($value);
}
return $input;
}
else if (is_array($input)) {
foreach ($input as $idx => $value)
$input[$idx] = $this->encode($value);
return $input;
foreach ($input as $idx => $value) {
$input[$idx] = self::encode($value);
}
return $input;
}
return utf8_encode($input);
@ -685,20 +707,22 @@ class rcube_mdb2
* Decodes encoded UTF-8 string/object/array (recursive)
*
* @param mixed $input Input data
*
* @return mixed Decoded data
* @access public
*/
function decode($input)
public static function decode($input)
{
if (is_object($input)) {
foreach (get_object_vars($input) as $idx => $value)
$input->$idx = $this->decode($value);
foreach (get_object_vars($input) as $idx => $value) {
$input->$idx = self::decode($value);
}
return $input;
}
else if (is_array($input)) {
foreach ($input as $idx => $value)
$input[$idx] = $this->decode($value);
return $input;
foreach ($input as $idx => $value) {
$input[$idx] = self::decode($value);
}
return $input;
}
return utf8_decode($input);
@ -709,8 +733,8 @@ class rcube_mdb2
* Adds a query result and returns a handle ID
*
* @param object $res Query handle
*
* @return mixed Handle ID
* @access private
*/
private function _add_result($res)
{
@ -718,7 +742,7 @@ class rcube_mdb2
if (PEAR::isError($res)) {
$this->db_error = true;
$this->db_error_msg = $res->getMessage();
raise_error(array('code' => 500, 'type' => 'db',
rcube::raise_error(array('code' => 500, 'type' => 'db',
'line' => __LINE__, 'file' => __FILE__,
'message' => $res->getMessage() . " Query: "
. substr(preg_replace('/[\r\n]+\s*/', ' ', $res->userinfo), 0, 512)),
@ -737,17 +761,20 @@ class rcube_mdb2
* If no ID is specified, the last resource handle will be returned
*
* @param number $res_id Handle ID
*
* @return mixed Resource handle or false on failure
* @access private
*/
private function _get_result($res_id = null)
{
if ($res_id == null)
if ($res_id == null) {
$res_id = $this->last_res_id;
}
if (isset($this->a_query_results[$res_id]))
if (!PEAR::isError($this->a_query_results[$res_id]))
if (isset($this->a_query_results[$res_id])) {
if (!PEAR::isError($this->a_query_results[$res_id])) {
return $this->a_query_results[$res_id];
}
}
return false;
}
@ -758,42 +785,36 @@ class rcube_mdb2
*
* @param MDB2 $dbh SQLite database handle
* @param string $file_name File path to use for DB creation
* @access private
*/
private function _sqlite_create_database($dbh, $file_name)
private function sqlite_create_database($dbh, $file_name)
{
if (empty($file_name) || !is_string($file_name))
if (empty($file_name) || !is_string($file_name)) {
return;
}
$data = file_get_contents($file_name);
if (strlen($data))
if (!sqlite_exec($dbh->connection, $data, $error) || MDB2::isError($dbh))
raise_error(array('code' => 500, 'type' => 'db',
if (strlen($data)) {
if (!sqlite_exec($dbh->connection, $data, $error) || MDB2::isError($dbh)) {
rcube::raise_error(array('code' => 500, 'type' => 'db',
'line' => __LINE__, 'file' => __FILE__,
'message' => $error), true, false);
'message' => $error), true, false);
}
}
}
/**
* Add some proprietary database functions to the current SQLite handle
* in order to make it MySQL compatible
*
* @access private
*/
private function _sqlite_prepare()
private function sqlite_prepare()
{
include_once(INSTALL_PATH . 'program/include/rcube_sqlite.inc');
// we emulate via callback some missing MySQL function
sqlite_create_function($this->db_handle->connection,
'from_unixtime', 'rcube_sqlite_from_unixtime');
// we emulate via callback some missing MySQL functions
sqlite_create_function($this->db_handle->connection,
'unix_timestamp', 'rcube_sqlite_unix_timestamp');
'unix_timestamp', array('rcube_mdb2', 'sqlite_unix_timestamp'));
sqlite_create_function($this->db_handle->connection,
'now', 'rcube_sqlite_now');
sqlite_create_function($this->db_handle->connection,
'md5', 'rcube_sqlite_md5');
'now', array('rcube_mdb2', 'sqlite_now'));
}
@ -805,8 +826,82 @@ class rcube_mdb2
if ($scope != 'prepare') {
$debug_output = sprintf('%s(%d): %s;',
$scope, $db->db_index, rtrim($message, ';'));
write_log('sql', $debug_output);
rcmail::write_log('sql', $debug_output);
}
}
} // end class rcube_db
/**
* Return correct name for a specific database table
*
* @param string $table Table name
*
* @return string Translated table name
*/
public function table_name($table)
{
$rcmail = rcube::get_instance();
// return table name if configured
$config_key = 'db_table_'.$table;
if ($name = $rcmail->config->get($config_key)) {
return $name;
}
return $table;
}
/**
* Return correct name for a specific database sequence
* (used for Postgres only)
*
* @param string $sequence Secuence name
*
* @return string Translated sequence name
*/
public function sequence_name($sequence)
{
$rcmail = rcube::get_instance();
// return sequence name if configured
$config_key = 'db_sequence_'.$sequence;
if ($name = $rcmail->config->get($config_key)) {
return $name;
}
return $sequence;
}
/**
* Callback for sqlite: unix_timestamp()
*/
public static function sqlite_unix_timestamp($timestamp = '')
{
$timestamp = trim($timestamp);
if (!$timestamp) {
$ret = time();
}
else if (!preg_match('/^[0-9]+$/s', $timestamp)) {
$ret = strtotime($timestamp);
}
else {
$ret = $timestamp;
}
return $ret;
}
/**
* Callback for sqlite: now()
*/
public static function sqlite_now()
{
return date("Y-m-d H:i:s");
}
}

@ -78,7 +78,7 @@ class rcube_message
function __construct($uid)
{
$this->uid = $uid;
$this->app = rcmail::get_instance();
$this->app = rcube::get_instance();
$this->storage = $this->app->get_storage();
$this->storage->set_options(array('all_headers' => true));
@ -96,8 +96,10 @@ class rcube_message
$this->opt = array(
'safe' => $this->is_safe,
'prefer_html' => $this->app->config->get('prefer_html'),
'get_url' => rcmail_url('get', array(
'_mbox' => $this->storage->get_folder(), '_uid' => $uid))
'get_url' => $this->app->url(array(
'action' => 'get',
'mbox' => $this->storage->get_folder(),
'uid' => $uid))
);
if (!empty($this->headers->structure)) {
@ -380,7 +382,8 @@ class rcube_message
$c->type = 'content';
$c->ctype_primary = 'text';
$c->ctype_secondary = 'plain';
$c->body = rcube_label('htmlmessage');
$c->mimetype = 'text/plain';
$c->realtype = 'text/html';
$this->parts[] = $c;
}
@ -388,7 +391,6 @@ class rcube_message
// 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;
@ -400,8 +402,8 @@ class rcube_message
$p->type = 'content';
$p->ctype_primary = 'text';
$p->ctype_secondary = 'plain';
$p->body = rcube_label('encryptedmessage');
$p->size = strlen($p->body);
$p->mimetype = 'text/plain';
$p->realtype = 'multipart/encrypted';
$this->parts[] = $p;
}
@ -671,7 +673,7 @@ class rcube_message
$uupart->size = strlen($uupart->body);
$uupart->mime_id = 'uu.' . $part->mime_id . '.' . $pid;
$ctype = rc_mime_content_type($uupart->body, $uupart->filename, 'application/octet-stream', true);
$ctype = rcube_mime::content_type($uupart->body, $uupart->filename, 'application/octet-stream', true);
$uupart->mimetype = $ctype;
list($uupart->ctype_primary, $uupart->ctype_secondary) = explode('/', $ctype);

@ -0,0 +1,238 @@
<?php
/**
+-----------------------------------------------------------------------+
| program/include/rcube_message_header.php |
| |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2005-2012, The Roundcube Dev Team |
| Copyright (C) 2011-2012, Kolab Systems AG |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
| See the README file for a full license statement. |
| |
| PURPOSE: |
| E-mail message headers representation |
| |
+-----------------------------------------------------------------------+
| Author: Aleksander Machniak <alec@alec.pl> |
+-----------------------------------------------------------------------+
$Id$
*/
/**
* Struct representing an e-mail message header
*
* @package Mail
* @author Aleksander Machniak <alec@alec.pl>
*/
class rcube_message_header
{
/**
* Message sequence number
*
* @var int
*/
public $id;
/**
* Message unique identifier
*
* @var int
*/
public $uid;
/**
* Message subject
*
* @var string
*/
public $subject;
/**
* Message sender (From)
*
* @var string
*/
public $from;
/**
* Message recipient (To)
*
* @var string
*/
public $to;
/**
* Message additional recipients (Cc)
*
* @var string
*/
public $cc;
/**
* Message Reply-To header
*
* @var string
*/
public $replyto;
/**
* Message In-Reply-To header
*
* @var string
*/
public $in_reply_to;
/**
* Message date (Date)
*
* @var string
*/
public $date;
/**
* Message identifier (Message-ID)
*
* @var string
*/
public $messageID;
/**
* Message size
*
* @var int
*/
public $size;
/**
* Message encoding
*
* @var string
*/
public $encoding;
/**
* Message charset
*
* @var string
*/
public $charset;
/**
* Message Content-type
*
* @var string
*/
public $ctype;
/**
* Message timestamp (based on message date)
*
* @var int
*/
public $timestamp;
/**
* IMAP bodystructure string
*
* @var string
*/
public $bodystructure;
/**
* IMAP internal date
*
* @var string
*/
public $internaldate;
/**
* Message References header
*
* @var string
*/
public $references;
/**
* Message priority (X-Priority)
*
* @var int
*/
public $priority;
/**
* Message receipt recipient
*
* @var string
*/
public $mdn_to;
/**
* Other message headers
*
* @var array
*/
public $others = array();
/**
* Message flags
*
* @var array
*/
public $flags = array();
}
/**
* Class for sorting an array of rcube_message_header objects in a predetermined order.
*
* @package Mail
* @author Aleksander Machniak <alec@alec.pl>
*/
class rcube_message_header_sorter
{
private $uids = array();
/**
* Set the predetermined sort order.
*
* @param array $index Numerically indexed array of IMAP UIDs
*/
function set_index($index)
{
$index = array_flip($index);
$this->uids = $index;
}
/**
* Sort the array of header objects
*
* @param array $headers Array of rcube_message_header objects indexed by UID
*/
function sort_headers(&$headers)
{
uksort($headers, array($this, "compare_uids"));
}
/**
* Sort method called by uksort()
*
* @param int $a Array key (UID)
* @param int $b Array key (UID)
*/
function compare_uids($a, $b)
{
// then find each sequence number in my ordered list
$posa = isset($this->uids[$a]) ? intval($this->uids[$a]) : -1;
$posb = isset($this->uids[$b]) ? intval($this->uids[$b]) : -1;
// return the relative position as the comparison value
return $posa - $posb;
}
}

@ -0,0 +1,103 @@
<?php
/*
+-----------------------------------------------------------------------+
| program/include/rcube_message_part.php |
| |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2005-2012, The Roundcube Dev Team |
| Copyright (C) 2011-2012, Kolab Systems AG |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
| See the README file for a full license statement. |
| |
| PURPOSE: |
| Class representing a message part |
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
| Author: Aleksander Machniak <alec@alec.pl> |
+-----------------------------------------------------------------------+
$Id$
*/
/**
* Class representing a message part
*
* @package Mail
* @author Thomas Bruederli <roundcube@gmail.com>
* @author Aleksander Machniak <alec@alec.pl>
* @version 2.0
*/
class rcube_message_part
{
/**
* Part MIME identifier
*
* @var string
*/
public $mime_id = '';
/**
* Content main type
*
* @var string
*/
public $ctype_primary = 'text';
/**
* Content subtype
*
* @var string
*/
public $ctype_secondary = 'plain';
/**
* Complete content type
*
* @var string
*/
public $mimetype = 'text/plain';
public $disposition = '';
public $filename = '';
public $encoding = '8bit';
public $charset = '';
/**
* Part size in bytes
*
* @var int
*/
public $size = 0;
/**
* Part headers
*
* @var array
*/
public $headers = array();
public $d_parameters = array();
public $ctype_parameters = array();
/**
* Clone handler.
*/
function __clone()
{
if (isset($this->parts)) {
foreach ($this->parts as $idx => $part) {
if (is_object($part)) {
$this->parts[$idx] = clone $part;
}
}
}
}
}

@ -0,0 +1,259 @@
<?php
/*
+-----------------------------------------------------------------------+
| program/include/rcube_output.php |
| |
| This file is part of the Roundcube PHP suite |
| Copyright (C) 2005-2012 The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
| See the README file for a full license statement. |
| CONTENTS: |
| Abstract class for output generation |
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
| Author: Aleksander Machniak <alec@alec.pl> |
+-----------------------------------------------------------------------+
$Id$
*/
/**
* Class for output generation
*
* @package HTML
*/
abstract class rcube_output
{
public $browser;
public $type = 'html';
public $ajax_call = false;
public $framed = false;
protected $app;
protected $config;
protected $charset = RCMAIL_CHARSET;
protected $env = array();
protected $pagetitle = '';
protected $object_handlers = array();
/**
* Object constructor
*/
public function __construct($task = null, $framed = false)
{
$this->app = rcmail::get_instance();
$this->config = $this->app->config;
$this->browser = new rcube_browser();
}
/**
* Setter for page title
*
* @param string $title Page title
*/
public function set_pagetitle($title)
{
$this->pagetitle = $title;
}
/**
* Setter for output charset.
* To be specified in a meta tag and sent as http-header
*
* @param string $charset Charset name
*/
public function set_charset($charset)
{
$this->charset = $charset;
}
/**
* Getter for output charset
*
* @return string Output charset name
*/
public function get_charset()
{
return $this->charset;
}
/**
* Getter for the current skin path property
*/
public function get_skin_path()
{
return $this->config->get('skin_path');
}
/**
* Set environment variable
*
* @param string $name Property name
* @param mixed $value Property value
*/
public function set_env($name, $value)
{
$this->env[$name] = $value;
}
/**
* Environment variable getter.
*
* @param string $name Property name
*
* @return mixed Property value
*/
public function get_env($name)
{
return $this->env[$name];
}
/**
* Delete all stored env variables and commands
*/
public function reset()
{
$this->env = array();
$this->object_handlers = array();
$this->pagetitle = '';
}
/**
* Call a client method
*
* @param string Method to call
* @param ... Additional arguments
*/
abstract function command();
/**
* Add a localized label to the client environment
*/
abstract function add_label();
/**
* Invoke display_message command
*
* @param string $message Message to display
* @param string $type Message type [notice|confirm|error]
* @param array $vars Key-value pairs to be replaced in localized text
* @param boolean $override Override last set message
* @param int $timeout Message displaying time in seconds
*/
abstract function show_message($message, $type = 'notice', $vars = null, $override = true, $timeout = 0);
/**
* Redirect to a certain url.
*
* @param mixed $p Either a string with the action or url parameters as key-value pairs
* @param int $delay Delay in seconds
*/
abstract function redirect($p = array(), $delay = 1);
/**
* Send output to the client.
*/
abstract function send();
/**
* Register a template object handler
*
* @param string Object name
* @param string Function name to call
* @return void
*/
public function add_handler($obj, $func)
{
$this->object_handlers[$obj] = $func;
}
/**
* Register a list of template object handlers
*
* @param array Hash array with object=>handler pairs
* @return void
*/
public function add_handlers($arr)
{
$this->object_handlers = array_merge($this->object_handlers, $arr);
}
/**
* Send HTTP headers to prevent caching a page
*/
public function 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");
// Request browser to disable DNS prefetching (CVE-2010-0464)
header("X-DNS-Prefetch-Control: off");
// We need to set the following headers to make downloads work using IE in HTTPS mode.
if ($this->browser->ie && rcube_ui::https_check()) {
header('Pragma: private');
header("Cache-Control: private, must-revalidate");
}
else {
header("Cache-Control: private, no-cache, must-revalidate, post-check=0, pre-check=0");
header("Pragma: no-cache");
}
}
/**
* Show error page and terminate script execution
*
* @param int $code Error code
* @param string $message Error message
*/
public function raise_error($code, $message)
{
// STUB: to be overloaded by specific output classes
fputs(STDERR, "Error $code: $message\n");
exit(-1);
}
/**
* Convert a variable into a javascript object notation
*
* @param mixed Input value
*
* @return string Serialized JSON string
*/
public static function json_serialize($input)
{
$input = rcube_charset::clean($input);
// sometimes even using rcube_charset::clean() the input contains invalid UTF-8 sequences
// that's why we have @ here
return @json_encode($input);
}
}

@ -2,21 +2,20 @@
/*
+-----------------------------------------------------------------------+
| program/include/rcube_json_output.php |
| program/include/rcube_output_json.php |
| |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2008-2010, The Roundcube Dev Team |
| Copyright (C) 2008-2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
| See the README file for a full license statement. |
| |
| PURPOSE: |
| Class to handle HTML page output using a skin template. |
| Extends rcube_html_page class from rcube_shared.inc |
| |
| Class to handle JSON (AJAX) output |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
| Author: Aleksander Machniak <alec@alec.pl> |
+-----------------------------------------------------------------------+
$Id$
@ -29,36 +28,17 @@
*
* @package View
*/
class rcube_json_output
class rcube_output_json extends rcube_output
{
/**
* Stores configuration object.
*
* @var rcube_config
*/
private $config;
private $charset = RCMAIL_CHARSET;
private $texts = array();
private $commands = array();
private $callbacks = array();
private $message = null;
public $browser;
public $env = array();
protected $texts = array();
protected $commands = array();
protected $callbacks = array();
protected $message = null;
public $type = 'js';
public $ajax_call = true;
/**
* Constructor
*/
public function __construct($task=null)
{
$this->config = rcmail::get_instance()->config;
$this->browser = new rcube_browser();
}
/**
* Set environment variable
*
@ -87,32 +67,11 @@ class rcube_json_output
}
/**
* @ignore
*/
function set_charset($charset)
{
// ignore: $this->charset = $charset;
}
/**
* Get charset for output
*
* @return string Output charset
*/
function get_charset()
{
return $this->charset;
}
/**
* Register a template object handler
*
* @param string $obj Object name
* @param string $func Function name to call
* @return void
*/
public function add_handler($obj, $func)
{
@ -124,7 +83,6 @@ class rcube_json_output
* Register a list of template object handlers
*
* @param array $arr Hash array with object=>handler pairs
* @return void
*/
public function add_handlers($arr)
{
@ -159,7 +117,7 @@ class rcube_json_output
$args = $args[0];
foreach ($args as $name) {
$this->texts[$name] = rcube_label($name);
$this->texts[$name] = $this->app->gettext($name);
}
}
@ -177,10 +135,11 @@ class rcube_json_output
public function show_message($message, $type='notice', $vars=null, $override=true, $timeout=0)
{
if ($override || !$this->message) {
if (rcube_label_exists($message)) {
if (!empty($vars))
$vars = array_map('Q', $vars);
$msgtext = rcube_label(array('name' => $message, 'vars' => $vars));
if ($this->app->text_exists($message)) {
if (!empty($vars)) {
$vars = array_map(array('rcube_ui', 'Q'), $vars);
}
$msgtext = $this->app->gettext(array('name' => $message, 'vars' => $vars));
}
else
$msgtext = $message;
@ -196,7 +155,7 @@ class rcube_json_output
*/
public function reset()
{
$this->env = array();
parent::reset();
$this->texts = array();
$this->commands = array();
}
@ -227,6 +186,20 @@ class rcube_json_output
}
/**
* Show error page and terminate script execution
*
* @param int $code Error code
* @param string $message Error message
*/
public function raise_error($code, $message)
{
$this->show_message("Application Error ($code): $message", 'error');
$this->remote_response();
exit;
}
/**
* Send an AJAX response with executable JS code
*
@ -235,13 +208,13 @@ class rcube_json_output
* @return void
* @deprecated
*/
public function remote_response($add='')
protected function remote_response($add='')
{
static $s_header_sent = false;
if (!$s_header_sent) {
$s_header_sent = true;
send_nocacheing_headers();
$this->nocacheing_headers();
header('Content-Type: text/plain; charset=' . $this->get_charset());
}
@ -251,7 +224,7 @@ class rcube_json_output
$rcmail = rcmail::get_instance();
$response['action'] = $rcmail->action;
if ($unlock = get_input_value('_unlock', RCUBE_INPUT_GPC)) {
if ($unlock = rcube_ui::get_input_value('_unlock', rcube_ui::INPUT_GPC)) {
$response['unlock'] = $unlock;
}
@ -267,7 +240,7 @@ class rcube_json_output
if (!empty($this->callbacks))
$response['callbacks'] = $this->callbacks;
echo json_serialize($response);
echo self::json_serialize($response);
}
@ -276,14 +249,14 @@ class rcube_json_output
*
* @return string $out
*/
private function get_js_commands()
protected function get_js_commands()
{
$out = '';
foreach ($this->commands as $i => $args) {
$method = array_shift($args);
foreach ($args as $i => $arg) {
$args[$i] = json_serialize($arg);
$args[$i] = self::json_serialize($arg);
}
$out .= sprintf(

@ -110,9 +110,10 @@ abstract class rcube_plugin
public function load_config($fname = 'config.inc.php')
{
$fpath = $this->home.'/'.$fname;
$rcmail = rcmail::get_instance();
$rcmail = rcube::get_instance();
if (is_file($fpath) && !$rcmail->config->load_from_file($fpath)) {
raise_error(array('code' => 527, 'type' => 'php',
rcube::raise_error(array(
'code' => 527, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Failed to load config from $fpath"), true, false);
return false;
@ -176,7 +177,7 @@ abstract class rcube_plugin
foreach ($texts as $key => $value)
$add[$domain.'.'.$key] = $value;
$rcmail = rcmail::get_instance();
$rcmail = rcube::get_instance();
$rcmail->load_language($lang, $add);
// add labels to client
@ -196,7 +197,7 @@ abstract class rcube_plugin
*/
public function gettext($p)
{
return rcmail::get_instance()->gettext($p, $this->ID);
return rcube::get_instance()->gettext($p, $this->ID);
}
/**
@ -309,9 +310,10 @@ abstract class rcube_plugin
*/
public function local_skin_path()
{
$skin_path = 'skins/'.$this->api->config->get('skin');
if (!is_dir(realpath(slashify($this->home) . $skin_path)))
$skin_path = 'skins/default';
$rcmail = rcube::get_instance();
$skin_path = 'skins/' . $rcmail->config->get('skin');
if (!is_dir(realpath(slashify($this->home) . $skin_path)))
$skin_path = 'skins/default';
return $skin_path;
}

@ -22,6 +22,11 @@
*/
// location where plugins are loade from
if (!defined('RCMAIL_PLUGINS_DIR'))
define('RCMAIL_PLUGINS_DIR', INSTALL_PATH . 'plugins/');
/**
* The plugin loader and global API
*
@ -33,8 +38,8 @@ class rcube_plugin_api
public $dir;
public $url = 'plugins/';
public $task = '';
public $output;
public $config;
public $handlers = array();
private $plugins = array();
@ -43,7 +48,6 @@ class rcube_plugin_api
private $actionmap = array();
private $objectsmap = array();
private $template_contents = array();
private $required_plugins = array('filesystem_attachments', 'jqueryui');
private $active_hook = false;
// Deprecated names of hooks, will be removed after 0.5-stable release
@ -99,29 +103,48 @@ class rcube_plugin_api
*/
private function __construct()
{
$this->dir = INSTALL_PATH . $this->url;
$this->dir = slashify(RCMAIL_PLUGINS_DIR);
}
/**
* Load and init all enabled plugins
* Initialize plugin engine
*
* This has to be done after rcmail::load_gui() or rcmail::json_init()
* was called because plugins need to have access to rcmail->output
*
* @param object rcube Instance of the rcube base class
* @param string Current application task (used for conditional plugin loading)
*/
public function init()
public function init($app, $task = '')
{
$rcmail = rcmail::get_instance();
$this->output = $rcmail->output;
$this->config = $rcmail->config;
$this->task = $task;
$this->output = $app->output;
// register an internal hook
$this->register_hook('template_container', array($this, 'template_container_hook'));
$plugins_enabled = (array)$rcmail->config->get('plugins', array());
// maybe also register a shudown function which triggers shutdown functions of all plugin objects
}
/**
* Load and init all enabled plugins
*
* This has to be done after rcmail::load_gui() or rcmail::json_init()
* was called because plugins need to have access to rcmail->output
*
* @param array List of configured plugins to load
* @param array List of plugins required by the application
*/
public function load_plugins($plugins_enabled, $required_plugins = array())
{
foreach ($plugins_enabled as $plugin_name) {
$this->load_plugin($plugin_name);
}
// check existance of all required core plugins
foreach ($this->required_plugins as $plugin_name) {
foreach ($required_plugins as $plugin_name) {
$loaded = false;
foreach ($this->plugins as $plugin) {
if ($plugin instanceof $plugin_name) {
@ -136,19 +159,13 @@ class rcube_plugin_api
// trigger fatal error if still not loaded
if (!$loaded) {
raise_error(array('code' => 520, 'type' => 'php',
rcube::raise_error(array('code' => 520, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Requried plugin $plugin_name was not loaded"), true, true);
}
}
// register an internal hook
$this->register_hook('template_container', array($this, 'template_container_hook'));
// maybe also register a shudown function which triggers shutdown functions of all plugin objects
}
/**
* Load the specified plugin
*
@ -159,8 +176,6 @@ class rcube_plugin_api
{
static $plugins_dir;
$rcmail = rcmail::get_instance();
if (!$plugins_dir) {
$dir = dir($this->dir);
$plugins_dir = unslashify($dir->path);
@ -181,8 +196,8 @@ class rcube_plugin_api
// check inheritance...
if (is_subclass_of($plugin, 'rcube_plugin')) {
// ... task, request type and framed mode
if ((!$plugin->task || preg_match('/^('.$plugin->task.')$/i', $rcmail->task))
&& (!$plugin->noajax || (is_object($rcmail->output) && is_a($rcmail->output, 'rcube_template')))
if ((!$plugin->task || preg_match('/^('.$plugin->task.')$/i', $this->task))
&& (!$plugin->noajax || (is_object($this->output) && $this->output->type == 'html'))
&& (!$plugin->noframe || empty($_REQUEST['_framed']))
) {
$plugin->init();
@ -192,13 +207,13 @@ class rcube_plugin_api
}
}
else {
raise_error(array('code' => 520, 'type' => 'php',
rcube::raise_error(array('code' => 520, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "No plugin class $plugin_name found in $fn"), true, false);
}
}
else {
raise_error(array('code' => 520, 'type' => 'php',
rcube::raise_error(array('code' => 520, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Failed to load plugin file $fn"), true, false);
}
@ -217,7 +232,7 @@ class rcube_plugin_api
{
if (is_callable($callback)) {
if (isset($this->deprecated_hooks[$hook])) {
raise_error(array('code' => 522, 'type' => 'php',
rcube::raise_error(array('code' => 522, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Deprecated hook name. ".$hook.' -> '.$this->deprecated_hooks[$hook]), true, false);
$hook = $this->deprecated_hooks[$hook];
@ -225,7 +240,7 @@ class rcube_plugin_api
$this->handlers[$hook][] = $callback;
}
else
raise_error(array('code' => 521, 'type' => 'php',
rcube::raise_error(array('code' => 521, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Invalid callback function for $hook"), true, false);
}
@ -297,7 +312,7 @@ class rcube_plugin_api
$this->actionmap[$action] = $owner;
}
else {
raise_error(array('code' => 523, 'type' => 'php',
rcube::raise_error(array('code' => 523, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Cannot register action $action; already taken by another plugin"), true, false);
}
@ -316,7 +331,7 @@ class rcube_plugin_api
call_user_func($this->actions[$action]);
}
else {
raise_error(array('code' => 524, 'type' => 'php',
rcube::raise_error(array('code' => 524, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "No handler found for action $action"), true, true);
}
@ -337,14 +352,14 @@ class rcube_plugin_api
$name = 'plugin.'.$name;
// can register handler only if it's not taken or registered by myself
if (!isset($this->objectsmap[$name]) || $this->objectsmap[$name] == $owner) {
if (is_object($this->output) && (!isset($this->objectsmap[$name]) || $this->objectsmap[$name] == $owner)) {
$this->output->add_handler($name, $callback);
$this->objectsmap[$name] = $owner;
}
else {
raise_error(array('code' => 525, 'type' => 'php',
rcube::raise_error(array('code' => 525, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Cannot register template handler $name; already taken by another plugin"), true, false);
'message' => "Cannot register template handler $name; already taken by another plugin or no output object available"), true, false);
}
}
@ -358,12 +373,12 @@ class rcube_plugin_api
public function register_task($task, $owner)
{
if ($task != asciiwords($task)) {
raise_error(array('code' => 526, 'type' => 'php',
rcube::raise_error(array('code' => 526, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Invalid task name: $task. Only characters [a-z0-9_.-] are allowed"), true, false);
}
else if (in_array($task, rcmail::$main_tasks)) {
raise_error(array('code' => 526, 'type' => 'php',
rcube::raise_error(array('code' => 526, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Cannot register taks $task; already taken by another plugin or the application itself"), true, false);
}
@ -408,7 +423,7 @@ class rcube_plugin_api
*/
public function include_script($fn)
{
if ($this->output->type == 'html') {
if (is_object($this->output) && $this->output->type == 'html') {
$src = $this->resource_url($fn);
$this->output->add_header(html::tag('script', array('type' => "text/javascript", 'src' => $src)));
}
@ -422,7 +437,7 @@ class rcube_plugin_api
*/
public function include_stylesheet($fn)
{
if ($this->output->type == 'html') {
if (is_object($this->output) && $this->output->type == 'html') {
$src = $this->resource_url($fn);
$this->output->include_css($src);
}

@ -78,7 +78,7 @@ class rcube_session
array($this, 'gc'));
}
else {
raise_error(array('code' => 604, 'type' => 'db',
rcube::raise_error(array('code' => 604, 'type' => 'db',
'line' => __LINE__, 'file' => __FILE__,
'message' => "Failed to connect to memcached. Please check configuration"),
true, true);
@ -129,7 +129,7 @@ class rcube_session
public function db_read($key)
{
$sql_result = $this->db->query(
"SELECT vars, ip, changed FROM ".get_table_name('session')
"SELECT vars, ip, changed FROM ".$this->db->table_name('session')
." WHERE sess_id = ?", $key);
if ($sql_result && ($sql_arr = $this->db->fetch_assoc($sql_result))) {
@ -177,18 +177,18 @@ class rcube_session
if ($newvars !== $oldvars) {
$this->db->query(
sprintf("UPDATE %s SET vars=?, changed=%s WHERE sess_id=?",
get_table_name('session'), $now),
$this->db->table_name('session'), $now),
base64_encode($newvars), $key);
}
else if ($ts - $this->changed > $this->lifetime / 2) {
$this->db->query("UPDATE ".get_table_name('session')." SET changed=$now WHERE sess_id=?", $key);
$this->db->query("UPDATE ".$this->db->table_name('session')." SET changed=$now WHERE sess_id=?", $key);
}
}
else {
$this->db->query(
sprintf("INSERT INTO %s (sess_id, vars, ip, created, changed) ".
"VALUES (?, ?, ?, %s, %s)",
get_table_name('session'), $now, $now),
$this->db->table_name('session'), $now, $now),
$key, base64_encode($vars), (string)$this->ip);
}
@ -228,7 +228,7 @@ class rcube_session
public function db_destroy($key)
{
$this->db->query(
sprintf("DELETE FROM %s WHERE sess_id = ?", get_table_name('session')),
sprintf("DELETE FROM %s WHERE sess_id = ?", $this->db->table_name('session')),
$key);
return true;
@ -246,7 +246,7 @@ class rcube_session
// just delete all expired sessions
$this->db->query(
sprintf("DELETE FROM %s WHERE changed < %s",
get_table_name('session'), $this->db->fromunixtime(time() - $maxlifetime)));
$this->db->table_name('session'), $this->db->fromunixtime(time() - $maxlifetime)));
$this->gc();
@ -322,8 +322,9 @@ class rcube_session
*/
public function gc()
{
foreach ($this->gc_handlers as $fct)
foreach ($this->gc_handlers as $fct) {
call_user_func($fct);
}
}
@ -624,14 +625,14 @@ class rcube_session
$auth_string = "$this->key,$this->secret,$timeslot";
return "S" . (function_exists('sha1') ? sha1($auth_string) : md5($auth_string));
}
/**
*
*/
function log($line)
{
if ($this->logging)
write_log('session', $line);
rcmail::write_log('session', $line);
}
}

@ -2,17 +2,17 @@
/*
+-----------------------------------------------------------------------+
| rcube_shared.inc |
| program/include/rcube_shared.inc |
| |
| This file is part of the Roundcube PHP suite |
| Copyright (C) 2005-2007, The Roundcube Dev Team |
| Copyright (C) 2005-2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
| See the README file for a full license statement. |
| |
| CONTENTS: |
| Shared functions and classes used in PHP projects |
| Shared functions used by Roundcube Framework |
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
@ -30,214 +30,96 @@
*/
/**
* Send HTTP headers to prevent caching this page
*/
function send_nocacheing_headers()
{
global $OUTPUT;
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");
// Request browser to disable DNS prefetching (CVE-2010-0464)
header("X-DNS-Prefetch-Control: off");
// We need to set the following headers to make downloads work using IE in HTTPS mode.
if ($OUTPUT->browser->ie && rcube_https_check()) {
header('Pragma: private');
header("Cache-Control: private, must-revalidate");
} else {
header("Cache-Control: private, no-cache, must-revalidate, post-check=0, pre-check=0");
header("Pragma: no-cache");
}
}
/**
* 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: ");
}
/**
* Similar function as in_array() but case-insensitive
*
* @param mixed Needle value
* @param array Array to search in
* @param string $needle Needle value
* @param array $heystack Array to search in
*
* @return boolean True if found, False if not
*/
function in_array_nocase($needle, $haystack)
{
$needle = mb_strtolower($needle);
foreach ($haystack as $value)
if ($needle===mb_strtolower($value))
return true;
$needle = mb_strtolower($needle);
foreach ($haystack as $value) {
if ($needle === mb_strtolower($value)) {
return true;
}
}
return false;
return false;
}
/**
* Find out if the string content means TRUE or FALSE
* Find out if the string content means true or false
*
* @param string Input value
* @return boolean Imagine what!
* @param string $str Input value
*
* @return boolean Boolean value
*/
function get_boolean($str)
{
$str = strtolower($str);
if (in_array($str, array('false', '0', 'no', 'off', 'nein', ''), TRUE))
return FALSE;
else
return TRUE;
$str = strtolower($str);
return !in_array($str, array('false', '0', 'no', 'off', 'nein', ''), true);
}
/**
* Parse a human readable string for a number of bytes
* Parse a human readable string for a number of bytes.
*
* @param string $str Input string
*
* @param string Input string
* @return float Number of bytes
*/
function parse_bytes($str)
{
if (is_numeric($str))
return floatval($str);
if (preg_match('/([0-9\.]+)\s*([a-z]*)/i', $str, $regs))
{
$bytes = floatval($regs[1]);
switch (strtolower($regs[2]))
{
case 'g':
case 'gb':
$bytes *= 1073741824;
break;
case 'm':
case 'mb':
$bytes *= 1048576;
break;
case 'k':
case 'kb':
$bytes *= 1024;
break;
if (is_numeric($str)) {
return floatval($str);
}
}
return floatval($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;
}
/**
* Wrapper function for wordwrap
*/
function rc_wordwrap($string, $width=75, $break="\n", $cut=false)
{
$para = explode($break, $string);
$string = '';
while (count($para)) {
$line = array_shift($para);
if ($line[0] == '>') {
$string .= $line.$break;
continue;
}
$list = explode(' ', $line);
$len = 0;
while (count($list)) {
$line = array_shift($list);
$l = mb_strlen($line);
$newlen = $len + $l + ($len ? 1 : 0);
if ($newlen <= $width) {
$string .= ($len ? ' ' : '').$line;
$len += (1 + $l);
} else {
if ($l > $width) {
if ($cut) {
$start = 0;
while ($l) {
$str = mb_substr($line, $start, $width);
$strlen = mb_strlen($str);
$string .= ($len ? $break : '').$str;
$start += $strlen;
$l -= $strlen;
$len = $strlen;
}
} else {
$string .= ($len ? $break : '').$line;
if (count($list)) $string .= $break;
$len = 0;
}
} else {
$string .= $break.$line;
$len = $l;
if (preg_match('/([0-9\.]+)\s*([a-z]*)/i', $str, $regs)) {
$bytes = floatval($regs[1]);
switch (strtolower($regs[2])) {
case 'g':
case 'gb':
$bytes *= 1073741824;
break;
case 'm':
case 'mb':
$bytes *= 1048576;
break;
case 'k':
case 'kb':
$bytes *= 1024;
break;
}
}
}
if (count($para)) $string .= $break;
}
return $string;
return floatval($bytes);
}
/**
* Read a specific HTTP request header
* 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)
function rcube_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];
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];
}
@ -263,219 +145,251 @@ function unslashify($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;
$dir = @opendir($dir_path);
if (!$dir) {
return false;
}
while ($file = readdir($dir))
if (strlen($file)>2)
unlink("$dir_path/$file");
while ($file = readdir($dir)) {
if (strlen($file) > 2) {
unlink("$dir_path/$file");
}
}
closedir($dir);
return TRUE;
closedir($dir);
return true;
}
/**
* Create a unix timestamp with a specified offset from now
* Create a unix timestamp with a specified offset from now.
*
* @param string $offset_str String representation of the offset (e.g. 20min, 5h, 2days)
* @param int $factor Factor to multiply with the offset
*
* @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)
{
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;
$amount *= 7;
case 'd':
$amount *= 24;
$amount *= 24;
case 'h':
$amount *= 60;
$amount *= 60;
case 'm':
$amount *= 60;
$amount *= 60;
case 's':
$ts += $amount * $factor;
}
$ts += $amount * $factor;
}
return $ts;
return $ts;
}
/**
* Truncate string if it is longer than the allowed length
* Replace the middle or the ending part of a string with a placeholder
* Truncate string if it is longer than the allowed length.
* Replace the middle or the ending part of a string with a placeholder.
*
* @param string $str Input string
* @param int $maxlength Max. length
* @param string $placeholder Replace removed chars with this
* @param bool $ending Set to True if string should be truncated from the end
*
* @param string Input string
* @param int Max. length
* @param string Replace removed chars with this
* @param bool Set to True if string should be truncated from the end
* @return string Abbreviated string
*/
function abbreviate_string($str, $maxlength, $place_holder='...', $ending=false)
function abbreviate_string($str, $maxlength, $placeholder='...', $ending=false)
{
$length = mb_strlen($str);
$length = mb_strlen($str);
if ($length > $maxlength)
{
if ($ending)
return mb_substr($str, 0, $maxlength) . $place_holder;
if ($length > $maxlength) {
if ($ending) {
return mb_substr($str, 0, $maxlength) . $placeholder;
}
$placeholder_length = mb_strlen($placeholder);
$first_part_length = floor(($maxlength - $placeholder_length)/2);
$second_starting_location = $length - $maxlength + $first_part_length + $placeholder_length;
$place_holder_length = mb_strlen($place_holder);
$first_part_length = floor(($maxlength - $place_holder_length)/2);
$second_starting_location = $length - $maxlength + $first_part_length + $place_holder_length;
$str = mb_substr($str, 0, $first_part_length) . $place_holder . mb_substr($str, $second_starting_location);
}
$str = mb_substr($str, 0, $first_part_length) . $placeholder . mb_substr($str, $second_starting_location);
}
return $str;
return $str;
}
/**
* A method to guess the mime_type of an attachment.
*
* @param string $path Path to the file.
* @param string $name File name (with suffix)
* @param string $failover Mime type supplied for failover.
* @param string $is_stream Set to True if $path contains file body
* Explode quoted string
*
* @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
* @param string Delimiter expression string for preg_match()
* @param string Input string
*/
function rc_mime_content_type($path, $name, $failover = 'application/octet-stream', $is_stream=false)
function rcube_explode_quoted_string($delimiter, $string)
{
$mime_type = null;
$mime_magic = rcmail::get_instance()->config->get('mime_magic');
$mime_ext = @include(RCMAIL_CONFIG_DIR . '/mimetypes.php');
// use file name suffix with hard-coded mime-type map
if (is_array($mime_ext) && $name) {
if ($suffix = substr($name, strrpos($name, '.')+1)) {
$mime_type = $mime_ext[strtolower($suffix)];
$result = array();
$strlen = strlen($string);
for ($q=$p=$i=0; $i < $strlen; $i++) {
if ($string[$i] == "\"" && $string[$i-1] != "\\") {
$q = $q ? false : true;
}
else if (!$q && preg_match("/$delimiter/", $string[$i])) {
$result[] = substr($string, $p, $i - $p);
$p = $i + 1;
}
}
// try fileinfo extension if available
if (!$mime_type && function_exists('finfo_open')) {
if ($finfo = finfo_open(FILEINFO_MIME, $mime_magic)) {
if ($is_stream)
$mime_type = finfo_buffer($finfo, $path);
else
$mime_type = finfo_file($finfo, $path);
finfo_close($finfo);
$result[] = substr($string, $p);
return $result;
}
/**
* Get all keys from array (recursive).
*
* @param array $array Input array
*
* @return array List of array keys
*/
function array_keys_recursive($array)
{
$keys = array();
if (!empty($array)) {
foreach ($array as $key => $child) {
$keys[] = $key;
foreach (array_keys_recursive($child) as $val) {
$keys[] = $val;
}
}
}
// try PHP's mime_content_type
if (!$mime_type && !$is_stream && function_exists('mime_content_type')) {
$mime_type = @mime_content_type($path);
}
return $keys;
}
// fall back to user-submitted string
if (!$mime_type) {
$mime_type = $failover;
}
else {
// Sometimes (PHP-5.3?) content-type contains charset definition,
// Remove it (#1487122) also "charset=binary" is useless
$mime_type = array_shift(preg_split('/[; ]/', $mime_type));
}
return $mime_type;
/**
* Remove all non-ascii and non-word chars except ., -, _
*/
function asciiwords($str, $css_id = false, $replace_with = '')
{
$allowed = 'a-z0-9\_\-' . (!$css_id ? '\.' : '');
return preg_replace("/[^$allowed]/i", $replace_with, $str);
}
/**
* Detect image type of the given binary data by checking magic numbers
* Remove single and double quotes from given string
*
* @param string Binary file content
* @return string Detected mime-type or jpeg as fallback
* @param string Input value
*
* @return string Dequoted string
*/
function rc_image_content_type($data)
function strip_quotes($str)
{
$type = 'jpeg';
if (preg_match('/^\x89\x50\x4E\x47/', $data)) $type = 'png';
else if (preg_match('/^\x47\x49\x46\x38/', $data)) $type = 'gif';
else if (preg_match('/^\x00\x00\x01\x00/', $data)) $type = 'ico';
// else if (preg_match('/^\xFF\xD8\xFF\xE0/', $data)) $type = 'jpeg';
return str_replace(array("'", '"'), '', $str);
}
return 'image/' . $type;
/**
* Remove new lines characters from given string
*
* @param string $str Input value
*
* @return string Stripped string
*/
function strip_newlines($str)
{
return preg_replace('/[\r\n]/', '', $str);
}
/**
* Explode quoted string
*
* @param string Delimiter expression string for preg_match()
* @param string Input string
* Improved equivalent to strtotime()
*
* @param string $date Date string
*
* @return int Unix timestamp
*/
function rcube_explode_quoted_string($delimiter, $string)
function rcube_strtotime($date)
{
$result = array();
$strlen = strlen($string);
for ($q=$p=$i=0; $i < $strlen; $i++) {
if ($string[$i] == "\"" && $string[$i-1] != "\\") {
$q = $q ? false : true;
}
else if (!$q && preg_match("/$delimiter/", $string[$i])) {
$result[] = substr($string, $p, $i - $p);
$p = $i + 1;
// check for MS Outlook vCard date format YYYYMMDD
if (preg_match('/^([12][90]\d\d)([01]\d)(\d\d)$/', trim($date), $matches)) {
return mktime(0,0,0, intval($matches[2]), intval($matches[3]), intval($matches[1]));
}
else if (is_numeric($date)) {
return $date;
}
// support non-standard "GMTXXXX" literal
$date = preg_replace('/GMT\s*([+-][0-9]+)/', '\\1', $date);
// if date parsing fails, we have a date in non-rfc format.
// remove token from the end and try again
while ((($ts = @strtotime($date)) === false) || ($ts < 0)) {
$d = explode(' ', $date);
array_pop($d);
if (!$d) {
break;
}
$date = implode(' ', $d);
}
}
$result[] = substr($string, $p);
return $result;
return $ts;
}
/**
* Get all keys from array (recursive)
*
* @param array Input array
* @return array
* Compose a valid representation of name and e-mail address
*
* @param string $email E-mail address
* @param string $name Person name
*
* @return string Formatted string
*/
function array_keys_recursive($array)
function format_email_recipient($email, $name = '')
{
$keys = array();
$email = trim($email);
if ($name && $name != $email) {
// Special chars as defined by RFC 822 need to in quoted string (or escaped).
if (preg_match('/[\(\)\<\>\\\.\[\]@,;:"]/', $name)) {
$name = '"'.addcslashes($name, '"').'"';
}
if (!empty($array))
foreach ($array as $key => $child) {
$keys[] = $key;
foreach (array_keys_recursive($child) as $val)
$keys[] = $val;
return "$name <$email>";
}
return $keys;
return $email;
}
/**
* mbstring replacement functions
*/
if (!extension_loaded('mbstring'))
{
function mb_strlen($str)
{
return strlen($str);
return strlen($str);
}
function mb_strtolower($str)
@ -552,3 +466,89 @@ if (!function_exists('idn_to_ascii'))
}
}
/*
* Idn_to_ascii wrapper.
* Intl/Idn modules version of this function doesn't work with e-mail address
*/
function rcube_idn_to_ascii($str)
{
return rcube_idn_convert($str, true);
}
/*
* Idn_to_ascii wrapper.
* Intl/Idn modules version of this function doesn't work with e-mail address
*/
function rcube_idn_to_utf8($str)
{
return rcube_idn_convert($str, false);
}
function rcube_idn_convert($input, $is_utf=false)
{
if ($at = strpos($input, '@')) {
$user = substr($input, 0, $at);
$domain = substr($input, $at+1);
}
else {
$domain = $input;
}
$domain = $is_utf ? idn_to_ascii($domain) : idn_to_utf8($domain);
if ($domain === false) {
return '';
}
return $at ? $user . '@' . $domain : $domain;
}
/**
* Use PHP5 autoload for dynamic class loading
*
* @todo Make Zend, PEAR etc play with this
* @todo Make our classes conform to a more straight forward CS.
*/
function rcube_autoload($classname)
{
$filename = preg_replace(
array(
'/MDB2_(.+)/',
'/Mail_(.+)/',
'/Net_(.+)/',
'/Auth_(.+)/',
'/^html_.+/',
'/^utf8$/',
),
array(
'MDB2/\\1',
'Mail/\\1',
'Net/\\1',
'Auth/\\1',
'html',
'utf8.class',
),
$classname
);
if ($fp = @fopen("$filename.php", 'r', true)) {
fclose($fp);
include_once("$filename.php");
return true;
}
return false;
}
/**
* Local callback function for PEAR errors
*/
function rcube_pear_error($err)
{
error_log(sprintf("%s (%s): %s",
$err->getMessage(),
$err->getCode(),
$err->getUserinfo()), 0);
}

@ -52,7 +52,7 @@ class rcube_smtp
*/
public function connect($host=null, $port=null, $user=null, $pass=null)
{
$RCMAIL = rcmail::get_instance();
$RCMAIL = rcube::get_instance();
// disconnect/destroy $this->conn
$this->disconnect();
@ -74,7 +74,7 @@ class rcube_smtp
'smtp_auth_callbacks' => array(),
));
$smtp_host = rcube_parse_host($CONFIG['smtp_server']);
$smtp_host = rcmail::parse_host($CONFIG['smtp_server']);
// when called from Installer it's possible to have empty $smtp_host here
if (!$smtp_host) $smtp_host = 'localhost';
$smtp_port = is_numeric($CONFIG['smtp_port']) ? $CONFIG['smtp_port'] : 25;
@ -338,7 +338,7 @@ class rcube_smtp
*/
public function debug_handler(&$smtp, $message)
{
write_log('smtp', preg_replace('/\r\n$/', '', $message));
rcmail::write_log('smtp', preg_replace('/\r\n$/', '', $message));
}

@ -61,7 +61,7 @@ class rcube_spellchecker
$this->lang = $lang ? $lang : 'en';
if ($this->engine == 'pspell' && !extension_loaded('pspell')) {
raise_error(array(
rcube::raise_error(array(
'code' => 500, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Pspell extension not available"), true, true);
@ -535,7 +535,7 @@ class rcube_spellchecker
private function update_dict()
{
if (strcasecmp($this->options['dictionary'], 'shared') != 0) {
$userid = (int) $this->rc->user->ID;
$userid = $this->rc->get_user_id();
}
$plugin = $this->rc->plugins->exec_hook('spell_dictionary_save', array(
@ -548,24 +548,24 @@ class rcube_spellchecker
if ($this->have_dict) {
if (!empty($this->dict)) {
$this->rc->db->query(
"UPDATE ".get_table_name('dictionary')
"UPDATE ".$this->rc->db->table_name('dictionary')
." SET data = ?"
." WHERE user_id " . ($plugin['userid'] ? "= ".$plugin['userid'] : "IS NULL")
." WHERE user_id " . ($plugin['userid'] ? "= ".$this->rc->db->quote($plugin['userid']) : "IS NULL")
." AND " . $this->rc->db->quoteIdentifier('language') . " = ?",
implode(' ', $plugin['dictionary']), $plugin['language']);
}
// don't store empty dict
else {
$this->rc->db->query(
"DELETE FROM " . get_table_name('dictionary')
." WHERE user_id " . ($plugin['userid'] ? "= ".$plugin['userid'] : "IS NULL")
"DELETE FROM " . $this->rc->db->table_name('dictionary')
." WHERE user_id " . ($plugin['userid'] ? "= ".$this->rc->db->quote($plugin['userid']) : "IS NULL")
." AND " . $this->rc->db->quoteIdentifier('language') . " = ?",
$plugin['language']);
}
}
else if (!empty($this->dict)) {
$this->rc->db->query(
"INSERT INTO " .get_table_name('dictionary')
"INSERT INTO " .$this->rc->db->table_name('dictionary')
." (user_id, " . $this->rc->db->quoteIdentifier('language') . ", data) VALUES (?, ?, ?)",
$plugin['userid'], $plugin['language'], implode(' ', $plugin['dictionary']));
}
@ -582,7 +582,7 @@ class rcube_spellchecker
}
if (strcasecmp($this->options['dictionary'], 'shared') != 0) {
$userid = (int) $this->rc->user->ID;
$userid = $this->rc->get_user_id();
}
$plugin = $this->rc->plugins->exec_hook('spell_dictionary_get', array(
@ -591,8 +591,8 @@ class rcube_spellchecker
if (empty($plugin['abort'])) {
$dict = array();
$this->rc->db->query(
"SELECT data FROM ".get_table_name('dictionary')
." WHERE user_id ". ($plugin['userid'] ? "= ".$plugin['userid'] : "IS NULL")
"SELECT data FROM ".$this->rc->db->table_name('dictionary')
." WHERE user_id ". ($plugin['userid'] ? "= ".$this->rc->db->quote($plugin['userid']) : "IS NULL")
." AND " . $this->rc->db->quoteIdentifier('language') . " = ?",
$plugin['language']);

@ -1,79 +0,0 @@
<?php
/*
+-----------------------------------------------------------------------+
| program/include/rcube_sqlite.inc |
| |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2005-2010, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
| See the README file for a full license statement. |
| |
| PURPOSE: |
| Provide callback functions for sqlite that will emulate |
| sone MySQL functions |
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
$Id$
*/
/**
* Callback functions for sqlite database interface
*
* @package Database
*/
function rcube_sqlite_from_unixtime($timestamp)
{
$timestamp = trim($timestamp);
if (!preg_match('/^[0-9]+$/is', $timestamp))
$ret = strtotime($timestamp);
else
$ret = $timestamp;
$ret = date('Y-m-d H:i:s', $ret);
rcube_sqlite_debug("FROM_UNIXTIME ($timestamp) = $ret");
return $ret;
}
function rcube_sqlite_unix_timestamp($timestamp='')
{
$timestamp = trim($timestamp);
if (!$timestamp)
$ret = time();
else if (!preg_match('/^[0-9]+$/is', $timestamp))
$ret = strtotime($timestamp);
else
$ret = $timestamp;
rcube_sqlite_debug("UNIX_TIMESTAMP ($timestamp) = $ret");
return $ret;
}
function rcube_sqlite_now()
{
rcube_sqlite_debug("NOW() = ".date("Y-m-d H:i:s"));
return date("Y-m-d H:i:s");
}
function rcube_sqlite_md5($str)
{
return md5($str);
}
function rcube_sqlite_debug($str)
{
//console($str);
}

@ -434,7 +434,7 @@ abstract class rcube_storage
* @param int $uid Message UID to fetch
* @param string $folder Folder to read from
*
* @return object rcube_mail_header Message data
* @return object rcube_message_header Message data
*/
abstract function get_message($uid, $folder = null);
@ -446,7 +446,7 @@ abstract class rcube_storage
* @param string $folder Folder to read from
* @param bool $force True to skip cache
*
* @return rcube_mail_header Message headers
* @return rcube_message_header Message headers
*/
abstract function get_message_headers($uid, $folder = null, $force = false);
@ -477,7 +477,7 @@ abstract class rcube_storage
public function get_body($uid, $part = 1)
{
$headers = $this->get_message_headers($uid);
return rcube_charset_convert($this->get_message_part($uid, $part, null),
return rcube_charset::convert($this->get_message_part($uid, $part, null),
$headers->charset ? $headers->charset : $this->default_charset);
}
@ -970,6 +970,7 @@ abstract class rcube_storage
*/
abstract function clear_cache($key = null, $prefix_mode = false);
/**
* Returns cached value
*
@ -979,93 +980,10 @@ abstract class rcube_storage
*/
abstract function get_cache($key);
/**
* Delete outdated cache entries
*/
abstract function expunge_cache();
} // end class rcube_storage
/**
* Class representing a message part
*
* @package Mail
*/
class rcube_message_part
{
var $mime_id = '';
var $ctype_primary = 'text';
var $ctype_secondary = 'plain';
var $mimetype = 'text/plain';
var $disposition = '';
var $filename = '';
var $encoding = '8bit';
var $charset = '';
var $size = 0;
var $headers = array();
var $d_parameters = array();
var $ctype_parameters = array();
function __clone()
{
if (isset($this->parts)) {
foreach ($this->parts as $idx => $part) {
if (is_object($part)) {
$this->parts[$idx] = clone $part;
}
}
}
}
}
/**
* Class for sorting an array of rcube_mail_header objects in a predetermined order.
*
* @package Mail
* @author Eric Stadtherr
*/
class rcube_header_sorter
{
private $uids = array();
/**
* Set the predetermined sort order.
*
* @param array $index Numerically indexed array of IMAP UIDs
*/
function set_index($index)
{
$index = array_flip($index);
$this->uids = $index;
}
/**
* Sort the array of header objects
*
* @param array $headers Array of rcube_mail_header objects indexed by UID
*/
function sort_headers(&$headers)
{
uksort($headers, array($this, "compare_uids"));
}
/**
* Sort method called by uksort()
*
* @param int $a Array key (UID)
* @param int $b Array key (UID)
*/
function compare_uids($a, $b)
{
// then find each sequence number in my ordered list
$posa = isset($this->uids[$a]) ? intval($this->uids[$a]) : -1;
$posb = isset($this->uids[$b]) ? intval($this->uids[$b]) : -1;
// return the relative position as the comparison value
return $posa - $posb;
}
}

@ -98,7 +98,7 @@ class rcube_string_replacer
$i = $this->add($prefix . html::a(array(
'href' => $url_prefix . $url,
'target' => '_blank'
), Q($url)) . $suffix);
), rcube_ui::Q($url)) . $suffix);
}
// Return valid link for recognized schemes, otherwise, return the unmodified string for unrecognized schemes.
@ -118,8 +118,8 @@ class rcube_string_replacer
$i = $this->add(html::a(array(
'href' => 'mailto:' . $href,
'onclick' => "return ".JS_OBJECT_NAME.".command('compose','".JQ($href)."',this)",
), Q($href)) . $suffix);
'onclick' => "return ".JS_OBJECT_NAME.".command('compose','".rcube_ui::JQ($href)."',this)",
), rcube_ui::Q($href)) . $suffix);
return $i >= 0 ? $this->get_replacement($i) : '';
}

File diff suppressed because it is too large Load Diff

@ -66,7 +66,7 @@ class rcube_user
if ($id && !$sql_arr) {
$sql_result = $this->db->query(
"SELECT * FROM ".get_table_name('users')." WHERE user_id = ?", $id);
"SELECT * FROM ".$this->db->table_name('users')." WHERE user_id = ?", $id);
$sql_arr = $this->db->fetch_assoc($sql_result);
}
@ -127,9 +127,9 @@ class rcube_user
if (!empty($_SESSION['preferences'])) {
// Check last write attempt time, try to write again (every 5 minutes)
if ($_SESSION['preferences_time'] < time() - 5 * 60) {
$saved_prefs = unserialize($_SESSION['preferences']);
$saved_prefs = unserialize($_SESSION['preferences']);
$this->rc->session->remove('preferences');
$this->rc->session->remove('preferences_time');
$this->rc->session->remove('preferences_time');
$this->save_prefs($saved_prefs);
}
else {
@ -173,7 +173,7 @@ class rcube_user
$save_prefs = serialize($save_prefs);
$this->db->query(
"UPDATE ".get_table_name('users').
"UPDATE ".$this->db->table_name('users').
" SET preferences = ?".
", language = ?".
" WHERE user_id = ?",
@ -232,7 +232,7 @@ class rcube_user
$result = array();
$sql_result = $this->db->query(
"SELECT * FROM ".get_table_name('identities').
"SELECT * FROM ".$this->db->table_name('identities').
" WHERE del <> 1 AND user_id = ?".
($sql_add ? " ".$sql_add : "").
" ORDER BY ".$this->db->quoteIdentifier('standard')." DESC, name ASC, identity_id ASC",
@ -267,7 +267,7 @@ class rcube_user
$query_params[] = $iid;
$query_params[] = $this->ID;
$sql = "UPDATE ".get_table_name('identities').
$sql = "UPDATE ".$this->db->table_name('identities').
" SET changed = ".$this->db->now().", ".join(', ', $query_cols).
" WHERE identity_id = ?".
" AND user_id = ?".
@ -301,7 +301,7 @@ class rcube_user
$insert_cols[] = 'user_id';
$insert_values[] = $this->ID;
$sql = "INSERT INTO ".get_table_name('identities').
$sql = "INSERT INTO ".$this->db->table_name('identities').
" (changed, ".join(', ', $insert_cols).")".
" VALUES (".$this->db->now().", ".join(', ', array_pad(array(), sizeof($insert_values), '?')).")";
@ -324,7 +324,7 @@ class rcube_user
return false;
$sql_result = $this->db->query(
"SELECT count(*) AS ident_count FROM ".get_table_name('identities').
"SELECT count(*) AS ident_count FROM ".$this->db->table_name('identities').
" WHERE user_id = ? AND del <> 1",
$this->ID);
@ -335,7 +335,7 @@ class rcube_user
return -1;
$this->db->query(
"UPDATE ".get_table_name('identities').
"UPDATE ".$this->db->table_name('identities').
" SET del = 1, changed = ".$this->db->now().
" WHERE user_id = ?".
" AND identity_id = ?",
@ -355,7 +355,7 @@ class rcube_user
{
if ($this->ID && $iid) {
$this->db->query(
"UPDATE ".get_table_name('identities').
"UPDATE ".$this->db->table_name('identities').
" SET ".$this->db->quoteIdentifier('standard')." = '0'".
" WHERE user_id = ?".
" AND identity_id <> ?".
@ -373,7 +373,7 @@ class rcube_user
{
if ($this->ID) {
$this->db->query(
"UPDATE ".get_table_name('users').
"UPDATE ".$this->db->table_name('users').
" SET last_login = ".$this->db->now().
" WHERE user_id = ?",
$this->ID);
@ -403,7 +403,7 @@ class rcube_user
$dbh = rcmail::get_instance()->get_dbh();
// query for matching user name
$query = "SELECT * FROM ".get_table_name('users')." WHERE mail_host = ? AND %s = ?";
$query = "SELECT * FROM ".$dbh->table_name('users')." WHERE mail_host = ? AND %s = ?";
$sql_result = $dbh->query(sprintf($query, 'username'), $host, $user);
// query for matching alias
@ -451,7 +451,7 @@ class rcube_user
$dbh = $rcmail->get_dbh();
$dbh->query(
"INSERT INTO ".get_table_name('users').
"INSERT INTO ".$dbh->table_name('users').
" (created, last_login, username, mail_host, alias, language)".
" VALUES (".$dbh->now().", ".$dbh->now().", ?, ?, ?, ?)",
strip_newlines($user),
@ -507,7 +507,7 @@ class rcube_user
}
}
else {
raise_error(array(
rcube::raise_error(array(
'code' => 500,
'type' => 'php',
'line' => __LINE__,
@ -573,7 +573,7 @@ class rcube_user
$sql_result = $this->db->query(
"SELECT search_id AS id, ".$this->db->quoteIdentifier('name')
." FROM ".get_table_name('searches')
." FROM ".$this->db->table_name('searches')
." WHERE user_id = ?"
." AND ".$this->db->quoteIdentifier('type')." = ?"
." ORDER BY ".$this->db->quoteIdentifier('name'),
@ -607,7 +607,7 @@ class rcube_user
"SELECT ".$this->db->quoteIdentifier('name')
.", ".$this->db->quoteIdentifier('data')
.", ".$this->db->quoteIdentifier('type')
." FROM ".get_table_name('searches')
." FROM ".$this->db->table_name('searches')
." WHERE user_id = ?"
." AND search_id = ?",
(int) $this->ID, (int) $id);
@ -638,7 +638,7 @@ class rcube_user
return false;
$this->db->query(
"DELETE FROM ".get_table_name('searches')
"DELETE FROM ".$this->db->table_name('searches')
." WHERE user_id = ?"
." AND search_id = ?",
(int) $this->ID, $sid);
@ -668,7 +668,7 @@ class rcube_user
$insert_cols[] = $this->db->quoteIdentifier('data');
$insert_values[] = serialize($data['data']);
$sql = "INSERT INTO ".get_table_name('searches')
$sql = "INSERT INTO ".$this->db->table_name('searches')
." (".join(', ', $insert_cols).")"
." VALUES (".join(', ', array_pad(array(), sizeof($insert_values), '?')).")";

@ -389,7 +389,7 @@ class rcube_vcard
if (is_array($subnode) && (($charset = $force_charset) || ($subnode['charset'] && ($charset = $subnode['charset'][0])))) {
foreach ($subnode as $j => $value) {
if (is_numeric($j) && is_string($value))
$card[$key][$i][$j] = rcube_charset_convert($value, $charset);
$card[$key][$i][$j] = rcube_charset::convert($value, $charset);
}
unset($card[$key][$i]['charset']);
}
@ -425,7 +425,7 @@ class rcube_vcard
$charset = null;
// detect charset and convert to utf-8
else if (($charset = self::detect_encoding($data)) && $charset != RCMAIL_CHARSET) {
$data = rcube_charset_convert($data, $charset);
$data = rcube_charset::convert($data, $charset);
$data = preg_replace(array('/^[\xFE\xFF]{2}/', '/^\xEF\xBB\xBF/', '/^\x00+/'), '', $data); // also remove BOM
$charset = RCMAIL_CHARSET;
}
@ -780,7 +780,7 @@ class rcube_vcard
)*\z/xs', substr($string, 0, 2048)))
return 'UTF-8';
return rcmail::get_instance()->config->get('default_charset', 'ISO-8859-1'); # fallback to Latin-1
return rcube::get_instance()->config->get('default_charset', 'ISO-8859-1'); # fallback to Latin-1
}
}

@ -203,7 +203,7 @@ function rcmail_directory_list($attrib)
'rel' => '%s',
'onclick' => "return ".JS_OBJECT_NAME.".command('list','%s',this)"), '%s'));
$sources = (array) $OUTPUT->env['address_sources'];
$sources = (array) $OUTPUT->get_env('address_sources');
reset($sources);
// currently selected source

@ -1162,10 +1162,22 @@ function rcmail_save_attachment(&$message, $pid)
$data = $message->get_part_content($pid);
}
$mimetype = $part->ctype_primary . '/' . $part->ctype_secondary;
$filename = $part->filename;
if (!strlen($filename)) {
if ($mimetype == 'text/html') {
$filename = rcube_label('htmlmessage');
}
else {
$filename = 'Part_'.$pid;
}
$filename .= '.' . $part->ctype_secondary;
}
$attachment = array(
'group' => $COMPOSE['id'],
'name' => $part->filename ? $part->filename : 'Part_'.$pid.'.'.$part->ctype_secondary,
'mimetype' => $part->ctype_primary . '/' . $part->ctype_secondary,
'name' => $filename,
'mimetype' => $mimetype,
'content_id' => $part->content_id,
'data' => $data,
'path' => $path,

@ -230,7 +230,7 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE, $a_show_cols=null
// Make sure there are no duplicated columns (#1486999)
$a_show_cols = array_unique($a_show_cols);
// Plugins may set header's list_cols/list_flags and other rcube_mail_header variables
// Plugins may set header's list_cols/list_flags and other rcube_message_header variables
// and list columns
$plugin = $RCMAIL->plugins->exec_hook('messages_list',
array('messages' => $a_headers, 'cols' => $a_show_cols));
@ -1024,10 +1024,20 @@ function rcmail_message_body($attrib)
foreach ($MESSAGE->parts as $i => $part) {
if ($part->type == 'headers')
$out .= rcmail_message_headers(sizeof($header_attrib) ? $header_attrib : NULL, $part->headers);
else if ($part->type == 'content' && $part->size) {
else if ($part->type == 'content') {
// unsapported
if ($part->realtype) {
if ($part->realtype == 'multipart/encrypted') {
$out .= html::span('part-notice', rcube_label('encryptedmessage'));
}
continue;
}
else if (!$part->size) {
continue;
}
// Check if we have enough memory to handle the message in it
// #1487424: we need up to 10x more memory than the body
if (!rcmail_mem_check($part->size * 10)) {
else if (!rcmail_mem_check($part->size * 10)) {
$out .= html::span('part-notice', rcube_label('messagetoobig'). ' '
. html::a('?_task=mail&_action=get&_download=1&_uid='.$MESSAGE->uid.'&_part='.$part->mime_id
.'&_mbox='. urlencode($RCMAIL->storage->get_folder()), rcube_label('download')));
@ -1438,9 +1448,14 @@ function rcmail_message_part_controls($attrib)
$part = $MESSAGE->mime_parts[$part];
$table = new html_table(array('cols' => 3));
if (!empty($part->filename)) {
$filename = $part->filename;
if (empty($filename) && $attach_prop->mimetype == 'text/html') {
$filename = rcube_label('htmlmessage');
}
if (!empty($filename)) {
$table->add('title', Q(rcube_label('filename')));
$table->add('header', Q($part->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'))));
}

@ -69,8 +69,15 @@ if (!empty($_GET['_uid'])) {
// show part page
if (!empty($_GET['_frame'])) {
if (($part_id = get_input_value('_part', RCUBE_INPUT_GPC)) && ($part = $MESSAGE->mime_parts[$part_id]) && $part->filename)
$OUTPUT->set_pagetitle($part->filename);
if (($part_id = get_input_value('_part', RCUBE_INPUT_GPC)) && ($part = $MESSAGE->mime_parts[$part_id])) {
$filename = $part->filename;
if (empty($filename) && $part->mimetype == 'text/html') {
$filename = rcube_label('htmlmessage');
}
if (!empty($filename)) {
$OUTPUT->set_pagetitle($filename);
}
}
$OUTPUT->send('messagepart');
exit;
@ -130,15 +137,25 @@ else if (strlen($pid = get_input_value('_part', RCUBE_INPUT_GET))) {
$out = rcmail_print_body($part, array('safe' => $MESSAGE->is_safe, 'inline_html' => false));
}
$OUTPUT = new rcube_html_page();
$OUTPUT = new rcube_output_html();
$OUTPUT->write($out);
}
else {
// don't kill the connection if download takes more than 30 sec.
@set_time_limit(0);
if ($part->filename) {
$filename = $part->filename;
}
else if ($part->mimetype == 'text/html') {
$filename = rcube_label('htmlmessage');
}
else {
$filename = ($MESSAGE->subject ? $MESSAGE->subject : 'roundcube');
}
$ext = '.' . ($mimetype == 'text/plain' ? 'txt' : $ctype_secondary);
$filename = $part->filename ? $part->filename : ($MESSAGE->subject ? $MESSAGE->subject : 'roundcube') . $ext;
$filename .= $ext;
$filename = preg_replace('[\r\n]', '', $filename);
if ($browser->ie && $browser->ver < 7)

@ -126,20 +126,24 @@ function rcmail_message_attachments($attrib)
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))));
$filename = $attach_prop->filename;
if (empty($filename) && $attach_prop->mimetype == 'text/html') {
$filename = rcube_label('htmlmessage');
}
else {
if (mb_strlen($attach_prop->filename) > 50) {
$filename = abbreviate_string($attach_prop->filename, 50);
$title = $attach_prop->filename;
if ($PRINT_MODE) {
$ol .= html::tag('li', null, sprintf("%s (%s)", Q($filename), Q(show_bytes($attach_prop->size))));
}
else {
$filename = $attach_prop->filename;
$title = '';
}
$ol .= html::tag('li', rcmail_filetype2classname($attach_prop->mimetype, $attach_prop->filename),
if (mb_strlen($filename) > 50) {
$filename = abbreviate_string($filename, 50);
$title = $filename;
}
else {
$title = '';
}
$ol .= html::tag('li', rcmail_filetype2classname($attach_prop->mimetype, $filename),
html::a(array(
'href' => $MESSAGE->get_part_url($attach_prop->mime_id, false),
'onclick' => sprintf(

@ -22,6 +22,7 @@
*/
$rcmail = rcmail::get_instance();
// browser is not compatible with this application
if ($ERROR_CODE==409) {
@ -88,7 +89,7 @@ else {
$__error_title = "SERVICE CURRENTLY NOT AVAILABLE!";
$__error_text = "Please contact your server-administrator.";
if (($CONFIG['debug_level'] & 4) && $ERROR_MESSAGE)
if (($rcmail->config->get('debug_level') & 4) && $ERROR_MESSAGE)
$__error_text = $ERROR_MESSAGE;
else
$__error_text = sprintf('Error No. [%s]', $ERROR_CODE);
@ -97,7 +98,7 @@ else {
$HTTP_ERR_CODE = $ERROR_CODE && $ERROR_CODE < 600 ? $ERROR_CODE : 500;
// Ajax request
if ($OUTPUT && ($OUTPUT instanceof rcube_json_output)) {
if ($rcmail->output && $rcmail->output->type == 'js') {
header("HTTP/1.0 $HTTP_ERR_CODE $__error_title");
die;
}
@ -110,13 +111,13 @@ $__page_content = <<<EOF
</div>
EOF;
if ($OUTPUT && $OUTPUT->template_exists('error')) {
$OUTPUT->reset();
$OUTPUT->send('error');
if ($rcmail->output && $rcmail->output->template_exists('error')) {
$rcmail->output->reset();
$rcmail->output->send('error');
}
$__skin = $CONFIG->skin ? $CONFIG->skin : 'default';
$__productname = $CONFIG['product_name'] ? $CONFIG['product_name'] : 'Roundcube Webmail';
$__skin = $rcmail->config->get('skin', 'default');
$__productname = $rcmail->config->get('product_name', 'Roundcube Webmail');
// print system error page
print <<<EOF

Loading…
Cancel
Save