summaryrefslogtreecommitdiffstats
path: root/system/core
diff options
context:
space:
mode:
Diffstat (limited to 'system/core')
-rw-r--r--system/core/Benchmark.php35
-rw-r--r--system/core/CodeIgniter.php102
-rw-r--r--system/core/Common.php44
-rw-r--r--system/core/Config.php87
-rw-r--r--system/core/Controller.php14
-rw-r--r--system/core/Exceptions.php51
-rw-r--r--system/core/Hooks.php71
-rw-r--r--system/core/Input.php379
-rw-r--r--system/core/Lang.php35
-rw-r--r--system/core/Loader.php349
-rw-r--r--system/core/Model.php13
-rw-r--r--system/core/Output.php163
-rw-r--r--system/core/Router.php209
-rw-r--r--system/core/Security.php184
-rw-r--r--system/core/URI.php337
-rw-r--r--system/core/Utf8.php67
16 files changed, 1171 insertions, 969 deletions
diff --git a/system/core/Benchmark.php b/system/core/Benchmark.php
index 2fabdf46e..e80ee54dd 100644
--- a/system/core/Benchmark.php
+++ b/system/core/Benchmark.php
@@ -1,4 +1,4 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php
/**
* CodeIgniter
*
@@ -24,9 +24,10 @@
* @since Version 1.0
* @filesource
*/
+defined('BASEPATH') OR exit('No direct script access allowed');
/**
- * CodeIgniter Benchmark Class
+ * Benchmark Class
*
* This class enables you to mark points and calculate the time difference
* between them. Memory consumption can also be displayed.
@@ -40,21 +41,19 @@
class CI_Benchmark {
/**
- * List of all benchmark markers and when they were added
+ * List of all benchmark markers
*
- * @var array
+ * @var array
*/
- public $marker = array();
-
- // --------------------------------------------------------------------
+ public $marker = array();
/**
* Set a benchmark marker
*
* Multiple calls to this function can be made so that several
- * execution points can be timed
+ * execution points can be timed.
*
- * @param string $name name of the marker
+ * @param string $name Marker name
* @return void
*/
public function mark($name)
@@ -65,6 +64,8 @@ class CI_Benchmark {
// --------------------------------------------------------------------
/**
+ * Elapsed time
+ *
* Calculates the time difference between two marked points.
*
* If the first parameter is empty this function instead returns the
@@ -72,10 +73,13 @@ class CI_Benchmark {
* execution time to be shown in a template. The output class will
* swap the real value for this variable.
*
- * @param string a particular marked point
- * @param string a particular marked point
- * @param integer the number of decimal places
- * @return mixed
+ * @param string $point1 A particular marked point
+ * @param string $point2 A particular marked point
+ * @param int $decimals Number of decimal places
+ *
+ * @return string Calculated elapsed time on success,
+ * an '{elapsed_string}' if $point1 is empty
+ * or an empty string if $point1 is not found.
*/
public function elapsed_time($point1 = '', $point2 = '', $decimals = 4)
{
@@ -102,12 +106,13 @@ class CI_Benchmark {
/**
* Memory Usage
*
- * This function returns the {memory_usage} pseudo-variable.
+ * Simply returns the {memory_usage} marker.
+ *
* This permits it to be put it anywhere in a template
* without the memory being calculated until the end.
* The output class will swap the real value for this variable.
*
- * @return string
+ * @return string '{memory_usage}'
*/
public function memory_usage()
{
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php
index 8159b19f5..1cd6403bf 100644
--- a/system/core/CodeIgniter.php
+++ b/system/core/CodeIgniter.php
@@ -1,4 +1,4 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php
/**
* CodeIgniter
*
@@ -24,6 +24,7 @@
* @since Version 1.0
* @filesource
*/
+defined('BASEPATH') OR exit('No direct script access allowed');
/**
* System Initialization File
@@ -50,7 +51,7 @@
* Load the global functions
* ------------------------------------------------------
*/
- require(BASEPATH.'core/Common.php');
+ require_once(BASEPATH.'core/Common.php');
/*
* ------------------------------------------------------
@@ -130,9 +131,12 @@
$CFG =& load_class('Config', 'core');
// Do we have any manually set config items in the index.php file?
- if (isset($assign_to_config))
+ if (isset($assign_to_config) && is_array($assign_to_config))
{
- $CFG->_assign_to_config($assign_to_config);
+ foreach ($assign_to_config as $key => $value)
+ {
+ $CFG->set_item($key, $value);
+ }
}
/*
@@ -229,7 +233,6 @@
return CI_Controller::get_instance();
}
-
if (file_exists(APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php'))
{
require APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php';
@@ -253,23 +256,22 @@
* Security check
* ------------------------------------------------------
*
- * None of the functions in the app controller or the
+ * None of the methods in the app controller or the
* loader class can be called via the URI, nor can
- * controller functions that begin with an underscore
+ * controller functions that begin with an underscore.
*/
$class = $RTR->fetch_class();
$method = $RTR->fetch_method();
- if ( ! class_exists($class)
- OR strpos($method, '_') === 0
- OR in_array(strtolower($method), array_map('strtolower', get_class_methods('CI_Controller')))
- )
+ if ( ! class_exists($class) OR $method[0] === '_' OR method_exists('CI_Controller', $method))
{
if ( ! empty($RTR->routes['404_override']))
{
- $x = explode('/', $RTR->routes['404_override'], 2);
- $class = $x[0];
- $method = isset($x[1]) ? $x[1] : 'index';
+ if (sscanf($RTR->routes['404_override'], '%[^/]/%s', $class, $method) !== 2)
+ {
+ $method = 'index';
+ }
+
if ( ! class_exists($class))
{
if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
@@ -286,6 +288,38 @@
}
}
+ if (method_exists($class, '_remap'))
+ {
+ $params = array($method, array_slice($URI->rsegments, 2));
+ $method = '_remap';
+ }
+ else
+ {
+ if ( ! is_callable(array($class, $method)))
+ {
+ if (empty($RTR->routes['404_override']))
+ {
+ show_404($class.'/'.$method);
+ }
+ elseif (sscanf($RTR->routes['404_override'], '%[^/]/%s', $class, $method) !== 2)
+ {
+ $method = 'index';
+ }
+
+ if ( ! class_exists($class))
+ {
+ if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
+ {
+ show_404($class.'/'.$method);
+ }
+
+ include_once(APPPATH.'controllers/'.$class.'.php');
+ }
+ }
+
+ $params = array_slice($URI->rsegments, 2);
+ }
+
/*
* ------------------------------------------------------
* Is there a "pre_controller" hook?
@@ -315,45 +349,7 @@
* Call the requested method
* ------------------------------------------------------
*/
- // Is there a "remap" function? If so, we call it instead
- if (method_exists($CI, '_remap'))
- {
- $CI->_remap($method, array_slice($URI->rsegments, 2));
- }
- else
- {
- // is_callable() returns TRUE on some versions of PHP 5 for private and protected
- // methods, so we'll use this workaround for consistent behavior
- if ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($CI))))
- {
- // Check and see if we are using a 404 override and use it.
- if ( ! empty($RTR->routes['404_override']))
- {
- $x = explode('/', $RTR->routes['404_override'], 2);
- $class = $x[0];
- $method = isset($x[1]) ? $x[1] : 'index';
- if ( ! class_exists($class))
- {
- if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
- {
- show_404($class.'/'.$method);
- }
-
- include_once(APPPATH.'controllers/'.$class.'.php');
- unset($CI);
- $CI = new $class();
- }
- }
- else
- {
- show_404($class.'/'.$method);
- }
- }
-
- // Call the requested method.
- // Any URI segments present (besides the class/function) will be passed to the method for convenience
- call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2));
- }
+ call_user_func_array(array(&$CI, $method), $params);
// Mark a benchmark end point
$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end');
diff --git a/system/core/Common.php b/system/core/Common.php
index 57374b07d..3b7ea6ad4 100644
--- a/system/core/Common.php
+++ b/system/core/Common.php
@@ -1,4 +1,4 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php
/**
* CodeIgniter
*
@@ -24,6 +24,7 @@
* @since Version 1.0
* @filesource
*/
+defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Common Functions
@@ -150,7 +151,7 @@ if ( ! function_exists('load_class'))
if (class_exists($name) === FALSE)
{
- require($path.$directory.'/'.$class.'.php');
+ require_once($path.$directory.'/'.$class.'.php');
}
break;
@@ -164,7 +165,7 @@ if ( ! function_exists('load_class'))
if (class_exists($name) === FALSE)
{
- require(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php');
+ require_once(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php');
}
}
@@ -330,6 +331,24 @@ if ( ! function_exists('get_mimes'))
// ------------------------------------------------------------------------
+if ( ! function_exists('is_https'))
+{
+ /**
+ * Is HTTPS?
+ *
+ * Determines if the application is accessed via an encrypted
+ * (HTTPS) connection.
+ *
+ * @return bool
+ */
+ function is_https()
+ {
+ return ( ! empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off');
+ }
+}
+
+// ------------------------------------------------------------------------
+
if ( ! function_exists('show_error'))
{
/**
@@ -488,13 +507,9 @@ if ( ! function_exists('set_status_header'))
{
header('Status: '.$code.' '.$text, TRUE);
}
- elseif ($server_protocol === 'HTTP/1.0')
- {
- header('HTTP/1.0 '.$code.' '.$text, TRUE, $code);
- }
else
{
- header('HTTP/1.1 '.$code.' '.$text, TRUE, $code);
+ header(($server_protocol ? $server_protocol : 'HTTP/1.1').' '.$code.' '.$text, TRUE, $code);
}
}
}
@@ -524,18 +539,17 @@ if ( ! function_exists('_exception_handler'))
{
$_error =& load_class('Exceptions', 'core');
- // Should we display the error? We'll get the current error_reporting
+ // Should we ignore the error? We'll get the current error_reporting
// level and add its bits with the severity bits to find out.
- // And respect display_errors
- if (($severity & error_reporting()) === $severity && (bool) ini_get('display_errors') === TRUE)
+ if (($severity & error_reporting()) !== $severity)
{
- $_error->show_php_error($severity, $message, $filepath, $line);
+ return;
}
- // Should we log the error? No? We're done...
- if (config_item('log_threshold') === 0)
+ // Should we display the error?
+ if ((bool) ini_get('display_errors') === TRUE)
{
- return;
+ $_error->show_php_error($severity, $message, $filepath, $line);
}
$_error->log_exception($severity, $message, $filepath, $line);
diff --git a/system/core/Config.php b/system/core/Config.php
index 2f6a9e085..8250b5b1a 100644
--- a/system/core/Config.php
+++ b/system/core/Config.php
@@ -1,4 +1,4 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php
/**
* CodeIgniter
*
@@ -24,9 +24,10 @@
* @since Version 1.0
* @filesource
*/
+defined('BASEPATH') OR exit('No direct script access allowed');
/**
- * CodeIgniter Config Class
+ * Config Class
*
* This class contains functions that enable config files to be managed
*
@@ -41,29 +42,31 @@ class CI_Config {
/**
* List of all loaded config values
*
- * @var array
+ * @var array
*/
public $config = array();
/**
* List of all loaded config files
*
- * @var array
+ * @var array
*/
public $is_loaded = array();
/**
* List of paths to search when trying to load a config file.
- * This must be public as it's used by the Loader class.
*
- * @var array
+ * @used-by CI_Loader
+ * @var array
*/
public $_config_paths = array(APPPATH);
/**
- * Constructor
+ * Class constructor
*
- * Sets the $config data from the primary config.php file as a class variable
+ * Sets the $config data from the primary config.php file as a class variable.
+ *
+ * @return void
*/
public function __construct()
{
@@ -75,7 +78,7 @@ class CI_Config {
{
if (isset($_SERVER['HTTP_HOST']))
{
- $base_url = ( ! empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') ? 'https' : 'http';
+ $base_url = is_https() ? 'https' : 'http';
$base_url .= '://'.$_SERVER['HTTP_HOST']
.str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']);
}
@@ -93,16 +96,16 @@ class CI_Config {
/**
* Load Config File
*
- * @param string the config file name
- * @param bool if configuration values should be loaded into their own section
- * @param bool true if errors should just return false, false if an error message should be displayed
- * @return bool if the file was loaded correctly
+ * @param string $file Configuration file name
+ * @param bool $use_sections Whether configuration values should be loaded into their own section
+ * @param bool $fail_gracefully Whether to just return FALSE or display an error message
+ * @return bool TRUE if the file was loaded correctly or FALSE on failure
*/
public function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
{
$file = ($file === '') ? 'config' : str_replace('.php', '', $file);
$found = $loaded = FALSE;
-
+
$check_locations = defined('ENVIRONMENT')
? array(ENVIRONMENT.'/'.$file, $file)
: array($file);
@@ -183,9 +186,9 @@ class CI_Config {
/**
* Fetch a config file item
*
- * @param string the config item name
- * @param string the index name
- * @return string
+ * @param string $item Config item name
+ * @param string $index Index name
+ * @return string|bool The configuration item or FALSE on failure
*/
public function item($item, $index = '')
{
@@ -200,10 +203,10 @@ class CI_Config {
// --------------------------------------------------------------------
/**
- * Fetch a config file item - adds slash after item (if item is not empty)
+ * Fetch a config file item with slash appended (if not empty)
*
- * @param string the config item name
- * @return string
+ * @param string $item Config item name
+ * @return string|bool The configuration item or FALSE on failure
*/
public function slash_item($item)
{
@@ -223,9 +226,12 @@ class CI_Config {
/**
* Site URL
+ *
* Returns base_url . index_page [. uri_string]
*
- * @param mixed the URI string or an array of segments
+ * @uses CI_Config::_uri_string()
+ *
+ * @param string|string[] $uri URI string or an array of segments
* @return string
*/
public function site_url($uri = '')
@@ -264,9 +270,12 @@ class CI_Config {
/**
* Base URL
+ *
* Returns base_url [. uri_string]
*
- * @param string $uri
+ * @uses CI_Config::_uri_string()
+ *
+ * @param string|string[] $uri URI string or an array of segments
* @return string
*/
public function base_url($uri = '')
@@ -277,9 +286,12 @@ class CI_Config {
// -------------------------------------------------------------
/**
- * Build URI string for use in Config::site_url() and Config::base_url()
+ * Build URI string
*
- * @param mixed $uri
+ * @used-by CI_Config::site_url()
+ * @used-by CI_Config::base_url()
+ *
+ * @param string|string[] $uri URI string or an array of segments
* @return string
*/
protected function _uri_string($uri)
@@ -318,8 +330,8 @@ class CI_Config {
/**
* Set a config file item
*
- * @param string the config item key
- * @param string the config item value
+ * @param string $item Config item key
+ * @param string $value Config item value
* @return void
*/
public function set_item($item, $value)
@@ -327,29 +339,6 @@ class CI_Config {
$this->config[$item] = $value;
}
- // --------------------------------------------------------------------
-
- /**
- * Assign to Config
- *
- * This function is called by the front controller (CodeIgniter.php)
- * after the Config class is instantiated. It permits config items
- * to be assigned or overriden by variables contained in the index.php file
- *
- * @param array
- * @return void
- */
- public function _assign_to_config($items = array())
- {
- if (is_array($items))
- {
- foreach ($items as $key => $val)
- {
- $this->set_item($key, $val);
- }
- }
- }
-
}
/* End of file Config.php */
diff --git a/system/core/Controller.php b/system/core/Controller.php
index 491414807..ee6fec8d5 100644
--- a/system/core/Controller.php
+++ b/system/core/Controller.php
@@ -1,4 +1,4 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php
/**
* CodeIgniter
*
@@ -24,9 +24,10 @@
* @since Version 1.0
* @filesource
*/
+defined('BASEPATH') OR exit('No direct script access allowed');
/**
- * CodeIgniter Application Controller Class
+ * Application Controller Class
*
* This class object is the super class that every library in
* CodeIgniter will be assigned to.
@@ -40,14 +41,14 @@
class CI_Controller {
/**
- * Reference to the global CI instance
+ * Reference to the CI singleton
*
* @var object
*/
private static $instance;
/**
- * Set up controller properties and methods
+ * Class constructor
*
* @return void
*/
@@ -68,9 +69,12 @@ class CI_Controller {
log_message('debug', 'Controller Class Initialized');
}
+ // --------------------------------------------------------------------
+
/**
- * Return the CI object
+ * Get the CI singleton
*
+ * @static
* @return object
*/
public static function &get_instance()
diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php
index bd9178dbd..ced65ece4 100644
--- a/system/core/Exceptions.php
+++ b/system/core/Exceptions.php
@@ -1,4 +1,4 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php
/**
* CodeIgniter
*
@@ -24,6 +24,7 @@
* @since Version 1.0
* @filesource
*/
+defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Exceptions Class
@@ -64,7 +65,7 @@ class CI_Exceptions {
);
/**
- * Initialize execption class
+ * Class constructor
*
* @return void
*/
@@ -79,12 +80,12 @@ class CI_Exceptions {
/**
* Exception Logger
*
- * This function logs PHP generated error messages
+ * Logs PHP generated error messages
*
- * @param string the error severity
- * @param string the error string
- * @param string the error filepath
- * @param string the error line number
+ * @param int $severity Log level
+ * @param string $message Error message
+ * @param string $filepath File path
+ * @param int $line Line number
* @return void
*/
public function log_exception($severity, $message, $filepath, $line)
@@ -96,11 +97,13 @@ class CI_Exceptions {
// --------------------------------------------------------------------
/**
- * 404 Page Not Found Handler
+ * 404 Error Handler
*
- * @param string the page
- * @param bool log error yes/no
- * @return string
+ * @uses CI_Exceptions::show_error()
+ *
+ * @param string $page Page URI
+ * @param bool $log_error Whether to log the error
+ * @return void
*/
public function show_404($page = '', $log_error = TRUE)
{
@@ -122,15 +125,15 @@ class CI_Exceptions {
/**
* General Error Page
*
- * This function takes an error message as input
- * (either as a string or an array) and displays
- * it using the specified template.
+ * Takes an error message as input (either as a string or an array)
+ * and displays it using the specified template.
+ *
+ * @param string $heading Page heading
+ * @param string|string[] $message Error message
+ * @param string $template Template name
+ * @param int $status_code (default: 500)
*
- * @param string the heading
- * @param string the message
- * @param string the template name
- * @param int the status code
- * @return string
+ * @return string Error page output
*/
public function show_error($heading, $message, $template = 'error_general', $status_code = 500)
{
@@ -154,11 +157,11 @@ class CI_Exceptions {
/**
* Native PHP error handler
*
- * @param string the error severity
- * @param string the error string
- * @param string the error filepath
- * @param string the error line number
- * @return string
+ * @param int $severity Error level
+ * @param string $message Error message
+ * @param string $filepath File path
+ * @param int $line Line number
+ * @return string Error page output
*/
public function show_php_error($severity, $message, $filepath, $line)
{
diff --git a/system/core/Hooks.php b/system/core/Hooks.php
index afbf4b453..3c28ec9ba 100644
--- a/system/core/Hooks.php
+++ b/system/core/Hooks.php
@@ -1,4 +1,4 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php
/**
* CodeIgniter
*
@@ -24,9 +24,10 @@
* @since Version 1.0
* @filesource
*/
+defined('BASEPATH') OR exit('No direct script access allowed');
/**
- * CodeIgniter Hooks Class
+ * Hooks Class
*
* Provides a mechanism to extend the base system without hacking.
*
@@ -41,26 +42,28 @@ class CI_Hooks {
/**
* Determines whether hooks are enabled
*
- * @var bool
+ * @var bool
*/
- public $enabled = FALSE;
+ public $enabled = FALSE;
/**
* List of all hooks set in config/hooks.php
*
- * @var array
+ * @var array
*/
public $hooks = array();
/**
+ * In progress flag
+ *
* Determines whether hook is in progress, used to prevent infinte loops
*
- * @var bool
+ * @var bool
*/
- public $in_progress = FALSE;
+ protected $_in_progress = FALSE;
/**
- * Initialize the Hooks Preferences
+ * Class constructor
*
* @return void
*/
@@ -104,8 +107,10 @@ class CI_Hooks {
*
* Calls a particular hook. Called by CodeIgniter.php.
*
- * @param string the hook name
- * @return mixed
+ * @uses CI_Hooks::_run_hook()
+ *
+ * @param string $which Hook name
+ * @return bool TRUE on success or FALSE on failure
*/
public function call_hook($which = '')
{
@@ -136,8 +141,8 @@ class CI_Hooks {
*
* Runs a particular hook
*
- * @param array the hook details
- * @return bool
+ * @param array $data Hook details
+ * @return bool TRUE on success or FALSE on failure
*/
protected function _run_hook($data)
{
@@ -152,7 +157,7 @@ class CI_Hooks {
// If the script being called happens to have the same
// hook call within it a loop can happen
- if ($this->in_progress === TRUE)
+ if ($this->_in_progress === TRUE)
{
return;
}
@@ -173,44 +178,20 @@ class CI_Hooks {
return FALSE;
}
- // -----------------------------------
- // Set class/function name
- // -----------------------------------
-
- $class = FALSE;
- $function = FALSE;
- $params = '';
-
- if ( ! empty($data['class']))
- {
- $class = $data['class'];
- }
-
- if ( ! empty($data['function']))
- {
- $function = $data['function'];
- }
-
- if (isset($data['params']))
- {
- $params = $data['params'];
- }
+ // Determine and class and/or function names
+ $class = empty($data['class']) ? FALSE : $data['class'];
+ $function = empty($data['function']) ? FALSE : $data['function'];
+ $params = isset($data['params']) ? $data['params'] : '';
if ($class === FALSE && $function === FALSE)
{
return FALSE;
}
- // -----------------------------------
- // Set the in_progress flag
- // -----------------------------------
-
- $this->in_progress = TRUE;
+ // Set the _in_progress flag
+ $this->_in_progress = TRUE;
- // -----------------------------------
// Call the requested class and/or function
- // -----------------------------------
-
if ($class !== FALSE)
{
if ( ! class_exists($class))
@@ -218,7 +199,7 @@ class CI_Hooks {
require($filepath);
}
- $HOOK = new $class;
+ $HOOK = new $class();
$HOOK->$function($params);
}
else
@@ -231,7 +212,7 @@ class CI_Hooks {
$function($params);
}
- $this->in_progress = FALSE;
+ $this->_in_progress = FALSE;
return TRUE;
}
diff --git a/system/core/Input.php b/system/core/Input.php
index d7bfed3f8..c0158df99 100644
--- a/system/core/Input.php
+++ b/system/core/Input.php
@@ -1,4 +1,4 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php
/**
* CodeIgniter
*
@@ -24,6 +24,7 @@
* @since Version 1.0
* @filesource
*/
+defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Input Class
@@ -41,59 +42,68 @@ class CI_Input {
/**
* IP address of the current user
*
- * @var string
+ * @var string
*/
- public $ip_address = FALSE;
+ public $ip_address = FALSE;
/**
- * user agent (web browser) being used by the current user
+ * User agent strin
*
- * @var string
+ * @var string
*/
- public $user_agent = FALSE;
+ public $user_agent = FALSE;
/**
- * If FALSE, then $_GET will be set to an empty array
+ * Allow GET array flag
*
- * @var bool
+ * If set to FALSE, then $_GET will be set to an empty array.
+ *
+ * @var bool
*/
- protected $_allow_get_array = TRUE;
+ protected $_allow_get_array = TRUE;
/**
- * If TRUE, then newlines are standardized
+ * Standartize new lines flag
+ *
+ * If set to TRUE, then newlines are standardized.
*
- * @var bool
+ * @var bool
*/
- protected $_standardize_newlines = TRUE;
+ protected $_standardize_newlines = TRUE;
/**
- * Determines whether the XSS filter is always active when GET, POST or COOKIE data is encountered
- * Set automatically based on config setting
+ * Enable XSS flag
+ *
+ * Determines whether the XSS filter is always active when
+ * GET, POST or COOKIE data is encountered.
+ * Set automatically based on config setting.
*
- * @var bool
+ * @var bool
*/
- protected $_enable_xss = FALSE;
+ protected $_enable_xss = FALSE;
/**
+ * Enable CSRF flag
+ *
* Enables a CSRF cookie token to be set.
- * Set automatically based on config setting
+ * Set automatically based on config setting.
*
- * @var bool
+ * @var bool
*/
- protected $_enable_csrf = FALSE;
+ protected $_enable_csrf = FALSE;
/**
* List of all HTTP request headers
*
* @var array
*/
- protected $headers = array();
+ protected $headers = array();
/**
- * Constructor
+ * Class constructor
*
- * Sets whether to globally enable the XSS processing
- * and whether to allow the $_GET array
+ * Determines whether to globally enable the XSS processing
+ * and whether to allow the $_GET array.
*
* @return void
*/
@@ -124,12 +134,12 @@ class CI_Input {
/**
* Fetch from array
*
- * This is a helper function to retrieve values from global arrays
+ * Internal method used to retrieve values from global arrays.
*
- * @param array
- * @param string
- * @param bool
- * @return string
+ * @param array &$array $_GET, $_POST, $_COOKIE, $_SERVER, etc.
+ * @param string $index Index for item to be fetched from $array
+ * @param bool $xss_clean Whether to apply XSS filtering
+ * @return mixed
*/
protected function _fetch_from_array(&$array, $index = '', $xss_clean = FALSE)
{
@@ -151,9 +161,9 @@ class CI_Input {
/**
* Fetch an item from the GET array
*
- * @param string
- * @param bool
- * @return string
+ * @param string $index Index for item to be fetched from $_GET
+ * @param bool $xss_clean Whether to apply XSS filtering
+ * @return mixed
*/
public function get($index = NULL, $xss_clean = FALSE)
{
@@ -178,9 +188,9 @@ class CI_Input {
/**
* Fetch an item from the POST array
*
- * @param string
- * @param bool
- * @return string
+ * @param string $index Index for item to be fetched from $_POST
+ * @param bool $xss_clean Whether to apply XSS filtering
+ * @return mixed
*/
public function post($index = NULL, $xss_clean = FALSE)
{
@@ -200,15 +210,14 @@ class CI_Input {
return $this->_fetch_from_array($_POST, $index, $xss_clean);
}
-
// --------------------------------------------------------------------
/**
- * Fetch an item from either the GET array or the POST
+ * Fetch an item from POST data with fallback to GET
*
- * @param string The index key
- * @param bool XSS cleaning
- * @return string
+ * @param string $index Index for item to be fetched from $_POST or $_GET
+ * @param bool $xss_clean Whether to apply XSS filtering
+ * @return mixed
*/
public function get_post($index = '', $xss_clean = FALSE)
{
@@ -222,31 +231,45 @@ class CI_Input {
/**
* Fetch an item from the COOKIE array
*
- * @param string
- * @param bool
- * @return string
+ * @param string $index Index for item to be fetched from $_COOKIE
+ * @param bool $xss_clean Whether to apply XSS filtering
+ * @return mixed
*/
public function cookie($index = '', $xss_clean = FALSE)
{
return $this->_fetch_from_array($_COOKIE, $index, $xss_clean);
}
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch an item from the SERVER array
+ *
+ * @param string $index Index for item to be fetched from $_SERVER
+ * @param bool $xss_clean Whether to apply XSS filtering
+ * @return mixed
+ */
+ public function server($index = '', $xss_clean = FALSE)
+ {
+ return $this->_fetch_from_array($_SERVER, $index, $xss_clean);
+ }
+
// ------------------------------------------------------------------------
/**
* Set cookie
*
- * Accepts seven parameters, or you can submit an associative
+ * Accepts an arbitrary number of parameters (up to 7) or an associative
* array in the first parameter containing all the values.
*
- * @param mixed
- * @param string the value of the cookie
- * @param string the number of seconds until expiration
- * @param string the cookie domain. Usually: .yourdomain.com
- * @param string the cookie path
- * @param string the cookie prefix
- * @param bool true makes the cookie secure
- * @param bool true makes the cookie accessible via http(s) only (no javascript)
+ * @param string|mixed[] $name Cookie name or an array containing parameters
+ * @param string $value Cookie value
+ * @param int $expire Cookie expiration time in seconds
+ * @param string $domain Cookie domain (e.g.: '.yourdomain.com')
+ * @param string $path Cookie path (default: '/')
+ * @param string $prefix Cookie name prefix
+ * @param bool $secure Whether to only transfer cookies via SSL
+ * @param bool $httponly Whether to only makes the cookie accessible via HTTP (no javascript)
* @return void
*/
public function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE)
@@ -303,23 +326,11 @@ class CI_Input {
// --------------------------------------------------------------------
/**
- * Fetch an item from the SERVER array
- *
- * @param string
- * @param bool
- * @return string
- */
- public function server($index = '', $xss_clean = FALSE)
- {
- return $this->_fetch_from_array($_SERVER, $index, $xss_clean);
- }
-
- // --------------------------------------------------------------------
-
- /**
* Fetch the IP Address
*
- * @return string
+ * Determines and validates the visitor's IP address.
+ *
+ * @return string IP address
*/
public function ip_address()
{
@@ -328,62 +339,117 @@ class CI_Input {
return $this->ip_address;
}
- if (config_item('proxy_ips') != '' && $this->server('HTTP_X_FORWARDED_FOR') && $this->server('REMOTE_ADDR'))
+ $proxy_ips = config_item('proxy_ips');
+ if ( ! empty($proxy_ips) && ! is_array($proxy_ips))
{
- $has_ranges = strpos($proxies, '/') !== false;
- $proxies = preg_split('/[\s,]/', config_item('proxy_ips'), -1, PREG_SPLIT_NO_EMPTY);
- $proxies = is_array($proxies) ? $proxies : array($proxies);
-
- if ($has_ranges)
- {
- $long_ip = ip2long($_SERVER['REMOTE_ADDR']);
- $bit_32 = 1 << 32;
+ $proxy_ips = explode(',', str_replace(' ', '', $proxy_ips));
+ }
+
+ $this->ip_address = $this->server('REMOTE_ADDR');
- // Go through each of the IP Addresses to check for and
- // test against range notation
- foreach($proxies as $ip)
+ if ($proxy_ips)
+ {
+ foreach (array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_X_CLIENT_IP', 'HTTP_X_CLUSTER_CLIENT_IP') as $header)
+ {
+ if (($spoof = $this->server($header)) !== NULL)
{
- list($address, $mask_length) = explode('/', $ip);
+ // Some proxies typically list the whole chain of IP
+ // addresses through which the client has reached us.
+ // e.g. client_ip, proxy_ip1, proxy_ip2, etc.
+ sscanf($spoof, '%[^,]', $spoof);
- // Generate the bitmask for a 32 bit IP Address
- $bitmask = $bit_32 - (1 << (32 - (int)$mask_length));
- if (($long_ip & $bitmask) == $address)
+ if ( ! $this->valid_ip($spoof))
+ {
+ $spoof = NULL;
+ }
+ else
{
- $this->ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
break;
}
}
-
- } else {
- $this->ip_address = in_array($_SERVER['REMOTE_ADDR'], $proxies) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
}
- }
- elseif ( ! $this->server('HTTP_CLIENT_IP') && $this->server('REMOTE_ADDR'))
- {
- $this->ip_address = $_SERVER['REMOTE_ADDR'];
- }
- elseif ($this->server('REMOTE_ADDR') && $this->server('HTTP_CLIENT_IP'))
- {
- $this->ip_address = $_SERVER['HTTP_CLIENT_IP'];
- }
- elseif ($this->server('HTTP_CLIENT_IP'))
- {
- $this->ip_address = $_SERVER['HTTP_CLIENT_IP'];
- }
- elseif ($this->server('HTTP_X_FORWARDED_FOR'))
- {
- $this->ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
- }
- if ($this->ip_address === FALSE)
- {
- return $this->ip_address = '0.0.0.0';
- }
+ if ($spoof)
+ {
+ for ($i = 0, $c = count($proxy_ips); $i < $c; $i++)
+ {
+ // Check if we have an IP address or a subnet
+ if (strpos($proxy_ips[$i], '/') === FALSE)
+ {
+ // An IP address (and not a subnet) is specified.
+ // We can compare right away.
+ if ($proxy_ips[$i] === $this->ip_address)
+ {
+ $this->ip_address = $spoof;
+ break;
+ }
+
+ continue;
+ }
- if (strpos($this->ip_address, ',') !== FALSE)
- {
- $x = explode(',', $this->ip_address);
- $this->ip_address = trim(end($x));
+ // We have a subnet ... now the heavy lifting begins
+ isset($separator) OR $separator = $this->valid_ip($this->ip_address, 'ipv6') ? ':' : '.';
+
+ // If the proxy entry doesn't match the IP protocol - skip it
+ if (strpos($proxy_ips[$i], $separator) === FALSE)
+ {
+ continue;
+ }
+
+ // Convert the REMOTE_ADDR IP address to binary, if needed
+ if ( ! isset($ip, $sprintf))
+ {
+ if ($separator === ':')
+ {
+ // Make sure we're have the "full" IPv6 format
+ $ip = explode(':',
+ str_replace('::',
+ str_repeat(':', 9 - substr_count($this->ip_address, ':')),
+ $this->ip_address
+ )
+ );
+
+ for ($i = 0; $i < 8; $i++)
+ {
+ $ip[$i] = intval($ip[$i], 16);
+ }
+
+ $sprintf = '%016b%016b%016b%016b%016b%016b%016b%016b';
+ }
+ else
+ {
+ $ip = explode('.', $this->ip_address);
+ $sprintf = '%08b%08b%08b%08b';
+ }
+
+ $ip = vsprintf($sprintf, $ip);
+ }
+
+ // Split the netmask length off the network address
+ sscanf($proxy_ips[$i], '%[^/]/%d', $netaddr, $masklen);
+
+ // Again, an IPv6 address is most likely in a compressed form
+ if ($separator === ':')
+ {
+ $netaddr = explode(':', str_replace('::', str_repeat(':', 9 - substr_count($netaddr, ':')), $netaddr));
+ for ($i = 0; $i < 8; $i++)
+ {
+ $netaddr[$i] = intval($netaddr[$i], 16);
+ }
+ }
+ else
+ {
+ $netaddr = explode('.', $netaddr);
+ }
+
+ // Convert to binary and finally compare
+ if (strncmp($ip, vsprintf($sprintf, $netaddr), $masklen) === 0)
+ {
+ $this->ip_address = $spoof;
+ break;
+ }
+ }
+ }
}
if ( ! $this->valid_ip($this->ip_address))
@@ -399,8 +465,8 @@ class CI_Input {
/**
* Validate IP Address
*
- * @param string
- * @param string 'ipv4' or 'ipv6'
+ * @param string $ip IP address
+ * @param string $which IP protocol: 'ipv4' or 'ipv6'
* @return bool
*/
public function valid_ip($ip, $which = '')
@@ -424,9 +490,9 @@ class CI_Input {
// --------------------------------------------------------------------
/**
- * User Agent
+ * Fetch User Agent string
*
- * @return string
+ * @return string|null User Agent string or NULL if it doesn't exist
*/
public function user_agent()
{
@@ -435,7 +501,7 @@ class CI_Input {
return $this->user_agent;
}
- return $this->user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : FALSE;
+ return $this->user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : NULL;
}
// --------------------------------------------------------------------
@@ -443,11 +509,12 @@ class CI_Input {
/**
* Sanitize Globals
*
- * This function does the following:
+ * Internal method serving for the following purposes:
*
- * - Unsets $_GET data (if query strings are not enabled)
- * - Unsets all globals if register_globals is enabled
- * - Standardizes newline characters to \n
+ * - Unsets $_GET data (if query strings are not enabled)
+ * - Unsets all globals if register_globals is enabled
+ * - Cleans POST, COOKIE and SERVER data
+ * - Standardizes newline characters to PHP_EOL
*
* @return void
*/
@@ -475,25 +542,29 @@ class CI_Input {
'IN'
);
- // Unset globals for securiy.
+ // Unset globals for security.
// This is effectively the same as register_globals = off
- foreach (array($_GET, $_POST, $_COOKIE) as $global)
+ // PHP 5.4 no longer has the register_globals functionality.
+ if ( ! is_php('5.4'))
{
- if (is_array($global))
+ foreach (array($_GET, $_POST, $_COOKIE) as $global)
{
- foreach ($global as $key => $val)
+ if (is_array($global))
{
- if ( ! in_array($key, $protected))
+ foreach ($global as $key => $val)
{
- global $$key;
- $$key = NULL;
+ if ( ! in_array($key, $protected))
+ {
+ global $$key;
+ $$key = NULL;
+ }
}
}
- }
- elseif ( ! in_array($global, $protected))
- {
- global $$global;
- $$global = NULL;
+ elseif ( ! in_array($global, $protected))
+ {
+ global $$global;
+ $$global = NULL;
+ }
}
}
@@ -541,7 +612,7 @@ class CI_Input {
$_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']);
// CSRF Protection check
- if ($this->_enable_csrf === TRUE)
+ if ($this->_enable_csrf === TRUE && ! $this->is_cli_request())
{
$this->security->csrf_verify();
}
@@ -554,10 +625,10 @@ class CI_Input {
/**
* Clean Input Data
*
- * This is a helper function. It escapes data and
- * standardizes newline characters to \n
+ * Internal method that aids in escaping data and
+ * standardizing newline characters to PHP_EOL.
*
- * @param string
+ * @param string|string[] $str Input string(s)
* @return string
*/
protected function _clean_input_data($str)
@@ -565,9 +636,9 @@ class CI_Input {
if (is_array($str))
{
$new_array = array();
- foreach ($str as $key => $val)
+ foreach (array_keys($str) as $key)
{
- $new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
+ $new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($str[$key]);
}
return $new_array;
}
@@ -611,11 +682,11 @@ class CI_Input {
/**
* Clean Keys
*
- * This is a helper function. To prevent malicious users
+ * Internal method that helps to prevent malicious users
* from trying to exploit keys we make sure that keys are
* only named with alpha-numeric text and a few other items.
*
- * @param string
+ * @param string $str Input string
* @return string
*/
protected function _clean_input_keys($str)
@@ -640,15 +711,12 @@ class CI_Input {
/**
* Request Headers
*
- * In Apache, you can simply call apache_request_headers(), however for
- * people running other webservers the function is undefined.
- *
- * @param bool XSS cleaning
+ * @param bool $xss_clean Whether to apply XSS filtering
* @return array
*/
public function request_headers($xss_clean = FALSE)
{
- // Look at Apache go!
+ // In Apache, you can simply call apache_request_headers()
if (function_exists('apache_request_headers'))
{
$headers = apache_request_headers();
@@ -685,9 +753,9 @@ class CI_Input {
*
* Returns the value of a single member of the headers class member
*
- * @param string array key for $this->headers
- * @param bool XSS Clean or not
- * @return mixed FALSE on failure, string on success
+ * @param string $index Header name
+ * @param bool $xss_clean Whether to apply XSS filtering
+ * @return string|bool The requested header on success or FALSE on failure
*/
public function get_request_header($index, $xss_clean = FALSE)
{
@@ -709,9 +777,9 @@ class CI_Input {
// --------------------------------------------------------------------
/**
- * Is ajax Request?
+ * Is AJAX request?
*
- * Test to see if a request contains the HTTP_X_REQUESTED_WITH header
+ * Test to see if a request contains the HTTP_X_REQUESTED_WITH header.
*
* @return bool
*/
@@ -723,9 +791,9 @@ class CI_Input {
// --------------------------------------------------------------------
/**
- * Is cli Request?
+ * Is CLI request?
*
- * Test to see if a request was made from the command line
+ * Test to see if a request was made from the command line.
*
* @return bool
*/
@@ -739,10 +807,11 @@ class CI_Input {
/**
* Get Request Method
*
- * Return the Request Method
+ * Return the request method
*
- * @param bool uppercase or lowercase
- * @return bool
+ * @param bool $upper Whether to return in upper or lower case
+ * (default: FALSE)
+ * @return string
*/
public function method($upper = FALSE)
{
diff --git a/system/core/Lang.php b/system/core/Lang.php
index 3001f1b13..896385134 100644
--- a/system/core/Lang.php
+++ b/system/core/Lang.php
@@ -1,4 +1,4 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php
/**
* CodeIgniter
*
@@ -24,6 +24,7 @@
* @since Version 1.0
* @filesource
*/
+defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Language Class
@@ -39,19 +40,19 @@ class CI_Lang {
/**
* List of translations
*
- * @var array
+ * @var array
*/
public $language = array();
/**
* List of loaded language files
*
- * @var array
+ * @var array
*/
public $is_loaded = array();
/**
- * Initialize language class
+ * Class constructor
*
* @return void
*/
@@ -65,12 +66,13 @@ class CI_Lang {
/**
* Load a language file
*
- * @param mixed the name of the language file to be loaded
- * @param string the language (english, etc.)
- * @param bool return loaded array of translations
- * @param bool add suffix to $langfile
- * @param string alternative path to look for language file
- * @return mixed
+ * @param mixed $langfile Language file name
+ * @param string $idiom Language name (english, etc.)
+ * @param bool $return Whether to return the loaded array of translations
+ * @param bool $add_suffix Whether to add suffix to $langfile
+ * @param string $alt_path Alternative path to look for the language file
+ *
+ * @return void|string[] Array containing translations, if $return is set to TRUE
*/
public function load($langfile, $idiom = '', $return = FALSE, $add_suffix = TRUE, $alt_path = '')
{
@@ -83,10 +85,10 @@ class CI_Lang {
$langfile .= '.php';
- if ($idiom === '')
+ if (empty($idiom) OR ! ctype_alpha($idiom))
{
$config =& get_config();
- $idiom = ( ! empty($config['language'])) ? $config['language'] : 'english';
+ $idiom = empty($config['language']) ? 'english' : $config['language'];
}
if ($return === FALSE && isset($this->is_loaded[$langfile]) && $this->is_loaded[$langfile] === $idiom)
@@ -119,7 +121,6 @@ class CI_Lang {
}
}
-
if ( ! isset($lang) OR ! is_array($lang))
{
log_message('error', 'Language file contains no data: language/'.$idiom.'/'.$langfile);
@@ -146,10 +147,12 @@ class CI_Lang {
// --------------------------------------------------------------------
/**
- * Fetch a single line of text from the language array
+ * Language line
+ *
+ * Fetches a single line of text from the language array
*
- * @param string $line the language line
- * @return string
+ * @param string $line Language line key
+ * @return string Translation
*/
public function line($line = '')
{
diff --git a/system/core/Loader.php b/system/core/Loader.php
index 0bc6e844a..88fbdb6e1 100644
--- a/system/core/Loader.php
+++ b/system/core/Loader.php
@@ -1,4 +1,4 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php
/**
* CodeIgniter
*
@@ -24,11 +24,12 @@
* @since Version 1.0
* @filesource
*/
+defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Loader Class
*
- * Loads views and files
+ * Loads framework components.
*
* @package CodeIgniter
* @subpackage Libraries
@@ -42,84 +43,84 @@ class CI_Loader {
/**
* Nesting level of the output buffering mechanism
*
- * @var int
+ * @var int
*/
protected $_ci_ob_level;
/**
* List of paths to load views from
*
- * @var array
+ * @var array
*/
protected $_ci_view_paths = array();
/**
* List of paths to load libraries from
*
- * @var array
+ * @var array
*/
protected $_ci_library_paths = array();
/**
* List of paths to load models from
*
- * @var array
+ * @var array
*/
protected $_ci_model_paths = array();
/**
* List of paths to load helpers from
*
- * @var array
+ * @var array
*/
protected $_ci_helper_paths = array();
/**
* List of loaded base classes
*
- * @var array
+ * @var array
*/
protected $_base_classes = array(); // Set by the controller class
/**
* List of cached variables
*
- * @var array
+ * @var array
*/
protected $_ci_cached_vars = array();
/**
* List of loaded classes
*
- * @var array
+ * @var array
*/
protected $_ci_classes = array();
/**
* List of loaded files
*
- * @var array
+ * @var array
*/
protected $_ci_loaded_files = array();
/**
* List of loaded models
*
- * @var array
+ * @var array
*/
protected $_ci_models = array();
/**
* List of loaded helpers
*
- * @var array
+ * @var array
*/
protected $_ci_helpers = array();
/**
* List of class name mappings
*
- * @var array
+ * @var array
*/
protected $_ci_varmap = array(
'unit_test' => 'unit',
@@ -127,9 +128,9 @@ class CI_Loader {
);
/**
- * Constructor
+ * Class constructor
*
- * Sets the path to the view files and gets the initial output buffering level
+ * Sets component load paths, gets the initial output buffering level.
*
* @return void
*/
@@ -147,21 +148,18 @@ class CI_Loader {
// --------------------------------------------------------------------
/**
- * Initialize the Loader
+ * Initializer
*
- * This method is called once in CI_Controller.
- *
- * @return object
+ * @todo Figure out a way to move this to the constructor
+ * without breaking *package_path*() methods.
+ * @uses CI_Loader::_ci_autoloader()
+ * @used-by CI_Controller::__construct()
+ * @return void
*/
public function initialize()
{
- $this->_ci_classes = array();
- $this->_ci_loaded_files = array();
- $this->_ci_models = array();
$this->_base_classes =& is_loaded();
-
$this->_ci_autoloader();
- return $this;
}
// --------------------------------------------------------------------
@@ -169,14 +167,12 @@ class CI_Loader {
/**
* Is Loaded
*
- * A utility function to test if a class is in the self::$_ci_classes array.
- * This function returns the object name if the class tested for is loaded,
- * and returns FALSE if it isn't.
+ * A utility method to test if a class is in the self::$_ci_classes array.
*
- * It is mainly used in the form_helper -> _get_validation_object()
+ * @used-by Mainly used by Form Helper function _get_validation_object().
*
- * @param string class being checked for
- * @return mixed class object name on the CI SuperObject or FALSE
+ * @param string $class Class name to check for
+ * @return string|bool Class object name if loaded or FALSE
*/
public function is_loaded($class)
{
@@ -186,14 +182,14 @@ class CI_Loader {
// --------------------------------------------------------------------
/**
- * Class Loader
+ * Library Loader
*
- * This function lets users load and instantiate classes.
- * It is designed to be called from a user's app controllers.
+ * Loads and instantiates libraries.
+ * Designed to be called from application controllers.
*
- * @param string the name of the class
- * @param mixed the optional parameters
- * @param string an optional object name
+ * @param string $library Library name
+ * @param array $params Optional parameters to pass to the library class constructor
+ * @param string $object_name An optional object name to assign to
* @return void
*/
public function library($library = '', $params = NULL, $object_name = NULL)
@@ -210,7 +206,7 @@ class CI_Loader {
if ($library === '' OR isset($this->_base_classes[$library]))
{
- return FALSE;
+ return;
}
if ( ! is_null($params) && ! is_array($params))
@@ -226,16 +222,20 @@ class CI_Loader {
/**
* Model Loader
*
- * This function lets users load and instantiate models.
+ * Loads and instantiates libraries.
*
- * @param string the name of the class
- * @param string name for the model
- * @param bool database connection
+ * @param string $model Model name
+ * @param string $name An optional object name to assign to
+ * @param bool $db_conn An optional database connection configuration to initialize
* @return void
*/
public function model($model, $name = '', $db_conn = FALSE)
{
- if (is_array($model))
+ if (empty($model))
+ {
+ return;
+ }
+ elseif (is_array($model))
{
foreach ($model as $class)
{
@@ -244,11 +244,6 @@ class CI_Loader {
return;
}
- if ($model === '')
- {
- return;
- }
-
$path = '';
// Is the model in a sub-folder? If so, parse out the filename and path.
@@ -318,10 +313,13 @@ class CI_Loader {
/**
* Database Loader
*
- * @param string the DB credentials
- * @param bool whether to return the DB object
- * @param bool whether to enable query builder (this allows us to override the config setting)
- * @return object
+ * @param mixed $params Database configuration options
+ * @param bool $return Whether to return the database object
+ * @param bool $query_builder Whether to enable Query Builder
+ * (overrides the configuration setting)
+ *
+ * @return void|object|bool Database object if $return is set to TRUE,
+ * FALSE on failure, void in any other case
*/
public function database($params = '', $return = FALSE, $query_builder = NULL)
{
@@ -329,7 +327,7 @@ class CI_Loader {
$CI =& get_instance();
// Do we even need to load the database class?
- if (class_exists('CI_DB') && $return === FALSE && $query_builder === NULL && isset($CI->db) && is_object($CI->db))
+ if ($return === FALSE && $query_builder === NULL && isset($CI->db) && is_object($CI->db) && ! empty($CI->db->conn_id))
{
return FALSE;
}
@@ -352,9 +350,9 @@ class CI_Loader {
// --------------------------------------------------------------------
/**
- * Load the Utilities Class
+ * Load the Database Utilities Class
*
- * @return string
+ * @return void
*/
public function dbutil()
{
@@ -381,7 +379,7 @@ class CI_Loader {
/**
* Load the Database Forge Class
*
- * @return string
+ * @return void
*/
public function dbforge()
{
@@ -402,19 +400,15 @@ class CI_Loader {
// --------------------------------------------------------------------
/**
- * Load View
+ * View Loader
*
- * This function is used to load a "view" file. It has three parameters:
+ * Loads "view" files.
*
- * 1. The name of the "view" file to be included.
- * 2. An associative array of data to be extracted for use in the view.
- * 3. TRUE/FALSE - whether to return the data or load it. In
- * some cases it's advantageous to be able to return data so that
- * a developer can process it in some way.
- *
- * @param string
- * @param array
- * @param bool
+ * @param string $view View name
+ * @param array $vars An associative array of data
+ * to be extracted for use in the view
+ * @param bool $return Whether to return the view output
+ * or leave it to the Output class
* @return void
*/
public function view($view, $vars = array(), $return = FALSE)
@@ -425,13 +419,11 @@ class CI_Loader {
// --------------------------------------------------------------------
/**
- * Load File
- *
- * This is a generic file loader
+ * Generic File Loader
*
- * @param string
- * @param bool
- * @return string
+ * @param string $path File path
+ * @param bool $return Whether to return the file output
+ * @return void|string
*/
public function file($path, $return = FALSE)
{
@@ -446,8 +438,10 @@ class CI_Loader {
* Once variables are set they become available within
* the controller class and its "view" files.
*
- * @param array
- * @param string
+ * @param array|object|string $vars
+ * An associative array or object containing values
+ * to be set, or a value's name if string
+ * @param string $val Value to set, only used if $vars is a string
* @return void
*/
public function vars($vars = array(), $val = '')
@@ -475,8 +469,8 @@ class CI_Loader {
*
* Check if a variable is set and retrieve it.
*
- * @param array
- * @return void
+ * @param string $key Variable name
+ * @return mixed The variable or NULL if not found
*/
public function get_var($key)
{
@@ -488,7 +482,7 @@ class CI_Loader {
/**
* Get Variables
*
- * Retrieve all loaded variables
+ * Retrieves all loaded variables.
*
* @return array
*/
@@ -500,11 +494,9 @@ class CI_Loader {
// --------------------------------------------------------------------
/**
- * Load Helper
+ * Helper Loader
*
- * This function loads the specified helper file.
- *
- * @param mixed
+ * @param string|string[] $helpers Helper name(s)
* @return void
*/
public function helper($helpers = array())
@@ -562,10 +554,11 @@ class CI_Loader {
/**
* Load Helpers
*
- * This is simply an alias to the above function in case the
- * user has written the plural form of this function.
+ * An alias for the helper() method in case the developer has
+ * written the plural form of it.
*
- * @param array
+ * @uses CI_Loader::helper()
+ * @param string|string[] $helpers Helper name(s)
* @return void
*/
public function helpers($helpers = array())
@@ -576,22 +569,21 @@ class CI_Loader {
// --------------------------------------------------------------------
/**
- * Loads a language file
+ * Language Loader
+ *
+ * Loads language files.
*
- * @param array
- * @param string
+ * @param string|string[] $files List of language file names to load
+ * @param string Language name
* @return void
*/
- public function language($file = array(), $lang = '')
+ public function language($files = array(), $lang = '')
{
$CI =& get_instance();
- if ( ! is_array($file))
- {
- $file = array($file);
- }
+ is_array($files) OR $files = array($files);
- foreach ($file as $langfile)
+ foreach ($files as $langfile)
{
$CI->lang->load($langfile, $lang);
}
@@ -600,30 +592,35 @@ class CI_Loader {
// --------------------------------------------------------------------
/**
- * Loads a config file
+ * Config Loader
*
- * @param string
- * @param bool
- * @param bool
- * @return void
+ * Loads a config file (an alias for CI_Config::load()).
+ *
+ * @uses CI_Config::load()
+ * @param string $file Configuration file name
+ * @param bool $use_sections Whether configuration values should be loaded into their own section
+ * @param bool $fail_gracefully Whether to just return FALSE or display an error message
+ * @return bool TRUE if the file was loaded correctly or FALSE on failure
*/
public function config($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
{
$CI =& get_instance();
- $CI->config->load($file, $use_sections, $fail_gracefully);
+ return $CI->config->load($file, $use_sections, $fail_gracefully);
}
// --------------------------------------------------------------------
/**
- * Driver
+ * Driver Loader
*
- * Loads a driver library
+ * Loads a driver library.
*
- * @param mixed the name of the class or array of classes
- * @param mixed the optional parameters
- * @param string an optional object name
- * @return void
+ * @param string|string[] $library Driver name(s)
+ * @param array $params Optional parameters to pass to the driver
+ * @param string $object_name An optional object name to assign to
+ *
+ * @return void|object|bool Object or FALSE on failure if $library is a string
+ * and $object_name is set. void otherwise.
*/
public function driver($library = '', $params = NULL, $object_name = NULL)
{
@@ -633,13 +630,7 @@ class CI_Loader {
{
$this->driver($driver);
}
- return FALSE;
- }
-
- if ( ! class_exists('CI_Driver_Library'))
- {
- // we aren't instantiating an object here, that'll be done by the Library itself
- require BASEPATH.'libraries/Driver.php';
+ return;
}
if ($library === '')
@@ -662,10 +653,16 @@ class CI_Loader {
/**
* Add Package Path
*
- * Prepends a parent path to the library, model, helper, and config path arrays
+ * Prepends a parent path to the library, model, helper and config
+ * path arrays.
+ *
+ * @see CI_Loader::$_ci_library_paths
+ * @see CI_Loader::$_ci_model_paths
+ * @see CI_Loader::$_ci_helper_paths
+ * @see CI_Config::$_config_paths
*
- * @param string
- * @param bool
+ * @param string $path Path to add
+ * @param bool $view_cascade (default: TRUE)
* @return void
*/
public function add_package_path($path, $view_cascade = TRUE)
@@ -688,14 +685,14 @@ class CI_Loader {
/**
* Get Package Paths
*
- * Return a list of all package paths, by default it will ignore BASEPATH.
+ * Return a list of all package paths.
*
- * @param string
- * @return void
+ * @param bool $include_base Whether to include BASEPATH (default: TRUE)
+ * @return array
*/
public function get_package_paths($include_base = FALSE)
{
- return $include_base === TRUE ? $this->_ci_library_paths : $this->_ci_model_paths;
+ return ($include_base === TRUE) ? $this->_ci_library_paths : $this->_ci_model_paths;
}
// --------------------------------------------------------------------
@@ -703,14 +700,14 @@ class CI_Loader {
/**
* Remove Package Path
*
- * Remove a path from the library, model, and helper path arrays if it exists
- * If no path is provided, the most recently added path is removed.
+ * Remove a path from the library, model, helper and/or config
+ * path arrays if it exists. If no path is provided, the most recently
+ * added path will be removed removed.
*
- * @param string
- * @param bool
+ * @param string $path Path to remove
* @return void
*/
- public function remove_package_path($path = '', $remove_config_path = TRUE)
+ public function remove_package_path($path = '')
{
$config =& $this->_ci_get_component('config');
@@ -755,13 +752,16 @@ class CI_Loader {
// --------------------------------------------------------------------
/**
- * Loader
+ * Internal CI Data Loader
+ *
+ * Used to load views and files.
*
- * This function is used to load views and files.
* Variables are prefixed with _ci_ to avoid symbol collision with
- * variables made available to view files
+ * variables made available to view files.
*
- * @param array
+ * @used-by CI_Loader::view()
+ * @used-by CI_Loader::file()
+ * @param array $_ci_data Data to load
* @return void
*/
protected function _ci_load($_ci_data)
@@ -785,11 +785,11 @@ class CI_Loader {
$_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);
$_ci_file = ($_ci_ext === '') ? $_ci_view.'.php' : $_ci_view;
- foreach ($this->_ci_view_paths as $view_file => $cascade)
+ foreach ($this->_ci_view_paths as $_ci_view_file => $cascade)
{
- if (file_exists($view_file.$_ci_file))
+ if (file_exists($_ci_view_file.$_ci_file))
{
- $_ci_path = $view_file.$_ci_file;
+ $_ci_path = $_ci_view_file.$_ci_file;
$file_exists = TRUE;
break;
}
@@ -837,10 +837,10 @@ class CI_Loader {
* We buffer the output for two reasons:
* 1. Speed. You get a significant speed boost.
* 2. So that the final rendered template can be post-processed by
- * the output class. Why do we need post processing? For one thing,
- * in order to show the elapsed page load time. Unless we can
- * intercept the content right before it's sent to the browser and
- * then stop the timer it won't be accurate.
+ * the output class. Why do we need post processing? For one thing,
+ * in order to show the elapsed page load time. Unless we can
+ * intercept the content right before it's sent to the browser and
+ * then stop the timer it won't be accurate.
*/
ob_start();
@@ -889,13 +889,14 @@ class CI_Loader {
// --------------------------------------------------------------------
/**
- * Load class
+ * Internal CI Class Loader
*
- * This function loads the requested class.
+ * @used-by CI_Loader::library()
+ * @uses CI_Loader::_ci_init_class()
*
- * @param string the item that is being loaded
- * @param mixed any additional parameters
- * @param string an optional object name
+ * @param string $class Class name to load
+ * @param mixed $params Optional parameters to pass to the class constructor
+ * @param string $object_name Optional object name to assign to
* @return void
*/
protected function _ci_load_class($class, $params = NULL, $object_name = NULL)
@@ -915,6 +916,13 @@ class CI_Loader {
// Get the filename from the path
$class = substr($class, $last_slash);
+
+ // Check for match and driver base class
+ if (strtolower(trim($subdir, '/')) == strtolower($class) && ! class_exists('CI_Driver_Library'))
+ {
+ // We aren't instantiating an object here, just making the base class available
+ require BASEPATH.'libraries/Driver.php';
+ }
}
// We'll test for both lowercase and capitalized versions of the file name
@@ -996,14 +1004,19 @@ class CI_Loader {
$this->_ci_loaded_files[] = $filepath;
return $this->_ci_init_class($class, '', $params, $object_name);
}
-
} // END FOREACH
// One last attempt. Maybe the library is in a subdirectory, but it wasn't specified?
if ($subdir === '')
{
$path = strtolower($class).'/'.$class;
- return $this->_ci_load_class($path, $params);
+ return $this->_ci_load_class($path, $params, $object_name);
+ }
+ elseif (ucfirst($subdir) != $subdir)
+ {
+ // Lowercase subdir failed - retry capitalized
+ $path = ucfirst($subdir).$class;
+ return $this->_ci_load_class($path, $params, $object_name);
}
// If we got this far we were unable to find the requested class.
@@ -1018,12 +1031,17 @@ class CI_Loader {
// --------------------------------------------------------------------
/**
- * Instantiates a class
+ * Internal CI Class Instantiator
+ *
+ * @used-by CI_Loader::_ci_load_class()
*
- * @param string
- * @param string
- * @param bool
- * @param string an optional object name
+ * @param string $class Class name
+ * @param string $prefix Class name prefix
+ * @param array|null|bool $config Optional configuration to pass to the class constructor:
+ * FALSE to skip;
+ * NULL to search in config paths;
+ * array containing configuration data
+ * @param string $object_name Optional object name to assign to
* @return void
*/
protected function _ci_init_class($class, $prefix = '', $config = FALSE, $object_name = NULL)
@@ -1125,11 +1143,11 @@ class CI_Loader {
// --------------------------------------------------------------------
/**
- * Autoloader
+ * CI Autoloader
*
- * The config/autoload.php file contains an array that permits sub-systems,
- * libraries, and helpers to be loaded automatically.
+ * Loads component listed in the config/autoload.php file.
*
+ * @used-by CI_Loader::initialize()
* @return void
*/
protected function _ci_autoloader()
@@ -1193,6 +1211,15 @@ class CI_Loader {
}
}
+ // Autoload drivers
+ if (isset($autoload['drivers']))
+ {
+ foreach ($autoload['drivers'] as $item)
+ {
+ $this->driver($item);
+ }
+ }
+
// Autoload models
if (isset($autoload['model']))
{
@@ -1203,11 +1230,12 @@ class CI_Loader {
// --------------------------------------------------------------------
/**
- * Object to Array
+ * CI Object to Array translator
*
- * Takes an object as input and converts the class variables to array key/vals
+ * Takes an object as input and converts the class variables to
+ * an associative array with key/value pairs.
*
- * @param object
+ * @param object $object Object data to translate
* @return array
*/
protected function _ci_object_to_array($object)
@@ -1218,9 +1246,11 @@ class CI_Loader {
// --------------------------------------------------------------------
/**
- * Get a reference to a specific library or model
+ * CI Component getter
+ *
+ * Get a reference to a specific library or model.
*
- * @param string
+ * @param string $component Component name
* @return bool
*/
protected function &_ci_get_component($component)
@@ -1234,10 +1264,11 @@ class CI_Loader {
/**
* Prep filename
*
- * This function preps the name of various items to make loading them more reliable.
+ * This function prepares filenames of various items to
+ * make their loading more reliable.
*
- * @param mixed
- * @param string
+ * @param string|string[] $filename Filename(s)
+ * @param string $extension Filename extension
* @return array
*/
protected function _ci_prep_filename($filename, $extension)
diff --git a/system/core/Model.php b/system/core/Model.php
index 9bc9f879f..28fdfbb69 100644
--- a/system/core/Model.php
+++ b/system/core/Model.php
@@ -1,4 +1,4 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php
/**
* CodeIgniter
*
@@ -24,9 +24,10 @@
* @since Version 1.0
* @filesource
*/
+defined('BASEPATH') OR exit('No direct script access allowed');
/**
- * CodeIgniter Model Class
+ * Model Class
*
* @package CodeIgniter
* @subpackage Libraries
@@ -37,7 +38,7 @@
class CI_Model {
/**
- * Initialize CI_Model Class
+ * Class constructor
*
* @return void
*/
@@ -46,13 +47,15 @@ class CI_Model {
log_message('debug', 'Model Class Initialized');
}
+ // --------------------------------------------------------------------
+
/**
- * __get
+ * __get magic
*
* Allows models to access CI's loaded classes using the same
* syntax as controllers.
*
- * @param string
+ * @param string $key
*/
public function __get($key)
{
diff --git a/system/core/Output.php b/system/core/Output.php
index 9842f834d..9300df356 100644
--- a/system/core/Output.php
+++ b/system/core/Output.php
@@ -1,4 +1,4 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php
/**
* CodeIgniter
*
@@ -24,11 +24,12 @@
* @since Version 1.0
* @filesource
*/
+defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Output Class
*
- * Responsible for sending final output to browser
+ * Responsible for sending final output to the browser.
*
* @package CodeIgniter
* @subpackage Libraries
@@ -39,70 +40,74 @@
class CI_Output {
/**
- * Current output string
+ * Final output string
*
- * @var string
+ * @var string
*/
public $final_output;
/**
* Cache expiration time
*
- * @var int
+ * @var int
*/
- public $cache_expiration = 0;
+ public $cache_expiration = 0;
/**
* List of server headers
*
- * @var array
+ * @var array
*/
public $headers = array();
/**
* List of mime types
*
- * @var array
+ * @var array
*/
public $mimes = array();
/**
* Mime-type for the current page
*
- * @var string
+ * @var string
*/
- protected $mime_type = 'text/html';
+ protected $mime_type = 'text/html';
/**
- * Determines whether profiler is enabled
+ * Enable Profiler flag
*
- * @var book
+ * @var bool
*/
- public $enable_profiler = FALSE;
+ public $enable_profiler = FALSE;
/**
- * Determines if output compression is enabled
+ * zLib output compression flag
*
- * @var bool
+ * @var bool
*/
protected $_zlib_oc = FALSE;
/**
* List of profiler sections
*
- * @var array
+ * @var array
*/
protected $_profiler_sections = array();
/**
- * Whether or not to parse variables like {elapsed_time} and {memory_usage}
+ * Parse markers flag
*
- * @var bool
+ * Whether or not to parse variables like {elapsed_time} and {memory_usage}.
+ *
+ * @var bool
*/
public $parse_exec_vars = TRUE;
/**
- * Set up Output class
+ * Class constructor
+ *
+ * Determines whether zLib output compression will be used.
*
* @return void
*/
@@ -121,7 +126,7 @@ class CI_Output {
/**
* Get Output
*
- * Returns the current output string
+ * Returns the current output string.
*
* @return string
*/
@@ -135,10 +140,10 @@ class CI_Output {
/**
* Set Output
*
- * Sets the output string
+ * Sets the output string.
*
- * @param string
- * @return void
+ * @param string $output Output data
+ * @return object $this
*/
public function set_output($output)
{
@@ -151,14 +156,14 @@ class CI_Output {
/**
* Append Output
*
- * Appends data onto the output string
+ * Appends data onto the output string.
*
- * @param string
- * @return void
+ * @param string $output Data to append
+ * @return object $this
*/
public function append_output($output)
{
- if ($this->final_output == '')
+ if (empty($this->final_output))
{
$this->final_output = $output;
}
@@ -175,14 +180,14 @@ class CI_Output {
/**
* Set Header
*
- * Lets you set a server header which will be outputted with the final display.
+ * Lets you set a server header which will be sent with the final output.
*
- * Note: If a file is cached, headers will not be sent. We need to figure out
- * how to permit header data to be saved with the cache data...
+ * Note: If a file is cached, headers will not be sent.
+ * @todo We need to figure out how to permit headers to be cached.
*
- * @param string
- * @param bool
- * @return void
+ * @param string $header Header
+ * @param bool $replace Whether to replace the old header value, if already set
+ * @return object $this
*/
public function set_header($header, $replace = TRUE)
{
@@ -192,7 +197,7 @@ class CI_Output {
// We'll just skip content-length in those cases.
if ($this->_zlib_oc && strncasecmp($header, 'content-length', 14) === 0)
{
- return;
+ return $this;
}
$this->headers[] = array($header, $replace);
@@ -202,10 +207,11 @@ class CI_Output {
// --------------------------------------------------------------------
/**
- * Set Content Type Header
+ * Set Content-Type Header
*
- * @param string extension of the file we're outputting
- * @return void
+ * @param string $mime_type Extension of the file we're outputting
+ * @param string $charset Character set (default: NULL)
+ * @return object $this
*/
public function set_content_type($mime_type, $charset = NULL)
{
@@ -242,7 +248,7 @@ class CI_Output {
// --------------------------------------------------------------------
/**
- * Get Current Content Type Header
+ * Get Current Content-Type Header
*
* @return string 'text/html', if not already set
*/
@@ -263,11 +269,13 @@ class CI_Output {
/**
* Set HTTP Status Header
- * moved to Common procedural functions in 1.7.2
*
- * @param int the status code
- * @param string
- * @return void
+ * As of version 1.7.2, this is an alias for common function
+ * set_status_header().
+ *
+ * @param int $code Status code (default: 200)
+ * @param string $text Optional message
+ * @return object $this
*/
public function set_status_header($code = 200, $text = '')
{
@@ -280,8 +288,8 @@ class CI_Output {
/**
* Enable/disable Profiler
*
- * @param bool
- * @return void
+ * @param bool $val TRUE to enable or FALSE to disable
+ * @return object $this
*/
public function enable_profiler($val = TRUE)
{
@@ -294,10 +302,11 @@ class CI_Output {
/**
* Set Profiler Sections
*
- * Allows override of default / config settings for Profiler section display
+ * Allows override of default/config settings for
+ * Profiler section display.
*
- * @param array
- * @return void
+ * @param array $sections Profiler sections
+ * @return object $this
*/
public function set_profiler_sections($sections)
{
@@ -320,8 +329,8 @@ class CI_Output {
/**
* Set Cache
*
- * @param int
- * @return void
+ * @param int $time Cache expiration time in seconds
+ * @return object $this
*/
public function cache($time)
{
@@ -334,16 +343,16 @@ class CI_Output {
/**
* Display Output
*
- * All "view" data is automatically put into this variable by the controller class:
- *
- * $this->final_output
+ * Processes sends the sends finalized output data to the browser along
+ * with any server headers and profile data. It also stops benchmark
+ * timers so the page rendering speed and memory usage can be shown.
*
- * This function sends the finalized output data to the browser along
- * with any server headers and profile data. It also stops the
- * benchmark timer so the page rendering speed and memory usage can be shown.
+ * Note: All "view" data is automatically put into $this->final_output
+ * by controller class.
*
- * @param string
- * @return mixed
+ * @uses CI_Output::$final_output
+ * @param string $output Output data override
+ * @return void
*/
public function _display($output = '')
{
@@ -374,10 +383,9 @@ class CI_Output {
$output = $this->minify($output, $this->mime_type);
}
-
// --------------------------------------------------------------------
- // Do we need to write a cache file? Only if the controller does not have its
+ // Do we need to write a cache file? Only if the controller does not have its
// own _output() method and we are not dealing with a cache file, which we
// can determine by the existence of the $CI object above
if ($this->cache_expiration > 0 && isset($CI) && ! method_exists($CI, '_output'))
@@ -430,7 +438,7 @@ class CI_Output {
echo $output;
log_message('debug', 'Final output sent to browser');
log_message('debug', 'Total execution time: '.$elapsed);
- return TRUE;
+ return;
}
// --------------------------------------------------------------------
@@ -472,9 +480,9 @@ class CI_Output {
// --------------------------------------------------------------------
/**
- * Write a Cache File
+ * Write Cache
*
- * @param string
+ * @param string $output Output data to cache
* @return void
*/
public function _write_cache($output)
@@ -525,11 +533,14 @@ class CI_Output {
// --------------------------------------------------------------------
/**
- * Update/serve a cached file
+ * Update/serve cached output
+ *
+ * @uses CI_Config
+ * @uses CI_URI
*
- * @param object config class
- * @param object uri class
- * @return bool
+ * @param object &$CFG CI_Config class instance
+ * @param object &$URI CI_URI class instance
+ * @return bool TRUE on success or FALSE on failure
*/
public function _display_cache(&$CFG, &$URI)
{
@@ -552,13 +563,13 @@ class CI_Output {
fclose($fp);
// Strip out the embedded timestamp
- if ( ! preg_match('/\d+TS--->/', $cache, $match))
+ if ( ! preg_match('/^(\d+)TS--->/', $cache, $match))
{
return FALSE;
}
$last_modified = filemtime($cache_path);
- $expire = str_replace('TS--->', '', $match[0]);
+ $expire = $match[1];
// Has the file expired?
if ($_SERVER['REQUEST_TIME'] >= $expire && is_really_writable($cache_path))
@@ -583,11 +594,13 @@ class CI_Output {
// --------------------------------------------------------------------
/**
+ * Set Cache Header
+ *
* Set the HTTP headers to match the server-side file cache settings
* in order to reduce bandwidth.
*
- * @param int timestamp of when the page was last modified
- * @param int timestamp of when should the requested page expire from cache
+ * @param int $last_modified Timestamp of when the page was last modified
+ * @param int $expiration Timestamp of when should the requested page expire from cache
* @return void
*/
public function set_cache_header($last_modified, $expiration)
@@ -611,11 +624,13 @@ class CI_Output {
// --------------------------------------------------------------------
/**
- * Reduce excessive size of HTML content.
+ * Minify
*
- * @param string
- * @param string
- * @return string
+ * Reduce excessive size of HTML/CSS/JavaScript content.
+ *
+ * @param string $output Output to minify
+ * @param string $type Output content MIME type
+ * @return string Minified output
*/
public function minify($output, $type = 'text/html')
{
diff --git a/system/core/Router.php b/system/core/Router.php
index 5bc053045..30bf39657 100644
--- a/system/core/Router.php
+++ b/system/core/Router.php
@@ -1,4 +1,4 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php
/**
* CodeIgniter
*
@@ -24,6 +24,7 @@
* @since Version 1.0
* @filesource
*/
+defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Router Class
@@ -39,56 +40,49 @@
class CI_Router {
/**
- * Config class
+ * CI_Config class object
*
- * @var object
+ * @var object
*/
public $config;
/**
* List of routes
*
- * @var array
+ * @var array
*/
public $routes = array();
/**
- * List of error routes
- *
- * @var array
- */
- public $error_routes = array();
-
- /**
* Current class name
*
- * @var string
+ * @var string
*/
public $class = '';
/**
* Current method name
*
- * @var string
+ * @var string
*/
public $method = 'index';
/**
* Sub-directory that contains the requested controller class
*
- * @var string
+ * @var string
*/
public $directory = '';
/**
* Default controller (and method if specific)
*
- * @var string
+ * @var string
*/
public $default_controller;
/**
- * Constructor
+ * Class constructor
*
* Runs the route mapping function.
*
@@ -104,9 +98,9 @@ class CI_Router {
// --------------------------------------------------------------------
/**
- * Set the route mapping
+ * Set route mapping
*
- * This function determines what should be served based on the URI request,
+ * Determines what should be served based on the URI request,
* as well as any "routes" that have been set in the routing config file.
*
* @return void
@@ -148,12 +142,12 @@ class CI_Router {
include(APPPATH.'config/routes.php');
}
- $this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route;
+ $this->routes = (isset($route) && is_array($route)) ? $route : array();
unset($route);
// Set the default controller so we can display it in the event
// the URI doesn't correlated to a valid controller.
- $this->default_controller = empty($this->routes['default_controller']) ? FALSE : strtolower($this->routes['default_controller']);
+ $this->default_controller = empty($this->routes['default_controller']) ? FALSE : $this->routes['default_controller'];
// Were there any query string segments? If so, we'll validate them and bail out since we're done.
if (count($segments) > 0)
@@ -179,31 +173,27 @@ class CI_Router {
// --------------------------------------------------------------------
/**
- * Set the default controller
+ * Set default controller
*
* @return void
*/
protected function _set_default_controller()
{
- if ($this->default_controller === FALSE)
+ if (empty($this->default_controller))
{
show_error('Unable to determine what should be displayed. A default route has not been specified in the routing file.');
}
+
// Is the method being specified?
- if (strpos($this->default_controller, '/') !== FALSE)
+ if (sscanf($this->default_controller, '%[^/]/%s', $class, $method) !== 2)
{
- $x = explode('/', $this->default_controller);
- $this->set_class($x[0]);
- $this->set_method($x[1]);
- $this->_set_request($x);
- }
- else
- {
- $this->set_class($this->default_controller);
- $this->set_method('index');
- $this->_set_request(array($this->default_controller, 'index'));
+ $method = 'index';
}
+ $this->set_class($class);
+ $this->set_method($method);
+ $this->_set_request(array($class, $method));
+
// re-index the routed segments array so it starts with 1 rather than 0
$this->uri->_reindex_segments();
@@ -213,12 +203,12 @@ class CI_Router {
// --------------------------------------------------------------------
/**
- * Set the Route
+ * Set request route
*
- * This function takes an array of URI segments as
- * input, and sets the current class/method
+ * Takes an array of URI segments as input and sets the class/method
+ * to be called.
*
- * @param array
+ * @param array $segments URI segments
* @return void
*/
protected function _set_request($segments = array())
@@ -232,17 +222,8 @@ class CI_Router {
$this->set_class($segments[0]);
- if (isset($segments[1]))
- {
- // A standard method request
- $this->set_method($segments[1]);
- }
- else
- {
- // This lets the "routed" segment array identify that the default
- // index method is being used.
- $segments[1] = 'index';
- }
+ isset($segments[1]) OR $segments[1] = 'index';
+ $this->set_method($segments[1]);
// Update our "routed" segment array to contain the segments.
// Note: If there is no custom routing, this array will be
@@ -253,11 +234,12 @@ class CI_Router {
// --------------------------------------------------------------------
/**
- * Validates the supplied segments.
- * Attempts to determine the path to the controller.
+ * Validate request
+ *
+ * Attempts validate the URI request and determine the controller path.
*
- * @param array
- * @return array
+ * @param array $segments URI segments
+ * @return array URI segments
*/
protected function _validate_request($segments)
{
@@ -266,9 +248,13 @@ class CI_Router {
return $segments;
}
+ $temp = str_replace('-', '_', $segments[0]);
+
// Does the requested controller exist in the root folder?
- if (file_exists(APPPATH.'controllers/'.$segments[0].'.php'))
+ if (file_exists(APPPATH.'controllers/'.$temp.'.php'))
{
+ $segments[0] = $temp;
+ empty($segments[1]) OR $segments[1] = str_replace('-', '_', $segments[1]);
return $segments;
}
@@ -276,22 +262,19 @@ class CI_Router {
if (is_dir(APPPATH.'controllers/'.$segments[0]))
{
// Set the directory and remove it from the segment array
- $this->set_directory($segments[0]);
- $segments = array_slice($segments, 1);
-
+ $this->set_directory(array_shift($segments));
if (count($segments) > 0)
{
+ $segments[0] = str_replace('-', '_', $segments[0]);
+ empty($segments[1]) OR $segments[1] = str_replace('-', '_', $segments[1]);
+
// Does the requested controller exist in the sub-folder?
if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].'.php'))
{
if ( ! empty($this->routes['404_override']))
{
- $x = explode('/', $this->routes['404_override']);
- $this->set_directory('');
- $this->set_class($x[0]);
- $this->set_method(isset($x[1]) ? $x[1] : 'index');
-
- return $x;
+ $this->directory = '';
+ return explode('/', $this->routes['404_override'], 2);
}
else
{
@@ -302,40 +285,26 @@ class CI_Router {
else
{
// Is the method being specified in the route?
- if (strpos($this->default_controller, '/') !== FALSE)
- {
- $x = explode('/', $this->default_controller);
- $this->set_class($x[0]);
- $this->set_method($x[1]);
- }
- else
- {
- $this->set_class($this->default_controller);
- $this->set_method('index');
- }
-
- // Does the default controller exist in the sub-folder?
- if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.'.php'))
+ $segments = explode('/', $this->default_controller);
+ if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].'.php'))
{
$this->directory = '';
- return array();
}
-
}
return $segments;
}
-
// If we've gotten this far it means that the URI does not correlate to a valid
// controller class. We will now see if there is an override
if ( ! empty($this->routes['404_override']))
{
- $x = explode('/', $this->routes['404_override']);
- $this->set_class($x[0]);
- $this->set_method(isset($x[1]) ? $x[1] : 'index');
+ if (sscanf($this->routes['404_override'], '%[^/]/%s', $class, $method) !== 2)
+ {
+ $method = 'index';
+ }
- return $x;
+ return array($class, $method);
}
// Nothing else to do at this point but show a 404
@@ -347,9 +316,8 @@ class CI_Router {
/**
* Parse Routes
*
- * This function matches any routes that may exist in
- * the config/routes.php file against the URI to
- * determine if the class/method need to be remapped.
+ * Matches any routes that may exist in the config/routes.php file
+ * against the URI to determine if the class/method need to be remapped.
*
* @return void
*/
@@ -368,13 +336,51 @@ class CI_Router {
foreach ($this->routes as $key => $val)
{
// Convert wild-cards to RegEx
- $key = str_replace(array(':any', ':num'), array('.+', '[0-9]+'), $key);
+ $key = str_replace(array(':any', ':num'), array('[^/]+', '[0-9]+'), $key);
// Does the RegEx match?
- if (preg_match('#^'.$key.'$#', $uri))
+ if (preg_match('#^'.$key.'$#', $uri, $matches))
{
- // Do we have a back-reference?
- if (strpos($val, '$') !== FALSE && strpos($key, '(') !== FALSE)
+ // Are we using callbacks to process back-references?
+ if ( ! is_string($val) && is_callable($val))
+ {
+ // Remove the original string from the matches array.
+ array_shift($matches);
+
+ // Get the match count.
+ $match_count = count($matches);
+
+ // Determine how many parameters the callback has.
+ $reflection = new ReflectionFunction($val);
+ $param_count = $reflection->getNumberOfParameters();
+
+ // Are there more parameters than matches?
+ if ($param_count > $match_count)
+ {
+ // Any params without matches will be set to an empty string.
+ $matches = array_merge($matches, array_fill($match_count, $param_count - $match_count, ''));
+
+ $match_count = $param_count;
+ }
+
+ // Get the parameters so we can use their default values.
+ $params = $reflection->getParameters();
+
+ for ($m = 0; $m < $match_count; $m++)
+ {
+ // Is the match empty and does a default value exist?
+ if (empty($matches[$m]) && $params[$m]->isDefaultValueAvailable())
+ {
+ // Substitute the empty match for the default value.
+ $matches[$m] = $params[$m]->getDefaultValue();
+ }
+ }
+
+ // Execute the callback using the values in matches as its parameters.
+ $val = call_user_func_array($val, $matches);
+ }
+ // Are we using the default routing method for back-references?
+ elseif (strpos($val, '$') !== FALSE && strpos($key, '(') !== FALSE)
{
$val = preg_replace('#^'.$key.'$#', $val, $uri);
}
@@ -391,9 +397,9 @@ class CI_Router {
// --------------------------------------------------------------------
/**
- * Set the class name
+ * Set class name
*
- * @param string
+ * @param string $class Class name
* @return void
*/
public function set_class($class)
@@ -416,9 +422,9 @@ class CI_Router {
// --------------------------------------------------------------------
/**
- * Set the method name
+ * Set method name
*
- * @param string
+ * @param string $method Method name
* @return void
*/
public function set_method($method)
@@ -441,9 +447,9 @@ class CI_Router {
// --------------------------------------------------------------------
/**
- * Set the directory name
+ * Set directory name
*
- * @param string
+ * @param string $dir Directory name
* @return void
*/
public function set_directory($dir)
@@ -454,7 +460,10 @@ class CI_Router {
// --------------------------------------------------------------------
/**
- * Fetch the sub-directory (if any) that contains the requested controller class
+ * Fetch directory
+ *
+ * Feches the sub-directory (if any) that contains the requested
+ * controller class.
*
* @return string
*/
@@ -466,9 +475,9 @@ class CI_Router {
// --------------------------------------------------------------------
/**
- * Set the controller overrides
+ * Set controller overrides
*
- * @param array
+ * @param array $routing Route overrides
* @return void
*/
public function _set_overrides($routing)
@@ -490,7 +499,7 @@ class CI_Router {
if (isset($routing['function']))
{
- $routing['function'] = ($routing['function'] == '') ? 'index' : $routing['function'];
+ $routing['function'] = empty($routing['function']) ? 'index' : $routing['function'];
$this->set_method($routing['function']);
}
}
diff --git a/system/core/Security.php b/system/core/Security.php
index b22d2cf19..b8e66c087 100644
--- a/system/core/Security.php
+++ b/system/core/Security.php
@@ -1,4 +1,4 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php
/**
* CodeIgniter
*
@@ -24,6 +24,7 @@
* @since Version 1.0
* @filesource
*/
+defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Security Class
@@ -37,45 +38,55 @@
class CI_Security {
/**
- * Random Hash for protecting URLs
+ * XSS Hash
*
- * @var string
+ * Random Hash for protecting URLs.
+ *
+ * @var string
*/
protected $_xss_hash = '';
/**
- * Random Hash for Cross Site Request Forgery Protection Cookie
+ * CSRF Hash
+ *
+ * Random hash for Cross Site Request Forgery protection cookie
*
- * @var string
+ * @var string
*/
protected $_csrf_hash = '';
/**
- * Expiration time for Cross Site Request Forgery Protection Cookie
- * Defaults to two hours (in seconds)
+ * CSRF Expire time
+ *
+ * Expiration time for Cross Site Request Forgery protection cookie.
+ * Defaults to two hours (in seconds).
*
- * @var int
+ * @var int
*/
protected $_csrf_expire = 7200;
/**
- * Token name for Cross Site Request Forgery Protection Cookie
+ * CSRF Token name
*
- * @var string
+ * Token name for Cross Site Request Forgery protection cookie.
+ *
+ * @var string
*/
protected $_csrf_token_name = 'ci_csrf_token';
/**
- * Cookie name for Cross Site Request Forgery Protection Cookie
+ * CSRF Cookie name
+ *
+ * Cookie name for Cross Site Request Forgery protection cookie.
*
- * @var string
+ * @var string
*/
protected $_csrf_cookie_name = 'ci_csrf_token';
/**
* List of never allowed strings
*
- * @var array
+ * @var array
*/
protected $_never_allowed_str = array(
'document.cookie' => '[removed]',
@@ -91,9 +102,9 @@ class CI_Security {
);
/**
- * List of never allowed regex replacement
+ * List of never allowed regex replacements
*
- * @var array
+ * @var array
*/
protected $_never_allowed_regex = array(
'javascript\s*:',
@@ -104,7 +115,7 @@ class CI_Security {
);
/**
- * Initialize security class
+ * Class constructor
*
* @return void
*/
@@ -138,7 +149,7 @@ class CI_Security {
// --------------------------------------------------------------------
/**
- * Verify Cross Site Request Forgery Protection
+ * CSRF Verify
*
* @return object
*/
@@ -161,7 +172,7 @@ class CI_Security {
}
// Do the tokens exist in both the _POST and _COOKIE arrays?
- if ( ! isset($_POST[$this->_csrf_token_name]) OR ! isset($_COOKIE[$this->_csrf_cookie_name])
+ if ( ! isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name])
OR $_POST[$this->_csrf_token_name] !== $_COOKIE[$this->_csrf_cookie_name]) // Do the tokens match?
{
$this->csrf_show_error();
@@ -188,17 +199,17 @@ class CI_Security {
// --------------------------------------------------------------------
/**
- * Set Cross Site Request Forgery Protection Cookie
+ * CSRF Set Cookie
*
- * @return object
* @codeCoverageIgnore
+ * @return object
*/
public function csrf_set_cookie()
{
$expire = time() + $this->_csrf_expire;
$secure_cookie = (bool) config_item('cookie_secure');
- if ($secure_cookie && (empty($_SERVER['HTTPS']) OR strtolower($_SERVER['HTTPS']) === 'off'))
+ if ($secure_cookie && ! is_https())
{
return FALSE;
}
@@ -234,9 +245,8 @@ class CI_Security {
/**
* Get CSRF Hash
*
- * Getter Method
- *
- * @return string self::_csrf_hash
+ * @see CI_Security::$_csrf_hash
+ * @return string CSRF hash
*/
public function get_csrf_hash()
{
@@ -248,9 +258,8 @@ class CI_Security {
/**
* Get CSRF Token Name
*
- * Getter Method
- *
- * @return string self::_csrf_token_name
+ * @see CI_Security::$_csrf_token_name
+ * @return string CSRF token name
*/
public function get_csrf_token_name()
{
@@ -263,26 +272,26 @@ class CI_Security {
* XSS Clean
*
* Sanitizes data so that Cross Site Scripting Hacks can be
- * prevented. This function does a fair amount of work but
+ * prevented. This method does a fair amount of work but
* it is extremely thorough, designed to prevent even the
* most obscure XSS attempts. Nothing is ever 100% foolproof,
* of course, but I haven't been able to get anything passed
* the filter.
*
- * Note: This function should only be used to deal with data
- * upon submission. It's not something that should
- * be used for general runtime processing.
+ * Note: Should only be used to deal with data upon submission.
+ * It's not something that should be used for general
+ * runtime processing.
*
- * This function was based in part on some code and ideas I
- * got from Bitflux: http://channel.bitflux.ch/wiki/XSS_Prevention
+ * @link http://channel.bitflux.ch/wiki/XSS_Prevention
+ * Based in part on some code and ideas from Bitflux.
*
- * To help develop this script I used this great list of
- * vulnerabilities along with a few other hacks I've
- * harvested from examining vulnerabilities in other programs:
- * http://ha.ckers.org/xss.html
+ * @link http://ha.ckers.org/xss.html
+ * To help develop this script I used this great list of
+ * vulnerabilities along with a few other hacks I've
+ * harvested from examining vulnerabilities in other programs.
*
- * @param mixed string or array
- * @param bool
+ * @param string|string[] $str Input data
+ * @param bool $is_image Whether the input is an image
* @return string
*/
public function xss_clean($str, $is_image = FALSE)
@@ -469,9 +478,12 @@ class CI_Security {
// --------------------------------------------------------------------
/**
- * Random Hash for protecting URLs
+ * XSS Hash
*
- * @return string
+ * Generates the XSS hash if needed and returns it.
+ *
+ * @see CI_Security::$_xss_hash
+ * @return string XSS hash
*/
public function xss_hash()
{
@@ -489,7 +501,7 @@ class CI_Security {
/**
* HTML Entities Decode
*
- * This function is a replacement for html_entity_decode()
+ * A replacement for html_entity_decode()
*
* The reason we are not using html_entity_decode() by itself is because
* while it is not technically correct to leave out the semicolon
@@ -497,8 +509,10 @@ class CI_Security {
* correctly. html_entity_decode() does not convert entities without
* semicolons, so we are left with our own little solution here. Bummer.
*
- * @param string
- * @param string
+ * @link http://php.net/html-entity-decode
+ *
+ * @param string $str Input
+ * @param string $charset Character set
* @return string
*/
public function entity_decode($str, $charset = NULL)
@@ -521,10 +535,10 @@ class CI_Security {
// --------------------------------------------------------------------
/**
- * Filename Security
+ * Sanitize Filename
*
- * @param string
- * @param bool
+ * @param string $str Input file name
+ * @param bool $relative_path Whether to preserve paths
* @return string
*/
public function sanitize_filename($str, $relative_path = FALSE)
@@ -563,7 +577,7 @@ class CI_Security {
/**
* Strip Image Tags
*
- * @param string
+ * @param string $str
* @return string
*/
public function strip_image_tags($str)
@@ -576,10 +590,11 @@ class CI_Security {
/**
* Compact Exploded Words
*
- * Callback function for xss_clean() to remove whitespace from
- * things like j a v a s c r i p t
+ * Callback method for xss_clean() to remove whitespace from
+ * things like 'j a v a s c r i p t'.
*
- * @param array
+ * @used-by CI_Security::xss_clean()
+ * @param array $matches
* @return string
*/
protected function _compact_exploded_words($matches)
@@ -593,16 +608,22 @@ class CI_Security {
* Remove Evil HTML Attributes (like event handlers and style)
*
* It removes the evil attribute and either:
- * - Everything up until a space
- * For example, everything between the pipes:
+ *
+ * - Everything up until a space. For example, everything between the pipes:
+ *
+ * <code>
* <a |style=document.write('hello');alert('world');| class=link>
- * - Everything inside the quotes
- * For example, everything between the pipes:
+ * </code>
+ *
+ * - Everything inside the quotes. For example, everything between the pipes:
+ *
+ * <code>
* <a |style="document.write('hello'); alert('world');"| class="link">
+ * </code>
*
- * @param string $str The string to check
- * @param boolean $is_image TRUE if this is an image
- * @return string The string with the evil attributes removed
+ * @param string $str The string to check
+ * @param bool $is_image Whether the input is an image
+ * @return string The string with the evil attributes removed
*/
protected function _remove_evil_attributes($str, $is_image)
{
@@ -655,9 +676,10 @@ class CI_Security {
/**
* Sanitize Naughty HTML
*
- * Callback function for xss_clean() to remove naughty HTML elements
+ * Callback method for xss_clean() to remove naughty HTML elements.
*
- * @param array
+ * @used-by CI_Security::xss_clean()
+ * @param array $matches
* @return string
*/
protected function _sanitize_naughty_html($matches)
@@ -672,12 +694,14 @@ class CI_Security {
/**
* JS Link Removal
*
- * Callback function for xss_clean() to sanitize links
+ * Callback method for xss_clean() to sanitize links.
+ *
* This limits the PCRE backtracks, making it more performance friendly
* and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in
- * PHP 5.2+ on link-heavy strings
+ * PHP 5.2+ on link-heavy strings.
*
- * @param array
+ * @used-by CI_Security::xss_clean()
+ * @param array $match
* @return string
*/
protected function _js_link_removal($match)
@@ -695,12 +719,14 @@ class CI_Security {
/**
* JS Image Removal
*
- * Callback function for xss_clean() to sanitize image tags
+ * Callback method for xss_clean() to sanitize image tags.
+ *
* This limits the PCRE backtracks, making it more performance friendly
* and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in
- * PHP 5.2+ on image tag heavy strings
+ * PHP 5.2+ on image tag heavy strings.
*
- * @param array
+ * @used-by CI_Security::xss_clean()
+ * @param array $match
* @return string
*/
protected function _js_img_removal($match)
@@ -718,9 +744,8 @@ class CI_Security {
/**
* Attribute Conversion
*
- * Used as a callback for XSS Clean
- *
- * @param array
+ * @used-by CI_Security::xss_clean()
+ * @param array $match
* @return string
*/
protected function _convert_attribute($match)
@@ -733,9 +758,11 @@ class CI_Security {
/**
* Filter Attributes
*
- * Filters tag attributes for consistency and safety
+ * Filters tag attributes for consistency and safety.
*
- * @param string
+ * @used-by CI_Security::_js_img_removal()
+ * @used-by CI_Security::_js_link_removal()
+ * @param string $str
* @return string
*/
protected function _filter_attributes($str)
@@ -757,9 +784,8 @@ class CI_Security {
/**
* HTML Entity Decode Callback
*
- * Used as a callback for XSS Clean
- *
- * @param array
+ * @used-by CI_Security::xss_clean()
+ * @param array $match
* @return string
*/
protected function _decode_entity($match)
@@ -772,9 +798,8 @@ class CI_Security {
/**
* Validate URL entities
*
- * Called by xss_clean()
- *
- * @param string
+ * @used-by CI_Security::xss_clean()
+ * @param string $str
* @return string
*/
protected function _validate_entities($str)
@@ -812,8 +837,7 @@ class CI_Security {
/**
* Do Never Allowed
*
- * A utility function for xss_clean()
- *
+ * @used-by CI_Security::xss_clean()
* @param string
* @return string
*/
@@ -832,7 +856,7 @@ class CI_Security {
// --------------------------------------------------------------------
/**
- * Set Cross Site Request Forgery Protection Cookie
+ * Set CSRF Hash and Cookie
*
* @return string
*/
diff --git a/system/core/URI.php b/system/core/URI.php
index 6a8b1a5ac..91740254c 100644
--- a/system/core/URI.php
+++ b/system/core/URI.php
@@ -1,4 +1,4 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php
/**
* CodeIgniter
*
@@ -24,6 +24,7 @@
* @since Version 1.0
* @filesource
*/
+defined('BASEPATH') OR exit('No direct script access allowed');
/**
* URI Class
@@ -39,36 +40,37 @@
class CI_URI {
/**
- * List of cached uri segments
+ * List of cached URI segments
*
- * @var array
+ * @var array
*/
public $keyval = array();
/**
- * Current uri string
+ * Current URI string
*
- * @var string
+ * @var string
*/
public $uri_string;
/**
- * List of uri segments
+ * List of URI segments
*
- * @var array
+ * @var array
*/
public $segments = array();
/**
- * Re-indexed list of uri segments
- * Starts at 1 instead of 0
+ * Re-indexed list of URI segments
*
- * @var array
+ * Starts at 1 instead of 0.
+ *
+ * @var array
*/
public $rsegments = array();
/**
- * Constructor
+ * Class constructor
*
* Simply globalizes the $RTR object. The front
* loads the Router class early on so it's not available
@@ -85,10 +87,9 @@ class CI_URI {
// --------------------------------------------------------------------
/**
- * Get the URI String
- *
- * Called by CI_Router
+ * Fetch URI String
*
+ * @used-by CI_Router
* @return void
*/
public function _fetch_uri_string()
@@ -98,31 +99,28 @@ class CI_URI {
// Is the request coming from the command line?
if ($this->_is_cli_request())
{
- $this->_set_uri_string($this->_parse_cli_args());
+ $this->_set_uri_string($this->_parse_argv());
return;
}
- // Let's try the REQUEST_URI first, this will work in most situations
- if ($uri = $this->_detect_uri())
+ // Is there a PATH_INFO variable? This should be the easiest solution.
+ if (isset($_SERVER['PATH_INFO']))
{
- $this->_set_uri_string($uri);
+ $this->_set_uri_string($_SERVER['PATH_INFO']);
return;
}
- // Is there a PATH_INFO variable?
- // Note: some servers seem to have trouble with getenv() so we'll test it two ways
- $path = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
- if (trim($path, '/') !== '' && $path !== '/'.SELF)
+ // Let's try REQUEST_URI then, this will work in most situations
+ if (($uri = $this->_parse_request_uri()) !== '')
{
- $this->_set_uri_string($path);
+ $this->_set_uri_string($uri);
return;
}
- // No PATH_INFO?... What about QUERY_STRING?
- $path = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
- if (trim($path, '/') !== '')
+ // No REQUEST_URI either?... What about QUERY_STRING?
+ if (($uri = $this->_parse_query_string()) !== '')
{
- $this->_set_uri_string($path);
+ $this->_set_uri_string($uri);
return;
}
@@ -140,95 +138,86 @@ class CI_URI {
$uri = strtoupper($this->config->item('uri_protocol'));
- if ($uri === 'REQUEST_URI')
+ if ($uri === 'CLI')
{
- $this->_set_uri_string($this->_detect_uri());
+ $this->_set_uri_string($this->_parse_argv());
return;
}
- elseif ($uri === 'CLI')
+ elseif (method_exists($this, ($method = '_parse_'.strtolower($uri))))
{
- $this->_set_uri_string($this->_parse_cli_args());
+ $this->_set_uri_string($this->$method());
return;
}
- $path = isset($_SERVER[$uri]) ? $_SERVER[$uri] : @getenv($uri);
- $this->_set_uri_string($path);
+ $uri = isset($_SERVER[$uri]) ? $_SERVER[$uri] : @getenv($uri);
+ $this->_set_uri_string($uri);
}
// --------------------------------------------------------------------
/**
- * Set the URI String
+ * Set URI String
*
- * @param string
+ * @param string $str
* @return void
*/
protected function _set_uri_string($str)
{
- // Filter out control characters
- $str = remove_invisible_characters($str, FALSE);
-
- // If the URI contains only a slash we'll kill it
- $this->uri_string = ($str === '/') ? '' : $str;
+ // Filter out control characters and trim slashes
+ $this->uri_string = trim(remove_invisible_characters($str, FALSE), '/');
}
// --------------------------------------------------------------------
/**
- * Detects the URI
+ * Parse REQUEST_URI
*
- * This function will detect the URI automatically
- * and fix the query string if necessary.
+ * Will parse REQUEST_URI and automatically detect the URI from it,
+ * while fixing the query string if necessary.
*
+ * @used-by CI_URI::_fetch_uri_string()
* @return string
*/
- protected function _detect_uri()
+ protected function _parse_request_uri()
{
if ( ! isset($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']))
{
return '';
}
- if (strpos($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']) === 0)
- {
- $uri = substr($_SERVER['REQUEST_URI'], strlen($_SERVER['SCRIPT_NAME']));
- }
- elseif (strpos($_SERVER['REQUEST_URI'], dirname($_SERVER['SCRIPT_NAME'])) === 0)
+ $uri = parse_url($_SERVER['REQUEST_URI']);
+ $query = isset($uri['query']) ? $uri['query'] : '';
+ $uri = isset($uri['path']) ? rawurldecode($uri['path']) : '';
+
+ if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0)
{
- $uri = substr($_SERVER['REQUEST_URI'], strlen(dirname($_SERVER['SCRIPT_NAME'])));
+ $uri = (string) substr($uri, strlen($_SERVER['SCRIPT_NAME']));
}
- else
+ elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0)
{
- $uri = $_SERVER['REQUEST_URI'];
+ $uri = (string) substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME'])));
}
// This section ensures that even on servers that require the URI to be in the query string (Nginx) a correct
// URI is found, and also fixes the QUERY_STRING server var and $_GET array.
- if (strpos($uri, '?/') === 0)
+ if (trim($uri, '/') === '' && strncmp($query, '/', 1) === 0)
{
- $uri = substr($uri, 2);
- }
-
- $parts = explode('?', $uri, 2);
- $uri = $parts[0];
- if (isset($parts[1]))
- {
- $_SERVER['QUERY_STRING'] = $parts[1];
- parse_str($_SERVER['QUERY_STRING'], $_GET);
+ $query = explode('?', $query, 2);
+ $uri = rawurldecode($query[0]);
+ $_SERVER['QUERY_STRING'] = isset($query[1]) ? $query[1] : '';
}
else
{
- $_SERVER['QUERY_STRING'] = '';
- $_GET = array();
+ $_SERVER['QUERY_STRING'] = $query;
}
- if ($uri === '/' OR empty($uri))
+ parse_str($_SERVER['QUERY_STRING'], $_GET);
+
+ if ($uri === '/' OR $uri === '')
{
return '/';
}
- $uri = parse_url('pseudo://hostname/'.$uri, PHP_URL_PATH);
-
// Do some final cleaning of the URI and return it
return str_replace(array('//', '../'), '/', trim($uri, '/'));
}
@@ -236,10 +225,43 @@ class CI_URI {
// --------------------------------------------------------------------
/**
- * Is cli Request?
+ * Parse QUERY_STRING
*
- * Duplicate of function from the Input class to test to see if a request was made from the command line
+ * Will parse QUERY_STRING and automatically detect the URI from it.
*
+ * @used-by CI_URI::_fetch_uri_string()
+ * @return string
+ */
+ protected function _parse_query_string()
+ {
+ $uri = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
+
+ if (trim($uri, '/') === '')
+ {
+ return '';
+ }
+ elseif (strncmp($uri, '/', 1) === 0)
+ {
+ $uri = explode('?', $uri, 2);
+ $_SERVER['QUERY_STRING'] = isset($uri[1]) ? $uri[1] : '';
+ $uri = rawurldecode($uri[0]);
+ }
+
+ parse_str($_SERVER['QUERY_STRING'], $_GET);
+
+ return str_replace(array('//', '../'), '/', trim($uri, '/'));
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Is CLI Request?
+ *
+ * Duplicate of method from the Input class to test to see if
+ * a request was made from the command line.
+ *
+ * @see CI_Input::is_cli_request()
+ * @used-by CI_URI::_fetch_uri_string()
* @return bool
*/
protected function _is_cli_request()
@@ -250,26 +272,27 @@ class CI_URI {
// --------------------------------------------------------------------
/**
- * Parse cli arguments
+ * Parse CLI arguments
*
* Take each command line argument and assume it is a URI segment.
*
* @return string
*/
- protected function _parse_cli_args()
+ protected function _parse_argv()
{
$args = array_slice($_SERVER['argv'], 1);
- return $args ? '/'.implode('/', $args) : '';
+ return $args ? implode('/', $args) : '';
}
// --------------------------------------------------------------------
/**
- * Filter segments for malicious characters
+ * Filter URI
*
- * Called by CI_Router
+ * Filters segments for malicious characters.
*
- * @param string
+ * @used-by CI_Router
+ * @param string $str
* @return string
*/
public function _filter_uri($str)
@@ -278,7 +301,7 @@ class CI_URI {
{
// preg_quote() in PHP 5.3 escapes -, so the str_replace() and addition of - to preg_quote() is to maintain backwards
// compatibility as many are unaware of how characters in the permitted_uri_chars will be parsed as a regex pattern
- if ( ! preg_match('|^['.str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-')).']+$|i', urldecode($str)))
+ if ( ! preg_match('|^['.str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-')).']+$|i', $str))
{
show_error('The URI you submitted has disallowed characters.', 400);
}
@@ -294,10 +317,11 @@ class CI_URI {
// --------------------------------------------------------------------
/**
- * Remove the suffix from the URL if needed
+ * Remove URL suffix
*
- * Called by CI_Router
+ * Removes the suffix from the URL if needed.
*
+ * @used-by CI_Router
* @return void
*/
public function _remove_url_suffix()
@@ -313,11 +337,12 @@ class CI_URI {
// --------------------------------------------------------------------
/**
- * Explode the URI Segments. The individual segments will
- * be stored in the $this->segments array.
+ * Explode URI segments
*
- * Called by CI_Router
+ * The individual segments will be stored in the $this->segments array.
*
+ * @see CI_URI::$segments
+ * @used-by CI_Router
* @return void
*/
public function _explode_segments()
@@ -339,13 +364,12 @@ class CI_URI {
/**
* Re-index Segments
*
- * This function re-indexes the $this->segment array so that it
- * starts at 1 rather than 0. Doing so makes it simpler to
- * use functions like $this->uri->segment(n) since there is
- * a 1:1 relationship between the segment array and the actual segments.
- *
- * Called by CI_Router
+ * Re-indexes the CI_URI::$segment array so that it starts at 1 rather
+ * than 0. Doing so makes it simpler to use methods like
+ * CI_URI::segment(n) since there is a 1:1 relationship between the
+ * segment array and the actual segments.
*
+ * @used-by CI_Router
* @return void
*/
public function _reindex_segments()
@@ -359,13 +383,12 @@ class CI_URI {
// --------------------------------------------------------------------
/**
- * Fetch a URI Segment
+ * Fetch URI Segment
*
- * This function returns the URI segment based on the number provided.
- *
- * @param int
- * @param mixed
- * @return string
+ * @see CI_URI::$segments
+ * @param int $n Index
+ * @param mixed $no_result What to return if the segment index is not found
+ * @return mixed
*/
public function segment($n, $no_result = NULL)
{
@@ -375,15 +398,17 @@ class CI_URI {
// --------------------------------------------------------------------
/**
- * Fetch a URI "routed" Segment
+ * Fetch URI "routed" Segment
*
- * This function returns the re-routed URI segment (assuming routing rules are used)
- * based on the number provided. If there is no routing this function returns the
- * same result as $this->segment()
+ * Returns the re-routed URI segment (assuming routing rules are used)
+ * based on the index provided. If there is no routing, will return
+ * the same result as CI_URI::segment().
*
- * @param int
- * @param mixed
- * @return string
+ * @see CI_URI::$rsegments
+ * @see CI_URI::segment()
+ * @param int $n Index
+ * @param mixed $no_result What to return if the segment index is not found
+ * @return mixed
*/
public function rsegment($n, $no_result = NULL)
{
@@ -393,23 +418,23 @@ class CI_URI {
// --------------------------------------------------------------------
/**
- * Generate a key value pair from the URI string
+ * URI to assoc
*
- * This function generates and associative array of URI data starting
- * at the supplied segment. For example, if this is your URI:
+ * Generates an associative array of URI data starting at the supplied
+ * segment index. For example, if this is your URI:
*
* example.com/user/search/name/joe/location/UK/gender/male
*
- * You can use this function to generate an array with this prototype:
+ * You can use this method to generate an array with this prototype:
*
- * array (
- * name => joe
- * location => UK
- * gender => male
- * )
+ * array (
+ * name => joe
+ * location => UK
+ * gender => male
+ * )
*
- * @param int the starting segment number
- * @param array an array of default values
+ * @param int $n Index (default: 3)
+ * @param array $default Default values
* @return array
*/
public function uri_to_assoc($n = 3, $default = array())
@@ -420,10 +445,14 @@ class CI_URI {
// --------------------------------------------------------------------
/**
- * Identical to above only it uses the re-routed segment array
+ * Routed URI to assoc
+ *
+ * Identical to CI_URI::uri_to_assoc(), only it uses the re-routed
+ * segment array.
*
- * @param int the starting segment number
- * @param array an array of default values
+ * @see CI_URI::uri_to_assoc()
+ * @param int $n Index (default: 3)
+ * @param array $default Default values
* @return array
*/
public function ruri_to_assoc($n = 3, $default = array())
@@ -434,11 +463,15 @@ class CI_URI {
// --------------------------------------------------------------------
/**
- * Generate a key value pair from the URI string or Re-routed URI string
+ * Internal URI-to-assoc
*
- * @param int the starting segment number
- * @param array an array of default values
- * @param string which array we should use
+ * Generates a key/value pair from the URI string or re-routed URI string.
+ *
+ * @used-by CI_URI::uri_to_assoc()
+ * @used-by CI_URI::ruri_to_assoc()
+ * @param int $n Index (default: 3)
+ * @param array $default Default values
+ * @param string $which Array name ('segment' or 'rsegment')
* @return array
*/
protected function _uri_to_assoc($n = 3, $default = array(), $which = 'segment')
@@ -448,9 +481,11 @@ class CI_URI {
return $default;
}
- if (isset($this->keyval[$n]))
+ in_array($which, array('segment', 'rsegment'), TRUE) OR $which = 'segment';
+
+ if (isset($this->keyval[$which], $this->keyval[$which][$n]))
{
- return $this->keyval[$n];
+ return $this->keyval[$which][$n];
}
if ($which === 'segment')
@@ -474,7 +509,7 @@ class CI_URI {
$segments = array_slice($this->$segment_array(), ($n - 1));
$i = 0;
$lastval = '';
- $retval = array();
+ $retval = array();
foreach ($segments as $seg)
{
if ($i % 2)
@@ -502,17 +537,20 @@ class CI_URI {
}
// Cache the array for reuse
- $this->keyval[$n] = $retval;
+ isset($this->keyval[$which]) OR $this->keyval[$which] = array();
+ $this->keyval[$which][$n] = $retval;
return $retval;
}
// --------------------------------------------------------------------
/**
- * Generate a URI string from an associative array
+ * Assoc to URI
*
- * @param array an associative array of key/values
- * @return array
+ * Generates a URI string from an associative array.
+ *
+ * @param array $array Input array of key/value pairs
+ * @return string URI string
*/
public function assoc_to_uri($array)
{
@@ -529,10 +567,12 @@ class CI_URI {
// --------------------------------------------------------------------
/**
- * Fetch a URI Segment and add a trailing slash
+ * Slash segment
+ *
+ * Fetches an URI segment with a slash.
*
- * @param int
- * @param string
+ * @param int $n Index
+ * @param string $where Where to add the slash ('trailing' or 'leading')
* @return string
*/
public function slash_segment($n, $where = 'trailing')
@@ -543,10 +583,12 @@ class CI_URI {
// --------------------------------------------------------------------
/**
- * Fetch a URI Segment and add a trailing slash
+ * Slash routed segment
*
- * @param int
- * @param string
+ * Fetches an URI routed segment with a slash.
+ *
+ * @param int $n Index
+ * @param string $where Where to add the slash ('trailing' or 'leading')
* @return string
*/
public function slash_rsegment($n, $where = 'trailing')
@@ -557,11 +599,16 @@ class CI_URI {
// --------------------------------------------------------------------
/**
- * Fetch a URI Segment and add a trailing slash - helper function
+ * Internal Slash segment
+ *
+ * Fetches an URI Segment and adds a slash to it.
*
- * @param int
- * @param string
- * @param string
+ * @used-by CI_URI::slash_segment()
+ * @used-by CI_URI::slash_rsegment()
+ *
+ * @param int $n Index
+ * @param string $where Where to add the slash ('trailing' or 'leading')
+ * @param string $which Array name ('segment' or 'rsegment')
* @return string
*/
protected function _slash_segment($n, $where = 'trailing', $which = 'segment')
@@ -585,7 +632,7 @@ class CI_URI {
/**
* Segment Array
*
- * @return array
+ * @return array CI_URI::$segments
*/
public function segment_array()
{
@@ -597,7 +644,7 @@ class CI_URI {
/**
* Routed Segment Array
*
- * @return array
+ * @return array CI_URI::$rsegments
*/
public function rsegment_array()
{
@@ -631,26 +678,32 @@ class CI_URI {
// --------------------------------------------------------------------
/**
- * Fetch the entire URI string
+ * Fetch URI string
*
- * @return string
+ * @return string CI_URI::$uri_string
*/
public function uri_string()
{
return $this->uri_string;
}
-
// --------------------------------------------------------------------
/**
- * Fetch the entire Re-routed URI string
+ * Fetch Re-routed URI string
*
* @return string
*/
public function ruri_string()
{
- return implode('/', $this->rsegment_array());
+ global $RTR;
+
+ if (($dir = $RTR->fetch_directory()) === '/')
+ {
+ $dir = '';
+ }
+
+ return $dir.implode('/', $this->rsegment_array());
}
}
diff --git a/system/core/Utf8.php b/system/core/Utf8.php
index 0a7ec501c..5bc2dd5c9 100644
--- a/system/core/Utf8.php
+++ b/system/core/Utf8.php
@@ -1,4 +1,4 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php
/**
* CodeIgniter
*
@@ -24,6 +24,7 @@
* @since Version 2.0
* @filesource
*/
+defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Utf8 Class
@@ -39,9 +40,9 @@
class CI_Utf8 {
/**
- * Constructor
+ * Class constructor
*
- * Determines if UTF-8 support is to be enabled
+ * Determines if UTF-8 support is to be enabled.
*
* @return void
*/
@@ -49,30 +50,30 @@ class CI_Utf8 {
{
log_message('debug', 'Utf8 Class Initialized');
- global $CFG;
+ $charset = strtoupper(config_item('charset'));
+
+ // set internal encoding for multibyte string functions if necessary
+ // and set a flag so we don't have to repeatedly use extension_loaded()
+ // or function_exists()
+ if (extension_loaded('mbstring'))
+ {
+ define('MB_ENABLED', TRUE);
+ mb_internal_encoding($charset);
+ }
+ else
+ {
+ define('MB_ENABLED', FALSE);
+ }
if (
- @preg_match('/./u', 'é') === 1 // PCRE must support UTF-8
- && function_exists('iconv') // iconv must be installed
- && (bool) @ini_get('mbstring.func_overload') !== TRUE // Multibyte string function overloading cannot be enabled
- && $CFG->item('charset') === 'UTF-8' // Application charset must be UTF-8
+ @preg_match('/./u', 'é') === 1 // PCRE must support UTF-8
+ && function_exists('iconv') // iconv must be installed
+ && MB_ENABLED === TRUE // mbstring must be enabled
+ && $charset === 'UTF-8' // Application charset must be UTF-8
)
{
define('UTF8_ENABLED', TRUE);
log_message('debug', 'UTF-8 Support Enabled');
-
- // set internal encoding for multibyte string functions if necessary
- // and set a flag so we don't have to repeatedly use extension_loaded()
- // or function_exists()
- if (extension_loaded('mbstring'))
- {
- define('MB_ENABLED', TRUE);
- mb_internal_encoding('UTF-8');
- }
- else
- {
- define('MB_ENABLED', FALSE);
- }
}
else
{
@@ -86,9 +87,11 @@ class CI_Utf8 {
/**
* Clean UTF-8 strings
*
- * Ensures strings are UTF-8
+ * Ensures strings contain only valid UTF-8 characters.
*
- * @param string
+ * @uses CI_Utf8::_is_ascii() Decide whether a conversion is needed
+ *
+ * @param string $str String to clean
* @return string
*/
public function clean_string($str)
@@ -108,9 +111,9 @@ class CI_Utf8 {
*
* Removes all ASCII control characters except horizontal tabs,
* line feeds, and carriage returns, as all others can cause
- * problems in XML
+ * problems in XML.
*
- * @param string
+ * @param string $str String to clean
* @return string
*/
public function safe_ascii_for_xml($str)
@@ -123,11 +126,11 @@ class CI_Utf8 {
/**
* Convert to UTF-8
*
- * Attempts to convert a string to UTF-8
+ * Attempts to convert a string to UTF-8.
*
- * @param string
- * @param string input encoding
- * @return string
+ * @param string $str Input string
+ * @param string $encoding Input encoding
+ * @return string $str encoded in UTF-8 or FALSE on failure
*/
public function convert_to_utf8($str, $encoding)
{
@@ -135,7 +138,7 @@ class CI_Utf8 {
{
return @iconv($encoding, 'UTF-8', $str);
}
- elseif (function_exists('mb_convert_encoding'))
+ elseif (MB_ENABLED === TRUE)
{
return @mb_convert_encoding($str, 'UTF-8', $encoding);
}
@@ -148,9 +151,9 @@ class CI_Utf8 {
/**
* Is ASCII?
*
- * Tests if a string is standard 7-bit ASCII or not
+ * Tests if a string is standard 7-bit ASCII or not.
*
- * @param string
+ * @param string $str String to check
* @return bool
*/
protected function _is_ascii($str)