blob: fd248e9b9d0c2776860ca925bc5c4181a6647b5f [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Phil Sturgeon07c1ac82012-03-09 17:03:37 +00005 * An open source application development framework for PHP 5.2.4 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Andrey Andreev188abaf2012-01-07 19:09:42 +02008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Andrey Andreev188abaf2012-01-07 19:09:42 +020010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * This source file is subject to the Open Software License (OSL 3.0) that is
12 * bundled with this package in the files license.txt / license.rst. It is
13 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
darwinel871754a2014-02-11 17:34:57 +010021 * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
Derek Jonesf4a4bd82011-10-20 12:18:42 -050022 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.0
25 * @filesource
26 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020027defined('BASEPATH') OR exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +000028
Derek Allard2067d1a2008-11-13 22:59:24 +000029/**
Derek Jonesdc8e9ea2010-03-02 13:17:19 -060030 * Common Functions
31 *
32 * Loads the base classes and executes the request.
33 *
34 * @package CodeIgniter
Andrey Andreev92ebfb62012-05-17 12:49:24 +030035 * @subpackage CodeIgniter
Derek Jonesdc8e9ea2010-03-02 13:17:19 -060036 * @category Common Functions
Derek Jonesf4a4bd82011-10-20 12:18:42 -050037 * @author EllisLab Dev Team
Derek Jonesdc8e9ea2010-03-02 13:17:19 -060038 * @link http://codeigniter.com/user_guide/
39 */
40
41// ------------------------------------------------------------------------
42
Dan Horrigan3ef65bd2011-05-08 11:06:44 -040043if ( ! function_exists('is_php'))
44{
Timothy Warrenad475052012-04-19 13:21:06 -040045 /**
46 * Determines if the current version of PHP is greater then the supplied value
47 *
Timothy Warrenad475052012-04-19 13:21:06 -040048 * @param string
49 * @return bool TRUE if the current version is $version or higher
50 */
vlakoff629d3752014-04-05 09:52:01 +020051 function is_php($version)
Derek Jones086ee5a2009-07-28 14:42:12 +000052 {
Derek Jonesdc8e9ea2010-03-02 13:17:19 -060053 static $_is_php;
Andrey Andreevb7b43962012-02-27 22:45:48 +020054 $version = (string) $version;
Barry Mienydd671972010-10-04 16:33:58 +020055
Derek Jonesdc8e9ea2010-03-02 13:17:19 -060056 if ( ! isset($_is_php[$version]))
57 {
vlakoff629d3752014-04-05 09:52:01 +020058 $_is_php[$version] = version_compare(PHP_VERSION, $version, '>=');
Derek Jonesdc8e9ea2010-03-02 13:17:19 -060059 }
Derek Jones086ee5a2009-07-28 14:42:12 +000060
Derek Jonesdc8e9ea2010-03-02 13:17:19 -060061 return $_is_php[$version];
62 }
Dan Horrigan3ef65bd2011-05-08 11:06:44 -040063}
Derek Jones5bcfd2e2009-07-28 14:42:42 +000064
Derek Jones086ee5a2009-07-28 14:42:12 +000065// ------------------------------------------------------------------------
66
Dan Horrigan3ef65bd2011-05-08 11:06:44 -040067if ( ! function_exists('is_really_writable'))
68{
Timothy Warrenad475052012-04-19 13:21:06 -040069 /**
70 * Tests for file writability
71 *
72 * is_writable() returns TRUE on Windows servers when you really can't write to
73 * the file, based on the read-only attribute. is_writable() is also unreliable
74 * on Unix servers if safe_mode is on.
75 *
Andrey Andreev2b284f92014-01-25 00:25:56 +020076 * @link https://bugs.php.net/bug.php?id=54709
Timothy Warrenad475052012-04-19 13:21:06 -040077 * @param string
78 * @return void
79 */
Derek Jonesdc8e9ea2010-03-02 13:17:19 -060080 function is_really_writable($file)
Derek Allard2067d1a2008-11-13 22:59:24 +000081 {
Derek Jonesdc8e9ea2010-03-02 13:17:19 -060082 // If we're on a Unix server with safe_mode off we call is_writable
Andrey Andreevf6274742014-02-20 18:05:58 +020083 if (DIRECTORY_SEPARATOR === '/' && (is_php('5.4') OR ! ini_get('safe_mode')))
Derek Jonesdc8e9ea2010-03-02 13:17:19 -060084 {
85 return is_writable($file);
86 }
Derek Allard2067d1a2008-11-13 22:59:24 +000087
Andrey Andreev188abaf2012-01-07 19:09:42 +020088 /* For Windows servers and safe_mode "on" installations we'll actually
89 * write a file then read it. Bah...
90 */
Derek Jonesdc8e9ea2010-03-02 13:17:19 -060091 if (is_dir($file))
92 {
vlakoff06127562013-03-30 00:06:39 +010093 $file = rtrim($file, '/').'/'.md5(mt_rand());
Andrey Andreev7cf682a2014-03-13 14:55:45 +020094 if (($fp = @fopen($file, 'ab')) === FALSE)
Derek Jonesdc8e9ea2010-03-02 13:17:19 -060095 {
96 return FALSE;
97 }
98
99 fclose($fp);
Andrey Andreev7cf682a2014-03-13 14:55:45 +0200100 @chmod($file, 0777);
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600101 @unlink($file);
102 return TRUE;
103 }
Andrey Andreev7cf682a2014-03-13 14:55:45 +0200104 elseif ( ! is_file($file) OR ($fp = @fopen($file, 'ab')) === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000105 {
106 return FALSE;
107 }
108
109 fclose($fp);
Derek Allard2067d1a2008-11-13 22:59:24 +0000110 return TRUE;
111 }
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400112}
Derek Allard2067d1a2008-11-13 22:59:24 +0000113
114// ------------------------------------------------------------------------
115
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400116if ( ! function_exists('load_class'))
117{
Timothy Warrenad475052012-04-19 13:21:06 -0400118 /**
119 * Class registry
120 *
121 * This function acts as a singleton. If the requested class does not
122 * exist it is instantiated and set to a static variable. If it has
123 * previously been instantiated the variable is returned.
124 *
125 * @param string the class name being requested
126 * @param string the directory where the class should be found
vlakoff102105d2014-05-18 05:13:33 +0200127 * @param string an optional argument to pass to the class constructor
Timothy Warrenad475052012-04-19 13:21:06 -0400128 * @return object
129 */
Andrey Andreevc26b9eb2014-02-24 11:31:36 +0200130 function &load_class($class, $directory = 'libraries', $param = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000131 {
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600132 static $_classes = array();
Barry Mienydd671972010-10-04 16:33:58 +0200133
Andrey Andreev188abaf2012-01-07 19:09:42 +0200134 // Does the class exist? If so, we're done...
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600135 if (isset($_classes[$class]))
Derek Allard2067d1a2008-11-13 22:59:24 +0000136 {
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600137 return $_classes[$class];
Derek Allard2067d1a2008-11-13 22:59:24 +0000138 }
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600139
140 $name = FALSE;
141
Shane Pearsonab57a352011-08-22 16:11:20 -0500142 // Look for the class first in the local application/libraries folder
143 // then in the native system/libraries folder
144 foreach (array(APPPATH, BASEPATH) as $path)
Barry Mienydd671972010-10-04 16:33:58 +0200145 {
Andrey Andreev536b7712012-01-07 21:31:25 +0200146 if (file_exists($path.$directory.'/'.$class.'.php'))
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600147 {
Andrey Andreevc26b9eb2014-02-24 11:31:36 +0200148 $name = 'CI_'.$class;
Barry Mienydd671972010-10-04 16:33:58 +0200149
Andrey Andreev49e68de2013-02-21 16:30:55 +0200150 if (class_exists($name, FALSE) === FALSE)
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600151 {
Andrey Andreeva52c7752012-10-11 10:54:02 +0300152 require_once($path.$directory.'/'.$class.'.php');
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600153 }
Barry Mienydd671972010-10-04 16:33:58 +0200154
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600155 break;
156 }
157 }
158
Andrey Andreev188abaf2012-01-07 19:09:42 +0200159 // Is the request a class extension? If so we load it too
Andrey Andreev536b7712012-01-07 21:31:25 +0200160 if (file_exists(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php'))
Barry Mienydd671972010-10-04 16:33:58 +0200161 {
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600162 $name = config_item('subclass_prefix').$class;
Barry Mienydd671972010-10-04 16:33:58 +0200163
Andrey Andreev49e68de2013-02-21 16:30:55 +0200164 if (class_exists($name, FALSE) === FALSE)
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600165 {
Andrey Andreevc26b9eb2014-02-24 11:31:36 +0200166 require_once(APPPATH.$directory.'/'.$name.'.php');
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600167 }
168 }
169
170 // Did we find the class?
171 if ($name === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000172 {
Barry Mienydd671972010-10-04 16:33:58 +0200173 // Note: We use exit() rather then show_error() in order to avoid a
vlakofffe8fe452012-07-11 19:56:50 +0200174 // self-referencing loop with the Exceptions class
Kevin Cuppd63e4012012-02-05 14:14:32 -0500175 set_status_header(503);
Daniel Hunsaker353f9832013-01-24 17:09:10 -0700176 echo 'Unable to locate the specified class: '.$class.'.php';
Andrey Andreev7cf682a2014-03-13 14:55:45 +0200177 exit(5); // EXIT_UNK_CLASS
Derek Allard2067d1a2008-11-13 22:59:24 +0000178 }
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600179
180 // Keep track of what we just loaded
181 is_loaded($class);
182
Andrey Andreevde9ec102014-02-24 17:16:32 +0200183 $_classes[$class] = isset($param)
Andrey Andreevc26b9eb2014-02-24 11:31:36 +0200184 ? new $name($param)
185 : new $name();
Andrey Andreevde9ec102014-02-24 17:16:32 +0200186 return $_classes[$class];
Derek Allard2067d1a2008-11-13 22:59:24 +0000187 }
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400188}
Derek Allard2067d1a2008-11-13 22:59:24 +0000189
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600190// --------------------------------------------------------------------
191
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400192if ( ! function_exists('is_loaded'))
193{
Timothy Warrenad475052012-04-19 13:21:06 -0400194 /**
195 * Keeps track of which libraries have been loaded. This function is
196 * called by the load_class() function above
197 *
198 * @param string
199 * @return array
200 */
Andrey Andreevd47baab2012-01-09 16:56:46 +0200201 function &is_loaded($class = '')
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600202 {
203 static $_is_loaded = array();
204
Alex Bilbieed944a32012-06-02 11:07:47 +0100205 if ($class !== '')
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600206 {
207 $_is_loaded[strtolower($class)] = $class;
208 }
209
210 return $_is_loaded;
211 }
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400212}
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600213
214// ------------------------------------------------------------------------
Derek Jonesf0a9b332009-07-29 14:19:18 +0000215
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400216if ( ! function_exists('get_config'))
217{
Timothy Warrenad475052012-04-19 13:21:06 -0400218 /**
219 * Loads the main config.php file
220 *
221 * This function lets us grab the config file even if the Config class
222 * hasn't been instantiated yet
223 *
224 * @param array
225 * @return array
226 */
Andrey Andreev49890a92013-08-19 19:56:18 +0300227 function &get_config(Array $replace = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000228 {
vlakoff5a346882014-05-17 07:17:41 +0200229 static $config;
Barry Mienydd671972010-10-04 16:33:58 +0200230
vlakoff5a346882014-05-17 07:17:41 +0200231 if (empty($config))
vlakoff8d70c0a2013-08-17 07:31:29 +0200232 {
233 $file_path = APPPATH.'config/config.php';
234 $found = FALSE;
235 if (file_exists($file_path))
236 {
237 $found = TRUE;
238 require($file_path);
239 }
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600240
vlakoff8d70c0a2013-08-17 07:31:29 +0200241 // Is the config file in the environment folder?
242 if (file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php'))
243 {
244 require($file_path);
245 }
246 elseif ( ! $found)
247 {
248 set_status_header(503);
249 echo 'The configuration file does not exist.';
Andrey Andreev7cf682a2014-03-13 14:55:45 +0200250 exit(3); // EXIT_CONFIG
vlakoff8d70c0a2013-08-17 07:31:29 +0200251 }
joelcox2035fd82011-01-16 16:50:36 +0100252
vlakoff8d70c0a2013-08-17 07:31:29 +0200253 // Does the $config array exist in the file?
254 if ( ! isset($config) OR ! is_array($config))
255 {
256 set_status_header(503);
257 echo 'Your config file does not appear to be formatted correctly.';
Andrey Andreev7cf682a2014-03-13 14:55:45 +0200258 exit(3); // EXIT_CONFIG
vlakoff8d70c0a2013-08-17 07:31:29 +0200259 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000260 }
261
vlakoff67e5ca62013-08-19 04:52:00 +0200262 // Are any values being dynamically added or replaced?
vlakoff2f7810a2013-08-19 04:46:26 +0200263 foreach ($replace as $key => $val)
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600264 {
vlakoff5a346882014-05-17 07:17:41 +0200265 $config[$key] = $val;
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600266 }
Barry Mienydd671972010-10-04 16:33:58 +0200267
vlakoff5a346882014-05-17 07:17:41 +0200268 return $config;
Derek Allard2067d1a2008-11-13 22:59:24 +0000269 }
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400270}
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600271
272// ------------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000273
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400274if ( ! function_exists('config_item'))
275{
Timothy Warrenad475052012-04-19 13:21:06 -0400276 /**
277 * Returns the specified config item
278 *
279 * @param string
280 * @return mixed
281 */
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600282 function config_item($item)
Derek Allard2067d1a2008-11-13 22:59:24 +0000283 {
vlakoffaf431ce2013-07-19 02:06:41 +0200284 static $_config;
Barry Mienydd671972010-10-04 16:33:58 +0200285
vlakoffaf431ce2013-07-19 02:06:41 +0200286 if (empty($_config))
Derek Allard2067d1a2008-11-13 22:59:24 +0000287 {
vlakoffaf431ce2013-07-19 02:06:41 +0200288 // references cannot be directly assigned to static variables, so we use an array
289 $_config[0] =& get_config();
Derek Allard2067d1a2008-11-13 22:59:24 +0000290 }
Barry Mienydd671972010-10-04 16:33:58 +0200291
vlakoffaf431ce2013-07-19 02:06:41 +0200292 return isset($_config[0][$item]) ? $_config[0][$item] : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000293 }
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400294}
Derek Allard2067d1a2008-11-13 22:59:24 +0000295
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600296// ------------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000297
Andrey Andreev6ef498b2012-06-05 22:01:58 +0300298if ( ! function_exists('get_mimes'))
299{
300 /**
301 * Returns the MIME types array from config/mimes.php
302 *
303 * @return array
304 */
305 function &get_mimes()
306 {
vlakoff69550c52014-05-19 13:45:02 +0200307 static $_mimes;
Andrey Andreev6ef498b2012-06-05 22:01:58 +0300308
vlakoff69550c52014-05-19 13:45:02 +0200309 if (empty($_mimes))
Andrey Andreev6ef498b2012-06-05 22:01:58 +0300310 {
vlakoff69550c52014-05-19 13:45:02 +0200311 if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
312 {
313 $_mimes = include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php');
314 }
315 elseif (file_exists(APPPATH.'config/mimes.php'))
316 {
317 $_mimes = include(APPPATH.'config/mimes.php');
318 }
319 else
320 {
321 $_mimes = array();
322 }
Andrey Andreev6ef498b2012-06-05 22:01:58 +0300323 }
324
325 return $_mimes;
326 }
327}
328
329// ------------------------------------------------------------------------
330
Andrey Andreev3fb02672012-10-22 16:48:01 +0300331if ( ! function_exists('is_https'))
332{
333 /**
334 * Is HTTPS?
335 *
336 * Determines if the application is accessed via an encrypted
337 * (HTTPS) connection.
338 *
339 * @return bool
340 */
341 function is_https()
Richard Deurwaarder (Xeli)23dc0522013-06-24 14:52:47 +0200342 {
Andrey Andreev333b80e2013-07-01 16:21:54 +0300343 if ( ! empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off')
Richard Deurwaarder (Xeli)23dc0522013-06-24 14:52:47 +0200344 {
345 return TRUE;
346 }
347 elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')
348 {
349 return TRUE;
350 }
Andrey Andreev333b80e2013-07-01 16:21:54 +0300351 elseif ( ! empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off')
Richard Deurwaarder (Xeli)23dc0522013-06-24 14:52:47 +0200352 {
353 return TRUE;
354 }
Richard Deurwaarder (Xeli)98999972013-06-24 15:19:30 +0200355
Richard Deurwaarder (Xeli)7cc29452013-06-24 15:06:19 +0200356 return FALSE;
Richard Deurwaarder (Xeli)23dc0522013-06-24 14:52:47 +0200357 }
Andrey Andreev3fb02672012-10-22 16:48:01 +0300358}
359
360// ------------------------------------------------------------------------
361
Andrey Andreevf964b162013-11-12 17:04:55 +0200362if ( ! function_exists('is_cli'))
363{
364
365 /**
366 * Is CLI?
367 *
368 * Test to see if a request was made from the command line.
369 *
370 * @return bool
371 */
372 function is_cli()
373 {
374 return (PHP_SAPI === 'cli' OR defined('STDIN'));
375 }
376}
377
378// ------------------------------------------------------------------------
379
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400380if ( ! function_exists('show_error'))
381{
Timothy Warrenad475052012-04-19 13:21:06 -0400382 /**
383 * Error Handler
384 *
385 * This function lets us invoke the exception class and
386 * display errors using the standard error template located
vlakoff52301c72013-03-29 14:23:34 +0100387 * in application/views/errors/error_general.php
Timothy Warrenad475052012-04-19 13:21:06 -0400388 * This function will send the error page directly to the
389 * browser and exit.
390 *
391 * @param string
392 * @param int
393 * @param string
394 * @return void
395 */
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600396 function show_error($message, $status_code = 500, $heading = 'An Error Was Encountered')
397 {
Daniel Hunsaker353f9832013-01-24 17:09:10 -0700398 $status_code = abs($status_code);
399 if ($status_code < 100)
400 {
Andrey Andreev7cf682a2014-03-13 14:55:45 +0200401 $exit_status = $status_code + 9; // 9 is EXIT__AUTO_MIN
402 if ($exit_status > 125) // 125 is EXIT__AUTO_MAX
Daniel Hunsaker3b5b7f42013-02-22 19:17:56 -0700403 {
Andrey Andreev7cf682a2014-03-13 14:55:45 +0200404 $exit_status = 1; // EXIT_ERROR
Daniel Hunsaker3b5b7f42013-02-22 19:17:56 -0700405 }
Andrey Andreev7cf682a2014-03-13 14:55:45 +0200406
Daniel Hunsaker353f9832013-01-24 17:09:10 -0700407 $status_code = 500;
408 }
409 else
410 {
Andrey Andreev7cf682a2014-03-13 14:55:45 +0200411 $exit_status = 1; // EXIT_ERROR
Daniel Hunsaker353f9832013-01-24 17:09:10 -0700412 }
Andrey Andreev5a6814e2013-03-04 15:44:12 +0200413
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600414 $_error =& load_class('Exceptions', 'core');
415 echo $_error->show_error($heading, $message, 'error_general', $status_code);
Daniel Hunsaker353f9832013-01-24 17:09:10 -0700416 exit($exit_status);
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600417 }
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400418}
Derek Allard2067d1a2008-11-13 22:59:24 +0000419
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600420// ------------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000421
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400422if ( ! function_exists('show_404'))
423{
Timothy Warrenad475052012-04-19 13:21:06 -0400424 /**
425 * 404 Page Handler
426 *
427 * This function is similar to the show_error() function above
428 * However, instead of the standard error template it displays
429 * 404 errors.
430 *
431 * @param string
432 * @param bool
433 * @return void
434 */
Derek Allard2ddc9492010-08-05 10:08:33 -0400435 function show_404($page = '', $log_error = TRUE)
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600436 {
437 $_error =& load_class('Exceptions', 'core');
Derek Allard2ddc9492010-08-05 10:08:33 -0400438 $_error->show_404($page, $log_error);
Andrey Andreev7cf682a2014-03-13 14:55:45 +0200439 exit(4); // EXIT_UNKNOWN_FILE
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600440 }
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400441}
Derek Allard2067d1a2008-11-13 22:59:24 +0000442
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600443// ------------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000444
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400445if ( ! function_exists('log_message'))
446{
Timothy Warrenad475052012-04-19 13:21:06 -0400447 /**
448 * Error Logging Interface
449 *
450 * We use this as a simple mechanism to access the logging
451 * class and send messages to be logged.
452 *
vlakoffd0c30ab2013-05-07 07:49:23 +0200453 * @param string the error level: 'error', 'debug' or 'info'
454 * @param string the error message
Timothy Warrenad475052012-04-19 13:21:06 -0400455 * @return void
456 */
Andrey Andreev838c9a92013-09-13 14:05:13 +0300457 function log_message($level, $message)
Derek Allard2067d1a2008-11-13 22:59:24 +0000458 {
Andrey Andreev2f8d2d32013-08-07 15:54:47 +0300459 static $_log;
Barry Mienydd671972010-10-04 16:33:58 +0200460
Andrey Andreev49890a92013-08-19 19:56:18 +0300461 if ($_log === NULL)
Ted Woodb19a2032013-01-05 16:02:43 -0800462 {
vlakoff61f1aa02013-08-07 11:29:17 +0200463 // references cannot be directly assigned to static variables, so we use an array
464 $_log[0] =& load_class('Log', 'core');
Ted Woodb19a2032013-01-05 16:02:43 -0800465 }
Andrey Andreeva107a0f2013-02-15 22:30:31 +0200466
Andrey Andreev838c9a92013-09-13 14:05:13 +0300467 $_log[0]->write_log($level, $message);
Derek Allard2067d1a2008-11-13 22:59:24 +0000468 }
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400469}
Derek Allard2067d1a2008-11-13 22:59:24 +0000470
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600471// ------------------------------------------------------------------------
Derek Jones817163a2009-07-11 17:05:58 +0000472
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400473if ( ! function_exists('set_status_header'))
474{
Timothy Warrenad475052012-04-19 13:21:06 -0400475 /**
476 * Set HTTP Status Header
477 *
478 * @param int the status code
479 * @param string
480 * @return void
481 */
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600482 function set_status_header($code = 200, $text = '')
Derek Jones817163a2009-07-11 17:05:58 +0000483 {
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600484 $stati = array(
Timothy Warrenad475052012-04-19 13:21:06 -0400485 200 => 'OK',
486 201 => 'Created',
487 202 => 'Accepted',
488 203 => 'Non-Authoritative Information',
489 204 => 'No Content',
490 205 => 'Reset Content',
491 206 => 'Partial Content',
Derek Jones817163a2009-07-11 17:05:58 +0000492
Timothy Warrenad475052012-04-19 13:21:06 -0400493 300 => 'Multiple Choices',
494 301 => 'Moved Permanently',
495 302 => 'Found',
Andrey Andreev51d6d842012-06-15 16:41:09 +0300496 303 => 'See Other',
Timothy Warrenad475052012-04-19 13:21:06 -0400497 304 => 'Not Modified',
498 305 => 'Use Proxy',
499 307 => 'Temporary Redirect',
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600500
Timothy Warrenad475052012-04-19 13:21:06 -0400501 400 => 'Bad Request',
502 401 => 'Unauthorized',
503 403 => 'Forbidden',
504 404 => 'Not Found',
505 405 => 'Method Not Allowed',
506 406 => 'Not Acceptable',
507 407 => 'Proxy Authentication Required',
508 408 => 'Request Timeout',
509 409 => 'Conflict',
510 410 => 'Gone',
511 411 => 'Length Required',
512 412 => 'Precondition Failed',
513 413 => 'Request Entity Too Large',
514 414 => 'Request-URI Too Long',
515 415 => 'Unsupported Media Type',
516 416 => 'Requested Range Not Satisfiable',
517 417 => 'Expectation Failed',
518 422 => 'Unprocessable Entity',
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600519
Timothy Warrenad475052012-04-19 13:21:06 -0400520 500 => 'Internal Server Error',
521 501 => 'Not Implemented',
522 502 => 'Bad Gateway',
523 503 => 'Service Unavailable',
524 504 => 'Gateway Timeout',
525 505 => 'HTTP Version Not Supported'
526 );
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600527
Andrey Andreev51d6d842012-06-15 16:41:09 +0300528 if (empty($code) OR ! is_numeric($code))
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600529 {
530 show_error('Status codes must be numeric', 500);
531 }
Barry Mienydd671972010-10-04 16:33:58 +0200532
Andrey Andreev51d6d842012-06-15 16:41:09 +0300533 is_int($code) OR $code = (int) $code;
534
535 if (empty($text))
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600536 {
Andrey Andreev51d6d842012-06-15 16:41:09 +0300537 if (isset($stati[$code]))
538 {
539 $text = $stati[$code];
540 }
541 else
542 {
543 show_error('No status text available. Please check your status code number or supply your own message text.', 500);
544 }
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600545 }
Barry Mienydd671972010-10-04 16:33:58 +0200546
Andrey Andreevb7b43962012-02-27 22:45:48 +0200547 $server_protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : FALSE;
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600548
vlakoff40d12492013-08-06 14:46:00 +0200549 if (strpos(PHP_SAPI, 'cgi') === 0)
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600550 {
Daniel Hunsaker8626e932013-03-04 05:14:22 -0700551 header('Status: '.$code.' '.$text, TRUE);
552 }
553 else
554 {
555 header(($server_protocol ? $server_protocol : 'HTTP/1.1').' '.$code.' '.$text, TRUE, $code);
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600556 }
Derek Jones817163a2009-07-11 17:05:58 +0000557 }
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400558}
Barry Mienydd671972010-10-04 16:33:58 +0200559
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600560// --------------------------------------------------------------------
Derek Jones817163a2009-07-11 17:05:58 +0000561
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400562if ( ! function_exists('_exception_handler'))
563{
Timothy Warrenad475052012-04-19 13:21:06 -0400564 /**
565 * Exception Handler
566 *
vlakoffc941d852013-08-06 14:44:40 +0200567 * This is the custom exception handler that is declared at the top
568 * of CodeIgniter.php. The main reason we use this is to permit
Timothy Warrenad475052012-04-19 13:21:06 -0400569 * PHP errors to be logged in our own log files since the user may
570 * not have access to server logs. Since this function
571 * effectively intercepts PHP errors, however, we also need
572 * to display errors based on the current error_reporting level.
573 * We do that with the use of a PHP error template.
574 *
Andrey Andreev0850a282013-10-21 14:26:18 +0300575 * @param int $severity
576 * @param string $message
577 * @param string $filepath
578 * @param int $line
Timothy Warrenad475052012-04-19 13:21:06 -0400579 * @return void
580 */
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600581 function _exception_handler($severity, $message, $filepath, $line)
Barry Mienydd671972010-10-04 16:33:58 +0200582 {
Andrey Andreev0850a282013-10-21 14:26:18 +0300583 $is_error = (((E_ERROR | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity);
Jesse van Assen7eb116a2013-07-06 10:42:14 +0200584
585 // When an error occurred, set the status header to '500 Internal Server Error'
586 // to indicate to the client something went wrong.
587 // This can't be done within the $_error->show_php_error method because
588 // it is only called when the display_errors flag is set (which isn't usually
589 // the case in a production environment) or when errors are ignored because
590 // they are above the error_reporting threshold.
591 if ($is_error)
592 {
593 set_status_header(500);
Andrey Andreev02545892014-02-19 23:49:31 +0200594 }
Barry Mienydd671972010-10-04 16:33:58 +0200595
Francesco Negri0e0c37b2012-08-04 14:16:50 +0300596 // Should we ignore the error? We'll get the current error_reporting
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600597 // level and add its bits with the severity bits to find out.
Francesco Negri0e0c37b2012-08-04 14:16:50 +0300598 if (($severity & error_reporting()) !== $severity)
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600599 {
600 return;
601 }
Barry Mienydd671972010-10-04 16:33:58 +0200602
Cristian Kocza2be27442014-02-19 21:52:38 +0200603 $_error =& load_class('Exceptions', 'core');
Andrey Andreev76160bc2014-01-30 22:26:14 +0200604 $_error->log_exception($severity, $message, $filepath, $line);
605
Francesco Negri312bdc52012-08-04 07:32:19 -0400606 // Should we display the error?
Andrey Andreevf6274742014-02-20 18:05:58 +0200607 if (ini_get('display_errors'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000608 {
609 $_error->show_php_error($severity, $message, $filepath, $line);
610 }
611
Jesse van Assen7eb116a2013-07-06 10:42:14 +0200612 // If the error is fatal, the execution of the script should be stopped because
613 // errors can't be recovered from. Halting the script conforms with PHP's
614 // default error handling. See http://www.php.net/manual/en/errorfunc.constants.php
615 if ($is_error)
616 {
Andrey Andreev7cf682a2014-03-13 14:55:45 +0200617 exit(1); // EXIT_ERROR
Jesse van Assen7eb116a2013-07-06 10:42:14 +0200618 }
Derek Jonesdc8e9ea2010-03-02 13:17:19 -0600619 }
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400620}
Derek Allard2067d1a2008-11-13 22:59:24 +0000621
Kaiwang Chen21fe9da2013-09-11 13:09:41 +0800622// ------------------------------------------------------------------------
623
624if ( ! function_exists('_shutdown_handler'))
625{
626 /**
627 * Shutdown Handler
628 *
629 * This is the shutdown handler that is declared at the top
630 * of CodeIgniter.php. The main reason we use this is to simulate
631 * a complete custom exception handler.
632 *
vkeranovd6f3d312013-09-14 21:39:49 +0300633 * E_STRICT is purposivly neglected because such events may have
Kaiwang Chen21fe9da2013-09-11 13:09:41 +0800634 * been caught. Duplication or none? None is preferred for now.
635 *
636 * @link http://insomanic.me.uk/post/229851073/php-trick-catching-fatal-errors-e-error-with-a
637 * @return void
638 */
639 function _shutdown_handler()
640 {
Andrey Andreevafca3522013-11-14 15:26:59 +0200641 $last_error = error_get_last();
Kaiwang Chen21fe9da2013-09-11 13:09:41 +0800642 if (isset($last_error) &&
643 ($last_error['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING)))
644 {
Kaiwang Chen21fe9da2013-09-11 13:09:41 +0800645 _exception_handler($last_error['type'], $last_error['message'], $last_error['file'], $last_error['line']);
646 }
647 }
648}
649
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400650// --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200651
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400652if ( ! function_exists('remove_invisible_characters'))
653{
Timothy Warrenad475052012-04-19 13:21:06 -0400654 /**
655 * Remove Invisible Characters
656 *
657 * This prevents sandwiching null characters
658 * between ascii characters, like Java\0script.
659 *
660 * @param string
661 * @param bool
662 * @return string
663 */
Pascal Kriete0ff50262011-04-05 14:52:03 -0400664 function remove_invisible_characters($str, $url_encoded = TRUE)
Greg Aker757dda62010-04-14 19:06:19 -0500665 {
Pascal Kriete0ff50262011-04-05 14:52:03 -0400666 $non_displayables = array();
Andrey Andreev188abaf2012-01-07 19:09:42 +0200667
668 // every control character except newline (dec 10),
669 // carriage return (dec 13) and horizontal tab (dec 09)
Pascal Kriete0ff50262011-04-05 14:52:03 -0400670 if ($url_encoded)
Greg Aker757dda62010-04-14 19:06:19 -0500671 {
Pascal Kriete0ff50262011-04-05 14:52:03 -0400672 $non_displayables[] = '/%0[0-8bcef]/'; // url encoded 00-08, 11, 12, 14, 15
673 $non_displayables[] = '/%1[0-9a-f]/'; // url encoded 16-31
Greg Aker757dda62010-04-14 19:06:19 -0500674 }
Andrey Andreev188abaf2012-01-07 19:09:42 +0200675
Pascal Kriete0ff50262011-04-05 14:52:03 -0400676 $non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S'; // 00-08, 11, 12, 14-31, 127
Greg Aker757dda62010-04-14 19:06:19 -0500677
678 do
679 {
Pascal Kriete0ff50262011-04-05 14:52:03 -0400680 $str = preg_replace($non_displayables, '', $str, -1, $count);
Greg Aker757dda62010-04-14 19:06:19 -0500681 }
Pascal Kriete0ff50262011-04-05 14:52:03 -0400682 while ($count);
Greg Aker757dda62010-04-14 19:06:19 -0500683
684 return $str;
685 }
Dan Horrigan3ef65bd2011-05-08 11:06:44 -0400686}
Derek Allard2067d1a2008-11-13 22:59:24 +0000687
kenjisfbac8b42011-08-25 10:51:44 +0900688// ------------------------------------------------------------------------
689
kenjisfbac8b42011-08-25 10:51:44 +0900690if ( ! function_exists('html_escape'))
691{
Timothy Warrenad475052012-04-19 13:21:06 -0400692 /**
Ivan Tcholakov4f458582014-08-25 11:20:22 +0300693 * Returns HTML escaped variable.
694 * $double_encode set to FALSE prevents escaping twice.
Timothy Warrenad475052012-04-19 13:21:06 -0400695 *
696 * @param mixed
Ivan Tcholakov4f458582014-08-25 11:20:22 +0300697 * @param bool
Timothy Warrenad475052012-04-19 13:21:06 -0400698 * @return mixed
699 */
Ivan Tcholakov4f458582014-08-25 11:20:22 +0300700 function html_escape($var, $double_encode = TRUE)
kenjisfbac8b42011-08-25 10:51:44 +0900701 {
Ivan Tcholakov4f458582014-08-25 11:20:22 +0300702 $double_encode = (bool) $double_encode;
703
Andrey Andreevb7b43962012-02-27 22:45:48 +0200704 return is_array($var)
Ivan Tcholakov4f458582014-08-25 11:20:22 +0300705 ? ($double_encode === FALSE ? array_map('html_escape', $var, array_fill(0, count($var), FALSE)) : array_map('html_escape', $var))
706 : htmlspecialchars($var, ENT_QUOTES, config_item('charset'), $double_encode);
Greg Aker5c1aa632011-12-25 01:24:29 -0600707 }
Greg Akerd96f8822011-12-27 16:23:47 -0600708}
Greg Aker5c1aa632011-12-25 01:24:29 -0600709
Chad Furmana1abada2012-07-29 01:03:50 -0400710// ------------------------------------------------------------------------
711
712if ( ! function_exists('_stringify_attributes'))
713{
714 /**
Andrey Andreevbdb99992012-07-30 17:38:05 +0300715 * Stringify attributes for use in HTML tags.
Chad Furmana1abada2012-07-29 01:03:50 -0400716 *
Andrey Andreevbdb99992012-07-30 17:38:05 +0300717 * Helper function used to convert a string, array, or object
718 * of attributes to a string.
Chad Furmana1abada2012-07-29 01:03:50 -0400719 *
Andrey Andreevbdb99992012-07-30 17:38:05 +0300720 * @param mixed string, array, object
721 * @param bool
722 * @return string
Chad Furmana1abada2012-07-29 01:03:50 -0400723 */
724 function _stringify_attributes($attributes, $js = FALSE)
725 {
Andrey Andreevbdb99992012-07-30 17:38:05 +0300726 $atts = NULL;
Chad Furmana1abada2012-07-29 01:03:50 -0400727
728 if (empty($attributes))
729 {
730 return $atts;
731 }
732
733 if (is_string($attributes))
734 {
735 return ' '.$attributes;
736 }
737
738 $attributes = (array) $attributes;
739
740 foreach ($attributes as $key => $val)
741 {
742 $atts .= ($js) ? $key.'='.$val.',' : ' '.$key.'="'.$val.'"';
743 }
Andrey Andreevbdb99992012-07-30 17:38:05 +0300744
Chad Furmana1abada2012-07-29 01:03:50 -0400745 return rtrim($atts, ',');
746 }
747}
748
Andrey Andreeve9d2dc82012-11-07 14:23:29 +0200749// ------------------------------------------------------------------------
750
751if ( ! function_exists('function_usable'))
752{
753 /**
754 * Function usable
755 *
756 * Executes a function_exists() check, and if the Suhosin PHP
757 * extension is loaded - checks whether the function that is
758 * checked might be disabled in there as well.
759 *
760 * This is useful as function_exists() will return FALSE for
761 * functions disabled via the *disable_functions* php.ini
762 * setting, but not for *suhosin.executor.func.blacklist* and
763 * *suhosin.executor.disable_eval*. These settings will just
764 * terminate script execution if a disabled function is executed.
765 *
Andrey Andreevaaa8ddb2014-02-03 14:10:44 +0200766 * The above described behavior turned out to be a bug in Suhosin,
767 * but even though a fix was commited for 0.9.34 on 2012-02-12,
768 * that version is yet to be released. This function will therefore
769 * be just temporary, but would probably be kept for a few years.
770 *
Andrey Andreeve9d2dc82012-11-07 14:23:29 +0200771 * @link http://www.hardened-php.net/suhosin/
772 * @param string $function_name Function to check for
773 * @return bool TRUE if the function exists and is safe to call,
774 * FALSE otherwise.
775 */
776 function function_usable($function_name)
777 {
778 static $_suhosin_func_blacklist;
779
780 if (function_exists($function_name))
781 {
782 if ( ! isset($_suhosin_func_blacklist))
783 {
Andrey Andreevae634622012-12-17 10:30:18 +0200784 if (extension_loaded('suhosin'))
Andrey Andreeve9d2dc82012-11-07 14:23:29 +0200785 {
Andrey Andreevf6274742014-02-20 18:05:58 +0200786 $_suhosin_func_blacklist = explode(',', trim(ini_get('suhosin.executor.func.blacklist')));
Andrey Andreevae634622012-12-17 10:30:18 +0200787
Andrey Andreevf6274742014-02-20 18:05:58 +0200788 if ( ! in_array('eval', $_suhosin_func_blacklist, TRUE) && ini_get('suhosin.executor.disable_eval'))
Andrey Andreevae634622012-12-17 10:30:18 +0200789 {
790 $_suhosin_func_blacklist[] = 'eval';
791 }
792 }
793 else
794 {
795 $_suhosin_func_blacklist = array();
Andrey Andreeve9d2dc82012-11-07 14:23:29 +0200796 }
797 }
798
Andrey Andreevae634622012-12-17 10:30:18 +0200799 return ! in_array($function_name, $_suhosin_func_blacklist, TRUE);
Andrey Andreeve9d2dc82012-11-07 14:23:29 +0200800 }
801
802 return FALSE;
803 }
804}
Richard Deurwaarder (Xeli)668d0092013-06-24 13:50:52 +0200805
Derek Allard2067d1a2008-11-13 22:59:24 +0000806/* End of file Common.php */
Andrey Andreev13c818e2013-09-14 21:44:36 +0300807/* Location: ./system/core/Common.php */