diff --git a/.gitignore b/.gitignore
index da6b5f4..cb51b98 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,4 @@
htdocs/
-.DS_Store
application/cache/*
!application/cache/index.html
@@ -11,28 +10,5 @@ application/logs/*
composer.lock
-user_guide_src/build/*
-user_guide_src/cilexer/build/*
-user_guide_src/cilexer/dist/*
-user_guide_src/cilexer/pycilexer.egg-info/*
/vendor/
/bin/
-simplecishop.sqlite
-
-# IDE Files
-#-------------------------
-/nbproject/
-.idea/*
-
-## Sublime Text cache files
-*.tmlanguage.cache
-*.tmPreferences.cache
-*.stTheme.cache
-*.sublime-workspace
-*.sublime-project
-/tests/tests/
-/tests/results/
-
-## VScode settings
-
-.vscode/*
\ No newline at end of file
diff --git a/license.txt b/LICENSE.txt
similarity index 92%
rename from license.txt
rename to LICENSE.txt
index dcac585..2866b26 100644
--- a/license.txt
+++ b/LICENSE.txt
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2014 - 2018, British Columbia Institute of Technology
+Copyright (c) 2011 - 2020, Nikolaos Papagiannopoulos
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ 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.
\ No newline at end of file
+THE SOFTWARE.
diff --git a/README.md b/README.md
index 5621a37..59ed7ec 100755
--- a/README.md
+++ b/README.md
@@ -1,20 +1,19 @@
:warning: :warning: :warning: **This project is work in progress and should not be used in production !** :warning: :warning: :warning:
-SimpleCiShop
-============
+# SimpleCiShop
+
The SimpleCiShop is an ecommerce web application based on the famous CodeIgniter framework.
-It's being currently refactored to run with PHP 7.2 and CodeIgniter 3.1.9
+It's being currently refactored to run with PHP >=7.2 and CodeIgniter ^3.1.
-The shop was fully functional since I have used it to sell myself products; actually the products you see in the demo site are real and I use to sell them.
+The shop was fully functional since I have used it to sell myself products; actually the products you see in the demo site are real, and I used to sell them.
I was not satisfied with the other open source ecommerce systems that were in the market that time - neither am I now - so I decided to build my own simple shopping cart.
-There is a lot of stuff to be done and a lot of stuff-junk to be removed. But ~~__Everything that has a Beginning..... has an end__~~ apparently not always :smile:.
+There is a lot of stuff to be done.
-Features
---------
+## Features
* Nested Categories translatable with html description
* Products with image upload (unlimited) and translatable html description
@@ -22,38 +21,37 @@ Features
* Product variables - you can set as any variables as you like at any product which are also reusable but not yet very much implemented
* Discount Coupons - The system can generate discount coupons with a certain discount which can be used by the customers at an order to get a discount
-Directory Structure
----------
+## Directory Structure
The directory structure is mainly the CodeIgniter structure. There are a few things that are outside of that.
-`/assets` - Contains js / fonts
+`public/assets` - Contains js / fonts
-`/images` - Contains the images of the products
+`public/images` - Contains the images of the products
-`/theme` - Contains the css and the images of the frontend website (notice that the website is not themeable yet)
+`public/theme` - Contains the css and the images of the frontend website (notice that the website is not themeable yet)
-`/uploads` - Uploaded images that are used in the Product details/description
+`public/uploads` - Uploaded images that are used in the Product details/description
-`/application/controllers/admin` - The admin (backend) application controllers
+`application/controllers/admin` - The admin (backend) application controllers
-`/application/controllers/shop` - The shop (frontend) application controllers
+`application/controllers/shop` - The shop (frontend) application controllers
-Installation
-------------
+## Installation
-- Clone the project `git clone https://github.com/panigrc/SimpleCiShop.git` to your webserver root directory
-- Import the [simplecishop.sql](https://github.com/panigrc/SimpleCiShop/blob/master/simplecishop.sql) to your MySQL/MariaDB
+- Clone the project `git clone https://github.com/panigrc/SimpleCiShop.git`
+- Import the [simplecishop.sql](https://github.com/panigrc/SimpleCiShop/blob/master/simplecishop.sql) to your MySQL/MariaDB server
- Change the 'database connectivity settings' in the `application/config/database.php` file according to your needs
+- Change into the project directory and run `composer install`
+- Your Docroot directory should be the `public` directory. If you have another Docroot configuration i.e. `public_html` you could create a symlink like this:
+`ln -s public public_html`.
- Browse to `http://localhost/your/webserver/path/SimpleCiShop/index.php/shop/home`
- To access the administration visit `http://localhost/your/webserver/path/SimpleCiShop/index.php/admin/catalog`
-Database structure
-------------------
+## Database structure
See [simplecishop.sql](https://github.com/panigrc/SimpleCiShop/blob/master/simplecishop.sql)
-TODOs
------
+## TODOs
See [Project](https://github.com/panigrc/SimpleCiShop/projects/1)
diff --git a/composer.json b/composer.json
index 9a9aa67..88a3bc1 100644
--- a/composer.json
+++ b/composer.json
@@ -14,7 +14,8 @@
"php": ">=7.2",
"craftsman/cli": "^5.1",
"emporio/core": "@dev",
- "emporio/ui": "@dev"
+ "emporio/ui": "@dev",
+ "codeigniter/framework": "^3.1"
},
"repositories": [
{ "type": "path", "url": "packages/emporio/core" },
diff --git a/public/index.php b/public/index.php
index 2f27b92..bb64c64 100755
--- a/public/index.php
+++ b/public/index.php
@@ -97,7 +97,7 @@
* This variable must contain the name of your "system" directory.
* Set the path if it is not in the same directory as this file.
*/
- $system_path = '../system';
+ $system_path = '../vendor/codeigniter/framework/system';
/*
*---------------------------------------------------------------
diff --git a/system/.htaccess b/system/.htaccess
deleted file mode 100644
index 97c65d2..0000000
--- a/system/.htaccess
+++ /dev/null
@@ -1,6 +0,0 @@
-
'.(is_array($message) ? implode('
', $message) : $message).'
'; - $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; - } - -} diff --git a/system/core/Hooks.php b/system/core/Hooks.php deleted file mode 100644 index 82c68b1..0000000 --- a/system/core/Hooks.php +++ /dev/null @@ -1,266 +0,0 @@ -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; - } - -} diff --git a/system/core/Input.php b/system/core/Input.php deleted file mode 100644 index 143babf..0000000 --- a/system/core/Input.php +++ /dev/null @@ -1,895 +0,0 @@ -_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; - } - } - -} diff --git a/system/core/Lang.php b/system/core/Lang.php deleted file mode 100644 index 39fdd06..0000000 --- a/system/core/Lang.php +++ /dev/null @@ -1,203 +0,0 @@ -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; - } - -} diff --git a/system/core/Loader.php b/system/core/Loader.php deleted file mode 100644 index c84aff3..0000000 --- a/system/core/Loader.php +++ /dev/null @@ -1,1415 +0,0 @@ - TRUE); - - /** - * List of paths to load libraries from - * - * @var array - */ - protected $_ci_library_paths = array(APPPATH, BASEPATH); - - /** - * List of paths to load models from - * - * @var array - */ - protected $_ci_model_paths = array(APPPATH); - - /** - * List of paths to load helpers from - * - * @var array - */ - protected $_ci_helper_paths = array(APPPATH, BASEPATH); - - /** - * List of cached variables - * - * @var array - */ - protected $_ci_cached_vars = array(); - - /** - * List of loaded classes - * - * @var array - */ - protected $_ci_classes = array(); - - /** - * List of loaded models - * - * @var array - */ - protected $_ci_models = array(); - - /** - * List of loaded helpers - * - * @var array - */ - protected $_ci_helpers = array(); - - /** - * List of class name mappings - * - * @var array - */ - protected $_ci_varmap = array( - 'unit_test' => 'unit', - 'user_agent' => 'agent' - ); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Sets component load paths, gets the initial output buffering level. - * - * @return void - */ - public function __construct() - { - $this->_ci_ob_level = ob_get_level(); - $this->_ci_classes =& is_loaded(); - - log_message('info', 'Loader Class Initialized'); - } - - // -------------------------------------------------------------------- - - /** - * Initializer - * - * @todo Figure out a way to move this to the constructor - * without breaking *package_path*() methods. - * @uses CI_Loader::_ci_autoloader() - * @used-by CI_Controller::__construct() - * @return void - */ - public function initialize() - { - $this->_ci_autoloader(); - } - - // -------------------------------------------------------------------- - - /** - * Is Loaded - * - * A utility method to test if a class is in the self::$_ci_classes array. - * - * @used-by Mainly used by Form Helper function _get_validation_object(). - * - * @param string $class Class name to check for - * @return string|bool Class object name if loaded or FALSE - */ - public function is_loaded($class) - { - return array_search(ucfirst($class), $this->_ci_classes, TRUE); - } - - // -------------------------------------------------------------------- - - /** - * Library Loader - * - * Loads and instantiates libraries. - * Designed to be called from application controllers. - * - * @param mixed $library Library name - * @param array $params Optional parameters to pass to the library class constructor - * @param string $object_name An optional object name to assign to - * @return object - */ - public function library($library, $params = NULL, $object_name = NULL) - { - if (empty($library)) - { - return $this; - } - elseif (is_array($library)) - { - foreach ($library as $key => $value) - { - if (is_int($key)) - { - $this->library($value, $params); - } - else - { - $this->library($key, $params, $value); - } - } - - return $this; - } - - if ($params !== NULL && ! is_array($params)) - { - $params = NULL; - } - - $this->_ci_load_library($library, $params, $object_name); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Model Loader - * - * Loads and instantiates models. - * - * @param mixed $model Model name - * @param string $name An optional object name to assign to - * @param bool $db_conn An optional database connection configuration to initialize - * @return object - */ - public function model($model, $name = '', $db_conn = FALSE) - { - if (empty($model)) - { - return $this; - } - elseif (is_array($model)) - { - foreach ($model as $key => $value) - { - is_int($key) ? $this->model($value, '', $db_conn) : $this->model($key, $value, $db_conn); - } - - return $this; - } - - $path = ''; - - // Is the model in a sub-folder? If so, parse out the filename and path. - if (($last_slash = strrpos($model, '/')) !== FALSE) - { - // The path is in front of the last slash - $path = substr($model, 0, ++$last_slash); - - // And the model name behind it - $model = substr($model, $last_slash); - } - - if (empty($name)) - { - $name = $model; - } - - if (in_array($name, $this->_ci_models, TRUE)) - { - return $this; - } - - $CI =& get_instance(); - if (isset($CI->$name)) - { - throw new RuntimeException('The model name you are loading is the name of a resource that is already being used: '.$name); - } - - if ($db_conn !== FALSE && ! class_exists('CI_DB', FALSE)) - { - if ($db_conn === TRUE) - { - $db_conn = ''; - } - - $this->database($db_conn, FALSE, TRUE); - } - - // Note: All of the code under this condition used to be just: - // - // load_class('Model', 'core'); - // - // However, load_class() instantiates classes - // to cache them for later use and that prevents - // MY_Model from being an abstract class and is - // sub-optimal otherwise anyway. - if ( ! class_exists('CI_Model', FALSE)) - { - $app_path = APPPATH.'core'.DIRECTORY_SEPARATOR; - if (file_exists($app_path.'Model.php')) - { - require_once($app_path.'Model.php'); - if ( ! class_exists('CI_Model', FALSE)) - { - throw new RuntimeException($app_path."Model.php exists, but doesn't declare class CI_Model"); - } - - log_message('info', 'CI_Model class loaded'); - } - elseif ( ! class_exists('CI_Model', FALSE)) - { - require_once(BASEPATH.'core'.DIRECTORY_SEPARATOR.'Model.php'); - } - - $class = config_item('subclass_prefix').'Model'; - if (file_exists($app_path.$class.'.php')) - { - require_once($app_path.$class.'.php'); - if ( ! class_exists($class, FALSE)) - { - throw new RuntimeException($app_path.$class.".php exists, but doesn't declare class ".$class); - } - - log_message('info', config_item('subclass_prefix').'Model class loaded'); - } - } - - $model = ucfirst($model); - if ( ! class_exists($model, FALSE)) - { - foreach ($this->_ci_model_paths as $mod_path) - { - if ( ! file_exists($mod_path.'models/'.$path.$model.'.php')) - { - continue; - } - - require_once($mod_path.'models/'.$path.$model.'.php'); - if ( ! class_exists($model, FALSE)) - { - throw new RuntimeException($mod_path."models/".$path.$model.".php exists, but doesn't declare class ".$model); - } - - break; - } - - if ( ! class_exists($model, FALSE)) - { - throw new RuntimeException('Unable to locate the model you have specified: '.$model); - } - } - elseif ( ! is_subclass_of($model, 'CI_Model')) - { - throw new RuntimeException("Class ".$model." already exists and doesn't extend CI_Model"); - } - - $this->_ci_models[] = $name; - $model = new $model(); - $CI->$name = $model; - log_message('info', 'Model "'.get_class($model).'" initialized'); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Database Loader - * - * @param mixed $params Database configuration options - * @param bool $return Whether to return the database object - * @param bool $query_builder Whether to enable Query Builder - * (overrides the configuration setting) - * - * @return object|bool Database object if $return is set to TRUE, - * FALSE on failure, CI_Loader instance in any other case - */ - public function database($params = '', $return = FALSE, $query_builder = NULL) - { - // Grab the super object - $CI =& get_instance(); - - // Do we even need to load the database class? - if ($return === FALSE && $query_builder === NULL && isset($CI->db) && is_object($CI->db) && ! empty($CI->db->conn_id)) - { - return FALSE; - } - - require_once(BASEPATH.'database/DB.php'); - - if ($return === TRUE) - { - return DB($params, $query_builder); - } - - // Initialize the db variable. Needed to prevent - // reference errors with some configurations - $CI->db = ''; - - // Load the DB class - $CI->db =& DB($params, $query_builder); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Load the Database Utilities Class - * - * @param object $db Database object - * @param bool $return Whether to return the DB Utilities class object or not - * @return object - */ - public function dbutil($db = NULL, $return = FALSE) - { - $CI =& get_instance(); - - if ( ! is_object($db) OR ! ($db instanceof CI_DB)) - { - class_exists('CI_DB', FALSE) OR $this->database(); - $db =& $CI->db; - } - - require_once(BASEPATH.'database/DB_utility.php'); - require_once(BASEPATH.'database/drivers/'.$db->dbdriver.'/'.$db->dbdriver.'_utility.php'); - $class = 'CI_DB_'.$db->dbdriver.'_utility'; - - if ($return === TRUE) - { - return new $class($db); - } - - $CI->dbutil = new $class($db); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Load the Database Forge Class - * - * @param object $db Database object - * @param bool $return Whether to return the DB Forge class object or not - * @return object - */ - public function dbforge($db = NULL, $return = FALSE) - { - $CI =& get_instance(); - if ( ! is_object($db) OR ! ($db instanceof CI_DB)) - { - class_exists('CI_DB', FALSE) OR $this->database(); - $db =& $CI->db; - } - - require_once(BASEPATH.'database/DB_forge.php'); - require_once(BASEPATH.'database/drivers/'.$db->dbdriver.'/'.$db->dbdriver.'_forge.php'); - - if ( ! empty($db->subdriver)) - { - $driver_path = BASEPATH.'database/drivers/'.$db->dbdriver.'/subdrivers/'.$db->dbdriver.'_'.$db->subdriver.'_forge.php'; - if (file_exists($driver_path)) - { - require_once($driver_path); - $class = 'CI_DB_'.$db->dbdriver.'_'.$db->subdriver.'_forge'; - } - } - else - { - $class = 'CI_DB_'.$db->dbdriver.'_forge'; - } - - if ($return === TRUE) - { - return new $class($db); - } - - $CI->dbforge = new $class($db); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * View Loader - * - * Loads "view" files. - * - * @param string $view View name - * @param array $vars An associative array of data - * to be extracted for use in the view - * @param bool $return Whether to return the view output - * or leave it to the Output class - * @return object|string - */ - public function view($view, $vars = array(), $return = FALSE) - { - return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_prepare_view_vars($vars), '_ci_return' => $return)); - } - - // -------------------------------------------------------------------- - - /** - * Generic File Loader - * - * @param string $path File path - * @param bool $return Whether to return the file output - * @return object|string - */ - public function file($path, $return = FALSE) - { - return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return)); - } - - // -------------------------------------------------------------------- - - /** - * Set Variables - * - * Once variables are set they become available within - * the controller class and its "view" files. - * - * @param array|object|string $vars - * An associative array or object containing values - * to be set, or a value's name if string - * @param string $val Value to set, only used if $vars is a string - * @return object - */ - public function vars($vars, $val = '') - { - $vars = is_string($vars) - ? array($vars => $val) - : $this->_ci_prepare_view_vars($vars); - - foreach ($vars as $key => $val) - { - $this->_ci_cached_vars[$key] = $val; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Clear Cached Variables - * - * Clears the cached variables. - * - * @return CI_Loader - */ - public function clear_vars() - { - $this->_ci_cached_vars = array(); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Get Variable - * - * Check if a variable is set and retrieve it. - * - * @param string $key Variable name - * @return mixed The variable or NULL if not found - */ - public function get_var($key) - { - return isset($this->_ci_cached_vars[$key]) ? $this->_ci_cached_vars[$key] : NULL; - } - - // -------------------------------------------------------------------- - - /** - * Get Variables - * - * Retrieves all loaded variables. - * - * @return array - */ - public function get_vars() - { - return $this->_ci_cached_vars; - } - - // -------------------------------------------------------------------- - - /** - * Helper Loader - * - * @param string|string[] $helpers Helper name(s) - * @return object - */ - public function helper($helpers = array()) - { - is_array($helpers) OR $helpers = array($helpers); - foreach ($helpers as &$helper) - { - $filename = basename($helper); - $filepath = ($filename === $helper) ? '' : substr($helper, 0, strlen($helper) - strlen($filename)); - $filename = strtolower(preg_replace('#(_helper)?(\.php)?$#i', '', $filename)).'_helper'; - $helper = $filepath.$filename; - - if (isset($this->_ci_helpers[$helper])) - { - continue; - } - - // Is this a helper extension request? - $ext_helper = config_item('subclass_prefix').$filename; - $ext_loaded = FALSE; - foreach ($this->_ci_helper_paths as $path) - { - if (file_exists($path.'helpers/'.$ext_helper.'.php')) - { - include_once($path.'helpers/'.$ext_helper.'.php'); - $ext_loaded = TRUE; - } - } - - // If we have loaded extensions - check if the base one is here - if ($ext_loaded === TRUE) - { - $base_helper = BASEPATH.'helpers/'.$helper.'.php'; - if ( ! file_exists($base_helper)) - { - show_error('Unable to load the requested file: helpers/'.$helper.'.php'); - } - - include_once($base_helper); - $this->_ci_helpers[$helper] = TRUE; - log_message('info', 'Helper loaded: '.$helper); - continue; - } - - // No extensions found ... try loading regular helpers and/or overrides - foreach ($this->_ci_helper_paths as $path) - { - if (file_exists($path.'helpers/'.$helper.'.php')) - { - include_once($path.'helpers/'.$helper.'.php'); - - $this->_ci_helpers[$helper] = TRUE; - log_message('info', 'Helper loaded: '.$helper); - break; - } - } - - // unable to load the helper - if ( ! isset($this->_ci_helpers[$helper])) - { - show_error('Unable to load the requested file: helpers/'.$helper.'.php'); - } - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Load Helpers - * - * An alias for the helper() method in case the developer has - * written the plural form of it. - * - * @uses CI_Loader::helper() - * @param string|string[] $helpers Helper name(s) - * @return object - */ - public function helpers($helpers = array()) - { - return $this->helper($helpers); - } - - // -------------------------------------------------------------------- - - /** - * Language Loader - * - * Loads language files. - * - * @param string|string[] $files List of language file names to load - * @param string Language name - * @return object - */ - public function language($files, $lang = '') - { - get_instance()->lang->load($files, $lang); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Config Loader - * - * Loads a config file (an alias for CI_Config::load()). - * - * @uses CI_Config::load() - * @param string $file Configuration file name - * @param bool $use_sections Whether configuration values should be loaded into their own section - * @param bool $fail_gracefully Whether to just return FALSE or display an error message - * @return bool TRUE if the file was loaded correctly or FALSE on failure - */ - public function config($file, $use_sections = FALSE, $fail_gracefully = FALSE) - { - return get_instance()->config->load($file, $use_sections, $fail_gracefully); - } - - // -------------------------------------------------------------------- - - /** - * Driver Loader - * - * Loads a driver library. - * - * @param string|string[] $library Driver name(s) - * @param array $params Optional parameters to pass to the driver - * @param string $object_name An optional object name to assign to - * - * @return object|bool Object or FALSE on failure if $library is a string - * and $object_name is set. CI_Loader instance otherwise. - */ - public function driver($library, $params = NULL, $object_name = NULL) - { - if (is_array($library)) - { - foreach ($library as $key => $value) - { - if (is_int($key)) - { - $this->driver($value, $params); - } - else - { - $this->driver($key, $params, $value); - } - } - - return $this; - } - elseif (empty($library)) - { - return FALSE; - } - - if ( ! class_exists('CI_Driver_Library', FALSE)) - { - // We aren't instantiating an object here, just making the base class available - require BASEPATH.'libraries/Driver.php'; - } - - // We can save the loader some time since Drivers will *always* be in a subfolder, - // and typically identically named to the library - if ( ! strpos($library, '/')) - { - $library = ucfirst($library).'/'.$library; - } - - return $this->library($library, $params, $object_name); - } - - // -------------------------------------------------------------------- - - /** - * Add Package Path - * - * Prepends a parent path to the library, model, helper and config - * path arrays. - * - * @see CI_Loader::$_ci_library_paths - * @see CI_Loader::$_ci_model_paths - * @see CI_Loader::$_ci_helper_paths - * @see CI_Config::$_config_paths - * - * @param string $path Path to add - * @param bool $view_cascade (default: TRUE) - * @return object - */ - public function add_package_path($path, $view_cascade = TRUE) - { - $path = rtrim($path, '/').'/'; - - array_unshift($this->_ci_library_paths, $path); - array_unshift($this->_ci_model_paths, $path); - array_unshift($this->_ci_helper_paths, $path); - - $this->_ci_view_paths = array($path.'views/' => $view_cascade) + $this->_ci_view_paths; - - // Add config file path - $config =& $this->_ci_get_component('config'); - $config->_config_paths[] = $path; - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Get Package Paths - * - * Return a list of all package paths. - * - * @param bool $include_base Whether to include BASEPATH (default: FALSE) - * @return array - */ - public function get_package_paths($include_base = FALSE) - { - return ($include_base === TRUE) ? $this->_ci_library_paths : $this->_ci_model_paths; - } - - // -------------------------------------------------------------------- - - /** - * Remove Package Path - * - * Remove a path from the library, model, helper and/or config - * path arrays if it exists. If no path is provided, the most recently - * added path will be removed removed. - * - * @param string $path Path to remove - * @return object - */ - public function remove_package_path($path = '') - { - $config =& $this->_ci_get_component('config'); - - if ($path === '') - { - array_shift($this->_ci_library_paths); - array_shift($this->_ci_model_paths); - array_shift($this->_ci_helper_paths); - array_shift($this->_ci_view_paths); - array_pop($config->_config_paths); - } - else - { - $path = rtrim($path, '/').'/'; - foreach (array('_ci_library_paths', '_ci_model_paths', '_ci_helper_paths') as $var) - { - if (($key = array_search($path, $this->{$var})) !== FALSE) - { - unset($this->{$var}[$key]); - } - } - - if (isset($this->_ci_view_paths[$path.'views/'])) - { - unset($this->_ci_view_paths[$path.'views/']); - } - - if (($key = array_search($path, $config->_config_paths)) !== FALSE) - { - unset($config->_config_paths[$key]); - } - } - - // make sure the application default paths are still in the array - $this->_ci_library_paths = array_unique(array_merge($this->_ci_library_paths, array(APPPATH, BASEPATH))); - $this->_ci_helper_paths = array_unique(array_merge($this->_ci_helper_paths, array(APPPATH, BASEPATH))); - $this->_ci_model_paths = array_unique(array_merge($this->_ci_model_paths, array(APPPATH))); - $this->_ci_view_paths = array_merge($this->_ci_view_paths, array(APPPATH.'views/' => TRUE)); - $config->_config_paths = array_unique(array_merge($config->_config_paths, array(APPPATH))); - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Internal CI Data Loader - * - * Used to load views and files. - * - * Variables are prefixed with _ci_ to avoid symbol collision with - * variables made available to view files. - * - * @used-by CI_Loader::view() - * @used-by CI_Loader::file() - * @param array $_ci_data Data to load - * @return object - */ - protected function _ci_load($_ci_data) - { - // Set the default data variables - foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val) - { - $$_ci_val = isset($_ci_data[$_ci_val]) ? $_ci_data[$_ci_val] : FALSE; - } - - $file_exists = FALSE; - - // Set the path to the requested file - if (is_string($_ci_path) && $_ci_path !== '') - { - $_ci_x = explode('/', $_ci_path); - $_ci_file = end($_ci_x); - } - else - { - $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION); - $_ci_file = ($_ci_ext === '') ? $_ci_view.'.php' : $_ci_view; - - foreach ($this->_ci_view_paths as $_ci_view_file => $cascade) - { - if (file_exists($_ci_view_file.$_ci_file)) - { - $_ci_path = $_ci_view_file.$_ci_file; - $file_exists = TRUE; - break; - } - - if ( ! $cascade) - { - break; - } - } - } - - if ( ! $file_exists && ! file_exists($_ci_path)) - { - show_error('Unable to load the requested file: '.$_ci_file); - } - - // This allows anything loaded using $this->load (views, files, etc.) - // to become accessible from within the Controller and Model functions. - $_ci_CI =& get_instance(); - foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var) - { - if ( ! isset($this->$_ci_key)) - { - $this->$_ci_key =& $_ci_CI->$_ci_key; - } - } - - /* - * Extract and cache variables - * - * You can either set variables using the dedicated $this->load->vars() - * function or via the second parameter of this function. We'll merge - * the two types and cache them so that views that are embedded within - * other views can have access to these variables. - */ - empty($_ci_vars) OR $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars); - extract($this->_ci_cached_vars); - - /* - * Buffer the output - * - * We buffer the output for two reasons: - * 1. Speed. You get a significant speed boost. - * 2. So that the final rendered template can be post-processed by - * the output class. Why do we need post processing? For one thing, - * in order to show the elapsed page load time. Unless we can - * intercept the content right before it's sent to the browser and - * then stop the timer it won't be accurate. - */ - ob_start(); - - // If the PHP installation does not support short tags we'll - // do a little string replacement, changing the short tags - // to standard PHP echo statements. - if ( ! is_php('5.4') && ! ini_get('short_open_tag') && config_item('rewrite_short_tags') === TRUE) - { - echo eval('?>'.preg_replace('/;*\s*\?>/', '; ?>', str_replace('=', ' $this->_ci_ob_level + 1) - { - ob_end_flush(); - } - else - { - $_ci_CI->output->append_output(ob_get_contents()); - @ob_end_clean(); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Internal CI Library Loader - * - * @used-by CI_Loader::library() - * @uses CI_Loader::_ci_init_library() - * - * @param string $class Class name to load - * @param mixed $params Optional parameters to pass to the class constructor - * @param string $object_name Optional object name to assign to - * @return void - */ - protected function _ci_load_library($class, $params = NULL, $object_name = NULL) - { - // Get the class name, and while we're at it trim any slashes. - // The directory path can be included as part of the class name, - // but we don't want a leading slash - $class = str_replace('.php', '', trim($class, '/')); - - // Was the path included with the class name? - // We look for a slash to determine this - if (($last_slash = strrpos($class, '/')) !== FALSE) - { - // Extract the path - $subdir = substr($class, 0, ++$last_slash); - - // Get the filename from the path - $class = substr($class, $last_slash); - } - else - { - $subdir = ''; - } - - $class = ucfirst($class); - - // Is this a stock library? There are a few special conditions if so ... - if (file_exists(BASEPATH.'libraries/'.$subdir.$class.'.php')) - { - return $this->_ci_load_stock_library($class, $subdir, $params, $object_name); - } - - // Safety: Was the class already loaded by a previous call? - if (class_exists($class, FALSE)) - { - $property = $object_name; - if (empty($property)) - { - $property = strtolower($class); - isset($this->_ci_varmap[$property]) && $property = $this->_ci_varmap[$property]; - } - - $CI =& get_instance(); - if (isset($CI->$property)) - { - log_message('debug', $class.' class already loaded. Second attempt ignored.'); - return; - } - - return $this->_ci_init_library($class, '', $params, $object_name); - } - - // Let's search for the requested library file and load it. - foreach ($this->_ci_library_paths as $path) - { - // BASEPATH has already been checked for - if ($path === BASEPATH) - { - continue; - } - - $filepath = $path.'libraries/'.$subdir.$class.'.php'; - // Does the file exist? No? Bummer... - if ( ! file_exists($filepath)) - { - continue; - } - - include_once($filepath); - return $this->_ci_init_library($class, '', $params, $object_name); - } - - // One last attempt. Maybe the library is in a subdirectory, but it wasn't specified? - if ($subdir === '') - { - return $this->_ci_load_library($class.'/'.$class, $params, $object_name); - } - - // If we got this far we were unable to find the requested class. - log_message('error', 'Unable to load the requested class: '.$class); - show_error('Unable to load the requested class: '.$class); - } - - // -------------------------------------------------------------------- - - /** - * Internal CI Stock Library Loader - * - * @used-by CI_Loader::_ci_load_library() - * @uses CI_Loader::_ci_init_library() - * - * @param string $library_name Library name to load - * @param string $file_path Path to the library filename, relative to libraries/ - * @param mixed $params Optional parameters to pass to the class constructor - * @param string $object_name Optional object name to assign to - * @return void - */ - protected function _ci_load_stock_library($library_name, $file_path, $params, $object_name) - { - $prefix = 'CI_'; - - if (class_exists($prefix.$library_name, FALSE)) - { - if (class_exists(config_item('subclass_prefix').$library_name, FALSE)) - { - $prefix = config_item('subclass_prefix'); - } - - $property = $object_name; - if (empty($property)) - { - $property = strtolower($library_name); - isset($this->_ci_varmap[$property]) && $property = $this->_ci_varmap[$property]; - } - - $CI =& get_instance(); - if ( ! isset($CI->$property)) - { - return $this->_ci_init_library($library_name, $prefix, $params, $object_name); - } - - log_message('debug', $library_name.' class already loaded. Second attempt ignored.'); - return; - } - - $paths = $this->_ci_library_paths; - array_pop($paths); // BASEPATH - array_pop($paths); // APPPATH (needs to be the first path checked) - array_unshift($paths, APPPATH); - - foreach ($paths as $path) - { - if (file_exists($path = $path.'libraries/'.$file_path.$library_name.'.php')) - { - // Override - include_once($path); - if (class_exists($prefix.$library_name, FALSE)) - { - return $this->_ci_init_library($library_name, $prefix, $params, $object_name); - } - - log_message('debug', $path.' exists, but does not declare '.$prefix.$library_name); - } - } - - include_once(BASEPATH.'libraries/'.$file_path.$library_name.'.php'); - - // Check for extensions - $subclass = config_item('subclass_prefix').$library_name; - foreach ($paths as $path) - { - if (file_exists($path = $path.'libraries/'.$file_path.$subclass.'.php')) - { - include_once($path); - if (class_exists($subclass, FALSE)) - { - $prefix = config_item('subclass_prefix'); - break; - } - - log_message('debug', $path.' exists, but does not declare '.$subclass); - } - } - - return $this->_ci_init_library($library_name, $prefix, $params, $object_name); - } - - // -------------------------------------------------------------------- - - /** - * Internal CI Library Instantiator - * - * @used-by CI_Loader::_ci_load_stock_library() - * @used-by CI_Loader::_ci_load_library() - * - * @param string $class Class name - * @param string $prefix Class name prefix - * @param array|null|bool $config Optional configuration to pass to the class constructor: - * FALSE to skip; - * NULL to search in config paths; - * array containing configuration data - * @param string $object_name Optional object name to assign to - * @return void - */ - protected function _ci_init_library($class, $prefix, $config = FALSE, $object_name = NULL) - { - // Is there an associated config file for this class? Note: these should always be lowercase - if ($config === NULL) - { - // Fetch the config paths containing any package paths - $config_component = $this->_ci_get_component('config'); - - if (is_array($config_component->_config_paths)) - { - $found = FALSE; - foreach ($config_component->_config_paths as $path) - { - // We test for both uppercase and lowercase, for servers that - // are case-sensitive with regard to file names. Load global first, - // override with environment next - if (file_exists($path.'config/'.strtolower($class).'.php')) - { - include($path.'config/'.strtolower($class).'.php'); - $found = TRUE; - } - elseif (file_exists($path.'config/'.ucfirst(strtolower($class)).'.php')) - { - include($path.'config/'.ucfirst(strtolower($class)).'.php'); - $found = TRUE; - } - - if (file_exists($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php')) - { - include($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php'); - $found = TRUE; - } - elseif (file_exists($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php')) - { - include($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php'); - $found = TRUE; - } - - // Break on the first found configuration, thus package - // files are not overridden by default paths - if ($found === TRUE) - { - break; - } - } - } - } - - $class_name = $prefix.$class; - - // Is the class name valid? - if ( ! class_exists($class_name, FALSE)) - { - log_message('error', 'Non-existent class: '.$class_name); - show_error('Non-existent class: '.$class_name); - } - - // Set the variable name we will assign the class to - // Was a custom class name supplied? If so we'll use it - if (empty($object_name)) - { - $object_name = strtolower($class); - if (isset($this->_ci_varmap[$object_name])) - { - $object_name = $this->_ci_varmap[$object_name]; - } - } - - // Don't overwrite existing properties - $CI =& get_instance(); - if (isset($CI->$object_name)) - { - if ($CI->$object_name instanceof $class_name) - { - log_message('debug', $class_name." has already been instantiated as '".$object_name."'. Second attempt aborted."); - return; - } - - show_error("Resource '".$object_name."' already exists and is not a ".$class_name." instance."); - } - - // Save the class name and object name - $this->_ci_classes[$object_name] = $class; - - // Instantiate the class - $CI->$object_name = isset($config) - ? new $class_name($config) - : new $class_name(); - } - - // -------------------------------------------------------------------- - - /** - * CI Autoloader - * - * Loads component listed in the config/autoload.php file. - * - * @used-by CI_Loader::initialize() - * @return void - */ - protected function _ci_autoloader() - { - if (file_exists(APPPATH.'config/autoload.php')) - { - include(APPPATH.'config/autoload.php'); - } - - if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php')) - { - include(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'); - } - - if ( ! isset($autoload)) - { - return; - } - - // Autoload packages - if (isset($autoload['packages'])) - { - foreach ($autoload['packages'] as $package_path) - { - $this->add_package_path($package_path); - } - } - - // Load any custom config file - if (count($autoload['config']) > 0) - { - foreach ($autoload['config'] as $val) - { - $this->config($val); - } - } - - // Autoload helpers and languages - foreach (array('helper', 'language') as $type) - { - if (isset($autoload[$type]) && count($autoload[$type]) > 0) - { - $this->$type($autoload[$type]); - } - } - - // Autoload drivers - if (isset($autoload['drivers'])) - { - $this->driver($autoload['drivers']); - } - - // Load libraries - if (isset($autoload['libraries']) && count($autoload['libraries']) > 0) - { - // Load the database driver. - if (in_array('database', $autoload['libraries'])) - { - $this->database(); - $autoload['libraries'] = array_diff($autoload['libraries'], array('database')); - } - - // Load all other libraries - $this->library($autoload['libraries']); - } - - // Autoload models - if (isset($autoload['model'])) - { - $this->model($autoload['model']); - } - } - - // -------------------------------------------------------------------- - - /** - * Prepare variables for _ci_vars, to be later extract()-ed inside views - * - * Converts objects to associative arrays and filters-out internal - * variable names (i.e. keys prefixed with '_ci_'). - * - * @param mixed $vars - * @return array - */ - protected function _ci_prepare_view_vars($vars) - { - if ( ! is_array($vars)) - { - $vars = is_object($vars) - ? get_object_vars($vars) - : array(); - } - - foreach (array_keys($vars) as $key) - { - if (strncmp($key, '_ci_', 4) === 0) - { - unset($vars[$key]); - } - } - - return $vars; - } - - // -------------------------------------------------------------------- - - /** - * CI Component getter - * - * Get a reference to a specific library or model. - * - * @param string $component Component name - * @return bool - */ - protected function &_ci_get_component($component) - { - $CI =& get_instance(); - return $CI->$component; - } -} diff --git a/system/core/Log.php b/system/core/Log.php deleted file mode 100644 index a2b464c..0000000 --- a/system/core/Log.php +++ /dev/null @@ -1,296 +0,0 @@ - 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 .= "\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); - } -} diff --git a/system/core/Model.php b/system/core/Model.php deleted file mode 100644 index dd11dd2..0000000 --- a/system/core/Model.php +++ /dev/null @@ -1,76 +0,0 @@ -$key; - } - -} diff --git a/system/core/Output.php b/system/core/Output.php deleted file mode 100644 index 3cda062..0000000 --- a/system/core/Output.php +++ /dev/null @@ -1,842 +0,0 @@ -_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