blob: f45c85c260218514612a6f48e4acea954765343a [file] [log] [blame]
Derek Allard2067d1a2008-11-13 22:59:24 +00001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2/**
3 * CodeIgniter
4 *
5 * An open source application development framework for PHP 4.3.2 or newer
6 *
7 * @package CodeIgniter
8 * @author ExpressionEngine Dev Team
Derek Jonesfc395a12009-04-22 14:15:09 +00009 * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc.
Derek Allard2067d1a2008-11-13 22:59:24 +000010 * @license http://codeigniter.com/user_guide/license.html
11 * @link http://codeigniter.com
12 * @since Version 1.0
13 * @filesource
14 */
15
16// ------------------------------------------------------------------------
17
18/**
19 * Common Functions
20 *
21 * Loads the base classes and executes the request.
22 *
23 * @package CodeIgniter
24 * @subpackage codeigniter
25 * @category Common Functions
26 * @author ExpressionEngine Dev Team
27 * @link http://codeigniter.com/user_guide/
28 */
29
30// ------------------------------------------------------------------------
31
32/**
Derek Jones086ee5a2009-07-28 14:42:12 +000033* Determines if the current version of PHP is greater then the supplied value
34*
35* Since there are a few places where we conditionally test for PHP > 5
36* we'll set a static variable.
37*
38* @access public
39* @return bool
40*/
Derek Jones5bcfd2e2009-07-28 14:42:42 +000041function is_php($version = '5.0.0')
42{
43 static $_is_php;
44
45 if ( ! isset($_is_php[$version]))
Derek Jones086ee5a2009-07-28 14:42:12 +000046 {
Derek Jones5bcfd2e2009-07-28 14:42:42 +000047 $_is_php[$version] = (version_compare(PHP_VERSION, $version) < 0) ? FALSE : TRUE;
Derek Jones086ee5a2009-07-28 14:42:12 +000048 }
49
Derek Jones5bcfd2e2009-07-28 14:42:42 +000050 return $_is_php[$version];
51}
52
Derek Jones086ee5a2009-07-28 14:42:12 +000053// ------------------------------------------------------------------------
54
55/**
Derek Allard2067d1a2008-11-13 22:59:24 +000056 * Tests for file writability
57 *
58 * is_writable() returns TRUE on Windows servers when you really can't write to
59 * the file, based on the read-only attribute. is_writable() is also unreliable
60 * on Unix servers if safe_mode is on.
61 *
62 * @access private
63 * @return void
64 */
65function is_really_writable($file)
66{
67 // If we're on a Unix server with safe_mode off we call is_writable
68 if (DIRECTORY_SEPARATOR == '/' AND @ini_get("safe_mode") == FALSE)
69 {
70 return is_writable($file);
71 }
72
73 // For windows servers and safe_mode "on" installations we'll actually
74 // write a file then read it. Bah...
75 if (is_dir($file))
76 {
77 $file = rtrim($file, '/').'/'.md5(rand(1,100));
78
79 if (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
80 {
81 return FALSE;
82 }
83
84 fclose($fp);
85 @chmod($file, DIR_WRITE_MODE);
86 @unlink($file);
87 return TRUE;
88 }
89 elseif (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
90 {
91 return FALSE;
92 }
93
94 fclose($fp);
95 return TRUE;
96}
97
98// ------------------------------------------------------------------------
99
100/**
101* Class registry
102*
103* This function acts as a singleton. If the requested class does not
104* exist it is instantiated and set to a static variable. If it has
105* previously been instantiated the variable is returned.
106*
107* @access public
108* @param string the class name being requested
109* @param bool optional flag that lets classes get loaded but not instantiated
110* @return object
111*/
112function &load_class($class, $instantiate = TRUE)
113{
114 static $objects = array();
115
116 // Does the class exist? If so, we're done...
117 if (isset($objects[$class]))
118 {
119 return $objects[$class];
120 }
121
122 // If the requested class does not exist in the application/libraries
123 // folder we'll load the native class from the system/libraries folder.
124 if (file_exists(APPPATH.'libraries/'.config_item('subclass_prefix').$class.EXT))
125 {
126 require(BASEPATH.'libraries/'.$class.EXT);
127 require(APPPATH.'libraries/'.config_item('subclass_prefix').$class.EXT);
128 $is_subclass = TRUE;
129 }
130 else
131 {
132 if (file_exists(APPPATH.'libraries/'.$class.EXT))
133 {
134 require(APPPATH.'libraries/'.$class.EXT);
135 $is_subclass = FALSE;
136 }
137 else
138 {
139 require(BASEPATH.'libraries/'.$class.EXT);
140 $is_subclass = FALSE;
141 }
142 }
143
144 if ($instantiate == FALSE)
145 {
146 $objects[$class] = TRUE;
147 return $objects[$class];
148 }
149
150 if ($is_subclass == TRUE)
151 {
152 $name = config_item('subclass_prefix').$class;
153 $objects[$class] =& new $name();
154 return $objects[$class];
155 }
156
157 $name = ($class != 'Controller') ? 'CI_'.$class : $class;
158
159 $objects[$class] =& new $name();
160 return $objects[$class];
161}
162
163/**
164* Loads the main config.php file
165*
166* @access private
167* @return array
168*/
169function &get_config()
170{
171 static $main_conf;
172
173 if ( ! isset($main_conf))
174 {
175 if ( ! file_exists(APPPATH.'config/config'.EXT))
176 {
177 exit('The configuration file config'.EXT.' does not exist.');
178 }
179
180 require(APPPATH.'config/config'.EXT);
181
182 if ( ! isset($config) OR ! is_array($config))
183 {
184 exit('Your config file does not appear to be formatted correctly.');
185 }
186
187 $main_conf[0] =& $config;
188 }
189 return $main_conf[0];
190}
191
192/**
193* Gets a config item
194*
195* @access public
196* @return mixed
197*/
198function config_item($item)
199{
200 static $config_item = array();
201
202 if ( ! isset($config_item[$item]))
203 {
204 $config =& get_config();
205
206 if ( ! isset($config[$item]))
207 {
208 return FALSE;
209 }
210 $config_item[$item] = $config[$item];
211 }
212
213 return $config_item[$item];
214}
215
216
217/**
218* Error Handler
219*
220* This function lets us invoke the exception class and
221* display errors using the standard error template located
222* in application/errors/errors.php
223* This function will send the error page directly to the
224* browser and exit.
225*
226* @access public
227* @return void
228*/
Derek Jones817163a2009-07-11 17:05:58 +0000229function show_error($message, $status_code = 500)
Derek Allard2067d1a2008-11-13 22:59:24 +0000230{
231 $error =& load_class('Exceptions');
Derek Jones817163a2009-07-11 17:05:58 +0000232 echo $error->show_error('An Error Was Encountered', $message, 'error_general', $status_code);
Derek Allard2067d1a2008-11-13 22:59:24 +0000233 exit;
234}
235
236
237/**
238* 404 Page Handler
239*
240* This function is similar to the show_error() function above
241* However, instead of the standard error template it displays
242* 404 errors.
243*
244* @access public
245* @return void
246*/
247function show_404($page = '')
248{
249 $error =& load_class('Exceptions');
250 $error->show_404($page);
251 exit;
252}
253
254
255/**
256* Error Logging Interface
257*
258* We use this as a simple mechanism to access the logging
259* class and send messages to be logged.
260*
261* @access public
262* @return void
263*/
264function log_message($level = 'error', $message, $php_error = FALSE)
265{
266 static $LOG;
267
268 $config =& get_config();
269 if ($config['log_threshold'] == 0)
270 {
271 return;
272 }
273
274 $LOG =& load_class('Log');
275 $LOG->write_log($level, $message, $php_error);
276}
277
Derek Jones817163a2009-07-11 17:05:58 +0000278
279/**
280 * Set HTTP Status Header
281 *
282 * @access public
283 * @param int the status code
284 * @param string
285 * @return void
286 */
287function set_status_header($code = 200, $text = '')
288{
289 $stati = array(
290 200 => 'OK',
291 201 => 'Created',
292 202 => 'Accepted',
293 203 => 'Non-Authoritative Information',
294 204 => 'No Content',
295 205 => 'Reset Content',
296 206 => 'Partial Content',
297
298 300 => 'Multiple Choices',
299 301 => 'Moved Permanently',
300 302 => 'Found',
301 304 => 'Not Modified',
302 305 => 'Use Proxy',
303 307 => 'Temporary Redirect',
304
305 400 => 'Bad Request',
306 401 => 'Unauthorized',
307 403 => 'Forbidden',
308 404 => 'Not Found',
309 405 => 'Method Not Allowed',
310 406 => 'Not Acceptable',
311 407 => 'Proxy Authentication Required',
312 408 => 'Request Timeout',
313 409 => 'Conflict',
314 410 => 'Gone',
315 411 => 'Length Required',
316 412 => 'Precondition Failed',
317 413 => 'Request Entity Too Large',
318 414 => 'Request-URI Too Long',
319 415 => 'Unsupported Media Type',
320 416 => 'Requested Range Not Satisfiable',
321 417 => 'Expectation Failed',
322
323 500 => 'Internal Server Error',
324 501 => 'Not Implemented',
325 502 => 'Bad Gateway',
326 503 => 'Service Unavailable',
327 504 => 'Gateway Timeout',
328 505 => 'HTTP Version Not Supported'
329 );
330
331 if ($code == '' OR ! is_numeric($code))
332 {
333 show_error('Status codes must be numeric', 500);
334 }
335
336 if (isset($stati[$code]) AND $text == '')
337 {
338 $text = $stati[$code];
339 }
340
341 if ($text == '')
342 {
343 show_error('No status text available. Please check your status code number or supply your own message text.', 500);
344 }
345
346 $server_protocol = (isset($_SERVER['SERVER_PROTOCOL'])) ? $_SERVER['SERVER_PROTOCOL'] : FALSE;
347
348 if (substr(php_sapi_name(), 0, 3) == 'cgi')
349 {
350 header("Status: {$code} {$text}", TRUE);
351 }
352 elseif ($server_protocol == 'HTTP/1.1' OR $server_protocol == 'HTTP/1.0')
353 {
354 header($server_protocol." {$code} {$text}", TRUE, $code);
355 }
356 else
357 {
358 header("HTTP/1.1 {$code} {$text}", TRUE, $code);
359 }
360}
361
362
Derek Allard2067d1a2008-11-13 22:59:24 +0000363/**
364* Exception Handler
365*
366* This is the custom exception handler that is declaired at the top
367* of Codeigniter.php. The main reason we use this is permit
368* PHP errors to be logged in our own log files since we may
369* not have access to server logs. Since this function
370* effectively intercepts PHP errors, however, we also need
371* to display errors based on the current error_reporting level.
372* We do that with the use of a PHP error template.
373*
374* @access private
375* @return void
376*/
377function _exception_handler($severity, $message, $filepath, $line)
378{
379 // We don't bother with "strict" notices since they will fill up
380 // the log file with information that isn't normally very
381 // helpful. For example, if you are running PHP 5 and you
382 // use version 4 style class functions (without prefixes
383 // like "public", "private", etc.) you'll get notices telling
384 // you that these have been deprecated.
385
386 if ($severity == E_STRICT)
387 {
388 return;
389 }
390
391 $error =& load_class('Exceptions');
392
393 // Should we display the error?
394 // We'll get the current error_reporting level and add its bits
395 // with the severity bits to find out.
396
397 if (($severity & error_reporting()) == $severity)
398 {
399 $error->show_php_error($severity, $message, $filepath, $line);
400 }
401
402 // Should we log the error? No? We're done...
403 $config =& get_config();
404 if ($config['log_threshold'] == 0)
405 {
406 return;
407 }
408
409 $error->log_exception($severity, $message, $filepath, $line);
410}
411
412
413
414/* End of file Common.php */
Derek Jonesa3ffbbb2008-05-11 18:18:29 +0000415/* Location: ./system/codeigniter/Common.php */