Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2571673
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
38 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/.ci/setup.sh b/.ci/setup.sh
index 45236b1a1..0383009b2 100755
--- a/.ci/setup.sh
+++ b/.ci/setup.sh
@@ -1,15 +1,17 @@
#!/bin/bash
# The script is intended for use on Travis with Trusty distribution
+set -x
+
DIR=$(dirname $0)
GMV=1.5.11
# Roundcube tests and instance configuration
cp $DIR/config-test.inc.php $DIR/../config/config-test.inc.php
# In-Browser tests dependencies installation
# and GreenMail server setup and start
wget http://central.maven.org/maven2/com/icegreen/greenmail-standalone/$GMV/greenmail-standalone-$GMV.jar \
&& (sudo java -Dgreenmail.setup.all -Dgreenmail.users=test:test -jar greenmail-standalone-$GMV.jar &) \
&& sleep 5
diff --git a/program/lib/Roundcube/rcube_config.php b/program/lib/Roundcube/rcube_config.php
index 5226ac32a..9bce9dd3e 100644
--- a/program/lib/Roundcube/rcube_config.php
+++ b/program/lib/Roundcube/rcube_config.php
@@ -1,910 +1,912 @@
<?php
/**
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
| |
| Copyright (C) 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 read configuration settings |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
*/
/**
* Configuration class for Roundcube
*
* @package Framework
* @subpackage Core
*/
class rcube_config
{
const DEFAULT_SKIN = 'elastic';
private $env = '';
private $paths = array();
private $prop = array();
private $errors = array();
private $userprefs = array();
private $immutable = array();
private $client_tz;
/**
* Renamed options
*
* @var array
*/
private $legacy_props = array(
// new name => old name
'mail_pagesize' => 'pagesize',
'addressbook_pagesize' => 'pagesize',
'reply_mode' => 'top_posting',
'refresh_interval' => 'keep_alive',
'min_refresh_interval' => 'min_keep_alive',
'messages_cache_ttl' => 'message_cache_lifetime',
'mail_read_time' => 'preview_pane_mark_read',
'session_debug' => 'log_session',
'redundant_attachments_cache_ttl' => 'redundant_attachments_memcache_ttl',
);
/**
* Object constructor
*
* @param string $env Environment suffix for config files to load
*/
public function __construct($env = '')
{
$this->env = $env;
if ($paths = getenv('RCUBE_CONFIG_PATH')) {
$this->paths = explode(PATH_SEPARATOR, $paths);
// make all paths absolute
foreach ($this->paths as $i => $path) {
if (!rcube_utils::is_absolute_path($path)) {
if ($realpath = realpath(RCUBE_INSTALL_PATH . $path)) {
$this->paths[$i] = unslashify($realpath) . '/';
}
else {
unset($this->paths[$i]);
}
}
else {
$this->paths[$i] = unslashify($path) . '/';
}
}
}
if (defined('RCUBE_CONFIG_DIR') && !in_array(RCUBE_CONFIG_DIR, $this->paths)) {
$this->paths[] = RCUBE_CONFIG_DIR;
}
if (empty($this->paths)) {
$this->paths[] = RCUBE_INSTALL_PATH . 'config/';
}
$this->load();
// Defaults, that we do not require you to configure,
// but contain information that is used in various locations in the code:
if (empty($this->prop['contactlist_fields'])) {
$this->set('contactlist_fields', array('name', 'firstname', 'surname', 'email'));
}
}
/**
* @brief Guess the type the string may fit into.
*
* Look inside the string to determine what type might be best as a container.
*
* @param mixed $value The value to inspect
*
* @return The guess at the type.
*/
private function guess_type($value)
{
$type = 'string';
// array requires hint to be passed.
if (preg_match('/^[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?$/', $value)) {
$type = 'double';
}
else if (preg_match('/^\d+$/', $value)) {
$type = 'integer';
}
else if (preg_match('/^(t(rue)?)|(f(alse)?)$/i', $value)) {
$type = 'boolean';
}
return $type;
}
/**
* @brief Parse environment variable into PHP type.
*
* Perform an appropriate parsing of the string to create the desired PHP type.
*
* @param string $string String to parse into PHP type
* @param string $type Type of value to return
*
* @return Appropriately typed interpretation of $string.
*/
private function parse_env($string, $type)
{
$_ = $string;
switch ($type) {
case 'boolean':
$_ = (boolean) $_;
break;
case 'integer':
$_ = (integer) $_;
break;
case 'double':
$_ = (double) $_;
break;
case 'string':
break;
case 'array':
$_ = json_decode($_, true);
break;
case 'object':
$_ = json_decode($_, false);
break;
case 'resource':
case 'NULL':
default:
$_ = $this->parse_env($_, $this->guess_type($_));
}
return $_;
}
/**
* @brief Get environment variable value.
*
* Retrieve an environment variable's value or if it's not found, return the
* provided default value.
*
* @param string $varname Environment variable name
* @param mixed $default_value Default value to return if necessary
* @param string $type Type of value to return
*
* @return Value of the environment variable or default if not found.
*/
private function getenv_default($varname, $default_value, $type = null)
{
$value = getenv($varname);
if ($value === false) {
$value = $default_value;
}
else {
$value = $this->parse_env($value, $type ?: gettype($default_value));
}
return $value;
}
/**
* Load config from local config file
*/
private function load()
{
// Load default settings
if (!$this->load_from_file('defaults.inc.php')) {
$this->errors[] = 'defaults.inc.php was not found.';
}
// load main config file
if (!$this->load_from_file('config.inc.php')) {
// Old configuration files
if (!$this->load_from_file('main.inc.php') || !$this->load_from_file('db.inc.php')) {
$this->errors[] = 'config.inc.php was not found.';
}
else if (rand(1,100) == 10) { // log warning on every 100th request (average)
trigger_error("config.inc.php was not found. Please migrate your config by running bin/update.sh", E_USER_WARNING);
}
}
// load host-specific configuration
$this->load_host_config();
// set skin (with fallback to old 'skin_path' property)
if (empty($this->prop['skin'])) {
if (!empty($this->prop['skin_path'])) {
$this->prop['skin'] = str_replace('skins/', '', unslashify($this->prop['skin_path']));
}
else {
$this->prop['skin'] = self::DEFAULT_SKIN;
}
}
if ($this->prop['skin'] == 'default') {
$this->prop['skin'] = self::DEFAULT_SKIN;
}
// fix paths
foreach (array('log_dir' => 'logs', 'temp_dir' => 'temp') as $key => $dir) {
foreach (array($this->prop[$key], '../' . $this->prop[$key], RCUBE_INSTALL_PATH . $dir) as $path) {
if ($path && ($realpath = realpath(unslashify($path)))) {
$this->prop[$key] = $realpath;
break;
}
}
}
// 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], RCUBE_CHARSET, 'UTF7-IMAP');
}
// set PHP error logging according to config
$error_log = $this->prop['log_driver'] ?: 'file';
if ($error_log == 'file') {
$error_log = $this->prop['log_dir'] . '/errors';
$error_log .= isset($this->prop['log_file_ext']) ? $this->prop['log_file_ext'] : '.log';
}
if ($error_log && $error_log != 'stdout') {
ini_set('error_log', $error_log);
}
// remove deprecated properties
unset($this->prop['dst_active']);
}
/**
* Load a host-specific config file if configured
* This will merge the host specific configuration with the given one
*/
private function load_host_config()
{
if (empty($this->prop['include_host_config'])) {
return;
}
foreach (array('HTTP_HOST', 'SERVER_NAME', 'SERVER_ADDR') as $key) {
$fname = null;
$name = $_SERVER[$key];
if (!$name) {
continue;
}
if (is_array($this->prop['include_host_config'])) {
$fname = $this->prop['include_host_config'][$name];
}
else {
$fname = preg_replace('/[^a-z0-9\.\-_]/i', '', $name) . '.inc.php';
}
if ($fname && $this->load_from_file($fname)) {
return;
}
}
}
/**
* Read configuration from a file
* and merge with the already stored config values
*
* @param string $file Name of the config file to be loaded
*
* @return booelan True on success, false on failure
*/
public function load_from_file($file)
{
$success = false;
foreach ($this->resolve_paths($file) as $fpath) {
if ($fpath && is_file($fpath) && is_readable($fpath)) {
// use output buffering, we don't need any output here
ob_start();
include($fpath);
ob_end_clean();
if (is_array($config)) {
$this->merge($config);
$success = true;
}
// deprecated name of config variable
if (is_array($rcmail_config)) {
$this->merge($rcmail_config);
$success = true;
}
}
}
return $success;
}
/**
* Helper method to resolve absolute paths to the given config file.
* This also takes the 'env' property into account.
*
* @param string $file Filename or absolute file path
* @param boolean $use_env Return -$env file path if exists
*
* @return array List of candidates in config dir path(s)
*/
public function resolve_paths($file, $use_env = true)
{
$files = array();
$abs_path = rcube_utils::is_absolute_path($file);
foreach ($this->paths as $basepath) {
$realpath = $abs_path ? $file : realpath($basepath . '/' . $file);
- // check if <file>-env.ini exists
- if ($realpath && $use_env && !empty($this->env)) {
- $envfile = preg_replace('/\.(inc.php)$/', '-' . $this->env . '.\\1', $realpath);
+ // check if <file>-<env>.inc.php exists
+ if ($use_env && !empty($this->env)) {
+ $envfile = preg_replace('/\.(inc.php)$/', '-' . $this->env . '.\\1', $file);
+ $envfile = $abs_path ? $envfile : realpath($basepath . '/' . $envfile);
+
if (is_file($envfile)) {
$realpath = $envfile;
}
}
if ($realpath) {
$files[] = $realpath;
// no need to continue the loop if an absolute file path is given
if ($abs_path) {
break;
}
}
}
return $files;
}
/**
* Getter for a specific config parameter
*
* @param string $name Parameter name
* @param mixed $def Default value if not set
*
* @return mixed The requested config value
*/
public function get($name, $def = null)
{
if (isset($this->prop[$name])) {
$result = $this->prop[$name];
}
else {
$result = $def;
}
$result = $this->getenv_default('ROUNDCUBE_' . strtoupper($name), $result);
$rcube = rcube::get_instance();
if ($name == 'timezone') {
if (empty($result) || $result == 'auto') {
$result = $this->client_timezone();
}
}
else if ($name == 'client_mimetypes') {
if (!$result && !$def) {
$result = 'text/plain,text/html,text/xml'
. ',image/jpeg,image/gif,image/png,image/bmp,image/tiff,image/webp'
. ',application/x-javascript,application/pdf,application/x-shockwave-flash';
}
if ($result && is_string($result)) {
$result = explode(',', $result);
}
}
$plugin = $rcube->plugins->exec_hook('config_get', array(
'name' => $name, 'default' => $def, 'result' => $result));
return $plugin['result'];
}
/**
* Setter for a config parameter
*
* @param string $name Parameter name
* @param mixed $value Parameter value
* @param bool $immutable Make the value immutable
*/
public function set($name, $value, $immutable = false)
{
$this->prop[$name] = $value;
if ($immutable) {
$this->immutable[$name] = $value;
}
}
/**
* Override config options with the given values (eg. user prefs)
*
* @param array $prefs Hash array with config props to merge over
*/
public function merge($prefs)
{
$prefs = $this->fix_legacy_props($prefs);
$this->prop = array_merge($this->prop, $prefs, $this->userprefs, $this->immutable);
}
/**
* Merge the given prefs over the current config
* and make sure that they survive further merging.
*
* @param array $prefs Hash array with user prefs
*/
public function set_user_prefs($prefs)
{
$prefs = $this->fix_legacy_props($prefs);
// Honor the dont_override setting for any existing user preferences
$dont_override = $this->get('dont_override');
if (is_array($dont_override) && !empty($dont_override)) {
foreach ($dont_override as $key) {
unset($prefs[$key]);
}
}
if ($prefs['skin'] == 'default') {
$prefs['skin'] = self::DEFAULT_SKIN;
}
$skins_allowed = $this->get('skins_allowed');
if (!empty($prefs['skin']) && !empty($skins_allowed) && !in_array($prefs['skin'], (array) $skins_allowed)) {
unset($prefs['skin']);
}
$this->userprefs = $prefs;
$this->prop = array_merge($this->prop, $prefs);
}
/**
* Getter for all config options
*
* @return array Hash array containing all config properties
*/
public function all()
{
$props = $this->prop;
foreach ($props as $prop_name => $prop_value) {
$props[$prop_name] = $this->getenv_default('ROUNDCUBE_' . strtoupper($prop_name), $prop_value);
}
$rcube = rcube::get_instance();
$plugin = $rcube->plugins->exec_hook('config_get', array(
'name' => '*', 'result' => $props));
return $plugin['result'];
}
/**
* Some options set as immutable that are also listed
* in dont_override should not be stored permanently
* in user preferences. Here's the list of these
*
* @return array List of transient options
*/
public function transient_options()
{
return array_intersect(array_keys($this->immutable), (array) $this->get('dont_override'));
}
/**
* Special getter for user's timezone offset including DST
*
* @return float Timezone offset (in hours)
* @deprecated
*/
public function get_timezone()
{
if ($tz = $this->get('timezone')) {
try {
$tz = new DateTimeZone($tz);
return $tz->getOffset(new DateTime('now')) / 3600;
}
catch (Exception $e) {
}
}
return 0;
}
/**
* Return requested DES crypto key.
*
* @param string $key Crypto key name
*
* @return string Crypto key
*/
public function get_crypto_key($key)
{
// Bomb out if the requested key does not exist
if (!array_key_exists($key, $this->prop) || empty($this->prop[$key])) {
rcube::raise_error(array(
'code' => 500, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Request for unconfigured crypto key \"$key\""
), true, true);
}
return $this->prop[$key];
}
/**
* Return configured crypto method.
*
* @return string Crypto method
*/
public function get_crypto_method()
{
return $this->get('cipher_method') ?: 'DES-EDE3-CBC';
}
/**
* Try to autodetect operating system and find the correct line endings
*
* @return string The appropriate mail header delimiter
* @deprecated Since 1.3 we don't use mail()
*/
public function header_delimiter()
{
// use the configured delimiter for headers
if (!empty($this->prop['mail_header_delimiter'])) {
$delim = $this->prop['mail_header_delimiter'];
if ($delim == "\n" || $delim == "\r\n") {
return $delim;
}
else {
rcube::raise_error(array(
'code' => 500, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Invalid mail_header_delimiter setting"
), true, false);
}
}
$php_os = strtolower(substr(PHP_OS, 0, 3));
if ($php_os == 'win')
return "\r\n";
if ($php_os == 'mac')
return "\r\n";
return "\n";
}
/**
* Returns list of configured PGP key servers
*
* @return array|null List of keyservers' URLs
*/
public function keyservers()
{
$list = (array) $this->prop['keyservers'];
foreach ($list as $idx => $host) {
if (!preg_match('|^[a-z]://|', $host)) {
$host = "https://$host";
}
$list[$idx] = slashify($host);
}
return !empty($list) ? $list : null;
}
/**
* Return the mail domain configured for the given host
*
* @param string $host IMAP host
* @param boolean $encode If true, domain name will be converted to IDN ASCII
*
* @return string Resolved SMTP host
*/
public function mail_domain($host, $encode=true)
{
$domain = $host;
if (is_array($this->prop['mail_domain'])) {
if (isset($this->prop['mail_domain'][$host])) {
$domain = $this->prop['mail_domain'][$host];
}
}
else if (!empty($this->prop['mail_domain'])) {
$domain = rcube_utils::parse_host($this->prop['mail_domain']);
}
if ($encode) {
$domain = rcube_utils::idn_to_ascii($domain);
}
return $domain;
}
/**
* Getter for error state
*
* @return mixed Error message on error, False if no errors
*/
public function get_error()
{
return empty($this->errors) ? false : implode("\n", $this->errors);
}
/**
* Internal getter for client's (browser) timezone identifier
*/
private function client_timezone()
{
if ($this->client_tz) {
return $this->client_tz;
}
// @TODO: remove this legacy timezone handling in the future
$props = $this->fix_legacy_props(array('timezone' => $_SESSION['timezone']));
if (!empty($props['timezone'])) {
// Prevent from using deprecated timezone names
$props['timezone'] = $this->resolve_timezone_alias($props['timezone']);
try {
$tz = new DateTimeZone($props['timezone']);
return $this->client_tz = $tz->getName();
}
catch (Exception $e) { /* gracefully ignore */ }
}
// fallback to server's timezone
return date_default_timezone_get();
}
/**
* Convert legacy options into new ones
*
* @param array $props Hash array with config props
*
* @return array Converted config props
*/
private function fix_legacy_props($props)
{
foreach ($this->legacy_props as $new => $old) {
if (isset($props[$old])) {
if (!isset($props[$new])) {
$props[$new] = $props[$old];
}
unset($props[$old]);
}
}
// convert deprecated numeric timezone value
if (isset($props['timezone']) && is_numeric($props['timezone'])) {
if ($tz = self::timezone_name_from_abbr($props['timezone'])) {
$props['timezone'] = $tz;
}
else {
unset($props['timezone']);
}
}
// translate old `preview_pane` settings to `layout`
if (isset($props['preview_pane']) && !isset($props['layout'])) {
$props['layout'] = $props['preview_pane'] ? 'desktop' : 'list';
unset($props['preview_pane']);
}
// translate old `display_version` settings to `display_product_info`
if (isset($props['display_version']) && !isset($props['display_product_info'])) {
$props['display_product_info'] = $props['display_version'] ? 2 : 1;
unset($props['display_version']);
}
return $props;
}
/**
* timezone_name_from_abbr() replacement. Converts timezone offset
* into timezone name abbreviation.
*
* @param float $offset Timezone offset (in hours)
*
* @return string Timezone abbreviation
*/
static public function timezone_name_from_abbr($offset)
{
// List of timezones here is not complete - https://bugs.php.net/bug.php?id=44780
if ($tz = timezone_name_from_abbr('', $offset * 3600, 0)) {
return $tz;
}
// try with more complete list (#1489261)
$timezones = array(
'-660' => "Pacific/Apia",
'-600' => "Pacific/Honolulu",
'-570' => "Pacific/Marquesas",
'-540' => "America/Anchorage",
'-480' => "America/Los_Angeles",
'-420' => "America/Denver",
'-360' => "America/Chicago",
'-300' => "America/New_York",
'-270' => "America/Caracas",
'-240' => "America/Halifax",
'-210' => "Canada/Newfoundland",
'-180' => "America/Sao_Paulo",
'-60' => "Atlantic/Azores",
'0' => "Europe/London",
'60' => "Europe/Paris",
'120' => "Europe/Helsinki",
'180' => "Europe/Moscow",
'210' => "Asia/Tehran",
'240' => "Asia/Dubai",
'270' => "Asia/Kabul",
'300' => "Asia/Karachi",
'330' => "Asia/Kolkata",
'345' => "Asia/Katmandu",
'360' => "Asia/Yekaterinburg",
'390' => "Asia/Rangoon",
'420' => "Asia/Krasnoyarsk",
'480' => "Asia/Shanghai",
'525' => "Australia/Eucla",
'540' => "Asia/Tokyo",
'570' => "Australia/Adelaide",
'600' => "Australia/Melbourne",
'630' => "Australia/Lord_Howe",
'660' => "Asia/Vladivostok",
'690' => "Pacific/Norfolk",
'720' => "Pacific/Auckland",
'765' => "Pacific/Chatham",
'780' => "Pacific/Enderbury",
'840' => "Pacific/Kiritimati",
);
return $timezones[(string) intval($offset * 60)];
}
/**
* Replace deprecated timezone name with a valid one.
*
* @param string $tzname Timezone name
*
* @return string Timezone name
*/
static public function resolve_timezone_alias($tzname)
{
// http://www.php.net/manual/en/timezones.others.php
// https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
$deprecated_timezones = array(
'Australia/ACT' => 'Australia/Sydney',
'Australia/LHI' => 'Australia/Lord_Howe',
'Australia/North' => 'Australia/Darwin',
'Australia/NSW' => 'Australia/Sydney',
'Australia/Queensland' => 'Australia/Brisbane',
'Australia/South' => 'Australia/Adelaide',
'Australia/Adelaide' => 'Australia/Hobart',
'Australia/Tasmania' => 'Australia/Hobart',
'Australia/Victoria' => 'Australia/Melbourne',
'Australia/West' => 'Australia/Perth',
'Brazil/Acre' => 'America/Rio_Branco',
'Brazil/DeNoronha' => 'America/Noronha',
'Brazil/East' => 'America/Sao_Paulo',
'Brazil/West' => 'America/Manaus',
'Canada/Atlantic' => 'America/Halifax',
'Canada/Central' => 'America/Winnipeg',
'Canada/Eastern' => 'America/Toronto',
'Canada/Mountain' => 'America/Edmonton',
'Canada/Newfoundland' => 'America/St_Johns',
'Canada/Pacific' => 'America/Vancouver',
'Canada/Saskatchewan' => 'America/Regina',
'Canada/Yukon' => 'America/Whitehorse',
'CET' => 'Europe/Berlin',
'Chile/Continental' => 'America/Santiago',
'Chile/EasterIsland' => 'Pacific/Easter',
'CST6CDT' => 'America/Chicago',
'Cuba' => ' America/Havana',
'EET' => 'Europe/Berlin',
'Egypt' => 'Africa/Cairo',
'Eire' => 'Europe/Dublin',
'EST' => 'America/New_York',
'EST5EDT' => 'America/New_York',
'Factory' => 'UTC', // ?
'GB' => 'Europe/London',
'GB-Eire' => 'Europe/London',
'GMT' => 'UTC',
'GMT+0' => 'UTC',
'GMT-0' => 'UTC',
'GMT0' => 'UTC',
'Greenwich' => 'UTC',
'Hongkong' => 'Asia/Hong_Kong',
'HST' => 'Pacific/Honolulu',
'Iceland' => 'Atlantic/Reykjavik',
'Iran' => 'Asia/Tehran',
'Israel' => 'Asia/Jerusalem',
'Jamaica' => 'America/Jamaica',
'Japan' => 'Asia/Tokyo',
'Kwajalein' => 'Pacific/Kwajalein',
'Libya' => 'Africa/Tripoli',
'MET' => 'Europe/Berlin',
'Mexico/BajaNorte' => 'America/Tijuana',
'Mexico/BajaSur' => 'America/Mazatlan',
'Mexico/General' => 'America/Mexico_City',
'MST' => 'America/Denver',
'MST7MDT' => 'America/Denver',
'Navajo' => 'America/Denver',
'NZ' => 'Pacific/Auckland',
'NZ-CHAT' => 'Pacific/Chatham',
'Poland' => 'Europe/Warsaw',
'Portugal' => 'Europe/Lisbon',
'PRC' => 'Asia/Shanghai',
'PST8PDT' => 'America/Los_Angeles',
'ROC' => 'Asia/Taipei',
'ROK' => 'Asia/Seoul',
'Singapore' => 'Asia/Singapore',
'Turkey' => 'Europe/Istanbul',
'UCT' => 'UTC',
'Universal' => 'UTC',
'US/Alaska' => 'America/Anchorage',
'US/Aleutian' => 'America/Adak',
'US/Arizona' => 'America/Phoenix',
'US/Central' => 'America/Chicago',
'US/East-Indiana' => 'America/Indiana/Indianapolis',
'US/Eastern' => 'America/New_York',
'US/Hawaii' => 'Pacific/Honolulu',
'US/Indiana-Starke' => 'America/Indiana/Knox',
'US/Michigan' => 'America/Detroit',
'US/Mountain' => 'America/Denver',
'US/Pacific' => 'America/Los_Angeles',
'US/Pacific-New' => 'America/Los_Angeles',
'US/Samoa' => 'Pacific/Pago_Pago',
'W-SU' => 'Europe/Moscow',
'WET' => 'Europe/Berlin',
'Z' => 'UTC',
'Zulu' => 'UTC',
// Some of these Etc/X zones are not deprecated, but still problematic
'Etc/GMT' => 'UTC',
'Etc/GMT+0' => 'UTC',
'Etc/GMT+1' => 'Atlantic/Azores',
'Etc/GMT+10' => 'Pacific/Honolulu',
'Etc/GMT+11' => 'Pacific/Midway',
'Etc/GMT+12' => 'Pacific/Auckland',
'Etc/GMT+2' => 'America/Noronha',
'Etc/GMT+3' => 'America/Argentina/Buenos_Aires',
'Etc/GMT+4' => 'America/Manaus',
'Etc/GMT+5' => 'America/New_York',
'Etc/GMT+6' => 'America/Chicago',
'Etc/GMT+7' => 'America/Denver',
'Etc/GMT+8' => 'America/Los_Angeles',
'Etc/GMT+9' => 'America/Anchorage',
'Etc/GMT-0' => 'UTC',
'Etc/GMT-1' => 'Europe/Berlin',
'Etc/GMT-10' => 'Australia/Sydney',
'Etc/GMT-11' => 'Pacific/Norfolk',
'Etc/GMT-12' => 'Pacific/Auckland',
'Etc/GMT-13' => 'Pacific/Apia',
'Etc/GMT-14' => 'Pacific/Kiritimati',
'Etc/GMT-2' => 'Africa/Cairo',
'Etc/GMT-3' => 'Europe/Moscow',
'Etc/GMT-4' => 'Europe/Samara',
'Etc/GMT-5' => 'Asia/Yekaterinburg',
'Etc/GMT-6' => 'Asia/Almaty',
'Etc/GMT-7' => 'Asia/Bangkok',
'Etc/GMT-8' => 'Asia/Hong_Kong',
'Etc/GMT-9' => 'Asia/Tokyo',
'Etc/GMT0' => 'UTC',
'Etc/Greenwich' => 'UTC',
'Etc/UCT' => 'UTC',
'Etc/Universal' => 'UTC',
'Etc/UTC' => 'UTC',
'Etc/Zulu' => 'UTC',
);
return $deprecated_timezones[$tzname] ?: $tzname;
}
}
diff --git a/tests/Browser/bootstrap.php b/tests/Browser/bootstrap.php
index 658ff84e3..f8803c420 100644
--- a/tests/Browser/bootstrap.php
+++ b/tests/Browser/bootstrap.php
@@ -1,180 +1,174 @@
<?php
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
| |
| Copyright (C) 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: |
| Environment initialization script for functional tests |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
| Author: Aleksander Machniak <alec@alec.pl> |
+-----------------------------------------------------------------------+
*/
if (php_sapi_name() != 'cli')
die("Not in shell mode (php-cli)");
if (!defined('INSTALL_PATH')) define('INSTALL_PATH', realpath(__DIR__ . '/../../') . '/' );
require_once(INSTALL_PATH . 'program/include/iniset.php');
$rcmail = rcmail::get_instance(0, 'test');
define('TESTS_DIR', realpath(__DIR__) . '/');
define('TESTS_USER', $rcmail->config->get('tests_username'));
define('TESTS_PASS', $rcmail->config->get('tests_password'));
require_once(__DIR__ . '/DuskTestCase.php');
/**
* Utilities for test environment setup
*/
class bootstrap
{
static $imap_ready = null;
/**
* Wipe and re-initialize database
*/
public static function init_db()
{
$rcmail = rcmail::get_instance();
$dsn = rcube_db::parse_dsn($rcmail->config->get('db_dsnw'));
-passthru('ls -l ' . INSTALL_PATH . 'config');
-passthru('cat ' . INSTALL_PATH . 'config/config-test.inc.php');
-passthru('ls -l /tmp');
-print_r($dsn);
-die;
-
if ($dsn['phptype'] == 'mysql' || $dsn['phptype'] == 'mysqli') {
// drop all existing tables first
$db = $rcmail->get_dbh();
$db->query("SET FOREIGN_KEY_CHECKS=0");
$sql_res = $db->query("SHOW TABLES");
while ($sql_arr = $db->fetch_array($sql_res)) {
$table = reset($sql_arr);
$db->query("DROP TABLE $table");
}
// init database with schema
system(sprintf('cat %s %s | mysql -h %s -u %s --password=%s %s',
realpath(INSTALL_PATH . '/SQL/mysql.initial.sql'),
realpath(TESTS_DIR . 'data/mysql.sql'),
escapeshellarg($dsn['hostspec']),
escapeshellarg($dsn['username']),
escapeshellarg($dsn['password']),
escapeshellarg($dsn['database'])
));
}
else if ($dsn['phptype'] == 'sqlite') {
// delete database file -- will be re-initialized on first access
system(sprintf('rm -f %s', escapeshellarg($dsn['database'])));
}
}
/**
* Wipe the configured IMAP account and fill with test data
*/
public static function init_imap()
{
if (!TESTS_USER) {
return false;
}
else if (self::$imap_ready !== null) {
return self::$imap_ready;
}
self::connect_imap(TESTS_USER, TESTS_PASS);
self::purge_mailbox('INBOX');
self::ensure_mailbox('Archive', true);
return self::$imap_ready;
}
/**
* Authenticate to IMAP with the given credentials
*/
public static function connect_imap($username, $password, $host = null)
{
$rcmail = rcmail::get_instance();
$imap = $rcmail->get_storage();
if ($imap->is_connected()) {
$imap->close();
self::$imap_ready = false;
}
$imap_host = $host ?: $rcmail->config->get('default_host');
$a_host = parse_url($imap_host);
if ($a_host['host']) {
$imap_host = $a_host['host'];
$imap_ssl = isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl','imaps','tls'));
$imap_port = isset($a_host['port']) ? $a_host['port'] : ($imap_ssl ? 993 : 143);
}
else {
$imap_port = 143;
$imap_ssl = false;
}
if (!$imap->connect($imap_host, $username, $password, $imap_port, $imap_ssl)) {
die("IMAP error: unable to authenticate with user " . TESTS_USER);
}
self::$imap_ready = true;
}
/**
* Import the given file into IMAP
*/
public static function import_message($filename, $mailbox = 'INBOX')
{
if (!self::init_imap()) {
die(__METHOD__ . ': IMAP connection unavailable');
}
$imap = rcmail::get_instance()->get_storage();
$imap->save_message($mailbox, file_get_contents($filename));
}
/**
* Delete all messages from the given mailbox
*/
public static function purge_mailbox($mailbox)
{
if (!self::init_imap()) {
die(__METHOD__ . ': IMAP connection unavailable');
}
$imap = rcmail::get_instance()->get_storage();
$imap->delete_message('*', $mailbox);
}
/**
* Make sure the given mailbox exists in IMAP
*/
public static function ensure_mailbox($mailbox, $empty = false)
{
if (!self::init_imap()) {
die(__METHOD__ . ': IMAP connection unavailable');
}
$imap = rcmail::get_instance()->get_storage();
$folders = $imap->list_folders();
if (!in_array($mailbox, $folders)) {
$imap->create_folder($mailbox, true);
}
else if ($empty) {
$imap->delete_message('*', $mailbox);
}
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Mar 19, 8:51 AM (18 h, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
458521
Default Alt Text
(38 KB)
Attached To
Mode
R3 roundcubemail
Attached
Detach File
Event Timeline
Log In to Comment