first commit
This commit is contained in:
118
system/core/Benchmark.php
Normal file
118
system/core/Benchmark.php
Normal file
@ -0,0 +1,118 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP 5.1.6 or newer
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
|
||||
* @license http://codeigniter.com/user_guide/license.html
|
||||
* @link http://codeigniter.com
|
||||
* @since Version 1.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* CodeIgniter Benchmark Class
|
||||
*
|
||||
* This class enables you to mark points and calculate the time difference
|
||||
* between them. Memory consumption can also be displayed.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Libraries
|
||||
* @category Libraries
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @link http://codeigniter.com/user_guide/libraries/benchmark.html
|
||||
*/
|
||||
class CI_Benchmark {
|
||||
|
||||
/**
|
||||
* List of all benchmark markers and when they were added
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $marker = array();
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set a benchmark marker
|
||||
*
|
||||
* Multiple calls to this function can be made so that several
|
||||
* execution points can be timed
|
||||
*
|
||||
* @access public
|
||||
* @param string $name name of the marker
|
||||
* @return void
|
||||
*/
|
||||
function mark($name)
|
||||
{
|
||||
$this->marker[$name] = microtime();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Calculates the time difference between two marked points.
|
||||
*
|
||||
* If the first parameter is empty this function instead returns the
|
||||
* {elapsed_time} pseudo-variable. This permits the full system
|
||||
* execution time to be shown in a template. The output class will
|
||||
* swap the real value for this variable.
|
||||
*
|
||||
* @access public
|
||||
* @param string a particular marked point
|
||||
* @param string a particular marked point
|
||||
* @param integer the number of decimal places
|
||||
* @return mixed
|
||||
*/
|
||||
function elapsed_time($point1 = '', $point2 = '', $decimals = 4)
|
||||
{
|
||||
if ($point1 == '')
|
||||
{
|
||||
return '{elapsed_time}';
|
||||
}
|
||||
|
||||
if ( ! isset($this->marker[$point1]))
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( ! isset($this->marker[$point2]))
|
||||
{
|
||||
$this->marker[$point2] = microtime();
|
||||
}
|
||||
|
||||
list($sm, $ss) = explode(' ', $this->marker[$point1]);
|
||||
list($em, $es) = explode(' ', $this->marker[$point2]);
|
||||
|
||||
return number_format(($em + $es) - ($sm + $ss), $decimals);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Memory Usage
|
||||
*
|
||||
* This function returns the {memory_usage} pseudo-variable.
|
||||
* 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.
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function memory_usage()
|
||||
{
|
||||
return '{memory_usage}';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// END CI_Benchmark class
|
||||
|
||||
/* End of file Benchmark.php */
|
||||
/* Location: ./system/core/Benchmark.php */
|
402
system/core/CodeIgniter.php
Normal file
402
system/core/CodeIgniter.php
Normal file
@ -0,0 +1,402 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP 5.1.6 or newer
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
|
||||
* @license http://codeigniter.com/user_guide/license.html
|
||||
* @link http://codeigniter.com
|
||||
* @since Version 1.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* System Initialization File
|
||||
*
|
||||
* Loads the base classes and executes the request.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage codeigniter
|
||||
* @category Front-controller
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @link http://codeigniter.com/user_guide/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CodeIgniter Version
|
||||
*
|
||||
* @var string
|
||||
*
|
||||
*/
|
||||
define('CI_VERSION', '2.1.3');
|
||||
|
||||
/**
|
||||
* CodeIgniter Branch (Core = TRUE, Reactor = FALSE)
|
||||
*
|
||||
* @var boolean
|
||||
*
|
||||
*/
|
||||
define('CI_CORE', FALSE);
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Load the global functions
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
require(BASEPATH.'core/Common.php');
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Load the framework constants
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/constants.php'))
|
||||
{
|
||||
require(APPPATH.'config/'.ENVIRONMENT.'/constants.php');
|
||||
}
|
||||
else
|
||||
{
|
||||
require(APPPATH.'config/constants.php');
|
||||
}
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Define a custom error handler so we can log PHP errors
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
set_error_handler('_exception_handler');
|
||||
|
||||
if ( ! is_php('5.3'))
|
||||
{
|
||||
@set_magic_quotes_runtime(0); // Kill magic quotes
|
||||
}
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Set the subclass_prefix
|
||||
* ------------------------------------------------------
|
||||
*
|
||||
* Normally the "subclass_prefix" is set in the config file.
|
||||
* The subclass prefix allows CI to know if a core class is
|
||||
* being extended via a library in the local application
|
||||
* "libraries" folder. Since CI allows config items to be
|
||||
* overriden via data set in the main index. php file,
|
||||
* before proceeding we need to know if a subclass_prefix
|
||||
* override exists. If so, we will set this value now,
|
||||
* before any classes are loaded
|
||||
* Note: Since the config file data is cached it doesn't
|
||||
* hurt to load it here.
|
||||
*/
|
||||
if (isset($assign_to_config['subclass_prefix']) AND $assign_to_config['subclass_prefix'] != '')
|
||||
{
|
||||
get_config(array('subclass_prefix' => $assign_to_config['subclass_prefix']));
|
||||
}
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Set a liberal script execution time limit
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
if (function_exists("set_time_limit") == TRUE AND @ini_get("safe_mode") == 0)
|
||||
{
|
||||
@set_time_limit(300);
|
||||
}
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Start the timer... tick tock tick tock...
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
$BM =& load_class('Benchmark', 'core');
|
||||
$BM->mark('total_execution_time_start');
|
||||
$BM->mark('loading_time:_base_classes_start');
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Instantiate the hooks class
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
$EXT =& load_class('Hooks', 'core');
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Is there a "pre_system" hook?
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
$EXT->_call_hook('pre_system');
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Instantiate the config class
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
$CFG =& load_class('Config', 'core');
|
||||
|
||||
// Do we have any manually set config items in the index.php file?
|
||||
if (isset($assign_to_config))
|
||||
{
|
||||
$CFG->_assign_to_config($assign_to_config);
|
||||
}
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Instantiate the UTF-8 class
|
||||
* ------------------------------------------------------
|
||||
*
|
||||
* Note: Order here is rather important as the UTF-8
|
||||
* class needs to be used very early on, but it cannot
|
||||
* properly determine if UTf-8 can be supported until
|
||||
* after the Config class is instantiated.
|
||||
*
|
||||
*/
|
||||
|
||||
$UNI =& load_class('Utf8', 'core');
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Instantiate the URI class
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
$URI =& load_class('URI', 'core');
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Instantiate the routing class and set the routing
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
$RTR =& load_class('Router', 'core');
|
||||
$RTR->_set_routing();
|
||||
|
||||
// Set any routing overrides that may exist in the main index file
|
||||
if (isset($routing))
|
||||
{
|
||||
$RTR->_set_overrides($routing);
|
||||
}
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Instantiate the output class
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
$OUT =& load_class('Output', 'core');
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Is there a valid cache file? If so, we're done...
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
if ($EXT->_call_hook('cache_override') === FALSE)
|
||||
{
|
||||
if ($OUT->_display_cache($CFG, $URI) == TRUE)
|
||||
{
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------
|
||||
* Load the security class for xss and csrf support
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
$SEC =& load_class('Security', 'core');
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Load the Input class and sanitize globals
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
$IN =& load_class('Input', 'core');
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Load the Language class
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
$LANG =& load_class('Lang', 'core');
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Load the app controller and local controller
|
||||
* ------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
// Load the base controller class
|
||||
require BASEPATH.'core/Controller.php';
|
||||
|
||||
function &get_instance()
|
||||
{
|
||||
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';
|
||||
}
|
||||
|
||||
// Load the local application controller
|
||||
// Note: The Router class automatically validates the controller path using the router->_validate_request().
|
||||
// If this include fails it means that the default controller in the Routes.php file is not resolving to something valid.
|
||||
if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php'))
|
||||
{
|
||||
show_error('Unable to load your default controller. Please make sure the controller specified in your Routes.php file is valid.');
|
||||
}
|
||||
|
||||
include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php');
|
||||
|
||||
// Set a mark point for benchmarking
|
||||
$BM->mark('loading_time:_base_classes_end');
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Security check
|
||||
* ------------------------------------------------------
|
||||
*
|
||||
* None of the functions in the app controller or the
|
||||
* loader class can be called via the URI, nor can
|
||||
* controller functions that begin with an underscore
|
||||
*/
|
||||
$class = $RTR->fetch_class();
|
||||
$method = $RTR->fetch_method();
|
||||
|
||||
if ( ! class_exists($class)
|
||||
OR strncmp($method, '_', 1) == 0
|
||||
OR in_array(strtolower($method), array_map('strtolower', get_class_methods('CI_Controller')))
|
||||
)
|
||||
{
|
||||
if ( ! empty($RTR->routes['404_override']))
|
||||
{
|
||||
$x = explode('/', $RTR->routes['404_override']);
|
||||
$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');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
show_404("{$class}/{$method}");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Is there a "pre_controller" hook?
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
$EXT->_call_hook('pre_controller');
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Instantiate the requested controller
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
// Mark a start point so we can benchmark the controller
|
||||
$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_start');
|
||||
|
||||
$CI = new $class();
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Is there a "post_controller_constructor" hook?
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
$EXT->_call_hook('post_controller_constructor');
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* 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']);
|
||||
$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));
|
||||
}
|
||||
|
||||
|
||||
// Mark a benchmark end point
|
||||
$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end');
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Is there a "post_controller" hook?
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
$EXT->_call_hook('post_controller');
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Send the final rendered output to the browser
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
if ($EXT->_call_hook('display_override') === FALSE)
|
||||
{
|
||||
$OUT->_display();
|
||||
}
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Is there a "post_system" hook?
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
$EXT->_call_hook('post_system');
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
* Close the DB connection if one exists
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
if (class_exists('CI_DB') AND isset($CI->db))
|
||||
{
|
||||
$CI->db->close();
|
||||
}
|
||||
|
||||
|
||||
/* End of file CodeIgniter.php */
|
||||
/* Location: ./system/core/CodeIgniter.php */
|
564
system/core/Common.php
Normal file
564
system/core/Common.php
Normal file
@ -0,0 +1,564 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP 5.1.6 or newer
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
|
||||
* @license http://codeigniter.com/user_guide/license.html
|
||||
* @link http://codeigniter.com
|
||||
* @since Version 1.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Common Functions
|
||||
*
|
||||
* Loads the base classes and executes the request.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage codeigniter
|
||||
* @category Common Functions
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @link http://codeigniter.com/user_guide/
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Determines if the current version of PHP is greater then the supplied value
|
||||
*
|
||||
* Since there are a few places where we conditionally test for PHP > 5
|
||||
* we'll set a static variable.
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @return bool TRUE if the current version is $version or higher
|
||||
*/
|
||||
if ( ! function_exists('is_php'))
|
||||
{
|
||||
function is_php($version = '5.0.0')
|
||||
{
|
||||
static $_is_php;
|
||||
$version = (string)$version;
|
||||
|
||||
if ( ! isset($_is_php[$version]))
|
||||
{
|
||||
$_is_php[$version] = (version_compare(PHP_VERSION, $version) < 0) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
return $_is_php[$version];
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Tests for file writability
|
||||
*
|
||||
* is_writable() returns TRUE on Windows servers when you really can't write to
|
||||
* the file, based on the read-only attribute. is_writable() is also unreliable
|
||||
* on Unix servers if safe_mode is on.
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
if ( ! function_exists('is_really_writable'))
|
||||
{
|
||||
function is_really_writable($file)
|
||||
{
|
||||
// If we're on a Unix server with safe_mode off we call is_writable
|
||||
if (DIRECTORY_SEPARATOR == '/' AND @ini_get("safe_mode") == FALSE)
|
||||
{
|
||||
return is_writable($file);
|
||||
}
|
||||
|
||||
// For windows servers and safe_mode "on" installations we'll actually
|
||||
// write a file then read it. Bah...
|
||||
if (is_dir($file))
|
||||
{
|
||||
$file = rtrim($file, '/').'/'.md5(mt_rand(1,100).mt_rand(1,100));
|
||||
|
||||
if (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
@chmod($file, DIR_WRITE_MODE);
|
||||
@unlink($file);
|
||||
return TRUE;
|
||||
}
|
||||
elseif ( ! is_file($file) OR ($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Class registry
|
||||
*
|
||||
* This function acts as a singleton. If the requested class does not
|
||||
* exist it is instantiated and set to a static variable. If it has
|
||||
* previously been instantiated the variable is returned.
|
||||
*
|
||||
* @access public
|
||||
* @param string the class name being requested
|
||||
* @param string the directory where the class should be found
|
||||
* @param string the class name prefix
|
||||
* @return object
|
||||
*/
|
||||
if ( ! function_exists('load_class'))
|
||||
{
|
||||
function &load_class($class, $directory = 'libraries', $prefix = 'CI_')
|
||||
{
|
||||
static $_classes = array();
|
||||
|
||||
// Does the class exist? If so, we're done...
|
||||
if (isset($_classes[$class]))
|
||||
{
|
||||
return $_classes[$class];
|
||||
}
|
||||
|
||||
$name = FALSE;
|
||||
|
||||
// Look for the class first in the local application/libraries folder
|
||||
// then in the native system/libraries folder
|
||||
foreach (array(APPPATH, BASEPATH) as $path)
|
||||
{
|
||||
if (file_exists($path.$directory.'/'.$class.'.php'))
|
||||
{
|
||||
$name = $prefix.$class;
|
||||
|
||||
if (class_exists($name) === FALSE)
|
||||
{
|
||||
require($path.$directory.'/'.$class.'.php');
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Is the request a class extension? If so we load it too
|
||||
if (file_exists(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php'))
|
||||
{
|
||||
$name = config_item('subclass_prefix').$class;
|
||||
|
||||
if (class_exists($name) === FALSE)
|
||||
{
|
||||
require(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php');
|
||||
}
|
||||
}
|
||||
|
||||
// Did we find the class?
|
||||
if ($name === FALSE)
|
||||
{
|
||||
// Note: We use exit() rather then show_error() in order to avoid a
|
||||
// self-referencing loop with the Excptions class
|
||||
exit('Unable to locate the specified class: '.$class.'.php');
|
||||
}
|
||||
|
||||
// Keep track of what we just loaded
|
||||
is_loaded($class);
|
||||
|
||||
$_classes[$class] = new $name();
|
||||
return $_classes[$class];
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Keeps track of which libraries have been loaded. This function is
|
||||
* called by the load_class() function above
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
if ( ! function_exists('is_loaded'))
|
||||
{
|
||||
function &is_loaded($class = '')
|
||||
{
|
||||
static $_is_loaded = array();
|
||||
|
||||
if ($class != '')
|
||||
{
|
||||
$_is_loaded[strtolower($class)] = $class;
|
||||
}
|
||||
|
||||
return $_is_loaded;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Loads the main config.php file
|
||||
*
|
||||
* This function lets us grab the config file even if the Config class
|
||||
* hasn't been instantiated yet
|
||||
*
|
||||
* @access private
|
||||
* @return array
|
||||
*/
|
||||
if ( ! function_exists('get_config'))
|
||||
{
|
||||
function &get_config($replace = array())
|
||||
{
|
||||
static $_config;
|
||||
|
||||
if (isset($_config))
|
||||
{
|
||||
return $_config[0];
|
||||
}
|
||||
|
||||
// Is the config file in the environment folder?
|
||||
if ( ! defined('ENVIRONMENT') OR ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php'))
|
||||
{
|
||||
$file_path = APPPATH.'config/config.php';
|
||||
}
|
||||
|
||||
// Fetch the config file
|
||||
if ( ! file_exists($file_path))
|
||||
{
|
||||
exit('The configuration file does not exist.');
|
||||
}
|
||||
|
||||
require($file_path);
|
||||
|
||||
// Does the $config array exist in the file?
|
||||
if ( ! isset($config) OR ! is_array($config))
|
||||
{
|
||||
exit('Your config file does not appear to be formatted correctly.');
|
||||
}
|
||||
|
||||
// Are any values being dynamically replaced?
|
||||
if (count($replace) > 0)
|
||||
{
|
||||
foreach ($replace as $key => $val)
|
||||
{
|
||||
if (isset($config[$key]))
|
||||
{
|
||||
$config[$key] = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $_config[0] =& $config;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the specified config item
|
||||
*
|
||||
* @access public
|
||||
* @return mixed
|
||||
*/
|
||||
if ( ! function_exists('config_item'))
|
||||
{
|
||||
function config_item($item)
|
||||
{
|
||||
static $_config_item = array();
|
||||
|
||||
if ( ! isset($_config_item[$item]))
|
||||
{
|
||||
$config =& get_config();
|
||||
|
||||
if ( ! isset($config[$item]))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
$_config_item[$item] = $config[$item];
|
||||
}
|
||||
|
||||
return $_config_item[$item];
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Error Handler
|
||||
*
|
||||
* This function lets us invoke the exception class and
|
||||
* display errors using the standard error template located
|
||||
* in application/errors/errors.php
|
||||
* This function will send the error page directly to the
|
||||
* browser and exit.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
if ( ! function_exists('show_error'))
|
||||
{
|
||||
function show_error($message, $status_code = 500, $heading = 'An Error Was Encountered')
|
||||
{
|
||||
$_error =& load_class('Exceptions', 'core');
|
||||
echo $_error->show_error($heading, $message, 'error_general', $status_code);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 404 Page Handler
|
||||
*
|
||||
* This function is similar to the show_error() function above
|
||||
* However, instead of the standard error template it displays
|
||||
* 404 errors.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
if ( ! function_exists('show_404'))
|
||||
{
|
||||
function show_404($page = '', $log_error = TRUE)
|
||||
{
|
||||
$_error =& load_class('Exceptions', 'core');
|
||||
$_error->show_404($page, $log_error);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Error Logging Interface
|
||||
*
|
||||
* We use this as a simple mechanism to access the logging
|
||||
* class and send messages to be logged.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
if ( ! function_exists('log_message'))
|
||||
{
|
||||
function log_message($level = 'error', $message, $php_error = FALSE)
|
||||
{
|
||||
static $_log;
|
||||
|
||||
if (config_item('log_threshold') == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$_log =& load_class('Log');
|
||||
$_log->write_log($level, $message, $php_error);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set HTTP Status Header
|
||||
*
|
||||
* @access public
|
||||
* @param int the status code
|
||||
* @param string
|
||||
* @return void
|
||||
*/
|
||||
if ( ! function_exists('set_status_header'))
|
||||
{
|
||||
function set_status_header($code = 200, $text = '')
|
||||
{
|
||||
$stati = array(
|
||||
200 => 'OK',
|
||||
201 => 'Created',
|
||||
202 => 'Accepted',
|
||||
203 => 'Non-Authoritative Information',
|
||||
204 => 'No Content',
|
||||
205 => 'Reset Content',
|
||||
206 => 'Partial Content',
|
||||
|
||||
300 => 'Multiple Choices',
|
||||
301 => 'Moved Permanently',
|
||||
302 => 'Found',
|
||||
304 => 'Not Modified',
|
||||
305 => 'Use Proxy',
|
||||
307 => 'Temporary Redirect',
|
||||
|
||||
400 => 'Bad Request',
|
||||
401 => 'Unauthorized',
|
||||
403 => 'Forbidden',
|
||||
404 => 'Not Found',
|
||||
405 => 'Method Not Allowed',
|
||||
406 => 'Not Acceptable',
|
||||
407 => 'Proxy Authentication Required',
|
||||
408 => 'Request Timeout',
|
||||
409 => 'Conflict',
|
||||
410 => 'Gone',
|
||||
411 => 'Length Required',
|
||||
412 => 'Precondition Failed',
|
||||
413 => 'Request Entity Too Large',
|
||||
414 => 'Request-URI Too Long',
|
||||
415 => 'Unsupported Media Type',
|
||||
416 => 'Requested Range Not Satisfiable',
|
||||
417 => 'Expectation Failed',
|
||||
|
||||
500 => 'Internal Server Error',
|
||||
501 => 'Not Implemented',
|
||||
502 => 'Bad Gateway',
|
||||
503 => 'Service Unavailable',
|
||||
504 => 'Gateway Timeout',
|
||||
505 => 'HTTP Version Not Supported'
|
||||
);
|
||||
|
||||
if ($code == '' OR ! is_numeric($code))
|
||||
{
|
||||
show_error('Status codes must be numeric', 500);
|
||||
}
|
||||
|
||||
if (isset($stati[$code]) AND $text == '')
|
||||
{
|
||||
$text = $stati[$code];
|
||||
}
|
||||
|
||||
if ($text == '')
|
||||
{
|
||||
show_error('No status text available. Please check your status code number or supply your own message text.', 500);
|
||||
}
|
||||
|
||||
$server_protocol = (isset($_SERVER['SERVER_PROTOCOL'])) ? $_SERVER['SERVER_PROTOCOL'] : FALSE;
|
||||
|
||||
if (substr(php_sapi_name(), 0, 3) == 'cgi')
|
||||
{
|
||||
header("Status: {$code} {$text}", TRUE);
|
||||
}
|
||||
elseif ($server_protocol == 'HTTP/1.1' OR $server_protocol == 'HTTP/1.0')
|
||||
{
|
||||
header($server_protocol." {$code} {$text}", TRUE, $code);
|
||||
}
|
||||
else
|
||||
{
|
||||
header("HTTP/1.1 {$code} {$text}", TRUE, $code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Exception Handler
|
||||
*
|
||||
* This is the custom exception handler that is declaired at the top
|
||||
* of Codeigniter.php. The main reason we use this is to permit
|
||||
* PHP errors to be logged in our own log files since the user may
|
||||
* not have access to server logs. Since this function
|
||||
* effectively intercepts PHP errors, however, we also need
|
||||
* to display errors based on the current error_reporting level.
|
||||
* We do that with the use of a PHP error template.
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
if ( ! function_exists('_exception_handler'))
|
||||
{
|
||||
function _exception_handler($severity, $message, $filepath, $line)
|
||||
{
|
||||
// We don't bother with "strict" notices since they tend to fill up
|
||||
// the log file with excess information that isn't normally very helpful.
|
||||
// For example, if you are running PHP 5 and you use version 4 style
|
||||
// class functions (without prefixes like "public", "private", etc.)
|
||||
// you'll get notices telling you that these have been deprecated.
|
||||
if ($severity == E_STRICT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$_error =& load_class('Exceptions', 'core');
|
||||
|
||||
// Should we display the error? We'll get the current error_reporting
|
||||
// level and add its bits with the severity bits to find out.
|
||||
if (($severity & error_reporting()) == $severity)
|
||||
{
|
||||
$_error->show_php_error($severity, $message, $filepath, $line);
|
||||
}
|
||||
|
||||
// Should we log the error? No? We're done...
|
||||
if (config_item('log_threshold') == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$_error->log_exception($severity, $message, $filepath, $line);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Remove Invisible Characters
|
||||
*
|
||||
* This prevents sandwiching null characters
|
||||
* between ascii characters, like Java\0script.
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
if ( ! function_exists('remove_invisible_characters'))
|
||||
{
|
||||
function remove_invisible_characters($str, $url_encoded = TRUE)
|
||||
{
|
||||
$non_displayables = array();
|
||||
|
||||
// every control character except newline (dec 10)
|
||||
// carriage return (dec 13), and horizontal tab (dec 09)
|
||||
|
||||
if ($url_encoded)
|
||||
{
|
||||
$non_displayables[] = '/%0[0-8bcef]/'; // url encoded 00-08, 11, 12, 14, 15
|
||||
$non_displayables[] = '/%1[0-9a-f]/'; // url encoded 16-31
|
||||
}
|
||||
|
||||
$non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S'; // 00-08, 11, 12, 14-31, 127
|
||||
|
||||
do
|
||||
{
|
||||
$str = preg_replace($non_displayables, '', $str, -1, $count);
|
||||
}
|
||||
while ($count);
|
||||
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns HTML escaped variable
|
||||
*
|
||||
* @access public
|
||||
* @param mixed
|
||||
* @return mixed
|
||||
*/
|
||||
if ( ! function_exists('html_escape'))
|
||||
{
|
||||
function html_escape($var)
|
||||
{
|
||||
if (is_array($var))
|
||||
{
|
||||
return array_map('html_escape', $var);
|
||||
}
|
||||
else
|
||||
{
|
||||
return htmlspecialchars($var, ENT_QUOTES, config_item('charset'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* End of file Common.php */
|
||||
/* Location: ./system/core/Common.php */
|
379
system/core/Config.php
Normal file
379
system/core/Config.php
Normal file
@ -0,0 +1,379 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP 5.1.6 or newer
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
|
||||
* @license http://codeigniter.com/user_guide/license.html
|
||||
* @link http://codeigniter.com
|
||||
* @since Version 1.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* CodeIgniter Config Class
|
||||
*
|
||||
* This class contains functions that enable config files to be managed
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Libraries
|
||||
* @category Libraries
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @link http://codeigniter.com/user_guide/libraries/config.html
|
||||
*/
|
||||
class CI_Config {
|
||||
|
||||
/**
|
||||
* List of all loaded config values
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $config = array();
|
||||
/**
|
||||
* List of all loaded config files
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $is_loaded = array();
|
||||
/**
|
||||
* List of paths to search when trying to load a config file
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $_config_paths = array(APPPATH);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Sets the $config data from the primary config.php file as a class variable
|
||||
*
|
||||
* @access public
|
||||
* @param string the config file name
|
||||
* @param boolean if configuration values should be loaded into their own section
|
||||
* @param boolean true if errors should just return false, false if an error message should be displayed
|
||||
* @return boolean if the file was successfully loaded or not
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
$this->config =& get_config();
|
||||
log_message('debug', "Config Class Initialized");
|
||||
|
||||
// Set the base_url automatically if none was provided
|
||||
if ($this->config['base_url'] == '')
|
||||
{
|
||||
if (isset($_SERVER['HTTP_HOST']))
|
||||
{
|
||||
$base_url = isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off' ? 'https' : 'http';
|
||||
$base_url .= '://'. $_SERVER['HTTP_HOST'];
|
||||
$base_url .= str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
$base_url = 'http://localhost/';
|
||||
}
|
||||
|
||||
$this->set_item('base_url', $base_url);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Load Config File
|
||||
*
|
||||
* @access public
|
||||
* @param string the config file name
|
||||
* @param boolean if configuration values should be loaded into their own section
|
||||
* @param boolean true if errors should just return false, false if an error message should be displayed
|
||||
* @return boolean if the file was loaded correctly
|
||||
*/
|
||||
function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
|
||||
{
|
||||
$file = ($file == '') ? 'config' : str_replace('.php', '', $file);
|
||||
$found = FALSE;
|
||||
$loaded = FALSE;
|
||||
|
||||
$check_locations = defined('ENVIRONMENT')
|
||||
? array(ENVIRONMENT.'/'.$file, $file)
|
||||
: array($file);
|
||||
|
||||
foreach ($this->_config_paths as $path)
|
||||
{
|
||||
foreach ($check_locations as $location)
|
||||
{
|
||||
$file_path = $path.'config/'.$location.'.php';
|
||||
|
||||
if (in_array($file_path, $this->is_loaded, TRUE))
|
||||
{
|
||||
$loaded = TRUE;
|
||||
continue 2;
|
||||
}
|
||||
|
||||
if (file_exists($file_path))
|
||||
{
|
||||
$found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($found === FALSE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
include($file_path);
|
||||
|
||||
if ( ! isset($config) OR ! is_array($config))
|
||||
{
|
||||
if ($fail_gracefully === TRUE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
show_error('Your '.$file_path.' file does not appear to contain a valid configuration array.');
|
||||
}
|
||||
|
||||
if ($use_sections === TRUE)
|
||||
{
|
||||
if (isset($this->config[$file]))
|
||||
{
|
||||
$this->config[$file] = array_merge($this->config[$file], $config);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->config[$file] = $config;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->config = array_merge($this->config, $config);
|
||||
}
|
||||
|
||||
$this->is_loaded[] = $file_path;
|
||||
unset($config);
|
||||
|
||||
$loaded = TRUE;
|
||||
log_message('debug', 'Config file loaded: '.$file_path);
|
||||
break;
|
||||
}
|
||||
|
||||
if ($loaded === FALSE)
|
||||
{
|
||||
if ($fail_gracefully === TRUE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
show_error('The configuration file '.$file.'.php does not exist.');
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch a config file item
|
||||
*
|
||||
*
|
||||
* @access public
|
||||
* @param string the config item name
|
||||
* @param string the index name
|
||||
* @param bool
|
||||
* @return string
|
||||
*/
|
||||
function item($item, $index = '')
|
||||
{
|
||||
if ($index == '')
|
||||
{
|
||||
if ( ! isset($this->config[$item]))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$pref = $this->config[$item];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ! isset($this->config[$index]))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( ! isset($this->config[$index][$item]))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$pref = $this->config[$index][$item];
|
||||
}
|
||||
|
||||
return $pref;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch a config file item - adds slash after item (if item is not empty)
|
||||
*
|
||||
* @access public
|
||||
* @param string the config item name
|
||||
* @param bool
|
||||
* @return string
|
||||
*/
|
||||
function slash_item($item)
|
||||
{
|
||||
if ( ! isset($this->config[$item]))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if( trim($this->config[$item]) == '')
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
return rtrim($this->config[$item], '/').'/';
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Site URL
|
||||
* Returns base_url . index_page [. uri_string]
|
||||
*
|
||||
* @access public
|
||||
* @param string the URI string
|
||||
* @return string
|
||||
*/
|
||||
function site_url($uri = '')
|
||||
{
|
||||
if ($uri == '')
|
||||
{
|
||||
return $this->slash_item('base_url').$this->item('index_page');
|
||||
}
|
||||
|
||||
if ($this->item('enable_query_strings') == FALSE)
|
||||
{
|
||||
$suffix = ($this->item('url_suffix') == FALSE) ? '' : $this->item('url_suffix');
|
||||
return $this->slash_item('base_url').$this->slash_item('index_page').$this->_uri_string($uri).$suffix;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->slash_item('base_url').$this->item('index_page').'?'.$this->_uri_string($uri);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Base URL
|
||||
* Returns base_url [. uri_string]
|
||||
*
|
||||
* @access public
|
||||
* @param string $uri
|
||||
* @return string
|
||||
*/
|
||||
function base_url($uri = '')
|
||||
{
|
||||
return $this->slash_item('base_url').ltrim($this->_uri_string($uri), '/');
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Build URI string for use in Config::site_url() and Config::base_url()
|
||||
*
|
||||
* @access protected
|
||||
* @param $uri
|
||||
* @return string
|
||||
*/
|
||||
protected function _uri_string($uri)
|
||||
{
|
||||
if ($this->item('enable_query_strings') == FALSE)
|
||||
{
|
||||
if (is_array($uri))
|
||||
{
|
||||
$uri = implode('/', $uri);
|
||||
}
|
||||
$uri = trim($uri, '/');
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_array($uri))
|
||||
{
|
||||
$i = 0;
|
||||
$str = '';
|
||||
foreach ($uri as $key => $val)
|
||||
{
|
||||
$prefix = ($i == 0) ? '' : '&';
|
||||
$str .= $prefix.$key.'='.$val;
|
||||
$i++;
|
||||
}
|
||||
$uri = $str;
|
||||
}
|
||||
}
|
||||
return $uri;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* System URL
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function system_url()
|
||||
{
|
||||
$x = explode("/", preg_replace("|/*(.+?)/*$|", "\\1", BASEPATH));
|
||||
return $this->slash_item('base_url').end($x).'/';
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set a config file item
|
||||
*
|
||||
* @access public
|
||||
* @param string the config item key
|
||||
* @param string the config item value
|
||||
* @return void
|
||||
*/
|
||||
function set_item($item, $value)
|
||||
{
|
||||
$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
|
||||
*
|
||||
* @access private
|
||||
* @param array
|
||||
* @return void
|
||||
*/
|
||||
function _assign_to_config($items = array())
|
||||
{
|
||||
if (is_array($items))
|
||||
{
|
||||
foreach ($items as $key => $val)
|
||||
{
|
||||
$this->set_item($key, $val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// END CI_Config class
|
||||
|
||||
/* End of file Config.php */
|
||||
/* Location: ./system/core/Config.php */
|
64
system/core/Controller.php
Normal file
64
system/core/Controller.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP 5.1.6 or newer
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
|
||||
* @license http://codeigniter.com/user_guide/license.html
|
||||
* @link http://codeigniter.com
|
||||
* @since Version 1.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* CodeIgniter Application Controller Class
|
||||
*
|
||||
* This class object is the super class that every library in
|
||||
* CodeIgniter will be assigned to.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Libraries
|
||||
* @category Libraries
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @link http://codeigniter.com/user_guide/general/controllers.html
|
||||
*/
|
||||
class CI_Controller {
|
||||
|
||||
private static $instance;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
self::$instance =& $this;
|
||||
|
||||
// Assign all the class objects that were instantiated by the
|
||||
// bootstrap file (CodeIgniter.php) to local class variables
|
||||
// so that CI can run as one big super object.
|
||||
foreach (is_loaded() as $var => $class)
|
||||
{
|
||||
$this->$var =& load_class($class);
|
||||
}
|
||||
|
||||
$this->load =& load_class('Loader', 'core');
|
||||
|
||||
$this->load->initialize();
|
||||
|
||||
log_message('debug', "Controller Class Initialized");
|
||||
}
|
||||
|
||||
public static function &get_instance()
|
||||
{
|
||||
return self::$instance;
|
||||
}
|
||||
}
|
||||
// END Controller class
|
||||
|
||||
/* End of file Controller.php */
|
||||
/* Location: ./system/core/Controller.php */
|
193
system/core/Exceptions.php
Normal file
193
system/core/Exceptions.php
Normal file
@ -0,0 +1,193 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP 5.1.6 or newer
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
|
||||
* @license http://codeigniter.com/user_guide/license.html
|
||||
* @link http://codeigniter.com
|
||||
* @since Version 1.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Exceptions Class
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Libraries
|
||||
* @category Exceptions
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @link http://codeigniter.com/user_guide/libraries/exceptions.html
|
||||
*/
|
||||
class CI_Exceptions {
|
||||
var $action;
|
||||
var $severity;
|
||||
var $message;
|
||||
var $filename;
|
||||
var $line;
|
||||
|
||||
/**
|
||||
* Nesting level of the output buffering mechanism
|
||||
*
|
||||
* @var int
|
||||
* @access public
|
||||
*/
|
||||
var $ob_level;
|
||||
|
||||
/**
|
||||
* List if available error levels
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
var $levels = array(
|
||||
E_ERROR => 'Error',
|
||||
E_WARNING => 'Warning',
|
||||
E_PARSE => 'Parsing Error',
|
||||
E_NOTICE => 'Notice',
|
||||
E_CORE_ERROR => 'Core Error',
|
||||
E_CORE_WARNING => 'Core Warning',
|
||||
E_COMPILE_ERROR => 'Compile Error',
|
||||
E_COMPILE_WARNING => 'Compile Warning',
|
||||
E_USER_ERROR => 'User Error',
|
||||
E_USER_WARNING => 'User Warning',
|
||||
E_USER_NOTICE => 'User Notice',
|
||||
E_STRICT => 'Runtime Notice'
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->ob_level = ob_get_level();
|
||||
// Note: Do not log messages from this constructor.
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Exception Logger
|
||||
*
|
||||
* This function logs PHP generated error messages
|
||||
*
|
||||
* @access private
|
||||
* @param string the error severity
|
||||
* @param string the error string
|
||||
* @param string the error filepath
|
||||
* @param string the error line number
|
||||
* @return string
|
||||
*/
|
||||
function log_exception($severity, $message, $filepath, $line)
|
||||
{
|
||||
$severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity];
|
||||
|
||||
log_message('error', 'Severity: '.$severity.' --> '.$message. ' '.$filepath.' '.$line, TRUE);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 404 Page Not Found Handler
|
||||
*
|
||||
* @access private
|
||||
* @param string the page
|
||||
* @param bool log error yes/no
|
||||
* @return string
|
||||
*/
|
||||
function show_404($page = '', $log_error = TRUE)
|
||||
{
|
||||
$heading = "404 Page Not Found";
|
||||
$message = "The page you requested was not found.";
|
||||
|
||||
// By default we log this, but allow a dev to skip it
|
||||
if ($log_error)
|
||||
{
|
||||
log_message('error', '404 Page Not Found --> '.$page);
|
||||
}
|
||||
|
||||
echo $this->show_error($heading, $message, 'error_404', 404);
|
||||
exit;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @access private
|
||||
* @param string the heading
|
||||
* @param string the message
|
||||
* @param string the template name
|
||||
* @param int the status code
|
||||
* @return string
|
||||
*/
|
||||
function show_error($heading, $message, $template = 'error_general', $status_code = 500)
|
||||
{
|
||||
set_status_header($status_code);
|
||||
|
||||
$message = '<p>'.implode('</p><p>', ( ! is_array($message)) ? array($message) : $message).'</p>';
|
||||
|
||||
if (ob_get_level() > $this->ob_level + 1)
|
||||
{
|
||||
ob_end_flush();
|
||||
}
|
||||
ob_start();
|
||||
include(APPPATH.'errors/'.$template.'.php');
|
||||
$buffer = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Native PHP error handler
|
||||
*
|
||||
* @access private
|
||||
* @param string the error severity
|
||||
* @param string the error string
|
||||
* @param string the error filepath
|
||||
* @param string the error line number
|
||||
* @return string
|
||||
*/
|
||||
function show_php_error($severity, $message, $filepath, $line)
|
||||
{
|
||||
$severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity];
|
||||
|
||||
$filepath = str_replace("\\", "/", $filepath);
|
||||
|
||||
// For safety reasons we do not show the full file path
|
||||
if (FALSE !== strpos($filepath, '/'))
|
||||
{
|
||||
$x = explode('/', $filepath);
|
||||
$filepath = $x[count($x)-2].'/'.end($x);
|
||||
}
|
||||
|
||||
if (ob_get_level() > $this->ob_level + 1)
|
||||
{
|
||||
ob_end_flush();
|
||||
}
|
||||
ob_start();
|
||||
include(APPPATH.'errors/error_php.php');
|
||||
$buffer = ob_get_contents();
|
||||
ob_end_clean();
|
||||
echo $buffer;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// END Exceptions Class
|
||||
|
||||
/* End of file Exceptions.php */
|
||||
/* Location: ./system/core/Exceptions.php */
|
248
system/core/Hooks.php
Normal file
248
system/core/Hooks.php
Normal file
@ -0,0 +1,248 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP 5.1.6 or newer
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
|
||||
* @license http://codeigniter.com/user_guide/license.html
|
||||
* @link http://codeigniter.com
|
||||
* @since Version 1.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* CodeIgniter Hooks Class
|
||||
*
|
||||
* Provides a mechanism to extend the base system without hacking.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Libraries
|
||||
* @category Libraries
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @link http://codeigniter.com/user_guide/libraries/encryption.html
|
||||
*/
|
||||
class CI_Hooks {
|
||||
|
||||
/**
|
||||
* Determines wether hooks are enabled
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
var $enabled = FALSE;
|
||||
/**
|
||||
* List of all hooks set in config/hooks.php
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $hooks = array();
|
||||
/**
|
||||
* Determines wether hook is in progress, used to prevent infinte loops
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
var $in_progress = FALSE;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
$this->_initialize();
|
||||
log_message('debug', "Hooks Class Initialized");
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Initialize the Hooks Preferences
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
function _initialize()
|
||||
{
|
||||
$CFG =& load_class('Config', 'core');
|
||||
|
||||
// If hooks are not enabled in the config file
|
||||
// there is nothing else to do
|
||||
|
||||
if ($CFG->item('enable_hooks') == FALSE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Grab the "hooks" definition file.
|
||||
// If there are no hooks, we're done.
|
||||
|
||||
if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'))
|
||||
{
|
||||
include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php');
|
||||
}
|
||||
elseif (is_file(APPPATH.'config/hooks.php'))
|
||||
{
|
||||
include(APPPATH.'config/hooks.php');
|
||||
}
|
||||
|
||||
|
||||
if ( ! isset($hook) OR ! is_array($hook))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->hooks =& $hook;
|
||||
$this->enabled = TRUE;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Call Hook
|
||||
*
|
||||
* Calls a particular hook
|
||||
*
|
||||
* @access private
|
||||
* @param string the hook name
|
||||
* @return mixed
|
||||
*/
|
||||
function _call_hook($which = '')
|
||||
{
|
||||
if ( ! $this->enabled OR ! isset($this->hooks[$which]))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0]))
|
||||
{
|
||||
foreach ($this->hooks[$which] as $val)
|
||||
{
|
||||
$this->_run_hook($val);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_run_hook($this->hooks[$which]);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Run Hook
|
||||
*
|
||||
* Runs a particular hook
|
||||
*
|
||||
* @access private
|
||||
* @param array the hook details
|
||||
* @return bool
|
||||
*/
|
||||
function _run_hook($data)
|
||||
{
|
||||
if ( ! is_array($data))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// -----------------------------------
|
||||
// Safety - Prevents run-away loops
|
||||
// -----------------------------------
|
||||
|
||||
// If the script being called happens to have the same
|
||||
// hook call within it a loop can happen
|
||||
|
||||
if ($this->in_progress == TRUE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// -----------------------------------
|
||||
// Set file path
|
||||
// -----------------------------------
|
||||
|
||||
if ( ! isset($data['filepath']) OR ! isset($data['filename']))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$filepath = APPPATH.$data['filepath'].'/'.$data['filename'];
|
||||
|
||||
if ( ! file_exists($filepath))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// -----------------------------------
|
||||
// Set class/function name
|
||||
// -----------------------------------
|
||||
|
||||
$class = FALSE;
|
||||
$function = FALSE;
|
||||
$params = '';
|
||||
|
||||
if (isset($data['class']) AND $data['class'] != '')
|
||||
{
|
||||
$class = $data['class'];
|
||||
}
|
||||
|
||||
if (isset($data['function']))
|
||||
{
|
||||
$function = $data['function'];
|
||||
}
|
||||
|
||||
if (isset($data['params']))
|
||||
{
|
||||
$params = $data['params'];
|
||||
}
|
||||
|
||||
if ($class === FALSE AND $function === FALSE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// -----------------------------------
|
||||
// Set the in_progress flag
|
||||
// -----------------------------------
|
||||
|
||||
$this->in_progress = TRUE;
|
||||
|
||||
// -----------------------------------
|
||||
// Call the requested class and/or function
|
||||
// -----------------------------------
|
||||
|
||||
if ($class !== FALSE)
|
||||
{
|
||||
if ( ! class_exists($class))
|
||||
{
|
||||
require($filepath);
|
||||
}
|
||||
|
||||
$HOOK = new $class;
|
||||
$HOOK->$function($params);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ! function_exists($function))
|
||||
{
|
||||
require($filepath);
|
||||
}
|
||||
|
||||
$function($params);
|
||||
}
|
||||
|
||||
$this->in_progress = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// END CI_Hooks class
|
||||
|
||||
/* End of file Hooks.php */
|
||||
/* Location: ./system/core/Hooks.php */
|
849
system/core/Input.php
Normal file
849
system/core/Input.php
Normal file
@ -0,0 +1,849 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP 5.1.6 or newer
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
|
||||
* @license http://codeigniter.com/user_guide/license.html
|
||||
* @link http://codeigniter.com
|
||||
* @since Version 1.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Input Class
|
||||
*
|
||||
* Pre-processes global input data for security
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Libraries
|
||||
* @category Input
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @link http://codeigniter.com/user_guide/libraries/input.html
|
||||
*/
|
||||
class CI_Input {
|
||||
|
||||
/**
|
||||
* IP address of the current user
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $ip_address = FALSE;
|
||||
/**
|
||||
* user agent (web browser) being used by the current user
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $user_agent = FALSE;
|
||||
/**
|
||||
* If FALSE, then $_GET will be set to an empty array
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
var $_allow_get_array = TRUE;
|
||||
/**
|
||||
* If TRUE, then newlines are standardized
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
var $_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
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
var $_enable_xss = FALSE;
|
||||
/**
|
||||
* Enables a CSRF cookie token to be set.
|
||||
* Set automatically based on config setting
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
var $_enable_csrf = FALSE;
|
||||
/**
|
||||
* List of all HTTP request headers
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $headers = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Sets whether to globally enable the XSS processing
|
||||
* and whether to allow the $_GET array
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
log_message('debug', "Input Class Initialized");
|
||||
|
||||
$this->_allow_get_array = (config_item('allow_get_array') === TRUE);
|
||||
$this->_enable_xss = (config_item('global_xss_filtering') === TRUE);
|
||||
$this->_enable_csrf = (config_item('csrf_protection') === TRUE);
|
||||
|
||||
global $SEC;
|
||||
$this->security =& $SEC;
|
||||
|
||||
// Do we need the UTF-8 class?
|
||||
if (UTF8_ENABLED === TRUE)
|
||||
{
|
||||
global $UNI;
|
||||
$this->uni =& $UNI;
|
||||
}
|
||||
|
||||
// Sanitize global arrays
|
||||
$this->_sanitize_globals();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch from array
|
||||
*
|
||||
* This is a helper function to retrieve values from global arrays
|
||||
*
|
||||
* @access private
|
||||
* @param array
|
||||
* @param string
|
||||
* @param bool
|
||||
* @return string
|
||||
*/
|
||||
function _fetch_from_array(&$array, $index = '', $xss_clean = FALSE)
|
||||
{
|
||||
if ( ! isset($array[$index]))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ($xss_clean === TRUE)
|
||||
{
|
||||
return $this->security->xss_clean($array[$index]);
|
||||
}
|
||||
|
||||
return $array[$index];
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch an item from the GET array
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @param bool
|
||||
* @return string
|
||||
*/
|
||||
function get($index = NULL, $xss_clean = FALSE)
|
||||
{
|
||||
// Check if a field has been provided
|
||||
if ($index === NULL AND ! empty($_GET))
|
||||
{
|
||||
$get = array();
|
||||
|
||||
// loop through the full _GET array
|
||||
foreach (array_keys($_GET) as $key)
|
||||
{
|
||||
$get[$key] = $this->_fetch_from_array($_GET, $key, $xss_clean);
|
||||
}
|
||||
return $get;
|
||||
}
|
||||
|
||||
return $this->_fetch_from_array($_GET, $index, $xss_clean);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch an item from the POST array
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @param bool
|
||||
* @return string
|
||||
*/
|
||||
function post($index = NULL, $xss_clean = FALSE)
|
||||
{
|
||||
// Check if a field has been provided
|
||||
if ($index === NULL AND ! empty($_POST))
|
||||
{
|
||||
$post = array();
|
||||
|
||||
// Loop through the full _POST array and return it
|
||||
foreach (array_keys($_POST) as $key)
|
||||
{
|
||||
$post[$key] = $this->_fetch_from_array($_POST, $key, $xss_clean);
|
||||
}
|
||||
return $post;
|
||||
}
|
||||
|
||||
return $this->_fetch_from_array($_POST, $index, $xss_clean);
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch an item from either the GET array or the POST
|
||||
*
|
||||
* @access public
|
||||
* @param string The index key
|
||||
* @param bool XSS cleaning
|
||||
* @return string
|
||||
*/
|
||||
function get_post($index = '', $xss_clean = FALSE)
|
||||
{
|
||||
if ( ! isset($_POST[$index]) )
|
||||
{
|
||||
return $this->get($index, $xss_clean);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->post($index, $xss_clean);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch an item from the COOKIE array
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @param bool
|
||||
* @return string
|
||||
*/
|
||||
function cookie($index = '', $xss_clean = FALSE)
|
||||
{
|
||||
return $this->_fetch_from_array($_COOKIE, $index, $xss_clean);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set cookie
|
||||
*
|
||||
* Accepts six parameter, or you can submit an associative
|
||||
* array in the first parameter containing all the values.
|
||||
*
|
||||
* @access public
|
||||
* @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
|
||||
* @return void
|
||||
*/
|
||||
function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE)
|
||||
{
|
||||
if (is_array($name))
|
||||
{
|
||||
// always leave 'name' in last place, as the loop will break otherwise, due to $$item
|
||||
foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'secure', 'name') as $item)
|
||||
{
|
||||
if (isset($name[$item]))
|
||||
{
|
||||
$$item = $name[$item];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($prefix == '' AND config_item('cookie_prefix') != '')
|
||||
{
|
||||
$prefix = config_item('cookie_prefix');
|
||||
}
|
||||
if ($domain == '' AND config_item('cookie_domain') != '')
|
||||
{
|
||||
$domain = config_item('cookie_domain');
|
||||
}
|
||||
if ($path == '/' AND config_item('cookie_path') != '/')
|
||||
{
|
||||
$path = config_item('cookie_path');
|
||||
}
|
||||
if ($secure == FALSE AND config_item('cookie_secure') != FALSE)
|
||||
{
|
||||
$secure = config_item('cookie_secure');
|
||||
}
|
||||
|
||||
if ( ! is_numeric($expire))
|
||||
{
|
||||
$expire = time() - 86500;
|
||||
}
|
||||
else
|
||||
{
|
||||
$expire = ($expire > 0) ? time() + $expire : 0;
|
||||
}
|
||||
|
||||
setcookie($prefix.$name, $value, $expire, $path, $domain, $secure);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch an item from the SERVER array
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @param bool
|
||||
* @return string
|
||||
*/
|
||||
function server($index = '', $xss_clean = FALSE)
|
||||
{
|
||||
return $this->_fetch_from_array($_SERVER, $index, $xss_clean);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch the IP Address
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function ip_address()
|
||||
{
|
||||
if ($this->ip_address !== FALSE)
|
||||
{
|
||||
return $this->ip_address;
|
||||
}
|
||||
|
||||
$proxy_ips = config_item('proxy_ips');
|
||||
if ( ! empty($proxy_ips))
|
||||
{
|
||||
$proxy_ips = explode(',', str_replace(' ', '', $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)) !== FALSE)
|
||||
{
|
||||
// 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.
|
||||
if (strpos($spoof, ',') !== FALSE)
|
||||
{
|
||||
$spoof = explode(',', $spoof, 2);
|
||||
$spoof = $spoof[0];
|
||||
}
|
||||
|
||||
if ( ! $this->valid_ip($spoof))
|
||||
{
|
||||
$spoof = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->ip_address = ($spoof !== FALSE && in_array($_SERVER['REMOTE_ADDR'], $proxy_ips, TRUE))
|
||||
? $spoof : $_SERVER['REMOTE_ADDR'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->ip_address = $_SERVER['REMOTE_ADDR'];
|
||||
}
|
||||
|
||||
if ( ! $this->valid_ip($this->ip_address))
|
||||
{
|
||||
$this->ip_address = '0.0.0.0';
|
||||
}
|
||||
|
||||
return $this->ip_address;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Validate IP Address
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @param string ipv4 or ipv6
|
||||
* @return bool
|
||||
*/
|
||||
public function valid_ip($ip, $which = '')
|
||||
{
|
||||
$which = strtolower($which);
|
||||
|
||||
// First check if filter_var is available
|
||||
if (is_callable('filter_var'))
|
||||
{
|
||||
switch ($which) {
|
||||
case 'ipv4':
|
||||
$flag = FILTER_FLAG_IPV4;
|
||||
break;
|
||||
case 'ipv6':
|
||||
$flag = FILTER_FLAG_IPV6;
|
||||
break;
|
||||
default:
|
||||
$flag = '';
|
||||
break;
|
||||
}
|
||||
|
||||
return (bool) filter_var($ip, FILTER_VALIDATE_IP, $flag);
|
||||
}
|
||||
|
||||
if ($which !== 'ipv6' && $which !== 'ipv4')
|
||||
{
|
||||
if (strpos($ip, ':') !== FALSE)
|
||||
{
|
||||
$which = 'ipv6';
|
||||
}
|
||||
elseif (strpos($ip, '.') !== FALSE)
|
||||
{
|
||||
$which = 'ipv4';
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
$func = '_valid_'.$which;
|
||||
return $this->$func($ip);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Validate IPv4 Address
|
||||
*
|
||||
* Updated version suggested by Geert De Deckere
|
||||
*
|
||||
* @access protected
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
protected function _valid_ipv4($ip)
|
||||
{
|
||||
$ip_segments = explode('.', $ip);
|
||||
|
||||
// Always 4 segments needed
|
||||
if (count($ip_segments) !== 4)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
// IP can not start with 0
|
||||
if ($ip_segments[0][0] == '0')
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Check each segment
|
||||
foreach ($ip_segments as $segment)
|
||||
{
|
||||
// IP segments must be digits and can not be
|
||||
// longer than 3 digits or greater then 255
|
||||
if ($segment == '' OR preg_match("/[^0-9]/", $segment) OR $segment > 255 OR strlen($segment) > 3)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Validate IPv6 Address
|
||||
*
|
||||
* @access protected
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
protected function _valid_ipv6($str)
|
||||
{
|
||||
// 8 groups, separated by :
|
||||
// 0-ffff per group
|
||||
// one set of consecutive 0 groups can be collapsed to ::
|
||||
|
||||
$groups = 8;
|
||||
$collapsed = FALSE;
|
||||
|
||||
$chunks = array_filter(
|
||||
preg_split('/(:{1,2})/', $str, NULL, PREG_SPLIT_DELIM_CAPTURE)
|
||||
);
|
||||
|
||||
// Rule out easy nonsense
|
||||
if (current($chunks) == ':' OR end($chunks) == ':')
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// PHP supports IPv4-mapped IPv6 addresses, so we'll expect those as well
|
||||
if (strpos(end($chunks), '.') !== FALSE)
|
||||
{
|
||||
$ipv4 = array_pop($chunks);
|
||||
|
||||
if ( ! $this->_valid_ipv4($ipv4))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$groups--;
|
||||
}
|
||||
|
||||
while ($seg = array_pop($chunks))
|
||||
{
|
||||
if ($seg[0] == ':')
|
||||
{
|
||||
if (--$groups == 0)
|
||||
{
|
||||
return FALSE; // too many groups
|
||||
}
|
||||
|
||||
if (strlen($seg) > 2)
|
||||
{
|
||||
return FALSE; // long separator
|
||||
}
|
||||
|
||||
if ($seg == '::')
|
||||
{
|
||||
if ($collapsed)
|
||||
{
|
||||
return FALSE; // multiple collapsed
|
||||
}
|
||||
|
||||
$collapsed = TRUE;
|
||||
}
|
||||
}
|
||||
elseif (preg_match("/[^0-9a-f]/i", $seg) OR strlen($seg) > 4)
|
||||
{
|
||||
return FALSE; // invalid segment
|
||||
}
|
||||
}
|
||||
|
||||
return $collapsed OR $groups == 1;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* User Agent
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function user_agent()
|
||||
{
|
||||
if ($this->user_agent !== FALSE)
|
||||
{
|
||||
return $this->user_agent;
|
||||
}
|
||||
|
||||
$this->user_agent = ( ! isset($_SERVER['HTTP_USER_AGENT'])) ? FALSE : $_SERVER['HTTP_USER_AGENT'];
|
||||
|
||||
return $this->user_agent;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Sanitize Globals
|
||||
*
|
||||
* This function does the following:
|
||||
*
|
||||
* Unsets $_GET data (if query strings are not enabled)
|
||||
*
|
||||
* Unsets all globals if register_globals is enabled
|
||||
*
|
||||
* Standardizes newline characters to \n
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
function _sanitize_globals()
|
||||
{
|
||||
// It would be "wrong" to unset any of these GLOBALS.
|
||||
$protected = array('_SERVER', '_GET', '_POST', '_FILES', '_REQUEST',
|
||||
'_SESSION', '_ENV', 'GLOBALS', 'HTTP_RAW_POST_DATA',
|
||||
'system_folder', 'application_folder', 'BM', 'EXT',
|
||||
'CFG', 'URI', 'RTR', 'OUT', 'IN');
|
||||
|
||||
// Unset globals for securiy.
|
||||
// This is effectively the same as register_globals = off
|
||||
foreach (array($_GET, $_POST, $_COOKIE) as $global)
|
||||
{
|
||||
if ( ! is_array($global))
|
||||
{
|
||||
if ( ! in_array($global, $protected))
|
||||
{
|
||||
global $$global;
|
||||
$$global = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($global as $key => $val)
|
||||
{
|
||||
if ( ! in_array($key, $protected))
|
||||
{
|
||||
global $$key;
|
||||
$$key = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Is $_GET data allowed? If not we'll set the $_GET to an empty array
|
||||
if ($this->_allow_get_array == FALSE)
|
||||
{
|
||||
$_GET = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_array($_GET) AND count($_GET) > 0)
|
||||
{
|
||||
foreach ($_GET as $key => $val)
|
||||
{
|
||||
$_GET[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean $_POST Data
|
||||
if (is_array($_POST) AND count($_POST) > 0)
|
||||
{
|
||||
foreach ($_POST as $key => $val)
|
||||
{
|
||||
$_POST[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
|
||||
}
|
||||
}
|
||||
|
||||
// Clean $_COOKIE Data
|
||||
if (is_array($_COOKIE) AND count($_COOKIE) > 0)
|
||||
{
|
||||
// Also get rid of specially treated cookies that might be set by a server
|
||||
// or silly application, that are of no use to a CI application anyway
|
||||
// but that when present will trip our 'Disallowed Key Characters' alarm
|
||||
// http://www.ietf.org/rfc/rfc2109.txt
|
||||
// note that the key names below are single quoted strings, and are not PHP variables
|
||||
unset($_COOKIE['$Version']);
|
||||
unset($_COOKIE['$Path']);
|
||||
unset($_COOKIE['$Domain']);
|
||||
|
||||
foreach ($_COOKIE as $key => $val)
|
||||
{
|
||||
$_COOKIE[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
|
||||
}
|
||||
}
|
||||
|
||||
// Sanitize PHP_SELF
|
||||
$_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']);
|
||||
|
||||
|
||||
// CSRF Protection check on HTTP requests
|
||||
if ($this->_enable_csrf == TRUE && ! $this->is_cli_request())
|
||||
{
|
||||
$this->security->csrf_verify();
|
||||
}
|
||||
|
||||
log_message('debug', "Global POST and COOKIE data sanitized");
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Clean Input Data
|
||||
*
|
||||
* This is a helper function. It escapes data and
|
||||
* standardizes newline characters to \n
|
||||
*
|
||||
* @access private
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function _clean_input_data($str)
|
||||
{
|
||||
if (is_array($str))
|
||||
{
|
||||
$new_array = array();
|
||||
foreach ($str as $key => $val)
|
||||
{
|
||||
$new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
|
||||
}
|
||||
return $new_array;
|
||||
}
|
||||
|
||||
/* We strip slashes if magic quotes is on to keep things consistent
|
||||
|
||||
NOTE: In PHP 5.4 get_magic_quotes_gpc() will always return 0 and
|
||||
it will probably not exist in future versions at all.
|
||||
*/
|
||||
if ( ! is_php('5.4') && get_magic_quotes_gpc())
|
||||
{
|
||||
$str = stripslashes($str);
|
||||
}
|
||||
|
||||
// Clean UTF-8 if supported
|
||||
if (UTF8_ENABLED === TRUE)
|
||||
{
|
||||
$str = $this->uni->clean_string($str);
|
||||
}
|
||||
|
||||
// Remove control characters
|
||||
$str = remove_invisible_characters($str);
|
||||
|
||||
// Should we filter the input data?
|
||||
if ($this->_enable_xss === TRUE)
|
||||
{
|
||||
$str = $this->security->xss_clean($str);
|
||||
}
|
||||
|
||||
// Standardize newlines if needed
|
||||
if ($this->_standardize_newlines == TRUE)
|
||||
{
|
||||
if (strpos($str, "\r") !== FALSE)
|
||||
{
|
||||
$str = str_replace(array("\r\n", "\r", "\r\n\n"), PHP_EOL, $str);
|
||||
}
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Clean Keys
|
||||
*
|
||||
* This is a helper function. 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.
|
||||
*
|
||||
* @access private
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function _clean_input_keys($str)
|
||||
{
|
||||
if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str))
|
||||
{
|
||||
exit('Disallowed Key Characters.');
|
||||
}
|
||||
|
||||
// Clean UTF-8 if supported
|
||||
if (UTF8_ENABLED === TRUE)
|
||||
{
|
||||
$str = $this->uni->clean_string($str);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function request_headers($xss_clean = FALSE)
|
||||
{
|
||||
// Look at Apache go!
|
||||
if (function_exists('apache_request_headers'))
|
||||
{
|
||||
$headers = apache_request_headers();
|
||||
}
|
||||
else
|
||||
{
|
||||
$headers['Content-Type'] = (isset($_SERVER['CONTENT_TYPE'])) ? $_SERVER['CONTENT_TYPE'] : @getenv('CONTENT_TYPE');
|
||||
|
||||
foreach ($_SERVER as $key => $val)
|
||||
{
|
||||
if (strncmp($key, 'HTTP_', 5) === 0)
|
||||
{
|
||||
$headers[substr($key, 5)] = $this->_fetch_from_array($_SERVER, $key, $xss_clean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// take SOME_HEADER and turn it into Some-Header
|
||||
foreach ($headers as $key => $val)
|
||||
{
|
||||
$key = str_replace('_', ' ', strtolower($key));
|
||||
$key = str_replace(' ', '-', ucwords($key));
|
||||
|
||||
$this->headers[$key] = $val;
|
||||
}
|
||||
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get Request Header
|
||||
*
|
||||
* Returns the value of a single member of the headers class member
|
||||
*
|
||||
* @param string array key for $this->headers
|
||||
* @param boolean XSS Clean or not
|
||||
* @return mixed FALSE on failure, string on success
|
||||
*/
|
||||
public function get_request_header($index, $xss_clean = FALSE)
|
||||
{
|
||||
if (empty($this->headers))
|
||||
{
|
||||
$this->request_headers();
|
||||
}
|
||||
|
||||
if ( ! isset($this->headers[$index]))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ($xss_clean === TRUE)
|
||||
{
|
||||
return $this->security->xss_clean($this->headers[$index]);
|
||||
}
|
||||
|
||||
return $this->headers[$index];
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Is ajax Request?
|
||||
*
|
||||
* Test to see if a request contains the HTTP_X_REQUESTED_WITH header
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_ajax_request()
|
||||
{
|
||||
return ($this->server('HTTP_X_REQUESTED_WITH') === 'XMLHttpRequest');
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Is cli Request?
|
||||
*
|
||||
* Test to see if a request was made from the command line
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_cli_request()
|
||||
{
|
||||
return (php_sapi_name() === 'cli' OR defined('STDIN'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* End of file Input.php */
|
||||
/* Location: ./system/core/Input.php */
|
160
system/core/Lang.php
Normal file
160
system/core/Lang.php
Normal file
@ -0,0 +1,160 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP 5.1.6 or newer
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
|
||||
* @license http://codeigniter.com/user_guide/license.html
|
||||
* @link http://codeigniter.com
|
||||
* @since Version 1.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Language Class
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Libraries
|
||||
* @category Language
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @link http://codeigniter.com/user_guide/libraries/language.html
|
||||
*/
|
||||
class CI_Lang {
|
||||
|
||||
/**
|
||||
* List of translations
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $language = array();
|
||||
/**
|
||||
* List of loaded language files
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $is_loaded = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
log_message('debug', "Language Class Initialized");
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Load a language file
|
||||
*
|
||||
* @access public
|
||||
* @param mixed the name of the language file to be loaded. Can be an array
|
||||
* @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
|
||||
*/
|
||||
function load($langfile = '', $idiom = '', $return = FALSE, $add_suffix = TRUE, $alt_path = '')
|
||||
{
|
||||
$langfile = str_replace('.php', '', $langfile);
|
||||
|
||||
if ($add_suffix == TRUE)
|
||||
{
|
||||
$langfile = str_replace('_lang.', '', $langfile).'_lang';
|
||||
}
|
||||
|
||||
$langfile .= '.php';
|
||||
|
||||
if (in_array($langfile, $this->is_loaded, TRUE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$config =& get_config();
|
||||
|
||||
if ($idiom == '')
|
||||
{
|
||||
$deft_lang = ( ! isset($config['language'])) ? 'english' : $config['language'];
|
||||
$idiom = ($deft_lang == '') ? 'english' : $deft_lang;
|
||||
}
|
||||
|
||||
// Determine where the language file is and load it
|
||||
if ($alt_path != '' && file_exists($alt_path.'language/'.$idiom.'/'.$langfile))
|
||||
{
|
||||
include($alt_path.'language/'.$idiom.'/'.$langfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
$found = FALSE;
|
||||
|
||||
foreach (get_instance()->load->get_package_paths(TRUE) as $package_path)
|
||||
{
|
||||
if (file_exists($package_path.'language/'.$idiom.'/'.$langfile))
|
||||
{
|
||||
include($package_path.'language/'.$idiom.'/'.$langfile);
|
||||
$found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($found !== TRUE)
|
||||
{
|
||||
show_error('Unable to load the requested language file: language/'.$idiom.'/'.$langfile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( ! isset($lang))
|
||||
{
|
||||
log_message('error', 'Language file contains no data: language/'.$idiom.'/'.$langfile);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($return == TRUE)
|
||||
{
|
||||
return $lang;
|
||||
}
|
||||
|
||||
$this->is_loaded[] = $langfile;
|
||||
$this->language = array_merge($this->language, $lang);
|
||||
unset($lang);
|
||||
|
||||
log_message('debug', 'Language file loaded: language/'.$idiom.'/'.$langfile);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch a single line of text from the language array
|
||||
*
|
||||
* @access public
|
||||
* @param string $line the language line
|
||||
* @return string
|
||||
*/
|
||||
function line($line = '')
|
||||
{
|
||||
$value = ($line == '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line];
|
||||
|
||||
// Because killer robots like unicorns!
|
||||
if ($value === FALSE)
|
||||
{
|
||||
log_message('error', 'Could not find the language line "'.$line.'"');
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
}
|
||||
// END Language Class
|
||||
|
||||
/* End of file Lang.php */
|
||||
/* Location: ./system/core/Lang.php */
|
1248
system/core/Loader.php
Normal file
1248
system/core/Loader.php
Normal file
File diff suppressed because it is too large
Load Diff
57
system/core/Model.php
Normal file
57
system/core/Model.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP 5.1.6 or newer
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
|
||||
* @license http://codeigniter.com/user_guide/license.html
|
||||
* @link http://codeigniter.com
|
||||
* @since Version 1.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* CodeIgniter Model Class
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Libraries
|
||||
* @category Libraries
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @link http://codeigniter.com/user_guide/libraries/config.html
|
||||
*/
|
||||
class CI_Model {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
log_message('debug', "Model Class Initialized");
|
||||
}
|
||||
|
||||
/**
|
||||
* __get
|
||||
*
|
||||
* Allows models to access CI's loaded classes using the same
|
||||
* syntax as controllers.
|
||||
*
|
||||
* @param string
|
||||
* @access private
|
||||
*/
|
||||
function __get($key)
|
||||
{
|
||||
$CI =& get_instance();
|
||||
return $CI->$key;
|
||||
}
|
||||
}
|
||||
// END Model Class
|
||||
|
||||
/* End of file Model.php */
|
||||
/* Location: ./system/core/Model.php */
|
574
system/core/Output.php
Normal file
574
system/core/Output.php
Normal file
@ -0,0 +1,574 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP 5.1.6 or newer
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
|
||||
* @license http://codeigniter.com/user_guide/license.html
|
||||
* @link http://codeigniter.com
|
||||
* @since Version 1.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Output Class
|
||||
*
|
||||
* Responsible for sending final output to browser
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Libraries
|
||||
* @category Output
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @link http://codeigniter.com/user_guide/libraries/output.html
|
||||
*/
|
||||
class CI_Output {
|
||||
|
||||
/**
|
||||
* Current output string
|
||||
*
|
||||
* @var string
|
||||
* @access protected
|
||||
*/
|
||||
protected $final_output;
|
||||
/**
|
||||
* Cache expiration time
|
||||
*
|
||||
* @var int
|
||||
* @access protected
|
||||
*/
|
||||
protected $cache_expiration = 0;
|
||||
/**
|
||||
* List of server headers
|
||||
*
|
||||
* @var array
|
||||
* @access protected
|
||||
*/
|
||||
protected $headers = array();
|
||||
/**
|
||||
* List of mime types
|
||||
*
|
||||
* @var array
|
||||
* @access protected
|
||||
*/
|
||||
protected $mime_types = array();
|
||||
/**
|
||||
* Determines wether profiler is enabled
|
||||
*
|
||||
* @var book
|
||||
* @access protected
|
||||
*/
|
||||
protected $enable_profiler = FALSE;
|
||||
/**
|
||||
* Determines if output compression is enabled
|
||||
*
|
||||
* @var bool
|
||||
* @access protected
|
||||
*/
|
||||
protected $_zlib_oc = FALSE;
|
||||
/**
|
||||
* List of profiler sections
|
||||
*
|
||||
* @var array
|
||||
* @access protected
|
||||
*/
|
||||
protected $_profiler_sections = array();
|
||||
/**
|
||||
* Whether or not to parse variables like {elapsed_time} and {memory_usage}
|
||||
*
|
||||
* @var bool
|
||||
* @access protected
|
||||
*/
|
||||
protected $parse_exec_vars = TRUE;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
$this->_zlib_oc = @ini_get('zlib.output_compression');
|
||||
|
||||
// Get mime types for later
|
||||
if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
|
||||
{
|
||||
include APPPATH.'config/'.ENVIRONMENT.'/mimes.php';
|
||||
}
|
||||
else
|
||||
{
|
||||
include APPPATH.'config/mimes.php';
|
||||
}
|
||||
|
||||
|
||||
$this->mime_types = $mimes;
|
||||
|
||||
log_message('debug', "Output Class Initialized");
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get Output
|
||||
*
|
||||
* Returns the current output string
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function get_output()
|
||||
{
|
||||
return $this->final_output;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set Output
|
||||
*
|
||||
* Sets the output string
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @return void
|
||||
*/
|
||||
function set_output($output)
|
||||
{
|
||||
$this->final_output = $output;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Append Output
|
||||
*
|
||||
* Appends data onto the output string
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @return void
|
||||
*/
|
||||
function append_output($output)
|
||||
{
|
||||
if ($this->final_output == '')
|
||||
{
|
||||
$this->final_output = $output;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->final_output .= $output;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set Header
|
||||
*
|
||||
* Lets you set a server header which will be outputted with the final display.
|
||||
*
|
||||
* 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...
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @param bool
|
||||
* @return void
|
||||
*/
|
||||
function set_header($header, $replace = TRUE)
|
||||
{
|
||||
// If zlib.output_compression is enabled it will compress the output,
|
||||
// but it will not modify the content-length header to compensate for
|
||||
// the reduction, causing the browser to hang waiting for more data.
|
||||
// We'll just skip content-length in those cases.
|
||||
|
||||
if ($this->_zlib_oc && strncasecmp($header, 'content-length', 14) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->headers[] = array($header, $replace);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set Content Type Header
|
||||
*
|
||||
* @access public
|
||||
* @param string extension of the file we're outputting
|
||||
* @return void
|
||||
*/
|
||||
function set_content_type($mime_type)
|
||||
{
|
||||
if (strpos($mime_type, '/') === FALSE)
|
||||
{
|
||||
$extension = ltrim($mime_type, '.');
|
||||
|
||||
// Is this extension supported?
|
||||
if (isset($this->mime_types[$extension]))
|
||||
{
|
||||
$mime_type =& $this->mime_types[$extension];
|
||||
|
||||
if (is_array($mime_type))
|
||||
{
|
||||
$mime_type = current($mime_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$header = 'Content-Type: '.$mime_type;
|
||||
|
||||
$this->headers[] = array($header, TRUE);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set HTTP Status Header
|
||||
* moved to Common procedural functions in 1.7.2
|
||||
*
|
||||
* @access public
|
||||
* @param int the status code
|
||||
* @param string
|
||||
* @return void
|
||||
*/
|
||||
function set_status_header($code = 200, $text = '')
|
||||
{
|
||||
set_status_header($code, $text);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Enable/disable Profiler
|
||||
*
|
||||
* @access public
|
||||
* @param bool
|
||||
* @return void
|
||||
*/
|
||||
function enable_profiler($val = TRUE)
|
||||
{
|
||||
$this->enable_profiler = (is_bool($val)) ? $val : TRUE;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set Profiler Sections
|
||||
*
|
||||
* Allows override of default / config settings for Profiler section display
|
||||
*
|
||||
* @access public
|
||||
* @param array
|
||||
* @return void
|
||||
*/
|
||||
function set_profiler_sections($sections)
|
||||
{
|
||||
foreach ($sections as $section => $enable)
|
||||
{
|
||||
$this->_profiler_sections[$section] = ($enable !== FALSE) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set Cache
|
||||
*
|
||||
* @access public
|
||||
* @param integer
|
||||
* @return void
|
||||
*/
|
||||
function cache($time)
|
||||
{
|
||||
$this->cache_expiration = ( ! is_numeric($time)) ? 0 : $time;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Display Output
|
||||
*
|
||||
* All "view" data is automatically put into this variable by the controller class:
|
||||
*
|
||||
* $this->final_output
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @return mixed
|
||||
*/
|
||||
function _display($output = '')
|
||||
{
|
||||
// Note: We use globals because we can't use $CI =& get_instance()
|
||||
// since this function is sometimes called by the caching mechanism,
|
||||
// which happens before the CI super object is available.
|
||||
global $BM, $CFG;
|
||||
|
||||
// Grab the super object if we can.
|
||||
if (class_exists('CI_Controller'))
|
||||
{
|
||||
$CI =& get_instance();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
// Set the output data
|
||||
if ($output == '')
|
||||
{
|
||||
$output =& $this->final_output;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
// 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'))
|
||||
{
|
||||
$this->_write_cache($output);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
// Parse out the elapsed time and memory usage,
|
||||
// then swap the pseudo-variables with the data
|
||||
|
||||
$elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end');
|
||||
|
||||
if ($this->parse_exec_vars === TRUE)
|
||||
{
|
||||
$memory = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB';
|
||||
|
||||
$output = str_replace('{elapsed_time}', $elapsed, $output);
|
||||
$output = str_replace('{memory_usage}', $memory, $output);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
// Is compression requested?
|
||||
if ($CFG->item('compress_output') === TRUE && $this->_zlib_oc == FALSE)
|
||||
{
|
||||
if (extension_loaded('zlib'))
|
||||
{
|
||||
if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
|
||||
{
|
||||
ob_start('ob_gzhandler');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
// Are there any server headers to send?
|
||||
if (count($this->headers) > 0)
|
||||
{
|
||||
foreach ($this->headers as $header)
|
||||
{
|
||||
@header($header[0], $header[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
// Does the $CI object exist?
|
||||
// If not we know we are dealing with a cache file so we'll
|
||||
// simply echo out the data and exit.
|
||||
if ( ! isset($CI))
|
||||
{
|
||||
echo $output;
|
||||
log_message('debug', "Final output sent to browser");
|
||||
log_message('debug', "Total execution time: ".$elapsed);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
// Do we need to generate profile data?
|
||||
// If so, load the Profile class and run it.
|
||||
if ($this->enable_profiler == TRUE)
|
||||
{
|
||||
$CI->load->library('profiler');
|
||||
|
||||
if ( ! empty($this->_profiler_sections))
|
||||
{
|
||||
$CI->profiler->set_sections($this->_profiler_sections);
|
||||
}
|
||||
|
||||
// If the output data contains closing </body> and </html> tags
|
||||
// we will remove them and add them back after we insert the profile data
|
||||
if (preg_match("|</body>.*?</html>|is", $output))
|
||||
{
|
||||
$output = preg_replace("|</body>.*?</html>|is", '', $output);
|
||||
$output .= $CI->profiler->run();
|
||||
$output .= '</body></html>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$output .= $CI->profiler->run();
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
// Does the controller contain a function named _output()?
|
||||
// If so send the output there. Otherwise, echo it.
|
||||
if (method_exists($CI, '_output'))
|
||||
{
|
||||
$CI->_output($output);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo $output; // Send it to the browser!
|
||||
}
|
||||
|
||||
log_message('debug', "Final output sent to browser");
|
||||
log_message('debug', "Total execution time: ".$elapsed);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Write a Cache File
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @return void
|
||||
*/
|
||||
function _write_cache($output)
|
||||
{
|
||||
$CI =& get_instance();
|
||||
$path = $CI->config->item('cache_path');
|
||||
|
||||
$cache_path = ($path == '') ? APPPATH.'cache/' : $path;
|
||||
|
||||
if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
|
||||
{
|
||||
log_message('error', "Unable to write cache file: ".$cache_path);
|
||||
return;
|
||||
}
|
||||
|
||||
$uri = $CI->config->item('base_url').
|
||||
$CI->config->item('index_page').
|
||||
$CI->uri->uri_string();
|
||||
|
||||
$cache_path .= md5($uri);
|
||||
|
||||
if ( ! $fp = @fopen($cache_path, FOPEN_WRITE_CREATE_DESTRUCTIVE))
|
||||
{
|
||||
log_message('error', "Unable to write cache file: ".$cache_path);
|
||||
return;
|
||||
}
|
||||
|
||||
$expire = time() + ($this->cache_expiration * 60);
|
||||
|
||||
if (flock($fp, LOCK_EX))
|
||||
{
|
||||
fwrite($fp, $expire.'TS--->'.$output);
|
||||
flock($fp, LOCK_UN);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_message('error', "Unable to secure a file lock for file at: ".$cache_path);
|
||||
return;
|
||||
}
|
||||
fclose($fp);
|
||||
@chmod($cache_path, FILE_WRITE_MODE);
|
||||
|
||||
log_message('debug', "Cache file written: ".$cache_path);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Update/serve a cached file
|
||||
*
|
||||
* @access public
|
||||
* @param object config class
|
||||
* @param object uri class
|
||||
* @return void
|
||||
*/
|
||||
function _display_cache(&$CFG, &$URI)
|
||||
{
|
||||
$cache_path = ($CFG->item('cache_path') == '') ? APPPATH.'cache/' : $CFG->item('cache_path');
|
||||
|
||||
// Build the file path. The file name is an MD5 hash of the full URI
|
||||
$uri = $CFG->item('base_url').
|
||||
$CFG->item('index_page').
|
||||
$URI->uri_string;
|
||||
|
||||
$filepath = $cache_path.md5($uri);
|
||||
|
||||
if ( ! @file_exists($filepath))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( ! $fp = @fopen($filepath, FOPEN_READ))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
flock($fp, LOCK_SH);
|
||||
|
||||
$cache = '';
|
||||
if (filesize($filepath) > 0)
|
||||
{
|
||||
$cache = fread($fp, filesize($filepath));
|
||||
}
|
||||
|
||||
flock($fp, LOCK_UN);
|
||||
fclose($fp);
|
||||
|
||||
// Strip out the embedded timestamp
|
||||
if ( ! preg_match("/(\d+TS--->)/", $cache, $match))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Has the file expired? If so we'll delete it.
|
||||
if (time() >= trim(str_replace('TS--->', '', $match['1'])))
|
||||
{
|
||||
if (is_really_writable($cache_path))
|
||||
{
|
||||
@unlink($filepath);
|
||||
log_message('debug', "Cache file has expired. File deleted");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Display the cache
|
||||
$this->_display(str_replace($match['0'], '', $cache));
|
||||
log_message('debug', "Cache file is current. Sending it to browser.");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// END Output Class
|
||||
|
||||
/* End of file Output.php */
|
||||
/* Location: ./system/core/Output.php */
|
522
system/core/Router.php
Normal file
522
system/core/Router.php
Normal file
@ -0,0 +1,522 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP 5.1.6 or newer
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
|
||||
* @license http://codeigniter.com/user_guide/license.html
|
||||
* @link http://codeigniter.com
|
||||
* @since Version 1.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Router Class
|
||||
*
|
||||
* Parses URIs and determines routing
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Libraries
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @category Libraries
|
||||
* @link http://codeigniter.com/user_guide/general/routing.html
|
||||
*/
|
||||
class CI_Router {
|
||||
|
||||
/**
|
||||
* Config class
|
||||
*
|
||||
* @var object
|
||||
* @access public
|
||||
*/
|
||||
var $config;
|
||||
/**
|
||||
* List of routes
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
var $routes = array();
|
||||
/**
|
||||
* List of error routes
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
var $error_routes = array();
|
||||
/**
|
||||
* Current class name
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
var $class = '';
|
||||
/**
|
||||
* Current method name
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
var $method = 'index';
|
||||
/**
|
||||
* Sub-directory that contains the requested controller class
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
var $directory = '';
|
||||
/**
|
||||
* Default controller (and method if specific)
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
var $default_controller;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Runs the route mapping function.
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
$this->config =& load_class('Config', 'core');
|
||||
$this->uri =& load_class('URI', 'core');
|
||||
log_message('debug', "Router Class Initialized");
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set the route mapping
|
||||
*
|
||||
* This function determines what should be served based on the URI request,
|
||||
* as well as any "routes" that have been set in the routing config file.
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
function _set_routing()
|
||||
{
|
||||
// Are query strings enabled in the config file? Normally CI doesn't utilize query strings
|
||||
// since URI segments are more search-engine friendly, but they can optionally be used.
|
||||
// If this feature is enabled, we will gather the directory/class/method a little differently
|
||||
$segments = array();
|
||||
if ($this->config->item('enable_query_strings') === TRUE AND isset($_GET[$this->config->item('controller_trigger')]))
|
||||
{
|
||||
if (isset($_GET[$this->config->item('directory_trigger')]))
|
||||
{
|
||||
$this->set_directory(trim($this->uri->_filter_uri($_GET[$this->config->item('directory_trigger')])));
|
||||
$segments[] = $this->fetch_directory();
|
||||
}
|
||||
|
||||
if (isset($_GET[$this->config->item('controller_trigger')]))
|
||||
{
|
||||
$this->set_class(trim($this->uri->_filter_uri($_GET[$this->config->item('controller_trigger')])));
|
||||
$segments[] = $this->fetch_class();
|
||||
}
|
||||
|
||||
if (isset($_GET[$this->config->item('function_trigger')]))
|
||||
{
|
||||
$this->set_method(trim($this->uri->_filter_uri($_GET[$this->config->item('function_trigger')])));
|
||||
$segments[] = $this->fetch_method();
|
||||
}
|
||||
}
|
||||
|
||||
// Load the routes.php file.
|
||||
if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/routes.php'))
|
||||
{
|
||||
include(APPPATH.'config/'.ENVIRONMENT.'/routes.php');
|
||||
}
|
||||
elseif (is_file(APPPATH.'config/routes.php'))
|
||||
{
|
||||
include(APPPATH.'config/routes.php');
|
||||
}
|
||||
|
||||
$this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route;
|
||||
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 = ( ! isset($this->routes['default_controller']) OR $this->routes['default_controller'] == '') ? FALSE : strtolower($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)
|
||||
{
|
||||
return $this->_validate_request($segments);
|
||||
}
|
||||
|
||||
// Fetch the complete URI string
|
||||
$this->uri->_fetch_uri_string();
|
||||
|
||||
// Is there a URI string? If not, the default controller specified in the "routes" file will be shown.
|
||||
if ($this->uri->uri_string == '')
|
||||
{
|
||||
return $this->_set_default_controller();
|
||||
}
|
||||
|
||||
// Do we need to remove the URL suffix?
|
||||
$this->uri->_remove_url_suffix();
|
||||
|
||||
// Compile the segments into an array
|
||||
$this->uri->_explode_segments();
|
||||
|
||||
// Parse any custom routing that may exist
|
||||
$this->_parse_routes();
|
||||
|
||||
// Re-index the segment array so that it starts with 1 rather than 0
|
||||
$this->uri->_reindex_segments();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set the default controller
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
function _set_default_controller()
|
||||
{
|
||||
if ($this->default_controller === FALSE)
|
||||
{
|
||||
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)
|
||||
{
|
||||
$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'));
|
||||
}
|
||||
|
||||
// re-index the routed segments array so it starts with 1 rather than 0
|
||||
$this->uri->_reindex_segments();
|
||||
|
||||
log_message('debug', "No URI present. Default controller set.");
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set the Route
|
||||
*
|
||||
* This function takes an array of URI segments as
|
||||
* input, and sets the current class/method
|
||||
*
|
||||
* @access private
|
||||
* @param array
|
||||
* @param bool
|
||||
* @return void
|
||||
*/
|
||||
function _set_request($segments = array())
|
||||
{
|
||||
$segments = $this->_validate_request($segments);
|
||||
|
||||
if (count($segments) == 0)
|
||||
{
|
||||
return $this->_set_default_controller();
|
||||
}
|
||||
|
||||
$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';
|
||||
}
|
||||
|
||||
// Update our "routed" segment array to contain the segments.
|
||||
// Note: If there is no custom routing, this array will be
|
||||
// identical to $this->uri->segments
|
||||
$this->uri->rsegments = $segments;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Validates the supplied segments. Attempts to determine the path to
|
||||
* the controller.
|
||||
*
|
||||
* @access private
|
||||
* @param array
|
||||
* @return array
|
||||
*/
|
||||
function _validate_request($segments)
|
||||
{
|
||||
if (count($segments) == 0)
|
||||
{
|
||||
return $segments;
|
||||
}
|
||||
|
||||
// Does the requested controller exist in the root folder?
|
||||
if (file_exists(APPPATH.'controllers/'.$segments[0].'.php'))
|
||||
{
|
||||
return $segments;
|
||||
}
|
||||
|
||||
// Is the controller in a sub-folder?
|
||||
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);
|
||||
|
||||
if (count($segments) > 0)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
else
|
||||
{
|
||||
show_404($this->fetch_directory().$segments[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
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'))
|
||||
{
|
||||
$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');
|
||||
|
||||
return $x;
|
||||
}
|
||||
|
||||
|
||||
// Nothing else to do at this point but show a 404
|
||||
show_404($segments[0]);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
function _parse_routes()
|
||||
{
|
||||
// Turn the segment array into a URI string
|
||||
$uri = implode('/', $this->uri->segments);
|
||||
|
||||
// Is there a literal match? If so we're done
|
||||
if (isset($this->routes[$uri]))
|
||||
{
|
||||
return $this->_set_request(explode('/', $this->routes[$uri]));
|
||||
}
|
||||
|
||||
// Loop through the route array looking for wild-cards
|
||||
foreach ($this->routes as $key => $val)
|
||||
{
|
||||
// Convert wild-cards to RegEx
|
||||
$key = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $key));
|
||||
|
||||
// Does the RegEx match?
|
||||
if (preg_match('#^'.$key.'$#', $uri))
|
||||
{
|
||||
// Do we have a back-reference?
|
||||
if (strpos($val, '$') !== FALSE AND strpos($key, '(') !== FALSE)
|
||||
{
|
||||
$val = preg_replace('#^'.$key.'$#', $val, $uri);
|
||||
}
|
||||
|
||||
return $this->_set_request(explode('/', $val));
|
||||
}
|
||||
}
|
||||
|
||||
// If we got this far it means we didn't encounter a
|
||||
// matching route so we'll set the site default route
|
||||
$this->_set_request($this->uri->segments);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set the class name
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @return void
|
||||
*/
|
||||
function set_class($class)
|
||||
{
|
||||
$this->class = str_replace(array('/', '.'), '', $class);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch the current class
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function fetch_class()
|
||||
{
|
||||
return $this->class;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set the method name
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @return void
|
||||
*/
|
||||
function set_method($method)
|
||||
{
|
||||
$this->method = $method;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch the current method
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function fetch_method()
|
||||
{
|
||||
if ($this->method == $this->fetch_class())
|
||||
{
|
||||
return 'index';
|
||||
}
|
||||
|
||||
return $this->method;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set the directory name
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @return void
|
||||
*/
|
||||
function set_directory($dir)
|
||||
{
|
||||
$this->directory = str_replace(array('/', '.'), '', $dir).'/';
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch the sub-directory (if any) that contains the requested controller class
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function fetch_directory()
|
||||
{
|
||||
return $this->directory;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set the controller overrides
|
||||
*
|
||||
* @access public
|
||||
* @param array
|
||||
* @return null
|
||||
*/
|
||||
function _set_overrides($routing)
|
||||
{
|
||||
if ( ! is_array($routing))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($routing['directory']))
|
||||
{
|
||||
$this->set_directory($routing['directory']);
|
||||
}
|
||||
|
||||
if (isset($routing['controller']) AND $routing['controller'] != '')
|
||||
{
|
||||
$this->set_class($routing['controller']);
|
||||
}
|
||||
|
||||
if (isset($routing['function']))
|
||||
{
|
||||
$routing['function'] = ($routing['function'] == '') ? 'index' : $routing['function'];
|
||||
$this->set_method($routing['function']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// END Router Class
|
||||
|
||||
/* End of file Router.php */
|
||||
/* Location: ./system/core/Router.php */
|
876
system/core/Security.php
Normal file
876
system/core/Security.php
Normal file
@ -0,0 +1,876 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP 5.1.6 or newer
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
|
||||
* @license http://codeigniter.com/user_guide/license.html
|
||||
* @link http://codeigniter.com
|
||||
* @since Version 1.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Security Class
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Libraries
|
||||
* @category Security
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @link http://codeigniter.com/user_guide/libraries/security.html
|
||||
*/
|
||||
class CI_Security {
|
||||
|
||||
/**
|
||||
* Random Hash for protecting URLs
|
||||
*
|
||||
* @var string
|
||||
* @access protected
|
||||
*/
|
||||
protected $_xss_hash = '';
|
||||
/**
|
||||
* Random Hash for Cross Site Request Forgery Protection Cookie
|
||||
*
|
||||
* @var string
|
||||
* @access protected
|
||||
*/
|
||||
protected $_csrf_hash = '';
|
||||
/**
|
||||
* Expiration time for Cross Site Request Forgery Protection Cookie
|
||||
* Defaults to two hours (in seconds)
|
||||
*
|
||||
* @var int
|
||||
* @access protected
|
||||
*/
|
||||
protected $_csrf_expire = 7200;
|
||||
/**
|
||||
* Token name for Cross Site Request Forgery Protection Cookie
|
||||
*
|
||||
* @var string
|
||||
* @access protected
|
||||
*/
|
||||
protected $_csrf_token_name = 'ci_csrf_token';
|
||||
/**
|
||||
* Cookie name for Cross Site Request Forgery Protection Cookie
|
||||
*
|
||||
* @var string
|
||||
* @access protected
|
||||
*/
|
||||
protected $_csrf_cookie_name = 'ci_csrf_token';
|
||||
/**
|
||||
* List of never allowed strings
|
||||
*
|
||||
* @var array
|
||||
* @access protected
|
||||
*/
|
||||
protected $_never_allowed_str = array(
|
||||
'document.cookie' => '[removed]',
|
||||
'document.write' => '[removed]',
|
||||
'.parentNode' => '[removed]',
|
||||
'.innerHTML' => '[removed]',
|
||||
'window.location' => '[removed]',
|
||||
'-moz-binding' => '[removed]',
|
||||
'<!--' => '<!--',
|
||||
'-->' => '-->',
|
||||
'<![CDATA[' => '<![CDATA[',
|
||||
'<comment>' => '<comment>'
|
||||
);
|
||||
|
||||
/* never allowed, regex replacement */
|
||||
/**
|
||||
* List of never allowed regex replacement
|
||||
*
|
||||
* @var array
|
||||
* @access protected
|
||||
*/
|
||||
protected $_never_allowed_regex = array(
|
||||
'javascript\s*:',
|
||||
'expression\s*(\(|&\#40;)', // CSS and IE
|
||||
'vbscript\s*:', // IE, surprise!
|
||||
'Redirect\s+302',
|
||||
"([\"'])?data\s*:[^\\1]*?base64[^\\1]*?,[^\\1]*?\\1?"
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Is CSRF protection enabled?
|
||||
if (config_item('csrf_protection') === TRUE)
|
||||
{
|
||||
// CSRF config
|
||||
foreach (array('csrf_expire', 'csrf_token_name', 'csrf_cookie_name') as $key)
|
||||
{
|
||||
if (FALSE !== ($val = config_item($key)))
|
||||
{
|
||||
$this->{'_'.$key} = $val;
|
||||
}
|
||||
}
|
||||
|
||||
// Append application specific cookie prefix
|
||||
if (config_item('cookie_prefix'))
|
||||
{
|
||||
$this->_csrf_cookie_name = config_item('cookie_prefix').$this->_csrf_cookie_name;
|
||||
}
|
||||
|
||||
// Set the CSRF hash
|
||||
$this->_csrf_set_hash();
|
||||
}
|
||||
|
||||
log_message('debug', "Security Class Initialized");
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Verify Cross Site Request Forgery Protection
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function csrf_verify()
|
||||
{
|
||||
// If it's not a POST request we will set the CSRF cookie
|
||||
if (strtoupper($_SERVER['REQUEST_METHOD']) !== 'POST')
|
||||
{
|
||||
return $this->csrf_set_cookie();
|
||||
}
|
||||
|
||||
// Do the tokens exist in both the _POST and _COOKIE arrays?
|
||||
if ( ! isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name]))
|
||||
{
|
||||
$this->csrf_show_error();
|
||||
}
|
||||
|
||||
// Do the tokens match?
|
||||
if ($_POST[$this->_csrf_token_name] != $_COOKIE[$this->_csrf_cookie_name])
|
||||
{
|
||||
$this->csrf_show_error();
|
||||
}
|
||||
|
||||
// We kill this since we're done and we don't want to
|
||||
// polute the _POST array
|
||||
unset($_POST[$this->_csrf_token_name]);
|
||||
|
||||
// Nothing should last forever
|
||||
unset($_COOKIE[$this->_csrf_cookie_name]);
|
||||
$this->_csrf_set_hash();
|
||||
$this->csrf_set_cookie();
|
||||
|
||||
log_message('debug', 'CSRF token verified');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set Cross Site Request Forgery Protection Cookie
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function csrf_set_cookie()
|
||||
{
|
||||
$expire = time() + $this->_csrf_expire;
|
||||
$secure_cookie = (config_item('cookie_secure') === TRUE) ? 1 : 0;
|
||||
|
||||
if ($secure_cookie && (empty($_SERVER['HTTPS']) OR strtolower($_SERVER['HTTPS']) === 'off'))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
setcookie($this->_csrf_cookie_name, $this->_csrf_hash, $expire, config_item('cookie_path'), config_item('cookie_domain'), $secure_cookie);
|
||||
|
||||
log_message('debug', "CRSF cookie Set");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Show CSRF Error
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function csrf_show_error()
|
||||
{
|
||||
show_error('The action you have requested is not allowed.');
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get CSRF Hash
|
||||
*
|
||||
* Getter Method
|
||||
*
|
||||
* @return string self::_csrf_hash
|
||||
*/
|
||||
public function get_csrf_hash()
|
||||
{
|
||||
return $this->_csrf_hash;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get CSRF Token Name
|
||||
*
|
||||
* Getter Method
|
||||
*
|
||||
* @return string self::csrf_token_name
|
||||
*/
|
||||
public function get_csrf_token_name()
|
||||
{
|
||||
return $this->_csrf_token_name;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* XSS Clean
|
||||
*
|
||||
* Sanitizes data so that Cross Site Scripting Hacks can be
|
||||
* prevented. This function 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.
|
||||
*
|
||||
* This function was based in part on some code and ideas I
|
||||
* got from Bitflux: http://channel.bitflux.ch/wiki/XSS_Prevention
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* @param mixed string or array
|
||||
* @param bool
|
||||
* @return string
|
||||
*/
|
||||
public function xss_clean($str, $is_image = FALSE)
|
||||
{
|
||||
/*
|
||||
* Is the string an array?
|
||||
*
|
||||
*/
|
||||
if (is_array($str))
|
||||
{
|
||||
while (list($key) = each($str))
|
||||
{
|
||||
$str[$key] = $this->xss_clean($str[$key]);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove Invisible Characters
|
||||
*/
|
||||
$str = remove_invisible_characters($str);
|
||||
|
||||
// Validate Entities in URLs
|
||||
$str = $this->_validate_entities($str);
|
||||
|
||||
/*
|
||||
* URL Decode
|
||||
*
|
||||
* Just in case stuff like this is submitted:
|
||||
*
|
||||
* <a href="http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D">Google</a>
|
||||
*
|
||||
* Note: Use rawurldecode() so it does not remove plus signs
|
||||
*
|
||||
*/
|
||||
$str = rawurldecode($str);
|
||||
|
||||
/*
|
||||
* Convert character entities to ASCII
|
||||
*
|
||||
* This permits our tests below to work reliably.
|
||||
* We only convert entities that are within tags since
|
||||
* these are the ones that will pose security problems.
|
||||
*
|
||||
*/
|
||||
|
||||
$str = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, '_convert_attribute'), $str);
|
||||
|
||||
$str = preg_replace_callback("/<\w+.*?(?=>|<|$)/si", array($this, '_decode_entity'), $str);
|
||||
|
||||
/*
|
||||
* Remove Invisible Characters Again!
|
||||
*/
|
||||
$str = remove_invisible_characters($str);
|
||||
|
||||
/*
|
||||
* Convert all tabs to spaces
|
||||
*
|
||||
* This prevents strings like this: ja vascript
|
||||
* NOTE: we deal with spaces between characters later.
|
||||
* NOTE: preg_replace was found to be amazingly slow here on
|
||||
* large blocks of data, so we use str_replace.
|
||||
*/
|
||||
|
||||
if (strpos($str, "\t") !== FALSE)
|
||||
{
|
||||
$str = str_replace("\t", ' ', $str);
|
||||
}
|
||||
|
||||
/*
|
||||
* Capture converted string for later comparison
|
||||
*/
|
||||
$converted_string = $str;
|
||||
|
||||
// Remove Strings that are never allowed
|
||||
$str = $this->_do_never_allowed($str);
|
||||
|
||||
/*
|
||||
* Makes PHP tags safe
|
||||
*
|
||||
* Note: XML tags are inadvertently replaced too:
|
||||
*
|
||||
* <?xml
|
||||
*
|
||||
* But it doesn't seem to pose a problem.
|
||||
*/
|
||||
if ($is_image === TRUE)
|
||||
{
|
||||
// Images have a tendency to have the PHP short opening and
|
||||
// closing tags every so often so we skip those and only
|
||||
// do the long opening tags.
|
||||
$str = preg_replace('/<\?(php)/i', "<?\\1", $str);
|
||||
}
|
||||
else
|
||||
{
|
||||
$str = str_replace(array('<?', '?'.'>'), array('<?', '?>'), $str);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compact any exploded words
|
||||
*
|
||||
* This corrects words like: j a v a s c r i p t
|
||||
* These words are compacted back to their correct state.
|
||||
*/
|
||||
$words = array(
|
||||
'javascript', 'expression', 'vbscript', 'script', 'base64',
|
||||
'applet', 'alert', 'document', 'write', 'cookie', 'window'
|
||||
);
|
||||
|
||||
foreach ($words as $word)
|
||||
{
|
||||
$temp = '';
|
||||
|
||||
for ($i = 0, $wordlen = strlen($word); $i < $wordlen; $i++)
|
||||
{
|
||||
$temp .= substr($word, $i, 1)."\s*";
|
||||
}
|
||||
|
||||
// We only want to do this when it is followed by a non-word character
|
||||
// That way valid stuff like "dealer to" does not become "dealerto"
|
||||
$str = preg_replace_callback('#('.substr($temp, 0, -3).')(\W)#is', array($this, '_compact_exploded_words'), $str);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove disallowed Javascript in links or img tags
|
||||
* We used to do some version comparisons and use of stripos for PHP5,
|
||||
* but it is dog slow compared to these simplified non-capturing
|
||||
* preg_match(), especially if the pattern exists in the string
|
||||
*/
|
||||
do
|
||||
{
|
||||
$original = $str;
|
||||
|
||||
if (preg_match("/<a/i", $str))
|
||||
{
|
||||
$str = preg_replace_callback("#<a\s+([^>]*?)(>|$)#si", array($this, '_js_link_removal'), $str);
|
||||
}
|
||||
|
||||
if (preg_match("/<img/i", $str))
|
||||
{
|
||||
$str = preg_replace_callback("#<img\s+([^>]*?)(\s?/?>|$)#si", array($this, '_js_img_removal'), $str);
|
||||
}
|
||||
|
||||
if (preg_match("/script/i", $str) OR preg_match("/xss/i", $str))
|
||||
{
|
||||
$str = preg_replace("#<(/*)(script|xss)(.*?)\>#si", '[removed]', $str);
|
||||
}
|
||||
}
|
||||
while($original != $str);
|
||||
|
||||
unset($original);
|
||||
|
||||
// Remove evil attributes such as style, onclick and xmlns
|
||||
$str = $this->_remove_evil_attributes($str, $is_image);
|
||||
|
||||
/*
|
||||
* Sanitize naughty HTML elements
|
||||
*
|
||||
* If a tag containing any of the words in the list
|
||||
* below is found, the tag gets converted to entities.
|
||||
*
|
||||
* So this: <blink>
|
||||
* Becomes: <blink>
|
||||
*/
|
||||
$naughty = 'alert|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|isindex|layer|link|meta|object|plaintext|style|script|textarea|title|video|xml|xss';
|
||||
$str = preg_replace_callback('#<(/*\s*)('.$naughty.')([^><]*)([><]*)#is', array($this, '_sanitize_naughty_html'), $str);
|
||||
|
||||
/*
|
||||
* Sanitize naughty scripting elements
|
||||
*
|
||||
* Similar to above, only instead of looking for
|
||||
* tags it looks for PHP and JavaScript commands
|
||||
* that are disallowed. Rather than removing the
|
||||
* code, it simply converts the parenthesis to entities
|
||||
* rendering the code un-executable.
|
||||
*
|
||||
* For example: eval('some code')
|
||||
* Becomes: eval('some code')
|
||||
*/
|
||||
$str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2(\\3)", $str);
|
||||
|
||||
|
||||
// Final clean up
|
||||
// This adds a bit of extra precaution in case
|
||||
// something got through the above filters
|
||||
$str = $this->_do_never_allowed($str);
|
||||
|
||||
/*
|
||||
* Images are Handled in a Special Way
|
||||
* - Essentially, we want to know that after all of the character
|
||||
* conversion is done whether any unwanted, likely XSS, code was found.
|
||||
* If not, we return TRUE, as the image is clean.
|
||||
* However, if the string post-conversion does not matched the
|
||||
* string post-removal of XSS, then it fails, as there was unwanted XSS
|
||||
* code found and removed/changed during processing.
|
||||
*/
|
||||
|
||||
if ($is_image === TRUE)
|
||||
{
|
||||
return ($str == $converted_string) ? TRUE: FALSE;
|
||||
}
|
||||
|
||||
log_message('debug', "XSS Filtering completed");
|
||||
return $str;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Random Hash for protecting URLs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function xss_hash()
|
||||
{
|
||||
if ($this->_xss_hash == '')
|
||||
{
|
||||
mt_srand();
|
||||
$this->_xss_hash = md5(time() + mt_rand(0, 1999999999));
|
||||
}
|
||||
|
||||
return $this->_xss_hash;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* HTML Entities Decode
|
||||
*
|
||||
* This function is 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
|
||||
* at the end of an entity most browsers will still interpret the entity
|
||||
* 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
|
||||
* @return string
|
||||
*/
|
||||
public function entity_decode($str, $charset='UTF-8')
|
||||
{
|
||||
if (stristr($str, '&') === FALSE)
|
||||
{
|
||||
return $str;
|
||||
}
|
||||
|
||||
$str = html_entity_decode($str, ENT_COMPAT, $charset);
|
||||
$str = preg_replace('~&#x(0*[0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str);
|
||||
return preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Filename Security
|
||||
*
|
||||
* @param string
|
||||
* @param bool
|
||||
* @return string
|
||||
*/
|
||||
public function sanitize_filename($str, $relative_path = FALSE)
|
||||
{
|
||||
$bad = array(
|
||||
"../",
|
||||
"<!--",
|
||||
"-->",
|
||||
"<",
|
||||
">",
|
||||
"'",
|
||||
'"',
|
||||
'&',
|
||||
'$',
|
||||
'#',
|
||||
'{',
|
||||
'}',
|
||||
'[',
|
||||
']',
|
||||
'=',
|
||||
';',
|
||||
'?',
|
||||
"%20",
|
||||
"%22",
|
||||
"%3c", // <
|
||||
"%253c", // <
|
||||
"%3e", // >
|
||||
"%0e", // >
|
||||
"%28", // (
|
||||
"%29", // )
|
||||
"%2528", // (
|
||||
"%26", // &
|
||||
"%24", // $
|
||||
"%3f", // ?
|
||||
"%3b", // ;
|
||||
"%3d" // =
|
||||
);
|
||||
|
||||
if ( ! $relative_path)
|
||||
{
|
||||
$bad[] = './';
|
||||
$bad[] = '/';
|
||||
}
|
||||
|
||||
$str = remove_invisible_characters($str, FALSE);
|
||||
return stripslashes(str_replace($bad, '', $str));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Compact Exploded Words
|
||||
*
|
||||
* Callback function for xss_clean() to remove whitespace from
|
||||
* things like j a v a s c r i p t
|
||||
*
|
||||
* @param type
|
||||
* @return type
|
||||
*/
|
||||
protected function _compact_exploded_words($matches)
|
||||
{
|
||||
return preg_replace('/\s+/s', '', $matches[1]).$matches[2];
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Remove Evil HTML Attributes (like evenhandlers and style)
|
||||
*
|
||||
* It removes the evil attribute and either:
|
||||
* - Everything up until a space
|
||||
* For example, everything between the pipes:
|
||||
* <a |style=document.write('hello');alert('world');| class=link>
|
||||
* - Everything inside the quotes
|
||||
* For example, everything between the pipes:
|
||||
* <a |style="document.write('hello'); alert('world');"| class="link">
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
protected function _remove_evil_attributes($str, $is_image)
|
||||
{
|
||||
// All javascript event handlers (e.g. onload, onclick, onmouseover), style, and xmlns
|
||||
$evil_attributes = array('on\w*', 'style', 'xmlns', 'formaction');
|
||||
|
||||
if ($is_image === TRUE)
|
||||
{
|
||||
/*
|
||||
* Adobe Photoshop puts XML metadata into JFIF images,
|
||||
* including namespacing, so we have to allow this for images.
|
||||
*/
|
||||
unset($evil_attributes[array_search('xmlns', $evil_attributes)]);
|
||||
}
|
||||
|
||||
do {
|
||||
$count = 0;
|
||||
$attribs = array();
|
||||
|
||||
// find occurrences of illegal attribute strings without quotes
|
||||
preg_match_all('/('.implode('|', $evil_attributes).')\s*=\s*([^\s>]*)/is', $str, $matches, PREG_SET_ORDER);
|
||||
|
||||
foreach ($matches as $attr)
|
||||
{
|
||||
|
||||
$attribs[] = preg_quote($attr[0], '/');
|
||||
}
|
||||
|
||||
// find occurrences of illegal attribute strings with quotes (042 and 047 are octal quotes)
|
||||
preg_match_all("/(".implode('|', $evil_attributes).")\s*=\s*(\042|\047)([^\\2]*?)(\\2)/is", $str, $matches, PREG_SET_ORDER);
|
||||
|
||||
foreach ($matches as $attr)
|
||||
{
|
||||
$attribs[] = preg_quote($attr[0], '/');
|
||||
}
|
||||
|
||||
// replace illegal attribute strings that are inside an html tag
|
||||
if (count($attribs) > 0)
|
||||
{
|
||||
$str = preg_replace("/<(\/?[^><]+?)([^A-Za-z<>\-])(.*?)(".implode('|', $attribs).")(.*?)([\s><])([><]*)/i", '<$1 $3$5$6$7', $str, -1, $count);
|
||||
}
|
||||
|
||||
} while ($count);
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Sanitize Naughty HTML
|
||||
*
|
||||
* Callback function for xss_clean() to remove naughty HTML elements
|
||||
*
|
||||
* @param array
|
||||
* @return string
|
||||
*/
|
||||
protected function _sanitize_naughty_html($matches)
|
||||
{
|
||||
// encode opening brace
|
||||
$str = '<'.$matches[1].$matches[2].$matches[3];
|
||||
|
||||
// encode captured opening or closing brace to prevent recursive vectors
|
||||
$str .= str_replace(array('>', '<'), array('>', '<'),
|
||||
$matches[4]);
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* JS Link Removal
|
||||
*
|
||||
* Callback function 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
|
||||
*
|
||||
* @param array
|
||||
* @return string
|
||||
*/
|
||||
protected function _js_link_removal($match)
|
||||
{
|
||||
return str_replace(
|
||||
$match[1],
|
||||
preg_replace(
|
||||
'#href=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|data\s*:)#si',
|
||||
'',
|
||||
$this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]))
|
||||
),
|
||||
$match[0]
|
||||
);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* JS Image Removal
|
||||
*
|
||||
* Callback function 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
|
||||
*
|
||||
* @param array
|
||||
* @return string
|
||||
*/
|
||||
protected function _js_img_removal($match)
|
||||
{
|
||||
return str_replace(
|
||||
$match[1],
|
||||
preg_replace(
|
||||
'#src=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si',
|
||||
'',
|
||||
$this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]))
|
||||
),
|
||||
$match[0]
|
||||
);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Attribute Conversion
|
||||
*
|
||||
* Used as a callback for XSS Clean
|
||||
*
|
||||
* @param array
|
||||
* @return string
|
||||
*/
|
||||
protected function _convert_attribute($match)
|
||||
{
|
||||
return str_replace(array('>', '<', '\\'), array('>', '<', '\\\\'), $match[0]);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Filter Attributes
|
||||
*
|
||||
* Filters tag attributes for consistency and safety
|
||||
*
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
protected function _filter_attributes($str)
|
||||
{
|
||||
$out = '';
|
||||
|
||||
if (preg_match_all('#\s*[a-z\-]+\s*=\s*(\042|\047)([^\\1]*?)\\1#is', $str, $matches))
|
||||
{
|
||||
foreach ($matches[0] as $match)
|
||||
{
|
||||
$out .= preg_replace("#/\*.*?\*/#s", '', $match);
|
||||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* HTML Entity Decode Callback
|
||||
*
|
||||
* Used as a callback for XSS Clean
|
||||
*
|
||||
* @param array
|
||||
* @return string
|
||||
*/
|
||||
protected function _decode_entity($match)
|
||||
{
|
||||
return $this->entity_decode($match[0], strtoupper(config_item('charset')));
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Validate URL entities
|
||||
*
|
||||
* Called by xss_clean()
|
||||
*
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
protected function _validate_entities($str)
|
||||
{
|
||||
/*
|
||||
* Protect GET variables in URLs
|
||||
*/
|
||||
|
||||
// 901119URL5918AMP18930PROTECT8198
|
||||
|
||||
$str = preg_replace('|\&([a-z\_0-9\-]+)\=([a-z\_0-9\-]+)|i', $this->xss_hash()."\\1=\\2", $str);
|
||||
|
||||
/*
|
||||
* Validate standard character entities
|
||||
*
|
||||
* Add a semicolon if missing. We do this to enable
|
||||
* the conversion of entities to ASCII later.
|
||||
*
|
||||
*/
|
||||
$str = preg_replace('#(&\#?[0-9a-z]{2,})([\x00-\x20])*;?#i', "\\1;\\2", $str);
|
||||
|
||||
/*
|
||||
* Validate UTF16 two byte encoding (x00)
|
||||
*
|
||||
* Just as above, adds a semicolon if missing.
|
||||
*
|
||||
*/
|
||||
$str = preg_replace('#(&\#x?)([0-9A-F]+);?#i',"\\1\\2;",$str);
|
||||
|
||||
/*
|
||||
* Un-Protect GET variables in URLs
|
||||
*/
|
||||
$str = str_replace($this->xss_hash(), '&', $str);
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Do Never Allowed
|
||||
*
|
||||
* A utility function for xss_clean()
|
||||
*
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
protected function _do_never_allowed($str)
|
||||
{
|
||||
$str = str_replace(array_keys($this->_never_allowed_str), $this->_never_allowed_str, $str);
|
||||
|
||||
foreach ($this->_never_allowed_regex as $regex)
|
||||
{
|
||||
$str = preg_replace('#'.$regex.'#is', '[removed]', $str);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set Cross Site Request Forgery Protection Cookie
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _csrf_set_hash()
|
||||
{
|
||||
if ($this->_csrf_hash == '')
|
||||
{
|
||||
// If the cookie exists we will use it's value.
|
||||
// We don't necessarily want to regenerate it with
|
||||
// each page load since a page could contain embedded
|
||||
// sub-pages causing this feature to fail
|
||||
if (isset($_COOKIE[$this->_csrf_cookie_name]) &&
|
||||
preg_match('#^[0-9a-f]{32}$#iS', $_COOKIE[$this->_csrf_cookie_name]) === 1)
|
||||
{
|
||||
return $this->_csrf_hash = $_COOKIE[$this->_csrf_cookie_name];
|
||||
}
|
||||
|
||||
return $this->_csrf_hash = md5(uniqid(rand(), TRUE));
|
||||
}
|
||||
|
||||
return $this->_csrf_hash;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* End of file Security.php */
|
||||
/* Location: ./system/libraries/Security.php */
|
654
system/core/URI.php
Normal file
654
system/core/URI.php
Normal file
@ -0,0 +1,654 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP 5.1.6 or newer
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
|
||||
* @license http://codeigniter.com/user_guide/license.html
|
||||
* @link http://codeigniter.com
|
||||
* @since Version 1.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* URI Class
|
||||
*
|
||||
* Parses URIs and determines routing
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Libraries
|
||||
* @category URI
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @link http://codeigniter.com/user_guide/libraries/uri.html
|
||||
*/
|
||||
class CI_URI {
|
||||
|
||||
/**
|
||||
* List of cached uri segments
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
var $keyval = array();
|
||||
/**
|
||||
* Current uri string
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
var $uri_string;
|
||||
/**
|
||||
* List of uri segments
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
var $segments = array();
|
||||
/**
|
||||
* Re-indexed list of uri segments
|
||||
* Starts at 1 instead of 0
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
var $rsegments = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Simply globalizes the $RTR object. The front
|
||||
* loads the Router class early on so it's not available
|
||||
* normally as other classes are.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
$this->config =& load_class('Config', 'core');
|
||||
log_message('debug', "URI Class Initialized");
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get the URI String
|
||||
*
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
function _fetch_uri_string()
|
||||
{
|
||||
if (strtoupper($this->config->item('uri_protocol')) == 'AUTO')
|
||||
{
|
||||
// Is the request coming from the command line?
|
||||
if (php_sapi_name() == 'cli' or defined('STDIN'))
|
||||
{
|
||||
$this->_set_uri_string($this->_parse_cli_args());
|
||||
return;
|
||||
}
|
||||
|
||||
// Let's try the REQUEST_URI first, this will work in most situations
|
||||
if ($uri = $this->_detect_uri())
|
||||
{
|
||||
$this->_set_uri_string($uri);
|
||||
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)
|
||||
{
|
||||
$this->_set_uri_string($path);
|
||||
return;
|
||||
}
|
||||
|
||||
// No PATH_INFO?... What about QUERY_STRING?
|
||||
$path = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
|
||||
if (trim($path, '/') != '')
|
||||
{
|
||||
$this->_set_uri_string($path);
|
||||
return;
|
||||
}
|
||||
|
||||
// As a last ditch effort lets try using the $_GET array
|
||||
if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != '')
|
||||
{
|
||||
$this->_set_uri_string(key($_GET));
|
||||
return;
|
||||
}
|
||||
|
||||
// We've exhausted all our options...
|
||||
$this->uri_string = '';
|
||||
return;
|
||||
}
|
||||
|
||||
$uri = strtoupper($this->config->item('uri_protocol'));
|
||||
|
||||
if ($uri == 'REQUEST_URI')
|
||||
{
|
||||
$this->_set_uri_string($this->_detect_uri());
|
||||
return;
|
||||
}
|
||||
elseif ($uri == 'CLI')
|
||||
{
|
||||
$this->_set_uri_string($this->_parse_cli_args());
|
||||
return;
|
||||
}
|
||||
|
||||
$path = (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri);
|
||||
$this->_set_uri_string($path);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set the URI String
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Detects the URI
|
||||
*
|
||||
* This function will detect the URI automatically and fix the query string
|
||||
* if necessary.
|
||||
*
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
private function _detect_uri()
|
||||
{
|
||||
if ( ! isset($_SERVER['REQUEST_URI']) OR ! isset($_SERVER['SCRIPT_NAME']))
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
$uri = $_SERVER['REQUEST_URI'];
|
||||
if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0)
|
||||
{
|
||||
$uri = substr($uri, strlen($_SERVER['SCRIPT_NAME']));
|
||||
}
|
||||
elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0)
|
||||
{
|
||||
$uri = 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 (strncmp($uri, '?/', 2) === 0)
|
||||
{
|
||||
$uri = substr($uri, 2);
|
||||
}
|
||||
$parts = preg_split('#\?#i', $uri, 2);
|
||||
$uri = $parts[0];
|
||||
if (isset($parts[1]))
|
||||
{
|
||||
$_SERVER['QUERY_STRING'] = $parts[1];
|
||||
parse_str($_SERVER['QUERY_STRING'], $_GET);
|
||||
}
|
||||
else
|
||||
{
|
||||
$_SERVER['QUERY_STRING'] = '';
|
||||
$_GET = array();
|
||||
}
|
||||
|
||||
if ($uri == '/' || empty($uri))
|
||||
{
|
||||
return '/';
|
||||
}
|
||||
|
||||
$uri = parse_url($uri, PHP_URL_PATH);
|
||||
|
||||
// Do some final cleaning of the URI and return it
|
||||
return str_replace(array('//', '../'), '/', trim($uri, '/'));
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Parse cli arguments
|
||||
*
|
||||
* Take each command line argument and assume it is a URI segment.
|
||||
*
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
private function _parse_cli_args()
|
||||
{
|
||||
$args = array_slice($_SERVER['argv'], 1);
|
||||
|
||||
return $args ? '/' . implode('/', $args) : '';
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Filter segments for malicious characters
|
||||
*
|
||||
* @access private
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function _filter_uri($str)
|
||||
{
|
||||
if ($str != '' && $this->config->item('permitted_uri_chars') != '' && $this->config->item('enable_query_strings') == FALSE)
|
||||
{
|
||||
// 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", $str))
|
||||
{
|
||||
show_error('The URI you submitted has disallowed characters.', 400);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert programatic characters to entities
|
||||
$bad = array('$', '(', ')', '%28', '%29');
|
||||
$good = array('$', '(', ')', '(', ')');
|
||||
|
||||
return str_replace($bad, $good, $str);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Remove the suffix from the URL if needed
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
function _remove_url_suffix()
|
||||
{
|
||||
if ($this->config->item('url_suffix') != "")
|
||||
{
|
||||
$this->uri_string = preg_replace("|".preg_quote($this->config->item('url_suffix'))."$|", "", $this->uri_string);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Explode the URI Segments. The individual segments will
|
||||
* be stored in the $this->segments array.
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
function _explode_segments()
|
||||
{
|
||||
foreach (explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val)
|
||||
{
|
||||
// Filter segments for security
|
||||
$val = trim($this->_filter_uri($val));
|
||||
|
||||
if ($val != '')
|
||||
{
|
||||
$this->segments[] = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
function _reindex_segments()
|
||||
{
|
||||
array_unshift($this->segments, NULL);
|
||||
array_unshift($this->rsegments, NULL);
|
||||
unset($this->segments[0]);
|
||||
unset($this->rsegments[0]);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch a URI Segment
|
||||
*
|
||||
* This function returns the URI segment based on the number provided.
|
||||
*
|
||||
* @access public
|
||||
* @param integer
|
||||
* @param bool
|
||||
* @return string
|
||||
*/
|
||||
function segment($n, $no_result = FALSE)
|
||||
{
|
||||
return ( ! isset($this->segments[$n])) ? $no_result : $this->segments[$n];
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch a 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()
|
||||
*
|
||||
* @access public
|
||||
* @param integer
|
||||
* @param bool
|
||||
* @return string
|
||||
*/
|
||||
function rsegment($n, $no_result = FALSE)
|
||||
{
|
||||
return ( ! isset($this->rsegments[$n])) ? $no_result : $this->rsegments[$n];
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Generate a key value pair from the URI string
|
||||
*
|
||||
* This function generates and associative array of URI data starting
|
||||
* at the supplied segment. 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:
|
||||
*
|
||||
* array (
|
||||
* name => joe
|
||||
* location => UK
|
||||
* gender => male
|
||||
* )
|
||||
*
|
||||
* @access public
|
||||
* @param integer the starting segment number
|
||||
* @param array an array of default values
|
||||
* @return array
|
||||
*/
|
||||
function uri_to_assoc($n = 3, $default = array())
|
||||
{
|
||||
return $this->_uri_to_assoc($n, $default, 'segment');
|
||||
}
|
||||
/**
|
||||
* Identical to above only it uses the re-routed segment array
|
||||
*
|
||||
* @access public
|
||||
* @param integer the starting segment number
|
||||
* @param array an array of default values
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
function ruri_to_assoc($n = 3, $default = array())
|
||||
{
|
||||
return $this->_uri_to_assoc($n, $default, 'rsegment');
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Generate a key value pair from the URI string or Re-routed URI string
|
||||
*
|
||||
* @access private
|
||||
* @param integer the starting segment number
|
||||
* @param array an array of default values
|
||||
* @param string which array we should use
|
||||
* @return array
|
||||
*/
|
||||
function _uri_to_assoc($n = 3, $default = array(), $which = 'segment')
|
||||
{
|
||||
if ($which == 'segment')
|
||||
{
|
||||
$total_segments = 'total_segments';
|
||||
$segment_array = 'segment_array';
|
||||
}
|
||||
else
|
||||
{
|
||||
$total_segments = 'total_rsegments';
|
||||
$segment_array = 'rsegment_array';
|
||||
}
|
||||
|
||||
if ( ! is_numeric($n))
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
|
||||
if (isset($this->keyval[$n]))
|
||||
{
|
||||
return $this->keyval[$n];
|
||||
}
|
||||
|
||||
if ($this->$total_segments() < $n)
|
||||
{
|
||||
if (count($default) == 0)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
$retval = array();
|
||||
foreach ($default as $val)
|
||||
{
|
||||
$retval[$val] = FALSE;
|
||||
}
|
||||
return $retval;
|
||||
}
|
||||
|
||||
$segments = array_slice($this->$segment_array(), ($n - 1));
|
||||
|
||||
$i = 0;
|
||||
$lastval = '';
|
||||
$retval = array();
|
||||
foreach ($segments as $seg)
|
||||
{
|
||||
if ($i % 2)
|
||||
{
|
||||
$retval[$lastval] = $seg;
|
||||
}
|
||||
else
|
||||
{
|
||||
$retval[$seg] = FALSE;
|
||||
$lastval = $seg;
|
||||
}
|
||||
|
||||
$i++;
|
||||
}
|
||||
|
||||
if (count($default) > 0)
|
||||
{
|
||||
foreach ($default as $val)
|
||||
{
|
||||
if ( ! array_key_exists($val, $retval))
|
||||
{
|
||||
$retval[$val] = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cache the array for reuse
|
||||
$this->keyval[$n] = $retval;
|
||||
return $retval;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Generate a URI string from an associative array
|
||||
*
|
||||
*
|
||||
* @access public
|
||||
* @param array an associative array of key/values
|
||||
* @return array
|
||||
*/
|
||||
function assoc_to_uri($array)
|
||||
{
|
||||
$temp = array();
|
||||
foreach ((array)$array as $key => $val)
|
||||
{
|
||||
$temp[] = $key;
|
||||
$temp[] = $val;
|
||||
}
|
||||
|
||||
return implode('/', $temp);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch a URI Segment and add a trailing slash
|
||||
*
|
||||
* @access public
|
||||
* @param integer
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function slash_segment($n, $where = 'trailing')
|
||||
{
|
||||
return $this->_slash_segment($n, $where, 'segment');
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch a URI Segment and add a trailing slash
|
||||
*
|
||||
* @access public
|
||||
* @param integer
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function slash_rsegment($n, $where = 'trailing')
|
||||
{
|
||||
return $this->_slash_segment($n, $where, 'rsegment');
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch a URI Segment and add a trailing slash - helper function
|
||||
*
|
||||
* @access private
|
||||
* @param integer
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function _slash_segment($n, $where = 'trailing', $which = 'segment')
|
||||
{
|
||||
$leading = '/';
|
||||
$trailing = '/';
|
||||
|
||||
if ($where == 'trailing')
|
||||
{
|
||||
$leading = '';
|
||||
}
|
||||
elseif ($where == 'leading')
|
||||
{
|
||||
$trailing = '';
|
||||
}
|
||||
|
||||
return $leading.$this->$which($n).$trailing;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Segment Array
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
function segment_array()
|
||||
{
|
||||
return $this->segments;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Routed Segment Array
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
function rsegment_array()
|
||||
{
|
||||
return $this->rsegments;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Total number of segments
|
||||
*
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
function total_segments()
|
||||
{
|
||||
return count($this->segments);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Total number of routed segments
|
||||
*
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
function total_rsegments()
|
||||
{
|
||||
return count($this->rsegments);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch the entire URI string
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function uri_string()
|
||||
{
|
||||
return $this->uri_string;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch the entire Re-routed URI string
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function ruri_string()
|
||||
{
|
||||
return '/'.implode('/', $this->rsegment_array());
|
||||
}
|
||||
|
||||
}
|
||||
// END URI Class
|
||||
|
||||
/* End of file URI.php */
|
||||
/* Location: ./system/core/URI.php */
|
165
system/core/Utf8.php
Normal file
165
system/core/Utf8.php
Normal file
@ -0,0 +1,165 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP 5.1.6 or newer
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
|
||||
* @license http://codeigniter.com/user_guide/license.html
|
||||
* @link http://codeigniter.com
|
||||
* @since Version 2.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Utf8 Class
|
||||
*
|
||||
* Provides support for UTF-8 environments
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Libraries
|
||||
* @category UTF-8
|
||||
* @author ExpressionEngine Dev Team
|
||||
* @link http://codeigniter.com/user_guide/libraries/utf8.html
|
||||
*/
|
||||
class CI_Utf8 {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Determines if UTF-8 support is to be enabled
|
||||
*
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
log_message('debug', "Utf8 Class Initialized");
|
||||
|
||||
global $CFG;
|
||||
|
||||
if (
|
||||
preg_match('/./u', 'é') === 1 // PCRE must support UTF-8
|
||||
AND function_exists('iconv') // iconv must be installed
|
||||
AND ini_get('mbstring.func_overload') != 1 // Multibyte string function overloading cannot be enabled
|
||||
AND $CFG->item('charset') == 'UTF-8' // Application charset must be UTF-8
|
||||
)
|
||||
{
|
||||
log_message('debug', "UTF-8 Support Enabled");
|
||||
|
||||
define('UTF8_ENABLED', TRUE);
|
||||
|
||||
// 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
|
||||
{
|
||||
log_message('debug', "UTF-8 Support Disabled");
|
||||
define('UTF8_ENABLED', FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Clean UTF-8 strings
|
||||
*
|
||||
* Ensures strings are UTF-8
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function clean_string($str)
|
||||
{
|
||||
if ($this->_is_ascii($str) === FALSE)
|
||||
{
|
||||
$str = @iconv('UTF-8', 'UTF-8//IGNORE', $str);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Remove ASCII control characters
|
||||
*
|
||||
* Removes all ASCII control characters except horizontal tabs,
|
||||
* line feeds, and carriage returns, as all others can cause
|
||||
* problems in XML
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function safe_ascii_for_xml($str)
|
||||
{
|
||||
return remove_invisible_characters($str, FALSE);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Convert to UTF-8
|
||||
*
|
||||
* Attempts to convert a string to UTF-8
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @param string - input encoding
|
||||
* @return string
|
||||
*/
|
||||
function convert_to_utf8($str, $encoding)
|
||||
{
|
||||
if (function_exists('iconv'))
|
||||
{
|
||||
$str = @iconv($encoding, 'UTF-8', $str);
|
||||
}
|
||||
elseif (function_exists('mb_convert_encoding'))
|
||||
{
|
||||
$str = @mb_convert_encoding($str, 'UTF-8', $encoding);
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Is ASCII?
|
||||
*
|
||||
* Tests if a string is standard 7-bit ASCII or not
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
function _is_ascii($str)
|
||||
{
|
||||
return (preg_match('/[^\x00-\x7F]/S', $str) == 0);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
}
|
||||
// End Utf8 Class
|
||||
|
||||
/* End of file Utf8.php */
|
||||
/* Location: ./system/core/Utf8.php */
|
10
system/core/index.html
Normal file
10
system/core/index.html
Normal file
@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>403 Forbidden</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>Directory access is forbidden.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user