Mercurial > hg > rc2
comparison program/lib/Roundcube/bootstrap.php @ 0:4681f974d28b
vanilla 1.3.3 distro, I hope
| author | Charlie Root |
|---|---|
| date | Thu, 04 Jan 2018 15:52:31 -0500 |
| parents | |
| children | 73124dd49283 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:4681f974d28b |
|---|---|
| 1 <?php | |
| 2 | |
| 3 /** | |
| 4 +-----------------------------------------------------------------------+ | |
| 5 | This file is part of the Roundcube PHP suite | | |
| 6 | Copyright (C) 2005-2017, The Roundcube Dev Team | | |
| 7 | | | |
| 8 | Licensed under the GNU General Public License version 3 or | | |
| 9 | any later version with exceptions for skins & plugins. | | |
| 10 | See the README file for a full license statement. | | |
| 11 | | | |
| 12 | CONTENTS: | | |
| 13 | Roundcube Framework Initialization | | |
| 14 +-----------------------------------------------------------------------+ | |
| 15 | Author: Thomas Bruederli <roundcube@gmail.com> | | |
| 16 | Author: Aleksander Machniak <alec@alec.pl> | | |
| 17 +-----------------------------------------------------------------------+ | |
| 18 */ | |
| 19 | |
| 20 /** | |
| 21 * Roundcube Framework Initialization | |
| 22 * | |
| 23 * @package Framework | |
| 24 * @subpackage Core | |
| 25 */ | |
| 26 | |
| 27 $config = array( | |
| 28 'error_reporting' => E_ALL & ~E_NOTICE & ~E_STRICT, | |
| 29 // Some users are not using Installer, so we'll check some | |
| 30 // critical PHP settings here. Only these, which doesn't provide | |
| 31 // an error/warning in the logs later. See (#1486307). | |
| 32 'mbstring.func_overload' => 0, | |
| 33 ); | |
| 34 | |
| 35 // check these additional ini settings if not called via CLI | |
| 36 if (php_sapi_name() != 'cli') { | |
| 37 $config += array( | |
| 38 'suhosin.session.encrypt' => false, | |
| 39 'file_uploads' => true, | |
| 40 ); | |
| 41 } | |
| 42 | |
| 43 foreach ($config as $optname => $optval) { | |
| 44 $ini_optval = filter_var(ini_get($optname), is_bool($optval) ? FILTER_VALIDATE_BOOLEAN : FILTER_VALIDATE_INT); | |
| 45 if ($optval != $ini_optval && @ini_set($optname, $optval) === false) { | |
| 46 $optval = !is_bool($optval) ? $optval : ($optval ? 'On' : 'Off'); | |
| 47 $error = "ERROR: Wrong '$optname' option value and it wasn't possible to set it to required value ($optval).\n" | |
| 48 . "Check your PHP configuration (including php_admin_flag)."; | |
| 49 | |
| 50 if (defined('STDERR')) fwrite(STDERR, $error); else echo $error; | |
| 51 exit(1); | |
| 52 } | |
| 53 } | |
| 54 | |
| 55 // framework constants | |
| 56 define('RCUBE_VERSION', '1.3.3'); | |
| 57 define('RCUBE_CHARSET', 'UTF-8'); | |
| 58 | |
| 59 if (!defined('RCUBE_LIB_DIR')) { | |
| 60 define('RCUBE_LIB_DIR', __DIR__ . '/'); | |
| 61 } | |
| 62 | |
| 63 if (!defined('RCUBE_INSTALL_PATH')) { | |
| 64 define('RCUBE_INSTALL_PATH', RCUBE_LIB_DIR); | |
| 65 } | |
| 66 | |
| 67 if (!defined('RCUBE_CONFIG_DIR')) { | |
| 68 define('RCUBE_CONFIG_DIR', RCUBE_INSTALL_PATH . 'config/'); | |
| 69 } | |
| 70 | |
| 71 if (!defined('RCUBE_PLUGINS_DIR')) { | |
| 72 define('RCUBE_PLUGINS_DIR', RCUBE_INSTALL_PATH . 'plugins/'); | |
| 73 } | |
| 74 | |
| 75 if (!defined('RCUBE_LOCALIZATION_DIR')) { | |
| 76 define('RCUBE_LOCALIZATION_DIR', RCUBE_INSTALL_PATH . 'localization/'); | |
| 77 } | |
| 78 | |
| 79 // set internal encoding for mbstring extension | |
| 80 if (function_exists('mb_internal_encoding')) { | |
| 81 mb_internal_encoding(RCUBE_CHARSET); | |
| 82 } | |
| 83 if (function_exists('mb_regex_encoding')) { | |
| 84 mb_regex_encoding(RCUBE_CHARSET); | |
| 85 } | |
| 86 | |
| 87 // make sure the Roundcube lib directory is in the include_path | |
| 88 $rcube_path = realpath(RCUBE_LIB_DIR . '..'); | |
| 89 $sep = PATH_SEPARATOR; | |
| 90 $regexp = "!(^|$sep)" . preg_quote($rcube_path, '!') . "($sep|\$)!"; | |
| 91 $path = ini_get('include_path'); | |
| 92 | |
| 93 if (!preg_match($regexp, $path)) { | |
| 94 set_include_path($path . PATH_SEPARATOR . $rcube_path); | |
| 95 } | |
| 96 | |
| 97 // Register autoloader | |
| 98 spl_autoload_register('rcube_autoload'); | |
| 99 | |
| 100 // set PEAR error handling (will also load the PEAR main class) | |
| 101 PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'rcube_pear_error'); | |
| 102 | |
| 103 | |
| 104 /** | |
| 105 * Similar function as in_array() but case-insensitive with multibyte support. | |
| 106 * | |
| 107 * @param string $needle Needle value | |
| 108 * @param array $heystack Array to search in | |
| 109 * | |
| 110 * @return boolean True if found, False if not | |
| 111 */ | |
| 112 function in_array_nocase($needle, $haystack) | |
| 113 { | |
| 114 // use much faster method for ascii | |
| 115 if (is_ascii($needle)) { | |
| 116 foreach ((array) $haystack as $value) { | |
| 117 if (strcasecmp($value, $needle) === 0) { | |
| 118 return true; | |
| 119 } | |
| 120 } | |
| 121 } | |
| 122 else { | |
| 123 $needle = mb_strtolower($needle); | |
| 124 foreach ((array) $haystack as $value) { | |
| 125 if ($needle === mb_strtolower($value)) { | |
| 126 return true; | |
| 127 } | |
| 128 } | |
| 129 } | |
| 130 | |
| 131 return false; | |
| 132 } | |
| 133 | |
| 134 /** | |
| 135 * Parse a human readable string for a number of bytes. | |
| 136 * | |
| 137 * @param string $str Input string | |
| 138 * | |
| 139 * @return float Number of bytes | |
| 140 */ | |
| 141 function parse_bytes($str) | |
| 142 { | |
| 143 if (is_numeric($str)) { | |
| 144 return floatval($str); | |
| 145 } | |
| 146 | |
| 147 if (preg_match('/([0-9\.]+)\s*([a-z]*)/i', $str, $regs)) { | |
| 148 $bytes = floatval($regs[1]); | |
| 149 switch (strtolower($regs[2])) { | |
| 150 case 'g': | |
| 151 case 'gb': | |
| 152 $bytes *= 1073741824; | |
| 153 break; | |
| 154 case 'm': | |
| 155 case 'mb': | |
| 156 $bytes *= 1048576; | |
| 157 break; | |
| 158 case 'k': | |
| 159 case 'kb': | |
| 160 $bytes *= 1024; | |
| 161 break; | |
| 162 } | |
| 163 } | |
| 164 | |
| 165 return floatval($bytes); | |
| 166 } | |
| 167 | |
| 168 /** | |
| 169 * Make sure the string ends with a slash | |
| 170 */ | |
| 171 function slashify($str) | |
| 172 { | |
| 173 return unslashify($str).'/'; | |
| 174 } | |
| 175 | |
| 176 /** | |
| 177 * Remove slashes at the end of the string | |
| 178 */ | |
| 179 function unslashify($str) | |
| 180 { | |
| 181 return preg_replace('/\/+$/', '', $str); | |
| 182 } | |
| 183 | |
| 184 /** | |
| 185 * Returns number of seconds for a specified offset string. | |
| 186 * | |
| 187 * @param string $str String representation of the offset (e.g. 20min, 5h, 2days, 1week) | |
| 188 * | |
| 189 * @return int Number of seconds | |
| 190 */ | |
| 191 function get_offset_sec($str) | |
| 192 { | |
| 193 if (preg_match('/^([0-9]+)\s*([smhdw])/i', $str, $regs)) { | |
| 194 $amount = (int) $regs[1]; | |
| 195 $unit = strtolower($regs[2]); | |
| 196 } | |
| 197 else { | |
| 198 $amount = (int) $str; | |
| 199 $unit = 's'; | |
| 200 } | |
| 201 | |
| 202 switch ($unit) { | |
| 203 case 'w': | |
| 204 $amount *= 7; | |
| 205 case 'd': | |
| 206 $amount *= 24; | |
| 207 case 'h': | |
| 208 $amount *= 60; | |
| 209 case 'm': | |
| 210 $amount *= 60; | |
| 211 } | |
| 212 | |
| 213 return $amount; | |
| 214 } | |
| 215 | |
| 216 /** | |
| 217 * Create a unix timestamp with a specified offset from now. | |
| 218 * | |
| 219 * @param string $offset_str String representation of the offset (e.g. 20min, 5h, 2days) | |
| 220 * @param int $factor Factor to multiply with the offset | |
| 221 * | |
| 222 * @return int Unix timestamp | |
| 223 */ | |
| 224 function get_offset_time($offset_str, $factor = 1) | |
| 225 { | |
| 226 return time() + get_offset_sec($offset_str) * $factor; | |
| 227 } | |
| 228 | |
| 229 /** | |
| 230 * Truncate string if it is longer than the allowed length. | |
| 231 * Replace the middle or the ending part of a string with a placeholder. | |
| 232 * | |
| 233 * @param string $str Input string | |
| 234 * @param int $maxlength Max. length | |
| 235 * @param string $placeholder Replace removed chars with this | |
| 236 * @param bool $ending Set to True if string should be truncated from the end | |
| 237 * | |
| 238 * @return string Abbreviated string | |
| 239 */ | |
| 240 function abbreviate_string($str, $maxlength, $placeholder = '...', $ending = false) | |
| 241 { | |
| 242 $length = mb_strlen($str); | |
| 243 | |
| 244 if ($length > $maxlength) { | |
| 245 if ($ending) { | |
| 246 return mb_substr($str, 0, $maxlength) . $placeholder; | |
| 247 } | |
| 248 | |
| 249 $placeholder_length = mb_strlen($placeholder); | |
| 250 $first_part_length = floor(($maxlength - $placeholder_length)/2); | |
| 251 $second_starting_location = $length - $maxlength + $first_part_length + $placeholder_length; | |
| 252 | |
| 253 $prefix = mb_substr($str, 0, $first_part_length); | |
| 254 $suffix = mb_substr($str, $second_starting_location); | |
| 255 $str = $prefix . $placeholder . $suffix; | |
| 256 } | |
| 257 | |
| 258 return $str; | |
| 259 } | |
| 260 | |
| 261 /** | |
| 262 * Get all keys from array (recursive). | |
| 263 * | |
| 264 * @param array $array Input array | |
| 265 * | |
| 266 * @return array List of array keys | |
| 267 */ | |
| 268 function array_keys_recursive($array) | |
| 269 { | |
| 270 $keys = array(); | |
| 271 | |
| 272 if (!empty($array) && is_array($array)) { | |
| 273 foreach ($array as $key => $child) { | |
| 274 $keys[] = $key; | |
| 275 foreach (array_keys_recursive($child) as $val) { | |
| 276 $keys[] = $val; | |
| 277 } | |
| 278 } | |
| 279 } | |
| 280 | |
| 281 return $keys; | |
| 282 } | |
| 283 | |
| 284 /** | |
| 285 * Remove all non-ascii and non-word chars except ., -, _ | |
| 286 */ | |
| 287 function asciiwords($str, $css_id = false, $replace_with = '') | |
| 288 { | |
| 289 $allowed = 'a-z0-9\_\-' . (!$css_id ? '\.' : ''); | |
| 290 return preg_replace("/[^$allowed]/i", $replace_with, $str); | |
| 291 } | |
| 292 | |
| 293 /** | |
| 294 * Check if a string contains only ascii characters | |
| 295 * | |
| 296 * @param string $str String to check | |
| 297 * @param bool $control_chars Includes control characters | |
| 298 * | |
| 299 * @return bool | |
| 300 */ | |
| 301 function is_ascii($str, $control_chars = true) | |
| 302 { | |
| 303 $regexp = $control_chars ? '/[^\x00-\x7F]/' : '/[^\x20-\x7E]/'; | |
| 304 return preg_match($regexp, $str) ? false : true; | |
| 305 } | |
| 306 | |
| 307 /** | |
| 308 * Compose a valid representation of name and e-mail address | |
| 309 * | |
| 310 * @param string $email E-mail address | |
| 311 * @param string $name Person name | |
| 312 * | |
| 313 * @return string Formatted string | |
| 314 */ | |
| 315 function format_email_recipient($email, $name = '') | |
| 316 { | |
| 317 $email = trim($email); | |
| 318 | |
| 319 if ($name && $name != $email) { | |
| 320 // Special chars as defined by RFC 822 need to in quoted string (or escaped). | |
| 321 if (preg_match('/[\(\)\<\>\\\.\[\]@,;:"]/', $name)) { | |
| 322 $name = '"'.addcslashes($name, '"').'"'; | |
| 323 } | |
| 324 | |
| 325 return "$name <$email>"; | |
| 326 } | |
| 327 | |
| 328 return $email; | |
| 329 } | |
| 330 | |
| 331 /** | |
| 332 * Format e-mail address | |
| 333 * | |
| 334 * @param string $email E-mail address | |
| 335 * | |
| 336 * @return string Formatted e-mail address | |
| 337 */ | |
| 338 function format_email($email) | |
| 339 { | |
| 340 $email = trim($email); | |
| 341 $parts = explode('@', $email); | |
| 342 $count = count($parts); | |
| 343 | |
| 344 if ($count > 1) { | |
| 345 $parts[$count-1] = mb_strtolower($parts[$count-1]); | |
| 346 | |
| 347 $email = implode('@', $parts); | |
| 348 } | |
| 349 | |
| 350 return $email; | |
| 351 } | |
| 352 | |
| 353 /** | |
| 354 * Fix version number so it can be used correctly in version_compare() | |
| 355 * | |
| 356 * @param string $version Version number string | |
| 357 * | |
| 358 * @param return Version number string | |
| 359 */ | |
| 360 function version_parse($version) | |
| 361 { | |
| 362 return str_replace( | |
| 363 array('-stable', '-git'), | |
| 364 array('.0', '.99'), | |
| 365 $version | |
| 366 ); | |
| 367 } | |
| 368 | |
| 369 /** | |
| 370 * intl replacement functions | |
| 371 */ | |
| 372 | |
| 373 if (!function_exists('idn_to_utf8')) | |
| 374 { | |
| 375 function idn_to_utf8($domain) | |
| 376 { | |
| 377 static $idn, $loaded; | |
| 378 | |
| 379 if (!$loaded) { | |
| 380 $idn = new Net_IDNA2(); | |
| 381 $loaded = true; | |
| 382 } | |
| 383 | |
| 384 if ($idn && $domain && preg_match('/(^|\.)xn--/i', $domain)) { | |
| 385 try { | |
| 386 $domain = $idn->decode($domain); | |
| 387 } | |
| 388 catch (Exception $e) { | |
| 389 } | |
| 390 } | |
| 391 | |
| 392 return $domain; | |
| 393 } | |
| 394 } | |
| 395 | |
| 396 if (!function_exists('idn_to_ascii')) | |
| 397 { | |
| 398 function idn_to_ascii($domain) | |
| 399 { | |
| 400 static $idn, $loaded; | |
| 401 | |
| 402 if (!$loaded) { | |
| 403 $idn = new Net_IDNA2(); | |
| 404 $loaded = true; | |
| 405 } | |
| 406 | |
| 407 if ($idn && $domain && preg_match('/[^\x20-\x7E]/', $domain)) { | |
| 408 try { | |
| 409 $domain = $idn->encode($domain); | |
| 410 } | |
| 411 catch (Exception $e) { | |
| 412 } | |
| 413 } | |
| 414 | |
| 415 return $domain; | |
| 416 } | |
| 417 } | |
| 418 | |
| 419 /** | |
| 420 * Use PHP5 autoload for dynamic class loading | |
| 421 * | |
| 422 * @todo Make Zend, PEAR etc play with this | |
| 423 * @todo Make our classes conform to a more straight forward CS. | |
| 424 */ | |
| 425 function rcube_autoload($classname) | |
| 426 { | |
| 427 if (strpos($classname, 'rcube') === 0) { | |
| 428 $classname = 'Roundcube/' . $classname; | |
| 429 } | |
| 430 else if (strpos($classname, 'html_') === 0 || $classname === 'html') { | |
| 431 $classname = 'Roundcube/html'; | |
| 432 } | |
| 433 else if (strpos($classname, 'Mail_') === 0) { | |
| 434 $classname = 'Mail/' . substr($classname, 5); | |
| 435 } | |
| 436 else if (strpos($classname, 'Net_') === 0) { | |
| 437 $classname = 'Net/' . substr($classname, 4); | |
| 438 } | |
| 439 else if (strpos($classname, 'Auth_') === 0) { | |
| 440 $classname = 'Auth/' . substr($classname, 5); | |
| 441 } | |
| 442 | |
| 443 // Translate PHP namespaces into directories, | |
| 444 // i.e. use \Sabre\VObject; $vcf = VObject\Reader::read(...) | |
| 445 // -> Sabre/VObject/Reader.php | |
| 446 $classname = str_replace('\\', '/', $classname); | |
| 447 | |
| 448 if ($fp = @fopen("$classname.php", 'r', true)) { | |
| 449 fclose($fp); | |
| 450 include_once "$classname.php"; | |
| 451 return true; | |
| 452 } | |
| 453 | |
| 454 return false; | |
| 455 } | |
| 456 | |
| 457 /** | |
| 458 * Local callback function for PEAR errors | |
| 459 */ | |
| 460 function rcube_pear_error($err) | |
| 461 { | |
| 462 $msg = sprintf("ERROR: %s (%s)", $err->getMessage(), $err->getCode()); | |
| 463 | |
| 464 if ($info = $err->getUserinfo()) { | |
| 465 $msg .= ': ' . $info; | |
| 466 } | |
| 467 | |
| 468 error_log($msg, 0); | |
| 469 } |
