summaryrefslogtreecommitdiffstats
path: root/system
diff options
context:
space:
mode:
Diffstat (limited to 'system')
-rw-r--r--system/core/CodeIgniter.php89
-rw-r--r--system/core/Common.php14
-rw-r--r--system/core/Config.php16
-rw-r--r--system/core/Exceptions.php12
-rw-r--r--system/core/Hooks.php6
-rw-r--r--system/core/Input.php285
-rw-r--r--system/core/Loader.php72
-rw-r--r--system/core/Log.php29
-rw-r--r--system/core/Model.php8
-rw-r--r--system/core/Output.php19
-rw-r--r--system/core/Router.php47
-rw-r--r--system/core/Security.php43
-rw-r--r--system/core/URI.php122
-rw-r--r--system/core/Utf8.php14
-rw-r--r--system/core/compat/hash.php6
-rw-r--r--system/core/compat/index.html2
-rw-r--r--system/core/compat/mbstring.php6
-rw-r--r--system/core/compat/password.php10
-rw-r--r--system/core/compat/standard.php50
-rw-r--r--system/core/index.html2
-rw-r--r--system/database/DB.php55
-rw-r--r--system/database/DB_driver.php101
-rw-r--r--system/database/DB_forge.php46
-rw-r--r--system/database/DB_query_builder.php154
-rw-r--r--system/database/DB_utility.php14
-rw-r--r--system/database/drivers/cubrid/index.html2
-rw-r--r--system/database/drivers/ibase/index.html2
-rw-r--r--system/database/drivers/index.html2
-rw-r--r--system/database/drivers/mssql/index.html2
-rw-r--r--system/database/drivers/mssql/mssql_driver.php14
-rw-r--r--system/database/drivers/mysql/index.html2
-rw-r--r--system/database/drivers/mysql/mysql_driver.php57
-rw-r--r--system/database/drivers/mysqli/index.html2
-rw-r--r--system/database/drivers/mysqli/mysqli_driver.php20
-rw-r--r--system/database/drivers/oci8/index.html2
-rw-r--r--system/database/drivers/oci8/oci8_driver.php165
-rw-r--r--system/database/drivers/oci8/oci8_result.php61
-rw-r--r--system/database/drivers/odbc/index.html2
-rw-r--r--system/database/drivers/pdo/index.html2
-rw-r--r--system/database/drivers/pdo/subdrivers/index.html2
-rw-r--r--system/database/drivers/postgre/index.html2
-rw-r--r--system/database/drivers/postgre/postgre_driver.php22
-rw-r--r--system/database/drivers/sqlite/index.html11
-rw-r--r--system/database/drivers/sqlite/sqlite_driver.php331
-rw-r--r--system/database/drivers/sqlite/sqlite_forge.php206
-rw-r--r--system/database/drivers/sqlite/sqlite_result.php165
-rw-r--r--system/database/drivers/sqlite/sqlite_utility.php62
-rw-r--r--system/database/drivers/sqlite3/index.html2
-rw-r--r--system/database/drivers/sqlsrv/index.html2
-rw-r--r--system/database/index.html2
-rw-r--r--system/fonts/index.html2
-rw-r--r--system/helpers/captcha_helper.php93
-rw-r--r--system/helpers/cookie_helper.php9
-rw-r--r--system/helpers/date_helper.php106
-rw-r--r--system/helpers/download_helper.php54
-rw-r--r--system/helpers/email_helper.php85
-rw-r--r--system/helpers/file_helper.php25
-rw-r--r--system/helpers/form_helper.php22
-rw-r--r--system/helpers/html_helper.php61
-rw-r--r--system/helpers/index.html2
-rw-r--r--system/helpers/inflector_helper.php39
-rw-r--r--system/helpers/security_helper.php24
-rw-r--r--system/helpers/smiley_helper.php256
-rw-r--r--system/helpers/string_helper.php51
-rw-r--r--system/helpers/url_helper.php21
-rw-r--r--system/index.html2
-rw-r--r--system/language/english/form_validation_lang.php1
-rw-r--r--system/language/english/imglib_lang.php1
-rw-r--r--system/language/english/index.html2
-rw-r--r--system/language/index.html2
-rw-r--r--system/libraries/Cache/Cache.php13
-rw-r--r--system/libraries/Cache/drivers/Cache_apcu.php219
-rw-r--r--system/libraries/Cache/drivers/Cache_memcached.php18
-rw-r--r--system/libraries/Cache/drivers/Cache_redis.php90
-rw-r--r--system/libraries/Cache/drivers/index.html2
-rw-r--r--system/libraries/Cache/index.html2
-rw-r--r--system/libraries/Cart.php568
-rw-r--r--system/libraries/Email.php249
-rw-r--r--system/libraries/Encrypt.php522
-rw-r--r--system/libraries/Encryption.php7
-rw-r--r--system/libraries/Form_validation.php153
-rw-r--r--system/libraries/Image_lib.php40
-rw-r--r--system/libraries/Javascript.php857
-rw-r--r--system/libraries/Javascript/Jquery.php1077
-rw-r--r--system/libraries/Javascript/index.html11
-rw-r--r--system/libraries/Pagination.php8
-rw-r--r--system/libraries/Session/Session.php2
-rw-r--r--system/libraries/Session/SessionHandlerInterface.php60
-rw-r--r--system/libraries/Session/drivers/Session_redis_driver.php70
-rw-r--r--system/libraries/Session/drivers/index.html2
-rw-r--r--system/libraries/Session/index.html2
-rw-r--r--system/libraries/Table.php1
-rw-r--r--system/libraries/Upload.php8
-rw-r--r--system/libraries/Xmlrpc.php8
-rw-r--r--system/libraries/Xmlrpcs.php4
-rw-r--r--system/libraries/Zip.php7
-rw-r--r--system/libraries/index.html2
97 files changed, 1272 insertions, 5952 deletions
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php
index 2a61a32f7..87dd868f9 100644
--- a/system/core/CodeIgniter.php
+++ b/system/core/CodeIgniter.php
@@ -56,7 +56,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @var string
*
*/
- const CI_VERSION = '3.1.13-dev';
+ const CI_VERSION = '3.2.0-dev';
/*
* ------------------------------------------------------
@@ -80,57 +80,6 @@ defined('BASEPATH') OR exit('No direct script access allowed');
*/
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
@@ -195,20 +144,6 @@ if ( ! is_php('5.4'))
/*
* ------------------------------------------------------
- * Instantiate the hooks class
- * ------------------------------------------------------
- */
- $EXT =& load_class('Hooks', 'core');
-
-/*
- * ------------------------------------------------------
- * Is there a "pre_system" hook?
- * ------------------------------------------------------
- */
- $EXT->call_hook('pre_system');
-
-/*
- * ------------------------------------------------------
* Instantiate the config class
* ------------------------------------------------------
*
@@ -230,6 +165,20 @@ if ( ! is_php('5.4'))
/*
* ------------------------------------------------------
+ * Instantiate the hooks class
+ * ------------------------------------------------------
+ */
+ $EXT =& load_class('Hooks', 'core', $CFG);
+
+/*
+ * ------------------------------------------------------
+ * Is there a "pre_system" hook?
+ * ------------------------------------------------------
+ */
+ $EXT->call_hook('pre_system');
+
+/*
+ * ------------------------------------------------------
* Important charset-related stuff
* ------------------------------------------------------
*
@@ -295,14 +244,14 @@ if ( ! is_php('5.4'))
* Instantiate the UTF-8 class
* ------------------------------------------------------
*/
- $UNI =& load_class('Utf8', 'core');
+ $UNI =& load_class('Utf8', 'core', $charset);
/*
* ------------------------------------------------------
* Instantiate the URI class
* ------------------------------------------------------
*/
- $URI =& load_class('URI', 'core');
+ $URI =& load_class('URI', 'core', $CFG);
/*
* ------------------------------------------------------
@@ -333,14 +282,14 @@ if ( ! is_php('5.4'))
* Load the security class for xss and csrf support
* -----------------------------------------------------
*/
- $SEC =& load_class('Security', 'core');
+ $SEC =& load_class('Security', 'core', $charset);
/*
* ------------------------------------------------------
* Load the Input class and sanitize globals
* ------------------------------------------------------
*/
- $IN =& load_class('Input', 'core');
+ $IN =& load_class('Input', 'core', $SEC);
/*
* ------------------------------------------------------
diff --git a/system/core/Common.php b/system/core/Common.php
index a56cb1464..c7bb34549 100644
--- a/system/core/Common.php
+++ b/system/core/Common.php
@@ -82,8 +82,7 @@ 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.
+ * the file, based on the read-only attribute.
*
* @link https://bugs.php.net/bug.php?id=54709
* @param string
@@ -91,8 +90,8 @@ if ( ! function_exists('is_really_writable'))
*/
function is_really_writable($file)
{
- // If we're on a Unix server with safe_mode off we call is_writable
- if (DIRECTORY_SEPARATOR === '/' && (is_php('5.4') OR ! ini_get('safe_mode')))
+ // If we're on a UNIX-like server, just is_writable()
+ if (DIRECTORY_SEPARATOR === '/')
{
return is_writable($file);
}
@@ -500,6 +499,7 @@ if ( ! function_exists('set_status_header'))
$stati = array(
100 => 'Continue',
101 => 'Switching Protocols',
+ 103 => 'Early Hints',
200 => 'OK',
201 => 'Created',
@@ -508,6 +508,7 @@ if ( ! function_exists('set_status_header'))
204 => 'No Content',
205 => 'Reset Content',
206 => 'Partial Content',
+ 207 => 'Multi-Status',
300 => 'Multiple Choices',
301 => 'Moved Permanently',
@@ -516,6 +517,7 @@ if ( ! function_exists('set_status_header'))
304 => 'Not Modified',
305 => 'Use Proxy',
307 => 'Temporary Redirect',
+ 308 => 'Permanent Redirect',
400 => 'Bad Request',
401 => 'Unauthorized',
@@ -535,11 +537,13 @@ if ( ! function_exists('set_status_header'))
415 => 'Unsupported Media Type',
416 => 'Requested Range Not Satisfiable',
417 => 'Expectation Failed',
+ 421 => 'Misdirected Request',
422 => 'Unprocessable Entity',
426 => 'Upgrade Required',
428 => 'Precondition Required',
429 => 'Too Many Requests',
431 => 'Request Header Fields Too Large',
+ 451 => 'Unavailable For Legal Reasons',
500 => 'Internal Server Error',
501 => 'Not Implemented',
@@ -626,7 +630,7 @@ if ( ! function_exists('_error_handler'))
// 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
+ // default error handling. See https://secure.php.net/manual/en/errorfunc.constants.php
if ($is_error)
{
exit(1); // EXIT_ERROR
diff --git a/system/core/Config.php b/system/core/Config.php
index 2454a9d71..4efe1e1ec 100644
--- a/system/core/Config.php
+++ b/system/core/Config.php
@@ -170,7 +170,7 @@ class CI_Config {
$this->is_loaded[] = $file_path;
$config = NULL;
$loaded = TRUE;
- log_message('debug', 'Config file loaded: '.$file_path);
+ log_message('info', 'Config file loaded: '.$file_path);
}
}
@@ -352,20 +352,6 @@ class CI_Config {
// --------------------------------------------------------------------
/**
- * 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
diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php
index b1bc2dec5..7244f3f28 100644
--- a/system/core/Exceptions.php
+++ b/system/core/Exceptions.php
@@ -162,6 +162,10 @@ class CI_Exceptions {
{
$templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
}
+ else
+ {
+ $templates_path = rtrim($templates_path, '/\\').DIRECTORY_SEPARATOR;
+ }
if (is_cli())
{
@@ -195,6 +199,10 @@ class CI_Exceptions {
{
$templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
}
+ else
+ {
+ $templates_path = rtrim($templates_path, '/\\').DIRECTORY_SEPARATOR;
+ }
$message = $exception->getMessage();
if (empty($message))
@@ -241,6 +249,10 @@ class CI_Exceptions {
{
$templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
}
+ else
+ {
+ $templates_path = rtrim($templates_path, '/\\').DIRECTORY_SEPARATOR;
+ }
$severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity;
diff --git a/system/core/Hooks.php b/system/core/Hooks.php
index 2246bbcb6..20248aa8a 100644
--- a/system/core/Hooks.php
+++ b/system/core/Hooks.php
@@ -84,16 +84,16 @@ class CI_Hooks {
/**
* Class constructor
*
+ * @param CI_Config $config
* @return void
*/
- public function __construct()
+ public function __construct(CI_Config $config)
{
- $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)
+ if ($config->item('enable_hooks') === FALSE)
{
return;
}
diff --git a/system/core/Input.php b/system/core/Input.php
index eba5f67f0..59ca3e112 100644
--- a/system/core/Input.php
+++ b/system/core/Input.php
@@ -59,45 +59,6 @@ class CI_Input {
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
@@ -123,8 +84,15 @@ class CI_Input {
*/
protected $_input_stream;
+ /**
+ * CI_Security instance
+ *
+ * Used for the optional $xss_filter parameter that most
+ * getter methods have here.
+ *
+ * @var CI_Security
+ */
protected $security;
- protected $uni;
// --------------------------------------------------------------------
@@ -136,30 +104,9 @@ class CI_Input {
*
* @return void
*/
- public function __construct()
+ public function __construct(CI_Security &$security)
{
- $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();
- }
-
+ $this->security = $security;
log_message('info', 'Input Class Initialized');
}
@@ -175,10 +122,8 @@ class CI_Input {
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
- protected function _fetch_from_array(&$array, $index = NULL, $xss_clean = NULL)
+ protected function _fetch_from_array(&$array, $index = NULL, $xss_clean = FALSE)
{
- 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);
@@ -238,7 +183,7 @@ class CI_Input {
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
- public function get($index = NULL, $xss_clean = NULL)
+ public function get($index = NULL, $xss_clean = FALSE)
{
return $this->_fetch_from_array($_GET, $index, $xss_clean);
}
@@ -252,7 +197,7 @@ class CI_Input {
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
- public function post($index = NULL, $xss_clean = NULL)
+ public function post($index = NULL, $xss_clean = FALSE)
{
return $this->_fetch_from_array($_POST, $index, $xss_clean);
}
@@ -266,11 +211,10 @@ class CI_Input {
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
- public function post_get($index, $xss_clean = NULL)
+ public function post_get($index, $xss_clean = FALSE)
{
- return isset($_POST[$index])
- ? $this->post($index, $xss_clean)
- : $this->get($index, $xss_clean);
+ $output = $this->post($index, $xss_clean);
+ return isset($output) ? $output : $this->get($index, $xss_clean);
}
// --------------------------------------------------------------------
@@ -282,11 +226,10 @@ class CI_Input {
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
- public function get_post($index, $xss_clean = NULL)
+ public function get_post($index, $xss_clean = FALSE)
{
- return isset($_GET[$index])
- ? $this->get($index, $xss_clean)
- : $this->post($index, $xss_clean);
+ $output = $this->get($index, $xss_clean);
+ return isset($output) ? $output : $this->post($index, $xss_clean);
}
// --------------------------------------------------------------------
@@ -298,7 +241,7 @@ class CI_Input {
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
- public function cookie($index = NULL, $xss_clean = NULL)
+ public function cookie($index = NULL, $xss_clean = FALSE)
{
return $this->_fetch_from_array($_COOKIE, $index, $xss_clean);
}
@@ -312,7 +255,7 @@ class CI_Input {
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
- public function server($index, $xss_clean = NULL)
+ public function server($index, $xss_clean = FALSE)
{
return $this->_fetch_from_array($_SERVER, $index, $xss_clean);
}
@@ -328,7 +271,7 @@ class CI_Input {
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
- public function input_stream($index = NULL, $xss_clean = NULL)
+ public function input_stream($index = NULL, $xss_clean = FALSE)
{
// 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.
@@ -361,7 +304,7 @@ class CI_Input {
* @param string $samesite SameSite attribute
* @return void
*/
- public function set_cookie($name, $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = NULL, $httponly = NULL, $samesite = NULL)
+ public function set_cookie($name, $value = '', $expire = 0, $domain = '', $path = '/', $prefix = '', $secure = NULL, $httponly = NULL, $samesite = NULL)
{
if (is_array($name))
{
@@ -398,9 +341,9 @@ class CI_Input {
? (bool) config_item('cookie_httponly')
: (bool) $httponly;
- if ( ! is_numeric($expire))
+ if ( ! is_numeric($expire) OR $expire < 0)
{
- $expire = time() - 86500;
+ $expire = 1;
}
else
{
@@ -621,7 +564,7 @@ class CI_Input {
*
* @return string|null User Agent string or NULL if it doesn't exist
*/
- public function user_agent($xss_clean = NULL)
+ public function user_agent($xss_clean = FALSE)
{
return $this->_fetch_from_array($_SERVER, 'HTTP_USER_AGENT', $xss_clean);
}
@@ -629,167 +572,6 @@ class CI_Input {
// --------------------------------------------------------------------
/**
- * 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
@@ -881,21 +663,6 @@ class CI_Input {
// --------------------------------------------------------------------
/**
- * 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
diff --git a/system/core/Loader.php b/system/core/Loader.php
index 9f0ae4159..b09f9e688 100644
--- a/system/core/Loader.php
+++ b/system/core/Loader.php
@@ -96,6 +96,13 @@ class CI_Loader {
protected $_ci_cached_vars = array();
/**
+ * Stack of variable arrays to provide nested _ci_load calls with all variables from parent calls
+ *
+ * @var array
+ */
+ protected $_ci_load_vars_stack = array();
+
+ /**
* List of loaded classes
*
* @var array
@@ -350,9 +357,10 @@ class CI_Loader {
throw new RuntimeException('Unable to locate the model you have specified: '.$model);
}
}
- elseif ( ! is_subclass_of($model, 'CI_Model'))
+
+ if ( ! is_subclass_of($model, 'CI_Model'))
{
- throw new RuntimeException("Class ".$model." already exists and doesn't extend CI_Model");
+ throw new RuntimeException("Class ".$model." doesn't extend CI_Model");
}
$this->_ci_models[] = $name;
@@ -369,19 +377,16 @@ class CI_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)
+ public function database($params = '', $return = FALSE)
{
// 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))
+ if ($return === FALSE && isset($CI->db) && is_object($CI->db) && ! empty($CI->db->conn_id))
{
return FALSE;
}
@@ -390,7 +395,7 @@ class CI_Loader {
if ($return === TRUE)
{
- return DB($params, $query_builder);
+ return DB($params);
}
// Initialize the db variable. Needed to prevent
@@ -398,7 +403,7 @@ class CI_Loader {
$CI->db = '';
// Load the DB class
- $CI->db =& DB($params, $query_builder);
+ $CI->db =& DB($params);
return $this;
}
@@ -935,17 +940,38 @@ class CI_Loader {
}
/*
- * Extract and cache variables
+ * Extract and stack 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.
+ * the two types so that loaded views and files have access to these
+ * variables.
+ * Additionally we want all subsequent nested _ci_load() calls embedded
+ * within the current file to 'inherit' all variables that are
+ * accessible to the current file. For this purpose we push the current
+ * variable configuration (_ci_vars) to the stack and remove it again
+ * after the file or view is completely loaded. Nested _ci_load() calls
+ * within the current file extend the stack with their variable
+ * configuration.
*/
- empty($_ci_vars) OR $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
- extract($this->_ci_cached_vars);
- /*
+ is_array($_ci_vars) OR $_ci_vars = array();
+
+ // Include the global cached vars into the current _ci_vars if needed
+ empty($this->_ci_cached_vars) OR $_ci_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
+
+ // Merge the last variable configuration from a parent _ci_load()
+ // call into the current _ci_vars
+ if ( ! empty($this->_ci_load_vars_stack))
+ {
+ $previous_variable_configuration = end($this->_ci_load_vars_stack);
+ $_ci_vars = array_merge($previous_variable_configuration, $_ci_vars);
+ }
+
+ array_push($this->_ci_load_vars_stack, $_ci_vars);
+ extract($_ci_vars);
+
+ /**
* Buffer the output
*
* We buffer the output for two reasons:
@@ -958,20 +984,12 @@ class CI_Loader {
*/
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('<?=', '<?php echo ', file_get_contents($_ci_path))));
- }
- else
- {
- include($_ci_path); // include() vs include_once() allows for multiple views with the same name
- }
-
+ include($_ci_path); // include() vs include_once() allows for multiple views with the same name
log_message('info', 'File loaded: '.$_ci_path);
+ // Remove current _ci_vars from stack
+ array_pop($this->_ci_load_vars_stack);
+
// Return the file data if requested
if ($_ci_return === TRUE)
{
diff --git a/system/core/Log.php b/system/core/Log.php
index ca3e38a7f..99642e0c6 100644
--- a/system/core/Log.php
+++ b/system/core/Log.php
@@ -57,6 +57,13 @@ class CI_Log {
protected $_log_path;
/**
+ * Log filename
+ *
+ * @var string
+ */
+ protected $_log_filename;
+
+ /**
* File permissions
*
* @var int
@@ -85,13 +92,6 @@ class CI_Log {
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
@@ -125,9 +125,11 @@ class CI_Log {
isset(self::$func_overload) OR self::$func_overload = ( ! is_php('8.0') && 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';
+ $this->_log_path = ($config['log_path'] !== '')
+ ? rtrim($config['log_path'], '/\\').DIRECTORY_SEPARATOR : APPPATH.'logs'.DIRECTORY_SEPARATOR;
+
+ $this->_log_filename = (isset($config['log_filename']) && $config['log_filename'] !== '')
+ ? $config['log_filename'] : 'log-'.date('Y-m-d').'.php';
file_exists($this->_log_path) OR mkdir($this->_log_path, 0755, TRUE);
@@ -183,14 +185,14 @@ class CI_Log {
return FALSE;
}
- $filepath = $this->_log_path.'log-'.date('Y-m-d').'.'.$this->_file_ext;
+ $filepath = $this->_log_path.$this->_log_filename;
$message = '';
if ( ! file_exists($filepath))
{
$newfile = TRUE;
// Only add protection to php files
- if ($this->_file_ext === 'php')
+ if (substr($this->_log_filename, -3, 3) === 'php')
{
$message .= "<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?>\n\n";
}
@@ -284,9 +286,6 @@ class CI_Log {
{
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');
}
diff --git a/system/core/Model.php b/system/core/Model.php
index b2bbbd4d4..1ba10fbb7 100644
--- a/system/core/Model.php
+++ b/system/core/Model.php
@@ -50,14 +50,6 @@ defined('BASEPATH') OR exit('No direct script access allowed');
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
diff --git a/system/core/Output.php b/system/core/Output.php
index a629a09d8..02f3933f5 100644
--- a/system/core/Output.php
+++ b/system/core/Output.php
@@ -417,7 +417,7 @@ class CI_Output {
* @param string $output Output data override
* @return void
*/
- public function _display($output = '')
+ public function _display($output = NULL)
{
// Note: We use load_class() because we can't use $CI =& get_instance()
// since this function is sometimes called by the caching mechanism,
@@ -434,7 +434,7 @@ class CI_Output {
// --------------------------------------------------------------------
// Set the output data
- if ($output === '')
+ if ($output === NULL)
{
$output =& $this->final_output;
}
@@ -507,7 +507,7 @@ class CI_Output {
echo $output;
log_message('info', 'Final output sent to browser');
- log_message('debug', 'Total execution time: '.$elapsed);
+ log_message('info', 'Total execution time: '.$elapsed);
return;
}
@@ -544,7 +544,7 @@ class CI_Output {
}
log_message('info', 'Final output sent to browser');
- log_message('debug', 'Total execution time: '.$elapsed);
+ log_message('info', 'Total execution time: '.$elapsed);
}
// --------------------------------------------------------------------
@@ -559,7 +559,7 @@ class CI_Output {
{
$CI =& get_instance();
$path = $CI->config->item('cache_path');
- $cache_path = ($path === '') ? APPPATH.'cache/' : $path;
+ $cache_path = ($path === '') ? APPPATH.'cache'.DIRECTORY_SEPARATOR : rtrim($path, '/\\').DIRECTORY_SEPARATOR;
if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
{
@@ -568,7 +568,7 @@ class CI_Output {
}
$uri = $CI->config->item('base_url')
- .$CI->config->item('index_page')
+ .$CI->config->slash_item('index_page')
.$CI->uri->uri_string();
if (($cache_query_string = $CI->config->item('cache_query_string')) && ! empty($_SERVER['QUERY_STRING']))
@@ -663,7 +663,7 @@ class CI_Output {
$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;
+ $uri = $CFG->item('base_url').$CFG->slash_item('index_page').$URI->uri_string;
if (($cache_query_string = $CFG->item('cache_query_string')) && ! empty($_SERVER['QUERY_STRING']))
{
@@ -766,7 +766,7 @@ class CI_Output {
}
}
- $cache_path .= md5($CI->config->item('base_url').$CI->config->item('index_page').ltrim($uri, '/'));
+ $cache_path .= md5($CI->config->item('base_url').$CI->config->slash_item('index_page').ltrim($uri, '/'));
if ( ! @unlink($cache_path))
{
@@ -834,9 +834,6 @@ class CI_Output {
{
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');
}
diff --git a/system/core/Router.php b/system/core/Router.php
index 1267afeb9..f15a596f4 100644
--- a/system/core/Router.php
+++ b/system/core/Router.php
@@ -84,7 +84,7 @@ class CI_Router {
*
* @var string
*/
- public $directory;
+ public $directory = '';
/**
* Default controller (and method if specific)
@@ -336,7 +336,7 @@ class CI_Router {
protected function _validate_request($segments)
{
$c = count($segments);
- $directory_override = isset($this->directory);
+ $directory_override = $this->directory !== '';
// Loop through our segments and return as soon as a controller
// is found or when such a directory doesn't exist
@@ -443,19 +443,6 @@ class CI_Router {
// --------------------------------------------------------------------
/**
- * 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
@@ -469,19 +456,6 @@ class CI_Router {
// --------------------------------------------------------------------
/**
- * 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
@@ -499,21 +473,4 @@ class CI_Router {
$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;
- }
-
}
diff --git a/system/core/Security.php b/system/core/Security.php
index e7772e03d..d3c8b976e 100644
--- a/system/core/Security.php
+++ b/system/core/Security.php
@@ -170,10 +170,12 @@ class CI_Security {
*
* @return void
*/
- public function __construct()
+ public function __construct($charset)
{
+ $this->charset = $charset;
+
// Is CSRF protection enabled?
- if (config_item('csrf_protection'))
+ if (config_item('csrf_protection') && ! is_cli())
{
// CSRF config
foreach (array('csrf_expire', 'csrf_token_name', 'csrf_cookie_name') as $key)
@@ -192,10 +194,9 @@ class CI_Security {
// Set the CSRF hash
$this->_csrf_set_hash();
+ $this->csrf_verify();
}
- $this->charset = strtoupper((string) config_item('charset'));
-
log_message('info', 'Security Class Initialized');
}
@@ -659,7 +660,7 @@ class CI_Security {
if (is_readable('/dev/urandom') && ($fp = fopen('/dev/urandom', 'rb')) !== FALSE)
{
// Try not to waste entropy ...
- is_php('5.4') && stream_set_chunk_size($fp, $length);
+ stream_set_chunk_size($fp, $length);
$output = fread($fp, $length);
fclose($fp);
if ($output !== FALSE)
@@ -689,7 +690,7 @@ class CI_Security {
* correctly. html_entity_decode() does not convert entities without
* semicolons, so we are left with our own little solution here. Bummer.
*
- * @link http://php.net/html-entity-decode
+ * @link https://secure.php.net/html-entity-decode
*
* @param string $str Input
* @param string $charset Character set
@@ -704,26 +705,8 @@ class CI_Security {
static $_entities;
- isset($charset) OR $charset = $this->charset;
- $flag = is_php('5.4')
- ? ENT_COMPAT | ENT_HTML5
- : ENT_COMPAT;
-
- if ( ! isset($_entities))
- {
- $_entities = array_map('strtolower', get_html_translation_table(HTML_ENTITIES, $flag, $charset));
-
- // If we're not on PHP 5.4+, add the possibly dangerous HTML 5
- // entities to the array manually
- if ($flag === ENT_COMPAT)
- {
- $_entities[':'] = '&colon;';
- $_entities['('] = '&lpar;';
- $_entities[')'] = '&rpar;';
- $_entities["\n"] = '&NewLine;';
- $_entities["\t"] = '&Tab;';
- }
- }
+ isset($charset) OR $charset = $this->charset;
+ isset($_entities) OR $_entities = array_map('strtolower', get_html_translation_table(HTML_ENTITIES, ENT_COMPAT | ENT_HTML5, $charset));
do
{
@@ -748,14 +731,9 @@ class CI_Security {
// Decode numeric & UTF16 two byte entities
$str = html_entity_decode(
preg_replace('/(&#(?:x0*[0-9a-f]{2,5}(?![0-9a-f;])|(?:0*\d{2,4}(?![0-9;]))))/iS', '$1;', $str),
- $flag,
+ ENT_COMPAT | ENT_HTML5,
$charset
);
-
- if ($flag === ENT_COMPAT)
- {
- $str = str_replace(array_values($_entities), array_keys($_entities), $str);
- }
}
while ($str_compare !== $str);
return $str;
@@ -1107,5 +1085,4 @@ class CI_Security {
return $this->_csrf_hash;
}
-
}
diff --git a/system/core/URI.php b/system/core/URI.php
index 55e872163..eff969d75 100644
--- a/system/core/URI.php
+++ b/system/core/URI.php
@@ -99,45 +99,40 @@ class CI_URI {
*
* @return void
*/
- public function __construct()
+ public function __construct(CI_Config $config)
{
- $this->config =& load_class('Config', 'core');
+ $this->config = $config;
+ // If it's a CLI request, ignore the configuration
+ if (is_cli())
+ {
+ $this->_set_uri_string($this->_parse_argv(), TRUE);
+ }
// 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)
+ elseif ($this->config->item('enable_query_strings') !== TRUE)
{
$this->_permitted_uri_chars = $this->config->item('permitted_uri_chars');
+ $protocol = $this->config->item('uri_protocol');
+ empty($protocol) && $protocol = 'REQUEST_URI';
- // If it's a CLI request, ignore the configuration
- if (is_cli())
+ switch ($protocol)
{
- $uri = $this->_parse_argv();
+ 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;
}
- 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);
+ $this->_set_uri_string($uri, FALSE);
}
log_message('info', 'URI Class Initialized');
@@ -148,43 +143,66 @@ class CI_URI {
/**
* Set URI String
*
- * @param string $str
+ * @param string $str Input URI string
+ * @param bool $is_cli Whether the input comes from CLI
* @return void
*/
- protected function _set_uri_string($str)
+ protected function _set_uri_string($str, $is_cli = FALSE)
{
- // Filter out control characters and trim slashes
- $this->uri_string = trim(remove_invisible_characters($str, FALSE), '/');
-
- if ($this->uri_string !== '')
+ // CLI requests have a bit simpler logic
+ if ($is_cli)
{
- // Remove the URL suffix, if present
- if (($suffix = (string) $this->config->item('url_suffix')) !== '')
+ if (($this->uri_string = trim($str, '/')) === '')
{
- $slen = strlen($suffix);
-
- if (substr($this->uri_string, -$slen) === $suffix)
- {
- $this->uri_string = substr($this->uri_string, 0, -$slen);
- }
+ return;
}
$this->segments[0] = NULL;
- // Populate the segments array
- foreach (explode('/', trim($this->uri_string, '/')) as $val)
+ foreach (explode('/', $this->uri_string) as $segment)
{
- $val = trim($val);
- // Filter segments for security
- $this->filter_uri($val);
-
- if ($val !== '')
+ if (($segment = trim($segment)) !== '')
{
- $this->segments[] = $val;
+ $this->segments[] = $segment;
}
}
unset($this->segments[0]);
+ return;
+ }
+
+ // Filter out control characters and trim slashes
+ $this->uri_string = trim(remove_invisible_characters($str, FALSE), '/');
+
+ if ($this->uri_string === '')
+ {
+ return;
}
+
+ // 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;
+ foreach (explode('/', trim($this->uri_string, '/')) as $segment)
+ {
+ $segment = trim($segment);
+ // Filter segments for security
+ $this->filter_uri($segment);
+
+ if ($segment !== '')
+ {
+ $this->segments[] = $segment;
+ }
+ }
+
+ unset($this->segments[0]);
}
// --------------------------------------------------------------------
diff --git a/system/core/Utf8.php b/system/core/Utf8.php
index 054722340..58cbb1334 100644
--- a/system/core/Utf8.php
+++ b/system/core/Utf8.php
@@ -58,21 +58,21 @@ class CI_Utf8 {
*
* @return void
*/
- public function __construct()
+ public function __construct($charset)
{
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
- )
+ defined('PREG_BAD_UTF8_ERROR') // PCRE must support UTF-8
+ && (ICONV_ENABLED === TRUE OR MB_ENABLED === TRUE) // iconv or mbstring must be installed
+ && $charset === 'UTF-8' // Application charset must be UTF-8
+ )
{
define('UTF8_ENABLED', TRUE);
- log_message('debug', 'UTF-8 Support Enabled');
+ log_message('info', 'UTF-8 Support Enabled');
}
else
{
define('UTF8_ENABLED', FALSE);
- log_message('debug', 'UTF-8 Support Disabled');
+ log_message('info', 'UTF-8 Support Disabled');
}
log_message('info', 'Utf8 Class Initialized');
diff --git a/system/core/compat/hash.php b/system/core/compat/hash.php
index 3fe3b85bc..8d03fa922 100644
--- a/system/core/compat/hash.php
+++ b/system/core/compat/hash.php
@@ -63,7 +63,7 @@ if ( ! function_exists('hash_equals'))
/**
* hash_equals()
*
- * @link http://php.net/hash_equals
+ * @link https://secure.php.net/hash_equals
* @param string $known_string
* @param string $user_string
* @return bool
@@ -109,7 +109,7 @@ if ( ! function_exists('hash_pbkdf2'))
/**
* hash_pbkdf2()
*
- * @link http://php.net/hash_pbkdf2
+ * @link https://secure.php.net/hash_pbkdf2
* @param string $algo
* @param string $password
* @param string $salt
@@ -206,8 +206,6 @@ if ( ! function_exists('hash_pbkdf2'))
'ripemd160' => 64,
'ripemd256' => 64,
'ripemd320' => 64,
- 'salsa10' => 64,
- 'salsa20' => 64,
'sha1' => 64,
'sha224' => 64,
'sha256' => 64,
diff --git a/system/core/compat/index.html b/system/core/compat/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/core/compat/index.html
+++ b/system/core/compat/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/core/compat/mbstring.php b/system/core/compat/mbstring.php
index 1c49d189e..7ec598d68 100644
--- a/system/core/compat/mbstring.php
+++ b/system/core/compat/mbstring.php
@@ -66,7 +66,7 @@ if ( ! function_exists('mb_strlen'))
* WARNING: This function WILL fall-back to strlen()
* if iconv is not available!
*
- * @link http://php.net/mb_strlen
+ * @link https://secure.php.net/mb_strlen
* @param string $str
* @param string $encoding
* @return int
@@ -93,7 +93,7 @@ if ( ! function_exists('mb_strpos'))
* WARNING: This function WILL fall-back to strpos()
* if iconv is not available!
*
- * @link http://php.net/mb_strpos
+ * @link https://secure.php.net/mb_strpos
* @param string $haystack
* @param string $needle
* @param int $offset
@@ -122,7 +122,7 @@ if ( ! function_exists('mb_substr'))
* WARNING: This function WILL fall-back to substr()
* if iconv is not available.
*
- * @link http://php.net/mb_substr
+ * @link https://secure.php.net/mb_substr
* @param string $str
* @param int $start
* @param int $length
diff --git a/system/core/compat/password.php b/system/core/compat/password.php
index 9937a47e8..3aae48576 100644
--- a/system/core/compat/password.php
+++ b/system/core/compat/password.php
@@ -68,7 +68,7 @@ if ( ! function_exists('password_get_info'))
/**
* password_get_info()
*
- * @link http://php.net/password_get_info
+ * @link https://secure.php.net/password_get_info
* @param string $hash
* @return array
*/
@@ -87,7 +87,7 @@ if ( ! function_exists('password_hash'))
/**
* password_hash()
*
- * @link http://php.net/password_hash
+ * @link https://secure.php.net/password_hash
* @param string $password
* @param int $algo
* @param array $options
@@ -142,7 +142,7 @@ if ( ! function_exists('password_hash'))
}
// Try not to waste entropy ...
- is_php('5.4') && stream_set_chunk_size($fp, 16);
+ stream_set_chunk_size($fp, 16);
$options['salt'] = '';
for ($read = 0; $read < 16; $read = ($func_overload) ? mb_strlen($options['salt'], '8bit') : strlen($options['salt']))
@@ -195,7 +195,7 @@ if ( ! function_exists('password_needs_rehash'))
/**
* password_needs_rehash()
*
- * @link http://php.net/password_needs_rehash
+ * @link https://secure.php.net/password_needs_rehash
* @param string $hash
* @param int $algo
* @param array $options
@@ -229,7 +229,7 @@ if ( ! function_exists('password_verify'))
/**
* password_verify()
*
- * @link http://php.net/password_verify
+ * @link https://secure.php.net/password_verify
* @param string $password
* @param string $hash
* @return bool
diff --git a/system/core/compat/standard.php b/system/core/compat/standard.php
index 18b1281ca..a6a1a9cee 100644
--- a/system/core/compat/standard.php
+++ b/system/core/compat/standard.php
@@ -62,7 +62,7 @@ if ( ! function_exists('array_column'))
/**
* array_column()
*
- * @link http://php.net/array_column
+ * @link https://secure.php.net/array_column
* @param array $array
* @param mixed $column_key
* @param mixed $index_key
@@ -133,51 +133,3 @@ if ( ! function_exists('array_column'))
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);
- }
-}
diff --git a/system/core/index.html b/system/core/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/core/index.html
+++ b/system/core/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/database/DB.php b/system/database/DB.php
index 23581af50..d029054b6 100644
--- a/system/database/DB.php
+++ b/system/database/DB.php
@@ -46,10 +46,8 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @link https://codeigniter.com/userguide3/database/
*
* @param string|string[] $params
- * @param bool $query_builder_override
- * Determines if query builder should be used or not
*/
-function &DB($params = '', $query_builder_override = NULL)
+function &DB($params = '')
{
// Load the DB config file if a DSN string wasn't passed
if (is_string($params) && strpos($params, '://') === FALSE)
@@ -83,7 +81,7 @@ function &DB($params = '', $query_builder_override = NULL)
}
}
- if ( ! isset($db) OR count($db) === 0)
+ if (empty($db))
{
show_error('No database connection settings were found in the database config file.');
}
@@ -150,53 +148,30 @@ function &DB($params = '', $query_builder_override = NULL)
show_error('You have not selected a database type to connect to.');
}
- // Load the DB classes. Note: Since the query builder class is optional
- // we need to dynamically create a class that extends proper parent class
- // based on whether we're using the query builder class or not.
- if ($query_builder_override !== NULL)
- {
- $query_builder = $query_builder_override;
- }
- // Backwards compatibility work-around for keeping the
- // $active_record config variable working. Should be
- // removed in v3.1
- elseif ( ! isset($query_builder) && isset($active_record))
- {
- $query_builder = $active_record;
- }
-
require_once(BASEPATH.'database/DB_driver.php');
-
- if ( ! isset($query_builder) OR $query_builder === TRUE)
- {
- require_once(BASEPATH.'database/DB_query_builder.php');
- if ( ! class_exists('CI_DB', FALSE))
- {
- /**
- * CI_DB
- *
- * Acts as an alias for both CI_DB_driver and CI_DB_query_builder.
- *
- * @see CI_DB_query_builder
- * @see CI_DB_driver
- */
- class CI_DB extends CI_DB_query_builder { }
- }
- }
- elseif ( ! class_exists('CI_DB', FALSE))
+ require_once(BASEPATH.'database/DB_query_builder.php');
+ if ( ! class_exists('CI_DB', FALSE))
{
/**
- * @ignore
+ * CI_DB
+ *
+ * Acts as an alias for both CI_DB_driver and CI_DB_query_builder.
+ *
+ * @see CI_DB_query_builder
+ * @see CI_DB_driver
*/
- class CI_DB extends CI_DB_driver { }
+ class CI_DB extends CI_DB_query_builder {}
}
// Load the DB driver
$driver_file = BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver.php';
-
file_exists($driver_file) OR show_error('Invalid DB driver');
require_once($driver_file);
+ // Load the result classes as well
+ require_once(BASEPATH.'database/DB_result.php');
+ require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_result.php');
+
// Instantiate the DB adapter
$driver = 'CI_DB_'.$params['dbdriver'].'_driver';
$DB = new $driver($params);
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index 031e0edcd..f7ff92197 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -382,7 +382,8 @@ abstract class CI_DB_driver {
/**
* Initialize Database Settings
*
- * @return bool
+ * @return void
+ * @throws RuntimeException In case of failure
*/
public function initialize()
{
@@ -394,7 +395,7 @@ abstract class CI_DB_driver {
*/
if ($this->conn_id)
{
- return TRUE;
+ return;
}
// ----------------------------------------------------------------
@@ -431,19 +432,9 @@ abstract class CI_DB_driver {
// We still don't have a connection?
if ( ! $this->conn_id)
{
- log_message('error', 'Unable to connect to the database');
-
- if ($this->db_debug)
- {
- $this->display_error('db_unable_to_connect');
- }
-
- return FALSE;
+ throw new RuntimeException('Unable to connect to the database.');
}
}
-
- // Now we set the character set and that's all
- return $this->db_set_charset($this->char_set);
}
// --------------------------------------------------------------------
@@ -519,31 +510,6 @@ abstract class CI_DB_driver {
// --------------------------------------------------------------------
/**
- * Set client character set
- *
- * @param string
- * @return bool
- */
- public function db_set_charset($charset)
- {
- if (method_exists($this, '_db_set_charset') && ! $this->_db_set_charset($charset))
- {
- log_message('error', 'Unable to set database connection charset: '.$charset);
-
- if ($this->db_debug)
- {
- $this->display_error('db_unable_to_set_charset', $charset);
- }
-
- return FALSE;
- }
-
- return TRUE;
- }
-
- // --------------------------------------------------------------------
-
- /**
* The name of the platform in use (mysql, mssql, etc...)
*
* @return string
@@ -636,7 +602,6 @@ abstract class CI_DB_driver {
// cached query if it exists
if ($this->cache_on === TRUE && $return_object === TRUE && $this->_cache_init())
{
- $this->load_rdriver();
if (FALSE !== ($cache = $this->CACHE->read($sql)))
{
return $cache;
@@ -720,9 +685,9 @@ abstract class CI_DB_driver {
return TRUE;
}
- // Load and instantiate the result driver
- $driver = $this->load_rdriver();
- $RES = new $driver($this);
+ // Instantiate the driver-specific result class
+ $driver = 'CI_DB_'.$this->dbdriver.'_result';
+ $RES = new $driver($this);
// Is query caching enabled? If so, we'll serialize the
// result object and save it to a cache file.
@@ -752,26 +717,6 @@ abstract class CI_DB_driver {
// --------------------------------------------------------------------
/**
- * Load the result drivers
- *
- * @return string the name of the result class
- */
- public function load_rdriver()
- {
- $driver = 'CI_DB_'.$this->dbdriver.'_result';
-
- if ( ! class_exists($driver, FALSE))
- {
- require_once(BASEPATH.'database/DB_result.php');
- require_once(BASEPATH.'database/drivers/'.$this->dbdriver.'/'.$this->dbdriver.'_result.php');
- }
-
- return $driver;
- }
-
- // --------------------------------------------------------------------
-
- /**
* Simple Query
* This is a simplified version of the query() function. Internally
* we only use it when running transaction commands since they do
@@ -782,14 +727,7 @@ abstract class CI_DB_driver {
*/
public function simple_query($sql)
{
- if ( ! $this->conn_id)
- {
- if ( ! $this->initialize())
- {
- return FALSE;
- }
- }
-
+ empty($this->conn_id) && $this->initialize();
return $this->_execute($sql);
}
@@ -1391,10 +1329,11 @@ abstract class CI_DB_driver {
*
* This function escapes column and table names
*
- * @param mixed
+ * @param mixed $item Identifier to escape
+ * @param bool $split Whether to split identifiers when a dot is encountered
* @return mixed
*/
- public function escape_identifiers($item)
+ public function escape_identifiers($item, $split = TRUE)
{
if ($this->_escape_char === '' OR empty($item) OR in_array($item, $this->_reserved_identifiers))
{
@@ -1415,22 +1354,22 @@ abstract class CI_DB_driver {
return $item;
}
- static $preg_ec = array();
+ static $preg_ec;
if (empty($preg_ec))
{
if (is_array($this->_escape_char))
{
$preg_ec = array(
- preg_quote($this->_escape_char[0], '/'),
- preg_quote($this->_escape_char[1], '/'),
+ preg_quote($this->_escape_char[0]),
+ preg_quote($this->_escape_char[1]),
$this->_escape_char[0],
$this->_escape_char[1]
);
}
else
{
- $preg_ec[0] = $preg_ec[1] = preg_quote($this->_escape_char, '/');
+ $preg_ec[0] = $preg_ec[1] = preg_quote($this->_escape_char);
$preg_ec[2] = $preg_ec[3] = $this->_escape_char;
}
}
@@ -1439,11 +1378,13 @@ abstract class CI_DB_driver {
{
if (strpos($item, '.'.$id) !== FALSE)
{
- return preg_replace('/'.$preg_ec[0].'?([^'.$preg_ec[1].'\.]+)'.$preg_ec[1].'?\./i', $preg_ec[2].'$1'.$preg_ec[3].'.', $item);
+ return preg_replace('#'.$preg_ec[0].'?([^'.$preg_ec[1].'\.]+)'.$preg_ec[1].'?\.#i', $preg_ec[2].'$1'.$preg_ec[3].'.', $item);
}
}
- return preg_replace('/'.$preg_ec[0].'?([^'.$preg_ec[1].'\.]+)'.$preg_ec[1].'?(\.)?/i', $preg_ec[2].'$1'.$preg_ec[3].'$2', $item);
+ $dot = ($split !== FALSE) ? '\.' : '';
+
+ return preg_replace('#'.$preg_ec[0].'?([^'.$preg_ec[1].$dot.']+)'.$preg_ec[1].'?(\.)?#i', $preg_ec[2].'$1'.$preg_ec[3].'$2', $item);
}
// --------------------------------------------------------------------
@@ -1858,14 +1799,14 @@ abstract class CI_DB_driver {
if ($offset = strripos($item, ' AS '))
{
$alias = ($protect_identifiers)
- ? substr($item, $offset, 4).$this->escape_identifiers(substr($item, $offset + 4))
+ ? substr($item, $offset, 4).$this->escape_identifiers(substr($item, $offset + 4), FALSE)
: substr($item, $offset);
$item = substr($item, 0, $offset);
}
elseif ($offset = strrpos($item, ' '))
{
$alias = ($protect_identifiers)
- ? ' '.$this->escape_identifiers(substr($item, $offset + 1))
+ ? ' '.$this->escape_identifiers(substr($item, $offset + 1), FALSE)
: substr($item, $offset);
$item = substr($item, 0, $offset);
}
diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php
index 64ccde0ef..36679a464 100644
--- a/system/database/DB_forge.php
+++ b/system/database/DB_forge.php
@@ -557,25 +557,17 @@ abstract class CI_DB_forge {
/**
* Column Add
*
- * @todo Remove deprecated $_after option in 3.1+
* @param string $table Table name
* @param array $field Column definition
- * @param string $_after Column for AFTER clause (deprecated)
* @return bool
*/
- public function add_column($table, $field, $_after = NULL)
+ public function add_column($table, $field)
{
// Work-around for literal column definitions
is_array($field) OR $field = array($field);
foreach (array_keys($field) as $k)
{
- // Backwards-compatibility work-around for MySQL/CUBRID AFTER clause (remove in 3.1+)
- if ($_after !== NULL && is_array($field[$k]) && ! isset($field[$k]['after']))
- {
- $field[$k]['after'] = $_after;
- }
-
$this->add_field(array($k => $field[$k]));
}
@@ -896,21 +888,33 @@ abstract class CI_DB_forge {
return;
}
- if (array_key_exists('DEFAULT', $attributes))
+ if ( ! array_key_exists('DEFAULT', $attributes))
{
- if ($attributes['DEFAULT'] === NULL)
- {
- $field['default'] = empty($this->_null) ? '' : $this->_default.$this->_null;
+ return;
+ }
- // Override the NULL attribute if that's our default
- $attributes['NULL'] = TRUE;
- $field['null'] = empty($this->_null) ? '' : ' '.$this->_null;
- }
- else
- {
- $field['default'] = $this->_default.$this->db->escape($attributes['DEFAULT']);
- }
+ if ($attributes['DEFAULT'] === NULL)
+ {
+ $field['default'] = empty($this->_null) ? '' : $this->_default.$this->_null;
+
+ // Override the NULL attribute if that's our default
+ $attributes['NULL'] = TRUE;
+ $field['null'] = empty($this->_null) ? '' : ' '.$this->_null;
+ return;
}
+
+ // White-list CURRENT_TIMESTAMP & similar (e.g. Oracle has stuff like SYSTIMESTAMP) defaults for date/time fields
+ if (
+ isset($attributes['TYPE'])
+ && (stripos($attributes['TYPE'], 'time') !== FALSE OR stripos($attributes['TYPE'], 'date') !== FALSE)
+ && (stripos($attributes['DEFAULT'], 'time') !== FALSE OR stripos($attributes['DEFAULT'], 'date') !== FALSE)
+ )
+ {
+ $field['default'] = $this->_default.$attributes['DEFAULT'];
+ return;
+ }
+
+ $field['default'] = $this->_default.$this->db->escape($attributes['DEFAULT']);
}
// --------------------------------------------------------------------
diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php
index 933108498..de6aa04fc 100644
--- a/system/database/DB_query_builder.php
+++ b/system/database/DB_query_builder.php
@@ -526,19 +526,8 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
*/
public function join($table, $cond, $type = '', $escape = NULL)
{
- if ($type !== '')
- {
- $type = strtoupper(trim($type));
-
- if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER', 'FULL OUTER', 'FULL'), TRUE))
- {
- $type = '';
- }
- else
- {
- $type .= ' ';
- }
- }
+ $type = trim(strtoupper($type).' JOIN');
+ preg_match('#^(NATURAL\s+)?((LEFT|RIGHT|FULL)\s+)?((INNER|OUTER)\s+)?JOIN$#', $type) OR $type = 'JOIN';
// Extract any aliases that might exist. We use this information
// in the protect_identifiers to know whether to add a table prefix
@@ -546,7 +535,11 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
is_bool($escape) OR $escape = $this->_protect_identifiers;
- if ( ! $this->_has_operator($cond))
+ if (strpos($type, 'NATURAL') === 0)
+ {
+ $cond = '';
+ }
+ elseif ( ! $this->_has_operator($cond))
{
$cond = ' USING ('.($escape ? $this->escape_identifiers($cond) : $cond).')';
}
@@ -595,7 +588,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
}
// Assemble the JOIN statement
- $this->qb_join[] = $join = $type.'JOIN '.$table.$cond;
+ $this->qb_join[] = $join = $type.' '.$table.$cond;
if ($this->qb_caching === TRUE)
{
@@ -699,11 +692,11 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$k = substr($k, 0, $match[0][1]).($match[1][0] === '=' ? ' IS NULL' : ' IS NOT NULL');
}
- ${$qb_key} = array('condition' => $prefix.$k, 'value' => $v, 'escape' => $escape);
- $this->{$qb_key}[] = ${$qb_key};
+ $$qb_key = array('condition' => $prefix.$k, 'value' => $v, 'escape' => $escape);
+ $this->{$qb_key}[] = $$qb_key;
if ($this->qb_caching === TRUE)
{
- $this->{$qb_cache_key}[] = ${$qb_key};
+ $this->{$qb_cache_key}[] = $$qb_key;
$this->qb_cache_exists[] = substr($qb_key, 3);
}
@@ -725,9 +718,9 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* @param bool $escape
* @return CI_DB_query_builder
*/
- public function where_in($key = NULL, $values = NULL, $escape = NULL)
+ public function where_in($key, array $values, $escape = NULL)
{
- return $this->_where_in($key, $values, FALSE, 'AND ', $escape);
+ return $this->_wh_in('qb_where', $key, $values, FALSE, 'AND ', $escape);
}
// --------------------------------------------------------------------
@@ -743,9 +736,9 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* @param bool $escape
* @return CI_DB_query_builder
*/
- public function or_where_in($key = NULL, $values = NULL, $escape = NULL)
+ public function or_where_in($key, array $values, $escape = NULL)
{
- return $this->_where_in($key, $values, FALSE, 'OR ', $escape);
+ return $this->_wh_in('qb_where', $key, $values, FALSE, 'OR ', $escape);
}
// --------------------------------------------------------------------
@@ -761,9 +754,9 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* @param bool $escape
* @return CI_DB_query_builder
*/
- public function where_not_in($key = NULL, $values = NULL, $escape = NULL)
+ public function where_not_in($key, array $values, $escape = NULL)
{
- return $this->_where_in($key, $values, TRUE, 'AND ', $escape);
+ return $this->_wh_in('qb_where', $key, $values, TRUE, 'AND ', $escape);
}
// --------------------------------------------------------------------
@@ -779,21 +772,98 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* @param bool $escape
* @return CI_DB_query_builder
*/
- public function or_where_not_in($key = NULL, $values = NULL, $escape = NULL)
+ public function or_where_not_in($key, array $values, $escape = NULL)
+ {
+ return $this->_wh_in('qb_where', $key, $values, TRUE, 'OR ', $escape);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * HAVING IN
+ *
+ * Generates a HAVING field IN('item', 'item') SQL query,
+ * joined with 'AND' if appropriate.
+ *
+ * @param string $key The field to search
+ * @param array $values The values searched on
+ * @param bool $escape
+ * @return CI_DB_query_builder
+ */
+ public function having_in($key, array $values, $escape = NULL)
+ {
+ return $this->_wh_in('qb_having', $key, $values, FALSE, 'AND ', $escape);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * OR HAVING IN
+ *
+ * Generates a HAVING field IN('item', 'item') SQL query,
+ * joined with 'OR' if appropriate.
+ *
+ * @param string $key The field to search
+ * @param array $values The values searched on
+ * @param bool $escape
+ * @return CI_DB_query_builder
+ */
+ public function or_having_in($key, array $values, $escape = NULL)
+ {
+ return $this->_wh_in('qb_having', $key, $values, FALSE, 'OR ', $escape);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * HAVING NOT IN
+ *
+ * Generates a HAVING field NOT IN('item', 'item') SQL query,
+ * joined with 'AND' if appropriate.
+ *
+ * @param string $key The field to search
+ * @param array $values The values searched on
+ * @param bool $escape
+ * @return CI_DB_query_builder
+ */
+ public function having_not_in($key, array $values, $escape = NULL)
{
- return $this->_where_in($key, $values, TRUE, 'OR ', $escape);
+ return $this->_wh_in('qb_having', $key, $values, TRUE, 'AND ', $escape);
}
// --------------------------------------------------------------------
/**
- * Internal WHERE IN
+ * OR HAVING NOT IN
+ *
+ * Generates a HAVING field NOT IN('item', 'item') SQL query,
+ * joined with 'OR' if appropriate.
+ *
+ * @param string $key The field to search
+ * @param array $values The values searched on
+ * @param bool $escape
+ * @return CI_DB_query_builder
+ */
+ public function or_having_not_in($key, array $values, $escape = NULL)
+ {
+ return $this->_wh_in('qb_having', $key, $values, TRUE, 'OR ', $escape);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Internal WHERE/HAVING IN
*
* @used-by where_in()
* @used-by or_where_in()
* @used-by where_not_in()
* @used-by or_where_not_in()
+ * @used-by having_in()
+ * @used-by or_having_in()
+ * @used-by having_not_in()
+ * @used-by or_having_not_in()
*
+ * @param string $qb_key 'qb_where' or 'qb_having'
* @param string $key The field to search
* @param array $values The values searched on
* @param bool $not If the statement would be IN or NOT IN
@@ -801,16 +871,18 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* @param bool $escape
* @return CI_DB_query_builder
*/
- protected function _where_in($key = NULL, $values = NULL, $not = FALSE, $type = 'AND ', $escape = NULL)
+ protected function _wh_in($qb_key, $key, array $values, $not = FALSE, $type = 'AND ', $escape = NULL)
{
- if ($key === NULL OR $values === NULL)
+ $qb_cache_key = ($qb_key === 'qb_having') ? 'qb_cache_having' : 'qb_cache_where';
+
+ if (empty($key) OR ! is_string($key))
{
- return $this;
+ throw new InvalidArgumentException(sprintf('%s() expects $key to be a non-empty string', debug_backtrace(0, 2)[1]['function']));
}
- if ( ! is_array($values))
+ if (empty($values))
{
- $values = array($values);
+ throw new InvalidArgumentException(sprintf('%s() expects $values to be a non-empty array', debug_backtrace(0, 2)[1]['function']));
}
is_bool($escape) OR $escape = $this->_protect_identifiers;
@@ -819,32 +891,32 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
if ($escape === TRUE)
{
- $where_in = array();
+ $wh_in = array();
foreach ($values as $value)
{
- $where_in[] = $this->escape($value);
+ $wh_in[] = $this->escape($value);
}
}
else
{
- $where_in = array_values($values);
+ $wh_in = array_values($values);
}
- $prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0)
+ $prefix = (count($this->$qb_key) === 0 && count($this->$qb_cache_key) === 0)
? $this->_group_get_type('')
: $this->_group_get_type($type);
- $where_in = array(
- 'condition' => $prefix.$key.$not.' IN('.implode(', ', $where_in).')',
+ $wh_in = array(
+ 'condition' => $prefix.$key.$not.' IN('.implode(', ', $wh_in).')',
'value' => NULL,
'escape' => $escape
);
- $this->qb_where[] = $where_in;
+ $this->{$qb_key}[] = $wh_in;
if ($this->qb_caching === TRUE)
{
- $this->qb_cache_where[] = $where_in;
- $this->qb_cache_exists[] = 'where';
+ $this->{$qb_cache_key}[] = $wh_in;
+ $this->qb_cache_exists[] = substr($qb_key, 3);
}
return $this;
diff --git a/system/database/DB_utility.php b/system/database/DB_utility.php
index 11aa67bbe..317e1bc8d 100644
--- a/system/database/DB_utility.php
+++ b/system/database/DB_utility.php
@@ -236,13 +236,8 @@ abstract class CI_DB_utility {
* @param string $enclosure Enclosure (default: ")
* @return string
*/
- public function csv_from_result($query, $delim = ',', $newline = "\n", $enclosure = '"')
+ public function csv_from_result(CI_DB_result $query, $delim = ',', $newline = "\n", $enclosure = '"')
{
- if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
- {
- show_error('You must submit a valid result object');
- }
-
$out = '';
// First generate the headings from the table column names
foreach ($query->list_fields() as $name)
@@ -275,13 +270,8 @@ abstract class CI_DB_utility {
* @param array $params Any preferences
* @return string
*/
- public function xml_from_result($query, $params = array())
+ public function xml_from_result(CI_DB_result $query, $params = array())
{
- if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
- {
- show_error('You must submit a valid result object');
- }
-
// Set our default values
foreach (array('root' => 'root', 'element' => 'element', 'newline' => "\n", 'tab' => "\t") as $key => $val)
{
diff --git a/system/database/drivers/cubrid/index.html b/system/database/drivers/cubrid/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/database/drivers/cubrid/index.html
+++ b/system/database/drivers/cubrid/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/database/drivers/ibase/index.html b/system/database/drivers/ibase/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/database/drivers/ibase/index.html
+++ b/system/database/drivers/ibase/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/database/drivers/index.html b/system/database/drivers/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/database/drivers/index.html
+++ b/system/database/drivers/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/database/drivers/mssql/index.html b/system/database/drivers/mssql/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/database/drivers/mssql/index.html
+++ b/system/database/drivers/mssql/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php
index 501264091..3fc323a02 100644
--- a/system/database/drivers/mssql/mssql_driver.php
+++ b/system/database/drivers/mssql/mssql_driver.php
@@ -109,6 +109,7 @@ class CI_DB_mssql_driver extends CI_DB {
*/
public function db_connect($persistent = FALSE)
{
+ ini_set('mssql.charset', $this->char_set);
$this->conn_id = ($persistent)
? mssql_pconnect($this->hostname, $this->username, $this->password)
: mssql_connect($this->hostname, $this->username, $this->password);
@@ -250,19 +251,6 @@ class CI_DB_mssql_driver extends CI_DB {
// --------------------------------------------------------------------
/**
- * Set client character set
- *
- * @param string $charset
- * @return bool
- */
- protected function _db_set_charset($charset)
- {
- return (ini_set('mssql.charset', $charset) !== FALSE);
- }
-
- // --------------------------------------------------------------------
-
- /**
* Version number query string
*
* @return string
diff --git a/system/database/drivers/mysql/index.html b/system/database/drivers/mysql/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/database/drivers/mysql/index.html
+++ b/system/database/drivers/mysql/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php
index 367f89a99..5c4d2d8fb 100644
--- a/system/database/drivers/mysql/mysql_driver.php
+++ b/system/database/drivers/mysql/mysql_driver.php
@@ -148,29 +148,41 @@ class CI_DB_mysql_driver extends CI_DB {
: FALSE;
}
- if (isset($this->stricton) && is_resource($this->conn_id))
+ if (is_resource($this->conn_id))
{
- if ($this->stricton)
+ if ( ! mysql_set_charset($this->char_set, $this->conn_id))
{
- $this->simple_query('SET SESSION sql_mode = CONCAT(@@sql_mode, ",", "STRICT_ALL_TABLES")');
+ log_message('error', "Database: Unable to set the configured connection charset ('{$this->char_set}').");
+ $this->close();
+ return ($this->db->debug) ? $this->display_error('db_unable_to_set_charset', $this->char_set) : FALSE;
}
- else
+
+ if (isset($this->stricton))
{
- $this->simple_query(
- 'SET SESSION sql_mode =
- REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
- @@sql_mode,
- "STRICT_ALL_TABLES,", ""),
- ",STRICT_ALL_TABLES", ""),
- "STRICT_ALL_TABLES", ""),
- "STRICT_TRANS_TABLES,", ""),
- ",STRICT_TRANS_TABLES", ""),
- "STRICT_TRANS_TABLES", "")'
- );
+ if ($this->stricton)
+ {
+ $this->simple_query('SET SESSION sql_mode = CONCAT(@@sql_mode, ",", "STRICT_ALL_TABLES")');
+ }
+ else
+ {
+ $this->simple_query(
+ 'SET SESSION sql_mode =
+ REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
+ @@sql_mode,
+ "STRICT_ALL_TABLES,", ""),
+ ",STRICT_ALL_TABLES", ""),
+ "STRICT_ALL_TABLES", ""),
+ "STRICT_TRANS_TABLES,", ""),
+ ",STRICT_TRANS_TABLES", ""),
+ "STRICT_TRANS_TABLES", "")'
+ );
+ }
}
+
+ return $this->conn_id;
}
- return $this->conn_id;
+ return FALSE;
}
// --------------------------------------------------------------------
@@ -219,19 +231,6 @@ class CI_DB_mysql_driver extends CI_DB {
// --------------------------------------------------------------------
/**
- * Set client character set
- *
- * @param string $charset
- * @return bool
- */
- protected function _db_set_charset($charset)
- {
- return mysql_set_charset($charset, $this->conn_id);
- }
-
- // --------------------------------------------------------------------
-
- /**
* Database version number
*
* @return string
diff --git a/system/database/drivers/mysqli/index.html b/system/database/drivers/mysqli/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/database/drivers/mysqli/index.html
+++ b/system/database/drivers/mysqli/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php
index f5e994960..61e7adee3 100644
--- a/system/database/drivers/mysqli/mysqli_driver.php
+++ b/system/database/drivers/mysqli/mysqli_driver.php
@@ -223,6 +223,13 @@ class CI_DB_mysqli_driver extends CI_DB {
return ($this->db_debug) ? $this->display_error($message, '', TRUE) : FALSE;
}
+ if ( ! $this->_mysqli->set_charset($this->char_set))
+ {
+ log_message('error', "Database: Unable to set the configured connection charset ('{$this->char_set}').");
+ $this->_mysqli->close();
+ return ($this->db->db_debug) ? $this->display_error('db_unable_to_set_charset', $this->char_set) : FALSE;
+ }
+
return $this->_mysqli;
}
@@ -275,19 +282,6 @@ class CI_DB_mysqli_driver extends CI_DB {
// --------------------------------------------------------------------
/**
- * Set client character set
- *
- * @param string $charset
- * @return bool
- */
- protected function _db_set_charset($charset)
- {
- return $this->conn_id->set_charset($charset);
- }
-
- // --------------------------------------------------------------------
-
- /**
* Database version number
*
* @return string
diff --git a/system/database/drivers/oci8/index.html b/system/database/drivers/oci8/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/database/drivers/oci8/index.html
+++ b/system/database/drivers/oci8/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php
index 7bb43b5be..6f8b21d75 100644
--- a/system/database/drivers/oci8/oci8_driver.php
+++ b/system/database/drivers/oci8/oci8_driver.php
@@ -70,20 +70,6 @@ class CI_DB_oci8_driver extends CI_DB {
public $dbdriver = 'oci8';
/**
- * Statement ID
- *
- * @var resource
- */
- public $stmt_id;
-
- /**
- * Cursor ID
- *
- * @var resource
- */
- public $curs_id;
-
- /**
* Commit mode flag
*
* @var int
@@ -100,15 +86,27 @@ class CI_DB_oci8_driver extends CI_DB {
*/
public $limit_used = FALSE;
- // --------------------------------------------------------------------
+ /**
+ * Error cache
+ *
+ * Cached error info about failed queries.
+ * Used so that statement IDs can be released immediately.
+ *
+ * @var array|false
+ */
+ protected $_error = FALSE;
/**
- * Reset $stmt_id flag
+ * Affected rows
*
- * Used by stored_procedure() to prevent _execute() from
- * re-setting the statement ID.
+ * Cached result of oci_num_rows().
+ * Used so that statement IDs can be released immediately.
+ *
+ * @var int|false
*/
- protected $_reset_stmt_id = TRUE;
+ protected $_affected_rows = FALSE;
+
+ // --------------------------------------------------------------------
/**
* List of reserved identifiers
@@ -278,104 +276,19 @@ class CI_DB_oci8_driver extends CI_DB {
/* Oracle must parse the query before it is run. All of the actions with
* the query are based on the statement id returned by oci_parse().
*/
- if ($this->_reset_stmt_id === TRUE)
- {
- $this->stmt_id = oci_parse($this->conn_id, $sql);
- }
-
- oci_set_prefetch($this->stmt_id, 1000);
- return oci_execute($this->stmt_id, $this->commit_mode);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Get cursor. Returns a cursor from the database
- *
- * @return resource
- */
- public function get_cursor()
- {
- return $this->curs_id = oci_new_cursor($this->conn_id);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Stored Procedure. Executes a stored procedure
- *
- * @param string package name in which the stored procedure is in
- * @param string stored procedure name to execute
- * @param array parameters
- * @return mixed
- *
- * params array keys
- *
- * KEY OPTIONAL NOTES
- * name no the name of the parameter should be in :<param_name> format
- * value no the value of the parameter. If this is an OUT or IN OUT parameter,
- * this should be a reference to a variable
- * type yes the type of the parameter
- * length yes the max size of the parameter
- */
- public function stored_procedure($package, $procedure, array $params)
- {
- if ($package === '' OR $procedure === '')
- {
- log_message('error', 'Invalid query: '.$package.'.'.$procedure);
- return ($this->db_debug) ? $this->display_error('db_invalid_query') : FALSE;
- }
+ $this->result_id = oci_parse($this->conn_id, $sql);
+ oci_set_prefetch($this->result_id, 1000);
+ $result = oci_execute($this->result_id, $this->commit_mode);
+ $this->_error = oci_error($this->result_id);
+ $this->is_write_type($sql) && $this->_affected_rows = oci_num_rows($this->result_id);
- // Build the query string
- $sql = 'BEGIN '.$package.'.'.$procedure.'(';
-
- $have_cursor = FALSE;
- foreach ($params as $param)
+ if ($this->is_write_type($sql) OR $result === FALSE)
{
- $sql .= $param['name'].',';
-
- if (isset($param['type']) && $param['type'] === OCI_B_CURSOR)
- {
- $have_cursor = TRUE;
- }
+ oci_free_statement($this->result_id);
+ return $result;
}
- $sql = trim($sql, ',').'); END;';
-
- $this->_reset_stmt_id = FALSE;
- $this->stmt_id = oci_parse($this->conn_id, $sql);
- $this->_bind_params($params);
- $result = $this->query($sql, FALSE, $have_cursor);
- $this->_reset_stmt_id = TRUE;
- return $result;
- }
-
- // --------------------------------------------------------------------
- /**
- * Bind parameters
- *
- * @param array $params
- * @return void
- */
- protected function _bind_params($params)
- {
- if ( ! is_array($params) OR ! is_resource($this->stmt_id))
- {
- return;
- }
-
- foreach ($params as $param)
- {
- foreach (array('name', 'value', 'type', 'length') as $val)
- {
- if ( ! isset($param[$val]))
- {
- $param[$val] = '';
- }
- }
-
- oci_bind_by_name($this->stmt_id, $param['name'], $param['value'], $param['length'], $param['type']);
- }
+ return $this->result_id;
}
// --------------------------------------------------------------------
@@ -427,7 +340,7 @@ class CI_DB_oci8_driver extends CI_DB {
*/
public function affected_rows()
{
- return oci_num_rows($this->stmt_id);
+ return $this->_affected_rows;
}
// --------------------------------------------------------------------
@@ -560,18 +473,15 @@ class CI_DB_oci8_driver extends CI_DB {
*/
public function error()
{
+ if ( ! empty($this->_error))
+ {
+ return $this->_error;
+ }
+
// oci_error() returns an array that already contains
// 'code' and 'message' keys, but it can return false
// if there was no error ....
- if (is_resource($this->curs_id))
- {
- $error = oci_error($this->curs_id);
- }
- elseif (is_resource($this->stmt_id))
- {
- $error = oci_error($this->stmt_id);
- }
- elseif (is_resource($this->conn_id))
+ if (is_resource($this->conn_id))
{
$error = oci_error($this->conn_id);
}
@@ -683,14 +593,9 @@ class CI_DB_oci8_driver extends CI_DB {
*/
protected function _close()
{
- if (is_resource($this->curs_id))
- {
- oci_free_statement($this->curs_id);
- }
-
- if (is_resource($this->stmt_id))
+ if (is_resource($this->result_id))
{
- oci_free_statement($this->stmt_id);
+ oci_free_statement($this->result_id);
}
oci_close($this->conn_id);
diff --git a/system/database/drivers/oci8/oci8_result.php b/system/database/drivers/oci8/oci8_result.php
index 4312f9b21..3b042fb75 100644
--- a/system/database/drivers/oci8/oci8_result.php
+++ b/system/database/drivers/oci8/oci8_result.php
@@ -50,20 +50,6 @@ defined('BASEPATH') OR exit('No direct script access allowed');
class CI_DB_oci8_result extends CI_DB_result {
/**
- * Statement ID
- *
- * @var resource
- */
- public $stmt_id;
-
- /**
- * Cursor ID
- *
- * @var resource
- */
- public $curs_id;
-
- /**
* Limit used flag
*
* @var bool
@@ -89,11 +75,10 @@ class CI_DB_oci8_result extends CI_DB_result {
{
parent::__construct($driver_object);
- $this->stmt_id = $driver_object->stmt_id;
- $this->curs_id = $driver_object->curs_id;
+ $this->result_id = $driver_object->result_id;
$this->limit_used = $driver_object->limit_used;
$this->commit_mode =& $driver_object->commit_mode;
- $driver_object->stmt_id = FALSE;
+ $driver_object->result_id = FALSE;
}
// --------------------------------------------------------------------
@@ -105,7 +90,7 @@ class CI_DB_oci8_result extends CI_DB_result {
*/
public function num_fields()
{
- $count = oci_num_fields($this->stmt_id);
+ $count = oci_num_fields($this->result_id);
// if we used a limit we subtract it
return ($this->limit_used) ? $count - 1 : $count;
@@ -125,7 +110,7 @@ class CI_DB_oci8_result extends CI_DB_result {
$field_names = array();
for ($c = 1, $fieldCount = $this->num_fields(); $c <= $fieldCount; $c++)
{
- $field_names[] = oci_field_name($this->stmt_id, $c);
+ $field_names[] = oci_field_name($this->result_id, $c);
}
return $field_names;
}
@@ -145,9 +130,9 @@ class CI_DB_oci8_result extends CI_DB_result {
for ($c = 1, $fieldCount = $this->num_fields(); $c <= $fieldCount; $c++)
{
$F = new stdClass();
- $F->name = oci_field_name($this->stmt_id, $c);
- $F->type = oci_field_type($this->stmt_id, $c);
- $F->max_length = oci_field_size($this->stmt_id, $c);
+ $F->name = oci_field_name($this->result_id, $c);
+ $F->type = oci_field_type($this->result_id, $c);
+ $F->max_length = oci_field_size($this->result_id, $c);
$retval[] = $F;
}
@@ -169,17 +154,6 @@ class CI_DB_oci8_result extends CI_DB_result {
oci_free_statement($this->result_id);
$this->result_id = FALSE;
}
-
- if (is_resource($this->stmt_id))
- {
- oci_free_statement($this->stmt_id);
- }
-
- if (is_resource($this->curs_id))
- {
- oci_cancel($this->curs_id);
- $this->curs_id = NULL;
- }
}
// --------------------------------------------------------------------
@@ -193,8 +167,7 @@ class CI_DB_oci8_result extends CI_DB_result {
*/
protected function _fetch_assoc()
{
- $id = ($this->curs_id) ? $this->curs_id : $this->stmt_id;
- return oci_fetch_assoc($id);
+ return oci_fetch_assoc($this->result_id);
}
// --------------------------------------------------------------------
@@ -209,9 +182,7 @@ class CI_DB_oci8_result extends CI_DB_result {
*/
protected function _fetch_object($class_name = 'stdClass')
{
- $row = ($this->curs_id)
- ? oci_fetch_object($this->curs_id)
- : oci_fetch_object($this->stmt_id);
+ $row = oci_fetch_object($this->result_id);
if ($class_name === 'stdClass' OR ! $row)
{
@@ -227,4 +198,18 @@ class CI_DB_oci8_result extends CI_DB_result {
return $class_name;
}
+ // --------------------------------------------------------------------
+
+ /**
+ * Destructor
+ *
+ * Attempt to free remaining statement IDs.
+ *
+ * @see https://github.com/bcit-ci/CodeIgniter/pull/5896
+ * @return void
+ */
+ public function __destruct()
+ {
+ $this->free_result();
+ }
}
diff --git a/system/database/drivers/odbc/index.html b/system/database/drivers/odbc/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/database/drivers/odbc/index.html
+++ b/system/database/drivers/odbc/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/database/drivers/pdo/index.html b/system/database/drivers/pdo/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/database/drivers/pdo/index.html
+++ b/system/database/drivers/pdo/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/database/drivers/pdo/subdrivers/index.html b/system/database/drivers/pdo/subdrivers/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/database/drivers/pdo/subdrivers/index.html
+++ b/system/database/drivers/pdo/subdrivers/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/database/drivers/postgre/index.html b/system/database/drivers/postgre/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/database/drivers/postgre/index.html
+++ b/system/database/drivers/postgre/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php
index 15d800b46..1cd473f2b 100644
--- a/system/database/drivers/postgre/postgre_driver.php
+++ b/system/database/drivers/postgre/postgre_driver.php
@@ -155,6 +155,13 @@ class CI_DB_postgre_driver extends CI_DB {
return FALSE;
}
+ if (pg_set_client_encoding($this->conn_id, $this->char_set) !== 0)
+ {
+ log_message('error', "Database: Unable to set the configured connection charset ('{$this->char_set}').");
+ pg_close($this->conn_id);
+ return ($this->db->db_debug) ? $this->display_error('db_unable_to_set_charset', $this->char_set) : FALSE;
+ }
+
empty($this->schema) OR $this->simple_query('SET search_path TO '.$this->schema.',public');
}
@@ -182,19 +189,6 @@ class CI_DB_postgre_driver extends CI_DB {
// --------------------------------------------------------------------
/**
- * Set client character set
- *
- * @param string $charset
- * @return bool
- */
- protected function _db_set_charset($charset)
- {
- return (pg_set_client_encoding($this->conn_id, $charset) === 0);
- }
-
- // --------------------------------------------------------------------
-
- /**
* Database version number
*
* @return string
@@ -313,7 +307,7 @@ class CI_DB_postgre_driver extends CI_DB {
*/
public function escape($str)
{
- if (is_php('5.4.4') && (is_string($str) OR (is_object($str) && method_exists($str, '__toString'))))
+ if (is_string($str) OR (is_object($str) && method_exists($str, '__toString')))
{
return pg_escape_literal($this->conn_id, $str);
}
diff --git a/system/database/drivers/sqlite/index.html b/system/database/drivers/sqlite/index.html
deleted file mode 100644
index b702fbc39..000000000
--- a/system/database/drivers/sqlite/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <title>403 Forbidden</title>
-</head>
-<body>
-
-<p>Directory access is forbidden.</p>
-
-</body>
-</html>
diff --git a/system/database/drivers/sqlite/sqlite_driver.php b/system/database/drivers/sqlite/sqlite_driver.php
deleted file mode 100644
index 188f00c93..000000000
--- a/system/database/drivers/sqlite/sqlite_driver.php
+++ /dev/null
@@ -1,331 +0,0 @@
-<?php
-/**
- * CodeIgniter
- *
- * An open source application development framework for PHP
- *
- * This content is released under the MIT License (MIT)
- *
- * Copyright (c) 2019 - 2022, CodeIgniter Foundation
- *
- * 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 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
- * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
- * @license https://opensource.org/licenses/MIT MIT License
- * @link https://codeigniter.com
- * @since Version 1.3.0
- * @filesource
- */
-defined('BASEPATH') OR exit('No direct script access allowed');
-
-/**
- * SQLite Database Adapter Class
- *
- * Note: _DB is an extender class that the app controller
- * creates dynamically based on whether the query builder
- * class is being used or not.
- *
- * @package CodeIgniter
- * @subpackage Drivers
- * @category Database
- * @author EllisLab Dev Team
- * @link https://codeigniter.com/userguide3/database/
- */
-class CI_DB_sqlite_driver extends CI_DB {
-
- /**
- * Database driver
- *
- * @var string
- */
- public $dbdriver = 'sqlite';
-
- // --------------------------------------------------------------------
-
- /**
- * ORDER BY random keyword
- *
- * @var array
- */
- protected $_random_keyword = array('RANDOM()', 'RANDOM()');
-
- // --------------------------------------------------------------------
-
- /**
- * Non-persistent database connection
- *
- * @param bool $persistent
- * @return resource
- */
- public function db_connect($persistent = FALSE)
- {
- $error = NULL;
- $conn_id = ($persistent === TRUE)
- ? sqlite_popen($this->database, 0666, $error)
- : sqlite_open($this->database, 0666, $error);
-
- isset($error) && log_message('error', $error);
-
- return $conn_id;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Database version number
- *
- * @return string
- */
- public function version()
- {
- return isset($this->data_cache['version'])
- ? $this->data_cache['version']
- : $this->data_cache['version'] = sqlite_libversion();
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Execute the query
- *
- * @param string $sql an SQL query
- * @return resource
- */
- protected function _execute($sql)
- {
- return $this->is_write_type($sql)
- ? sqlite_exec($this->conn_id, $sql)
- : sqlite_query($this->conn_id, $sql);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Begin Transaction
- *
- * @return bool
- */
- protected function _trans_begin()
- {
- return $this->simple_query('BEGIN TRANSACTION');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Commit Transaction
- *
- * @return bool
- */
- protected function _trans_commit()
- {
- return $this->simple_query('COMMIT');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Rollback Transaction
- *
- * @return bool
- */
- protected function _trans_rollback()
- {
- return $this->simple_query('ROLLBACK');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Platform-dependant string escape
- *
- * @param string
- * @return string
- */
- protected function _escape_str($str)
- {
- return sqlite_escape_string($str);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Affected Rows
- *
- * @return int
- */
- public function affected_rows()
- {
- return sqlite_changes($this->conn_id);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Insert ID
- *
- * @return int
- */
- public function insert_id()
- {
- return sqlite_last_insert_rowid($this->conn_id);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * List table query
- *
- * Generates a platform-specific query string so that the table names can be fetched
- *
- * @param bool $prefix_limit
- * @return string
- */
- protected function _list_tables($prefix_limit = FALSE)
- {
- $sql = "SELECT name FROM sqlite_master WHERE type='table'";
-
- if ($prefix_limit !== FALSE && $this->dbprefix != '')
- {
- return $sql." AND 'name' LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
- }
-
- return $sql;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Show column query
- *
- * Generates a platform-specific query string so that the column names can be fetched
- *
- * @param string $table
- * @return bool
- */
- protected function _list_columns($table = '')
- {
- // Not supported
- return FALSE;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Returns an object with field data
- *
- * @param string $table
- * @return array
- */
- public function field_data($table)
- {
- if (($query = $this->query('PRAGMA TABLE_INFO('.$this->protect_identifiers($table, TRUE, NULL, FALSE).')')) === FALSE)
- {
- return FALSE;
- }
-
- $query = $query->result_array();
- if (empty($query))
- {
- return FALSE;
- }
-
- $retval = array();
- for ($i = 0, $c = count($query); $i < $c; $i++)
- {
- $retval[$i] = new stdClass();
- $retval[$i]->name = $query[$i]['name'];
- $retval[$i]->type = $query[$i]['type'];
- $retval[$i]->max_length = NULL;
- $retval[$i]->default = $query[$i]['dflt_value'];
- $retval[$i]->primary_key = isset($query[$i]['pk']) ? (int) $query[$i]['pk'] : 0;
- }
-
- return $retval;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Error
- *
- * Returns an array containing code and message of the last
- * database error that has occured.
- *
- * @return array
- */
- public function error()
- {
- $error = array('code' => sqlite_last_error($this->conn_id));
- $error['message'] = sqlite_error_string($error['code']);
- return $error;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Replace statement
- *
- * Generates a platform-specific replace string from the supplied data
- *
- * @param string $table Table name
- * @param array $keys INSERT keys
- * @param array $values INSERT values
- * @return string
- */
- protected function _replace($table, $keys, $values)
- {
- return 'INSERT OR '.parent::_replace($table, $keys, $values);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Truncate statement
- *
- * Generates a platform-specific truncate string from the supplied data
- *
- * If the database does not support the TRUNCATE statement,
- * then this function maps to 'DELETE FROM table'
- *
- * @param string $table
- * @return string
- */
- protected function _truncate($table)
- {
- return 'DELETE FROM '.$table;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Close DB Connection
- *
- * @return void
- */
- protected function _close()
- {
- sqlite_close($this->conn_id);
- }
-
-}
diff --git a/system/database/drivers/sqlite/sqlite_forge.php b/system/database/drivers/sqlite/sqlite_forge.php
deleted file mode 100644
index 60aaa0995..000000000
--- a/system/database/drivers/sqlite/sqlite_forge.php
+++ /dev/null
@@ -1,206 +0,0 @@
-<?php
-/**
- * CodeIgniter
- *
- * An open source application development framework for PHP
- *
- * This content is released under the MIT License (MIT)
- *
- * Copyright (c) 2019 - 2022, CodeIgniter Foundation
- *
- * 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 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
- * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
- * @license https://opensource.org/licenses/MIT MIT License
- * @link https://codeigniter.com
- * @since Version 1.3.0
- * @filesource
- */
-defined('BASEPATH') OR exit('No direct script access allowed');
-
-/**
- * SQLite Forge Class
- *
- * @category Database
- * @author EllisLab Dev Team
- * @link https://codeigniter.com/userguide3/database/
- */
-class CI_DB_sqlite_forge extends CI_DB_forge {
-
- /**
- * CREATE TABLE IF statement
- *
- * @var string
- */
- protected $_create_table_if = FALSE;
-
- /**
- * UNSIGNED support
- *
- * @var bool|array
- */
- protected $_unsigned = FALSE;
-
- /**
- * NULL value representation in CREATE/ALTER TABLE statements
- *
- * @var string
- */
- protected $_null = 'NULL';
-
- // --------------------------------------------------------------------
-
- /**
- * Create database
- *
- * @param string $db_name (ignored)
- * @return bool
- */
- public function create_database($db_name)
- {
- // In SQLite, a database is created when you connect to the database.
- // We'll return TRUE so that an error isn't generated
- return TRUE;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Drop database
- *
- * @param string $db_name (ignored)
- * @return bool
- */
- public function drop_database($db_name)
- {
- if ( ! file_exists($this->db->database) OR ! @unlink($this->db->database))
- {
- return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE;
- }
- elseif ( ! empty($this->db->data_cache['db_names']))
- {
- $key = array_search(strtolower($this->db->database), array_map('strtolower', $this->db->data_cache['db_names']), TRUE);
- if ($key !== FALSE)
- {
- unset($this->db->data_cache['db_names'][$key]);
- }
- }
-
- return TRUE;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * ALTER TABLE
- *
- * @todo implement drop_column(), modify_column()
- * @param string $alter_type ALTER type
- * @param string $table Table name
- * @param mixed $field Column definition
- * @return string|string[]
- */
- protected function _alter_table($alter_type, $table, $field)
- {
- if ($alter_type === 'DROP' OR $alter_type === 'CHANGE')
- {
- // drop_column():
- // BEGIN TRANSACTION;
- // CREATE TEMPORARY TABLE t1_backup(a,b);
- // INSERT INTO t1_backup SELECT a,b FROM t1;
- // DROP TABLE t1;
- // CREATE TABLE t1(a,b);
- // INSERT INTO t1 SELECT a,b FROM t1_backup;
- // DROP TABLE t1_backup;
- // COMMIT;
-
- return FALSE;
- }
-
- return parent::_alter_table($alter_type, $table, $field);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Process column
- *
- * @param array $field
- * @return string
- */
- protected function _process_column($field)
- {
- return $this->db->escape_identifiers($field['name'])
- .' '.$field['type']
- .$field['auto_increment']
- .$field['null']
- .$field['unique']
- .$field['default'];
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Field attribute TYPE
- *
- * Performs a data type mapping between different databases.
- *
- * @param array &$attributes
- * @return void
- */
- protected function _attr_type(&$attributes)
- {
- switch (strtoupper($attributes['TYPE']))
- {
- case 'ENUM':
- case 'SET':
- $attributes['TYPE'] = 'TEXT';
- return;
- default: return;
- }
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Field attribute AUTO_INCREMENT
- *
- * @param array &$attributes
- * @param array &$field
- * @return void
- */
- protected function _attr_auto_increment(&$attributes, &$field)
- {
- if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE && stripos($field['type'], 'int') !== FALSE)
- {
- $field['type'] = 'INTEGER PRIMARY KEY';
- $field['default'] = '';
- $field['null'] = '';
- $field['unique'] = '';
- $field['auto_increment'] = ' AUTOINCREMENT';
-
- $this->primary_keys = array();
- }
- }
-
-}
diff --git a/system/database/drivers/sqlite/sqlite_result.php b/system/database/drivers/sqlite/sqlite_result.php
deleted file mode 100644
index 1df9025ea..000000000
--- a/system/database/drivers/sqlite/sqlite_result.php
+++ /dev/null
@@ -1,165 +0,0 @@
-<?php
-/**
- * CodeIgniter
- *
- * An open source application development framework for PHP
- *
- * This content is released under the MIT License (MIT)
- *
- * Copyright (c) 2019 - 2022, CodeIgniter Foundation
- *
- * 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 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
- * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
- * @license https://opensource.org/licenses/MIT MIT License
- * @link https://codeigniter.com
- * @since Version 1.3.0
- * @filesource
- */
-defined('BASEPATH') OR exit('No direct script access allowed');
-
-/**
- * SQLite Result Class
- *
- * This class extends the parent result class: CI_DB_result
- *
- * @category Database
- * @author EllisLab Dev Team
- * @link https://codeigniter.com/userguide3/database/
- */
-class CI_DB_sqlite_result extends CI_DB_result {
-
- /**
- * Number of rows in the result set
- *
- * @return int
- */
- public function num_rows()
- {
- return is_int($this->num_rows)
- ? $this->num_rows
- : $this->num_rows = @sqlite_num_rows($this->result_id);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Number of fields in the result set
- *
- * @return int
- */
- public function num_fields()
- {
- return @sqlite_num_fields($this->result_id);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Fetch Field Names
- *
- * Generates an array of column names
- *
- * @return array
- */
- public function list_fields()
- {
- $field_names = array();
- for ($i = 0, $c = $this->num_fields(); $i < $c; $i++)
- {
- $field_names[$i] = sqlite_field_name($this->result_id, $i);
- }
-
- return $field_names;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Field data
- *
- * Generates an array of objects containing field meta-data
- *
- * @return array
- */
- public function field_data()
- {
- $retval = array();
- for ($i = 0, $c = $this->num_fields(); $i < $c; $i++)
- {
- $retval[$i] = new stdClass();
- $retval[$i]->name = sqlite_field_name($this->result_id, $i);
- $retval[$i]->type = NULL;
- $retval[$i]->max_length = NULL;
- }
-
- return $retval;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Data Seek
- *
- * Moves the internal pointer to the desired offset. We call
- * this internally before fetching results to make sure the
- * result set starts at zero.
- *
- * @param int $n
- * @return bool
- */
- public function data_seek($n = 0)
- {
- return sqlite_seek($this->result_id, $n);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Result - associative array
- *
- * Returns the result set as an array
- *
- * @return array
- */
- protected function _fetch_assoc()
- {
- return sqlite_fetch_array($this->result_id);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Result - object
- *
- * Returns the result set as an object
- *
- * @param string $class_name
- * @return object
- */
- protected function _fetch_object($class_name = 'stdClass')
- {
- return sqlite_fetch_object($this->result_id, $class_name);
- }
-
-}
diff --git a/system/database/drivers/sqlite/sqlite_utility.php b/system/database/drivers/sqlite/sqlite_utility.php
deleted file mode 100644
index 5f9adf23b..000000000
--- a/system/database/drivers/sqlite/sqlite_utility.php
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-/**
- * CodeIgniter
- *
- * An open source application development framework for PHP
- *
- * This content is released under the MIT License (MIT)
- *
- * Copyright (c) 2019 - 2022, CodeIgniter Foundation
- *
- * 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 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
- * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
- * @license https://opensource.org/licenses/MIT MIT License
- * @link https://codeigniter.com
- * @since Version 1.3.0
- * @filesource
- */
-defined('BASEPATH') OR exit('No direct script access allowed');
-
-/**
- * SQLite Utility Class
- *
- * @category Database
- * @author EllisLab Dev Team
- * @link https://codeigniter.com/userguide3/database/
- */
-class CI_DB_sqlite_utility extends CI_DB_utility {
-
- /**
- * Export
- *
- * @param array $params Preferences
- * @return mixed
- */
- protected function _backup($params = array())
- {
- // Currently unsupported
- return $this->db->display_error('db_unsupported_feature');
- }
-
-}
diff --git a/system/database/drivers/sqlite3/index.html b/system/database/drivers/sqlite3/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/database/drivers/sqlite3/index.html
+++ b/system/database/drivers/sqlite3/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/database/drivers/sqlsrv/index.html b/system/database/drivers/sqlsrv/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/database/drivers/sqlsrv/index.html
+++ b/system/database/drivers/sqlsrv/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/database/index.html b/system/database/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/database/index.html
+++ b/system/database/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/fonts/index.html b/system/fonts/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/fonts/index.html
+++ b/system/fonts/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php
index 9fcbd1b2d..9f707524a 100644
--- a/system/helpers/captcha_helper.php
+++ b/system/helpers/captcha_helper.php
@@ -55,13 +55,10 @@ if ( ! function_exists('create_captcha'))
/**
* Create CAPTCHA
*
- * @param array $data Data for the CAPTCHA
- * @param string $img_path Path to create the image in (deprecated)
- * @param string $img_url URL to the CAPTCHA image folder (deprecated)
- * @param string $font_path Server path to font (deprecated)
- * @return string
+ * @param array $data Data for the CAPTCHA
+ * @return array
*/
- function create_captcha($data = '', $img_path = '', $img_url = '', $font_path = '')
+ function create_captcha($data)
{
$defaults = array(
'word' => '',
@@ -69,10 +66,12 @@ if ( ! function_exists('create_captcha'))
'img_url' => '',
'img_width' => '150',
'img_height' => '30',
+ 'img_alt' => 'captcha',
+ 'img_class' => '',
'font_path' => '',
+ 'font_size' => 16,
'expiration' => 7200,
'word_length' => 8,
- 'font_size' => 16,
'img_id' => '',
'pool' => '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
'colors' => array(
@@ -83,6 +82,8 @@ if ( ! function_exists('create_captcha'))
)
);
+ $now = microtime(TRUE);
+
foreach ($defaults as $key => $val)
{
if ( ! is_array($data) && empty($$key))
@@ -103,7 +104,7 @@ if ( ! function_exists('create_captcha'))
if ($img_path === '' OR $img_url === '')
{
- log_message('error', 'create_captcha(): $img_path and $img_url are required.');
+ log_message('error', 'create_captcha(): img_path and img_url are required.');
return FALSE;
}
@@ -113,23 +114,41 @@ if ( ! function_exists('create_captcha'))
return FALSE;
}
- // -----------------------------------
- // Remove old images
- // -----------------------------------
+ if ($img_url !== '' OR $img_path !== '')
+ {
+ if ($img_path === '' OR $img_url === '')
+ {
+ log_message('error', 'create_captcha(): $img_path and $img_url are required.');
+ return FALSE;
+ }
- $now = microtime(TRUE);
+ if ( ! is_dir($img_path) OR ! is_really_writable($img_path))
+ {
+ log_message('error', "create_captcha(): '{$img_path}' is not a dir, nor is it writable.");
+ return FALSE;
+ }
- $current_dir = @opendir($img_path);
- while ($filename = @readdir($current_dir))
- {
- if (in_array(substr($filename, -4), array('.jpg', '.png'))
- && (str_replace(array('.jpg', '.png'), '', $filename) + $expiration) < $now)
+ /**
+ * Remove old images
+ */
+ $current_dir = @opendir($img_path);
+ while ($filename = @readdir($current_dir))
{
- @unlink($img_path.$filename);
+ if (preg_match('#^(?<ts>\d{10})\.png$#', $filename, $match) && ($match['ts'] + $expiration) < $now)
+ {
+ @unlink($img_path.$filename);
+ }
}
- }
- @closedir($current_dir);
+ @closedir($current_dir);
+
+ // This variable will later be used later to determine whether we write to disk or output a data:image URI
+ $img_filename = $now.'.png';
+ }
+ else
+ {
+ $img_filename = NULL;
+ }
// -----------------------------------
// Do we have a "word" yet?
@@ -239,8 +258,8 @@ if ( ! function_exists('create_captcha'))
// Determine angle and position
// -----------------------------------
$length = strlen($word);
- $angle = ($length >= 6) ? mt_rand(-($length-6), ($length-6)) : 0;
- $x_axis = mt_rand(6, (360/$length)-16);
+ $angle = ($length >= 6) ? mt_rand(-($length - 6), ($length - 6)) : 0;
+ $x_axis = mt_rand(6, (360 / $length)-16);
$y_axis = ($angle >= 0) ? mt_rand($img_height, $img_width) : mt_rand(6, $img_height);
// Create image
@@ -328,24 +347,34 @@ if ( ! function_exists('create_captcha'))
// -----------------------------------
// Generate the image
// -----------------------------------
- $img_url = rtrim($img_url, '/').'/';
- if (function_exists('imagejpeg'))
+ if (isset($img_filename))
{
- $img_filename = $now.'.jpg';
- imagejpeg($im, $img_path.$img_filename);
- }
- elseif (function_exists('imagepng'))
- {
- $img_filename = $now.'.png';
+ $img_src = rtrim($img_url, '/').'/'.$img_filename;
imagepng($im, $img_path.$img_filename);
}
else
{
- return FALSE;
+ // I don't see an easier way to get the image contents without writing to file
+ $buffer = fopen('php://memory', 'wb+');
+ imagepng($im, $buffer);
+ rewind($buffer);
+ $img_src = '';
+
+ // fread() will return an empty string (not FALSE) after the entire contents are read
+ while (strlen($read = fread($buffer, 4096)))
+ {
+ $img_src .= $read;
+ }
+
+ fclose($buffer);
+ $img_src = 'data:image/png;base64,'.base64_encode($img_src);
}
- $img = '<img '.($img_id === '' ? '' : 'id="'.$img_id.'"').' src="'.$img_url.$img_filename.'" style="width: '.$img_width.'px; height: '.$img_height .'px; border: 0;" alt=" " />';
+ $img_class = trim($img_class);
+ $img_class = (bool) strlen($img_class) ? 'class="'.$img_class.'" ' : '';
+
+ $img = '<img '.($img_id === '' ? '' : 'id="'.$img_id.'"').' src="'.$img_src.'" style="width: '.$img_width.'px; height: '.$img_height .'px; border: 0;" '.$img_class.'alt="'.$img_alt.'" />';
ImageDestroy($im);
return array('word' => $word, 'time' => $now, 'image' => $img, 'filename' => $img_filename);
diff --git a/system/helpers/cookie_helper.php b/system/helpers/cookie_helper.php
index abe492f8e..0325e3db3 100644
--- a/system/helpers/cookie_helper.php
+++ b/system/helpers/cookie_helper.php
@@ -60,7 +60,7 @@ if ( ! function_exists('set_cookie'))
*
* @param mixed
* @param string the value of the cookie
- * @param string the number of seconds until expiration
+ * @param int the number of seconds until expiration
* @param string the cookie domain. Usually: .yourdomain.com
* @param string the cookie path
* @param string the cookie prefix
@@ -68,10 +68,10 @@ if ( ! function_exists('set_cookie'))
* @param bool true makes the cookie accessible via http(s) only (no javascript)
* @return void
*/
- function set_cookie($name, $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = NULL, $httponly = NULL)
+ function set_cookie($name, $value = '', $expire = 0, $domain = '', $path = '/', $prefix = '', $secure = NULL, $httponly = NULL, $samesite = NULL)
{
// Set the config file options
- get_instance()->input->set_cookie($name, $value, $expire, $domain, $path, $prefix, $secure, $httponly);
+ get_instance()->input->set_cookie($name, $value, $expire, $domain, $path, $prefix, $secure, $httponly, $samesite);
}
}
@@ -86,9 +86,8 @@ if ( ! function_exists('get_cookie'))
* @param bool
* @return mixed
*/
- function get_cookie($index, $xss_clean = NULL)
+ function get_cookie($index, $xss_clean = FALSE)
{
- is_bool($xss_clean) OR $xss_clean = (config_item('global_xss_filtering') === TRUE);
$prefix = isset($_COOKIE[$index]) ? '' : config_item('cookie_prefix');
return get_instance()->input->cookie($prefix.$index, $xss_clean);
}
diff --git a/system/helpers/date_helper.php b/system/helpers/date_helper.php
index 5b2f3e099..6ea9d82bd 100644
--- a/system/helpers/date_helper.php
+++ b/system/helpers/date_helper.php
@@ -123,46 +123,6 @@ if ( ! function_exists('mdate'))
// ------------------------------------------------------------------------
-if ( ! function_exists('standard_date'))
-{
- /**
- * Standard Date
- *
- * Returns a date formatted according to the submitted standard.
- *
- * As of PHP 5.2, the DateTime extension provides constants that
- * serve for the exact same purpose and are used with date().
- *
- * @todo Remove in version 3.1+.
- * @deprecated 3.0.0 Use PHP's native date() instead.
- * @link https://www.php.net/manual/en/class.datetime.php#datetime.constants.types
- *
- * @example date(DATE_RFC822, now()); // default
- * @example date(DATE_W3C, $time); // a different format and time
- *
- * @param string $fmt = 'DATE_RFC822' the chosen format
- * @param int $time = NULL Unix timestamp
- * @return string
- */
- function standard_date($fmt = 'DATE_RFC822', $time = NULL)
- {
- if (empty($time))
- {
- $time = now();
- }
-
- // Procedural style pre-defined constants from the DateTime extension
- if (strpos($fmt, 'DATE_') !== 0 OR defined($fmt) === FALSE)
- {
- return FALSE;
- }
-
- return date(constant($fmt), $time);
- }
-}
-
-// ------------------------------------------------------------------------
-
if ( ! function_exists('timespan'))
{
/**
@@ -491,72 +451,6 @@ if ( ! function_exists('human_to_unix'))
// ------------------------------------------------------------------------
-if ( ! function_exists('nice_date'))
-{
- /**
- * Turns many "reasonably-date-like" strings into something
- * that is actually useful. This only works for dates after unix epoch.
- *
- * @deprecated 3.1.3 Use DateTime::createFromFormat($input_format, $input)->format($output_format);
- * @param string The terribly formatted date-like string
- * @param string Date format to return (same as php date function)
- * @return string
- */
- function nice_date($bad_date = '', $format = FALSE)
- {
- if (empty($bad_date))
- {
- return 'Unknown';
- }
- elseif (empty($format))
- {
- $format = 'U';
- }
-
- // Date like: YYYYMM
- if (preg_match('/^\d{6}$/i', $bad_date))
- {
- if (in_array(substr($bad_date, 0, 2), array('19', '20')))
- {
- $year = substr($bad_date, 0, 4);
- $month = substr($bad_date, 4, 2);
- }
- else
- {
- $month = substr($bad_date, 0, 2);
- $year = substr($bad_date, 2, 4);
- }
-
- return date($format, strtotime($year.'-'.$month.'-01'));
- }
-
- // Date Like: YYYYMMDD
- if (preg_match('/^\d{8}$/i', $bad_date, $matches))
- {
- return DateTime::createFromFormat('Ymd', $bad_date)->format($format);
- }
-
- // Date Like: MM-DD-YYYY __or__ M-D-YYYY (or anything in between)
- if (preg_match('/^(\d{1,2})-(\d{1,2})-(\d{4})$/i', $bad_date, $matches))
- {
- return date($format, strtotime($matches[3].'-'.$matches[1].'-'.$matches[2]));
- }
-
- // Any other kind of string, when converted into UNIX time,
- // produces "0 seconds after epoc..." is probably bad...
- // return "Invalid Date".
- if (date('U', strtotime($bad_date)) === '0')
- {
- return 'Invalid Date';
- }
-
- // It's probably a valid-ish date format already
- return date($format, strtotime($bad_date));
- }
-}
-
-// ------------------------------------------------------------------------
-
if ( ! function_exists('timezone_menu'))
{
/**
diff --git a/system/helpers/download_helper.php b/system/helpers/download_helper.php
index 9b361c4bd..2c72c563a 100644
--- a/system/helpers/download_helper.php
+++ b/system/helpers/download_helper.php
@@ -57,7 +57,7 @@ if ( ! function_exists('force_download'))
*
* Generates headers that force a download to happen
*
- * @param string filename
+ * @param mixed filename (or an array of local file path => destination filename)
* @param mixed the data to be downloaded
* @param bool whether to try and send the actual file MIME type
* @return void
@@ -70,14 +70,34 @@ if ( ! function_exists('force_download'))
}
elseif ($data === NULL)
{
- if ( ! @is_file($filename) OR ($filesize = @filesize($filename)) === FALSE)
+ // Is $filename an array as ['local source path' => 'destination filename']?
+ if (is_array($filename))
{
- return;
+ if (count($filename) !== 1)
+ {
+ return;
+ }
+
+ reset($filename);
+ $filepath = key($filename);
+ $filename = current($filename);
+
+ if (is_int($filepath))
+ {
+ return;
+ }
+ }
+ else
+ {
+ $filepath = $filename;
+ $filename = explode('/', str_replace(DIRECTORY_SEPARATOR, '/', $filename));
+ $filename = end($filename);
}
- $filepath = $filename;
- $filename = explode('/', str_replace(DIRECTORY_SEPARATOR, '/', $filename));
- $filename = end($filename);
+ if ( ! @is_file($filepath) OR ($filesize = @filesize($filepath)) === FALSE)
+ {
+ return;
+ }
}
else
{
@@ -122,20 +142,23 @@ if ( ! function_exists('force_download'))
$filename = implode('.', $x);
}
- if ($data === NULL && ($fp = @fopen($filepath, 'rb')) === FALSE)
- {
- return;
- }
-
// Clean output buffer
if (ob_get_level() !== 0 && @ob_end_clean() === FALSE)
{
@ob_clean();
}
+ // RFC 6266 allows for multibyte filenames, but only in UTF-8,
+ // so we have to make it conditional ...
+ $charset = strtoupper(config_item('charset'));
+ $utf8_filename = ($charset !== 'UTF-8')
+ ? get_instance()->utf8->convert_to_utf8($filename, $charset)
+ : $filename;
+ isset($utf8_filename[0]) && $utf8_filename = " filename*=UTF-8''".rawurlencode($utf8_filename);
+
// Generate the server headers
header('Content-Type: '.$mime);
- header('Content-Disposition: attachment; filename="'.$filename.'"');
+ header('Content-Disposition: attachment; filename="'.$filename.'";'.$utf8_filename);
header('Expires: 0');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.$filesize);
@@ -147,13 +170,12 @@ if ( ! function_exists('force_download'))
exit($data);
}
- // Flush 1MB chunks of data
- while ( ! feof($fp) && ($data = fread($fp, 1048576)) !== FALSE)
+ // Flush the file
+ if (@readfile($filepath) === FALSE)
{
- echo $data;
+ return;
}
- fclose($fp);
exit;
}
}
diff --git a/system/helpers/email_helper.php b/system/helpers/email_helper.php
deleted file mode 100644
index ec0c4207e..000000000
--- a/system/helpers/email_helper.php
+++ /dev/null
@@ -1,85 +0,0 @@
-<?php
-/**
- * CodeIgniter
- *
- * An open source application development framework for PHP
- *
- * This content is released under the MIT License (MIT)
- *
- * Copyright (c) 2019 - 2022, CodeIgniter Foundation
- *
- * 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 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
- * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
- * @license https://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');
-
-/**
- * CodeIgniter Email Helpers
- *
- * @package CodeIgniter
- * @subpackage Helpers
- * @category Helpers
- * @author EllisLab Dev Team
- * @link https://codeigniter.com/userguide3/helpers/email_helper.html
- */
-
-// ------------------------------------------------------------------------
-
-if ( ! function_exists('valid_email'))
-{
- /**
- * Validate email address
- *
- * @deprecated 3.0.0 Use PHP's filter_var() instead
- * @param string $email
- * @return bool
- */
- function valid_email($email)
- {
- return (bool) filter_var($email, FILTER_VALIDATE_EMAIL);
- }
-}
-
-// ------------------------------------------------------------------------
-
-if ( ! function_exists('send_email'))
-{
- /**
- * Send an email
- *
- * @deprecated 3.0.0 Use PHP's mail() instead
- * @param string $recipient
- * @param string $subject
- * @param string $message
- * @return bool
- */
- function send_email($recipient, $subject, $message)
- {
- return mail($recipient, $subject, $message);
- }
-}
diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php
index a2adaf296..a751f771e 100644
--- a/system/helpers/file_helper.php
+++ b/system/helpers/file_helper.php
@@ -50,26 +50,6 @@ defined('BASEPATH') OR exit('No direct script access allowed');
// ------------------------------------------------------------------------
-if ( ! function_exists('read_file'))
-{
- /**
- * Read File
- *
- * Opens the file specified in the path and returns it as a string.
- *
- * @todo Remove in version 3.1+.
- * @deprecated 3.0.0 It is now just an alias for PHP's native file_get_contents().
- * @param string $file Path to file
- * @return string File contents
- */
- function read_file($file)
- {
- return @file_get_contents($file);
- }
-}
-
-// ------------------------------------------------------------------------
-
if ( ! function_exists('write_file'))
{
/**
@@ -248,8 +228,9 @@ if ( ! function_exists('get_dir_file_info'))
}
elseif ($file[0] !== '.')
{
- $_filedata[$file] = get_file_info($source_dir.$file);
- $_filedata[$file]['relative_path'] = $relative_path;
+ $filedata = get_dir_file_info($source_dir.$file);
+ $filedata['relative_path'] = $relative_path;
+ $_filedata[] = $filedata;
}
}
diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php
index ba74ff5ef..191fc7e6d 100644
--- a/system/helpers/form_helper.php
+++ b/system/helpers/form_helper.php
@@ -274,11 +274,10 @@ if ( ! function_exists('form_upload'))
* Identical to the input function but adds the "file" type
*
* @param mixed
- * @param string
* @param mixed
* @return string
*/
- function form_upload($data = '', $value = '', $extra = '')
+ function form_upload($data = '', $extra = '')
{
$defaults = array('type' => 'file', 'name' => '');
is_array($data) OR $data = array('name' => $data);
@@ -677,25 +676,6 @@ if ( ! function_exists('form_close'))
// ------------------------------------------------------------------------
-if ( ! function_exists('form_prep'))
-{
- /**
- * Form Prep
- *
- * Formats text so that it can be safely placed in a form field in the event it has HTML tags.
- *
- * @deprecated 3.0.0 An alias for html_escape()
- * @param string|string[] $str Value to escape
- * @return string|string[] Escaped values
- */
- function form_prep($str)
- {
- return html_escape($str, TRUE);
- }
-}
-
-// ------------------------------------------------------------------------
-
if ( ! function_exists('set_value'))
{
/**
diff --git a/system/helpers/html_helper.php b/system/helpers/html_helper.php
index 93ecb1d35..98998c7c4 100644
--- a/system/helpers/html_helper.php
+++ b/system/helpers/html_helper.php
@@ -229,7 +229,7 @@ if ( ! function_exists('doctype'))
* @param string type The doctype to be generated
* @return string
*/
- function doctype($type = 'xhtml1-strict')
+ function doctype($type = 'html5')
{
static $doctypes;
@@ -360,51 +360,32 @@ if ( ! function_exists('meta'))
$name = array($name);
}
+ $allowed_types = array('charset', 'http-equiv', 'name', 'property');
$str = '';
foreach ($name as $meta)
{
- $type = (isset($meta['type']) && $meta['type'] !== 'name') ? 'http-equiv' : 'name';
- $name = isset($meta['name']) ? $meta['name'] : '';
- $content = isset($meta['content']) ? $meta['content'] : '';
- $newline = isset($meta['newline']) ? $meta['newline'] : "\n";
+ // This is to preserve BC with pre-3.1 versions where only
+ // 'http-equiv' (default) and 'name' were supported.
+ if (isset($meta['type']))
+ {
+ if ($meta['type'] === 'equiv')
+ {
+ $meta['type'] = 'http-equiv';
+ }
+ elseif ( ! in_array($meta['type'], $allowed_types, TRUE))
+ {
+ $meta['type'] = 'name';
+ }
+ }
- $str .= '<meta '.$type.'="'.$name.'" content="'.$content.'" />'.$newline;
+ $type = isset($meta['type']) ? $meta['type'] : 'name';
+ $name = isset($meta['name']) ? $meta['name'] : '';
+ $content = isset($meta['content']) ? $meta['content'] : '';
+ $newline = isset($meta['newline']) ? $meta['newline'] : "\n";
+
+ $str .= '<meta '.$type.'="'.$name.($type === 'charset' ? '' : '" content="'.$content).'" />'.$newline;
}
return $str;
}
}
-
-// ------------------------------------------------------------------------
-
-if ( ! function_exists('br'))
-{
- /**
- * Generates HTML BR tags based on number supplied
- *
- * @deprecated 3.0.0 Use str_repeat() instead
- * @param int $count Number of times to repeat the tag
- * @return string
- */
- function br($count = 1)
- {
- return str_repeat('<br />', $count);
- }
-}
-
-// ------------------------------------------------------------------------
-
-if ( ! function_exists('nbs'))
-{
- /**
- * Generates non-breaking space entities based on number supplied
- *
- * @deprecated 3.0.0 Use str_repeat() instead
- * @param int
- * @return string
- */
- function nbs($num = 1)
- {
- return str_repeat('&nbsp;', $num);
- }
-}
diff --git a/system/helpers/index.html b/system/helpers/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/helpers/index.html
+++ b/system/helpers/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/helpers/inflector_helper.php b/system/helpers/inflector_helper.php
index 91a5d84ff..75e98c817 100644
--- a/system/helpers/inflector_helper.php
+++ b/system/helpers/inflector_helper.php
@@ -286,3 +286,42 @@ if ( ! function_exists('is_countable'))
return word_is_countable($word);
}
}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('ordinal_format'))
+{
+ /**
+ * Returns the English ordinal numeral for a given number
+ *
+ * @param int $number
+ * @return string
+ */
+ function ordinal_format($number)
+ {
+ if ( ! ctype_digit((string) $number) OR $number < 1)
+ {
+ return $number;
+ }
+
+ $last_digit = array(
+ 0 => 'th',
+ 1 => 'st',
+ 2 => 'nd',
+ 3 => 'rd',
+ 4 => 'th',
+ 5 => 'th',
+ 6 => 'th',
+ 7 => 'th',
+ 8 => 'th',
+ 9 => 'th'
+ );
+
+ if (($number % 100) >= 11 && ($number % 100) <= 13)
+ {
+ return $number.'th';
+ }
+
+ return $number.$last_digit[$number % 10];
+ }
+}
diff --git a/system/helpers/security_helper.php b/system/helpers/security_helper.php
index dc2b1a43a..54851a094 100644
--- a/system/helpers/security_helper.php
+++ b/system/helpers/security_helper.php
@@ -81,30 +81,6 @@ if ( ! function_exists('sanitize_filename'))
}
}
-// --------------------------------------------------------------------
-
-if ( ! function_exists('do_hash'))
-{
- /**
- * Hash encode a string
- *
- * @todo Remove in version 3.1+.
- * @deprecated 3.0.0 Use PHP's native hash() instead.
- * @param string $str
- * @param string $type = 'sha1'
- * @return string
- */
- function do_hash($str, $type = 'sha1')
- {
- if ( ! in_array(strtolower($type), hash_algos()))
- {
- $type = 'md5';
- }
-
- return hash($type, $str);
- }
-}
-
// ------------------------------------------------------------------------
if ( ! function_exists('strip_image_tags'))
diff --git a/system/helpers/smiley_helper.php b/system/helpers/smiley_helper.php
deleted file mode 100644
index 091e6decc..000000000
--- a/system/helpers/smiley_helper.php
+++ /dev/null
@@ -1,256 +0,0 @@
-<?php
-/**
- * CodeIgniter
- *
- * An open source application development framework for PHP
- *
- * This content is released under the MIT License (MIT)
- *
- * Copyright (c) 2019 - 2022, CodeIgniter Foundation
- *
- * 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 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
- * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
- * @license https://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');
-
-/**
- * CodeIgniter Smiley Helpers
- *
- * @package CodeIgniter
- * @subpackage Helpers
- * @category Helpers
- * @author EllisLab Dev Team
- * @link https://codeigniter.com/userguide3/helpers/smiley_helper.html
- * @deprecated 3.0.0 This helper is too specific for CI.
- */
-
-// ------------------------------------------------------------------------
-
-if ( ! function_exists('smiley_js'))
-{
- /**
- * Smiley Javascript
- *
- * Returns the javascript required for the smiley insertion. Optionally takes
- * an array of aliases to loosely couple the smiley array to the view.
- *
- * @param mixed alias name or array of alias->field_id pairs
- * @param string field_id if alias name was passed in
- * @param bool
- * @return array
- */
- function smiley_js($alias = '', $field_id = '', $inline = TRUE)
- {
- static $do_setup = TRUE;
- $r = '';
-
- if ($alias !== '' && ! is_array($alias))
- {
- $alias = array($alias => $field_id);
- }
-
- if ($do_setup === TRUE)
- {
- $do_setup = FALSE;
- $m = array();
-
- if (is_array($alias))
- {
- foreach ($alias as $name => $id)
- {
- $m[] = '"'.$name.'" : "'.$id.'"';
- }
- }
-
- $m = '{'.implode(',', $m).'}';
-
- $r .= <<<EOF
- var smiley_map = {$m};
-
- function insert_smiley(smiley, field_id) {
- var el = document.getElementById(field_id), newStart;
-
- if ( ! el && smiley_map[field_id]) {
- el = document.getElementById(smiley_map[field_id]);
-
- if ( ! el)
- return false;
- }
-
- el.focus();
- smiley = " " + smiley;
-
- if ('selectionStart' in el) {
- newStart = el.selectionStart + smiley.length;
-
- el.value = el.value.substr(0, el.selectionStart) +
- smiley +
- el.value.substr(el.selectionEnd, el.value.length);
- el.setSelectionRange(newStart, newStart);
- }
- else if (document.selection) {
- document.selection.createRange().text = smiley;
- }
- }
-EOF;
- }
- elseif (is_array($alias))
- {
- foreach ($alias as $name => $id)
- {
- $r .= 'smiley_map["'.$name.'"] = "'.$id."\";\n";
- }
- }
-
- return ($inline)
- ? '<script type="text/javascript" charset="utf-8">/*<![CDATA[ */'.$r.'// ]]></script>'
- : $r;
- }
-}
-
-// ------------------------------------------------------------------------
-
-if ( ! function_exists('get_clickable_smileys'))
-{
- /**
- * Get Clickable Smileys
- *
- * Returns an array of image tag links that can be clicked to be inserted
- * into a form field.
- *
- * @param string the URL to the folder containing the smiley images
- * @param array
- * @return array
- */
- function get_clickable_smileys($image_url, $alias = '')
- {
- // For backward compatibility with js_insert_smiley
- if (is_array($alias))
- {
- $smileys = $alias;
- }
- elseif (FALSE === ($smileys = _get_smiley_array()))
- {
- return FALSE;
- }
-
- // Add a trailing slash to the file path if needed
- $image_url = rtrim($image_url, '/').'/';
-
- $used = array();
- foreach ($smileys as $key => $val)
- {
- // Keep duplicates from being used, which can happen if the
- // mapping array contains multiple identical replacements. For example:
- // :-) and :) might be replaced with the same image so both smileys
- // will be in the array.
- if (isset($used[$smileys[$key][0]]))
- {
- continue;
- }
-
- $link[] = '<a href="javascript:void(0);" onclick="insert_smiley(\''.$key.'\', \''.$alias.'\')"><img src="'.$image_url.$smileys[$key][0].'" alt="'.$smileys[$key][3].'" style="width: '.$smileys[$key][1].'; height: '.$smileys[$key][2].'; border: 0;" /></a>';
- $used[$smileys[$key][0]] = TRUE;
- }
-
- return $link;
- }
-}
-
-// ------------------------------------------------------------------------
-
-if ( ! function_exists('parse_smileys'))
-{
- /**
- * Parse Smileys
- *
- * Takes a string as input and swaps any contained smileys for the actual image
- *
- * @param string the text to be parsed
- * @param string the URL to the folder containing the smiley images
- * @param array
- * @return string
- */
- function parse_smileys($str = '', $image_url = '', $smileys = NULL)
- {
- if ($image_url === '' OR ( ! is_array($smileys) && FALSE === ($smileys = _get_smiley_array())))
- {
- return $str;
- }
-
- // Add a trailing slash to the file path if needed
- $image_url = rtrim($image_url, '/').'/';
-
- foreach ($smileys as $key => $val)
- {
- $str = str_replace($key, '<img src="'.$image_url.$smileys[$key][0].'" alt="'.$smileys[$key][3].'" style="width: '.$smileys[$key][1].'; height: '.$smileys[$key][2].'; border: 0;" />', $str);
- }
-
- return $str;
- }
-}
-
-// ------------------------------------------------------------------------
-
-if ( ! function_exists('_get_smiley_array'))
-{
- /**
- * Get Smiley Array
- *
- * Fetches the config/smiley.php file
- *
- * @return mixed
- */
- function _get_smiley_array()
- {
- static $_smileys;
-
- if ( ! is_array($_smileys))
- {
- if (file_exists(APPPATH.'config/smileys.php'))
- {
- include(APPPATH.'config/smileys.php');
- }
-
- if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/smileys.php'))
- {
- include(APPPATH.'config/'.ENVIRONMENT.'/smileys.php');
- }
-
- if (empty($smileys) OR ! is_array($smileys))
- {
- $_smileys = array();
- return FALSE;
- }
-
- $_smileys = $smileys;
- }
-
- return $_smileys;
- }
-}
diff --git a/system/helpers/string_helper.php b/system/helpers/string_helper.php
index 7370f39f3..0cd87e915 100644
--- a/system/helpers/string_helper.php
+++ b/system/helpers/string_helper.php
@@ -50,33 +50,6 @@ defined('BASEPATH') OR exit('No direct script access allowed');
// ------------------------------------------------------------------------
-if ( ! function_exists('trim_slashes'))
-{
- /**
- * Trim Slashes
- *
- * Removes any leading/trailing slashes from a string:
- *
- * /this/that/theother/
- *
- * becomes:
- *
- * this/that/theother
- *
- * @todo Remove in version 3.1+.
- * @deprecated 3.0.0 This is just an alias for PHP's native trim()
- *
- * @param string
- * @return string
- */
- function trim_slashes($str)
- {
- return trim($str, '/');
- }
-}
-
-// ------------------------------------------------------------------------
-
if ( ! function_exists('strip_slashes'))
{
/**
@@ -198,7 +171,7 @@ if ( ! function_exists('random_string'))
/**
* Create a "Random" String
*
- * @param string type of random string. basic, alpha, alnum, numeric, nozero, unique, md5, encrypt and sha1
+ * @param string type of random string. basic, alpha, alnum, numeric, nozero, md5 and sha1
* @param int number of characters
* @return string
*/
@@ -228,10 +201,8 @@ if ( ! function_exists('random_string'))
break;
}
return substr(str_shuffle(str_repeat($pool, ceil($len / strlen($pool)))), 0, $len);
- case 'unique': // todo: remove in 3.1+
case 'md5':
return md5(uniqid(mt_rand()));
- case 'encrypt': // todo: remove in 3.1+
case 'sha1':
return sha1(uniqid(mt_rand(), TRUE));
}
@@ -283,23 +254,3 @@ if ( ! function_exists('alternator'))
return $args[($i++ % count($args))];
}
}
-
-// ------------------------------------------------------------------------
-
-if ( ! function_exists('repeater'))
-{
- /**
- * Repeater function
- *
- * @todo Remove in version 3.1+.
- * @deprecated 3.0.0 This is just an alias for PHP's native str_repeat()
- *
- * @param string $data String to repeat
- * @param int $num Number of repeats
- * @return string
- */
- function repeater($data, $num = 1)
- {
- return ($num > 0) ? str_repeat($data, $num) : '';
- }
-}
diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php
index d1d7ec135..e3c9bc0a4 100644
--- a/system/helpers/url_helper.php
+++ b/system/helpers/url_helper.php
@@ -212,7 +212,7 @@ if ( ! function_exists('anchor_popup'))
{
$attributes = array($attributes);
- // Ref: http://www.w3schools.com/jsref/met_win_open.asp
+ // Ref: https://www.w3schools.com/jsref/met_win_open.asp
$window_name = '_blank';
}
elseif ( ! empty($attributes['window_name']))
@@ -444,7 +444,7 @@ if ( ! function_exists('prep_url'))
*/
function prep_url($str = '')
{
- if ($str === 'http://' OR $str === '')
+ if ($str === '')
{
return '';
}
@@ -471,31 +471,20 @@ if ( ! function_exists('url_title'))
* human-friendly URL string with a "separator" string
* as the word separator.
*
- * @todo Remove old 'dash' and 'underscore' usage in 3.1+.
* @param string $str Input string
- * @param string $separator Word separator
- * (usually '-' or '_')
+ * @param string $separator Word separator (usually '-' or '_')
* @param bool $lowercase Whether to transform the output string to lowercase
* @return string
*/
function url_title($str, $separator = '-', $lowercase = FALSE)
{
- if ($separator === 'dash')
- {
- $separator = '-';
- }
- elseif ($separator === 'underscore')
- {
- $separator = '_';
- }
-
$q_separator = preg_quote($separator, '#');
$trans = array(
'&.+?;' => '',
'[^\w\d _-]' => '',
'\s+' => $separator,
- '('.$q_separator.')+' => $separator
+ '('.$q_separator.')+' => $separator,
);
$str = strip_tags($str);
@@ -547,7 +536,7 @@ if ( ! function_exists('redirect'))
if (isset($_SERVER['SERVER_PROTOCOL'], $_SERVER['REQUEST_METHOD']) && $_SERVER['SERVER_PROTOCOL'] === 'HTTP/1.1')
{
$code = ($_SERVER['REQUEST_METHOD'] !== 'GET')
- ? 303 // reference: http://en.wikipedia.org/wiki/Post/Redirect/Get
+ ? 303 // reference: https://en.wikipedia.org/wiki/Post/Redirect/Get
: 307;
}
else
diff --git a/system/index.html b/system/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/index.html
+++ b/system/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/language/english/form_validation_lang.php b/system/language/english/form_validation_lang.php
index a2e300efa..fdfb3cfa6 100644
--- a/system/language/english/form_validation_lang.php
+++ b/system/language/english/form_validation_lang.php
@@ -44,6 +44,7 @@ $lang['form_validation_valid_email'] = 'The {field} field must contain a valid
$lang['form_validation_valid_emails'] = 'The {field} field must contain all valid email addresses.';
$lang['form_validation_valid_url'] = 'The {field} field must contain a valid URL.';
$lang['form_validation_valid_ip'] = 'The {field} field must contain a valid IP.';
+$lang['form_validation_valid_mac'] = 'The {field} field must contain a valid MAC.';
$lang['form_validation_valid_base64'] = 'The {field} field must contain a valid Base64 string.';
$lang['form_validation_min_length'] = 'The {field} field must be at least {param} characters in length.';
$lang['form_validation_max_length'] = 'The {field} field cannot exceed {param} characters in length.';
diff --git a/system/language/english/imglib_lang.php b/system/language/english/imglib_lang.php
index 01ac9d345..b0a80a5d0 100644
--- a/system/language/english/imglib_lang.php
+++ b/system/language/english/imglib_lang.php
@@ -45,6 +45,7 @@ $lang['imglib_unsupported_imagecreate'] = 'Your server does not support the GD f
$lang['imglib_gif_not_supported'] = 'GIF images are often not supported due to licensing restrictions. You may have to use JPG or PNG images instead.';
$lang['imglib_jpg_not_supported'] = 'JPG images are not supported.';
$lang['imglib_png_not_supported'] = 'PNG images are not supported.';
+$lang['imglib_webp_not_supported'] = 'WEBP images are not supported.';
$lang['imglib_jpg_or_png_required'] = 'The image resize protocol specified in your preferences only works with JPEG or PNG image types.';
$lang['imglib_copy_error'] = 'An error was encountered while attempting to replace the file. Please make sure your file directory is writable.';
$lang['imglib_rotate_unsupported'] = 'Image rotation does not appear to be supported by your server.';
diff --git a/system/language/english/index.html b/system/language/english/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/language/english/index.html
+++ b/system/language/english/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/language/index.html b/system/language/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/language/index.html
+++ b/system/language/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/libraries/Cache/Cache.php b/system/libraries/Cache/Cache.php
index d0c4c8881..f3dfe25e4 100644
--- a/system/libraries/Cache/Cache.php
+++ b/system/libraries/Cache/Cache.php
@@ -56,6 +56,7 @@ class CI_Cache extends CI_Driver_Library {
*/
protected $valid_drivers = array(
'apc',
+ 'apcu',
'dummy',
'file',
'memcached',
@@ -253,4 +254,16 @@ class CI_Cache extends CI_Driver_Library {
return $support[$driver];
}
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get currently loaded driver
+ *
+ * @return string
+ */
+ public function get_loaded_driver()
+ {
+ return $this->_adapter;
+ }
}
diff --git a/system/libraries/Cache/drivers/Cache_apcu.php b/system/libraries/Cache/drivers/Cache_apcu.php
new file mode 100644
index 000000000..01f80e79b
--- /dev/null
+++ b/system/libraries/Cache/drivers/Cache_apcu.php
@@ -0,0 +1,219 @@
+<?php
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP
+ *
+ * This content is released under the MIT License (MIT)
+ *
+ * Copyright (c) 2014 - 2019, 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 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
+ * @license https://opensource.org/licenses/MIT MIT License
+ * @link https://codeigniter.com
+ * @since Version 3.2.0
+ * @filesource
+ */
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/**
+ * CodeIgniter APCu Caching Class
+ *
+ * @package CodeIgniter
+ * @subpackage Libraries
+ * @category Core
+ * @author CodeIgniter Dev team
+ */
+class CI_Cache_apcu extends CI_Driver {
+
+ /**
+ * Class constructor
+ *
+ * Only present so that an error message is logged
+ * if APCu is not available.
+ *
+ * @return void
+ */
+ public function __construct()
+ {
+ if ( ! $this->is_supported())
+ {
+ log_message('error', 'Cache: Failed to initialize APCu; extension not loaded/enabled?');
+ }
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get
+ *
+ * Look for a value in the cache. If it exists, return the data
+ * if not, return FALSE
+ *
+ * @param string
+ * @return mixed value that is stored/FALSE on failure
+ */
+ public function get($id)
+ {
+ $success = FALSE;
+ $data = apcu_fetch($id, $success);
+
+ if ($success === TRUE)
+ {
+ return is_array($data)
+ ? $data[0]
+ : $data;
+ }
+
+ return FALSE;
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Cache Save
+ *
+ * @param string $id Cache ID
+ * @param mixed $data Data to store
+ * @param int $ttl Length of time (in seconds) to cache the data
+ * @param bool $raw Whether to store the raw value
+ * @return bool TRUE on success, FALSE on failure
+ */
+ public function save($id, $data, $ttl = 60, $raw = FALSE)
+ {
+ $ttl = (int) $ttl;
+
+ return apcu_store(
+ $id,
+ ($raw === TRUE ? $data : array($data, time(), $ttl)),
+ $ttl
+ );
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Delete from Cache
+ *
+ * @param mixed unique identifier of the item in the cache
+ * @return bool true on success/false on failure
+ */
+ public function delete($id)
+ {
+ return apcu_delete($id);
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Increment a raw value
+ *
+ * @param string $id Cache ID
+ * @param int $offset Step/value to add
+ * @return mixed New value on success or FALSE on failure
+ */
+ public function increment($id, $offset = 1)
+ {
+ return apcu_inc($id, $offset);
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Decrement a raw value
+ *
+ * @param string $id Cache ID
+ * @param int $offset Step/value to reduce by
+ * @return mixed New value on success or FALSE on failure
+ */
+ public function decrement($id, $offset = 1)
+ {
+ return apcu_dec($id, $offset);
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Clean the cache
+ *
+ * @return bool false on failure/true on success
+ */
+ public function clean()
+ {
+ return apcu_clear_cache();
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Cache Info
+ *
+ * @return mixed array on success, false on failure
+ */
+ public function cache_info()
+ {
+ return apcu_cache_info();
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get Cache Metadata
+ *
+ * @param mixed key to get cache metadata on
+ * @return mixed array on success/false on failure
+ */
+ public function get_metadata($id)
+ {
+ $success = FALSE;
+ $stored = apcu_fetch($id, $success);
+
+ if ($success === FALSE OR count($stored) !== 3)
+ {
+ return FALSE;
+ }
+
+ list($data, $time, $ttl) = $stored;
+
+ return array(
+ 'expire' => $time + $ttl,
+ 'mtime' => $time,
+ 'data' => $data
+ );
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * is_supported()
+ *
+ * Check to see if APCu is available on this system, bail if it isn't.
+ *
+ * @return bool
+ */
+ public function is_supported()
+ {
+ return (extension_loaded('apcu') && ini_get('apc.enabled'));
+ }
+} \ No newline at end of file
diff --git a/system/libraries/Cache/drivers/Cache_memcached.php b/system/libraries/Cache/drivers/Cache_memcached.php
index 89002de4f..55963bb82 100644
--- a/system/libraries/Cache/drivers/Cache_memcached.php
+++ b/system/libraries/Cache/drivers/Cache_memcached.php
@@ -103,10 +103,22 @@ class CI_Cache_memcached extends CI_Driver {
return;
}
- foreach ($this->_config as $cache_server)
+ foreach ($this->_config as $cache_name => $cache_server)
{
- isset($cache_server['hostname']) OR $cache_server['hostname'] = $defaults['host'];
- isset($cache_server['port']) OR $cache_server['port'] = $defaults['port'];
+ if ( ! isset($cache_server['hostname']))
+ {
+ log_message('debug', 'Cache: Memcache(d) configuration "'.$cache_name.'" doesn\'t include a hostname; ignoring.');
+ continue;
+ }
+ elseif ($cache_server['hostname'][0] === '/')
+ {
+ $cache_server['port'] = 0;
+ }
+ elseif (empty($cache_server['port']))
+ {
+ $cache_server['port'] = $defaults['port'];
+ }
+
isset($cache_server['weight']) OR $cache_server['weight'] = $defaults['weight'];
if ($this->_memcached instanceof Memcache)
diff --git a/system/libraries/Cache/drivers/Cache_redis.php b/system/libraries/Cache/drivers/Cache_redis.php
index e8dd9b3a3..22af592e7 100644
--- a/system/libraries/Cache/drivers/Cache_redis.php
+++ b/system/libraries/Cache/drivers/Cache_redis.php
@@ -56,11 +56,11 @@ class CI_Cache_redis extends CI_Driver
* @var array
*/
protected static $_default_config = array(
- 'socket_type' => 'tcp',
'host' => '127.0.0.1',
'password' => NULL,
'port' => 6379,
- 'timeout' => 0
+ 'timeout' => 0,
+ 'database' => 0
);
/**
@@ -71,13 +71,6 @@ class CI_Cache_redis extends CI_Driver
protected $_redis;
/**
- * An internal cache for storing keys of serialized values.
- *
- * @var array
- */
- protected $_serialized = array();
-
- /**
* del()/delete() method name depending on phpRedis version
*
* @var string
@@ -102,6 +95,7 @@ class CI_Cache_redis extends CI_Driver
* if a Redis connection can't be established.
*
* @return void
+ * @throws RedisException
* @see Redis::connect()
*/
public function __construct()
@@ -139,30 +133,21 @@ class CI_Cache_redis extends CI_Driver
$this->_redis = new Redis();
- try
+ // The following calls used to be wrapped in a try ... catch
+ // and just log an error, but that only causes more errors later.
+ if ( ! $this->_redis->connect($config['host'], ($config['host'][0] === '/' ? 0 : $config['port']), $config['timeout']))
{
- if ($config['socket_type'] === 'unix')
- {
- $success = $this->_redis->connect($config['socket']);
- }
- else // tcp socket
- {
- $success = $this->_redis->connect($config['host'], $config['port'], $config['timeout']);
- }
-
- if ( ! $success)
- {
- log_message('error', 'Cache: Redis connection failed. Check your configuration.');
- }
+ log_message('error', 'Cache: Redis connection failed. Check your configuration.');
+ }
- if (isset($config['password']) && ! $this->_redis->auth($config['password']))
- {
- log_message('error', 'Cache: Redis authentication failed.');
- }
+ if (isset($config['password']) && ! $this->_redis->auth($config['password']))
+ {
+ log_message('error', 'Cache: Redis authentication failed.');
}
- catch (RedisException $e)
+
+ if (isset($config['database']) && $config['database'] > 0 && ! $this->_redis->select($config['database']))
{
- log_message('error', 'Cache: Redis connection refused ('.$e->getMessage().')');
+ log_message('error', 'Cache: Redis select database failed.');
}
}
@@ -176,14 +161,30 @@ class CI_Cache_redis extends CI_Driver
*/
public function get($key)
{
- $value = $this->_redis->get($key);
+ $data = $this->_redis->hMGet($key, array('__ci_type', '__ci_value'));
if ($value !== FALSE && $this->_redis->sIsMember('_ci_redis_serialized', $key))
{
- return unserialize($value);
+ return FALSE;
}
- return $value;
+ switch ($data['__ci_type'])
+ {
+ case 'array':
+ case 'object':
+ return unserialize($data['__ci_value']);
+ case 'boolean':
+ case 'integer':
+ case 'double': // Yes, 'double' is returned and NOT 'float'
+ case 'string':
+ case 'NULL':
+ return settype($data['__ci_value'], $data['__ci_type'])
+ ? $data['__ci_value']
+ : FALSE;
+ case 'resource':
+ default:
+ return FALSE;
+ }
}
// ------------------------------------------------------------------------
@@ -199,22 +200,33 @@ class CI_Cache_redis extends CI_Driver
*/
public function save($id, $data, $ttl = 60, $raw = FALSE)
{
- if (is_array($data) OR is_object($data))
+ switch ($data_type = gettype($data))
{
- if ( ! $this->_redis->sIsMember('_ci_redis_serialized', $id) && ! $this->_redis->sAdd('_ci_redis_serialized', $id))
- {
+ case 'array':
+ case 'object':
+ $data = serialize($data);
+ break;
+ case 'boolean':
+ case 'integer':
+ case 'double': // Yes, 'double' is returned and NOT 'float'
+ case 'string':
+ case 'NULL':
+ break;
+ case 'resource':
+ default:
return FALSE;
- }
+ }
- isset($this->_serialized[$id]) OR $this->_serialized[$id] = TRUE;
- $data = serialize($data);
+ if ( ! $this->_redis->hMSet($id, array('__ci_type' => $data_type, '__ci_value' => $data)))
+ {
+ return FALSE;
}
else
{
$this->_redis->{static::$_sRemove_name}('_ci_redis_serialized', $id);
}
- return $this->_redis->set($id, $data, $ttl);
+ return TRUE;
}
// ------------------------------------------------------------------------
diff --git a/system/libraries/Cache/drivers/index.html b/system/libraries/Cache/drivers/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/libraries/Cache/drivers/index.html
+++ b/system/libraries/Cache/drivers/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/libraries/Cache/index.html b/system/libraries/Cache/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/libraries/Cache/index.html
+++ b/system/libraries/Cache/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/libraries/Cart.php b/system/libraries/Cart.php
deleted file mode 100644
index f8244b153..000000000
--- a/system/libraries/Cart.php
+++ /dev/null
@@ -1,568 +0,0 @@
-<?php
-/**
- * CodeIgniter
- *
- * An open source application development framework for PHP
- *
- * This content is released under the MIT License (MIT)
- *
- * Copyright (c) 2019 - 2022, CodeIgniter Foundation
- *
- * 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 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
- * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
- * @license https://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');
-
-/**
- * Shopping Cart Class
- *
- * @package CodeIgniter
- * @subpackage Libraries
- * @category Shopping Cart
- * @author EllisLab Dev Team
- * @link https://codeigniter.com/userguide3/libraries/cart.html
- * @deprecated 3.0.0 This class is too specific for CI.
- */
-class CI_Cart {
-
- /**
- * These are the regular expression rules that we use to validate the product ID and product name
- * alpha-numeric, dashes, underscores, or periods
- *
- * @var string
- */
- public $product_id_rules = '\.a-z0-9_-';
-
- /**
- * These are the regular expression rules that we use to validate the product ID and product name
- * alpha-numeric, dashes, underscores, colons or periods
- *
- * @var string
- */
- public $product_name_rules = '\w \-\.\:';
-
- /**
- * only allow safe product names
- *
- * @var bool
- */
- public $product_name_safe = TRUE;
-
- // --------------------------------------------------------------------------
-
- /**
- * Reference to CodeIgniter instance
- *
- * @var object
- */
- protected $CI;
-
- /**
- * Contents of the cart
- *
- * @var array
- */
- protected $_cart_contents = array();
-
- /**
- * Shopping Class Constructor
- *
- * The constructor loads the Session class, used to store the shopping cart contents.
- *
- * @param array
- * @return void
- */
- public function __construct($params = array())
- {
- // Set the super object to a local variable for use later
- $this->CI =& get_instance();
-
- // Are any config settings being passed manually? If so, set them
- $config = is_array($params) ? $params : array();
-
- // Load the Sessions class
- $this->CI->load->driver('session', $config);
-
- // Grab the shopping cart array from the session table
- $this->_cart_contents = $this->CI->session->userdata('cart_contents');
- if ($this->_cart_contents === NULL)
- {
- // No cart exists so we'll set some base values
- $this->_cart_contents = array('cart_total' => 0, 'total_items' => 0);
- }
-
- log_message('info', 'Cart Class Initialized');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Insert items into the cart and save it to the session table
- *
- * @param array
- * @return bool
- */
- public function insert($items = array())
- {
- // Was any cart data passed? No? Bah...
- if ( ! is_array($items) OR count($items) === 0)
- {
- log_message('error', 'The insert method must be passed an array containing data.');
- return FALSE;
- }
-
- // You can either insert a single product using a one-dimensional array,
- // or multiple products using a multi-dimensional one. The way we
- // determine the array type is by looking for a required array key named "id"
- // at the top level. If it's not found, we will assume it's a multi-dimensional array.
-
- $save_cart = FALSE;
- if (isset($items['id']))
- {
- if (($rowid = $this->_insert($items)))
- {
- $save_cart = TRUE;
- }
- }
- else
- {
- foreach ($items as $val)
- {
- if (is_array($val) && isset($val['id']))
- {
- if ($this->_insert($val))
- {
- $save_cart = TRUE;
- }
- }
- }
- }
-
- // Save the cart data if the insert was successful
- if ($save_cart === TRUE)
- {
- $this->_save_cart();
- return isset($rowid) ? $rowid : TRUE;
- }
-
- return FALSE;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Insert
- *
- * @param array
- * @return bool
- */
- protected function _insert($items = array())
- {
- // Was any cart data passed? No? Bah...
- if ( ! is_array($items) OR count($items) === 0)
- {
- log_message('error', 'The insert method must be passed an array containing data.');
- return FALSE;
- }
-
- // --------------------------------------------------------------------
-
- // Does the $items array contain an id, quantity, price, and name? These are required
- if ( ! isset($items['id'], $items['qty'], $items['price'], $items['name']))
- {
- log_message('error', 'The cart array must contain a product ID, quantity, price, and name.');
- return FALSE;
- }
-
- // --------------------------------------------------------------------
-
- // Prep the quantity. It can only be a number. Duh... also trim any leading zeros
- $items['qty'] = (float) $items['qty'];
-
- // If the quantity is zero or blank there's nothing for us to do
- if ($items['qty'] == 0)
- {
- return FALSE;
- }
-
- // --------------------------------------------------------------------
-
- // Validate the product ID. It can only be alpha-numeric, dashes, underscores or periods
- // Not totally sure we should impose this rule, but it seems prudent to standardize IDs.
- // Note: These can be user-specified by setting the $this->product_id_rules variable.
- if ( ! preg_match('/^['.$this->product_id_rules.']+$/i', $items['id']))
- {
- log_message('error', 'Invalid product ID. The product ID can only contain alpha-numeric characters, dashes, and underscores');
- return FALSE;
- }
-
- // --------------------------------------------------------------------
-
- // Validate the product name. It can only be alpha-numeric, dashes, underscores, colons or periods.
- // Note: These can be user-specified by setting the $this->product_name_rules variable.
- if ($this->product_name_safe && ! preg_match('/^['.$this->product_name_rules.']+$/i'.(UTF8_ENABLED ? 'u' : ''), $items['name']))
- {
- log_message('error', 'An invalid name was submitted as the product name: '.$items['name'].' The name can only contain alpha-numeric characters, dashes, underscores, colons, and spaces');
- return FALSE;
- }
-
- // --------------------------------------------------------------------
-
- // Prep the price. Remove leading zeros and anything that isn't a number or decimal point.
- $items['price'] = (float) $items['price'];
-
- // We now need to create a unique identifier for the item being inserted into the cart.
- // Every time something is added to the cart it is stored in the master cart array.
- // Each row in the cart array, however, must have a unique index that identifies not only
- // a particular product, but makes it possible to store identical products with different options.
- // For example, what if someone buys two identical t-shirts (same product ID), but in
- // different sizes? The product ID (and other attributes, like the name) will be identical for
- // both sizes because it's the same shirt. The only difference will be the size.
- // Internally, we need to treat identical submissions, but with different options, as a unique product.
- // Our solution is to convert the options array to a string and MD5 it along with the product ID.
- // This becomes the unique "row ID"
- if (isset($items['options']) && count($items['options']) > 0)
- {
- $rowid = md5($items['id'].serialize($items['options']));
- }
- else
- {
- // No options were submitted so we simply MD5 the product ID.
- // Technically, we don't need to MD5 the ID in this case, but it makes
- // sense to standardize the format of array indexes for both conditions
- $rowid = md5($items['id']);
- }
-
- // --------------------------------------------------------------------
-
- // Now that we have our unique "row ID", we'll add our cart items to the master array
- // grab quantity if it's already there and add it on
- $old_quantity = isset($this->_cart_contents[$rowid]['qty']) ? (int) $this->_cart_contents[$rowid]['qty'] : 0;
-
- // Re-create the entry, just to make sure our index contains only the data from this submission
- $items['rowid'] = $rowid;
- $items['qty'] += $old_quantity;
- $this->_cart_contents[$rowid] = $items;
-
- return $rowid;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Update the cart
- *
- * This function permits the quantity of a given item to be changed.
- * Typically it is called from the "view cart" page if a user makes
- * changes to the quantity before checkout. That array must contain the
- * product ID and quantity for each item.
- *
- * @param array
- * @return bool
- */
- public function update($items = array())
- {
- // Was any cart data passed?
- if ( ! is_array($items) OR count($items) === 0)
- {
- return FALSE;
- }
-
- // You can either update a single product using a one-dimensional array,
- // or multiple products using a multi-dimensional one. The way we
- // determine the array type is by looking for a required array key named "rowid".
- // If it's not found we assume it's a multi-dimensional array
- $save_cart = FALSE;
- if (isset($items['rowid']))
- {
- if ($this->_update($items) === TRUE)
- {
- $save_cart = TRUE;
- }
- }
- else
- {
- foreach ($items as $val)
- {
- if (is_array($val) && isset($val['rowid']))
- {
- if ($this->_update($val) === TRUE)
- {
- $save_cart = TRUE;
- }
- }
- }
- }
-
- // Save the cart data if the insert was successful
- if ($save_cart === TRUE)
- {
- $this->_save_cart();
- return TRUE;
- }
-
- return FALSE;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Update the cart
- *
- * This function permits changing item properties.
- * Typically it is called from the "view cart" page if a user makes
- * changes to the quantity before checkout. That array must contain the
- * rowid and quantity for each item.
- *
- * @param array
- * @return bool
- */
- protected function _update($items = array())
- {
- // Without these array indexes there is nothing we can do
- if ( ! isset($items['rowid'], $this->_cart_contents[$items['rowid']]))
- {
- return FALSE;
- }
-
- // Prep the quantity
- if (isset($items['qty']))
- {
- $items['qty'] = (float) $items['qty'];
- // Is the quantity zero? If so we will remove the item from the cart.
- // If the quantity is greater than zero we are updating
- if ($items['qty'] == 0)
- {
- unset($this->_cart_contents[$items['rowid']]);
- return TRUE;
- }
- }
-
- // find updatable keys
- $keys = array_intersect(array_keys($this->_cart_contents[$items['rowid']]), array_keys($items));
- // if a price was passed, make sure it contains valid data
- if (isset($items['price']))
- {
- $items['price'] = (float) $items['price'];
- }
-
- // product id & name shouldn't be changed
- foreach (array_diff($keys, array('id', 'name')) as $key)
- {
- $this->_cart_contents[$items['rowid']][$key] = $items[$key];
- }
-
- return TRUE;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Save the cart array to the session DB
- *
- * @return bool
- */
- protected function _save_cart()
- {
- // Let's add up the individual prices and set the cart sub-total
- $this->_cart_contents['total_items'] = $this->_cart_contents['cart_total'] = 0;
- foreach ($this->_cart_contents as $key => $val)
- {
- // We make sure the array contains the proper indexes
- if ( ! is_array($val) OR ! isset($val['price'], $val['qty']))
- {
- continue;
- }
-
- $this->_cart_contents['cart_total'] += ($val['price'] * $val['qty']);
- $this->_cart_contents['total_items'] += $val['qty'];
- $this->_cart_contents[$key]['subtotal'] = ($this->_cart_contents[$key]['price'] * $this->_cart_contents[$key]['qty']);
- }
-
- // Is our cart empty? If so we delete it from the session
- if (count($this->_cart_contents) <= 2)
- {
- $this->CI->session->unset_userdata('cart_contents');
-
- // Nothing more to do... coffee time!
- return FALSE;
- }
-
- // If we made it this far it means that our cart has data.
- // Let's pass it to the Session class so it can be stored
- $this->CI->session->set_userdata(array('cart_contents' => $this->_cart_contents));
-
- // Woot!
- return TRUE;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Cart Total
- *
- * @return int
- */
- public function total()
- {
- return $this->_cart_contents['cart_total'];
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Remove Item
- *
- * Removes an item from the cart
- *
- * @param int
- * @return bool
- */
- public function remove($rowid)
- {
- // unset & save
- unset($this->_cart_contents[$rowid]);
- $this->_save_cart();
- return TRUE;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Total Items
- *
- * Returns the total item count
- *
- * @return int
- */
- public function total_items()
- {
- return $this->_cart_contents['total_items'];
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Cart Contents
- *
- * Returns the entire cart array
- *
- * @param bool
- * @return array
- */
- public function contents($newest_first = FALSE)
- {
- // do we want the newest first?
- $cart = ($newest_first) ? array_reverse($this->_cart_contents) : $this->_cart_contents;
-
- // Remove these so they don't create a problem when showing the cart table
- unset($cart['total_items']);
- unset($cart['cart_total']);
-
- return $cart;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Get cart item
- *
- * Returns the details of a specific item in the cart
- *
- * @param string $row_id
- * @return array
- */
- public function get_item($row_id)
- {
- return (in_array($row_id, array('total_items', 'cart_total'), TRUE) OR ! isset($this->_cart_contents[$row_id]))
- ? FALSE
- : $this->_cart_contents[$row_id];
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Has options
- *
- * Returns TRUE if the rowid passed to this function correlates to an item
- * that has options associated with it.
- *
- * @param string $row_id = ''
- * @return bool
- */
- public function has_options($row_id = '')
- {
- return (isset($this->_cart_contents[$row_id]['options']) && count($this->_cart_contents[$row_id]['options']) !== 0);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Product options
- *
- * Returns the an array of options, for a particular product row ID
- *
- * @param string $row_id = ''
- * @return array
- */
- public function product_options($row_id = '')
- {
- return isset($this->_cart_contents[$row_id]['options']) ? $this->_cart_contents[$row_id]['options'] : array();
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Format Number
- *
- * Returns the supplied number with commas and a decimal point.
- *
- * @param float
- * @return string
- */
- public function format_number($n = '')
- {
- return ($n === '') ? '' : number_format( (float) $n, 2, '.', ',');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Destroy the cart
- *
- * Empties the cart and kills the session
- *
- * @return void
- */
- public function destroy()
- {
- $this->_cart_contents = array('cart_total' => 0, 'total_items' => 0);
- $this->CI->session->unset_userdata('cart_contents');
- }
-
-}
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index 82fae128d..1b94b8358 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -148,7 +148,7 @@ class CI_Email {
*
* @var string
*/
- public $charset = 'UTF-8';
+ public $charset = 'utf-8';
/**
* Alternative message (for HTML messages only)
@@ -162,7 +162,7 @@ class CI_Email {
*
* @var bool
*/
- public $validate = FALSE;
+ public $validate = TRUE;
/**
* X-Priority header value.
@@ -175,7 +175,7 @@ class CI_Email {
* Newline character sequence.
* Use "\r\n" to comply with RFC 822.
*
- * @link http://www.ietf.org/rfc/rfc822.txt
+ * @link https://www.ietf.org/rfc/rfc822.txt
* @var string "\r\n" or "\n"
*/
public $newline = "\n"; // Default newline. "\r\n" or "\n" (Use "\r\n" to comply with RFC 822)
@@ -189,7 +189,7 @@ class CI_Email {
* switching to "\n", while improper, is the only solution
* that seems to work for all environments.
*
- * @link http://www.ietf.org/rfc/rfc822.txt
+ * @link https://www.ietf.org/rfc/rfc822.txt
* @var string
*/
public $crlf = "\n";
@@ -227,13 +227,6 @@ class CI_Email {
// --------------------------------------------------------------------
/**
- * Whether PHP is running in safe mode. Initialized by the class constructor.
- *
- * @var bool
- */
- protected $_safe_mode = FALSE;
-
- /**
* Subject header
*
* @var string
@@ -396,7 +389,6 @@ class CI_Email {
{
$this->charset = config_item('charset');
$this->initialize($config);
- $this->_safe_mode = ( ! is_php('5.4') && ini_get('safe_mode'));
isset(self::$func_overload) OR self::$func_overload = ( ! is_php('8.0') && extension_loaded('mbstring') && @ini_get('mbstring.func_overload'));
@@ -676,18 +668,6 @@ class CI_Email {
public function message($body)
{
$this->_body = rtrim(str_replace("\r", '', $body));
-
- /* strip slashes only if magic quotes is ON
- if we do it with magic quotes OFF, it strips real, user-inputted chars.
-
- 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())
- {
- $this->_body = stripslashes($this->_body);
- }
-
return $this;
}
@@ -1033,16 +1013,15 @@ class CI_Email {
*/
public function valid_email($email)
{
- if (function_exists('idn_to_ascii') && strpos($email, '@'))
+ if (function_exists('idn_to_ascii') && preg_match('#\A([^@]+)@(.+)\z#', $email, $matches))
{
- list($account, $domain) = explode('@', $email, 2);
$domain = defined('INTL_IDNA_VARIANT_UTS46')
- ? idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46)
- : idn_to_ascii($domain);
+ ? idn_to_ascii($matches[2], 0, INTL_IDNA_VARIANT_UTS46)
+ : idn_to_ascii($matches[2]);
if ($domain !== FALSE)
{
- $email = $account.'@'.$domain;
+ $email = $matches[1].'@'.$domain;
}
}
@@ -1262,7 +1241,7 @@ class CI_Email {
/**
* Build Final Body and attachments
*
- * @return bool
+ * @return void
*/
protected function _build_message()
{
@@ -1429,8 +1408,6 @@ class CI_Email {
$this->_finalbody = ($this->_get_protocol() === 'mail')
? $body
: $hdr.$this->newline.$this->newline.$body;
-
- return TRUE;
}
// --------------------------------------------------------------------
@@ -1491,7 +1468,7 @@ class CI_Email {
* Prep Quoted Printable
*
* Prepares string for Quoted-Printable Content-Transfer-Encoding
- * Refer to RFC 2045 http://www.ietf.org/rfc/rfc2045.txt
+ * Refer to RFC 2045 https://www.ietf.org/rfc/rfc2045.txt
*
* @param string
* @return string
@@ -1500,7 +1477,7 @@ class CI_Email {
{
// ASCII code numbers for "safe" characters that can always be
// used literally, without encoding, as described in RFC 2049.
- // http://www.ietf.org/rfc/rfc2049.txt
+ // https://www.ietf.org/rfc/rfc2049.txt
static $ascii_safe_chars = array(
// ' ( ) + , - . / : = ?
39, 40, 41, 43, 44, 45, 46, 47, 58, 61, 63,
@@ -1692,8 +1669,8 @@ class CI_Email {
$this->reply_to($this->_headers['From']);
}
- if ( ! isset($this->_recipients) && ! isset($this->_headers['To'])
- && ! isset($this->_bcc_array) && ! isset($this->_headers['Bcc'])
+ if (empty($this->_recipients) && ! isset($this->_headers['To'])
+ && empty($this->_bcc_array) && ! isset($this->_headers['Bcc'])
&& ! isset($this->_headers['Cc']))
{
$this->_set_error_message('lang:email_no_recipients');
@@ -1704,21 +1681,17 @@ class CI_Email {
if ($this->bcc_batch_mode && count($this->_bcc_array) > $this->bcc_batch_size)
{
- $result = $this->batch_bcc_send();
+ $this->batch_bcc_send();
- if ($result && $auto_clear)
+ if ($auto_clear)
{
$this->clear();
}
- return $result;
- }
-
- if ($this->_build_message() === FALSE)
- {
- return FALSE;
+ return TRUE;
}
+ $this->_build_message();
$result = $this->_spool_email();
if ($result && $auto_clear)
@@ -1777,11 +1750,7 @@ class CI_Email {
$this->_bcc_array = $bcc;
}
- if ($this->_build_message() === FALSE)
- {
- return FALSE;
- }
-
+ $this->_build_message();
$this->_spool_email();
}
}
@@ -1858,7 +1827,7 @@ class CI_Email {
*/
protected function _validate_email_for_shell(&$email)
{
- if (function_exists('idn_to_ascii') && strpos($email, '@'))
+ if (function_exists('idn_to_ascii') && $atpos = strpos($email, '@'))
{
list($account, $domain) = explode('@', $email, 2);
$domain = defined('INTL_IDNA_VARIANT_UTS46')
@@ -1892,16 +1861,14 @@ class CI_Email {
// so this needs to be assigned to a variable
$from = $this->clean_email($this->_headers['Return-Path']);
- if ($this->_safe_mode === TRUE || ! $this->_validate_email_for_shell($from))
+ if ( ! $this->_validate_email_for_shell($from))
{
return mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str);
}
- else
- {
- // most documentation of sendmail using the "-f" flag lacks a space after it, however
- // we've encountered servers that seem to require it to be in place.
- return mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, '-f '.$from);
- }
+
+ // most documentation of sendmail using the "-f" flag lacks a space after it, however
+ // we've encountered servers that seem to require it to be in place.
+ return mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, '-f '.$from);
}
// --------------------------------------------------------------------
@@ -1982,27 +1949,21 @@ class CI_Email {
}
}
- if (count($this->_cc_array) > 0)
+ foreach ($this->_cc_array as $val)
{
- foreach ($this->_cc_array as $val)
+ if ($val !== '' && ! $this->_send_command('to', $val))
{
- if ($val !== '' && ! $this->_send_command('to', $val))
- {
- $this->_smtp_end();
- return FALSE;
- }
+ $this->_smtp_end();
+ return FALSE;
}
}
- if (count($this->_bcc_array) > 0)
+ foreach ($this->_bcc_array as $val)
{
- foreach ($this->_bcc_array as $val)
+ if ($val !== '' && ! $this->_send_command('to', $val))
{
- if ($val !== '' && ! $this->_send_command('to', $val))
- {
- $this->_smtp_end();
- return FALSE;
- }
+ $this->_smtp_end();
+ return FALSE;
}
}
@@ -2016,7 +1977,6 @@ class CI_Email {
$this->_send_data($this->_header_str.preg_replace('/^\./m', '..$1', $this->_finalbody));
$this->_send_data('.');
-
$reply = $this->_get_smtp_data();
$this->_set_error_message($reply);
@@ -2042,9 +2002,7 @@ class CI_Email {
*/
protected function _smtp_end()
{
- ($this->smtp_keepalive)
- ? $this->_send_command('reset')
- : $this->_send_command('quit');
+ $this->_send_command($this->smtp_keepalive ? 'reset' : 'quit');
}
// --------------------------------------------------------------------
@@ -2063,11 +2021,13 @@ class CI_Email {
$ssl = ($this->smtp_crypto === 'ssl') ? 'ssl://' : '';
- $this->_smtp_connect = fsockopen($ssl.$this->smtp_host,
- $this->smtp_port,
- $errno,
- $errstr,
- $this->smtp_timeout);
+ $this->_smtp_connect = fsockopen(
+ $ssl.$this->smtp_host,
+ $this->smtp_port,
+ $errno,
+ $errstr,
+ $this->smtp_timeout
+ );
if ( ! is_resource($this->_smtp_connect))
{
@@ -2120,57 +2080,49 @@ class CI_Email {
{
switch ($cmd)
{
- case 'hello' :
-
- if ($this->_smtp_auth OR $this->_get_encoding() === '8bit')
- {
- $this->_send_data('EHLO '.$this->_get_hostname());
- }
- else
- {
- $this->_send_data('HELO '.$this->_get_hostname());
- }
-
- $resp = 250;
- break;
- case 'starttls' :
-
- $this->_send_data('STARTTLS');
- $resp = 220;
- break;
- case 'from' :
-
- $this->_send_data('MAIL FROM:<'.$data.'>');
- $resp = 250;
- break;
- case 'to' :
-
- if ($this->dsn)
- {
- $this->_send_data('RCPT TO:<'.$data.'> NOTIFY=SUCCESS,DELAY,FAILURE ORCPT=rfc822;'.$data);
- }
- else
- {
- $this->_send_data('RCPT TO:<'.$data.'>');
- }
-
- $resp = 250;
- break;
- case 'data' :
-
- $this->_send_data('DATA');
- $resp = 354;
- break;
- case 'reset':
-
- $this->_send_data('RSET');
- $resp = 250;
- break;
- case 'quit' :
+ case 'hello':
+ if ($this->_smtp_auth OR $this->_get_encoding() === '8bit')
+ {
+ $this->_send_data('EHLO '.$this->_get_hostname());
+ }
+ else
+ {
+ $this->_send_data('HELO '.$this->_get_hostname());
+ }
- $this->_send_data('QUIT');
- $resp = 221;
- break;
+ $resp = 250;
+ break;
+ case 'starttls':
+ $this->_send_data('STARTTLS');
+ $resp = 220;
+ break;
+ case 'from':
+ $this->_send_data('MAIL FROM:<'.$data.'>');
+ $resp = 250;
+ break;
+ case 'to':
+ if ($this->dsn)
+ {
+ $this->_send_data('RCPT TO:<'.$data.'> NOTIFY=SUCCESS,DELAY,FAILURE ORCPT=rfc822;'.$data);
+ }
+ else
+ {
+ $this->_send_data('RCPT TO:<'.$data.'>');
+ }
+ $resp = 250;
+ break;
+ case 'data':
+ $this->_send_data('DATA');
+ $resp = 354;
+ break;
+ case 'reset':
+ $this->_send_data('RSET');
+ $resp = 250;
+ break;
+ case 'quit':
+ $this->_send_data('QUIT');
+ $resp = 221;
+ break;
}
$reply = $this->_get_smtp_data();
@@ -2212,7 +2164,6 @@ class CI_Email {
}
$this->_send_data('AUTH LOGIN');
-
$reply = $this->_get_smtp_data();
if (strpos($reply, '503') === 0) // Already authenticated
@@ -2226,7 +2177,6 @@ class CI_Email {
}
$this->_send_data(base64_encode($this->smtp_user));
-
$reply = $this->_get_smtp_data();
if (strpos($reply, '334') !== 0)
@@ -2236,7 +2186,6 @@ class CI_Email {
}
$this->_send_data(base64_encode($this->smtp_pass));
-
$reply = $this->_get_smtp_data();
if (strpos($reply, '235') !== 0)
@@ -2270,7 +2219,7 @@ class CI_Email {
{
break;
}
- // See https://bugs.php.net/bug.php?id=39598 and http://php.net/manual/en/function.fwrite.php#96951
+ // See https://bugs.php.net/bug.php?id=39598 and https://secure.php.net/manual/en/function.fwrite.php#96951
elseif ($result === 0)
{
if ($timestamp === 0)
@@ -2333,7 +2282,7 @@ class CI_Email {
* (eg: "[1.2.3.4]").
*
* @link https://tools.ietf.org/html/rfc5321#section-2.3.5
- * @link http://cbl.abuseat.org/namingproblems.html
+ * @link https://cbl.abuseat.org/namingproblems.html
* @return string
*/
protected function _get_hostname()
@@ -2357,34 +2306,15 @@ class CI_Email {
*/
public function print_debugger($include = array('headers', 'subject', 'body'))
{
- $msg = '';
-
- if (count($this->_debug_msg) > 0)
- {
- foreach ($this->_debug_msg as $val)
- {
- $msg .= $val;
- }
- }
+ $msg = implode('', $this->_debug_msg);
// Determine which parts of our raw data needs to be printed
$raw_data = '';
is_array($include) OR $include = array($include);
- if (in_array('headers', $include, TRUE))
- {
- $raw_data = htmlspecialchars($this->_header_str)."\n";
- }
-
- if (in_array('subject', $include, TRUE))
- {
- $raw_data .= htmlspecialchars($this->_subject)."\n";
- }
-
- if (in_array('body', $include, TRUE))
- {
- $raw_data .= htmlspecialchars($this->_finalbody);
- }
+ in_array('headers', $include, TRUE) && $raw_data = htmlspecialchars($this->_header_str)."\n";
+ in_array('subject', $include, TRUE) && $raw_data .= htmlspecialchars($this->_subject)."\n";
+ in_array('body', $include, TRUE) && $raw_data .= htmlspecialchars($this->_finalbody);
return $msg.($raw_data === '' ? '' : '<pre>'.$raw_data.'</pre>');
}
@@ -2478,9 +2408,6 @@ class CI_Email {
{
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');
}
diff --git a/system/libraries/Encrypt.php b/system/libraries/Encrypt.php
deleted file mode 100644
index 4d1dae5d8..000000000
--- a/system/libraries/Encrypt.php
+++ /dev/null
@@ -1,522 +0,0 @@
-<?php
-/**
- * CodeIgniter
- *
- * An open source application development framework for PHP
- *
- * This content is released under the MIT License (MIT)
- *
- * Copyright (c) 2019 - 2022, CodeIgniter Foundation
- *
- * 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 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
- * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
- * @license https://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');
-
-/**
- * CodeIgniter Encryption Class
- *
- * Provides two-way keyed encoding using Mcrypt
- *
- * @package CodeIgniter
- * @subpackage Libraries
- * @category Libraries
- * @author EllisLab Dev Team
- * @link https://codeigniter.com/userguide3/libraries/encryption.html
- */
-class CI_Encrypt {
-
- /**
- * Reference to the user's encryption key
- *
- * @var string
- */
- public $encryption_key = '';
-
- /**
- * Type of hash operation
- *
- * @var string
- */
- protected $_hash_type = 'sha1';
-
- /**
- * Flag for the existence of mcrypt
- *
- * @var bool
- */
- protected $_mcrypt_exists = FALSE;
-
- /**
- * Current cipher to be used with mcrypt
- *
- * @var string
- */
- protected $_mcrypt_cipher;
-
- /**
- * Method for encrypting/decrypting data
- *
- * @var int
- */
- protected $_mcrypt_mode;
-
- /**
- * Initialize Encryption class
- *
- * @return void
- */
- public function __construct()
- {
- if (($this->_mcrypt_exists = function_exists('mcrypt_encrypt')) === FALSE)
- {
- show_error('The Encrypt library requires the Mcrypt extension.');
- }
-
- log_message('info', 'Encrypt Class Initialized');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Fetch the encryption key
- *
- * Returns it as MD5 in order to have an exact-length 128 bit key.
- * Mcrypt is sensitive to keys that are not the correct length
- *
- * @param string
- * @return string
- */
- public function get_key($key = '')
- {
- if ($key === '')
- {
- if ($this->encryption_key !== '')
- {
- return $this->encryption_key;
- }
-
- $key = config_item('encryption_key');
-
- if ( ! self::strlen($key))
- {
- show_error('In order to use the encryption class requires that you set an encryption key in your config file.');
- }
- }
-
- return md5($key);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Set the encryption key
- *
- * @param string
- * @return CI_Encrypt
- */
- public function set_key($key = '')
- {
- $this->encryption_key = $key;
- return $this;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Encode
- *
- * Encodes the message string using bitwise XOR encoding.
- * The key is combined with a random hash, and then it
- * too gets converted using XOR. The whole thing is then run
- * through mcrypt using the randomized key. The end result
- * is a double-encrypted message string that is randomized
- * with each call to this function, even if the supplied
- * message and key are the same.
- *
- * @param string the string to encode
- * @param string the key
- * @return string
- */
- public function encode($string, $key = '')
- {
- return base64_encode($this->mcrypt_encode($string, $this->get_key($key)));
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Decode
- *
- * Reverses the above process
- *
- * @param string
- * @param string
- * @return string
- */
- public function decode($string, $key = '')
- {
- if (preg_match('/[^a-zA-Z0-9\/\+=]/', $string) OR base64_encode(base64_decode($string)) !== $string)
- {
- return FALSE;
- }
-
- return $this->mcrypt_decode(base64_decode($string), $this->get_key($key));
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Encode from Legacy
- *
- * Takes an encoded string from the original Encryption class algorithms and
- * returns a newly encoded string using the improved method added in 2.0.0
- * This allows for backwards compatibility and a method to transition to the
- * new encryption algorithms.
- *
- * For more details, see https://codeigniter.com/userguide3/installation/upgrade_200.html#encryption
- *
- * @param string
- * @param int (mcrypt mode constant)
- * @param string
- * @return string
- */
- public function encode_from_legacy($string, $legacy_mode = MCRYPT_MODE_ECB, $key = '')
- {
- if (preg_match('/[^a-zA-Z0-9\/\+=]/', $string))
- {
- return FALSE;
- }
-
- // decode it first
- // set mode temporarily to what it was when string was encoded with the legacy
- // algorithm - typically MCRYPT_MODE_ECB
- $current_mode = $this->_get_mode();
- $this->set_mode($legacy_mode);
-
- $key = $this->get_key($key);
- $dec = base64_decode($string);
- if (($dec = $this->mcrypt_decode($dec, $key)) === FALSE)
- {
- $this->set_mode($current_mode);
- return FALSE;
- }
-
- $dec = $this->_xor_decode($dec, $key);
-
- // set the mcrypt mode back to what it should be, typically MCRYPT_MODE_CBC
- $this->set_mode($current_mode);
-
- // and re-encode
- return base64_encode($this->mcrypt_encode($dec, $key));
- }
-
- // --------------------------------------------------------------------
-
- /**
- * XOR Decode
- *
- * Takes an encoded string and key as input and generates the
- * plain-text original message
- *
- * @param string
- * @param string
- * @return string
- */
- protected function _xor_decode($string, $key)
- {
- $string = $this->_xor_merge($string, $key);
-
- $dec = '';
- for ($i = 0, $l = self::strlen($string); $i < $l; $i++)
- {
- $dec .= ($string[$i++] ^ $string[$i]);
- }
-
- return $dec;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * XOR key + string Combiner
- *
- * Takes a string and key as input and computes the difference using XOR
- *
- * @param string
- * @param string
- * @return string
- */
- protected function _xor_merge($string, $key)
- {
- $hash = $this->hash($key);
- $str = '';
-
- for ($i = 0, $ls = self::strlen($string), $lh = self::strlen($hash); $i < $ls; $i++)
- {
- $str .= $string[$i] ^ $hash[($i % $lh)];
- }
-
- return $str;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Encrypt using Mcrypt
- *
- * @param string
- * @param string
- * @return string
- */
- public function mcrypt_encode($data, $key)
- {
- $init_size = mcrypt_get_iv_size($this->_get_cipher(), $this->_get_mode());
- $init_vect = mcrypt_create_iv($init_size, MCRYPT_DEV_URANDOM);
- return $this->_add_cipher_noise($init_vect.mcrypt_encrypt($this->_get_cipher(), $key, $data, $this->_get_mode(), $init_vect), $key);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Decrypt using Mcrypt
- *
- * @param string
- * @param string
- * @return string
- */
- public function mcrypt_decode($data, $key)
- {
- $data = $this->_remove_cipher_noise($data, $key);
- $init_size = mcrypt_get_iv_size($this->_get_cipher(), $this->_get_mode());
-
- if ($init_size > self::strlen($data))
- {
- return FALSE;
- }
-
- $init_vect = self::substr($data, 0, $init_size);
- $data = self::substr($data, $init_size);
-
- return rtrim(mcrypt_decrypt($this->_get_cipher(), $key, $data, $this->_get_mode(), $init_vect), "\0");
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Adds permuted noise to the IV + encrypted data to protect
- * against Man-in-the-middle attacks on CBC mode ciphers
- * http://www.ciphersbyritter.com/GLOSSARY.HTM#IV
- *
- * @param string
- * @param string
- * @return string
- */
- protected function _add_cipher_noise($data, $key)
- {
- $key = $this->hash($key);
- $str = '';
-
- for ($i = 0, $j = 0, $ld = self::strlen($data), $lk = self::strlen($key); $i < $ld; ++$i, ++$j)
- {
- if ($j >= $lk)
- {
- $j = 0;
- }
-
- $str .= chr((ord($data[$i]) + ord($key[$j])) % 256);
- }
-
- return $str;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Removes permuted noise from the IV + encrypted data, reversing
- * _add_cipher_noise()
- *
- * Function description
- *
- * @param string $data
- * @param string $key
- * @return string
- */
- protected function _remove_cipher_noise($data, $key)
- {
- $key = $this->hash($key);
- $str = '';
-
- for ($i = 0, $j = 0, $ld = self::strlen($data), $lk = self::strlen($key); $i < $ld; ++$i, ++$j)
- {
- if ($j >= $lk)
- {
- $j = 0;
- }
-
- $temp = ord($data[$i]) - ord($key[$j]);
-
- if ($temp < 0)
- {
- $temp += 256;
- }
-
- $str .= chr($temp);
- }
-
- return $str;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Set the Mcrypt Cipher
- *
- * @param int
- * @return CI_Encrypt
- */
- public function set_cipher($cipher)
- {
- $this->_mcrypt_cipher = $cipher;
- return $this;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Set the Mcrypt Mode
- *
- * @param int
- * @return CI_Encrypt
- */
- public function set_mode($mode)
- {
- $this->_mcrypt_mode = $mode;
- return $this;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Get Mcrypt cipher Value
- *
- * @return int
- */
- protected function _get_cipher()
- {
- if ($this->_mcrypt_cipher === NULL)
- {
- return $this->_mcrypt_cipher = MCRYPT_RIJNDAEL_256;
- }
-
- return $this->_mcrypt_cipher;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Get Mcrypt Mode Value
- *
- * @return int
- */
- protected function _get_mode()
- {
- if ($this->_mcrypt_mode === NULL)
- {
- return $this->_mcrypt_mode = MCRYPT_MODE_CBC;
- }
-
- return $this->_mcrypt_mode;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Set the Hash type
- *
- * @param string
- * @return void
- */
- public function set_hash($type = 'sha1')
- {
- $this->_hash_type = in_array($type, hash_algos()) ? $type : 'sha1';
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Hash encode a string
- *
- * @param string
- * @return string
- */
- public function hash($str)
- {
- return hash($this->_hash_type, $str);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Byte-safe strlen()
- *
- * @param string $str
- * @return int
- */
- protected static function strlen($str)
- {
- return defined('MB_OVERLOAD_STRING')
- ? 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 (defined('MB_OVERLOAD_STRING'))
- {
- // 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/libraries/Encryption.php b/system/libraries/Encryption.php
index a1ad870af..572cab3fc 100644
--- a/system/libraries/Encryption.php
+++ b/system/libraries/Encryption.php
@@ -483,7 +483,7 @@ class CI_Encryption {
$data,
$params['handle'],
$params['key'],
- 1, // DO NOT TOUCH!
+ OPENSSL_RAW_DATA,
$iv
);
@@ -642,7 +642,7 @@ class CI_Encryption {
$data,
$params['handle'],
$params['key'],
- 1, // DO NOT TOUCH!
+ OPENSSL_RAW_DATA,
$iv
);
}
@@ -929,9 +929,6 @@ class CI_Encryption {
{
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');
}
diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php
index 024f0ed62..dd1685db1 100644
--- a/system/libraries/Form_validation.php
+++ b/system/libraries/Form_validation.php
@@ -106,13 +106,6 @@ class CI_Form_validation {
protected $error_string = '';
/**
- * Whether the form data has been validated as safe
- *
- * @var bool
- */
- protected $_safe_form_data = FALSE;
-
- /**
* Custom data to validate
*
* @var array
@@ -165,7 +158,7 @@ class CI_Form_validation {
* @param array $errors
* @return CI_Form_validation
*/
- public function set_rules($field, $label = '', $rules = array(), $errors = array())
+ public function set_rules($field, $label = null, $rules = null, $errors = array())
{
// No reason to set rules if we have no POST data
// or a validation array has not been specified
@@ -198,18 +191,22 @@ class CI_Form_validation {
return $this;
}
+ elseif ( ! isset($rules))
+ {
+ throw new BadMethodCallException('Form_validation: set_rules() called without a $rules parameter');
+ }
// No fields or no rules? Nothing to do...
if ( ! is_string($field) OR $field === '' OR empty($rules))
{
- return $this;
+ throw new RuntimeException('Form_validation: set_rules() called with an empty $rules parameter');
}
elseif ( ! is_array($rules))
{
// BC: Convert pipe-separated rules string to an array
if ( ! is_string($rules))
{
- return $this;
+ throw new InvalidArgumentException('Form_validation: set_rules() expect $rules to be string or array; '.gettype($rules).' given');
}
$rules = preg_split('/\|(?![^\[]*\])/', $rules);
@@ -411,10 +408,11 @@ class CI_Form_validation {
*
* This function does all the work.
*
- * @param string $group
+ * @param string $config
+ * @param array $data
* @return bool
*/
- public function run($group = '')
+ public function run($config = NULL, &$data = NULL)
{
$validation_array = empty($this->validation_data)
? $_POST
@@ -425,19 +423,19 @@ class CI_Form_validation {
if (count($this->_field_data) === 0)
{
// No validation rules? We're done...
- if (count($this->_config_rules) === 0)
+ if (empty($this->_config_rules))
{
return FALSE;
}
- if (empty($group))
+ if (empty($config))
{
// Is there a validation rule for the particular URI being accessed?
- $group = trim($this->CI->uri->ruri_string(), '/');
- isset($this->_config_rules[$group]) OR $group = $this->CI->router->class.'/'.$this->CI->router->method;
+ $config = trim($this->CI->uri->ruri_string(), '/');
+ isset($this->_config_rules[$config]) OR $config = $this->CI->router->class.'/'.$this->CI->router->method;
}
- $this->set_rules(isset($this->_config_rules[$group]) ? $this->_config_rules[$group] : $this->_config_rules);
+ $this->set_rules(isset($this->_config_rules[$config]) ? $this->_config_rules[$config] : $this->_config_rules);
// Were we able to set the rules correctly?
if (count($this->_field_data) === 0)
@@ -479,17 +477,22 @@ class CI_Form_validation {
$this->_execute($row, $row['rules'], $row['postdata']);
}
- // Did we end up with any errors?
- $total_errors = count($this->_error_array);
- if ($total_errors > 0)
+ if ( ! empty($this->_error_array))
{
- $this->_safe_form_data = TRUE;
+ return FALSE;
}
- // Now we need to re-set the POST data with the new, processed data
- empty($this->validation_data) && $this->_reset_post_array();
+ // Fill $data if requested, otherwise modify $_POST, as long as
+ // set_data() wasn't used (yea, I know it sounds confusing)
+ if (func_num_args() >= 2)
+ {
+ $data = empty($this->validation_data) ? $_POST : $this->validation_data;
+ $this->_reset_data_array($data);
+ return TRUE;
+ }
- return ($total_errors === 0);
+ empty($this->validation_data) && $this->_reset_data_array($_POST);
+ return TRUE;
}
// --------------------------------------------------------------------
@@ -577,7 +580,7 @@ class CI_Form_validation {
*
* @return void
*/
- protected function _reset_post_array()
+ protected function _reset_data_array(&$data)
{
foreach ($this->_field_data as $field => $row)
{
@@ -585,27 +588,26 @@ class CI_Form_validation {
{
if ($row['is_array'] === FALSE)
{
- isset($_POST[$field]) && $_POST[$field] = is_array($row['postdata']) ? NULL : $row['postdata'];
+ isset($data[$field]) && $data[$field] = is_array($row['postdata']) ? NULL : $row['postdata'];
}
else
{
- // start with a reference
- $post_ref =& $_POST;
+ $data_ref =& $data;
// before we assign values, make a reference to the right POST key
if (count($row['keys']) === 1)
{
- $post_ref =& $post_ref[current($row['keys'])];
+ $data_ref =& $data[current($row['keys'])];
}
else
{
foreach ($row['keys'] as $val)
{
- $post_ref =& $post_ref[$val];
+ $data_ref =& $data_ref[$val];
}
}
- $post_ref = $row['postdata'];
+ $data_ref = $row['postdata'];
}
}
}
@@ -624,11 +626,13 @@ class CI_Form_validation {
*/
protected function _execute($row, $rules, $postdata = NULL, $cycles = 0)
{
+ $allow_arrays = in_array('is_array', $rules, TRUE);
+
// If the $_POST data is an array we will run a recursive call
//
// Note: We MUST check if the array is empty or not!
// Otherwise empty arrays will always pass validation.
- if (is_array($postdata) && ! empty($postdata))
+ if ($allow_arrays === FALSE && is_array($postdata) && ! empty($postdata))
{
foreach ($postdata as $key => $val)
{
@@ -657,14 +661,16 @@ class CI_Form_validation {
$postdata = $this->_field_data[$row['field']]['postdata'][$cycles];
$_in_array = TRUE;
}
+ // If we get an array field, but it's not expected - then it is most likely
+ // somebody messing with the form on the client side, so we'll just consider
+ // it an empty field
+ elseif ($allow_arrays === FALSE && is_array($this->_field_data[$row['field']]['postdata']))
+ {
+ $postdata = NULL;
+ }
else
{
- // If we get an array field, but it's not expected - then it is most likely
- // somebody messing with the form on the client side, so we'll just consider
- // it an empty field
- $postdata = is_array($this->_field_data[$row['field']]['postdata'])
- ? NULL
- : $this->_field_data[$row['field']]['postdata'];
+ $postdata = $this->_field_data[$row['field']]['postdata'];
}
// Is the rule a callback?
@@ -699,7 +705,7 @@ class CI_Form_validation {
// Ignore empty, non-required inputs with a few exceptions ...
if (
- ($postdata === NULL OR $postdata === '')
+ ($postdata === NULL OR ($allow_arrays === FALSE && $postdata === ''))
&& $callback === FALSE
&& $callable === FALSE
&& ! in_array($rule, array('required', 'isset', 'matches'), TRUE)
@@ -846,11 +852,6 @@ class CI_Form_validation {
{
return $line;
}
- // DEPRECATED support for non-prefixed keys, lang file again
- elseif (FALSE !== ($line = $this->CI->lang->line($rule, FALSE)))
- {
- return $line;
- }
return $this->CI->lang->line('form_validation_error_message_not_set').'('.$rule.')';
}
@@ -1295,6 +1296,31 @@ class CI_Form_validation {
// --------------------------------------------------------------------
/**
+ * Validate MAC address
+ *
+ * @param string $mac
+ * @return bool
+ */
+ public function valid_mac($mac)
+ {
+ if ( ! is_php('5.5'))
+ {
+ // Most common format, with either dash or colon delimiters
+ if (preg_match('#\A[0-9a-f]{2}(?<delimiter>[:-])([0-9a-f]{2}(?P=delimiter)){4}[0-9a-f]{2}\z#i', $mac))
+ {
+ return TRUE;
+ }
+
+ // The less common format; e.g. 0123.4567.89ab
+ return (bool) preg_match('#((\A|\.)[0-9a-f]{4}){3}\z#i', $mac);
+ }
+
+ return (bool) filter_var($mac, FILTER_VALIDATE_MAC);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* Alpha
*
* @param string
@@ -1499,38 +1525,6 @@ class CI_Form_validation {
// --------------------------------------------------------------------
/**
- * Prep data for form
- *
- * This function allows HTML to be safely shown in a form.
- * Special characters are converted.
- *
- * @deprecated 3.0.6 Not used anywhere within the framework and pretty much useless
- * @param mixed $data Input data
- * @return mixed
- */
- public function prep_for_form($data)
- {
- if ($this->_safe_form_data === FALSE OR empty($data))
- {
- return $data;
- }
-
- if (is_array($data))
- {
- foreach ($data as $key => $val)
- {
- $data[$key] = $this->prep_for_form($val);
- }
-
- return $data;
- }
-
- return str_replace(array("'", '"', '<', '>'), array('&#39;', '&quot;', '&lt;', '&gt;'), stripslashes($data));
- }
-
- // --------------------------------------------------------------------
-
- /**
* Prep URL
*
* @param string
@@ -1538,12 +1532,7 @@ class CI_Form_validation {
*/
public function prep_url($str = '')
{
- if ($str === 'http://' OR $str === '')
- {
- return '';
- }
-
- if (strpos($str, 'http://') !== 0 && strpos($str, 'https://') !== 0)
+ if ($str !== '' && stripos($str, 'http://') !== 0 && stripos($str, 'https://') !== 0)
{
return 'http://'.$str;
}
diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php
index 3f9698c15..4e5fc7be6 100644
--- a/system/libraries/Image_lib.php
+++ b/system/libraries/Image_lib.php
@@ -947,6 +947,10 @@ class CI_Image_lib {
$cmd_in = 'pngtopnm';
$cmd_out = 'ppmtopng';
break;
+ case 18 :
+ $cmd_in = 'webptopnm';
+ $cmd_out = 'ppmtowebp';
+ break;
}
if ($action === 'crop')
@@ -1208,7 +1212,7 @@ class CI_Image_lib {
}
// Build the finalized image
- if ($wm_img_type === 3 && function_exists('imagealphablending'))
+ if ($wm_img_type === 3)
{
@imagealphablending($src_img, TRUE);
}
@@ -1473,6 +1477,14 @@ class CI_Image_lib {
}
return imagecreatefrompng($path);
+ case 18:
+ if ( ! function_exists('imagecreatefromwebp'))
+ {
+ $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_webp_not_supported'));
+ return FALSE;
+ }
+
+ return imagecreatefromwebp($path);
default:
$this->set_error(array('imglib_unsupported_imagecreate'));
return FALSE;
@@ -1533,6 +1545,19 @@ class CI_Image_lib {
return FALSE;
}
break;
+ case 18:
+ if ( ! function_exists('imagewebp'))
+ {
+ $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_webp_not_supported'));
+ return FALSE;
+ }
+
+ if ( ! @imagewebp($resource, $this->full_dst_path))
+ {
+ $this->set_error('imglib_save_failed');
+ return FALSE;
+ }
+ break;
default:
$this->set_error(array('imglib_unsupported_imagecreate'));
return FALSE;
@@ -1552,7 +1577,16 @@ class CI_Image_lib {
*/
public function image_display_gd($resource)
{
- header('Content-Disposition: filename='.$this->source_image.';');
+ // RFC 6266 allows for multibyte filenames, but only in UTF-8,
+ // so we have to make it conditional ...
+ $filename = basename(empty($this->new_image) ? $this->source_image : $this->new_image);
+ $charset = strtoupper(config_item('charset'));
+ $utf8_filename = ($charset !== 'UTF-8')
+ ? get_instance()->utf8->convert_to_utf8($filename, $charset)
+ : $filename;
+ isset($utf8_filename[0]) && $utf8_filename = " filename*=UTF-8''".rawurlencode($utf8_filename);
+
+ header('Content-Disposition: filename="'.$filename.'";'.$utf8_filename);
header('Content-Type: '.$this->mime_type);
header('Content-Transfer-Encoding: binary');
header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
@@ -1565,6 +1599,8 @@ class CI_Image_lib {
break;
case 3 : imagepng($resource);
break;
+ case 18 : imagewebp($resource);
+ break;
default: echo 'Unable to display the image';
break;
}
diff --git a/system/libraries/Javascript.php b/system/libraries/Javascript.php
deleted file mode 100644
index 8f2cf5871..000000000
--- a/system/libraries/Javascript.php
+++ /dev/null
@@ -1,857 +0,0 @@
-<?php
-/**
- * CodeIgniter
- *
- * An open source application development framework for PHP
- *
- * This content is released under the MIT License (MIT)
- *
- * Copyright (c) 2019 - 2022, CodeIgniter Foundation
- *
- * 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 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
- * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
- * @license https://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');
-
-/**
- * Javascript Class
- *
- * @package CodeIgniter
- * @subpackage Libraries
- * @category Javascript
- * @author EllisLab Dev Team
- * @link https://codeigniter.com/userguide3/libraries/javascript.html
- * @deprecated 3.0.0 This was never a good idea in the first place.
- */
-class CI_Javascript {
-
- /**
- * JavaScript location
- *
- * @var string
- */
- protected $_javascript_location = 'js';
-
- // --------------------------------------------------------------------
-
- /**
- * Constructor
- *
- * @param array $params
- * @return void
- */
- public function __construct($params = array())
- {
- $defaults = array('js_library_driver' => 'jquery', 'autoload' => TRUE);
-
- foreach ($defaults as $key => $val)
- {
- if (isset($params[$key]) && $params[$key] !== '')
- {
- $defaults[$key] = $params[$key];
- }
- }
-
- extract($defaults);
-
- $this->CI =& get_instance();
-
- // load the requested js library
- $this->CI->load->library('Javascript/'.$js_library_driver, array('autoload' => $autoload));
- // make js to refer to current library
- $this->js =& $this->CI->$js_library_driver;
-
- log_message('info', 'Javascript Class Initialized and loaded. Driver used: '.$js_library_driver);
- }
-
- // --------------------------------------------------------------------
- // Event Code
- // --------------------------------------------------------------------
-
- /**
- * Blur
- *
- * Outputs a javascript library blur event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- public function blur($element = 'this', $js = '')
- {
- return $this->js->_blur($element, $js);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Change
- *
- * Outputs a javascript library change event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- public function change($element = 'this', $js = '')
- {
- return $this->js->_change($element, $js);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Click
- *
- * Outputs a javascript library click event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @param bool whether or not to return false
- * @return string
- */
- public function click($element = 'this', $js = '', $ret_false = TRUE)
- {
- return $this->js->_click($element, $js, $ret_false);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Double Click
- *
- * Outputs a javascript library dblclick event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- public function dblclick($element = 'this', $js = '')
- {
- return $this->js->_dblclick($element, $js);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Error
- *
- * Outputs a javascript library error event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- public function error($element = 'this', $js = '')
- {
- return $this->js->_error($element, $js);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Focus
- *
- * Outputs a javascript library focus event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- public function focus($element = 'this', $js = '')
- {
- return $this->js->_focus($element, $js);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Hover
- *
- * Outputs a javascript library hover event
- *
- * @param string - element
- * @param string - Javascript code for mouse over
- * @param string - Javascript code for mouse out
- * @return string
- */
- public function hover($element = 'this', $over = '', $out = '')
- {
- return $this->js->_hover($element, $over, $out);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Keydown
- *
- * Outputs a javascript library keydown event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- public function keydown($element = 'this', $js = '')
- {
- return $this->js->_keydown($element, $js);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Keyup
- *
- * Outputs a javascript library keydown event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- public function keyup($element = 'this', $js = '')
- {
- return $this->js->_keyup($element, $js);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Load
- *
- * Outputs a javascript library load event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- public function load($element = 'this', $js = '')
- {
- return $this->js->_load($element, $js);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Mousedown
- *
- * Outputs a javascript library mousedown event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- public function mousedown($element = 'this', $js = '')
- {
- return $this->js->_mousedown($element, $js);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Mouse Out
- *
- * Outputs a javascript library mouseout event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- public function mouseout($element = 'this', $js = '')
- {
- return $this->js->_mouseout($element, $js);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Mouse Over
- *
- * Outputs a javascript library mouseover event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- public function mouseover($element = 'this', $js = '')
- {
- return $this->js->_mouseover($element, $js);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Mouseup
- *
- * Outputs a javascript library mouseup event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- public function mouseup($element = 'this', $js = '')
- {
- return $this->js->_mouseup($element, $js);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Output
- *
- * Outputs the called javascript to the screen
- *
- * @param string The code to output
- * @return string
- */
- public function output($js)
- {
- return $this->js->_output($js);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Ready
- *
- * Outputs a javascript library mouseup event
- *
- * @param string $js Code to execute
- * @return string
- */
- public function ready($js)
- {
- return $this->js->_document_ready($js);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Resize
- *
- * Outputs a javascript library resize event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- public function resize($element = 'this', $js = '')
- {
- return $this->js->_resize($element, $js);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Scroll
- *
- * Outputs a javascript library scroll event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- public function scroll($element = 'this', $js = '')
- {
- return $this->js->_scroll($element, $js);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Unload
- *
- * Outputs a javascript library unload event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- public function unload($element = 'this', $js = '')
- {
- return $this->js->_unload($element, $js);
- }
-
- // --------------------------------------------------------------------
- // Effects
- // --------------------------------------------------------------------
-
- /**
- * Add Class
- *
- * Outputs a javascript library addClass event
- *
- * @param string - element
- * @param string - Class to add
- * @return string
- */
- public function addClass($element = 'this', $class = '')
- {
- return $this->js->_addClass($element, $class);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Animate
- *
- * Outputs a javascript library animate event
- *
- * @param string $element = 'this'
- * @param array $params = array()
- * @param mixed $speed 'slow', 'normal', 'fast', or time in milliseconds
- * @param string $extra
- * @return string
- */
- public function animate($element = 'this', $params = array(), $speed = '', $extra = '')
- {
- return $this->js->_animate($element, $params, $speed, $extra);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Fade In
- *
- * Outputs a javascript library hide event
- *
- * @param string - element
- * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds
- * @param string - Javascript callback function
- * @return string
- */
- public function fadeIn($element = 'this', $speed = '', $callback = '')
- {
- return $this->js->_fadeIn($element, $speed, $callback);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Fade Out
- *
- * Outputs a javascript library hide event
- *
- * @param string - element
- * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds
- * @param string - Javascript callback function
- * @return string
- */
- public function fadeOut($element = 'this', $speed = '', $callback = '')
- {
- return $this->js->_fadeOut($element, $speed, $callback);
- }
- // --------------------------------------------------------------------
-
- /**
- * Slide Up
- *
- * Outputs a javascript library slideUp event
- *
- * @param string - element
- * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds
- * @param string - Javascript callback function
- * @return string
- */
- public function slideUp($element = 'this', $speed = '', $callback = '')
- {
- return $this->js->_slideUp($element, $speed, $callback);
-
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Remove Class
- *
- * Outputs a javascript library removeClass event
- *
- * @param string - element
- * @param string - Class to add
- * @return string
- */
- public function removeClass($element = 'this', $class = '')
- {
- return $this->js->_removeClass($element, $class);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Slide Down
- *
- * Outputs a javascript library slideDown event
- *
- * @param string - element
- * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds
- * @param string - Javascript callback function
- * @return string
- */
- public function slideDown($element = 'this', $speed = '', $callback = '')
- {
- return $this->js->_slideDown($element, $speed, $callback);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Slide Toggle
- *
- * Outputs a javascript library slideToggle event
- *
- * @param string - element
- * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds
- * @param string - Javascript callback function
- * @return string
- */
- public function slideToggle($element = 'this', $speed = '', $callback = '')
- {
- return $this->js->_slideToggle($element, $speed, $callback);
-
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Hide
- *
- * Outputs a javascript library hide action
- *
- * @param string - element
- * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds
- * @param string - Javascript callback function
- * @return string
- */
- public function hide($element = 'this', $speed = '', $callback = '')
- {
- return $this->js->_hide($element, $speed, $callback);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Toggle
- *
- * Outputs a javascript library toggle event
- *
- * @param string - element
- * @return string
- */
- public function toggle($element = 'this')
- {
- return $this->js->_toggle($element);
-
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Toggle Class
- *
- * Outputs a javascript library toggle class event
- *
- * @param string $element = 'this'
- * @param string $class = ''
- * @return string
- */
- public function toggleClass($element = 'this', $class = '')
- {
- return $this->js->_toggleClass($element, $class);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Show
- *
- * Outputs a javascript library show event
- *
- * @param string - element
- * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds
- * @param string - Javascript callback function
- * @return string
- */
- public function show($element = 'this', $speed = '', $callback = '')
- {
- return $this->js->_show($element, $speed, $callback);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Compile
- *
- * gather together all script needing to be output
- *
- * @param string $view_var
- * @param bool $script_tags
- * @return string
- */
- public function compile($view_var = 'script_foot', $script_tags = TRUE)
- {
- $this->js->_compile($view_var, $script_tags);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Clear Compile
- *
- * Clears any previous javascript collected for output
- *
- * @return void
- */
- public function clear_compile()
- {
- $this->js->_clear_compile();
- }
-
- // --------------------------------------------------------------------
-
- /**
- * External
- *
- * Outputs a <script> tag with the source as an external js file
- *
- * @param string $external_file
- * @param bool $relative
- * @return string
- */
- public function external($external_file = '', $relative = FALSE)
- {
- if ($external_file !== '')
- {
- $this->_javascript_location = $external_file;
- }
- elseif ($this->CI->config->item('javascript_location') !== '')
- {
- $this->_javascript_location = $this->CI->config->item('javascript_location');
- }
-
- if ($relative === TRUE OR strpos($external_file, 'http://') === 0 OR strpos($external_file, 'https://') === 0)
- {
- $str = $this->_open_script($external_file);
- }
- elseif (strpos($this->_javascript_location, 'http://') !== FALSE)
- {
- $str = $this->_open_script($this->_javascript_location.$external_file);
- }
- else
- {
- $str = $this->_open_script($this->CI->config->slash_item('base_url').$this->_javascript_location.$external_file);
- }
-
- return $str.$this->_close_script();
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Inline
- *
- * Outputs a <script> tag
- *
- * @param string The element to attach the event to
- * @param bool If a CDATA section should be added
- * @return string
- */
- public function inline($script, $cdata = TRUE)
- {
- return $this->_open_script()
- . ($cdata ? "\n// <![CDATA[\n".$script."\n// ]]>\n" : "\n".$script."\n")
- . $this->_close_script();
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Open Script
- *
- * Outputs an opening <script>
- *
- * @param string
- * @return string
- */
- protected function _open_script($src = '')
- {
- return '<script type="text/javascript" charset="'.strtolower($this->CI->config->item('charset')).'"'
- .($src === '' ? '>' : ' src="'.$src.'">');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Close Script
- *
- * Outputs an closing </script>
- *
- * @param string
- * @return string
- */
- protected function _close_script($extra = "\n")
- {
- return '</script>'.$extra;
- }
-
- // --------------------------------------------------------------------
- // AJAX-Y STUFF - still a testbed
- // --------------------------------------------------------------------
-
- /**
- * Update
- *
- * Outputs a javascript library slideDown event
- *
- * @param string - element
- * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds
- * @param string - Javascript callback function
- * @return string
- */
- public function update($element = 'this', $speed = '', $callback = '')
- {
- return $this->js->_updater($element, $speed, $callback);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Generate JSON
- *
- * Can be passed a database result or associative array and returns a JSON formatted string
- *
- * @param mixed result set or array
- * @param bool match array types (defaults to objects)
- * @return string a json formatted string
- */
- public function generate_json($result = NULL, $match_array_type = FALSE)
- {
- // JSON data can optionally be passed to this function
- // either as a database result object or an array, or a user supplied array
- if ($result !== NULL)
- {
- if (is_object($result))
- {
- $json_result = is_callable(array($result, 'result_array')) ? $result->result_array() : (array) $result;
- }
- elseif (is_array($result))
- {
- $json_result = $result;
- }
- else
- {
- return $this->_prep_args($result);
- }
- }
- else
- {
- return 'null';
- }
-
- $json = array();
- $_is_assoc = TRUE;
-
- if ( ! is_array($json_result) && empty($json_result))
- {
- show_error('Generate JSON Failed - Illegal key, value pair.');
- }
- elseif ($match_array_type)
- {
- $_is_assoc = $this->_is_associative_array($json_result);
- }
-
- foreach ($json_result as $k => $v)
- {
- if ($_is_assoc)
- {
- $json[] = $this->_prep_args($k, TRUE).':'.$this->generate_json($v, $match_array_type);
- }
- else
- {
- $json[] = $this->generate_json($v, $match_array_type);
- }
- }
-
- $json = implode(',', $json);
-
- return $_is_assoc ? '{'.$json.'}' : '['.$json.']';
-
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Is associative array
- *
- * Checks for an associative array
- *
- * @param array
- * @return bool
- */
- protected function _is_associative_array($arr)
- {
- foreach (array_keys($arr) as $key => $val)
- {
- if ($key !== $val)
- {
- return TRUE;
- }
- }
-
- return FALSE;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Prep Args
- *
- * Ensures a standard json value and escapes values
- *
- * @param mixed $result
- * @param bool $is_key = FALSE
- * @return string
- */
- protected function _prep_args($result, $is_key = FALSE)
- {
- if ($result === NULL)
- {
- return 'null';
- }
- elseif (is_bool($result))
- {
- return ($result === TRUE) ? 'true' : 'false';
- }
- elseif (is_string($result) OR $is_key)
- {
- return '"'.str_replace(array('\\', "\t", "\n", "\r", '"', '/'), array('\\\\', '\\t', '\\n', "\\r", '\"', '\/'), $result).'"';
- }
- elseif (is_scalar($result))
- {
- return $result;
- }
- }
-
-}
diff --git a/system/libraries/Javascript/Jquery.php b/system/libraries/Javascript/Jquery.php
deleted file mode 100644
index e06f1ba02..000000000
--- a/system/libraries/Javascript/Jquery.php
+++ /dev/null
@@ -1,1077 +0,0 @@
-<?php
-/**
- * CodeIgniter
- *
- * An open source application development framework for PHP
- *
- * This content is released under the MIT License (MIT)
- *
- * Copyright (c) 2019 - 2022, CodeIgniter Foundation
- *
- * 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 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
- * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
- * @license https://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');
-
-/**
- * Jquery Class
- *
- * @package CodeIgniter
- * @subpackage Libraries
- * @category Loader
- * @author EllisLab Dev Team
- * @link https://codeigniter.com/userguide3/libraries/javascript.html
- */
-class CI_Jquery extends CI_Javascript {
-
- /**
- * JavaScript directory location
- *
- * @var string
- */
- protected $_javascript_folder = 'js';
-
- /**
- * JQuery code for load
- *
- * @var array
- */
- public $jquery_code_for_load = array();
-
- /**
- * JQuery code for compile
- *
- * @var array
- */
- public $jquery_code_for_compile = array();
-
- /**
- * JQuery corner active flag
- *
- * @var bool
- */
- public $jquery_corner_active = FALSE;
-
- /**
- * JQuery table sorter active flag
- *
- * @var bool
- */
- public $jquery_table_sorter_active = FALSE;
-
- /**
- * JQuery table sorter pager active
- *
- * @var bool
- */
- public $jquery_table_sorter_pager_active = FALSE;
-
- /**
- * JQuery AJAX image
- *
- * @var string
- */
- public $jquery_ajax_img = '';
-
- // --------------------------------------------------------------------
-
- /**
- * Constructor
- *
- * @param array $params
- * @return void
- */
- public function __construct($params)
- {
- $this->CI =& get_instance();
- extract($params);
-
- if ($autoload === TRUE)
- {
- $this->script();
- }
-
- log_message('info', 'Jquery Class Initialized');
- }
-
- // --------------------------------------------------------------------
- // Event Code
- // --------------------------------------------------------------------
-
- /**
- * Blur
- *
- * Outputs a jQuery blur event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- protected function _blur($element = 'this', $js = '')
- {
- return $this->_add_event($element, $js, 'blur');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Change
- *
- * Outputs a jQuery change event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- protected function _change($element = 'this', $js = '')
- {
- return $this->_add_event($element, $js, 'change');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Click
- *
- * Outputs a jQuery click event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @param bool whether or not to return false
- * @return string
- */
- protected function _click($element = 'this', $js = '', $ret_false = TRUE)
- {
- is_array($js) OR $js = array($js);
-
- if ($ret_false)
- {
- $js[] = 'return false;';
- }
-
- return $this->_add_event($element, $js, 'click');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Double Click
- *
- * Outputs a jQuery dblclick event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- protected function _dblclick($element = 'this', $js = '')
- {
- return $this->_add_event($element, $js, 'dblclick');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Error
- *
- * Outputs a jQuery error event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- protected function _error($element = 'this', $js = '')
- {
- return $this->_add_event($element, $js, 'error');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Focus
- *
- * Outputs a jQuery focus event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- protected function _focus($element = 'this', $js = '')
- {
- return $this->_add_event($element, $js, 'focus');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Hover
- *
- * Outputs a jQuery hover event
- *
- * @param string - element
- * @param string - Javascript code for mouse over
- * @param string - Javascript code for mouse out
- * @return string
- */
- protected function _hover($element = 'this', $over = '', $out = '')
- {
- $event = "\n\t$(".$this->_prep_element($element).").hover(\n\t\tfunction()\n\t\t{\n\t\t\t{$over}\n\t\t}, \n\t\tfunction()\n\t\t{\n\t\t\t{$out}\n\t\t});\n";
-
- $this->jquery_code_for_compile[] = $event;
-
- return $event;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Keydown
- *
- * Outputs a jQuery keydown event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- protected function _keydown($element = 'this', $js = '')
- {
- return $this->_add_event($element, $js, 'keydown');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Keyup
- *
- * Outputs a jQuery keydown event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- protected function _keyup($element = 'this', $js = '')
- {
- return $this->_add_event($element, $js, 'keyup');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Load
- *
- * Outputs a jQuery load event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- protected function _load($element = 'this', $js = '')
- {
- return $this->_add_event($element, $js, 'load');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Mousedown
- *
- * Outputs a jQuery mousedown event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- protected function _mousedown($element = 'this', $js = '')
- {
- return $this->_add_event($element, $js, 'mousedown');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Mouse Out
- *
- * Outputs a jQuery mouseout event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- protected function _mouseout($element = 'this', $js = '')
- {
- return $this->_add_event($element, $js, 'mouseout');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Mouse Over
- *
- * Outputs a jQuery mouseover event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- protected function _mouseover($element = 'this', $js = '')
- {
- return $this->_add_event($element, $js, 'mouseover');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Mouseup
- *
- * Outputs a jQuery mouseup event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- protected function _mouseup($element = 'this', $js = '')
- {
- return $this->_add_event($element, $js, 'mouseup');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Output
- *
- * Outputs script directly
- *
- * @param array $array_js = array()
- * @return void
- */
- protected function _output($array_js = array())
- {
- if ( ! is_array($array_js))
- {
- $array_js = array($array_js);
- }
-
- foreach ($array_js as $js)
- {
- $this->jquery_code_for_compile[] = "\t".$js."\n";
- }
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Resize
- *
- * Outputs a jQuery resize event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- protected function _resize($element = 'this', $js = '')
- {
- return $this->_add_event($element, $js, 'resize');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Scroll
- *
- * Outputs a jQuery scroll event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- protected function _scroll($element = 'this', $js = '')
- {
- return $this->_add_event($element, $js, 'scroll');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Unload
- *
- * Outputs a jQuery unload event
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @return string
- */
- protected function _unload($element = 'this', $js = '')
- {
- return $this->_add_event($element, $js, 'unload');
- }
-
- // --------------------------------------------------------------------
- // Effects
- // --------------------------------------------------------------------
-
- /**
- * Add Class
- *
- * Outputs a jQuery addClass event
- *
- * @param string $element
- * @param string $class
- * @return string
- */
- protected function _addClass($element = 'this', $class = '')
- {
- $element = $this->_prep_element($element);
- return '$('.$element.').addClass("'.$class.'");';
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Animate
- *
- * Outputs a jQuery animate event
- *
- * @param string $element
- * @param array $params
- * @param string $speed 'slow', 'normal', 'fast', or time in milliseconds
- * @param string $extra
- * @return string
- */
- protected function _animate($element = 'this', $params = array(), $speed = '', $extra = '')
- {
- $element = $this->_prep_element($element);
- $speed = $this->_validate_speed($speed);
-
- $animations = "\t\t\t";
-
- foreach ($params as $param => $value)
- {
- $animations .= $param.": '".$value."', ";
- }
-
- $animations = substr($animations, 0, -2); // remove the last ", "
-
- if ($speed !== '')
- {
- $speed = ', '.$speed;
- }
-
- if ($extra !== '')
- {
- $extra = ', '.$extra;
- }
-
- return "$({$element}).animate({\n$animations\n\t\t}".$speed.$extra.');';
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Fade In
- *
- * Outputs a jQuery hide event
- *
- * @param string - element
- * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds
- * @param string - Javascript callback function
- * @return string
- */
- protected function _fadeIn($element = 'this', $speed = '', $callback = '')
- {
- $element = $this->_prep_element($element);
- $speed = $this->_validate_speed($speed);
-
- if ($callback !== '')
- {
- $callback = ", function(){\n{$callback}\n}";
- }
-
- return "$({$element}).fadeIn({$speed}{$callback});";
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Fade Out
- *
- * Outputs a jQuery hide event
- *
- * @param string - element
- * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds
- * @param string - Javascript callback function
- * @return string
- */
- protected function _fadeOut($element = 'this', $speed = '', $callback = '')
- {
- $element = $this->_prep_element($element);
- $speed = $this->_validate_speed($speed);
-
- if ($callback !== '')
- {
- $callback = ", function(){\n{$callback}\n}";
- }
-
- return '$('.$element.').fadeOut('.$speed.$callback.');';
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Hide
- *
- * Outputs a jQuery hide action
- *
- * @param string - element
- * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds
- * @param string - Javascript callback function
- * @return string
- */
- protected function _hide($element = 'this', $speed = '', $callback = '')
- {
- $element = $this->_prep_element($element);
- $speed = $this->_validate_speed($speed);
-
- if ($callback !== '')
- {
- $callback = ", function(){\n{$callback}\n}";
- }
-
- return "$({$element}).hide({$speed}{$callback});";
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Remove Class
- *
- * Outputs a jQuery remove class event
- *
- * @param string $element
- * @param string $class
- * @return string
- */
- protected function _removeClass($element = 'this', $class = '')
- {
- $element = $this->_prep_element($element);
- return '$('.$element.').removeClass("'.$class.'");';
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Slide Up
- *
- * Outputs a jQuery slideUp event
- *
- * @param string - element
- * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds
- * @param string - Javascript callback function
- * @return string
- */
- protected function _slideUp($element = 'this', $speed = '', $callback = '')
- {
- $element = $this->_prep_element($element);
- $speed = $this->_validate_speed($speed);
-
- if ($callback !== '')
- {
- $callback = ", function(){\n{$callback}\n}";
- }
-
- return '$('.$element.').slideUp('.$speed.$callback.');';
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Slide Down
- *
- * Outputs a jQuery slideDown event
- *
- * @param string - element
- * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds
- * @param string - Javascript callback function
- * @return string
- */
- protected function _slideDown($element = 'this', $speed = '', $callback = '')
- {
- $element = $this->_prep_element($element);
- $speed = $this->_validate_speed($speed);
-
- if ($callback !== '')
- {
- $callback = ", function(){\n{$callback}\n}";
- }
-
- return '$('.$element.').slideDown('.$speed.$callback.');';
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Slide Toggle
- *
- * Outputs a jQuery slideToggle event
- *
- * @param string - element
- * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds
- * @param string - Javascript callback function
- * @return string
- */
- protected function _slideToggle($element = 'this', $speed = '', $callback = '')
- {
- $element = $this->_prep_element($element);
- $speed = $this->_validate_speed($speed);
-
- if ($callback !== '')
- {
- $callback = ", function(){\n{$callback}\n}";
- }
-
- return '$('.$element.').slideToggle('.$speed.$callback.');';
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Toggle
- *
- * Outputs a jQuery toggle event
- *
- * @param string - element
- * @return string
- */
- protected function _toggle($element = 'this')
- {
- $element = $this->_prep_element($element);
- return '$('.$element.').toggle();';
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Toggle Class
- *
- * Outputs a jQuery toggle class event
- *
- * @param string $element
- * @param string $class
- * @return string
- */
- protected function _toggleClass($element = 'this', $class = '')
- {
- $element = $this->_prep_element($element);
- return '$('.$element.').toggleClass("'.$class.'");';
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Show
- *
- * Outputs a jQuery show event
- *
- * @param string - element
- * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds
- * @param string - Javascript callback function
- * @return string
- */
- protected function _show($element = 'this', $speed = '', $callback = '')
- {
- $element = $this->_prep_element($element);
- $speed = $this->_validate_speed($speed);
-
- if ($callback !== '')
- {
- $callback = ", function(){\n{$callback}\n}";
- }
-
- return '$('.$element.').show('.$speed.$callback.');';
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Updater
- *
- * An Ajax call that populates the designated DOM node with
- * returned content
- *
- * @param string The element to attach the event to
- * @param string the controller to run the call against
- * @param string optional parameters
- * @return string
- */
-
- protected function _updater($container = 'this', $controller = '', $options = '')
- {
- $container = $this->_prep_element($container);
- $controller = (strpos('://', $controller) === FALSE) ? $controller : $this->CI->config->site_url($controller);
-
- // ajaxStart and ajaxStop are better choices here... but this is a stop gap
- if ($this->CI->config->item('javascript_ajax_img') === '')
- {
- $loading_notifier = 'Loading...';
- }
- else
- {
- $loading_notifier = '<img src="'.$this->CI->config->slash_item('base_url').$this->CI->config->item('javascript_ajax_img').'" alt="Loading" />';
- }
-
- $updater = '$('.$container.").empty();\n" // anything that was in... get it out
- ."\t\t$(".$container.').prepend("'.$loading_notifier."\");\n"; // to replace with an image
-
- $request_options = '';
- if ($options !== '')
- {
- $request_options .= ', {'
- .(is_array($options) ? "'".implode("', '", $options)."'" : "'".str_replace(':', "':'", $options)."'")
- .'}';
- }
-
- return $updater."\t\t$($container).load('$controller'$request_options);";
- }
-
- // --------------------------------------------------------------------
- // Pre-written handy stuff
- // --------------------------------------------------------------------
-
- /**
- * Zebra tables
- *
- * @param string $class
- * @param string $odd
- * @param string $hover
- * @return string
- */
- protected function _zebraTables($class = '', $odd = 'odd', $hover = '')
- {
- $class = ($class !== '') ? '.'.$class : '';
- $zebra = "\t\$(\"table{$class} tbody tr:nth-child(even)\").addClass(\"{$odd}\");";
-
- $this->jquery_code_for_compile[] = $zebra;
-
- if ($hover !== '')
- {
- $hover = $this->hover("table{$class} tbody tr", "$(this).addClass('hover');", "$(this).removeClass('hover');");
- }
-
- return $zebra;
- }
-
- // --------------------------------------------------------------------
- // Plugins
- // --------------------------------------------------------------------
-
- /**
- * Corner Plugin
- *
- * @link https://www.malsup.com/jquery/corner/
- * @param string $element
- * @param string $corner_style
- * @return string
- */
- public function corner($element = '', $corner_style = '')
- {
- // may want to make this configurable down the road
- $corner_location = '/plugins/jquery.corner.js';
-
- if ($corner_style !== '')
- {
- $corner_style = '"'.$corner_style.'"';
- }
-
- return '$('.$this->_prep_element($element).').corner('.$corner_style.');';
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Modal window
- *
- * Load a thickbox modal window
- *
- * @param string $src
- * @param bool $relative
- * @return void
- */
- public function modal($src, $relative = FALSE)
- {
- $this->jquery_code_for_load[] = $this->external($src, $relative);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Effect
- *
- * Load an Effect library
- *
- * @param string $src
- * @param bool $relative
- * @return void
- */
- public function effect($src, $relative = FALSE)
- {
- $this->jquery_code_for_load[] = $this->external($src, $relative);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Plugin
- *
- * Load a plugin library
- *
- * @param string $src
- * @param bool $relative
- * @return void
- */
- public function plugin($src, $relative = FALSE)
- {
- $this->jquery_code_for_load[] = $this->external($src, $relative);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * UI
- *
- * Load a user interface library
- *
- * @param string $src
- * @param bool $relative
- * @return void
- */
- public function ui($src, $relative = FALSE)
- {
- $this->jquery_code_for_load[] = $this->external($src, $relative);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Sortable
- *
- * Creates a jQuery sortable
- *
- * @param string $element
- * @param array $options
- * @return string
- */
- public function sortable($element, $options = array())
- {
- if (count($options) > 0)
- {
- $sort_options = array();
- foreach ($options as $k=>$v)
- {
- $sort_options[] = "\n\t\t".$k.': '.$v;
- }
- $sort_options = implode(',', $sort_options);
- }
- else
- {
- $sort_options = '';
- }
-
- return '$('.$this->_prep_element($element).').sortable({'.$sort_options."\n\t});";
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Table Sorter Plugin
- *
- * @param string table name
- * @param string plugin location
- * @return string
- */
- public function tablesorter($table = '', $options = '')
- {
- $this->jquery_code_for_compile[] = "\t$(".$this->_prep_element($table).').tablesorter('.$options.");\n";
- }
-
- // --------------------------------------------------------------------
- // Class functions
- // --------------------------------------------------------------------
-
- /**
- * Add Event
- *
- * Constructs the syntax for an event, and adds to into the array for compilation
- *
- * @param string The element to attach the event to
- * @param string The code to execute
- * @param string The event to pass
- * @return string
- */
- protected function _add_event($element, $js, $event)
- {
- if (is_array($js))
- {
- $js = implode("\n\t\t", $js);
- }
-
- $event = "\n\t$(".$this->_prep_element($element).').'.$event."(function(){\n\t\t{$js}\n\t});\n";
- $this->jquery_code_for_compile[] = $event;
- return $event;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Compile
- *
- * As events are specified, they are stored in an array
- * This function compiles them all for output on a page
- *
- * @param string $view_var
- * @param bool $script_tags
- * @return void
- */
- protected function _compile($view_var = 'script_foot', $script_tags = TRUE)
- {
- // External references
- $external_scripts = implode('', $this->jquery_code_for_load);
- $this->CI->load->vars(array('library_src' => $external_scripts));
-
- if (count($this->jquery_code_for_compile) === 0)
- {
- // no inline references, let's just return
- return;
- }
-
- // Inline references
- $script = '$(document).ready(function() {'."\n"
- .implode('', $this->jquery_code_for_compile)
- .'});';
-
- $output = ($script_tags === FALSE) ? $script : $this->inline($script);
-
- $this->CI->load->vars(array($view_var => $output));
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Clear Compile
- *
- * Clears the array of script events collected for output
- *
- * @return void
- */
- protected function _clear_compile()
- {
- $this->jquery_code_for_compile = array();
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Document Ready
- *
- * A wrapper for writing document.ready()
- *
- * @param array $js
- * @return void
- */
- protected function _document_ready($js)
- {
- is_array($js) OR $js = array($js);
-
- foreach ($js as $script)
- {
- $this->jquery_code_for_compile[] = $script;
- }
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Script Tag
- *
- * Outputs the script tag that loads the jquery.js file into an HTML document
- *
- * @param string $library_src
- * @param bool $relative
- * @return string
- */
- public function script($library_src = '', $relative = FALSE)
- {
- $library_src = $this->external($library_src, $relative);
- $this->jquery_code_for_load[] = $library_src;
- return $library_src;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Prep Element
- *
- * Puts HTML element in quotes for use in jQuery code
- * unless the supplied element is the Javascript 'this'
- * object, in which case no quotes are added
- *
- * @param string
- * @return string
- */
- protected function _prep_element($element)
- {
- if ($element !== 'this')
- {
- $element = '"'.$element.'"';
- }
-
- return $element;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Validate Speed
- *
- * Ensures the speed parameter is valid for jQuery
- *
- * @param string
- * @return string
- */
- protected function _validate_speed($speed)
- {
- if (in_array($speed, array('slow', 'normal', 'fast')))
- {
- return '"'.$speed.'"';
- }
- elseif (preg_match('/[^0-9]/', $speed))
- {
- return '';
- }
-
- return $speed;
- }
-
-}
diff --git a/system/libraries/Javascript/index.html b/system/libraries/Javascript/index.html
deleted file mode 100644
index b702fbc39..000000000
--- a/system/libraries/Javascript/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <title>403 Forbidden</title>
-</head>
-<body>
-
-<p>Directory access is forbidden.</p>
-
-</body>
-</html>
diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php
index 4d945a002..7d21b47b3 100644
--- a/system/libraries/Pagination.php
+++ b/system/libraries/Pagination.php
@@ -364,14 +364,6 @@ class CI_Pagination {
unset($params['attributes']);
}
- // Deprecated legacy support for the anchor_class option
- // Should be removed in CI 3.1+
- if (isset($params['anchor_class']))
- {
- empty($params['anchor_class']) OR $attributes['class'] = $params['anchor_class'];
- unset($params['anchor_class']);
- }
-
foreach ($params as $key => $val)
{
if (property_exists($this, $key))
diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php
index a211ce31b..2d55f822a 100644
--- a/system/libraries/Session/Session.php
+++ b/system/libraries/Session/Session.php
@@ -205,8 +205,6 @@ class CI_Session {
*/
protected function _ci_load_classes($driver)
{
- // PHP 5.4 compatibility
- interface_exists('SessionHandlerInterface', FALSE) OR require_once(BASEPATH.'libraries/Session/SessionHandlerInterface.php');
// PHP 7 compatibility
interface_exists('SessionUpdateTimestampHandlerInterface', FALSE) OR require_once(BASEPATH.'libraries/Session/SessionUpdateTimestampHandlerInterface.php');
diff --git a/system/libraries/Session/SessionHandlerInterface.php b/system/libraries/Session/SessionHandlerInterface.php
deleted file mode 100644
index eadb63c1a..000000000
--- a/system/libraries/Session/SessionHandlerInterface.php
+++ /dev/null
@@ -1,60 +0,0 @@
-<?php
-/**
- * CodeIgniter
- *
- * An open source application development framework for PHP
- *
- * This content is released under the MIT License (MIT)
- *
- * Copyright (c) 2019 - 2022, CodeIgniter Foundation
- *
- * 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 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
- * @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
- * @license https://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');
-
-/**
- * SessionHandlerInterface
- *
- * PHP 5.4 compatibility interface
- *
- * @package CodeIgniter
- * @subpackage Libraries
- * @category Sessions
- * @author Andrey Andreev
- * @link https://codeigniter.com/userguide3/libraries/sessions.html
- */
-interface SessionHandlerInterface {
-
- public function open($save_path, $name);
- public function close();
- public function read($session_id);
- public function write($session_id, $session_data);
- public function destroy($session_id);
- public function gc($maxlifetime);
-}
diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php
index 269dfcd64..4d822d585 100644
--- a/system/libraries/Session/drivers/Session_redis_driver.php
+++ b/system/libraries/Session/drivers/Session_redis_driver.php
@@ -134,27 +134,40 @@ class CI_Session_redis_driver extends CI_Session_driver implements CI_Session_dr
{
log_message('error', 'Session: No Redis save path configured.');
}
- elseif (preg_match('#(?:tcp://)?([^:?]+)(?:\:(\d+))?(\?.+)?#', $this->_config['save_path'], $matches))
+ elseif (preg_match('#^unix://([^\?]+)(?<options>\?.+)?$#', $this->_config['save_path'], $matches))
{
- isset($matches[3]) OR $matches[3] = ''; // Just to avoid undefined index notices below
- $this->_config['save_path'] = array(
- 'host' => $matches[1],
- 'port' => empty($matches[2]) ? NULL : $matches[2],
- 'password' => preg_match('#auth=([^\s&]+)#', $matches[3], $match) ? $match[1] : NULL,
- 'database' => preg_match('#database=(\d+)#', $matches[3], $match) ? (int) $match[1] : NULL,
- 'timeout' => preg_match('#timeout=(\d+\.\d+)#', $matches[3], $match) ? (float) $match[1] : NULL
+ $save_path = array('path' => $matches[1]);
+ }
+ elseif (preg_match('#(?:(?:tcp|tls)://)?([^:?]+)(?:\:(\d+))?(?<options>\?.+)?#', $this->_config['save_path'], $matches))
+ {
+ $save_path = array(
+ 'host' => $matches[1],
+ 'port' => empty($matches[2]) ? NULL : $matches[2],
+ 'timeout' => 0.0 // We always pass this to Redis::connect(), so it needs to exist
);
-
- preg_match('#prefix=([^\s&]+)#', $matches[3], $match) && $this->_key_prefix = $match[1];
}
else
{
log_message('error', 'Session: Invalid Redis save path format: '.$this->_config['save_path']);
}
- if ($this->_config['match_ip'] === TRUE)
+ if (isset($save_path))
{
- $this->_key_prefix .= $_SERVER['REMOTE_ADDR'].':';
+ if (isset($matches['options']))
+ {
+ $save_path['password'] = preg_match('#auth=([^\s&]+)#', $matches['options'], $match) ? $match[1] : NULL;
+ $save_path['database'] = preg_match('#database=(\d+)#', $matches['options'], $match) ? (int) $match[1] : NULL;
+ $save_path['timeout'] = preg_match('#timeout=(\d+\.\d+)#', $matches['options'], $match) ? (float) $match[1] : NULL;
+
+ preg_match('#prefix=([^\s&]+)#', $matches['options'], $match) && $this->_key_prefix = $match[1];
+ }
+
+ $this->_config['save_path'] = $save_path;
+
+ if ($this->_config['match_ip'] === TRUE)
+ {
+ $this->_key_prefix .= $_SERVER['REMOTE_ADDR'].':';
+ }
}
}
@@ -177,17 +190,30 @@ class CI_Session_redis_driver extends CI_Session_driver implements CI_Session_dr
}
$redis = new Redis();
- if ( ! $redis->connect($this->_config['save_path']['host'], $this->_config['save_path']['port'], $this->_config['save_path']['timeout']))
- {
- log_message('error', 'Session: Unable to connect to Redis with the configured settings.');
- }
- elseif (isset($this->_config['save_path']['password']) && ! $redis->auth($this->_config['save_path']['password']))
- {
- log_message('error', 'Session: Unable to authenticate to Redis instance.');
- }
- elseif (isset($this->_config['save_path']['database']) && ! $redis->select($this->_config['save_path']['database']))
+ $connected = isset($this->_config['save_path']['path'])
+ ? $redis->connect($this->_config['save_path']['path'])
+ : $redis->connect(
+ $this->_config['save_path']['host'],
+ $this->_config['save_path']['port'],
+ $this->_config['save_path']['timeout']
+ );
+
+ if ($connected)
{
- log_message('error', 'Session: Unable to select Redis database with index '.$this->_config['save_path']['database']);
+ if (isset($this->_config['save_path']['password']) && ! $redis->auth($this->_config['save_path']['password']))
+ {
+ log_message('error', 'Session: Unable to authenticate to Redis instance.');
+ }
+ elseif (isset($this->_config['save_path']['database']) && ! $redis->select($this->_config['save_path']['database']))
+ {
+ log_message('error', 'Session: Unable to select Redis database with index '.$this->_config['save_path']['database']);
+ }
+ else
+ {
+ $this->_redis = $redis;
+ $this->php5_validate_id();
+ return $this->_success;
+ }
}
else
{
diff --git a/system/libraries/Session/drivers/index.html b/system/libraries/Session/drivers/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/libraries/Session/drivers/index.html
+++ b/system/libraries/Session/drivers/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/libraries/Session/index.html b/system/libraries/Session/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/libraries/Session/index.html
+++ b/system/libraries/Session/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>
diff --git a/system/libraries/Table.php b/system/libraries/Table.php
index 35f456a63..a033ced21 100644
--- a/system/libraries/Table.php
+++ b/system/libraries/Table.php
@@ -428,6 +428,7 @@ class CI_Table {
$this->rows = array();
$this->heading = array();
$this->auto_heading = TRUE;
+ $this->caption = NULL;
return $this;
}
diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php
index 434b6b136..168211a91 100644
--- a/system/libraries/Upload.php
+++ b/system/libraries/Upload.php
@@ -1184,7 +1184,7 @@ class CI_Upload {
* Prevents possible script execution from Apache's handling
* of files' multiple extensions.
*
- * @link http://httpd.apache.org/docs/1.3/mod/mod_mime.html#multipleext
+ * @link https://httpd.apache.org/docs/1.3/mod/mod_mime.html#multipleext
*
* @param string $filename
* @return string
@@ -1258,9 +1258,7 @@ class CI_Upload {
*/
if (DIRECTORY_SEPARATOR !== '\\')
{
- $cmd = function_exists('escapeshellarg')
- ? 'file --brief --mime '.escapeshellarg($file['tmp_name']).' 2>&1'
- : 'file --brief --mime '.$file['tmp_name'].' 2>&1';
+ $cmd = 'file --brief --mime '.escapeshellarg($file['tmp_name']).' 2>&1';
if (function_usable('exec'))
{
@@ -1277,7 +1275,7 @@ class CI_Upload {
}
}
- if ( ! ini_get('safe_mode') && function_usable('shell_exec'))
+ if (function_usable('shell_exec'))
{
$mime = @shell_exec($cmd);
if (strlen($mime) > 0)
diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php
index a22841cca..8587015e8 100644
--- a/system/libraries/Xmlrpc.php
+++ b/system/libraries/Xmlrpc.php
@@ -744,7 +744,7 @@ class XML_RPC_Client extends CI_Xmlrpc
{
break;
}
- // See https://bugs.php.net/bug.php?id=39598 and http://php.net/manual/en/function.fwrite.php#96951
+ // See https://bugs.php.net/bug.php?id=39598 and https://secure.php.net/manual/en/function.fwrite.php#96951
elseif ($result === 0)
{
if ($timestamp === 0)
@@ -837,9 +837,7 @@ class XML_RPC_Response
{
// error
$this->errno = $code;
- $this->errstr = htmlspecialchars($fstr,
- (is_php('5.4') ? ENT_XML1 | ENT_NOQUOTES : ENT_NOQUOTES),
- 'UTF-8');
+ $this->errstr = htmlspecialchars($fstr, ENT_XML1 | ENT_NOQUOTES, 'UTF-8');
}
elseif ( ! is_object($val))
{
@@ -1721,7 +1719,7 @@ class XML_RPC_Values extends CI_Xmlrpc
if ($typeof != 1)
{
- echo '<strong>XML_RPC_Values</strong>: not a scalar type (${typeof})<br />';
+ echo "<strong>XML_RPC_Values</strong>: not a scalar type ($typeof)<br />";
return 0;
}
diff --git a/system/libraries/Xmlrpcs.php b/system/libraries/Xmlrpcs.php
index b91d3fcb3..eb5a24c49 100644
--- a/system/libraries/Xmlrpcs.php
+++ b/system/libraries/Xmlrpcs.php
@@ -551,8 +551,8 @@ class CI_Xmlrpcs extends CI_Xmlrpc {
*/
public function multicall_error($err)
{
- $str = is_string($err) ? $this->xmlrpcstr["multicall_${err}"] : $err->faultString();
- $code = is_string($err) ? $this->xmlrpcerr["multicall_${err}"] : $err->faultCode();
+ $str = is_string($err) ? $this->xmlrpcstr["multicall_$err"] : $err->faultString();
+ $code = is_string($err) ? $this->xmlrpcerr["multicall_$err"] : $err->faultCode();
$struct['faultCode'] = new XML_RPC_Values($code, 'int');
$struct['faultString'] = new XML_RPC_Values($str, 'string');
diff --git a/system/libraries/Zip.php b/system/libraries/Zip.php
index 6b5081910..6b9b1816b 100644
--- a/system/libraries/Zip.php
+++ b/system/libraries/Zip.php
@@ -42,7 +42,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* Zip Compression Class
*
* This class is based on a library I found at Zend:
- * http://www.zend.com/codex.php?id=696&single=1
+ * https://www.zend.com/codex.php?id=696&single=1
*
* The original library is a little rough around the edges so I
* refactored it and added several additional methods -- Rick Ellis
@@ -367,7 +367,7 @@ class CI_Zip {
while (FALSE !== ($file = readdir($fp)))
{
- if ($file[0] === '.')
+ if ($file === '.' OR $file === '..')
{
continue;
}
@@ -521,9 +521,6 @@ class CI_Zip {
{
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');
}
diff --git a/system/libraries/index.html b/system/libraries/index.html
index b702fbc39..bcb7cae34 100644
--- a/system/libraries/index.html
+++ b/system/libraries/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
<title>403 Forbidden</title>
</head>