summaryrefslogtreecommitdiff
path: root/program/include
diff options
context:
space:
mode:
Diffstat (limited to 'program/include')
-rw-r--r--program/include/iniset.php2
-rw-r--r--program/include/rcmail.php130
-rw-r--r--program/include/rcmail_install.php60
-rw-r--r--program/include/rcmail_output_html.php135
4 files changed, 167 insertions, 160 deletions
diff --git a/program/include/iniset.php b/program/include/iniset.php
index cb72ae15b..5c3065489 100644
--- a/program/include/iniset.php
+++ b/program/include/iniset.php
@@ -61,7 +61,7 @@ require_once 'Roundcube/bootstrap.php';
spl_autoload_register('rcmail_autoload');
// include composer autoloader (if available)
-if (file_exists('vendor/autoload.php')) {
+if (@file_exists('vendor/autoload.php')) {
require 'vendor/autoload.php';
}
diff --git a/program/include/rcmail.php b/program/include/rcmail.php
index 5a5d4cb83..1a227927e 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -428,7 +428,8 @@ class rcmail extends rcube
}
// add some basic labels to client
- $this->output->add_label('loading', 'servererror', 'connerror', 'requesttimedout', 'refreshing');
+ $this->output->add_label('loading', 'servererror', 'connerror', 'requesttimedout',
+ 'refreshing', 'windowopenerror');
return $this->output;
}
@@ -494,30 +495,18 @@ class rcmail extends rcube
$username_domain = $this->config->get('username_domain');
$login_lc = $this->config->get('login_lc', 2);
- if (!$host) {
- $host = $default_host;
- }
-
- // Validate that selected host is in the list of configured hosts
- if (is_array($default_host)) {
- $allowed = false;
-
- foreach ($default_host as $key => $host_allowed) {
- if (!is_numeric($key)) {
- $host_allowed = $key;
- }
- if ($host == $host_allowed) {
- $allowed = true;
- break;
- }
+ // host is validated in rcmail::autoselect_host(), so here
+ // we'll only handle unset host (if possible)
+ if (!$host && !empty($default_host)) {
+ if (is_array($default_host)) {
+ list($key, $val) = each($default_host);
+ $host = is_numeric($key) ? $val : $key;
}
-
- if (!$allowed) {
- $host = null;
+ else {
+ $host = $default_host;
}
- }
- else if (!empty($default_host) && $host != rcube_utils::parse_host($default_host)) {
- $host = null;
+
+ $host = rcube_utils::parse_host($host);
}
if (!$host) {
@@ -840,7 +829,7 @@ class rcmail extends rcube
}
// write performance stats to logs/console
- if ($this->config->get('devel_mode')) {
+ if ($this->config->get('devel_mode') || $this->config->get('performance_stats')) {
// make sure logged numbers use unified format
setlocale(LC_NUMERIC, 'en_US.utf8', 'en_US.UTF-8', 'en_US', 'C');
@@ -1784,31 +1773,36 @@ class rcmail extends rcube
return;
}
- $lang = strtolower($_SESSION['language']);
+ $lang_codes = array($_SESSION['language']);
- // TinyMCE uses two-letter lang codes, with exception of Chinese
- if (strpos($lang, 'zh_') === 0) {
- $lang = str_replace('_', '-', $lang);
+ if ($pos = strpos($_SESSION['language'], '_')) {
+ $lang_codes[] = substr($_SESSION['language'], 0, $pos);
}
- else {
- $lang = substr($lang, 0, 2);
+
+ foreach ($lang_codes as $code) {
+ if (file_exists(INSTALL_PATH . 'program/js/tinymce/langs/'.$code.'.js')) {
+ $lang = $code;
+ break;
+ }
}
- if (!file_exists(INSTALL_PATH . 'program/js/tiny_mce/langs/'.$lang.'.js')) {
+ if (empty($lang)) {
$lang = 'en';
}
- $script = json_encode(array(
+ $config = array(
'mode' => $mode,
'lang' => $lang,
'skin_path' => $this->output->get_skin_path(),
'spellcheck' => intval($this->config->get('enable_spellcheck')),
'spelldict' => intval($this->config->get('spellcheck_dictionary'))
- ));
+ );
- $this->output->include_script('tiny_mce/tiny_mce.js');
+ $this->output->add_label('selectimage', 'addimage', 'selectmedia', 'addmedia');
+ $this->output->set_env('editor_config', $config);
+ $this->output->include_css('program/js/tinymce/roundcube/browser.css');
+ $this->output->include_script('tinymce/tinymce.min.js');
$this->output->include_script('editor.js');
- $this->output->add_script("rcmail_editor_init($script)", 'docready');
}
/**
@@ -1840,8 +1834,8 @@ class rcmail extends rcube
);
foreach ($emoticons as $idx => $file) {
- // <img title="Cry" src="http://.../program/js/tiny_mce/plugins/emotions/img/smiley-cry.gif" border="0" alt="Cry" />
- $search[] = '/<img title="[a-z ]+" src="https?:\/\/[a-z0-9_.\/-]+\/tiny_mce\/plugins\/emotions\/img\/'.$file.'.gif"[^>]+\/>/i';
+ // <img title="Cry" src="http://.../program/js/tinymce/plugins/emoticons/img/smiley-cry.gif" border="0" alt="Cry" />
+ $search[] = '/<img title="[a-z ]+" src="https?:\/\/[a-z0-9_.\/-]+\/tinymce\/plugins\/emoticons\/img\/'.$file.'.gif"[^>]+\/>/i';
$replace[] = $idx;
}
@@ -1853,27 +1847,52 @@ class rcmail extends rcube
*/
public function upload_progress()
{
- $prefix = ini_get('apc.rfc1867_prefix');
$params = array(
'action' => $this->action,
- 'name' => rcube_utils::get_input_value('_progress', rcube_utils::INPUT_GET),
+ 'name' => rcube_utils::get_input_value('_progress', rcube_utils::INPUT_GET),
);
- if (function_exists('apc_fetch')) {
+ if (function_exists('uploadprogress_get_info')) {
+ $status = uploadprogress_get_info($params['name']);
+
+ if (!empty($status)) {
+ $params['current'] = $status['bytes_uploaded'];
+ $params['total'] = $status['bytes_total'];
+ }
+ }
+
+ if (!isset($status) && filter_var(ini_get('apc.rfc1867'), FILTER_VALIDATE_BOOLEAN)
+ && ini_get('apc.rfc1867_name')
+ ) {
+ $prefix = ini_get('apc.rfc1867_prefix');
$status = apc_fetch($prefix . $params['name']);
if (!empty($status)) {
- $status['percent'] = round($status['current']/$status['total']*100);
- $params = array_merge($status, $params);
+ $params['current'] = $status['current'];
+ $params['total'] = $status['total'];
}
}
- if (isset($params['percent']))
- $params['text'] = $this->gettext(array('name' => 'uploadprogress', 'vars' => array(
- 'percent' => $params['percent'] . '%',
- 'current' => $this->show_bytes($params['current']),
- 'total' => $this->show_bytes($params['total'])
- )));
+ if (!isset($status) && filter_var(ini_get('session.upload_progress.enabled'), FILTER_VALIDATE_BOOLEAN)
+ && ini_get('session.upload_progress.name')
+ ) {
+ $key = ini_get('session.upload_progress.prefix') . $params['name'];
+
+ $params['total'] = $_SESSION[$key]['content_length'];
+ $params['current'] = $_SESSION[$key]['bytes_processed'];
+ }
+
+ if (!empty($params['total'])) {
+ $params['percent'] = round($status['current']/$status['total']*100);
+ $params['text'] = $this->gettext(array(
+ 'name' => 'uploadprogress',
+ 'vars' => array(
+ 'percent' => $params['percent'] . '%',
+ 'current' => $this->show_bytes($params['current']),
+ 'total' => $this->show_bytes($params['total'])
+ )
+ ));
+ }
$this->output->command('upload_progress_update', $params);
$this->output->send();
@@ -1885,9 +1904,18 @@ class rcmail extends rcube
public function upload_init()
{
// Enable upload progress bar
- $rfc1867 = filter_var(ini_get('apc.rfc1867'), FILTER_VALIDATE_BOOLEAN);
- if ($rfc1867 && ($seconds = $this->config->get('upload_progress'))) {
- if ($field_name = ini_get('apc.rfc1867_name')) {
+ if ($seconds = $this->config->get('upload_progress')) {
+ if (function_exists('uploadprogress_get_info')) {
+ $field_name = 'UPLOAD_IDENTIFIER';
+ }
+ if (!$field_name && filter_var(ini_get('apc.rfc1867'), FILTER_VALIDATE_BOOLEAN)) {
+ $field_name = ini_get('apc.rfc1867_name');
+ }
+ if (!$field_name && filter_var(ini_get('session.upload_progress.enabled'), FILTER_VALIDATE_BOOLEAN)) {
+ $field_name = ini_get('session.upload_progress.name');
+ }
+
+ if ($field_name) {
$this->output->set_env('upload_progress_name', $field_name);
$this->output->set_env('upload_progress_time', (int) $seconds);
}
diff --git a/program/include/rcmail_install.php b/program/include/rcmail_install.php
index ca06f10b7..eec21ec7e 100644
--- a/program/include/rcmail_install.php
+++ b/program/include/rcmail_install.php
@@ -710,7 +710,8 @@ class rcmail_install
// read schema file from /SQL/*
$fname = INSTALL_PATH . "SQL/$engine.initial.sql";
if ($sql = @file_get_contents($fname)) {
- $this->exec_sql($sql, $DB);
+ $DB->set_option('table_prefix', $this->config['db_prefix']);
+ $DB->exec_script($sql);
}
else {
$this->fail('DB Schema', "Cannot read the schema file: $fname");
@@ -745,63 +746,6 @@ class rcmail_install
/**
- * Execute the given SQL queries on the database connection
- *
- * @param string SQL queries to execute
- * @param object rcube_db Database connection
- * @return boolen True on success, False on error
- */
- function exec_sql($sql, $DB)
- {
- $sql = $this->fix_table_names($sql, $DB);
- $buff = '';
- foreach (explode("\n", $sql) as $line) {
- if (preg_match('/^--/', $line) || trim($line) == '')
- continue;
-
- $buff .= $line . "\n";
- if (preg_match('/(;|^GO)$/', trim($line))) {
- $DB->query($buff);
- $buff = '';
- if ($DB->is_error())
- break;
- }
- }
-
- return !$DB->is_error();
- }
-
-
- /**
- * Parse SQL file and fix table names according to db_prefix
- * Note: This need to be a complete database initial file
- */
- private function fix_table_names($sql, $DB)
- {
- if (empty($this->config['db_prefix'])) {
- return $sql;
- }
-
- // replace table names
- if (preg_match_all('/CREATE TABLE (\[dbo\]\.|IF NOT EXISTS )?[`"\[\]]*([^`"\[\] \r\n]+)/i', $sql, $matches)) {
- foreach ($matches[2] as $table) {
- $real_table = $this->config['db_prefix'] . $table;
- $sql = preg_replace("/([^a-zA-Z0-9_])$table([^a-zA-Z0-9_])/", "\\1$real_table\\2", $sql);
- }
- }
- // replace sequence names
- if ($DB->db_provider == 'postgres' && preg_match_all('/CREATE SEQUENCE (IF NOT EXISTS )?"?([^" \n\r]+)/i', $sql, $matches)) {
- foreach ($matches[2] as $sequence) {
- $real_sequence = $this->config['db_prefix'] . $sequence;
- $sql = preg_replace("/([^a-zA-Z0-9_])$sequence([^a-zA-Z0-9_])/", "\\1$real_sequence\\2", $sql);
- }
- }
-
- return $sql;
- }
-
-
- /**
* Handler for Roundcube errors
*/
function raise_error($p)
diff --git a/program/include/rcmail_output_html.php b/program/include/rcmail_output_html.php
index e8b5c9828..6594209f6 100644
--- a/program/include/rcmail_output_html.php
+++ b/program/include/rcmail_output_html.php
@@ -5,7 +5,7 @@
| program/include/rcmail_output_html.php |
| |
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2006-2013, The Roundcube Dev Team |
+ | Copyright (C) 2006-2014, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -30,16 +30,16 @@ class rcmail_output_html extends rcmail_output
{
public $type = 'html';
- protected $message = null;
- protected $js_env = array();
- protected $js_labels = array();
- protected $js_commands = array();
- protected $skin_paths = array();
+ protected $message;
protected $template_name;
+ protected $js_env = array();
+ protected $js_labels = array();
+ protected $js_commands = array();
+ protected $skin_paths = array();
protected $scripts_path = '';
protected $script_files = array();
- protected $css_files = array();
- protected $scripts = array();
+ protected $css_files = array();
+ protected $scripts = array();
protected $default_template = "<html>\n<head><title></title></head>\n<body></body>\n</html>";
protected $header = '';
protected $footer = '';
@@ -58,8 +58,6 @@ class rcmail_output_html extends rcmail_output
/**
* Constructor
- *
- * @todo Replace $this->config with the real rcube_config object
*/
public function __construct($task = null, $framed = false)
{
@@ -67,10 +65,10 @@ class rcmail_output_html extends rcmail_output
$this->devel_mode = $this->config->get('devel_mode');
- //$this->framed = $framed;
$this->set_env('task', $task);
$this->set_env('x_frame_options', $this->config->get('x_frame_options', 'sameorigin'));
$this->set_env('standard_windows', (bool) $this->config->get('standard_windows'));
+ $this->set_env('locale', $_SESSION['language']);
// add cookie info
$this->set_env('cookie_domain', ini_get('session.cookie_domain'));
@@ -84,7 +82,7 @@ class rcmail_output_html extends rcmail_output
if (!empty($_REQUEST['_extwin']))
$this->set_env('extwin', 1);
- if ($this->framed || !empty($_REQUEST['_framed']))
+ if ($this->framed || $framed)
$this->set_env('framed', 1);
$lic = <<<EOF
@@ -209,6 +207,14 @@ EOF;
// read meta file and check for dependecies
$meta = @file_get_contents(RCUBE_INSTALL_PATH . $skin_path . '/meta.json');
$meta = @json_decode($meta, true);
+
+ $meta['path'] = $skin_path;
+ $skin_id = end(explode('/', $skin_path));
+ if (!$meta['name']) {
+ $meta['name'] = $skin_id;
+ }
+ $this->skins[$skin_id] = $meta;
+
if ($meta['extends']) {
$path = RCUBE_INSTALL_PATH . 'skins/';
if (is_dir($path . $meta['extends']) && is_readable($path . $meta['extends'])) {
@@ -248,8 +254,9 @@ EOF;
public function get_skin_file($file, &$skin_path = null, $add_path = null)
{
$skin_paths = $this->skin_paths;
- if ($add_path)
+ if ($add_path) {
array_unshift($skin_paths, $add_path);
+ }
foreach ($skin_paths as $skin_path) {
$path = realpath($skin_path . $file);
@@ -283,9 +290,9 @@ EOF;
{
$cmd = func_get_args();
if (strpos($cmd[0], 'plugin.') !== false)
- $this->js_commands[] = array('triggerEvent', $cmd[0], $cmd[1]);
+ $this->js_commands[] = array('triggerEvent', $cmd[0], $cmd[1]);
else
- $this->js_commands[] = $cmd;
+ $this->js_commands[] = $cmd;
}
/**
@@ -295,7 +302,7 @@ EOF;
{
$args = func_get_args();
if (count($args) == 1 && is_array($args[0]))
- $args = $args[0];
+ $args = $args[0];
foreach ($args as $name) {
$this->js_labels[$name] = $this->app->gettext($name);
@@ -336,13 +343,13 @@ EOF;
public function reset($all = false)
{
$framed = $this->framed;
- $env = $all ? null : array_intersect_key($this->env, array('extwin'=>1, 'framed'=>1));
+ $env = $all ? null : array_intersect_key($this->env, array('extwin'=>1, 'framed'=>1));
parent::reset();
// let some env variables survive
- $this->env = $this->js_env = $env;
- $this->framed = $framed || $this->env['framed'];
+ $this->env = $this->js_env = $env;
+ $this->framed = $framed || $this->env['framed'];
$this->js_labels = array();
$this->js_commands = array();
$this->script_files = array();
@@ -421,20 +428,27 @@ EOF;
array_unshift($this->js_commands, array('hide_message', $unlock));
}
- if (!empty($this->script_files))
- $this->set_env('request_token', $this->app->get_request_token());
+ if (!empty($this->script_files)) {
+ $this->set_env('request_token', $this->app->get_request_token());
+ }
+
+ $commands = $this->get_js_commands($framed);
- // write all env variables to client
- if ($commands = $this->get_js_commands()) {
- $js = $this->framed ? "if (window.parent) {\n" : '';
- $js .= $commands . ($this->framed ? ' }' : '');
- $this->add_script($js, 'head_top');
+ // if all js commands go to parent window we can ignore all
+ // script files and skip rcube_webmail initialization (#1489792)
+ if ($framed) {
+ $this->scripts = array();
+ $this->script_files = array();
}
+ // write all javascript commands
+ $this->add_script($commands, 'head_top');
+
// send clickjacking protection headers
- $iframe = $this->framed || !empty($_REQUEST['_framed']);
- if (!headers_sent() && ($xframe = $this->app->config->get('x_frame_options', 'sameorigin')))
+ $iframe = $this->framed || $this->env['framed'];
+ if (!headers_sent() && ($xframe = $this->app->config->get('x_frame_options', 'sameorigin'))) {
header('X-Frame-Options: ' . ($iframe && $xframe == 'deny' ? 'sameorigin' : $xframe));
+ }
// call super method
$this->_write($template, $this->config->get('skin_path'));
@@ -451,15 +465,15 @@ EOF;
*/
function parse($name = 'main', $exit = true, $write = true)
{
- $plugin = false;
- $realname = $name;
+ $plugin = false;
+ $realname = $name;
$this->template_name = $realname;
$temp = explode('.', $name, 2);
if (count($temp) > 1) {
- $plugin = $temp[0];
- $name = $temp[1];
- $skin_dir = $plugin . '/skins/' . $this->config->get('skin');
+ $plugin = $temp[0];
+ $name = $temp[1];
+ $skin_dir = $plugin . '/skins/' . $this->config->get('skin');
// apply skin search escalation list to plugin directory
$plugin_skin_paths = array();
@@ -556,27 +570,47 @@ EOF;
*
* @return string $out
*/
- protected function get_js_commands()
+ protected function get_js_commands(&$framed = null)
{
- $out = '';
if (!$this->framed && !empty($this->js_env)) {
- $out .= self::JS_OBJECT_NAME . '.set_env('.self::json_serialize($this->js_env).");\n";
+ $this->command('set_env', $this->js_env);
}
+
if (!empty($this->js_labels)) {
$this->command('add_label', $this->js_labels);
}
+
+ $out = '';
+ $parent_commands = 0;
+
foreach ($this->js_commands as $i => $args) {
$method = array_shift($args);
+ $parent = $this->framed || preg_match('/^parent\./', $method);
+
foreach ($args as $i => $arg) {
$args[$i] = self::json_serialize($arg);
}
- $parent = $this->framed || preg_match('/^parent\./', $method);
- $out .= sprintf(
- "%s.%s(%s);\n",
- ($parent ? 'if(window.parent && parent.'.self::JS_OBJECT_NAME.') parent.' : '') . self::JS_OBJECT_NAME,
- preg_replace('/^parent\./', '', $method),
- implode(',', $args)
- );
+
+ if ($parent) {
+ $parent_commands++;
+ $method = preg_replace('/^parent\./', '', $method);
+ $parent_prefix = 'if (window.parent && parent.' . self::JS_OBJECT_NAME . ') parent.';
+ $method = $parent_prefix . self::JS_OBJECT_NAME . '.' . $method;
+ }
+ else {
+ $method = self::JS_OBJECT_NAME . '.' . $method;
+ }
+
+ $out .= sprintf("%s(%s);\n", $method, implode(',', $args));
+ }
+
+ $framed = $parent_prefix && $parent_commands == count($this->js_commands);
+
+ // make the output more compact if all commands go to parent window
+ if ($framed) {
+ $out = "if (window.parent && parent." . self::JS_OBJECT_NAME . ") {\n"
+ . str_replace($parent_prefix, "\tparent.", $out)
+ . "}\n";
}
return $out;
@@ -592,13 +626,14 @@ EOF;
public function abs_url($str, $search_path = false)
{
if ($str[0] == '/') {
- if ($search_path && ($file_url = $this->get_skin_file($str, $skin_path)))
+ if ($search_path && ($file_url = $this->get_skin_file($str, $skin_path))) {
return $file_url;
+ }
return $this->base_path . $str;
}
- else
- return $str;
+
+ return $str;
}
/**
@@ -1243,7 +1278,7 @@ EOF;
// generate html code for button
if ($btn_content) {
- $attrib_str = html::attrib_string($attrib, array_merge($link_attrib, array('data-*')));
+ $attrib_str = html::attrib_string($attrib, $link_attrib);
$out = sprintf('<a%s>%s</a>', $attrib_str, $btn_content);
}
@@ -1333,7 +1368,7 @@ EOF;
$output = trim($templ);
if (empty($output)) {
- $output = $this->default_template;
+ $output = html::doctype('html5') . "\n" . $this->default_template;
$is_empty = true;
}
@@ -1498,7 +1533,7 @@ EOF;
*/
public function form_tag($attrib, $content = null)
{
- if ($this->framed || !empty($_REQUEST['_framed'])) {
+ if ($this->framed || $this->env['framed']) {
$hiddenfield = new html_hiddenfield(array('name' => '_framed', 'value' => '1'));
$hidden = $hiddenfield->show();
}
@@ -1538,7 +1573,7 @@ EOF;
// we already have a <form> tag
if ($attrib['form']) {
- if ($this->framed || !empty($_REQUEST['_framed']))
+ if ($this->framed || $this->env['framed'])
$hidden->add(array('name' => '_framed', 'value' => '1'));
return $hidden->show() . $content;
}