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 |
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 } |