Moved to PHP folder

This commit is contained in:
2019-06-30 22:04:19 -04:00
parent 6822968785
commit b198cd212f
433 changed files with 0 additions and 0 deletions

View File

@ -0,0 +1,133 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2018, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* 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 EllisLab Dev Team
* @link https://codeigniter.com/user_guide/libraries/benchmark.html
*/
class CI_Benchmark {
/**
* List of all benchmark markers
*
* @var array
*/
public $marker = array();
/**
* Set a benchmark marker
*
* Multiple calls to this function can be made so that several
* execution points can be timed.
*
* @param string $name Marker name
* @return void
*/
public function mark($name)
{
$this->marker[$name] = microtime(TRUE);
}
// --------------------------------------------------------------------
/**
* Elapsed time
*
* 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.
*
* @param string $point1 A particular marked point
* @param string $point2 A particular marked point
* @param int $decimals Number of decimal places
*
* @return string Calculated elapsed time on success,
* an '{elapsed_string}' if $point1 is empty
* or an empty string if $point1 is not found.
*/
public function elapsed_time($point1 = '', $point2 = '', $decimals = 4)
{
if ($point1 === '')
{
return '{elapsed_time}';
}
if ( ! isset($this->marker[$point1]))
{
return '';
}
if ( ! isset($this->marker[$point2]))
{
$this->marker[$point2] = microtime(TRUE);
}
return number_format($this->marker[$point2] - $this->marker[$point1], $decimals);
}
// --------------------------------------------------------------------
/**
* Memory Usage
*
* Simply returns the {memory_usage} marker.
*
* This permits it to be put it anywhere in a template
* without the memory being calculated until the end.
* The output class will swap the real value for this variable.
*
* @return string '{memory_usage}'
*/
public function memory_usage()
{
return '{memory_usage}';
}
}

View File

@ -0,0 +1,559 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2018, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* System Initialization File
*
* Loads the base classes and executes the request.
*
* @package CodeIgniter
* @subpackage CodeIgniter
* @category Front-controller
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/
*/
/**
* CodeIgniter Version
*
* @var string
*
*/
const CI_VERSION = '3.1.9';
/*
* ------------------------------------------------------
* Load the framework constants
* ------------------------------------------------------
*/
if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/constants.php'))
{
require_once(APPPATH.'config/'.ENVIRONMENT.'/constants.php');
}
if (file_exists(APPPATH.'config/constants.php'))
{
require_once(APPPATH.'config/constants.php');
}
/*
* ------------------------------------------------------
* Load the global functions
* ------------------------------------------------------
*/
require_once(BASEPATH.'core/Common.php');
/*
* ------------------------------------------------------
* Security procedures
* ------------------------------------------------------
*/
if ( ! is_php('5.4'))
{
ini_set('magic_quotes_runtime', 0);
if ((bool) ini_get('register_globals'))
{
$_protected = array(
'_SERVER',
'_GET',
'_POST',
'_FILES',
'_REQUEST',
'_SESSION',
'_ENV',
'_COOKIE',
'GLOBALS',
'HTTP_RAW_POST_DATA',
'system_path',
'application_folder',
'view_folder',
'_protected',
'_registered'
);
$_registered = ini_get('variables_order');
foreach (array('E' => '_ENV', 'G' => '_GET', 'P' => '_POST', 'C' => '_COOKIE', 'S' => '_SERVER') as $key => $superglobal)
{
if (strpos($_registered, $key) === FALSE)
{
continue;
}
foreach (array_keys($$superglobal) as $var)
{
if (isset($GLOBALS[$var]) && ! in_array($var, $_protected, TRUE))
{
$GLOBALS[$var] = NULL;
}
}
}
}
}
/*
* ------------------------------------------------------
* Define a custom error handler so we can log PHP errors
* ------------------------------------------------------
*/
set_error_handler('_error_handler');
set_exception_handler('_exception_handler');
register_shutdown_function('_shutdown_handler');
/*
* ------------------------------------------------------
* 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
* overridden 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 ( ! empty($assign_to_config['subclass_prefix']))
{
get_config(array('subclass_prefix' => $assign_to_config['subclass_prefix']));
}
/*
* ------------------------------------------------------
* Should we use a Composer autoloader?
* ------------------------------------------------------
*/
if ($composer_autoload = config_item('composer_autoload'))
{
if ($composer_autoload === TRUE)
{
file_exists(APPPATH.'vendor/autoload.php')
? require_once(APPPATH.'vendor/autoload.php')
: log_message('error', '$config[\'composer_autoload\'] is set to TRUE but '.APPPATH.'vendor/autoload.php was not found.');
}
elseif (file_exists($composer_autoload))
{
require_once($composer_autoload);
}
else
{
log_message('error', 'Could not find the specified $config[\'composer_autoload\'] path: '.$composer_autoload);
}
}
/*
* ------------------------------------------------------
* 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
* ------------------------------------------------------
*
* Note: It is important that Config is loaded first as
* most other classes depend on it either directly or by
* depending on another class that uses it.
*
*/
$CFG =& load_class('Config', 'core');
// Do we have any manually set config items in the index.php file?
if (isset($assign_to_config) && is_array($assign_to_config))
{
foreach ($assign_to_config as $key => $value)
{
$CFG->set_item($key, $value);
}
}
/*
* ------------------------------------------------------
* Important charset-related stuff
* ------------------------------------------------------
*
* Configure mbstring and/or iconv if they are enabled
* and set MB_ENABLED and ICONV_ENABLED constants, so
* that we don't repeatedly do extension_loaded() or
* function_exists() calls.
*
* Note: UTF-8 class depends on this. It used to be done
* in it's constructor, but it's _not_ class-specific.
*
*/
$charset = strtoupper(config_item('charset'));
ini_set('default_charset', $charset);
if (extension_loaded('mbstring'))
{
define('MB_ENABLED', TRUE);
// mbstring.internal_encoding is deprecated starting with PHP 5.6
// and it's usage triggers E_DEPRECATED messages.
@ini_set('mbstring.internal_encoding', $charset);
// This is required for mb_convert_encoding() to strip invalid characters.
// That's utilized by CI_Utf8, but it's also done for consistency with iconv.
mb_substitute_character('none');
}
else
{
define('MB_ENABLED', FALSE);
}
// There's an ICONV_IMPL constant, but the PHP manual says that using
// iconv's predefined constants is "strongly discouraged".
if (extension_loaded('iconv'))
{
define('ICONV_ENABLED', TRUE);
// iconv.internal_encoding is deprecated starting with PHP 5.6
// and it's usage triggers E_DEPRECATED messages.
@ini_set('iconv.internal_encoding', $charset);
}
else
{
define('ICONV_ENABLED', FALSE);
}
if (is_php('5.6'))
{
ini_set('php.internal_encoding', $charset);
}
/*
* ------------------------------------------------------
* Load compatibility features
* ------------------------------------------------------
*/
require_once(BASEPATH.'core/compat/mbstring.php');
require_once(BASEPATH.'core/compat/hash.php');
require_once(BASEPATH.'core/compat/password.php');
require_once(BASEPATH.'core/compat/standard.php');
/*
* ------------------------------------------------------
* Instantiate the UTF-8 class
* ------------------------------------------------------
*/
$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', isset($routing) ? $routing : NULL);
/*
* ------------------------------------------------------
* 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 && $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_once BASEPATH.'core/Controller.php';
/**
* Reference to the CI_Controller method.
*
* Returns current CI instance object
*
* @return CI_Controller
*/
function &get_instance()
{
return CI_Controller::get_instance();
}
if (file_exists(APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php'))
{
require_once APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php';
}
// Set a mark point for benchmarking
$BM->mark('loading_time:_base_classes_end');
/*
* ------------------------------------------------------
* Sanity checks
* ------------------------------------------------------
*
* The Router class has already validated the request,
* leaving us with 3 options here:
*
* 1) an empty class name, if we reached the default
* controller, but it didn't exist;
* 2) a query string which doesn't go through a
* file_exists() check
* 3) a regular request for a non-existing page
*
* We handle all of these as a 404 error.
*
* Furthermore, none of the methods in the app controller
* or the loader class can be called via the URI, nor can
* controller methods that begin with an underscore.
*/
$e404 = FALSE;
$class = ucfirst($RTR->class);
$method = $RTR->method;
if (empty($class) OR ! file_exists(APPPATH.'controllers/'.$RTR->directory.$class.'.php'))
{
$e404 = TRUE;
}
else
{
require_once(APPPATH.'controllers/'.$RTR->directory.$class.'.php');
if ( ! class_exists($class, FALSE) OR $method[0] === '_' OR method_exists('CI_Controller', $method))
{
$e404 = TRUE;
}
elseif (method_exists($class, '_remap'))
{
$params = array($method, array_slice($URI->rsegments, 2));
$method = '_remap';
}
elseif ( ! method_exists($class, $method))
{
$e404 = TRUE;
}
/**
* DO NOT CHANGE THIS, NOTHING ELSE WORKS!
*
* - method_exists() returns true for non-public methods, which passes the previous elseif
* - is_callable() returns false for PHP 4-style constructors, even if there's a __construct()
* - method_exists($class, '__construct') won't work because CI_Controller::__construct() is inherited
* - People will only complain if this doesn't work, even though it is documented that it shouldn't.
*
* ReflectionMethod::isConstructor() is the ONLY reliable check,
* knowing which method will be executed as a constructor.
*/
elseif ( ! is_callable(array($class, $method)))
{
$reflection = new ReflectionMethod($class, $method);
if ( ! $reflection->isPublic() OR $reflection->isConstructor())
{
$e404 = TRUE;
}
}
}
if ($e404)
{
if ( ! empty($RTR->routes['404_override']))
{
if (sscanf($RTR->routes['404_override'], '%[^/]/%s', $error_class, $error_method) !== 2)
{
$error_method = 'index';
}
$error_class = ucfirst($error_class);
if ( ! class_exists($error_class, FALSE))
{
if (file_exists(APPPATH.'controllers/'.$RTR->directory.$error_class.'.php'))
{
require_once(APPPATH.'controllers/'.$RTR->directory.$error_class.'.php');
$e404 = ! class_exists($error_class, FALSE);
}
// Were we in a directory? If so, check for a global override
elseif ( ! empty($RTR->directory) && file_exists(APPPATH.'controllers/'.$error_class.'.php'))
{
require_once(APPPATH.'controllers/'.$error_class.'.php');
if (($e404 = ! class_exists($error_class, FALSE)) === FALSE)
{
$RTR->directory = '';
}
}
}
else
{
$e404 = FALSE;
}
}
// Did we reset the $e404 flag? If so, set the rsegments, starting from index 1
if ( ! $e404)
{
$class = $error_class;
$method = $error_method;
$URI->rsegments = array(
1 => $class,
2 => $method
);
}
else
{
show_404($RTR->directory.$class.'/'.$method);
}
}
if ($method !== '_remap')
{
$params = array_slice($URI->rsegments, 2);
}
/*
* ------------------------------------------------------
* 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
* ------------------------------------------------------
*/
call_user_func_array(array(&$CI, $method), $params);
// 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');

849
php/system/core/Common.php Normal file
View File

@ -0,0 +1,849 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2018, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Common Functions
*
* Loads the base classes and executes the request.
*
* @package CodeIgniter
* @subpackage CodeIgniter
* @category Common Functions
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/
*/
// ------------------------------------------------------------------------
if ( ! function_exists('is_php'))
{
/**
* Determines if the current version of PHP is equal to or greater than the supplied value
*
* @param string
* @return bool TRUE if the current version is $version or higher
*/
function is_php($version)
{
static $_is_php;
$version = (string) $version;
if ( ! isset($_is_php[$version]))
{
$_is_php[$version] = version_compare(PHP_VERSION, $version, '>=');
}
return $_is_php[$version];
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('is_really_writable'))
{
/**
* 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.
*
* @link https://bugs.php.net/bug.php?id=54709
* @param string
* @return bool
*/
function is_really_writable($file)
{
// If we're on a Unix server with safe_mode off we call is_writable
if (DIRECTORY_SEPARATOR === '/' && (is_php('5.4') OR ! ini_get('safe_mode')))
{
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());
if (($fp = @fopen($file, 'ab')) === FALSE)
{
return FALSE;
}
fclose($fp);
@chmod($file, 0777);
@unlink($file);
return TRUE;
}
elseif ( ! is_file($file) OR ($fp = @fopen($file, 'ab')) === FALSE)
{
return FALSE;
}
fclose($fp);
return TRUE;
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('load_class'))
{
/**
* 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.
*
* @param string the class name being requested
* @param string the directory where the class should be found
* @param mixed an optional argument to pass to the class constructor
* @return object
*/
function &load_class($class, $directory = 'libraries', $param = NULL)
{
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 = 'CI_'.$class;
if (class_exists($name, FALSE) === FALSE)
{
require_once($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) === FALSE)
{
require_once(APPPATH.$directory.'/'.$name.'.php');
}
}
// Did we find the class?
if ($name === FALSE)
{
// Note: We use exit() rather than show_error() in order to avoid a
// self-referencing loop with the Exceptions class
set_status_header(503);
echo 'Unable to locate the specified class: '.$class.'.php';
exit(5); // EXIT_UNK_CLASS
}
// Keep track of what we just loaded
is_loaded($class);
$_classes[$class] = isset($param)
? new $name($param)
: new $name();
return $_classes[$class];
}
}
// --------------------------------------------------------------------
if ( ! function_exists('is_loaded'))
{
/**
* Keeps track of which libraries have been loaded. This function is
* called by the load_class() function above
*
* @param string
* @return array
*/
function &is_loaded($class = '')
{
static $_is_loaded = array();
if ($class !== '')
{
$_is_loaded[strtolower($class)] = $class;
}
return $_is_loaded;
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('get_config'))
{
/**
* Loads the main config.php file
*
* This function lets us grab the config file even if the Config class
* hasn't been instantiated yet
*
* @param array
* @return array
*/
function &get_config(Array $replace = array())
{
static $config;
if (empty($config))
{
$file_path = APPPATH.'config/config.php';
$found = FALSE;
if (file_exists($file_path))
{
$found = TRUE;
require($file_path);
}
// Is the config file in the environment folder?
if (file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php'))
{
require($file_path);
}
elseif ( ! $found)
{
set_status_header(503);
echo 'The configuration file does not exist.';
exit(3); // EXIT_CONFIG
}
// Does the $config array exist in the file?
if ( ! isset($config) OR ! is_array($config))
{
set_status_header(503);
echo 'Your config file does not appear to be formatted correctly.';
exit(3); // EXIT_CONFIG
}
}
// Are any values being dynamically added or replaced?
foreach ($replace as $key => $val)
{
$config[$key] = $val;
}
return $config;
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('config_item'))
{
/**
* Returns the specified config item
*
* @param string
* @return mixed
*/
function config_item($item)
{
static $_config;
if (empty($_config))
{
// references cannot be directly assigned to static variables, so we use an array
$_config[0] =& get_config();
}
return isset($_config[0][$item]) ? $_config[0][$item] : NULL;
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('get_mimes'))
{
/**
* Returns the MIME types array from config/mimes.php
*
* @return array
*/
function &get_mimes()
{
static $_mimes;
if (empty($_mimes))
{
$_mimes = file_exists(APPPATH.'config/mimes.php')
? include(APPPATH.'config/mimes.php')
: array();
if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
{
$_mimes = array_merge($_mimes, include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'));
}
}
return $_mimes;
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('is_https'))
{
/**
* Is HTTPS?
*
* Determines if the application is accessed via an encrypted
* (HTTPS) connection.
*
* @return bool
*/
function is_https()
{
if ( ! empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off')
{
return TRUE;
}
elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https')
{
return TRUE;
}
elseif ( ! empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off')
{
return TRUE;
}
return FALSE;
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('is_cli'))
{
/**
* Is CLI?
*
* Test to see if a request was made from the command line.
*
* @return bool
*/
function is_cli()
{
return (PHP_SAPI === 'cli' OR defined('STDIN'));
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('show_error'))
{
/**
* Error Handler
*
* This function lets us invoke the exception class and
* display errors using the standard error template located
* in application/views/errors/error_general.php
* This function will send the error page directly to the
* browser and exit.
*
* @param string
* @param int
* @param string
* @return void
*/
function show_error($message, $status_code = 500, $heading = 'An Error Was Encountered')
{
$status_code = abs($status_code);
if ($status_code < 100)
{
$exit_status = $status_code + 9; // 9 is EXIT__AUTO_MIN
$status_code = 500;
}
else
{
$exit_status = 1; // EXIT_ERROR
}
$_error =& load_class('Exceptions', 'core');
echo $_error->show_error($heading, $message, 'error_general', $status_code);
exit($exit_status);
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('show_404'))
{
/**
* 404 Page Handler
*
* This function is similar to the show_error() function above
* However, instead of the standard error template it displays
* 404 errors.
*
* @param string
* @param bool
* @return void
*/
function show_404($page = '', $log_error = TRUE)
{
$_error =& load_class('Exceptions', 'core');
$_error->show_404($page, $log_error);
exit(4); // EXIT_UNKNOWN_FILE
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('log_message'))
{
/**
* Error Logging Interface
*
* We use this as a simple mechanism to access the logging
* class and send messages to be logged.
*
* @param string the error level: 'error', 'debug' or 'info'
* @param string the error message
* @return void
*/
function log_message($level, $message)
{
static $_log;
if ($_log === NULL)
{
// references cannot be directly assigned to static variables, so we use an array
$_log[0] =& load_class('Log', 'core');
}
$_log[0]->write_log($level, $message);
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('set_status_header'))
{
/**
* Set HTTP Status Header
*
* @param int the status code
* @param string
* @return void
*/
function set_status_header($code = 200, $text = '')
{
if (is_cli())
{
return;
}
if (empty($code) OR ! is_numeric($code))
{
show_error('Status codes must be numeric', 500);
}
if (empty($text))
{
is_int($code) OR $code = (int) $code;
$stati = array(
100 => 'Continue',
101 => 'Switching Protocols',
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',
303 => 'See Other',
304 => 'Not Modified',
305 => 'Use Proxy',
307 => 'Temporary Redirect',
400 => 'Bad Request',
401 => 'Unauthorized',
402 => 'Payment Required',
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',
422 => 'Unprocessable Entity',
426 => 'Upgrade Required',
428 => 'Precondition Required',
429 => 'Too Many Requests',
431 => 'Request Header Fields Too Large',
500 => 'Internal Server Error',
501 => 'Not Implemented',
502 => 'Bad Gateway',
503 => 'Service Unavailable',
504 => 'Gateway Timeout',
505 => 'HTTP Version Not Supported',
511 => 'Network Authentication Required',
);
if (isset($stati[$code]))
{
$text = $stati[$code];
}
else
{
show_error('No status text available. Please check your status code number or supply your own message text.', 500);
}
}
if (strpos(PHP_SAPI, 'cgi') === 0)
{
header('Status: '.$code.' '.$text, TRUE);
return;
}
$server_protocol = (isset($_SERVER['SERVER_PROTOCOL']) && in_array($_SERVER['SERVER_PROTOCOL'], array('HTTP/1.0', 'HTTP/1.1', 'HTTP/2'), TRUE))
? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1';
header($server_protocol.' '.$code.' '.$text, TRUE, $code);
}
}
// --------------------------------------------------------------------
if ( ! function_exists('_error_handler'))
{
/**
* Error Handler
*
* This is the custom error handler that is declared at the (relative)
* 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.
*
* @param int $severity
* @param string $message
* @param string $filepath
* @param int $line
* @return void
*/
function _error_handler($severity, $message, $filepath, $line)
{
$is_error = (((E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity);
// When an error occurred, set the status header to '500 Internal Server Error'
// to indicate to the client something went wrong.
// This can't be done within the $_error->show_php_error method because
// it is only called when the display_errors flag is set (which isn't usually
// the case in a production environment) or when errors are ignored because
// they are above the error_reporting threshold.
if ($is_error)
{
set_status_header(500);
}
// Should we ignore 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)
{
return;
}
$_error =& load_class('Exceptions', 'core');
$_error->log_exception($severity, $message, $filepath, $line);
// Should we display the error?
if (str_ireplace(array('off', 'none', 'no', 'false', 'null'), '', ini_get('display_errors')))
{
$_error->show_php_error($severity, $message, $filepath, $line);
}
// If the error is fatal, the execution of the script should be stopped because
// errors can't be recovered from. Halting the script conforms with PHP's
// default error handling. See http://www.php.net/manual/en/errorfunc.constants.php
if ($is_error)
{
exit(1); // EXIT_ERROR
}
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('_exception_handler'))
{
/**
* Exception Handler
*
* Sends uncaught exceptions to the logger and displays them
* only if display_errors is On so that they don't show up in
* production environments.
*
* @param Exception $exception
* @return void
*/
function _exception_handler($exception)
{
$_error =& load_class('Exceptions', 'core');
$_error->log_exception('error', 'Exception: '.$exception->getMessage(), $exception->getFile(), $exception->getLine());
is_cli() OR set_status_header(500);
// Should we display the error?
if (str_ireplace(array('off', 'none', 'no', 'false', 'null'), '', ini_get('display_errors')))
{
$_error->show_exception($exception);
}
exit(1); // EXIT_ERROR
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('_shutdown_handler'))
{
/**
* Shutdown Handler
*
* This is the shutdown handler that is declared at the top
* of CodeIgniter.php. The main reason we use this is to simulate
* a complete custom exception handler.
*
* E_STRICT is purposively neglected because such events may have
* been caught. Duplication or none? None is preferred for now.
*
* @link http://insomanic.me.uk/post/229851073/php-trick-catching-fatal-errors-e-error-with-a
* @return void
*/
function _shutdown_handler()
{
$last_error = error_get_last();
if (isset($last_error) &&
($last_error['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING)))
{
_error_handler($last_error['type'], $last_error['message'], $last_error['file'], $last_error['line']);
}
}
}
// --------------------------------------------------------------------
if ( ! function_exists('remove_invisible_characters'))
{
/**
* Remove Invisible Characters
*
* This prevents sandwiching null characters
* between ascii characters, like Java\0script.
*
* @param string
* @param bool
* @return string
*/
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]/i'; // url encoded 00-08, 11, 12, 14, 15
$non_displayables[] = '/%1[0-9a-f]/i'; // url encoded 16-31
$non_displayables[] = '/%7f/i'; // url encoded 127
}
$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;
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('html_escape'))
{
/**
* Returns HTML escaped variable.
*
* @param mixed $var The input string or array of strings to be escaped.
* @param bool $double_encode $double_encode set to FALSE prevents escaping twice.
* @return mixed The escaped string or array of strings as a result.
*/
function html_escape($var, $double_encode = TRUE)
{
if (empty($var))
{
return $var;
}
if (is_array($var))
{
foreach (array_keys($var) as $key)
{
$var[$key] = html_escape($var[$key], $double_encode);
}
return $var;
}
return htmlspecialchars($var, ENT_QUOTES, config_item('charset'), $double_encode);
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('_stringify_attributes'))
{
/**
* Stringify attributes for use in HTML tags.
*
* Helper function used to convert a string, array, or object
* of attributes to a string.
*
* @param mixed string, array, object
* @param bool
* @return string
*/
function _stringify_attributes($attributes, $js = FALSE)
{
$atts = NULL;
if (empty($attributes))
{
return $atts;
}
if (is_string($attributes))
{
return ' '.$attributes;
}
$attributes = (array) $attributes;
foreach ($attributes as $key => $val)
{
$atts .= ($js) ? $key.'='.$val.',' : ' '.$key.'="'.$val.'"';
}
return rtrim($atts, ',');
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('function_usable'))
{
/**
* Function usable
*
* Executes a function_exists() check, and if the Suhosin PHP
* extension is loaded - checks whether the function that is
* checked might be disabled in there as well.
*
* This is useful as function_exists() will return FALSE for
* functions disabled via the *disable_functions* php.ini
* setting, but not for *suhosin.executor.func.blacklist* and
* *suhosin.executor.disable_eval*. These settings will just
* terminate script execution if a disabled function is executed.
*
* The above described behavior turned out to be a bug in Suhosin,
* but even though a fix was committed for 0.9.34 on 2012-02-12,
* that version is yet to be released. This function will therefore
* be just temporary, but would probably be kept for a few years.
*
* @link http://www.hardened-php.net/suhosin/
* @param string $function_name Function to check for
* @return bool TRUE if the function exists and is safe to call,
* FALSE otherwise.
*/
function function_usable($function_name)
{
static $_suhosin_func_blacklist;
if (function_exists($function_name))
{
if ( ! isset($_suhosin_func_blacklist))
{
$_suhosin_func_blacklist = extension_loaded('suhosin')
? explode(',', trim(ini_get('suhosin.executor.func.blacklist')))
: array();
}
return ! in_array($function_name, $_suhosin_func_blacklist, TRUE);
}
return FALSE;
}
}

379
php/system/core/Config.php Normal file
View File

@ -0,0 +1,379 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2018, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Config Class
*
* This class contains functions that enable config files to be managed
*
* @package CodeIgniter
* @subpackage Libraries
* @category Libraries
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/libraries/config.html
*/
class CI_Config {
/**
* List of all loaded config values
*
* @var array
*/
public $config = array();
/**
* List of all loaded config files
*
* @var array
*/
public $is_loaded = array();
/**
* List of paths to search when trying to load a config file.
*
* @used-by CI_Loader
* @var array
*/
public $_config_paths = array(APPPATH);
// --------------------------------------------------------------------
/**
* Class constructor
*
* Sets the $config data from the primary config.php file as a class variable.
*
* @return void
*/
public function __construct()
{
$this->config =& get_config();
// Set the base_url automatically if none was provided
if (empty($this->config['base_url']))
{
if (isset($_SERVER['SERVER_ADDR']))
{
if (strpos($_SERVER['SERVER_ADDR'], ':') !== FALSE)
{
$server_addr = '['.$_SERVER['SERVER_ADDR'].']';
}
else
{
$server_addr = $_SERVER['SERVER_ADDR'];
}
$base_url = (is_https() ? 'https' : 'http').'://'.$server_addr
.substr($_SERVER['SCRIPT_NAME'], 0, strpos($_SERVER['SCRIPT_NAME'], basename($_SERVER['SCRIPT_FILENAME'])));
}
else
{
$base_url = 'http://localhost/';
}
$this->set_item('base_url', $base_url);
}
log_message('info', 'Config Class Initialized');
}
// --------------------------------------------------------------------
/**
* Load Config File
*
* @param string $file Configuration file name
* @param bool $use_sections Whether configuration values should be loaded into their own section
* @param bool $fail_gracefully Whether to just return FALSE or display an error message
* @return bool TRUE if the file was loaded correctly or FALSE on failure
*/
public function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
{
$file = ($file === '') ? 'config' : str_replace('.php', '', $file);
$loaded = FALSE;
foreach ($this->_config_paths as $path)
{
foreach (array($file, ENVIRONMENT.DIRECTORY_SEPARATOR.$file) as $location)
{
$file_path = $path.'config/'.$location.'.php';
if (in_array($file_path, $this->is_loaded, TRUE))
{
return TRUE;
}
if ( ! file_exists($file_path))
{
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)
{
$this->config[$file] = isset($this->config[$file])
? array_merge($this->config[$file], $config)
: $config;
}
else
{
$this->config = array_merge($this->config, $config);
}
$this->is_loaded[] = $file_path;
$config = NULL;
$loaded = TRUE;
log_message('debug', 'Config file loaded: '.$file_path);
}
}
if ($loaded === TRUE)
{
return TRUE;
}
elseif ($fail_gracefully === TRUE)
{
return FALSE;
}
show_error('The configuration file '.$file.'.php does not exist.');
}
// --------------------------------------------------------------------
/**
* Fetch a config file item
*
* @param string $item Config item name
* @param string $index Index name
* @return string|null The configuration item or NULL if the item doesn't exist
*/
public function item($item, $index = '')
{
if ($index == '')
{
return isset($this->config[$item]) ? $this->config[$item] : NULL;
}
return isset($this->config[$index], $this->config[$index][$item]) ? $this->config[$index][$item] : NULL;
}
// --------------------------------------------------------------------
/**
* Fetch a config file item with slash appended (if not empty)
*
* @param string $item Config item name
* @return string|null The configuration item or NULL if the item doesn't exist
*/
public function slash_item($item)
{
if ( ! isset($this->config[$item]))
{
return NULL;
}
elseif (trim($this->config[$item]) === '')
{
return '';
}
return rtrim($this->config[$item], '/').'/';
}
// --------------------------------------------------------------------
/**
* Site URL
*
* Returns base_url . index_page [. uri_string]
*
* @uses CI_Config::_uri_string()
*
* @param string|string[] $uri URI string or an array of segments
* @param string $protocol
* @return string
*/
public function site_url($uri = '', $protocol = NULL)
{
$base_url = $this->slash_item('base_url');
if (isset($protocol))
{
// For protocol-relative links
if ($protocol === '')
{
$base_url = substr($base_url, strpos($base_url, '//'));
}
else
{
$base_url = $protocol.substr($base_url, strpos($base_url, '://'));
}
}
if (empty($uri))
{
return $base_url.$this->item('index_page');
}
$uri = $this->_uri_string($uri);
if ($this->item('enable_query_strings') === FALSE)
{
$suffix = isset($this->config['url_suffix']) ? $this->config['url_suffix'] : '';
if ($suffix !== '')
{
if (($offset = strpos($uri, '?')) !== FALSE)
{
$uri = substr($uri, 0, $offset).$suffix.substr($uri, $offset);
}
else
{
$uri .= $suffix;
}
}
return $base_url.$this->slash_item('index_page').$uri;
}
elseif (strpos($uri, '?') === FALSE)
{
$uri = '?'.$uri;
}
return $base_url.$this->item('index_page').$uri;
}
// -------------------------------------------------------------
/**
* Base URL
*
* Returns base_url [. uri_string]
*
* @uses CI_Config::_uri_string()
*
* @param string|string[] $uri URI string or an array of segments
* @param string $protocol
* @return string
*/
public function base_url($uri = '', $protocol = NULL)
{
$base_url = $this->slash_item('base_url');
if (isset($protocol))
{
// For protocol-relative links
if ($protocol === '')
{
$base_url = substr($base_url, strpos($base_url, '//'));
}
else
{
$base_url = $protocol.substr($base_url, strpos($base_url, '://'));
}
}
return $base_url.$this->_uri_string($uri);
}
// -------------------------------------------------------------
/**
* Build URI string
*
* @used-by CI_Config::site_url()
* @used-by CI_Config::base_url()
*
* @param string|string[] $uri URI string or an array of segments
* @return string
*/
protected function _uri_string($uri)
{
if ($this->item('enable_query_strings') === FALSE)
{
is_array($uri) && $uri = implode('/', $uri);
return ltrim($uri, '/');
}
elseif (is_array($uri))
{
return http_build_query($uri);
}
return $uri;
}
// --------------------------------------------------------------------
/**
* System URL
*
* @deprecated 3.0.0 Encourages insecure practices
* @return string
*/
public function system_url()
{
$x = explode('/', preg_replace('|/*(.+?)/*$|', '\\1', BASEPATH));
return $this->slash_item('base_url').end($x).'/';
}
// --------------------------------------------------------------------
/**
* Set a config file item
*
* @param string $item Config item key
* @param string $value Config item value
* @return void
*/
public function set_item($item, $value)
{
$this->config[$item] = $value;
}
}

View File

@ -0,0 +1,96 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2018, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* 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 EllisLab Dev Team
* @link https://codeigniter.com/user_guide/general/controllers.html
*/
class CI_Controller {
/**
* Reference to the CI singleton
*
* @var object
*/
private static $instance;
/**
* Class constructor
*
* @return void
*/
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('info', 'Controller Class Initialized');
}
// --------------------------------------------------------------------
/**
* Get the CI singleton
*
* @static
* @return object
*/
public static function &get_instance()
{
return self::$instance;
}
}

View File

@ -0,0 +1,274 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2018, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Exceptions Class
*
* @package CodeIgniter
* @subpackage Libraries
* @category Exceptions
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/libraries/exceptions.html
*/
class CI_Exceptions {
/**
* Nesting level of the output buffering mechanism
*
* @var int
*/
public $ob_level;
/**
* List of available error levels
*
* @var array
*/
public $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'
);
/**
* Class constructor
*
* @return void
*/
public function __construct()
{
$this->ob_level = ob_get_level();
// Note: Do not log messages from this constructor.
}
// --------------------------------------------------------------------
/**
* Exception Logger
*
* Logs PHP generated error messages
*
* @param int $severity Log level
* @param string $message Error message
* @param string $filepath File path
* @param int $line Line number
* @return void
*/
public function log_exception($severity, $message, $filepath, $line)
{
$severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity;
log_message('error', 'Severity: '.$severity.' --> '.$message.' '.$filepath.' '.$line);
}
// --------------------------------------------------------------------
/**
* 404 Error Handler
*
* @uses CI_Exceptions::show_error()
*
* @param string $page Page URI
* @param bool $log_error Whether to log the error
* @return void
*/
public function show_404($page = '', $log_error = TRUE)
{
if (is_cli())
{
$heading = 'Not Found';
$message = 'The controller/method pair you requested was not found.';
}
else
{
$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', $heading.': '.$page);
}
echo $this->show_error($heading, $message, 'error_404', 404);
exit(4); // EXIT_UNKNOWN_FILE
}
// --------------------------------------------------------------------
/**
* General Error Page
*
* Takes an error message as input (either as a string or an array)
* and displays it using the specified template.
*
* @param string $heading Page heading
* @param string|string[] $message Error message
* @param string $template Template name
* @param int $status_code (default: 500)
*
* @return string Error page output
*/
public function show_error($heading, $message, $template = 'error_general', $status_code = 500)
{
$templates_path = config_item('error_views_path');
if (empty($templates_path))
{
$templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
}
if (is_cli())
{
$message = "\t".(is_array($message) ? implode("\n\t", $message) : $message);
$template = 'cli'.DIRECTORY_SEPARATOR.$template;
}
else
{
set_status_header($status_code);
$message = '<p>'.(is_array($message) ? implode('</p><p>', $message) : $message).'</p>';
$template = 'html'.DIRECTORY_SEPARATOR.$template;
}
if (ob_get_level() > $this->ob_level + 1)
{
ob_end_flush();
}
ob_start();
include($templates_path.$template.'.php');
$buffer = ob_get_contents();
ob_end_clean();
return $buffer;
}
// --------------------------------------------------------------------
public function show_exception($exception)
{
$templates_path = config_item('error_views_path');
if (empty($templates_path))
{
$templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
}
$message = $exception->getMessage();
if (empty($message))
{
$message = '(null)';
}
if (is_cli())
{
$templates_path .= 'cli'.DIRECTORY_SEPARATOR;
}
else
{
$templates_path .= 'html'.DIRECTORY_SEPARATOR;
}
if (ob_get_level() > $this->ob_level + 1)
{
ob_end_flush();
}
ob_start();
include($templates_path.'error_exception.php');
$buffer = ob_get_contents();
ob_end_clean();
echo $buffer;
}
// --------------------------------------------------------------------
/**
* Native PHP error handler
*
* @param int $severity Error level
* @param string $message Error message
* @param string $filepath File path
* @param int $line Line number
* @return void
*/
public function show_php_error($severity, $message, $filepath, $line)
{
$templates_path = config_item('error_views_path');
if (empty($templates_path))
{
$templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
}
$severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity;
// For safety reasons we don't show the full file path in non-CLI requests
if ( ! is_cli())
{
$filepath = str_replace('\\', '/', $filepath);
if (FALSE !== strpos($filepath, '/'))
{
$x = explode('/', $filepath);
$filepath = $x[count($x)-2].'/'.end($x);
}
$template = 'html'.DIRECTORY_SEPARATOR.'error_php';
}
else
{
$template = 'cli'.DIRECTORY_SEPARATOR.'error_php';
}
if (ob_get_level() > $this->ob_level + 1)
{
ob_end_flush();
}
ob_start();
include($templates_path.$template.'.php');
$buffer = ob_get_contents();
ob_end_clean();
echo $buffer;
}
}

266
php/system/core/Hooks.php Normal file
View File

@ -0,0 +1,266 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2018, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Hooks Class
*
* Provides a mechanism to extend the base system without hacking.
*
* @package CodeIgniter
* @subpackage Libraries
* @category Libraries
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/general/hooks.html
*/
class CI_Hooks {
/**
* Determines whether hooks are enabled
*
* @var bool
*/
public $enabled = FALSE;
/**
* List of all hooks set in config/hooks.php
*
* @var array
*/
public $hooks = array();
/**
* Array with class objects to use hooks methods
*
* @var array
*/
protected $_objects = array();
/**
* In progress flag
*
* Determines whether hook is in progress, used to prevent infinte loops
*
* @var bool
*/
protected $_in_progress = FALSE;
/**
* Class constructor
*
* @return void
*/
public function __construct()
{
$CFG =& load_class('Config', 'core');
log_message('info', 'Hooks Class Initialized');
// 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 (file_exists(APPPATH.'config/hooks.php'))
{
include(APPPATH.'config/hooks.php');
}
if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'))
{
include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php');
}
// If there are no hooks, we're done.
if ( ! isset($hook) OR ! is_array($hook))
{
return;
}
$this->hooks =& $hook;
$this->enabled = TRUE;
}
// --------------------------------------------------------------------
/**
* Call Hook
*
* Calls a particular hook. Called by CodeIgniter.php.
*
* @uses CI_Hooks::_run_hook()
*
* @param string $which Hook name
* @return bool TRUE on success or FALSE on failure
*/
public function call_hook($which = '')
{
if ( ! $this->enabled OR ! isset($this->hooks[$which]))
{
return FALSE;
}
if (is_array($this->hooks[$which]) && ! isset($this->hooks[$which]['function']))
{
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
*
* @param array $data Hook details
* @return bool TRUE on success or FALSE on failure
*/
protected function _run_hook($data)
{
// Closures/lambda functions and array($object, 'method') callables
if (is_callable($data))
{
is_array($data)
? $data[0]->{$data[1]}()
: $data();
return TRUE;
}
elseif ( ! 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'], $data['filename']))
{
return FALSE;
}
$filepath = APPPATH.$data['filepath'].'/'.$data['filename'];
if ( ! file_exists($filepath))
{
return FALSE;
}
// Determine and class and/or function names
$class = empty($data['class']) ? FALSE : $data['class'];
$function = empty($data['function']) ? FALSE : $data['function'];
$params = isset($data['params']) ? $data['params'] : '';
if (empty($function))
{
return FALSE;
}
// Set the _in_progress flag
$this->_in_progress = TRUE;
// Call the requested class and/or function
if ($class !== FALSE)
{
// The object is stored?
if (isset($this->_objects[$class]))
{
if (method_exists($this->_objects[$class], $function))
{
$this->_objects[$class]->$function($params);
}
else
{
return $this->_in_progress = FALSE;
}
}
else
{
class_exists($class, FALSE) OR require_once($filepath);
if ( ! class_exists($class, FALSE) OR ! method_exists($class, $function))
{
return $this->_in_progress = FALSE;
}
// Store the object and execute the method
$this->_objects[$class] = new $class();
$this->_objects[$class]->$function($params);
}
}
else
{
function_exists($function) OR require_once($filepath);
if ( ! function_exists($function))
{
return $this->_in_progress = FALSE;
}
$function($params);
}
$this->_in_progress = FALSE;
return TRUE;
}
}

895
php/system/core/Input.php Normal file
View File

@ -0,0 +1,895 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2018, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Input Class
*
* Pre-processes global input data for security
*
* @package CodeIgniter
* @subpackage Libraries
* @category Input
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/libraries/input.html
*/
class CI_Input {
/**
* IP address of the current user
*
* @var string
*/
protected $ip_address = FALSE;
/**
* Allow GET array flag
*
* If set to FALSE, then $_GET will be set to an empty array.
*
* @var bool
*/
protected $_allow_get_array = TRUE;
/**
* Standardize new lines flag
*
* If set to TRUE, then newlines are standardized.
*
* @var bool
*/
protected $_standardize_newlines;
/**
* Enable XSS flag
*
* Determines whether the XSS filter is always active when
* GET, POST or COOKIE data is encountered.
* Set automatically based on config setting.
*
* @var bool
*/
protected $_enable_xss = FALSE;
/**
* Enable CSRF flag
*
* Enables a CSRF cookie token to be set.
* Set automatically based on config setting.
*
* @var bool
*/
protected $_enable_csrf = FALSE;
/**
* List of all HTTP request headers
*
* @var array
*/
protected $headers = array();
/**
* Raw input stream data
*
* Holds a cache of php://input contents
*
* @var string
*/
protected $_raw_input_stream;
/**
* Parsed input stream data
*
* Parsed from php://input at runtime
*
* @see CI_Input::input_stream()
* @var array
*/
protected $_input_stream;
protected $security;
protected $uni;
// --------------------------------------------------------------------
/**
* Class constructor
*
* Determines whether to globally enable the XSS processing
* and whether to allow the $_GET array.
*
* @return void
*/
public function __construct()
{
$this->_allow_get_array = (config_item('allow_get_array') !== FALSE);
$this->_enable_xss = (config_item('global_xss_filtering') === TRUE);
$this->_enable_csrf = (config_item('csrf_protection') === TRUE);
$this->_standardize_newlines = (bool) config_item('standardize_newlines');
$this->security =& load_class('Security', 'core');
// Do we need the UTF-8 class?
if (UTF8_ENABLED === TRUE)
{
$this->uni =& load_class('Utf8', 'core');
}
// Sanitize global arrays
$this->_sanitize_globals();
// CSRF Protection check
if ($this->_enable_csrf === TRUE && ! is_cli())
{
$this->security->csrf_verify();
}
log_message('info', 'Input Class Initialized');
}
// --------------------------------------------------------------------
/**
* Fetch from array
*
* Internal method used to retrieve values from global arrays.
*
* @param array &$array $_GET, $_POST, $_COOKIE, $_SERVER, etc.
* @param mixed $index Index for item to be fetched from $array
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
protected function _fetch_from_array(&$array, $index = NULL, $xss_clean = NULL)
{
is_bool($xss_clean) OR $xss_clean = $this->_enable_xss;
// If $index is NULL, it means that the whole $array is requested
isset($index) OR $index = array_keys($array);
// allow fetching multiple keys at once
if (is_array($index))
{
$output = array();
foreach ($index as $key)
{
$output[$key] = $this->_fetch_from_array($array, $key, $xss_clean);
}
return $output;
}
if (isset($array[$index]))
{
$value = $array[$index];
}
elseif (($count = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $index, $matches)) > 1) // Does the index contain array notation
{
$value = $array;
for ($i = 0; $i < $count; $i++)
{
$key = trim($matches[0][$i], '[]');
if ($key === '') // Empty notation will return the value as array
{
break;
}
if (isset($value[$key]))
{
$value = $value[$key];
}
else
{
return NULL;
}
}
}
else
{
return NULL;
}
return ($xss_clean === TRUE)
? $this->security->xss_clean($value)
: $value;
}
// --------------------------------------------------------------------
/**
* Fetch an item from the GET array
*
* @param mixed $index Index for item to be fetched from $_GET
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
public function get($index = NULL, $xss_clean = NULL)
{
return $this->_fetch_from_array($_GET, $index, $xss_clean);
}
// --------------------------------------------------------------------
/**
* Fetch an item from the POST array
*
* @param mixed $index Index for item to be fetched from $_POST
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
public function post($index = NULL, $xss_clean = NULL)
{
return $this->_fetch_from_array($_POST, $index, $xss_clean);
}
// --------------------------------------------------------------------
/**
* Fetch an item from POST data with fallback to GET
*
* @param string $index Index for item to be fetched from $_POST or $_GET
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
public function post_get($index, $xss_clean = NULL)
{
return isset($_POST[$index])
? $this->post($index, $xss_clean)
: $this->get($index, $xss_clean);
}
// --------------------------------------------------------------------
/**
* Fetch an item from GET data with fallback to POST
*
* @param string $index Index for item to be fetched from $_GET or $_POST
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
public function get_post($index, $xss_clean = NULL)
{
return isset($_GET[$index])
? $this->get($index, $xss_clean)
: $this->post($index, $xss_clean);
}
// --------------------------------------------------------------------
/**
* Fetch an item from the COOKIE array
*
* @param mixed $index Index for item to be fetched from $_COOKIE
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
public function cookie($index = NULL, $xss_clean = NULL)
{
return $this->_fetch_from_array($_COOKIE, $index, $xss_clean);
}
// --------------------------------------------------------------------
/**
* Fetch an item from the SERVER array
*
* @param mixed $index Index for item to be fetched from $_SERVER
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
public function server($index, $xss_clean = NULL)
{
return $this->_fetch_from_array($_SERVER, $index, $xss_clean);
}
// ------------------------------------------------------------------------
/**
* Fetch an item from the php://input stream
*
* Useful when you need to access PUT, DELETE or PATCH request data.
*
* @param string $index Index for item to be fetched
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
public function input_stream($index = NULL, $xss_clean = NULL)
{
// Prior to PHP 5.6, the input stream can only be read once,
// so we'll need to check if we have already done that first.
if ( ! is_array($this->_input_stream))
{
// $this->raw_input_stream will trigger __get().
parse_str($this->raw_input_stream, $this->_input_stream);
is_array($this->_input_stream) OR $this->_input_stream = array();
}
return $this->_fetch_from_array($this->_input_stream, $index, $xss_clean);
}
// ------------------------------------------------------------------------
/**
* Set cookie
*
* Accepts an arbitrary number of parameters (up to 7) or an associative
* array in the first parameter containing all the values.
*
* @param string|mixed[] $name Cookie name or an array containing parameters
* @param string $value Cookie value
* @param int $expire Cookie expiration time in seconds
* @param string $domain Cookie domain (e.g.: '.yourdomain.com')
* @param string $path Cookie path (default: '/')
* @param string $prefix Cookie name prefix
* @param bool $secure Whether to only transfer cookies via SSL
* @param bool $httponly Whether to only makes the cookie accessible via HTTP (no javascript)
* @return void
*/
public function set_cookie($name, $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = NULL, $httponly = NULL)
{
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', 'httponly', 'name') as $item)
{
if (isset($name[$item]))
{
$$item = $name[$item];
}
}
}
if ($prefix === '' && config_item('cookie_prefix') !== '')
{
$prefix = config_item('cookie_prefix');
}
if ($domain == '' && config_item('cookie_domain') != '')
{
$domain = config_item('cookie_domain');
}
if ($path === '/' && config_item('cookie_path') !== '/')
{
$path = config_item('cookie_path');
}
$secure = ($secure === NULL && config_item('cookie_secure') !== NULL)
? (bool) config_item('cookie_secure')
: (bool) $secure;
$httponly = ($httponly === NULL && config_item('cookie_httponly') !== NULL)
? (bool) config_item('cookie_httponly')
: (bool) $httponly;
if ( ! is_numeric($expire))
{
$expire = time() - 86500;
}
else
{
$expire = ($expire > 0) ? time() + $expire : 0;
}
setcookie($prefix.$name, $value, $expire, $path, $domain, $secure, $httponly);
}
// --------------------------------------------------------------------
/**
* Fetch the IP Address
*
* Determines and validates the visitor's IP address.
*
* @return string IP address
*/
public function ip_address()
{
if ($this->ip_address !== FALSE)
{
return $this->ip_address;
}
$proxy_ips = config_item('proxy_ips');
if ( ! empty($proxy_ips) && ! is_array($proxy_ips))
{
$proxy_ips = explode(',', str_replace(' ', '', $proxy_ips));
}
$this->ip_address = $this->server('REMOTE_ADDR');
if ($proxy_ips)
{
foreach (array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_X_CLIENT_IP', 'HTTP_X_CLUSTER_CLIENT_IP') as $header)
{
if (($spoof = $this->server($header)) !== NULL)
{
// Some proxies typically list the whole chain of IP
// addresses through which the client has reached us.
// e.g. client_ip, proxy_ip1, proxy_ip2, etc.
sscanf($spoof, '%[^,]', $spoof);
if ( ! $this->valid_ip($spoof))
{
$spoof = NULL;
}
else
{
break;
}
}
}
if ($spoof)
{
for ($i = 0, $c = count($proxy_ips); $i < $c; $i++)
{
// Check if we have an IP address or a subnet
if (strpos($proxy_ips[$i], '/') === FALSE)
{
// An IP address (and not a subnet) is specified.
// We can compare right away.
if ($proxy_ips[$i] === $this->ip_address)
{
$this->ip_address = $spoof;
break;
}
continue;
}
// We have a subnet ... now the heavy lifting begins
isset($separator) OR $separator = $this->valid_ip($this->ip_address, 'ipv6') ? ':' : '.';
// If the proxy entry doesn't match the IP protocol - skip it
if (strpos($proxy_ips[$i], $separator) === FALSE)
{
continue;
}
// Convert the REMOTE_ADDR IP address to binary, if needed
if ( ! isset($ip, $sprintf))
{
if ($separator === ':')
{
// Make sure we're have the "full" IPv6 format
$ip = explode(':',
str_replace('::',
str_repeat(':', 9 - substr_count($this->ip_address, ':')),
$this->ip_address
)
);
for ($j = 0; $j < 8; $j++)
{
$ip[$j] = intval($ip[$j], 16);
}
$sprintf = '%016b%016b%016b%016b%016b%016b%016b%016b';
}
else
{
$ip = explode('.', $this->ip_address);
$sprintf = '%08b%08b%08b%08b';
}
$ip = vsprintf($sprintf, $ip);
}
// Split the netmask length off the network address
sscanf($proxy_ips[$i], '%[^/]/%d', $netaddr, $masklen);
// Again, an IPv6 address is most likely in a compressed form
if ($separator === ':')
{
$netaddr = explode(':', str_replace('::', str_repeat(':', 9 - substr_count($netaddr, ':')), $netaddr));
for ($j = 0; $j < 8; $j++)
{
$netaddr[$j] = intval($netaddr[$j], 16);
}
}
else
{
$netaddr = explode('.', $netaddr);
}
// Convert to binary and finally compare
if (strncmp($ip, vsprintf($sprintf, $netaddr), $masklen) === 0)
{
$this->ip_address = $spoof;
break;
}
}
}
}
if ( ! $this->valid_ip($this->ip_address))
{
return $this->ip_address = '0.0.0.0';
}
return $this->ip_address;
}
// --------------------------------------------------------------------
/**
* Validate IP Address
*
* @param string $ip IP address
* @param string $which IP protocol: 'ipv4' or 'ipv6'
* @return bool
*/
public function valid_ip($ip, $which = '')
{
switch (strtolower($which))
{
case 'ipv4':
$which = FILTER_FLAG_IPV4;
break;
case 'ipv6':
$which = FILTER_FLAG_IPV6;
break;
default:
$which = NULL;
break;
}
return (bool) filter_var($ip, FILTER_VALIDATE_IP, $which);
}
// --------------------------------------------------------------------
/**
* Fetch User Agent string
*
* @return string|null User Agent string or NULL if it doesn't exist
*/
public function user_agent($xss_clean = NULL)
{
return $this->_fetch_from_array($_SERVER, 'HTTP_USER_AGENT', $xss_clean);
}
// --------------------------------------------------------------------
/**
* Sanitize Globals
*
* Internal method serving for the following purposes:
*
* - Unsets $_GET data, if query strings are not enabled
* - Cleans POST, COOKIE and SERVER data
* - Standardizes newline characters to PHP_EOL
*
* @return void
*/
protected function _sanitize_globals()
{
// Is $_GET data allowed? If not we'll set the $_GET to an empty array
if ($this->_allow_get_array === FALSE)
{
$_GET = array();
}
elseif (is_array($_GET))
{
foreach ($_GET as $key => $val)
{
$_GET[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
}
}
// Clean $_POST Data
if (is_array($_POST))
{
foreach ($_POST as $key => $val)
{
$_POST[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
}
}
// Clean $_COOKIE Data
if (is_array($_COOKIE))
{
// 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'],
$_COOKIE['$Path'],
$_COOKIE['$Domain']
);
foreach ($_COOKIE as $key => $val)
{
if (($cookie_key = $this->_clean_input_keys($key)) !== FALSE)
{
$_COOKIE[$cookie_key] = $this->_clean_input_data($val);
}
else
{
unset($_COOKIE[$key]);
}
}
}
// Sanitize PHP_SELF
$_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']);
log_message('debug', 'Global POST, GET and COOKIE data sanitized');
}
// --------------------------------------------------------------------
/**
* Clean Input Data
*
* Internal method that aids in escaping data and
* standardizing newline characters to PHP_EOL.
*
* @param string|string[] $str Input string(s)
* @return string
*/
protected function _clean_input_data($str)
{
if (is_array($str))
{
$new_array = array();
foreach (array_keys($str) as $key)
{
$new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($str[$key]);
}
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, FALSE);
// Standardize newlines if needed
if ($this->_standardize_newlines === TRUE)
{
return preg_replace('/(?:\r\n|[\r\n])/', PHP_EOL, $str);
}
return $str;
}
// --------------------------------------------------------------------
/**
* Clean Keys
*
* Internal method that helps to prevent malicious users
* from trying to exploit keys we make sure that keys are
* only named with alpha-numeric text and a few other items.
*
* @param string $str Input string
* @param bool $fatal Whether to terminate script exection
* or to return FALSE if an invalid
* key is encountered
* @return string|bool
*/
protected function _clean_input_keys($str, $fatal = TRUE)
{
if ( ! preg_match('/^[a-z0-9:_\/|-]+$/i', $str))
{
if ($fatal === TRUE)
{
return FALSE;
}
else
{
set_status_header(503);
echo 'Disallowed Key Characters.';
exit(7); // EXIT_USER_INPUT
}
}
// Clean UTF-8 if supported
if (UTF8_ENABLED === TRUE)
{
return $this->uni->clean_string($str);
}
return $str;
}
// --------------------------------------------------------------------
/**
* Request Headers
*
* @param bool $xss_clean Whether to apply XSS filtering
* @return array
*/
public function request_headers($xss_clean = FALSE)
{
// If header is already defined, return it immediately
if ( ! empty($this->headers))
{
return $this->_fetch_from_array($this->headers, NULL, $xss_clean);
}
// In Apache, you can simply call apache_request_headers()
if (function_exists('apache_request_headers'))
{
$this->headers = apache_request_headers();
}
else
{
isset($_SERVER['CONTENT_TYPE']) && $this->headers['Content-Type'] = $_SERVER['CONTENT_TYPE'];
foreach ($_SERVER as $key => $val)
{
if (sscanf($key, 'HTTP_%s', $header) === 1)
{
// take SOME_HEADER and turn it into Some-Header
$header = str_replace('_', ' ', strtolower($header));
$header = str_replace(' ', '-', ucwords($header));
$this->headers[$header] = $_SERVER[$key];
}
}
}
return $this->_fetch_from_array($this->headers, NULL, $xss_clean);
}
// --------------------------------------------------------------------
/**
* Get Request Header
*
* Returns the value of a single member of the headers class member
*
* @param string $index Header name
* @param bool $xss_clean Whether to apply XSS filtering
* @return string|null The requested header on success or NULL on failure
*/
public function get_request_header($index, $xss_clean = FALSE)
{
static $headers;
if ( ! isset($headers))
{
empty($this->headers) && $this->request_headers();
foreach ($this->headers as $key => $value)
{
$headers[strtolower($key)] = $value;
}
}
$index = strtolower($index);
if ( ! isset($headers[$index]))
{
return NULL;
}
return ($xss_clean === TRUE)
? $this->security->xss_clean($headers[$index])
: $headers[$index];
}
// --------------------------------------------------------------------
/**
* Is AJAX request?
*
* Test to see if a request contains the HTTP_X_REQUESTED_WITH header.
*
* @return bool
*/
public function is_ajax_request()
{
return ( ! empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
}
// --------------------------------------------------------------------
/**
* Is CLI request?
*
* Test to see if a request was made from the command line.
*
* @deprecated 3.0.0 Use is_cli() instead
* @return bool
*/
public function is_cli_request()
{
return is_cli();
}
// --------------------------------------------------------------------
/**
* Get Request Method
*
* Return the request method
*
* @param bool $upper Whether to return in upper or lower case
* (default: FALSE)
* @return string
*/
public function method($upper = FALSE)
{
return ($upper)
? strtoupper($this->server('REQUEST_METHOD'))
: strtolower($this->server('REQUEST_METHOD'));
}
// ------------------------------------------------------------------------
/**
* Magic __get()
*
* Allows read access to protected properties
*
* @param string $name
* @return mixed
*/
public function __get($name)
{
if ($name === 'raw_input_stream')
{
isset($this->_raw_input_stream) OR $this->_raw_input_stream = file_get_contents('php://input');
return $this->_raw_input_stream;
}
elseif ($name === 'ip_address')
{
return $this->ip_address;
}
}
}

203
php/system/core/Lang.php Normal file
View File

@ -0,0 +1,203 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2018, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Language Class
*
* @package CodeIgniter
* @subpackage Libraries
* @category Language
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/libraries/language.html
*/
class CI_Lang {
/**
* List of translations
*
* @var array
*/
public $language = array();
/**
* List of loaded language files
*
* @var array
*/
public $is_loaded = array();
/**
* Class constructor
*
* @return void
*/
public function __construct()
{
log_message('info', 'Language Class Initialized');
}
// --------------------------------------------------------------------
/**
* Load a language file
*
* @param mixed $langfile Language file name
* @param string $idiom Language name (english, etc.)
* @param bool $return Whether to return the loaded array of translations
* @param bool $add_suffix Whether to add suffix to $langfile
* @param string $alt_path Alternative path to look for the language file
*
* @return void|string[] Array containing translations, if $return is set to TRUE
*/
public function load($langfile, $idiom = '', $return = FALSE, $add_suffix = TRUE, $alt_path = '')
{
if (is_array($langfile))
{
foreach ($langfile as $value)
{
$this->load($value, $idiom, $return, $add_suffix, $alt_path);
}
return;
}
$langfile = str_replace('.php', '', $langfile);
if ($add_suffix === TRUE)
{
$langfile = preg_replace('/_lang$/', '', $langfile).'_lang';
}
$langfile .= '.php';
if (empty($idiom) OR ! preg_match('/^[a-z_-]+$/i', $idiom))
{
$config =& get_config();
$idiom = empty($config['language']) ? 'english' : $config['language'];
}
if ($return === FALSE && isset($this->is_loaded[$langfile]) && $this->is_loaded[$langfile] === $idiom)
{
return;
}
// Load the base file, so any others found can override it
$basepath = BASEPATH.'language/'.$idiom.'/'.$langfile;
if (($found = file_exists($basepath)) === TRUE)
{
include($basepath);
}
// Do we have an alternative path to look in?
if ($alt_path !== '')
{
$alt_path .= 'language/'.$idiom.'/'.$langfile;
if (file_exists($alt_path))
{
include($alt_path);
$found = TRUE;
}
}
else
{
foreach (get_instance()->load->get_package_paths(TRUE) as $package_path)
{
$package_path .= 'language/'.$idiom.'/'.$langfile;
if ($basepath !== $package_path && file_exists($package_path))
{
include($package_path);
$found = TRUE;
break;
}
}
}
if ($found !== TRUE)
{
show_error('Unable to load the requested language file: language/'.$idiom.'/'.$langfile);
}
if ( ! isset($lang) OR ! is_array($lang))
{
log_message('error', 'Language file contains no data: language/'.$idiom.'/'.$langfile);
if ($return === TRUE)
{
return array();
}
return;
}
if ($return === TRUE)
{
return $lang;
}
$this->is_loaded[$langfile] = $idiom;
$this->language = array_merge($this->language, $lang);
log_message('info', 'Language file loaded: language/'.$idiom.'/'.$langfile);
return TRUE;
}
// --------------------------------------------------------------------
/**
* Language line
*
* Fetches a single line of text from the language array
*
* @param string $line Language line key
* @param bool $log_errors Whether to log an error message if the line is not found
* @return string Translation
*/
public function line($line, $log_errors = TRUE)
{
$value = isset($this->language[$line]) ? $this->language[$line] : FALSE;
// Because killer robots like unicorns!
if ($value === FALSE && $log_errors === TRUE)
{
log_message('error', 'Could not find the language line "'.$line.'"');
}
return $value;
}
}

1415
php/system/core/Loader.php Normal file

File diff suppressed because it is too large Load Diff

296
php/system/core/Log.php Normal file
View File

@ -0,0 +1,296 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2018, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Logging Class
*
* @package CodeIgniter
* @subpackage Libraries
* @category Logging
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/general/errors.html
*/
class CI_Log {
/**
* Path to save log files
*
* @var string
*/
protected $_log_path;
/**
* File permissions
*
* @var int
*/
protected $_file_permissions = 0644;
/**
* Level of logging
*
* @var int
*/
protected $_threshold = 1;
/**
* Array of threshold levels to log
*
* @var array
*/
protected $_threshold_array = array();
/**
* Format of timestamp for log files
*
* @var string
*/
protected $_date_fmt = 'Y-m-d H:i:s';
/**
* Filename extension
*
* @var string
*/
protected $_file_ext;
/**
* Whether or not the logger can write to the log files
*
* @var bool
*/
protected $_enabled = TRUE;
/**
* Predefined logging levels
*
* @var array
*/
protected $_levels = array('ERROR' => 1, 'DEBUG' => 2, 'INFO' => 3, 'ALL' => 4);
/**
* mbstring.func_overload flag
*
* @var bool
*/
protected static $func_overload;
// --------------------------------------------------------------------
/**
* Class constructor
*
* @return void
*/
public function __construct()
{
$config =& get_config();
isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload'));
$this->_log_path = ($config['log_path'] !== '') ? $config['log_path'] : APPPATH.'logs/';
$this->_file_ext = (isset($config['log_file_extension']) && $config['log_file_extension'] !== '')
? ltrim($config['log_file_extension'], '.') : 'php';
file_exists($this->_log_path) OR mkdir($this->_log_path, 0755, TRUE);
if ( ! is_dir($this->_log_path) OR ! is_really_writable($this->_log_path))
{
$this->_enabled = FALSE;
}
if (is_numeric($config['log_threshold']))
{
$this->_threshold = (int) $config['log_threshold'];
}
elseif (is_array($config['log_threshold']))
{
$this->_threshold = 0;
$this->_threshold_array = array_flip($config['log_threshold']);
}
if ( ! empty($config['log_date_format']))
{
$this->_date_fmt = $config['log_date_format'];
}
if ( ! empty($config['log_file_permissions']) && is_int($config['log_file_permissions']))
{
$this->_file_permissions = $config['log_file_permissions'];
}
}
// --------------------------------------------------------------------
/**
* Write Log File
*
* Generally this function will be called using the global log_message() function
*
* @param string $level The error level: 'error', 'debug' or 'info'
* @param string $msg The error message
* @return bool
*/
public function write_log($level, $msg)
{
if ($this->_enabled === FALSE)
{
return FALSE;
}
$level = strtoupper($level);
if (( ! isset($this->_levels[$level]) OR ($this->_levels[$level] > $this->_threshold))
&& ! isset($this->_threshold_array[$this->_levels[$level]]))
{
return FALSE;
}
$filepath = $this->_log_path.'log-'.date('Y-m-d').'.'.$this->_file_ext;
$message = '';
if ( ! file_exists($filepath))
{
$newfile = TRUE;
// Only add protection to php files
if ($this->_file_ext === 'php')
{
$message .= "<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?>\n\n";
}
}
if ( ! $fp = @fopen($filepath, 'ab'))
{
return FALSE;
}
flock($fp, LOCK_EX);
// Instantiating DateTime with microseconds appended to initial date is needed for proper support of this format
if (strpos($this->_date_fmt, 'u') !== FALSE)
{
$microtime_full = microtime(TRUE);
$microtime_short = sprintf("%06d", ($microtime_full - floor($microtime_full)) * 1000000);
$date = new DateTime(date('Y-m-d H:i:s.'.$microtime_short, $microtime_full));
$date = $date->format($this->_date_fmt);
}
else
{
$date = date($this->_date_fmt);
}
$message .= $this->_format_line($level, $date, $msg);
for ($written = 0, $length = self::strlen($message); $written < $length; $written += $result)
{
if (($result = fwrite($fp, self::substr($message, $written))) === FALSE)
{
break;
}
}
flock($fp, LOCK_UN);
fclose($fp);
if (isset($newfile) && $newfile === TRUE)
{
chmod($filepath, $this->_file_permissions);
}
return is_int($result);
}
// --------------------------------------------------------------------
/**
* Format the log line.
*
* This is for extensibility of log formatting
* If you want to change the log format, extend the CI_Log class and override this method
*
* @param string $level The error level
* @param string $date Formatted date string
* @param string $message The log message
* @return string Formatted log line with a new line character '\n' at the end
*/
protected function _format_line($level, $date, $message)
{
return $level.' - '.$date.' --> '.$message."\n";
}
// --------------------------------------------------------------------
/**
* Byte-safe strlen()
*
* @param string $str
* @return int
*/
protected static function strlen($str)
{
return (self::$func_overload)
? mb_strlen($str, '8bit')
: strlen($str);
}
// --------------------------------------------------------------------
/**
* Byte-safe substr()
*
* @param string $str
* @param int $start
* @param int $length
* @return string
*/
protected static function substr($str, $start, $length = NULL)
{
if (self::$func_overload)
{
// mb_substr($str, $start, null, '8bit') returns an empty
// string on PHP 5.3
isset($length) OR $length = ($start >= 0 ? self::strlen($str) - $start : -$start);
return mb_substr($str, $start, $length, '8bit');
}
return isset($length)
? substr($str, $start, $length)
: substr($str, $start);
}
}

76
php/system/core/Model.php Normal file
View File

@ -0,0 +1,76 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2018, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Model Class
*
* @package CodeIgniter
* @subpackage Libraries
* @category Libraries
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/libraries/config.html
*/
class CI_Model {
/**
* Class constructor
*
* @link https://github.com/bcit-ci/CodeIgniter/issues/5332
* @return void
*/
public function __construct() {}
/**
* __get magic
*
* Allows models to access CI's loaded classes using the same
* syntax as controllers.
*
* @param string $key
*/
public function __get($key)
{
// Debugging note:
// If you're here because you're getting an error message
// saying 'Undefined Property: system/core/Model.php', it's
// most likely a typo in your model code.
return get_instance()->$key;
}
}

842
php/system/core/Output.php Normal file
View File

@ -0,0 +1,842 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2018, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Output Class
*
* Responsible for sending final output to the browser.
*
* @package CodeIgniter
* @subpackage Libraries
* @category Output
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/libraries/output.html
*/
class CI_Output {
/**
* Final output string
*
* @var string
*/
public $final_output;
/**
* Cache expiration time
*
* @var int
*/
public $cache_expiration = 0;
/**
* List of server headers
*
* @var array
*/
public $headers = array();
/**
* List of mime types
*
* @var array
*/
public $mimes = array();
/**
* Mime-type for the current page
*
* @var string
*/
protected $mime_type = 'text/html';
/**
* Enable Profiler flag
*
* @var bool
*/
public $enable_profiler = FALSE;
/**
* php.ini zlib.output_compression flag
*
* @var bool
*/
protected $_zlib_oc = FALSE;
/**
* CI output compression flag
*
* @var bool
*/
protected $_compress_output = FALSE;
/**
* List of profiler sections
*
* @var array
*/
protected $_profiler_sections = array();
/**
* Parse markers flag
*
* Whether or not to parse variables like {elapsed_time} and {memory_usage}.
*
* @var bool
*/
public $parse_exec_vars = TRUE;
/**
* mbstring.func_overload flag
*
* @var bool
*/
protected static $func_overload;
/**
* Class constructor
*
* Determines whether zLib output compression will be used.
*
* @return void
*/
public function __construct()
{
$this->_zlib_oc = (bool) ini_get('zlib.output_compression');
$this->_compress_output = (
$this->_zlib_oc === FALSE
&& config_item('compress_output') === TRUE
&& extension_loaded('zlib')
);
isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload'));
// Get mime types for later
$this->mimes =& get_mimes();
log_message('info', 'Output Class Initialized');
}
// --------------------------------------------------------------------
/**
* Get Output
*
* Returns the current output string.
*
* @return string
*/
public function get_output()
{
return $this->final_output;
}
// --------------------------------------------------------------------
/**
* Set Output
*
* Sets the output string.
*
* @param string $output Output data
* @return CI_Output
*/
public function set_output($output)
{
$this->final_output = $output;
return $this;
}
// --------------------------------------------------------------------
/**
* Append Output
*
* Appends data onto the output string.
*
* @param string $output Data to append
* @return CI_Output
*/
public function append_output($output)
{
$this->final_output .= $output;
return $this;
}
// --------------------------------------------------------------------
/**
* Set Header
*
* Lets you set a server header which will be sent with the final output.
*
* Note: If a file is cached, headers will not be sent.
* @todo We need to figure out how to permit headers to be cached.
*
* @param string $header Header
* @param bool $replace Whether to replace the old header value, if already set
* @return CI_Output
*/
public 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;
}
$this->headers[] = array($header, $replace);
return $this;
}
// --------------------------------------------------------------------
/**
* Set Content-Type Header
*
* @param string $mime_type Extension of the file we're outputting
* @param string $charset Character set (default: NULL)
* @return CI_Output
*/
public function set_content_type($mime_type, $charset = NULL)
{
if (strpos($mime_type, '/') === FALSE)
{
$extension = ltrim($mime_type, '.');
// Is this extension supported?
if (isset($this->mimes[$extension]))
{
$mime_type =& $this->mimes[$extension];
if (is_array($mime_type))
{
$mime_type = current($mime_type);
}
}
}
$this->mime_type = $mime_type;
if (empty($charset))
{
$charset = config_item('charset');
}
$header = 'Content-Type: '.$mime_type
.(empty($charset) ? '' : '; charset='.$charset);
$this->headers[] = array($header, TRUE);
return $this;
}
// --------------------------------------------------------------------
/**
* Get Current Content-Type Header
*
* @return string 'text/html', if not already set
*/
public function get_content_type()
{
for ($i = 0, $c = count($this->headers); $i < $c; $i++)
{
if (sscanf($this->headers[$i][0], 'Content-Type: %[^;]', $content_type) === 1)
{
return $content_type;
}
}
return 'text/html';
}
// --------------------------------------------------------------------
/**
* Get Header
*
* @param string $header
* @return string
*/
public function get_header($header)
{
// Combine headers already sent with our batched headers
$headers = array_merge(
// We only need [x][0] from our multi-dimensional array
array_map('array_shift', $this->headers),
headers_list()
);
if (empty($headers) OR empty($header))
{
return NULL;
}
// Count backwards, in order to get the last matching header
for ($c = count($headers) - 1; $c > -1; $c--)
{
if (strncasecmp($header, $headers[$c], $l = self::strlen($header)) === 0)
{
return trim(self::substr($headers[$c], $l+1));
}
}
return NULL;
}
// --------------------------------------------------------------------
/**
* Set HTTP Status Header
*
* As of version 1.7.2, this is an alias for common function
* set_status_header().
*
* @param int $code Status code (default: 200)
* @param string $text Optional message
* @return CI_Output
*/
public function set_status_header($code = 200, $text = '')
{
set_status_header($code, $text);
return $this;
}
// --------------------------------------------------------------------
/**
* Enable/disable Profiler
*
* @param bool $val TRUE to enable or FALSE to disable
* @return CI_Output
*/
public 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.
*
* @param array $sections Profiler sections
* @return CI_Output
*/
public function set_profiler_sections($sections)
{
if (isset($sections['query_toggle_count']))
{
$this->_profiler_sections['query_toggle_count'] = (int) $sections['query_toggle_count'];
unset($sections['query_toggle_count']);
}
foreach ($sections as $section => $enable)
{
$this->_profiler_sections[$section] = ($enable !== FALSE);
}
return $this;
}
// --------------------------------------------------------------------
/**
* Set Cache
*
* @param int $time Cache expiration time in minutes
* @return CI_Output
*/
public function cache($time)
{
$this->cache_expiration = is_numeric($time) ? $time : 0;
return $this;
}
// --------------------------------------------------------------------
/**
* Display Output
*
* Processes and sends finalized output data to the browser along
* with any server headers and profile data. It also stops benchmark
* timers so the page rendering speed and memory usage can be shown.
*
* Note: All "view" data is automatically put into $this->final_output
* by controller class.
*
* @uses CI_Output::$final_output
* @param string $output Output data override
* @return void
*/
public function _display($output = '')
{
// Note: We use load_class() 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.
$BM =& load_class('Benchmark', 'core');
$CFG =& load_class('Config', 'core');
// Grab the super object if we can.
if (class_exists('CI_Controller', FALSE))
{
$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 = round(memory_get_usage() / 1024 / 1024, 2).'MB';
$output = str_replace(array('{elapsed_time}', '{memory_usage}'), array($elapsed, $memory), $output);
}
// --------------------------------------------------------------------
// Is compression requested?
if (isset($CI) // This means that we're not serving a cache file, if we were, it would already be compressed
&& $this->_compress_output === TRUE
&& isset($_SERVER['HTTP_ACCEPT_ENCODING']) && 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))
{
if ($this->_compress_output === TRUE)
{
if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
{
header('Content-Encoding: gzip');
header('Content-Length: '.self::strlen($output));
}
else
{
// User agent doesn't support gzip compression,
// so we'll have to decompress our cache
$output = gzinflate(self::substr($output, 10, -8));
}
}
echo $output;
log_message('info', 'Final output sent to browser');
log_message('debug', 'Total execution time: '.$elapsed);
return;
}
// --------------------------------------------------------------------
// 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
$output = preg_replace('|</body>.*?</html>|is', '', $output, -1, $count).$CI->profiler->run();
if ($count > 0)
{
$output .= '</body></html>';
}
}
// 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('info', 'Final output sent to browser');
log_message('debug', 'Total execution time: '.$elapsed);
}
// --------------------------------------------------------------------
/**
* Write Cache
*
* @param string $output Output data to cache
* @return void
*/
public 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();
if (($cache_query_string = $CI->config->item('cache_query_string')) && ! empty($_SERVER['QUERY_STRING']))
{
if (is_array($cache_query_string))
{
$uri .= '?'.http_build_query(array_intersect_key($_GET, array_flip($cache_query_string)));
}
else
{
$uri .= '?'.$_SERVER['QUERY_STRING'];
}
}
$cache_path .= md5($uri);
if ( ! $fp = @fopen($cache_path, 'w+b'))
{
log_message('error', 'Unable to write cache file: '.$cache_path);
return;
}
if ( ! flock($fp, LOCK_EX))
{
log_message('error', 'Unable to secure a file lock for file at: '.$cache_path);
fclose($fp);
return;
}
// If output compression is enabled, compress the cache
// itself, so that we don't have to do that each time
// we're serving it
if ($this->_compress_output === TRUE)
{
$output = gzencode($output);
if ($this->get_header('content-type') === NULL)
{
$this->set_content_type($this->mime_type);
}
}
$expire = time() + ($this->cache_expiration * 60);
// Put together our serialized info.
$cache_info = serialize(array(
'expire' => $expire,
'headers' => $this->headers
));
$output = $cache_info.'ENDCI--->'.$output;
for ($written = 0, $length = self::strlen($output); $written < $length; $written += $result)
{
if (($result = fwrite($fp, self::substr($output, $written))) === FALSE)
{
break;
}
}
flock($fp, LOCK_UN);
fclose($fp);
if ( ! is_int($result))
{
@unlink($cache_path);
log_message('error', 'Unable to write the complete cache content at: '.$cache_path);
return;
}
chmod($cache_path, 0640);
log_message('debug', 'Cache file written: '.$cache_path);
// Send HTTP cache-control headers to browser to match file cache settings.
$this->set_cache_header($_SERVER['REQUEST_TIME'], $expire);
}
// --------------------------------------------------------------------
/**
* Update/serve cached output
*
* @uses CI_Config
* @uses CI_URI
*
* @param object &$CFG CI_Config class instance
* @param object &$URI CI_URI class instance
* @return bool TRUE on success or FALSE on failure
*/
public function _display_cache(&$CFG, &$URI)
{
$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;
if (($cache_query_string = $CFG->item('cache_query_string')) && ! empty($_SERVER['QUERY_STRING']))
{
if (is_array($cache_query_string))
{
$uri .= '?'.http_build_query(array_intersect_key($_GET, array_flip($cache_query_string)));
}
else
{
$uri .= '?'.$_SERVER['QUERY_STRING'];
}
}
$filepath = $cache_path.md5($uri);
if ( ! file_exists($filepath) OR ! $fp = @fopen($filepath, 'rb'))
{
return FALSE;
}
flock($fp, LOCK_SH);
$cache = (filesize($filepath) > 0) ? fread($fp, filesize($filepath)) : '';
flock($fp, LOCK_UN);
fclose($fp);
// Look for embedded serialized file info.
if ( ! preg_match('/^(.*)ENDCI--->/', $cache, $match))
{
return FALSE;
}
$cache_info = unserialize($match[1]);
$expire = $cache_info['expire'];
$last_modified = filemtime($filepath);
// Has the file expired?
if ($_SERVER['REQUEST_TIME'] >= $expire && is_really_writable($cache_path))
{
// If so we'll delete it.
@unlink($filepath);
log_message('debug', 'Cache file has expired. File deleted.');
return FALSE;
}
// Send the HTTP cache control headers
$this->set_cache_header($last_modified, $expire);
// Add headers from cache file.
foreach ($cache_info['headers'] as $header)
{
$this->set_header($header[0], $header[1]);
}
// Display the cache
$this->_display(self::substr($cache, self::strlen($match[0])));
log_message('debug', 'Cache file is current. Sending it to browser.');
return TRUE;
}
// --------------------------------------------------------------------
/**
* Delete cache
*
* @param string $uri URI string
* @return bool
*/
public function delete_cache($uri = '')
{
$CI =& get_instance();
$cache_path = $CI->config->item('cache_path');
if ($cache_path === '')
{
$cache_path = APPPATH.'cache/';
}
if ( ! is_dir($cache_path))
{
log_message('error', 'Unable to find cache path: '.$cache_path);
return FALSE;
}
if (empty($uri))
{
$uri = $CI->uri->uri_string();
if (($cache_query_string = $CI->config->item('cache_query_string')) && ! empty($_SERVER['QUERY_STRING']))
{
if (is_array($cache_query_string))
{
$uri .= '?'.http_build_query(array_intersect_key($_GET, array_flip($cache_query_string)));
}
else
{
$uri .= '?'.$_SERVER['QUERY_STRING'];
}
}
}
$cache_path .= md5($CI->config->item('base_url').$CI->config->item('index_page').ltrim($uri, '/'));
if ( ! @unlink($cache_path))
{
log_message('error', 'Unable to delete cache file for '.$uri);
return FALSE;
}
return TRUE;
}
// --------------------------------------------------------------------
/**
* Set Cache Header
*
* Set the HTTP headers to match the server-side file cache settings
* in order to reduce bandwidth.
*
* @param int $last_modified Timestamp of when the page was last modified
* @param int $expiration Timestamp of when should the requested page expire from cache
* @return void
*/
public function set_cache_header($last_modified, $expiration)
{
$max_age = $expiration - $_SERVER['REQUEST_TIME'];
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $last_modified <= strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']))
{
$this->set_status_header(304);
exit;
}
header('Pragma: public');
header('Cache-Control: max-age='.$max_age.', public');
header('Expires: '.gmdate('D, d M Y H:i:s', $expiration).' GMT');
header('Last-modified: '.gmdate('D, d M Y H:i:s', $last_modified).' GMT');
}
// --------------------------------------------------------------------
/**
* Byte-safe strlen()
*
* @param string $str
* @return int
*/
protected static function strlen($str)
{
return (self::$func_overload)
? mb_strlen($str, '8bit')
: strlen($str);
}
// --------------------------------------------------------------------
/**
* Byte-safe substr()
*
* @param string $str
* @param int $start
* @param int $length
* @return string
*/
protected static function substr($str, $start, $length = NULL)
{
if (self::$func_overload)
{
// mb_substr($str, $start, null, '8bit') returns an empty
// string on PHP 5.3
isset($length) OR $length = ($start >= 0 ? self::strlen($str) - $start : -$start);
return mb_substr($str, $start, $length, '8bit');
}
return isset($length)
? substr($str, $start, $length)
: substr($str, $start);
}
}

515
php/system/core/Router.php Normal file
View File

@ -0,0 +1,515 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2018, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Router Class
*
* Parses URIs and determines routing
*
* @package CodeIgniter
* @subpackage Libraries
* @category Libraries
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/general/routing.html
*/
class CI_Router {
/**
* CI_Config class object
*
* @var object
*/
public $config;
/**
* List of routes
*
* @var array
*/
public $routes = array();
/**
* Current class name
*
* @var string
*/
public $class = '';
/**
* Current method name
*
* @var string
*/
public $method = 'index';
/**
* Sub-directory that contains the requested controller class
*
* @var string
*/
public $directory;
/**
* Default controller (and method if specific)
*
* @var string
*/
public $default_controller;
/**
* Translate URI dashes
*
* Determines whether dashes in controller & method segments
* should be automatically replaced by underscores.
*
* @var bool
*/
public $translate_uri_dashes = FALSE;
/**
* Enable query strings flag
*
* Determines whether to use GET parameters or segment URIs
*
* @var bool
*/
public $enable_query_strings = FALSE;
// --------------------------------------------------------------------
/**
* Class constructor
*
* Runs the route mapping function.
*
* @param array $routing
* @return void
*/
public function __construct($routing = NULL)
{
$this->config =& load_class('Config', 'core');
$this->uri =& load_class('URI', 'core');
$this->enable_query_strings = ( ! is_cli() && $this->config->item('enable_query_strings') === TRUE);
// If a directory override is configured, it has to be set before any dynamic routing logic
is_array($routing) && isset($routing['directory']) && $this->set_directory($routing['directory']);
$this->_set_routing();
// Set any routing overrides that may exist in the main index file
if (is_array($routing))
{
empty($routing['controller']) OR $this->set_class($routing['controller']);
empty($routing['function']) OR $this->set_method($routing['function']);
}
log_message('info', 'Router Class Initialized');
}
// --------------------------------------------------------------------
/**
* Set route mapping
*
* Determines what should be served based on the URI request,
* as well as any "routes" that have been set in the routing config file.
*
* @return void
*/
protected function _set_routing()
{
// Load the routes.php file. It would be great if we could
// skip this for enable_query_strings = TRUE, but then
// default_controller would be empty ...
if (file_exists(APPPATH.'config/routes.php'))
{
include(APPPATH.'config/routes.php');
}
if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/routes.php'))
{
include(APPPATH.'config/'.ENVIRONMENT.'/routes.php');
}
// Validate & get reserved routes
if (isset($route) && is_array($route))
{
isset($route['default_controller']) && $this->default_controller = $route['default_controller'];
isset($route['translate_uri_dashes']) && $this->translate_uri_dashes = $route['translate_uri_dashes'];
unset($route['default_controller'], $route['translate_uri_dashes']);
$this->routes = $route;
}
// 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
if ($this->enable_query_strings)
{
// If the directory is set at this time, it means an override exists, so skip the checks
if ( ! isset($this->directory))
{
$_d = $this->config->item('directory_trigger');
$_d = isset($_GET[$_d]) ? trim($_GET[$_d], " \t\n\r\0\x0B/") : '';
if ($_d !== '')
{
$this->uri->filter_uri($_d);
$this->set_directory($_d);
}
}
$_c = trim($this->config->item('controller_trigger'));
if ( ! empty($_GET[$_c]))
{
$this->uri->filter_uri($_GET[$_c]);
$this->set_class($_GET[$_c]);
$_f = trim($this->config->item('function_trigger'));
if ( ! empty($_GET[$_f]))
{
$this->uri->filter_uri($_GET[$_f]);
$this->set_method($_GET[$_f]);
}
$this->uri->rsegments = array(
1 => $this->class,
2 => $this->method
);
}
else
{
$this->_set_default_controller();
}
// Routing rules don't apply to query strings and we don't need to detect
// directories, so we're done here
return;
}
// Is there anything to parse?
if ($this->uri->uri_string !== '')
{
$this->_parse_routes();
}
else
{
$this->_set_default_controller();
}
}
// --------------------------------------------------------------------
/**
* Set request route
*
* Takes an array of URI segments as input and sets the class/method
* to be called.
*
* @used-by CI_Router::_parse_routes()
* @param array $segments URI segments
* @return void
*/
protected function _set_request($segments = array())
{
$segments = $this->_validate_request($segments);
// If we don't have any segments left - try the default controller;
// WARNING: Directories get shifted out of the segments array!
if (empty($segments))
{
$this->_set_default_controller();
return;
}
if ($this->translate_uri_dashes === TRUE)
{
$segments[0] = str_replace('-', '_', $segments[0]);
if (isset($segments[1]))
{
$segments[1] = str_replace('-', '_', $segments[1]);
}
}
$this->set_class($segments[0]);
if (isset($segments[1]))
{
$this->set_method($segments[1]);
}
else
{
$segments[1] = 'index';
}
array_unshift($segments, NULL);
unset($segments[0]);
$this->uri->rsegments = $segments;
}
// --------------------------------------------------------------------
/**
* Set default controller
*
* @return void
*/
protected function _set_default_controller()
{
if (empty($this->default_controller))
{
show_error('Unable to determine what should be displayed. A default route has not been specified in the routing file.');
}
// Is the method being specified?
if (sscanf($this->default_controller, '%[^/]/%s', $class, $method) !== 2)
{
$method = 'index';
}
if ( ! file_exists(APPPATH.'controllers/'.$this->directory.ucfirst($class).'.php'))
{
// This will trigger 404 later
return;
}
$this->set_class($class);
$this->set_method($method);
// Assign routed segments, index starting from 1
$this->uri->rsegments = array(
1 => $class,
2 => $method
);
log_message('debug', 'No URI present. Default controller set.');
}
// --------------------------------------------------------------------
/**
* Validate request
*
* Attempts validate the URI request and determine the controller path.
*
* @used-by CI_Router::_set_request()
* @param array $segments URI segments
* @return mixed URI segments
*/
protected function _validate_request($segments)
{
$c = count($segments);
$directory_override = isset($this->directory);
// Loop through our segments and return as soon as a controller
// is found or when such a directory doesn't exist
while ($c-- > 0)
{
$test = $this->directory
.ucfirst($this->translate_uri_dashes === TRUE ? str_replace('-', '_', $segments[0]) : $segments[0]);
if ( ! file_exists(APPPATH.'controllers/'.$test.'.php')
&& $directory_override === FALSE
&& is_dir(APPPATH.'controllers/'.$this->directory.$segments[0])
)
{
$this->set_directory(array_shift($segments), TRUE);
continue;
}
return $segments;
}
// This means that all segments were actually directories
return $segments;
}
// --------------------------------------------------------------------
/**
* Parse Routes
*
* Matches any routes that may exist in the config/routes.php file
* against the URI to determine if the class/method need to be remapped.
*
* @return void
*/
protected function _parse_routes()
{
// Turn the segment array into a URI string
$uri = implode('/', $this->uri->segments);
// Get HTTP verb
$http_verb = isset($_SERVER['REQUEST_METHOD']) ? strtolower($_SERVER['REQUEST_METHOD']) : 'cli';
// Loop through the route array looking for wildcards
foreach ($this->routes as $key => $val)
{
// Check if route format is using HTTP verbs
if (is_array($val))
{
$val = array_change_key_case($val, CASE_LOWER);
if (isset($val[$http_verb]))
{
$val = $val[$http_verb];
}
else
{
continue;
}
}
// Convert wildcards to RegEx
$key = str_replace(array(':any', ':num'), array('[^/]+', '[0-9]+'), $key);
// Does the RegEx match?
if (preg_match('#^'.$key.'$#', $uri, $matches))
{
// Are we using callbacks to process back-references?
if ( ! is_string($val) && is_callable($val))
{
// Remove the original string from the matches array.
array_shift($matches);
// Execute the callback using the values in matches as its parameters.
$val = call_user_func_array($val, $matches);
}
// Are we using the default routing method for back-references?
elseif (strpos($val, '$') !== FALSE && strpos($key, '(') !== FALSE)
{
$val = preg_replace('#^'.$key.'$#', $val, $uri);
}
$this->_set_request(explode('/', $val));
return;
}
}
// 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(array_values($this->uri->segments));
}
// --------------------------------------------------------------------
/**
* Set class name
*
* @param string $class Class name
* @return void
*/
public function set_class($class)
{
$this->class = str_replace(array('/', '.'), '', $class);
}
// --------------------------------------------------------------------
/**
* Fetch the current class
*
* @deprecated 3.0.0 Read the 'class' property instead
* @return string
*/
public function fetch_class()
{
return $this->class;
}
// --------------------------------------------------------------------
/**
* Set method name
*
* @param string $method Method name
* @return void
*/
public function set_method($method)
{
$this->method = $method;
}
// --------------------------------------------------------------------
/**
* Fetch the current method
*
* @deprecated 3.0.0 Read the 'method' property instead
* @return string
*/
public function fetch_method()
{
return $this->method;
}
// --------------------------------------------------------------------
/**
* Set directory name
*
* @param string $dir Directory name
* @param bool $append Whether we're appending rather than setting the full value
* @return void
*/
public function set_directory($dir, $append = FALSE)
{
if ($append !== TRUE OR empty($this->directory))
{
$this->directory = str_replace('.', '', trim($dir, '/')).'/';
}
else
{
$this->directory .= str_replace('.', '', trim($dir, '/')).'/';
}
}
// --------------------------------------------------------------------
/**
* Fetch directory
*
* Feches the sub-directory (if any) that contains the requested
* controller class.
*
* @deprecated 3.0.0 Read the 'directory' property instead
* @return string
*/
public function fetch_directory()
{
return $this->directory;
}
}

1090
php/system/core/Security.php Normal file

File diff suppressed because it is too large Load Diff

643
php/system/core/URI.php Normal file
View File

@ -0,0 +1,643 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2018, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* URI Class
*
* Parses URIs and determines routing
*
* @package CodeIgniter
* @subpackage Libraries
* @category URI
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/libraries/uri.html
*/
class CI_URI {
/**
* List of cached URI segments
*
* @var array
*/
public $keyval = array();
/**
* Current URI string
*
* @var string
*/
public $uri_string = '';
/**
* List of URI segments
*
* Starts at 1 instead of 0.
*
* @var array
*/
public $segments = array();
/**
* List of routed URI segments
*
* Starts at 1 instead of 0.
*
* @var array
*/
public $rsegments = array();
/**
* Permitted URI chars
*
* PCRE character group allowed in URI segments
*
* @var string
*/
protected $_permitted_uri_chars;
/**
* Class constructor
*
* @return void
*/
public function __construct()
{
$this->config =& load_class('Config', 'core');
// If query strings are enabled, we don't need to parse any segments.
// However, they don't make sense under CLI.
if (is_cli() OR $this->config->item('enable_query_strings') !== TRUE)
{
$this->_permitted_uri_chars = $this->config->item('permitted_uri_chars');
// If it's a CLI request, ignore the configuration
if (is_cli())
{
$uri = $this->_parse_argv();
}
else
{
$protocol = $this->config->item('uri_protocol');
empty($protocol) && $protocol = 'REQUEST_URI';
switch ($protocol)
{
case 'AUTO': // For BC purposes only
case 'REQUEST_URI':
$uri = $this->_parse_request_uri();
break;
case 'QUERY_STRING':
$uri = $this->_parse_query_string();
break;
case 'PATH_INFO':
default:
$uri = isset($_SERVER[$protocol])
? $_SERVER[$protocol]
: $this->_parse_request_uri();
break;
}
}
$this->_set_uri_string($uri);
}
log_message('info', 'URI Class Initialized');
}
// --------------------------------------------------------------------
/**
* Set URI String
*
* @param string $str
* @return void
*/
protected function _set_uri_string($str)
{
// Filter out control characters and trim slashes
$this->uri_string = trim(remove_invisible_characters($str, FALSE), '/');
if ($this->uri_string !== '')
{
// Remove the URL suffix, if present
if (($suffix = (string) $this->config->item('url_suffix')) !== '')
{
$slen = strlen($suffix);
if (substr($this->uri_string, -$slen) === $suffix)
{
$this->uri_string = substr($this->uri_string, 0, -$slen);
}
}
$this->segments[0] = NULL;
// Populate the segments array
foreach (explode('/', trim($this->uri_string, '/')) as $val)
{
$val = trim($val);
// Filter segments for security
$this->filter_uri($val);
if ($val !== '')
{
$this->segments[] = $val;
}
}
unset($this->segments[0]);
}
}
// --------------------------------------------------------------------
/**
* Parse REQUEST_URI
*
* Will parse REQUEST_URI and automatically detect the URI from it,
* while fixing the query string if necessary.
*
* @return string
*/
protected function _parse_request_uri()
{
if ( ! isset($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']))
{
return '';
}
// parse_url() returns false if no host is present, but the path or query string
// contains a colon followed by a number
$uri = parse_url('http://dummy'.$_SERVER['REQUEST_URI']);
$query = isset($uri['query']) ? $uri['query'] : '';
$uri = isset($uri['path']) ? $uri['path'] : '';
if (isset($_SERVER['SCRIPT_NAME'][0]))
{
if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0)
{
$uri = (string) substr($uri, strlen($_SERVER['SCRIPT_NAME']));
}
elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0)
{
$uri = (string) substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME'])));
}
}
// This section ensures that even on servers that require the URI to be in the query string (Nginx) a correct
// URI is found, and also fixes the QUERY_STRING server var and $_GET array.
if (trim($uri, '/') === '' && strncmp($query, '/', 1) === 0)
{
$query = explode('?', $query, 2);
$uri = $query[0];
$_SERVER['QUERY_STRING'] = isset($query[1]) ? $query[1] : '';
}
else
{
$_SERVER['QUERY_STRING'] = $query;
}
parse_str($_SERVER['QUERY_STRING'], $_GET);
if ($uri === '/' OR $uri === '')
{
return '/';
}
// Do some final cleaning of the URI and return it
return $this->_remove_relative_directory($uri);
}
// --------------------------------------------------------------------
/**
* Parse QUERY_STRING
*
* Will parse QUERY_STRING and automatically detect the URI from it.
*
* @return string
*/
protected function _parse_query_string()
{
$uri = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
if (trim($uri, '/') === '')
{
return '';
}
elseif (strncmp($uri, '/', 1) === 0)
{
$uri = explode('?', $uri, 2);
$_SERVER['QUERY_STRING'] = isset($uri[1]) ? $uri[1] : '';
$uri = $uri[0];
}
parse_str($_SERVER['QUERY_STRING'], $_GET);
return $this->_remove_relative_directory($uri);
}
// --------------------------------------------------------------------
/**
* Parse CLI arguments
*
* Take each command line argument and assume it is a URI segment.
*
* @return string
*/
protected function _parse_argv()
{
$args = array_slice($_SERVER['argv'], 1);
return $args ? implode('/', $args) : '';
}
// --------------------------------------------------------------------
/**
* Remove relative directory (../) and multi slashes (///)
*
* Do some final cleaning of the URI and return it, currently only used in self::_parse_request_uri()
*
* @param string $uri
* @return string
*/
protected function _remove_relative_directory($uri)
{
$uris = array();
$tok = strtok($uri, '/');
while ($tok !== FALSE)
{
if (( ! empty($tok) OR $tok === '0') && $tok !== '..')
{
$uris[] = $tok;
}
$tok = strtok('/');
}
return implode('/', $uris);
}
// --------------------------------------------------------------------
/**
* Filter URI
*
* Filters segments for malicious characters.
*
* @param string $str
* @return void
*/
public function filter_uri(&$str)
{
if ( ! empty($str) && ! empty($this->_permitted_uri_chars) && ! preg_match('/^['.$this->_permitted_uri_chars.']+$/i'.(UTF8_ENABLED ? 'u' : ''), $str))
{
show_error('The URI you submitted has disallowed characters.', 400);
}
}
// --------------------------------------------------------------------
/**
* Fetch URI Segment
*
* @see CI_URI::$segments
* @param int $n Index
* @param mixed $no_result What to return if the segment index is not found
* @return mixed
*/
public function segment($n, $no_result = NULL)
{
return isset($this->segments[$n]) ? $this->segments[$n] : $no_result;
}
// --------------------------------------------------------------------
/**
* Fetch URI "routed" Segment
*
* Returns the re-routed URI segment (assuming routing rules are used)
* based on the index provided. If there is no routing, will return
* the same result as CI_URI::segment().
*
* @see CI_URI::$rsegments
* @see CI_URI::segment()
* @param int $n Index
* @param mixed $no_result What to return if the segment index is not found
* @return mixed
*/
public function rsegment($n, $no_result = NULL)
{
return isset($this->rsegments[$n]) ? $this->rsegments[$n] : $no_result;
}
// --------------------------------------------------------------------
/**
* URI to assoc
*
* Generates an associative array of URI data starting at the supplied
* segment index. For example, if this is your URI:
*
* example.com/user/search/name/joe/location/UK/gender/male
*
* You can use this method to generate an array with this prototype:
*
* array (
* name => joe
* location => UK
* gender => male
* )
*
* @param int $n Index (default: 3)
* @param array $default Default values
* @return array
*/
public function uri_to_assoc($n = 3, $default = array())
{
return $this->_uri_to_assoc($n, $default, 'segment');
}
// --------------------------------------------------------------------
/**
* Routed URI to assoc
*
* Identical to CI_URI::uri_to_assoc(), only it uses the re-routed
* segment array.
*
* @see CI_URI::uri_to_assoc()
* @param int $n Index (default: 3)
* @param array $default Default values
* @return array
*/
public function ruri_to_assoc($n = 3, $default = array())
{
return $this->_uri_to_assoc($n, $default, 'rsegment');
}
// --------------------------------------------------------------------
/**
* Internal URI-to-assoc
*
* Generates a key/value pair from the URI string or re-routed URI string.
*
* @used-by CI_URI::uri_to_assoc()
* @used-by CI_URI::ruri_to_assoc()
* @param int $n Index (default: 3)
* @param array $default Default values
* @param string $which Array name ('segment' or 'rsegment')
* @return array
*/
protected function _uri_to_assoc($n = 3, $default = array(), $which = 'segment')
{
if ( ! is_numeric($n))
{
return $default;
}
if (isset($this->keyval[$which], $this->keyval[$which][$n]))
{
return $this->keyval[$which][$n];
}
$total_segments = "total_{$which}s";
$segment_array = "{$which}_array";
if ($this->$total_segments() < $n)
{
return (count($default) === 0)
? array()
: array_fill_keys($default, NULL);
}
$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] = NULL;
$lastval = $seg;
}
$i++;
}
if (count($default) > 0)
{
foreach ($default as $val)
{
if ( ! array_key_exists($val, $retval))
{
$retval[$val] = NULL;
}
}
}
// Cache the array for reuse
isset($this->keyval[$which]) OR $this->keyval[$which] = array();
$this->keyval[$which][$n] = $retval;
return $retval;
}
// --------------------------------------------------------------------
/**
* Assoc to URI
*
* Generates a URI string from an associative array.
*
* @param array $array Input array of key/value pairs
* @return string URI string
*/
public function assoc_to_uri($array)
{
$temp = array();
foreach ((array) $array as $key => $val)
{
$temp[] = $key;
$temp[] = $val;
}
return implode('/', $temp);
}
// --------------------------------------------------------------------
/**
* Slash segment
*
* Fetches an URI segment with a slash.
*
* @param int $n Index
* @param string $where Where to add the slash ('trailing' or 'leading')
* @return string
*/
public function slash_segment($n, $where = 'trailing')
{
return $this->_slash_segment($n, $where, 'segment');
}
// --------------------------------------------------------------------
/**
* Slash routed segment
*
* Fetches an URI routed segment with a slash.
*
* @param int $n Index
* @param string $where Where to add the slash ('trailing' or 'leading')
* @return string
*/
public function slash_rsegment($n, $where = 'trailing')
{
return $this->_slash_segment($n, $where, 'rsegment');
}
// --------------------------------------------------------------------
/**
* Internal Slash segment
*
* Fetches an URI Segment and adds a slash to it.
*
* @used-by CI_URI::slash_segment()
* @used-by CI_URI::slash_rsegment()
*
* @param int $n Index
* @param string $where Where to add the slash ('trailing' or 'leading')
* @param string $which Array name ('segment' or 'rsegment')
* @return string
*/
protected function _slash_segment($n, $where = 'trailing', $which = 'segment')
{
$leading = $trailing = '/';
if ($where === 'trailing')
{
$leading = '';
}
elseif ($where === 'leading')
{
$trailing = '';
}
return $leading.$this->$which($n).$trailing;
}
// --------------------------------------------------------------------
/**
* Segment Array
*
* @return array CI_URI::$segments
*/
public function segment_array()
{
return $this->segments;
}
// --------------------------------------------------------------------
/**
* Routed Segment Array
*
* @return array CI_URI::$rsegments
*/
public function rsegment_array()
{
return $this->rsegments;
}
// --------------------------------------------------------------------
/**
* Total number of segments
*
* @return int
*/
public function total_segments()
{
return count($this->segments);
}
// --------------------------------------------------------------------
/**
* Total number of routed segments
*
* @return int
*/
public function total_rsegments()
{
return count($this->rsegments);
}
// --------------------------------------------------------------------
/**
* Fetch URI string
*
* @return string CI_URI::$uri_string
*/
public function uri_string()
{
return $this->uri_string;
}
// --------------------------------------------------------------------
/**
* Fetch Re-routed URI string
*
* @return string
*/
public function ruri_string()
{
return ltrim(load_class('Router', 'core')->directory, '/').implode('/', $this->rsegments);
}
}

164
php/system/core/Utf8.php Normal file
View File

@ -0,0 +1,164 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2018, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 2.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Utf8 Class
*
* Provides support for UTF-8 environments
*
* @package CodeIgniter
* @subpackage Libraries
* @category UTF-8
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/libraries/utf8.html
*/
class CI_Utf8 {
/**
* Class constructor
*
* Determines if UTF-8 support is to be enabled.
*
* @return void
*/
public function __construct()
{
if (
defined('PREG_BAD_UTF8_ERROR') // PCRE must support UTF-8
&& (ICONV_ENABLED === TRUE OR MB_ENABLED === TRUE) // iconv or mbstring must be installed
&& strtoupper(config_item('charset')) === 'UTF-8' // Application charset must be UTF-8
)
{
define('UTF8_ENABLED', TRUE);
log_message('debug', 'UTF-8 Support Enabled');
}
else
{
define('UTF8_ENABLED', FALSE);
log_message('debug', 'UTF-8 Support Disabled');
}
log_message('info', 'Utf8 Class Initialized');
}
// --------------------------------------------------------------------
/**
* Clean UTF-8 strings
*
* Ensures strings contain only valid UTF-8 characters.
*
* @param string $str String to clean
* @return string
*/
public function clean_string($str)
{
if ($this->is_ascii($str) === FALSE)
{
if (MB_ENABLED)
{
$str = mb_convert_encoding($str, 'UTF-8', 'UTF-8');
}
elseif (ICONV_ENABLED)
{
$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.
*
* @param string $str String to clean
* @return string
*/
public function safe_ascii_for_xml($str)
{
return remove_invisible_characters($str, FALSE);
}
// --------------------------------------------------------------------
/**
* Convert to UTF-8
*
* Attempts to convert a string to UTF-8.
*
* @param string $str Input string
* @param string $encoding Input encoding
* @return string $str encoded in UTF-8 or FALSE on failure
*/
public function convert_to_utf8($str, $encoding)
{
if (MB_ENABLED)
{
return mb_convert_encoding($str, 'UTF-8', $encoding);
}
elseif (ICONV_ENABLED)
{
return @iconv($encoding, 'UTF-8', $str);
}
return FALSE;
}
// --------------------------------------------------------------------
/**
* Is ASCII?
*
* Tests if a string is standard 7-bit ASCII or not.
*
* @param string $str String to check
* @return bool
*/
public function is_ascii($str)
{
return (preg_match('/[^\x00-\x7F]/S', $str) === 0);
}
}

View File

@ -0,0 +1,254 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2018, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 3.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* PHP ext/hash compatibility package
*
* @package CodeIgniter
* @subpackage CodeIgniter
* @category Compatibility
* @author Andrey Andreev
* @link https://codeigniter.com/user_guide/
* @link http://php.net/hash
*/
// ------------------------------------------------------------------------
if (is_php('5.6'))
{
return;
}
// ------------------------------------------------------------------------
if ( ! function_exists('hash_equals'))
{
/**
* hash_equals()
*
* @link http://php.net/hash_equals
* @param string $known_string
* @param string $user_string
* @return bool
*/
function hash_equals($known_string, $user_string)
{
if ( ! is_string($known_string))
{
trigger_error('hash_equals(): Expected known_string to be a string, '.strtolower(gettype($known_string)).' given', E_USER_WARNING);
return FALSE;
}
elseif ( ! is_string($user_string))
{
trigger_error('hash_equals(): Expected user_string to be a string, '.strtolower(gettype($user_string)).' given', E_USER_WARNING);
return FALSE;
}
elseif (($length = strlen($known_string)) !== strlen($user_string))
{
return FALSE;
}
$diff = 0;
for ($i = 0; $i < $length; $i++)
{
$diff |= ord($known_string[$i]) ^ ord($user_string[$i]);
}
return ($diff === 0);
}
}
// ------------------------------------------------------------------------
if (is_php('5.5'))
{
return;
}
// ------------------------------------------------------------------------
if ( ! function_exists('hash_pbkdf2'))
{
/**
* hash_pbkdf2()
*
* @link http://php.net/hash_pbkdf2
* @param string $algo
* @param string $password
* @param string $salt
* @param int $iterations
* @param int $length
* @param bool $raw_output
* @return string
*/
function hash_pbkdf2($algo, $password, $salt, $iterations, $length = 0, $raw_output = FALSE)
{
if ( ! in_array(strtolower($algo), hash_algos(), TRUE))
{
trigger_error('hash_pbkdf2(): Unknown hashing algorithm: '.$algo, E_USER_WARNING);
return FALSE;
}
if (($type = gettype($iterations)) !== 'integer')
{
if ($type === 'object' && method_exists($iterations, '__toString'))
{
$iterations = (string) $iterations;
}
if (is_string($iterations) && is_numeric($iterations))
{
$iterations = (int) $iterations;
}
else
{
trigger_error('hash_pbkdf2() expects parameter 4 to be long, '.$type.' given', E_USER_WARNING);
return NULL;
}
}
if ($iterations < 1)
{
trigger_error('hash_pbkdf2(): Iterations must be a positive integer: '.$iterations, E_USER_WARNING);
return FALSE;
}
if (($type = gettype($length)) !== 'integer')
{
if ($type === 'object' && method_exists($length, '__toString'))
{
$length = (string) $length;
}
if (is_string($length) && is_numeric($length))
{
$length = (int) $length;
}
else
{
trigger_error('hash_pbkdf2() expects parameter 5 to be long, '.$type.' given', E_USER_WARNING);
return NULL;
}
}
if ($length < 0)
{
trigger_error('hash_pbkdf2(): Length must be greater than or equal to 0: '.$length, E_USER_WARNING);
return FALSE;
}
$hash_length = defined('MB_OVERLOAD_STRING')
? mb_strlen(hash($algo, NULL, TRUE), '8bit')
: strlen(hash($algo, NULL, TRUE));
empty($length) && $length = $hash_length;
// Pre-hash password inputs longer than the algorithm's block size
// (i.e. prepare HMAC key) to mitigate potential DoS attacks.
static $block_sizes;
empty($block_sizes) && $block_sizes = array(
'gost' => 32,
'haval128,3' => 128,
'haval160,3' => 128,
'haval192,3' => 128,
'haval224,3' => 128,
'haval256,3' => 128,
'haval128,4' => 128,
'haval160,4' => 128,
'haval192,4' => 128,
'haval224,4' => 128,
'haval256,4' => 128,
'haval128,5' => 128,
'haval160,5' => 128,
'haval192,5' => 128,
'haval224,5' => 128,
'haval256,5' => 128,
'md2' => 16,
'md4' => 64,
'md5' => 64,
'ripemd128' => 64,
'ripemd160' => 64,
'ripemd256' => 64,
'ripemd320' => 64,
'salsa10' => 64,
'salsa20' => 64,
'sha1' => 64,
'sha224' => 64,
'sha256' => 64,
'sha384' => 128,
'sha512' => 128,
'snefru' => 32,
'snefru256' => 32,
'tiger128,3' => 64,
'tiger160,3' => 64,
'tiger192,3' => 64,
'tiger128,4' => 64,
'tiger160,4' => 64,
'tiger192,4' => 64,
'whirlpool' => 64
);
if (isset($block_sizes[$algo], $password[$block_sizes[$algo]]))
{
$password = hash($algo, $password, TRUE);
}
$hash = '';
// Note: Blocks are NOT 0-indexed
for ($bc = (int) ceil($length / $hash_length), $bi = 1; $bi <= $bc; $bi++)
{
$key = $derived_key = hash_hmac($algo, $salt.pack('N', $bi), $password, TRUE);
for ($i = 1; $i < $iterations; $i++)
{
$derived_key ^= $key = hash_hmac($algo, $key, $password, TRUE);
}
$hash .= $derived_key;
}
// This is not RFC-compatible, but we're aiming for natural PHP compatibility
if ( ! $raw_output)
{
$hash = bin2hex($hash);
}
return defined('MB_OVERLOAD_STRING')
? mb_substr($hash, 0, $length, '8bit')
: substr($hash, 0, $length);
}
}

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>403 Forbidden</title>
</head>
<body>
<p>Directory access is forbidden.</p>
</body>
</html>

View File

@ -0,0 +1,149 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2018, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 3.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* PHP ext/mbstring compatibility package
*
* @package CodeIgniter
* @subpackage CodeIgniter
* @category Compatibility
* @author Andrey Andreev
* @link https://codeigniter.com/user_guide/
* @link http://php.net/mbstring
*/
// ------------------------------------------------------------------------
if (MB_ENABLED === TRUE)
{
return;
}
// ------------------------------------------------------------------------
if ( ! function_exists('mb_strlen'))
{
/**
* mb_strlen()
*
* WARNING: This function WILL fall-back to strlen()
* if iconv is not available!
*
* @link http://php.net/mb_strlen
* @param string $str
* @param string $encoding
* @return int
*/
function mb_strlen($str, $encoding = NULL)
{
if (ICONV_ENABLED === TRUE)
{
return iconv_strlen($str, isset($encoding) ? $encoding : config_item('charset'));
}
log_message('debug', 'Compatibility (mbstring): iconv_strlen() is not available, falling back to strlen().');
return strlen($str);
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('mb_strpos'))
{
/**
* mb_strpos()
*
* WARNING: This function WILL fall-back to strpos()
* if iconv is not available!
*
* @link http://php.net/mb_strpos
* @param string $haystack
* @param string $needle
* @param int $offset
* @param string $encoding
* @return mixed
*/
function mb_strpos($haystack, $needle, $offset = 0, $encoding = NULL)
{
if (ICONV_ENABLED === TRUE)
{
return iconv_strpos($haystack, $needle, $offset, isset($encoding) ? $encoding : config_item('charset'));
}
log_message('debug', 'Compatibility (mbstring): iconv_strpos() is not available, falling back to strpos().');
return strpos($haystack, $needle, $offset);
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('mb_substr'))
{
/**
* mb_substr()
*
* WARNING: This function WILL fall-back to substr()
* if iconv is not available.
*
* @link http://php.net/mb_substr
* @param string $str
* @param int $start
* @param int $length
* @param string $encoding
* @return string
*/
function mb_substr($str, $start, $length = NULL, $encoding = NULL)
{
if (ICONV_ENABLED === TRUE)
{
isset($encoding) OR $encoding = config_item('charset');
return iconv_substr(
$str,
$start,
isset($length) ? $length : iconv_strlen($str, $encoding), // NULL doesn't work
$encoding
);
}
log_message('debug', 'Compatibility (mbstring): iconv_substr() is not available, falling back to substr().');
return isset($length)
? substr($str, $start, $length)
: substr($str, $start);
}
}

View File

@ -0,0 +1,251 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2018, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 3.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* PHP ext/standard/password compatibility package
*
* @package CodeIgniter
* @subpackage CodeIgniter
* @category Compatibility
* @author Andrey Andreev
* @link https://codeigniter.com/user_guide/
* @link http://php.net/password
*/
// ------------------------------------------------------------------------
if (is_php('5.5') OR ! defined('CRYPT_BLOWFISH') OR CRYPT_BLOWFISH !== 1 OR defined('HHVM_VERSION'))
{
return;
}
// ------------------------------------------------------------------------
defined('PASSWORD_BCRYPT') OR define('PASSWORD_BCRYPT', 1);
defined('PASSWORD_DEFAULT') OR define('PASSWORD_DEFAULT', PASSWORD_BCRYPT);
// ------------------------------------------------------------------------
if ( ! function_exists('password_get_info'))
{
/**
* password_get_info()
*
* @link http://php.net/password_get_info
* @param string $hash
* @return array
*/
function password_get_info($hash)
{
return (strlen($hash) < 60 OR sscanf($hash, '$2y$%d', $hash) !== 1)
? array('algo' => 0, 'algoName' => 'unknown', 'options' => array())
: array('algo' => 1, 'algoName' => 'bcrypt', 'options' => array('cost' => $hash));
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('password_hash'))
{
/**
* password_hash()
*
* @link http://php.net/password_hash
* @param string $password
* @param int $algo
* @param array $options
* @return mixed
*/
function password_hash($password, $algo, array $options = array())
{
static $func_overload;
isset($func_overload) OR $func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload'));
if ($algo !== 1)
{
trigger_error('password_hash(): Unknown hashing algorithm: '.(int) $algo, E_USER_WARNING);
return NULL;
}
if (isset($options['cost']) && ($options['cost'] < 4 OR $options['cost'] > 31))
{
trigger_error('password_hash(): Invalid bcrypt cost parameter specified: '.(int) $options['cost'], E_USER_WARNING);
return NULL;
}
if (isset($options['salt']) && ($saltlen = ($func_overload ? mb_strlen($options['salt'], '8bit') : strlen($options['salt']))) < 22)
{
trigger_error('password_hash(): Provided salt is too short: '.$saltlen.' expecting 22', E_USER_WARNING);
return NULL;
}
elseif ( ! isset($options['salt']))
{
if (function_exists('random_bytes'))
{
try
{
$options['salt'] = random_bytes(16);
}
catch (Exception $e)
{
log_message('error', 'compat/password: Error while trying to use random_bytes(): '.$e->getMessage());
return FALSE;
}
}
elseif (defined('MCRYPT_DEV_URANDOM'))
{
$options['salt'] = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);
}
elseif (DIRECTORY_SEPARATOR === '/' && (is_readable($dev = '/dev/arandom') OR is_readable($dev = '/dev/urandom')))
{
if (($fp = fopen($dev, 'rb')) === FALSE)
{
log_message('error', 'compat/password: Unable to open '.$dev.' for reading.');
return FALSE;
}
// Try not to waste entropy ...
is_php('5.4') && stream_set_chunk_size($fp, 16);
$options['salt'] = '';
for ($read = 0; $read < 16; $read = ($func_overload) ? mb_strlen($options['salt'], '8bit') : strlen($options['salt']))
{
if (($read = fread($fp, 16 - $read)) === FALSE)
{
log_message('error', 'compat/password: Error while reading from '.$dev.'.');
return FALSE;
}
$options['salt'] .= $read;
}
fclose($fp);
}
elseif (function_exists('openssl_random_pseudo_bytes'))
{
$is_secure = NULL;
$options['salt'] = openssl_random_pseudo_bytes(16, $is_secure);
if ($is_secure !== TRUE)
{
log_message('error', 'compat/password: openssl_random_pseudo_bytes() set the $cryto_strong flag to FALSE');
return FALSE;
}
}
else
{
log_message('error', 'compat/password: No CSPRNG available.');
return FALSE;
}
$options['salt'] = str_replace('+', '.', rtrim(base64_encode($options['salt']), '='));
}
elseif ( ! preg_match('#^[a-zA-Z0-9./]+$#D', $options['salt']))
{
$options['salt'] = str_replace('+', '.', rtrim(base64_encode($options['salt']), '='));
}
isset($options['cost']) OR $options['cost'] = 10;
return (strlen($password = crypt($password, sprintf('$2y$%02d$%s', $options['cost'], $options['salt']))) === 60)
? $password
: FALSE;
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('password_needs_rehash'))
{
/**
* password_needs_rehash()
*
* @link http://php.net/password_needs_rehash
* @param string $hash
* @param int $algo
* @param array $options
* @return bool
*/
function password_needs_rehash($hash, $algo, array $options = array())
{
$info = password_get_info($hash);
if ($algo !== $info['algo'])
{
return TRUE;
}
elseif ($algo === 1)
{
$options['cost'] = isset($options['cost']) ? (int) $options['cost'] : 10;
return ($info['options']['cost'] !== $options['cost']);
}
// Odd at first glance, but according to a comment in PHP's own unit tests,
// because it is an unknown algorithm - it's valid and therefore doesn't
// need rehashing.
return FALSE;
}
}
// ------------------------------------------------------------------------
if ( ! function_exists('password_verify'))
{
/**
* password_verify()
*
* @link http://php.net/password_verify
* @param string $password
* @param string $hash
* @return bool
*/
function password_verify($password, $hash)
{
if (strlen($hash) !== 60 OR strlen($password = crypt($password, $hash)) !== 60)
{
return FALSE;
}
$compare = 0;
for ($i = 0; $i < 60; $i++)
{
$compare |= (ord($password[$i]) ^ ord($hash[$i]));
}
return ($compare === 0);
}
}

View File

@ -0,0 +1,182 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2018, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
* @license http://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 3.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* PHP ext/standard compatibility package
*
* @package CodeIgniter
* @subpackage CodeIgniter
* @category Compatibility
* @author Andrey Andreev
* @link https://codeigniter.com/user_guide/
*/
// ------------------------------------------------------------------------
if (is_php('5.5'))
{
return;
}
// ------------------------------------------------------------------------
if ( ! function_exists('array_column'))
{
/**
* array_column()
*
* @link http://php.net/array_column
* @param array $array
* @param mixed $column_key
* @param mixed $index_key
* @return array
*/
function array_column(array $array, $column_key, $index_key = NULL)
{
if ( ! in_array($type = gettype($column_key), array('integer', 'string', 'NULL'), TRUE))
{
if ($type === 'double')
{
$column_key = (int) $column_key;
}
elseif ($type === 'object' && method_exists($column_key, '__toString'))
{
$column_key = (string) $column_key;
}
else
{
trigger_error('array_column(): The column key should be either a string or an integer', E_USER_WARNING);
return FALSE;
}
}
if ( ! in_array($type = gettype($index_key), array('integer', 'string', 'NULL'), TRUE))
{
if ($type === 'double')
{
$index_key = (int) $index_key;
}
elseif ($type === 'object' && method_exists($index_key, '__toString'))
{
$index_key = (string) $index_key;
}
else
{
trigger_error('array_column(): The index key should be either a string or an integer', E_USER_WARNING);
return FALSE;
}
}
$result = array();
foreach ($array as &$a)
{
if ($column_key === NULL)
{
$value = $a;
}
elseif (is_array($a) && array_key_exists($column_key, $a))
{
$value = $a[$column_key];
}
else
{
continue;
}
if ($index_key === NULL OR ! array_key_exists($index_key, $a))
{
$result[] = $value;
}
else
{
$result[$a[$index_key]] = $value;
}
}
return $result;
}
}
// ------------------------------------------------------------------------
if (is_php('5.4'))
{
return;
}
// ------------------------------------------------------------------------
if ( ! function_exists('hex2bin'))
{
/**
* hex2bin()
*
* @link http://php.net/hex2bin
* @param string $data
* @return string
*/
function hex2bin($data)
{
if (in_array($type = gettype($data), array('array', 'double', 'object', 'resource'), TRUE))
{
if ($type === 'object' && method_exists($data, '__toString'))
{
$data = (string) $data;
}
else
{
trigger_error('hex2bin() expects parameter 1 to be string, '.$type.' given', E_USER_WARNING);
return NULL;
}
}
if (strlen($data) % 2 !== 0)
{
trigger_error('Hexadecimal input string must have an even length', E_USER_WARNING);
return FALSE;
}
elseif ( ! preg_match('/^[0-9a-f]*$/i', $data))
{
trigger_error('Input string must be hexadecimal string', E_USER_WARNING);
return FALSE;
}
return pack('H*', $data);
}
}

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>403 Forbidden</title>
</head>
<body>
<p>Directory access is forbidden.</p>
</body>
</html>