summaryrefslogtreecommitdiffstats
path: root/system
diff options
context:
space:
mode:
authorBrennan Thompson <brenjt@gmail.com>2014-02-14 20:03:57 +0100
committerBrennan Thompson <brenjt@gmail.com>2014-02-14 20:03:57 +0100
commit6949f95f6e21980f36095490bf38fc8a172dbc0f (patch)
treeb3141f390acd0051396cda6a3da51c1f98384cca /system
parent68a02a01a086bbb1b8128ea2744439de84873d11 (diff)
parent81f036753272391360ba5b64e6dd93c4101a8733 (diff)
Merge remote-tracking branch 'upstream/develop' into develop
Conflicts: system/helpers/form_helper.php
Diffstat (limited to 'system')
-rw-r--r--system/core/Benchmark.php2
-rw-r--r--system/core/CodeIgniter.php226
-rw-r--r--system/core/Common.php62
-rw-r--r--system/core/Config.php31
-rw-r--r--system/core/Controller.php2
-rw-r--r--system/core/Exceptions.php55
-rw-r--r--system/core/Hooks.php41
-rw-r--r--system/core/Input.php144
-rw-r--r--system/core/Lang.php4
-rw-r--r--system/core/Loader.php115
-rw-r--r--system/core/Log.php17
-rw-r--r--system/core/Model.php5
-rw-r--r--system/core/Output.php313
-rw-r--r--system/core/Router.php324
-rw-r--r--system/core/Security.php86
-rw-r--r--system/core/URI.php282
-rw-r--r--system/core/Utf8.php39
-rw-r--r--system/core/compat/index.html10
-rw-r--r--system/core/compat/mbstring.php141
-rw-r--r--system/core/compat/password.php216
-rw-r--r--system/database/DB.php7
-rw-r--r--system/database/DB_cache.php2
-rw-r--r--system/database/DB_driver.php21
-rw-r--r--system/database/DB_forge.php59
-rw-r--r--system/database/DB_query_builder.php46
-rw-r--r--system/database/DB_result.php2
-rw-r--r--system/database/DB_utility.php5
-rw-r--r--system/database/drivers/cubrid/cubrid_driver.php2
-rw-r--r--system/database/drivers/cubrid/cubrid_forge.php2
-rw-r--r--system/database/drivers/cubrid/cubrid_result.php2
-rw-r--r--system/database/drivers/cubrid/cubrid_utility.php2
-rw-r--r--system/database/drivers/ibase/ibase_driver.php2
-rw-r--r--system/database/drivers/ibase/ibase_forge.php2
-rw-r--r--system/database/drivers/ibase/ibase_result.php2
-rw-r--r--system/database/drivers/ibase/ibase_utility.php2
-rw-r--r--system/database/drivers/mssql/mssql_driver.php4
-rw-r--r--system/database/drivers/mssql/mssql_forge.php2
-rw-r--r--system/database/drivers/mssql/mssql_result.php2
-rw-r--r--system/database/drivers/mssql/mssql_utility.php2
-rw-r--r--system/database/drivers/mysql/mysql_driver.php16
-rw-r--r--system/database/drivers/mysql/mysql_forge.php32
-rw-r--r--system/database/drivers/mysql/mysql_result.php2
-rw-r--r--system/database/drivers/mysql/mysql_utility.php2
-rw-r--r--system/database/drivers/mysqli/mysqli_driver.php16
-rw-r--r--system/database/drivers/mysqli/mysqli_forge.php32
-rw-r--r--system/database/drivers/mysqli/mysqli_result.php2
-rw-r--r--system/database/drivers/mysqli/mysqli_utility.php2
-rw-r--r--system/database/drivers/oci8/oci8_driver.php4
-rw-r--r--system/database/drivers/oci8/oci8_forge.php2
-rw-r--r--system/database/drivers/oci8/oci8_result.php2
-rw-r--r--system/database/drivers/oci8/oci8_utility.php2
-rw-r--r--system/database/drivers/odbc/odbc_driver.php4
-rw-r--r--system/database/drivers/odbc/odbc_forge.php2
-rw-r--r--system/database/drivers/odbc/odbc_result.php2
-rw-r--r--system/database/drivers/odbc/odbc_utility.php2
-rw-r--r--system/database/drivers/pdo/pdo_driver.php5
-rw-r--r--system/database/drivers/pdo/pdo_forge.php2
-rw-r--r--system/database/drivers/pdo/pdo_result.php2
-rw-r--r--system/database/drivers/pdo/pdo_utility.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_4d_driver.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_4d_forge.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_informix_driver.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_informix_forge.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php23
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php32
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_oci_driver.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_oci_forge.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_odbc_forge.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php10
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php2
-rw-r--r--system/database/drivers/postgre/postgre_driver.php4
-rw-r--r--system/database/drivers/postgre/postgre_forge.php2
-rw-r--r--system/database/drivers/postgre/postgre_result.php2
-rw-r--r--system/database/drivers/postgre/postgre_utility.php2
-rw-r--r--system/database/drivers/sqlite/sqlite_driver.php2
-rw-r--r--system/database/drivers/sqlite/sqlite_forge.php2
-rw-r--r--system/database/drivers/sqlite/sqlite_result.php2
-rw-r--r--system/database/drivers/sqlite/sqlite_utility.php2
-rw-r--r--system/database/drivers/sqlite3/sqlite3_driver.php2
-rw-r--r--system/database/drivers/sqlite3/sqlite3_forge.php2
-rw-r--r--system/database/drivers/sqlite3/sqlite3_result.php2
-rw-r--r--system/database/drivers/sqlite3/sqlite3_utility.php2
-rw-r--r--system/database/drivers/sqlsrv/sqlsrv_driver.php39
-rw-r--r--system/database/drivers/sqlsrv/sqlsrv_forge.php2
-rw-r--r--system/database/drivers/sqlsrv/sqlsrv_result.php34
-rw-r--r--system/database/drivers/sqlsrv/sqlsrv_utility.php2
-rw-r--r--system/helpers/array_helper.php2
-rw-r--r--system/helpers/captcha_helper.php26
-rw-r--r--system/helpers/cookie_helper.php15
-rw-r--r--system/helpers/date_helper.php2
-rw-r--r--system/helpers/directory_helper.php4
-rw-r--r--system/helpers/download_helper.php4
-rw-r--r--system/helpers/email_helper.php2
-rw-r--r--system/helpers/file_helper.php17
-rw-r--r--system/helpers/form_helper.php42
-rw-r--r--system/helpers/html_helper.php8
-rw-r--r--system/helpers/inflector_helper.php19
-rw-r--r--system/helpers/language_helper.php5
-rw-r--r--system/helpers/number_helper.php2
-rw-r--r--system/helpers/path_helper.php2
-rw-r--r--system/helpers/security_helper.php11
-rw-r--r--system/helpers/smiley_helper.php2
-rw-r--r--system/helpers/string_helper.php4
-rw-r--r--system/helpers/text_helper.php57
-rw-r--r--system/helpers/typography_helper.php2
-rw-r--r--system/helpers/url_helper.php41
-rw-r--r--system/helpers/xml_helper.php2
-rw-r--r--system/language/english/calendar_lang.php2
-rw-r--r--system/language/english/date_lang.php2
-rw-r--r--system/language/english/db_lang.php2
-rw-r--r--system/language/english/email_lang.php2
-rw-r--r--system/language/english/form_validation_lang.php2
-rw-r--r--system/language/english/ftp_lang.php12
-rw-r--r--system/language/english/imglib_lang.php2
-rw-r--r--system/language/english/migration_lang.php2
-rw-r--r--system/language/english/number_lang.php2
-rw-r--r--system/language/english/pagination_lang.php35
-rw-r--r--system/language/english/profiler_lang.php2
-rw-r--r--system/language/english/unit_test_lang.php2
-rw-r--r--system/language/english/upload_lang.php2
-rw-r--r--system/libraries/Cache/Cache.php41
-rw-r--r--system/libraries/Cache/drivers/Cache_apc.php59
-rw-r--r--system/libraries/Cache/drivers/Cache_dummy.php33
-rw-r--r--system/libraries/Cache/drivers/Cache_file.php110
-rw-r--r--system/libraries/Cache/drivers/Cache_memcached.php56
-rw-r--r--system/libraries/Cache/drivers/Cache_redis.php75
-rw-r--r--system/libraries/Cache/drivers/Cache_wincache.php49
-rw-r--r--system/libraries/Calendar.php60
-rw-r--r--system/libraries/Cart.php22
-rw-r--r--system/libraries/Driver.php2
-rw-r--r--system/libraries/Email.php117
-rw-r--r--system/libraries/Encrypt.php2
-rw-r--r--system/libraries/Encryption.php887
-rw-r--r--system/libraries/Form_validation.php84
-rw-r--r--system/libraries/Ftp.php16
-rw-r--r--system/libraries/Image_lib.php73
-rw-r--r--system/libraries/Javascript.php3
-rw-r--r--system/libraries/Javascript/Jquery.php2
-rw-r--r--system/libraries/Migration.php2
-rw-r--r--system/libraries/Pagination.php70
-rw-r--r--system/libraries/Parser.php32
-rw-r--r--system/libraries/Profiler.php32
-rw-r--r--system/libraries/Session/Session.php109
-rw-r--r--system/libraries/Session/drivers/Session_cookie.php185
-rw-r--r--system/libraries/Session/drivers/Session_native.php2
-rw-r--r--system/libraries/Table.php180
-rw-r--r--system/libraries/Trackback.php11
-rw-r--r--system/libraries/Typography.php2
-rw-r--r--system/libraries/Unit_test.php32
-rw-r--r--system/libraries/Upload.php36
-rw-r--r--system/libraries/User_agent.php55
-rw-r--r--system/libraries/Xmlrpc.php117
-rw-r--r--system/libraries/Xmlrpcs.php16
-rw-r--r--system/libraries/Zip.php78
167 files changed, 3881 insertions, 1735 deletions
diff --git a/system/core/Benchmark.php b/system/core/Benchmark.php
index f9be18a42..36326f521 100644
--- a/system/core/Benchmark.php
+++ b/system/core/Benchmark.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php
index c12116236..1f10c452d 100644
--- a/system/core/CodeIgniter.php
+++ b/system/core/CodeIgniter.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -48,24 +48,22 @@ defined('BASEPATH') OR exit('No direct script access allowed');
/*
* ------------------------------------------------------
- * Load the global functions
+ * Load the framework constants
* ------------------------------------------------------
*/
- require_once(BASEPATH.'core/Common.php');
+ if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/constants.php'))
+ {
+ require_once(APPPATH.'config/'.ENVIRONMENT.'/constants.php');
+ }
+
+ require_once(APPPATH.'config/constants.php');
/*
* ------------------------------------------------------
- * Load the framework constants
+ * Load the global functions
* ------------------------------------------------------
*/
- if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/constants.php'))
- {
- require(APPPATH.'config/'.ENVIRONMENT.'/constants.php');
- }
- else
- {
- require(APPPATH.'config/constants.php');
- }
+ require_once(BASEPATH.'core/Common.php');
/*
* ------------------------------------------------------
@@ -126,6 +124,11 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* ------------------------------------------------------
* Instantiate the config class
* ------------------------------------------------------
+ *
+ * Note: It is important that Config is loaded first as
+ * most other classes depend on it either directly or by
+ * depending on another class that uses it.
+ *
*/
$CFG =& load_class('Config', 'core');
@@ -140,14 +143,58 @@ defined('BASEPATH') OR exit('No direct script access allowed');
/*
* ------------------------------------------------------
- * Instantiate the UTF-8 class
+ * Important charset-related stuff
* ------------------------------------------------------
*
- * Note: Order here is rather important as the UTF-8
- * class needs to be used very early on, but it cannot
- * properly determine if UTF-8 can be supported until
- * after the Config class is instantiated.
+ * Configure mbstring and/or iconv if they are enabled
+ * and set MB_ENABLED and ICONV_ENABLED constants, so
+ * that we don't repeatedly do extension_loaded() or
+ * function_exists() calls.
*
+ * Note: UTF-8 class depends on this. It used to be done
+ * in it's constructor, but it's _not_ class-specific.
+ *
+ */
+ $charset = strtoupper(config_item('charset'));
+
+ if (extension_loaded('mbstring'))
+ {
+ define('MB_ENABLED', TRUE);
+ mb_internal_encoding($charset);
+ // This is required for mb_convert_encoding() to strip invalid characters.
+ // That's utilized by CI_Utf8, but it's also done for consistency with iconv.
+ mb_substitute_character('none');
+ }
+ else
+ {
+ define('MB_ENABLED', FALSE);
+ }
+
+ // There's an ICONV_IMPL constant, but the PHP manual says that using
+ // iconv's predefined constants is "strongly discouraged".
+ if (extension_loaded('iconv'))
+ {
+ define('ICONV_ENABLED', TRUE);
+ iconv_set_encoding('internal_encoding', $charset);
+ }
+ else
+ {
+ define('ICONV_ENABLED', FALSE);
+ }
+
+/*
+ * ------------------------------------------------------
+ * Load compatibility features
+ * ------------------------------------------------------
+ */
+
+ require_once(BASEPATH.'core/compat/mbstring.php');
+ require_once(BASEPATH.'core/compat/password.php');
+
+/*
+ * ------------------------------------------------------
+ * Instantiate the UTF-8 class
+ * ------------------------------------------------------
*/
$UNI =& load_class('Utf8', 'core');
@@ -165,12 +212,6 @@ defined('BASEPATH') OR exit('No direct script access allowed');
*/
$RTR =& load_class('Router', 'core');
- // Set any routing overrides that may exist in the main index file
- if (isset($routing))
- {
- $RTR->_set_overrides($routing);
- }
-
/*
* ------------------------------------------------------
* Instantiate the output class
@@ -217,7 +258,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
*
*/
// Load the base controller class
- require BASEPATH.'core/Controller.php';
+ require_once BASEPATH.'core/Controller.php';
/**
* Reference to the CI_Controller method.
@@ -233,96 +274,117 @@ defined('BASEPATH') OR exit('No direct script access allowed');
if (file_exists(APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php'))
{
- require APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php';
- }
-
- // Load the local application controller
- // Note: The Router class automatically validates the controller path using the router->_validate_request().
- // If this include fails it means that the default controller in the Routes.php file is not resolving to something valid.
- $class = ucfirst($RTR->class);
- if ( ! file_exists(APPPATH.'controllers/'.$RTR->directory.$class.'.php'))
- {
- show_error('Unable to load your default controller. Please make sure the controller specified in your Routes.php file is valid.');
+ require_once APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php';
}
- include(APPPATH.'controllers/'.$RTR->directory.$class.'.php');
-
// Set a mark point for benchmarking
$BM->mark('loading_time:_base_classes_end');
/*
* ------------------------------------------------------
- * Security check
+ * Sanity checks
* ------------------------------------------------------
*
- * None of the methods in the app controller or the
- * loader class can be called via the URI, nor can
+ * The Router class has already validated the request,
+ * leaving us with 3 options here:
+ *
+ * 1) an empty class name, if we reached the default
+ * controller, but it didn't exist;
+ * 2) a query string which doesn't go through a
+ * file_exists() check
+ * 3) a regular request for a non-existing page
+ *
+ * We handle all of these as a 404 error.
+ *
+ * Furthermore, none of the methods in the app controller
+ * or the loader class can be called via the URI, nor can
* controller methods that begin with an underscore.
*/
- $method = $RTR->method;
- if ( ! class_exists($class, FALSE) OR $method[0] === '_' OR method_exists('CI_Controller', $method))
- {
- if ( ! empty($RTR->routes['404_override']))
- {
- if (sscanf($RTR->routes['404_override'], '%[^/]/%s', $class, $method) !== 2)
- {
- $method = 'index';
- }
-
- $class = ucfirst($class);
-
- if ( ! class_exists($class, FALSE))
- {
- if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
- {
- show_404($class.'/'.$method);
- }
-
- include_once(APPPATH.'controllers/'.$class.'.php');
- }
- }
- else
- {
- show_404($class.'/'.$method);
- }
- }
+ $e404 = FALSE;
+ $class = ucfirst($RTR->class);
+ $method = $RTR->method;
- if (method_exists($class, '_remap'))
+ if (empty($class) OR ! file_exists(APPPATH.'controllers/'.$RTR->directory.$class.'.php'))
{
- $params = array($method, array_slice($URI->rsegments, 2));
- $method = '_remap';
+ $e404 = TRUE;
}
else
{
+ require_once(APPPATH.'controllers/'.$RTR->directory.$class.'.php');
+
+ if ( ! class_exists($class, FALSE) OR $method[0] === '_' OR method_exists('CI_Controller', $method))
+ {
+ $e404 = TRUE;
+ }
+ elseif (method_exists($class, '_remap'))
+ {
+ $params = array($method, array_slice($URI->rsegments, 2));
+ $method = '_remap';
+ }
// WARNING: It appears that there are issues with is_callable() even in PHP 5.2!
// Furthermore, there are bug reports and feature/change requests related to it
// that make it unreliable to use in this context. Please, DO NOT change this
// work-around until a better alternative is available.
- if ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($class)), TRUE))
+ elseif ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($class)), TRUE))
{
- if (empty($RTR->routes['404_override']))
- {
- show_404($class.'/'.$method);
- }
- elseif (sscanf($RTR->routes['404_override'], '%[^/]/%s', $class, $method) !== 2)
+ $e404 = TRUE;
+ }
+ }
+
+ if ($e404)
+ {
+ if ( ! empty($RTR->routes['404_override']))
+ {
+ if (sscanf($RTR->routes['404_override'], '%[^/]/%s', $error_class, $error_method) !== 2)
{
- $method = 'index';
+ $error_method = 'index';
}
- $class = ucfirst($class);
+ $error_class = ucfirst($error_class);
- if ( ! class_exists($class, FALSE))
+ if ( ! class_exists($error_class, FALSE))
{
- if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
+ if (file_exists(APPPATH.'controllers/'.$RTR->directory.$error_class.'.php'))
{
- show_404($class.'/'.$method);
+ require_once(APPPATH.'controllers/'.$RTR->directory.$error_class.'.php');
+ $e404 = ! class_exists($error_class, FALSE);
}
-
- include_once(APPPATH.'controllers/'.$class.'.php');
+ // Were we in a directory? If so, check for a global override
+ elseif ( ! empty($RTR->directory) && file_exists(APPPATH.'controllers/'.$error_class.'.php'))
+ {
+ require_once(APPPATH.'controllers/'.$error_class.'.php');
+ if (($e404 = ! class_exists($error_class, FALSE)) === FALSE)
+ {
+ $RTR->directory = '';
+ }
+ }
+ }
+ else
+ {
+ $e404 = FALSE;
}
}
+ // Did we reset the $e404 flag? If so, set the rsegments, starting from index 1
+ if ( ! $e404)
+ {
+ $class = $error_class;
+ $method = $error_method;
+
+ $URI->rsegments = array(
+ 1 => $class,
+ 2 => $method
+ );
+ }
+ else
+ {
+ show_404($RTR->directory.$class.'/'.$method);
+ }
+ }
+
+ if ($method !== '_remap')
+ {
$params = array_slice($URI->rsegments, 2);
}
diff --git a/system/core/Common.php b/system/core/Common.php
index 286deccda..16a916a01 100644
--- a/system/core/Common.php
+++ b/system/core/Common.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -76,6 +76,7 @@ if ( ! function_exists('is_really_writable'))
* the file, based on the read-only attribute. is_writable() is also unreliable
* on Unix servers if safe_mode is on.
*
+ * @link https://bugs.php.net/bug.php?id=54709
* @param string
* @return void
*/
@@ -355,6 +356,24 @@ if ( ! function_exists('is_https'))
// ------------------------------------------------------------------------
+if ( ! function_exists('is_cli'))
+{
+
+ /**
+ * Is CLI?
+ *
+ * Test to see if a request was made from the command line.
+ *
+ * @return bool
+ */
+ function is_cli()
+ {
+ return (PHP_SAPI === 'cli' OR defined('STDIN'));
+ }
+}
+
+// ------------------------------------------------------------------------
+
if ( ! function_exists('show_error'))
{
/**
@@ -429,7 +448,6 @@ if ( ! function_exists('log_message'))
*
* @param string the error level: 'error', 'debug' or 'info'
* @param string the error message
- * @param bool whether the error is a native PHP error
* @return void
*/
function log_message($level, $message)
@@ -550,14 +568,27 @@ if ( ! function_exists('_exception_handler'))
* to display errors based on the current error_reporting level.
* We do that with the use of a PHP error template.
*
- * @param int
- * @param string
- * @param string
- * @param int
+ * @param int $severity
+ * @param string $message
+ * @param string $filepath
+ * @param int $line
* @return void
*/
function _exception_handler($severity, $message, $filepath, $line)
{
+ $is_error = (((E_ERROR | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity);
+
+ // When an error occurred, set the status header to '500 Internal Server Error'
+ // to indicate to the client something went wrong.
+ // This can't be done within the $_error->show_php_error method because
+ // it is only called when the display_errors flag is set (which isn't usually
+ // the case in a production environment) or when errors are ignored because
+ // they are above the error_reporting threshold.
+ if ($is_error)
+ {
+ set_status_header(500);
+ }
+
$_error =& load_class('Exceptions', 'core');
// Should we ignore the error? We'll get the current error_reporting
@@ -567,13 +598,21 @@ if ( ! function_exists('_exception_handler'))
return;
}
+ $_error->log_exception($severity, $message, $filepath, $line);
+
// Should we display the error?
if ((bool) ini_get('display_errors') === TRUE)
{
$_error->show_php_error($severity, $message, $filepath, $line);
}
- $_error->log_exception($severity, $message, $filepath, $line);
+ // If the error is fatal, the execution of the script should be stopped because
+ // errors can't be recovered from. Halting the script conforms with PHP's
+ // default error handling. See http://www.php.net/manual/en/errorfunc.constants.php
+ if ($is_error)
+ {
+ exit(EXIT_ERROR);
+ }
}
}
@@ -588,7 +627,7 @@ if ( ! function_exists('_shutdown_handler'))
* of CodeIgniter.php. The main reason we use this is to simulate
* a complete custom exception handler.
*
- * E_STRICT is purposivly neglected because such events may have
+ * E_STRICT is purposivly neglected because such events may have
* been caught. Duplication or none? None is preferred for now.
*
* @link http://insomanic.me.uk/post/229851073/php-trick-catching-fatal-errors-e-error-with-a
@@ -596,7 +635,7 @@ if ( ! function_exists('_shutdown_handler'))
*/
function _shutdown_handler()
{
- $last_error = function_exists('error_get_last') ? error_get_last() : NULL;
+ $last_error = error_get_last();
if (isset($last_error) &&
($last_error['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING)))
{
@@ -717,6 +756,11 @@ if ( ! function_exists('function_usable'))
* *suhosin.executor.disable_eval*. These settings will just
* terminate script execution if a disabled function is executed.
*
+ * The above described behavior turned out to be a bug in Suhosin,
+ * but even though a fix was commited for 0.9.34 on 2012-02-12,
+ * that version is yet to be released. This function will therefore
+ * be just temporary, but would probably be kept for a few years.
+ *
* @link http://www.hardened-php.net/suhosin/
* @param string $function_name Function to check for
* @return bool TRUE if the function exists and is safe to call,
diff --git a/system/core/Config.php b/system/core/Config.php
index 109ee6424..f630d1709 100644
--- a/system/core/Config.php
+++ b/system/core/Config.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -228,13 +228,21 @@ class CI_Config {
* @uses CI_Config::_uri_string()
*
* @param string|string[] $uri URI string or an array of segments
+ * @param string $protocol
* @return string
*/
- public function site_url($uri = '')
+ public function site_url($uri = '', $protocol = NULL)
{
+ $base_url = $this->slash_item('base_url');
+
+ if (isset($protocol))
+ {
+ $base_url = $protocol.substr($base_url, strpos($base_url, '://'));
+ }
+
if (empty($uri))
{
- return $this->slash_item('base_url').$this->item('index_page');
+ return $base_url.$this->item('index_page');
}
$uri = $this->_uri_string($uri);
@@ -255,14 +263,14 @@ class CI_Config {
}
}
- return $this->slash_item('base_url').$this->slash_item('index_page').$uri;
+ return $base_url.$this->slash_item('index_page').$uri;
}
elseif (strpos($uri, '?') === FALSE)
{
$uri = '?'.$uri;
}
- return $this->slash_item('base_url').$this->item('index_page').$uri;
+ return $base_url.$this->item('index_page').$uri;
}
// -------------------------------------------------------------
@@ -275,11 +283,19 @@ class CI_Config {
* @uses CI_Config::_uri_string()
*
* @param string|string[] $uri URI string or an array of segments
+ * @param string $protocol
* @return string
*/
- public function base_url($uri = '')
+ public function base_url($uri = '', $protocol = NULL)
{
- return $this->slash_item('base_url').ltrim($this->_uri_string($uri), '/');
+ $base_url = $this->slash_item('base_url');
+
+ if (isset($protocol))
+ {
+ $base_url = $protocol.substr($base_url, strpos($base_url, '://'));
+ }
+
+ return $base_url.ltrim($this->_uri_string($uri), '/');
}
// -------------------------------------------------------------
@@ -316,6 +332,7 @@ class CI_Config {
/**
* System URL
*
+ * @deprecated 3.0.0 Encourages insecure practices
* @return string
*/
public function system_url()
diff --git a/system/core/Controller.php b/system/core/Controller.php
index 3fcadcadf..8db222a98 100644
--- a/system/core/Controller.php
+++ b/system/core/Controller.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php
index d7e5ed4d9..54a5bc48b 100644
--- a/system/core/Exceptions.php
+++ b/system/core/Exceptions.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -91,7 +91,7 @@ class CI_Exceptions {
public function log_exception($severity, $message, $filepath, $line)
{
$severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity;
- log_message('error', 'Severity: '.$severity.' --> '.$message. ' '.$filepath.' '.$line);
+ log_message('error', 'Severity: '.$severity.' --> '.$message.' '.$filepath.' '.$line);
}
// --------------------------------------------------------------------
@@ -107,13 +107,21 @@ class CI_Exceptions {
*/
public function show_404($page = '', $log_error = TRUE)
{
- $heading = '404 Page Not Found';
- $message = 'The page you requested was not found.';
+ if (is_cli())
+ {
+ $heading = 'Not Found';
+ $message = 'The controller/method pair you requested was not found.';
+ }
+ else
+ {
+ $heading = '404 Page Not Found';
+ $message = 'The page you requested was not found.';
+ }
// By default we log this, but allow a dev to skip it
if ($log_error)
{
- log_message('error', '404 Page Not Found --> '.$page);
+ log_message('error', $heading.': '.$page);
}
echo $this->show_error($heading, $message, 'error_404', 404);
@@ -137,16 +145,24 @@ class CI_Exceptions {
*/
public function show_error($heading, $message, $template = 'error_general', $status_code = 500)
{
- set_status_header($status_code);
-
- $message = '<p>'.implode('</p><p>', is_array($message) ? $message : array($message)).'</p>';
+ if (is_cli())
+ {
+ $message = "\t".(is_array($message) ? implode("\n\t", $message) : $message);
+ $template = 'cli'.DIRECTORY_SEPARATOR.$template;
+ }
+ else
+ {
+ set_status_header($status_code);
+ $message = '<p>'.(is_array($message) ? implode('</p><p>', $message) : $message).'</p>';
+ $template = 'html'.DIRECTORY_SEPARATOR.$template;
+ }
if (ob_get_level() > $this->ob_level + 1)
{
ob_end_flush();
}
ob_start();
- include(VIEWPATH.'errors/'.$template.'.php');
+ include(VIEWPATH.'errors'.DIRECTORY_SEPARATOR.$template.'.php');
$buffer = ob_get_contents();
ob_end_clean();
return $buffer;
@@ -166,13 +182,22 @@ class CI_Exceptions {
public function show_php_error($severity, $message, $filepath, $line)
{
$severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity;
- $filepath = str_replace('\\', '/', $filepath);
- // For safety reasons we do not show the full file path
- if (FALSE !== strpos($filepath, '/'))
+ // For safety reasons we don't show the full file path in non-CLI requests
+ if ( ! is_cli())
+ {
+ $filepath = str_replace('\\', '/', $filepath);
+ if (FALSE !== strpos($filepath, '/'))
+ {
+ $x = explode('/', $filepath);
+ $filepath = $x[count($x)-2].'/'.end($x);
+ }
+
+ $template = 'html'.DIRECTORY_SEPARATOR.'error_php';
+ }
+ else
{
- $x = explode('/', $filepath);
- $filepath = $x[count($x)-2].'/'.end($x);
+ $template = 'cli'.DIRECTORY_SEPARATOR.'error_php';
}
if (ob_get_level() > $this->ob_level + 1)
@@ -180,7 +205,7 @@ class CI_Exceptions {
ob_end_flush();
}
ob_start();
- include(VIEWPATH.'errors/error_php.php');
+ include(VIEWPATH.'errors'.DIRECTORY_SEPARATOR.$template.'.php');
$buffer = ob_get_contents();
ob_end_clean();
echo $buffer;
diff --git a/system/core/Hooks.php b/system/core/Hooks.php
index b3b111991..f6eff4b3f 100644
--- a/system/core/Hooks.php
+++ b/system/core/Hooks.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -54,6 +54,13 @@ class CI_Hooks {
public $hooks = array();
/**
+ * Array with class objects to use hooks methods
+ *
+ * @var array
+ */
+ protected $_objects = array();
+
+ /**
* In progress flag
*
* Determines whether hook is in progress, used to prevent infinte loops
@@ -184,7 +191,7 @@ class CI_Hooks {
$function = empty($data['function']) ? FALSE : $data['function'];
$params = isset($data['params']) ? $data['params'] : '';
- if ($class === FALSE && $function === FALSE)
+ if (empty($function))
{
return FALSE;
}
@@ -195,19 +202,39 @@ class CI_Hooks {
// Call the requested class and/or function
if ($class !== FALSE)
{
- if ( ! class_exists($class, FALSE))
+ // The object is stored?
+ if (isset($this->_objects[$class]))
{
- require($filepath);
+ if (method_exists($this->_objects[$class], $function))
+ {
+ $this->_objects[$class]->$function($params);
+ }
+ else
+ {
+ return $this->_in_progress = FALSE;
+ }
}
+ else
+ {
+ class_exists($class, FALSE) OR require_once($filepath);
+
+ if ( ! class_exists($class, FALSE) OR ! method_exists($class, $function))
+ {
+ return $this->_in_progress = FALSE;
+ }
- $HOOK = new $class();
- $HOOK->$function($params);
+ // Store the object and execute the method
+ $this->_objects[$class] = new $class();
+ $this->_objects[$class]->$function($params);
+ }
}
else
{
+ function_exists($function) OR require_once($filepath);
+
if ( ! function_exists($function))
{
- require($filepath);
+ return $this->_in_progress = FALSE;
}
$function($params);
diff --git a/system/core/Input.php b/system/core/Input.php
index 24e21ea08..fdb308b5a 100644
--- a/system/core/Input.php
+++ b/system/core/Input.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -63,7 +63,7 @@ class CI_Input {
protected $_allow_get_array = TRUE;
/**
- * Standartize new lines flag
+ * Standardize new lines flag
*
* If set to TRUE, then newlines are standardized.
*
@@ -121,9 +121,10 @@ class CI_Input {
{
log_message('debug', 'Input Class Initialized');
- $this->_allow_get_array = (config_item('allow_get_array') === TRUE);
- $this->_enable_xss = (config_item('global_xss_filtering') === TRUE);
- $this->_enable_csrf = (config_item('csrf_protection') === TRUE);
+ $this->_allow_get_array = (config_item('allow_get_array') === TRUE);
+ $this->_enable_xss = (config_item('global_xss_filtering') === TRUE);
+ $this->_enable_csrf = (config_item('csrf_protection') === TRUE);
+ $this->_sandardize_newlines = (bool) config_item('standardize_newlines');
global $SEC;
$this->security =& $SEC;
@@ -151,8 +152,22 @@ class CI_Input {
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
- protected function _fetch_from_array(&$array, $index = '', $xss_clean = FALSE)
+ protected function _fetch_from_array(&$array, $index = NULL, $xss_clean = NULL)
{
+ // If $index is NULL, it means that the whole $array is requested
+ if ($index === NULL)
+ {
+ $output = array();
+ foreach (array_keys($array) as $key)
+ {
+ $output[$key] = $this->_fetch_from_array($array, $key, $xss_clean);
+ }
+
+ return $output;
+ }
+
+ is_bool($xss_clean) OR $xss_clean = $this->_enable_xss;
+
if (isset($array[$index]))
{
$value = $array[$index];
@@ -197,26 +212,8 @@ class CI_Input {
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
- public function get($index = NULL, $xss_clean = FALSE)
+ public function get($index = NULL, $xss_clean = NULL)
{
- // Check if a field has been provided
- if ($index === NULL)
- {
- if (empty($_GET))
- {
- return array();
- }
-
- $get = array();
-
- // loop through the full _GET array
- foreach (array_keys($_GET) as $key)
- {
- $get[$key] = $this->_fetch_from_array($_GET, $key, $xss_clean);
- }
- return $get;
- }
-
return $this->_fetch_from_array($_GET, $index, $xss_clean);
}
@@ -229,26 +226,8 @@ class CI_Input {
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
- public function post($index = NULL, $xss_clean = FALSE)
+ public function post($index = NULL, $xss_clean = NULL)
{
- // Check if a field has been provided
- if ($index === NULL)
- {
- if (empty($_POST))
- {
- return array();
- }
-
- $post = array();
-
- // Loop through the full _POST array and return it
- foreach (array_keys($_POST) as $key)
- {
- $post[$key] = $this->_fetch_from_array($_POST, $key, $xss_clean);
- }
- return $post;
- }
-
return $this->_fetch_from_array($_POST, $index, $xss_clean);
}
@@ -261,7 +240,7 @@ class CI_Input {
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
- public function post_get($index = '', $xss_clean = FALSE)
+ public function post_get($index, $xss_clean = NULL)
{
return isset($_POST[$index])
? $this->post($index, $xss_clean)
@@ -277,7 +256,7 @@ class CI_Input {
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
- public function get_post($index = '', $xss_clean = FALSE)
+ public function get_post($index, $xss_clean = NULL)
{
return isset($_GET[$index])
? $this->get($index, $xss_clean)
@@ -293,7 +272,7 @@ class CI_Input {
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
- public function cookie($index = '', $xss_clean = FALSE)
+ public function cookie($index = NULL, $xss_clean = NULL)
{
return $this->_fetch_from_array($_COOKIE, $index, $xss_clean);
}
@@ -307,7 +286,7 @@ class CI_Input {
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
- public function server($index = '', $xss_clean = FALSE)
+ public function server($index, $xss_clean = NULL)
{
return $this->_fetch_from_array($_SERVER, $index, $xss_clean);
}
@@ -323,21 +302,14 @@ class CI_Input {
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
- public function input_stream($index = '', $xss_clean = FALSE)
+ public function input_stream($index = NULL, $xss_clean = NULL)
{
// The input stream can only be read once, so we'll need to check
// if we have already done that first.
- if (is_array($this->_input_stream))
- {
- return $this->_fetch_from_array($this->_input_stream, $index, $xss_clean);
- }
-
- // Parse the input stream in our cache var
- parse_str(file_get_contents('php://input'), $this->_input_stream);
if ( ! is_array($this->_input_stream))
{
- $this->_input_stream = array();
- return NULL;
+ parse_str(file_get_contents('php://input'), $this->_input_stream);
+ is_array($this->_input_stream) OR $this->_input_stream = array();
}
return $this->_fetch_from_array($this->_input_stream, $index, $xss_clean);
@@ -361,7 +333,7 @@ class CI_Input {
* @param bool $httponly Whether to only makes the cookie accessible via HTTP (no javascript)
* @return void
*/
- public function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE)
+ public function set_cookie($name, $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE)
{
if (is_array($name))
{
@@ -687,13 +659,22 @@ class CI_Input {
// but that when present will trip our 'Disallowed Key Characters' alarm
// http://www.ietf.org/rfc/rfc2109.txt
// note that the key names below are single quoted strings, and are not PHP variables
- unset($_COOKIE['$Version']);
- unset($_COOKIE['$Path']);
- unset($_COOKIE['$Domain']);
+ unset(
+ $_COOKIE['$Version'],
+ $_COOKIE['$Path'],
+ $_COOKIE['$Domain']
+ );
foreach ($_COOKIE as $key => $val)
{
- $_COOKIE[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
+ if (($cookie_key = $this->_clean_input_keys($key)) !== FALSE)
+ {
+ $_COOKIE[$cookie_key] = $this->_clean_input_data($val);
+ }
+ else
+ {
+ unset($_COOKIE[$key]);
+ }
}
}
@@ -701,12 +682,12 @@ class CI_Input {
$_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']);
// CSRF Protection check
- if ($this->_enable_csrf === TRUE && ! $this->is_cli_request())
+ if ($this->_enable_csrf === TRUE && ! is_cli())
{
$this->security->csrf_verify();
}
- log_message('debug', 'Global POST and COOKIE data sanitized');
+ log_message('debug', 'Global POST, GET and COOKIE data sanitized');
}
// --------------------------------------------------------------------
@@ -749,13 +730,7 @@ class CI_Input {
}
// Remove control characters
- $str = remove_invisible_characters($str);
-
- // Should we filter the input data?
- if ($this->_enable_xss === TRUE)
- {
- $str = $this->security->xss_clean($str);
- }
+ $str = remove_invisible_characters($str, FALSE);
// Standardize newlines if needed
if ($this->_standardize_newlines === TRUE)
@@ -776,15 +751,25 @@ class CI_Input {
* only named with alpha-numeric text and a few other items.
*
* @param string $str Input string
- * @return string
+ * @param string $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)
+ protected function _clean_input_keys($str, $fatal = TRUE)
{
if ( ! preg_match('/^[a-z0-9:_\/|-]+$/i', $str))
{
- set_status_header(503);
- echo 'Disallowed Key Characters.';
- exit(EXIT_USER_INPUT);
+ if ($fatal === TRUE)
+ {
+ return FALSE;
+ }
+ else
+ {
+ set_status_header(503);
+ echo 'Disallowed Key Characters.';
+ exit(EXIT_USER_INPUT);
+ }
}
// Clean UTF-8 if supported
@@ -884,11 +869,12 @@ class CI_Input {
*
* Test to see if a request was made from the command line.
*
- * @return bool
+ * @deprecated 3.0.0 Use is_cli() instead
+ * @return bool
*/
public function is_cli_request()
{
- return (PHP_SAPI === 'cli' OR defined('STDIN'));
+ return is_cli();
}
// --------------------------------------------------------------------
diff --git a/system/core/Lang.php b/system/core/Lang.php
index 3236709f2..94342133a 100644
--- a/system/core/Lang.php
+++ b/system/core/Lang.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -166,7 +166,7 @@ class CI_Lang {
* @param bool $log_errors Whether to log an error message if the line is not found
* @return string Translation
*/
- public function line($line = '', $log_errors = TRUE)
+ public function line($line, $log_errors = TRUE)
{
$value = ($line === '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line];
diff --git a/system/core/Loader.php b/system/core/Loader.php
index 2eef9979c..2d40ab5b8 100644
--- a/system/core/Loader.php
+++ b/system/core/Loader.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -174,22 +174,29 @@ class CI_Loader {
* @param string $library Library name
* @param array $params Optional parameters to pass to the library class constructor
* @param string $object_name An optional object name to assign to
- * @return void
+ * @return object
*/
- public function library($library = '', $params = NULL, $object_name = NULL)
+ public function library($library, $params = NULL, $object_name = NULL)
{
if (empty($library))
{
- return;
+ return $this;
}
elseif (is_array($library))
{
- foreach ($library as $class)
+ foreach ($library as $key => $value)
{
- $this->library($class, $params);
+ if (is_int($key))
+ {
+ $this->library($value, $params);
+ }
+ else
+ {
+ $this->library($key, $params, $value);
+ }
}
- return;
+ return $this;
}
if ($params !== NULL && ! is_array($params))
@@ -198,6 +205,7 @@ class CI_Loader {
}
$this->_ci_load_class($library, $params, $object_name);
+ return $this;
}
// --------------------------------------------------------------------
@@ -210,13 +218,13 @@ class CI_Loader {
* @param string $model Model name
* @param string $name An optional object name to assign to
* @param bool $db_conn An optional database connection configuration to initialize
- * @return void
+ * @return object
*/
public function model($model, $name = '', $db_conn = FALSE)
{
if (empty($model))
{
- return;
+ return $this;
}
elseif (is_array($model))
{
@@ -224,7 +232,8 @@ class CI_Loader {
{
is_int($key) ? $this->model($value, '', $db_conn) : $this->model($key, $value, $db_conn);
}
- return;
+
+ return $this;
}
$path = '';
@@ -246,7 +255,7 @@ class CI_Loader {
if (in_array($name, $this->_ci_models, TRUE))
{
- return;
+ return $this;
}
$CI =& get_instance();
@@ -283,7 +292,7 @@ class CI_Loader {
$CI->$name = new $model();
$this->_ci_models[] = $name;
- return;
+ return $this;
}
// couldn't find the model
@@ -300,8 +309,8 @@ class CI_Loader {
* @param bool $query_builder Whether to enable Query Builder
* (overrides the configuration setting)
*
- * @return void|object|bool Database object if $return is set to TRUE,
- * FALSE on failure, void in any other case
+ * @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)
{
@@ -327,6 +336,7 @@ class CI_Loader {
// Load the DB class
$CI->db =& DB($params, $query_builder);
+ return $this;
}
// --------------------------------------------------------------------
@@ -335,8 +345,8 @@ class CI_Loader {
* Load the Database Utilities Class
*
* @param object $db Database object
- * @param bool $return Whether to return the DB Forge class object or not
- * @return void|object
+ * @param bool $return Whether to return the DB Utilities class object or not
+ * @return object
*/
public function dbutil($db = NULL, $return = FALSE)
{
@@ -358,6 +368,7 @@ class CI_Loader {
}
$CI->dbutil = new $class($db);
+ return $this;
}
// --------------------------------------------------------------------
@@ -367,7 +378,7 @@ class CI_Loader {
*
* @param object $db Database object
* @param bool $return Whether to return the DB Forge class object or not
- * @return void|object
+ * @return object
*/
public function dbforge($db = NULL, $return = FALSE)
{
@@ -401,6 +412,7 @@ class CI_Loader {
}
$CI->dbforge = new $class($db);
+ return $this;
}
// --------------------------------------------------------------------
@@ -415,7 +427,7 @@ class CI_Loader {
* to be extracted for use in the view
* @param bool $return Whether to return the view output
* or leave it to the Output class
- * @return void
+ * @return object|string
*/
public function view($view, $vars = array(), $return = FALSE)
{
@@ -429,7 +441,7 @@ class CI_Loader {
*
* @param string $path File path
* @param bool $return Whether to return the file output
- * @return void|string
+ * @return object|string
*/
public function file($path, $return = FALSE)
{
@@ -448,9 +460,9 @@ class CI_Loader {
* An associative array or object containing values
* to be set, or a value's name if string
* @param string $val Value to set, only used if $vars is a string
- * @return void
+ * @return object
*/
- public function vars($vars = array(), $val = '')
+ public function vars($vars, $val = '')
{
if (is_string($vars))
{
@@ -466,6 +478,23 @@ class CI_Loader {
$this->_ci_cached_vars[$key] = $val;
}
}
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Clear Cached Variables
+ *
+ * Clears the cached variables.
+ *
+ * @return object
+ */
+ public function clear_vars()
+ {
+ $this->_ci_cached_vars = array();
+ return $this;
}
// --------------------------------------------------------------------
@@ -503,7 +532,7 @@ class CI_Loader {
* Helper Loader
*
* @param string|string[] $helpers Helper name(s)
- * @return void
+ * @return object
*/
public function helper($helpers = array())
{
@@ -560,6 +589,8 @@ class CI_Loader {
show_error('Unable to load the requested file: helpers/'.$helper.'.php');
}
}
+
+ return $this;
}
// --------------------------------------------------------------------
@@ -572,11 +603,11 @@ class CI_Loader {
*
* @uses CI_Loader::helper()
* @param string|string[] $helpers Helper name(s)
- * @return void
+ * @return object
*/
public function helpers($helpers = array())
{
- $this->helper($helpers);
+ return $this->helper($helpers);
}
// --------------------------------------------------------------------
@@ -588,18 +619,19 @@ class CI_Loader {
*
* @param string|string[] $files List of language file names to load
* @param string Language name
- * @return void
+ * @return object
*/
- public function language($files = array(), $lang = '')
+ public function language($files, $lang = '')
{
$CI =& get_instance();
-
is_array($files) OR $files = array($files);
foreach ($files as $langfile)
{
$CI->lang->load($langfile, $lang);
}
+
+ return $this;
}
// --------------------------------------------------------------------
@@ -615,10 +647,9 @@ class CI_Loader {
* @param bool $fail_gracefully Whether to just return FALSE or display an error message
* @return bool TRUE if the file was loaded correctly or FALSE on failure
*/
- public function config($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
+ public function config($file, $use_sections = FALSE, $fail_gracefully = FALSE)
{
- $CI =& get_instance();
- return $CI->config->load($file, $use_sections, $fail_gracefully);
+ return get_instance()->config->load($file, $use_sections, $fail_gracefully);
}
// --------------------------------------------------------------------
@@ -632,10 +663,10 @@ class CI_Loader {
* @param array $params Optional parameters to pass to the driver
* @param string $object_name An optional object name to assign to
*
- * @return void|object|bool Object or FALSE on failure if $library is a string
- * and $object_name is set. void otherwise.
+ * @return object|bool Object or FALSE on failure if $library is a string
+ * and $object_name is set. CI_Loader instance otherwise.
*/
- public function driver($library = '', $params = NULL, $object_name = NULL)
+ public function driver($library, $params = NULL, $object_name = NULL)
{
if (is_array($library))
{
@@ -643,10 +674,10 @@ class CI_Loader {
{
$this->driver($driver);
}
- return;
- }
- if ($library === '')
+ return $this;
+ }
+ elseif (empty($library))
{
return FALSE;
}
@@ -682,7 +713,7 @@ class CI_Loader {
*
* @param string $path Path to add
* @param bool $view_cascade (default: TRUE)
- * @return void
+ * @return object
*/
public function add_package_path($path, $view_cascade = TRUE)
{
@@ -697,6 +728,8 @@ class CI_Loader {
// Add config file path
$config =& $this->_ci_get_component('config');
$config->_config_paths[] = $path;
+
+ return $this;
}
// --------------------------------------------------------------------
@@ -724,7 +757,7 @@ class CI_Loader {
* added path will be removed removed.
*
* @param string $path Path to remove
- * @return void
+ * @return object
*/
public function remove_package_path($path = '')
{
@@ -766,6 +799,8 @@ class CI_Loader {
$this->_ci_model_paths = array_unique(array_merge($this->_ci_model_paths, array(APPPATH)));
$this->_ci_view_paths = array_merge($this->_ci_view_paths, array(APPPATH.'views/' => TRUE));
$config->_config_paths = array_unique(array_merge($config->_config_paths, array(APPPATH)));
+
+ return $this;
}
// --------------------------------------------------------------------
@@ -781,7 +816,7 @@ class CI_Loader {
* @used-by CI_Loader::view()
* @used-by CI_Loader::file()
* @param array $_ci_data Data to load
- * @return void
+ * @return object
*/
protected function _ci_load($_ci_data)
{
@@ -905,6 +940,8 @@ class CI_Loader {
$_ci_CI->output->append_output(ob_get_contents());
@ob_end_clean();
}
+
+ return $this;
}
// --------------------------------------------------------------------
diff --git a/system/core/Log.php b/system/core/Log.php
index 20bc55986..707964ccc 100644
--- a/system/core/Log.php
+++ b/system/core/Log.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -140,7 +140,6 @@ class CI_Log {
*
* @param string the error level: 'error', 'debug' or 'info'
* @param string the error message
- * @param bool whether the error is a native PHP error
* @return bool
*/
public function write_log($level, $msg)
@@ -176,10 +175,18 @@ class CI_Log {
return FALSE;
}
- $message .= $level.' '.($level === 'INFO' ? ' -' : '-').' '.date($this->_date_fmt).' --> '.$msg."\n";
+ $message .= $level.' - '.date($this->_date_fmt).' --> '.$msg."\n";
flock($fp, LOCK_EX);
- fwrite($fp, $message);
+
+ for ($written = 0, $length = strlen($message); $written < $length; $written += $result)
+ {
+ if (($result = fwrite($fp, substr($message, $written))) === FALSE)
+ {
+ break;
+ }
+ }
+
flock($fp, LOCK_UN);
fclose($fp);
@@ -188,7 +195,7 @@ class CI_Log {
@chmod($filepath, FILE_WRITE_MODE);
}
- return TRUE;
+ return is_int($result);
}
}
diff --git a/system/core/Model.php b/system/core/Model.php
index 1eb6f909b..9485ec2c9 100644
--- a/system/core/Model.php
+++ b/system/core/Model.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -59,8 +59,7 @@ class CI_Model {
*/
public function __get($key)
{
- $CI =& get_instance();
- return $CI->$key;
+ return get_instance()->$key;
}
}
diff --git a/system/core/Output.php b/system/core/Output.php
index 7c2a64d24..ef56a97bf 100644
--- a/system/core/Output.php
+++ b/system/core/Output.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -58,21 +58,21 @@ class CI_Output {
*
* @var array
*/
- public $headers = array();
+ public $headers = array();
/**
* List of mime types
*
* @var array
*/
- public $mimes = array();
+ public $mimes = array();
/**
* Mime-type for the current page
*
* @var string
*/
- protected $mime_type = 'text/html';
+ protected $mime_type = 'text/html';
/**
* Enable Profiler flag
@@ -82,11 +82,18 @@ class CI_Output {
public $enable_profiler = FALSE;
/**
- * zLib output compression flag
+ * php.ini zlib.output_compression flag
*
* @var bool
*/
- protected $_zlib_oc = FALSE;
+ protected $_zlib_oc = FALSE;
+
+ /**
+ * CI output compression flag
+ *
+ * @var bool
+ */
+ protected $_compress_output = FALSE;
/**
* List of profiler sections
@@ -102,7 +109,7 @@ class CI_Output {
*
* @var bool
*/
- public $parse_exec_vars = TRUE;
+ public $parse_exec_vars = TRUE;
/**
* Class constructor
@@ -114,6 +121,11 @@ class CI_Output {
public function __construct()
{
$this->_zlib_oc = (bool) @ini_get('zlib.output_compression');
+ $this->_compress_output = (
+ $this->_zlib_oc === FALSE
+ && config_item('compress_output') === TRUE
+ && extension_loaded('zlib')
+ );
// Get mime types for later
$this->mimes =& get_mimes();
@@ -436,15 +448,14 @@ class CI_Output {
if ($this->parse_exec_vars === TRUE)
{
$memory = round(memory_get_usage() / 1024 / 1024, 2).'MB';
-
$output = str_replace(array('{elapsed_time}', '{memory_usage}'), array($elapsed, $memory), $output);
}
// --------------------------------------------------------------------
// Is compression requested?
- if ($CFG->item('compress_output') === TRUE && $this->_zlib_oc === FALSE
- && extension_loaded('zlib')
+ if (isset($CI) // This means that we're not serving a cache file, if we were, it would already be compressed
+ && $this->_compress_output === TRUE
&& isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
{
ob_start('ob_gzhandler');
@@ -468,6 +479,21 @@ class CI_Output {
// simply echo out the data and exit.
if ( ! isset($CI))
{
+ if ($this->_compress_output === TRUE)
+ {
+ if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
+ {
+ header('Content-Encoding: gzip');
+ header('Content-Length: '.strlen($output));
+ }
+ else
+ {
+ // User agent doesn't support gzip compression,
+ // so we'll have to decompress our cache
+ $output = gzinflate(substr($output, 10, -8));
+ }
+ }
+
echo $output;
log_message('debug', 'Final output sent to browser');
log_message('debug', 'Total execution time: '.$elapsed);
@@ -530,9 +556,9 @@ class CI_Output {
return;
}
- $uri = $CI->config->item('base_url').
- $CI->config->item('index_page').
- $CI->uri->uri_string();
+ $uri = $CI->config->item('base_url')
+ .$CI->config->item('index_page')
+ .$CI->uri->uri_string();
$cache_path .= md5($uri);
@@ -542,17 +568,39 @@ class CI_Output {
return;
}
- $expire = time() + ($this->cache_expiration * 60);
-
- // Put together our serialized info.
- $cache_info = serialize(array(
- 'expire' => $expire,
- 'headers' => $this->headers
- ));
-
if (flock($fp, LOCK_EX))
{
- fwrite($fp, $cache_info.'ENDCI--->'.$output);
+ // If output compression is enabled, compress the cache
+ // itself, so that we don't have to do that each time
+ // we're serving it
+ if ($this->_compress_output === TRUE)
+ {
+ $output = gzencode($output);
+
+ if ($this->get_header('content-type') === NULL)
+ {
+ $this->set_content_type($this->mime_type);
+ }
+ }
+
+ $expire = time() + ($this->cache_expiration * 60);
+
+ // Put together our serialized info.
+ $cache_info = serialize(array(
+ 'expire' => $expire,
+ 'headers' => $this->headers
+ ));
+
+ $output = $cache_info.'ENDCI--->'.$output;
+
+ for ($written = 0, $length = strlen($output); $written < $length; $written += $result)
+ {
+ if (($result = fwrite($fp, substr($output, $written))) === FALSE)
+ {
+ break;
+ }
+ }
+
flock($fp, LOCK_UN);
}
else
@@ -560,13 +608,22 @@ class CI_Output {
log_message('error', 'Unable to secure a file lock for file at: '.$cache_path);
return;
}
+
fclose($fp);
- @chmod($cache_path, FILE_WRITE_MODE);
- log_message('debug', 'Cache file written: '.$cache_path);
+ if (is_int($result))
+ {
+ @chmod($cache_path, FILE_WRITE_MODE);
+ log_message('debug', 'Cache file written: '.$cache_path);
- // Send HTTP cache-control headers to browser to match file cache settings.
- $this->set_cache_header($_SERVER['REQUEST_TIME'], $expire);
+ // Send HTTP cache-control headers to browser to match file cache settings.
+ $this->set_cache_header($_SERVER['REQUEST_TIME'], $expire);
+ }
+ else
+ {
+ @unlink($cache_path);
+ log_message('error', 'Unable to write the complete cache content at: '.$cache_path);
+ }
}
// --------------------------------------------------------------------
@@ -701,7 +758,7 @@ class CI_Output {
else
{
header('Pragma: public');
- header('Cache-Control: max-age=' . $max_age . ', public');
+ header('Cache-Control: max-age='.$max_age.', public');
header('Expires: '.gmdate('D, d M Y H:i:s', $expiration).' GMT');
header('Last-modified: '.gmdate('D, d M Y H:i:s', $last_modified).' GMT');
}
@@ -740,13 +797,13 @@ class CI_Output {
preg_match_all('{<style.+</style>}msU', $output, $style_clean);
foreach ($style_clean[0] as $s)
{
- $output = str_replace($s, $this->_minify_script_style($s, TRUE), $output);
+ $output = str_replace($s, $this->_minify_js_css($s, 'css', TRUE), $output);
}
// Minify the javascript in <script> tags.
foreach ($javascript_clean[0] as $s)
{
- $javascript_mini[] = $this->_minify_script_style($s, TRUE);
+ $javascript_mini[] = $this->_minify_js_css($s, 'js', TRUE);
}
// Replace multiple spaces with a single space.
@@ -792,13 +849,14 @@ class CI_Output {
break;
case 'text/css':
+
+ return $this->_minify_js_css($output, 'css');
+
case 'text/javascript':
case 'application/javascript':
case 'application/x-javascript':
- $output = $this->_minify_script_style($output);
-
- break;
+ return $this->_minify_js_css($output, 'js');
default: break;
}
@@ -809,163 +867,100 @@ class CI_Output {
// --------------------------------------------------------------------
/**
- * Minify Style and Script
- *
- * Reduce excessive size of CSS/JavaScript content. To remove spaces this
- * script walks the string as an array and determines if the pointer is inside
- * a string created by single quotes or double quotes. spaces inside those
- * strings are not stripped. Opening and closing tags are severed from
- * the string initially and saved without stripping whitespace to preserve
- * the tags and any associated properties if tags are present
+ * Minify JavaScript and CSS code
*
- * Minification logic/workflow is similar to methods used by Douglas Crockford
- * in JSMIN. http://www.crockford.com/javascript/jsmin.html
+ * Strips comments and excessive whitespace characters
*
- * KNOWN ISSUE: ending a line with a closing parenthesis ')' and no semicolon
- * where there should be one will break the Javascript. New lines after a
- * closing parenthesis are not recognized by the script. For best results
- * be sure to terminate lines with a semicolon when appropriate.
- *
- * @param string $output Output to minify
- * @param bool $has_tags Specify if the output has style or script tags
- * @return string Minified output
+ * @param string $output
+ * @param string $type 'js' or 'css'
+ * @param bool $tags Whether $output contains the 'script' or 'style' tag
+ * @return string
*/
- protected function _minify_script_style($output, $has_tags = FALSE)
+ protected function _minify_js_css($output, $type, $tags = FALSE)
{
- // We only need this if there are tags in the file
- if ($has_tags === TRUE)
+ if ($tags === TRUE)
{
- // Remove opening tag and save for later
- $pos = strpos($output, '>') + 1;
- $open_tag = substr($output, 0, $pos);
- $output = substr_replace($output, '', 0, $pos);
+ $tags = array('close' => strrchr($output, '<'));
- // Remove closing tag and save it for later
- $pos = strrpos($output, '</');
- $closing_tag = substr($output, $pos);
- $output = substr_replace($output, '', $pos);
+ $open_length = strpos($output, '>') + 1;
+ $tags['open'] = substr($output, 0, $open_length);
+
+ $output = substr($output, $open_length, -strlen($tags['close']));
+
+ // Strip spaces from the tags
+ $tags = preg_replace('#\s{2,}#', ' ', $tags);
}
- // Remove CSS comments
- $output = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!i', '', $output);
+ $output = trim($output);
- // Remove Javascript inline comments
- if ($has_tags === TRUE && strpos(strtolower($open_tag), 'script') !== FALSE)
+ if ($type === 'js')
{
- $lines = preg_split('/\r?\n|\n?\r/', $output);
- foreach ($lines as &$line)
+ // Catch all string literals and comment blocks
+ if (preg_match_all('#((?:((?<!\\\)\'|")|(/\*)|(//)).*(?(2)(?<!\\\)\2|(?(3)\*/|\n)))#msuUS', $output, $match, PREG_OFFSET_CAPTURE))
{
- $in_string = $in_dstring = FALSE;
- for ($i = 0, $len = strlen($line); $i < $len; $i++)
+ $js_literals = $js_code = array();
+ for ($match = $match[0], $c = count($match), $i = $pos = $offset = 0; $i < $c; $i++)
{
- if ( ! $in_string && ! $in_dstring && substr($line, $i, 2) === '//')
- {
- $line = substr($line, 0, $i);
- break;
- }
+ $js_code[$pos++] = trim(substr($output, $offset, $match[$i][1] - $offset));
+ $offset = $match[$i][1] + strlen($match[$i][0]);
- if ($line[$i] === "'" && ! $in_dstring)
+ // Save only if we haven't matched a comment block
+ if ($match[$i][0][0] !== '/')
{
- $in_string = ! $in_string;
- }
- elseif ($line[$i] === '"' && ! $in_string)
- {
- $in_dstring = ! $in_dstring;
+ $js_literals[$pos++] = array_shift($match[$i]);
}
}
+ $js_code[$pos] = substr($output, $offset);
+
+ // $match might be quite large, so free it up together with other vars that we no longer need
+ unset($match, $offset, $pos);
+ }
+ else
+ {
+ $js_code = array($output);
+ $js_literals = array();
}
- $output = implode("\n", $lines);
+ $varname = 'js_code';
}
-
- // Remove spaces around curly brackets, colons,
- // semi-colons, parenthesis, commas
- $chunks = preg_split('/([\'|"]).+(?![^\\\]\\1)\\1/iU', $output, -1, PREG_SPLIT_OFFSET_CAPTURE);
- for ($i = count($chunks) - 1; $i >= 0; $i--)
+ else
{
- $output = substr_replace(
- $output,
- preg_replace('/\s*(:|;|,|}|{|\(|\))\s*/i', '$1', $chunks[$i][0]),
- $chunks[$i][1],
- strlen($chunks[$i][0])
- );
+ $varname = 'output';
}
- // Replace tabs with spaces
- // Replace carriage returns & multiple new lines with single new line
- // and trim any leading or trailing whitespace
- $output = trim(preg_replace(array('/\t+/', '/\r/', '/\n+/'), array(' ', "\n", "\n"), $output));
+ // Standartize new lines
+ $$varname = str_replace(array("\r\n", "\r"), "\n", $$varname);
- // Remove spaces when safe to do so.
- $in_string = $in_dstring = $prev = FALSE;
- $array_output = str_split($output);
- foreach ($array_output as $key => $value)
+ if ($type === 'js')
{
- if ($in_string === FALSE && $in_dstring === FALSE)
- {
- if ($value === ' ')
- {
- // Get the next element in the array for comparisons
- $next = $array_output[$key + 1];
-
- // Strip spaces preceded/followed by a non-ASCII character
- // or not preceded/followed by an alphanumeric
- // or not preceded/followed \ $ and _
- if ((preg_match('/^[\x20-\x7f]*$/D', $next) OR preg_match('/^[\x20-\x7f]*$/D', $prev))
- && ( ! ctype_alnum($next) OR ! ctype_alnum($prev))
- && ! in_array($next, array('\\', '_', '$'), TRUE)
- && ! in_array($prev, array('\\', '_', '$'), TRUE)
- )
- {
- unset($array_output[$key]);
- }
- }
- else
- {
- // Save this value as previous for the next iteration
- // if it is not a blank space
- $prev = $value;
- }
- }
-
- if ($value === "'" && ! $in_dstring)
- {
- $in_string = ! $in_string;
- }
- elseif ($value === '"' && ! $in_string)
- {
- $in_dstring = ! $in_dstring;
- }
+ $patterns = array(
+ '#\s*([!\#%&()*+,\-./:;<=>?@\[\]^`{|}~])\s*#' => '$1', // Remove spaces following and preceeding JS-wise non-special & non-word characters
+ '#\s{2,}#' => ' ' // Reduce the remaining multiple whitespace characters to a single space
+ );
+ }
+ else
+ {
+ $patterns = array(
+ '#/\*.*(?=\*/)\*/#s' => '', // Remove /* block comments */
+ '#\n?//[^\n]*#' => '', // Remove // line comments
+ '#\s*([^\w.\#%])\s*#U' => '$1', // Remove spaces following and preceeding non-word characters, excluding dots, hashes and the percent sign
+ '#\s{2,}#' => ' ' // Reduce the remaining multiple space characters to a single space
+ );
}
- // Put the string back together after spaces have been stripped
- $output = implode($array_output);
+ $$varname = preg_replace(array_keys($patterns), array_values($patterns), $$varname);
- // Remove new line characters unless previous or next character is
- // printable or Non-ASCII
- preg_match_all('/[\n]/', $output, $lf, PREG_OFFSET_CAPTURE);
- $removed_lf = 0;
- foreach ($lf as $feed_position)
+ // Glue back JS quoted strings
+ if ($type === 'js')
{
- foreach ($feed_position as $position)
- {
- $position = $position[1] - $removed_lf;
- $next = $output[$position + 1];
- $prev = $output[$position - 1];
- if ( ! ctype_print($next) && ! ctype_print($prev)
- && ! preg_match('/^[\x20-\x7f]*$/D', $next)
- && ! preg_match('/^[\x20-\x7f]*$/D', $prev)
- )
- {
- $output = substr_replace($output, '', $position, 1);
- $removed_lf++;
- }
- }
+ $js_code += $js_literals;
+ ksort($js_code);
+ $output = implode($js_code);
+ unset($js_code, $js_literals, $varname, $patterns);
}
- // Put the opening and closing tags back if applicable
- return isset($open_tag)
- ? $open_tag.$output.$closing_tag
+ return is_array($tags)
+ ? $tags['open'].$output.$tags['close']
: $output;
}
diff --git a/system/core/Router.php b/system/core/Router.php
index 0f7278ae6..05263b153 100644
--- a/system/core/Router.php
+++ b/system/core/Router.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -91,6 +91,15 @@ class CI_Router {
*/
public $translate_uri_dashes = FALSE;
+ /**
+ * Enable query strings flag
+ *
+ * Determines wether to use GET parameters or segment URIs
+ *
+ * @var bool
+ */
+ public $enable_query_strings = FALSE;
+
// --------------------------------------------------------------------
/**
@@ -102,9 +111,34 @@ class CI_Router {
*/
public function __construct()
{
+ global $routing;
+
$this->config =& load_class('Config', 'core');
$this->uri =& load_class('URI', 'core');
+
+ $this->enable_query_strings = ( ! is_cli() && $this->config->item('enable_query_strings') === TRUE);
$this->_set_routing();
+
+ // Set any routing overrides that may exist in the main index file
+ if (isset($routing) && is_array($routing))
+ {
+ if (isset($routing['directory']))
+ {
+ $this->set_directory($routing['directory']);
+ }
+
+ if ( ! empty($routing['controller']))
+ {
+ $this->set_class($routing['controller']);
+ }
+
+ if (isset($routing['function']))
+ {
+ $routing['function'] = empty($routing['function']) ? 'index' : $routing['function'];
+ $this->set_method($routing['function']);
+ }
+ }
+
log_message('debug', 'Router Class Initialized');
}
@@ -123,26 +157,39 @@ class CI_Router {
// Are query strings enabled in the config file? Normally CI doesn't utilize query strings
// since URI segments are more search-engine friendly, but they can optionally be used.
// If this feature is enabled, we will gather the directory/class/method a little differently
- $segments = array();
- if ($this->config->item('enable_query_strings') === TRUE
- && ! empty($_GET[$this->config->item('controller_trigger')])
- && is_string($_GET[$this->config->item('controller_trigger')])
- )
+ if ($this->enable_query_strings)
{
- if (isset($_GET[$this->config->item('directory_trigger')]) && is_string($_GET[$this->config->item('directory_trigger')]))
+ $_d = $this->config->item('directory_trigger');
+ $_d = isset($_GET[$_d]) ? trim($_GET[$_d], " \t\n\r\0\x0B/") : '';
+ if ($_d !== '')
{
- $this->set_directory(trim($this->uri->_filter_uri($_GET[$this->config->item('directory_trigger')])));
- $segments[] = $this->directory;
+ $this->set_directory($this->uri->filter_uri($_d));
}
- $this->set_class(trim($this->uri->_filter_uri($_GET[$this->config->item('controller_trigger')])));
- $segments[] = $this->class;
+ $_c = $this->config->item('controller_trigger');
+ if ( ! empty($_GET[$_c]))
+ {
+ $this->set_class(trim($this->uri->filter_uri(trim($_GET[$_c]))));
+
+ $_f = $this->config->item('function_trigger');
+ if ( ! empty($_GET[$_f]))
+ {
+ $this->set_method(trim($this->uri->filter_uri($_GET[$_f])));
+ }
- if ( ! empty($_GET[$this->config->item('function_trigger')]) && is_string($_GET[$this->config->item('function_trigger')]))
+ $this->uri->rsegments = array(
+ 1 => $this->class,
+ 2 => $this->method
+ );
+ }
+ else
{
- $this->set_method(trim($this->uri->_filter_uri($_GET[$this->config->item('function_trigger')])));
- $segments[] = $this->method;
+ $this->_set_default_controller();
}
+
+ // Routing rules don't apply to query strings and we don't need to detect
+ // directories, so we're done here
+ return;
}
// Load the routes.php file.
@@ -165,53 +212,15 @@ class CI_Router {
$this->routes = $route;
}
- // Were there any query string segments? If so, we'll validate them and bail out since we're done.
- if (count($segments) > 0)
+ // Is there anything to parse?
+ if ($this->uri->uri_string !== '')
{
- return $this->_validate_request($segments);
+ $this->_parse_routes();
}
-
- // Fetch the complete URI string
- $this->uri->_fetch_uri_string();
-
- // Is there a URI string? If not, the default controller specified in the "routes" file will be shown.
- if ($this->uri->uri_string == '')
+ else
{
- return $this->_set_default_controller();
+ $this->_set_default_controller();
}
-
- $this->uri->_remove_url_suffix(); // Remove the URL suffix
- $this->uri->_explode_segments(); // Compile the segments into an array
- $this->_parse_routes(); // Parse any custom routing that may exist
- $this->uri->_reindex_segments(); // Re-index the segment array so that it starts with 1 rather than 0
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Set default controller
- *
- * @return void
- */
- protected function _set_default_controller()
- {
- if (empty($this->default_controller))
- {
- show_error('Unable to determine what should be displayed. A default route has not been specified in the routing file.');
- }
-
- // Is the method being specified?
- if (sscanf($this->default_controller, '%[^/]/%s', $class, $method) !== 2)
- {
- $method = 'index';
- }
-
- $this->_set_request(array($class, $method));
-
- // re-index the routed segments array so it starts with 1 rather than 0
- $this->uri->_reindex_segments();
-
- log_message('debug', 'No URI present. Default controller set.');
}
// --------------------------------------------------------------------
@@ -222,16 +231,19 @@ class CI_Router {
* Takes an array of URI segments as input and sets the class/method
* to be called.
*
+ * @used-by CI_Router::_parse_routes()
* @param array $segments URI segments
* @return void
*/
protected function _set_request($segments = array())
{
$segments = $this->_validate_request($segments);
-
- if (count($segments) === 0)
+ // If we don't have any segments left - try the default controller;
+ // WARNING: Directories get shifted out of the segments array!
+ if (empty($segments))
{
- return $this->_set_default_controller();
+ $this->_set_default_controller();
+ return;
}
if ($this->translate_uri_dashes === TRUE)
@@ -244,90 +256,86 @@ class CI_Router {
}
$this->set_class($segments[0]);
- isset($segments[1]) OR $segments[1] = 'index';
- $this->set_method($segments[1]);
+ if (isset($segments[1]))
+ {
+ $this->set_method($segments[1]);
+ }
- // Update our "routed" segment array to contain the segments.
- // Note: If there is no custom routing, this array will be
- // identical to $this->uri->segments
+ array_unshift($segments, NULL);
+ unset($segments[0]);
$this->uri->rsegments = $segments;
}
// --------------------------------------------------------------------
/**
- * Validate request
- *
- * Attempts validate the URI request and determine the controller path.
+ * Set default controller
*
- * @param array $segments URI segments
- * @return array URI segments
+ * @return void
*/
- protected function _validate_request($segments)
+ protected function _set_default_controller()
{
- if (count($segments) === 0)
+ if (empty($this->default_controller))
{
- return $segments;
+ show_error('Unable to determine what should be displayed. A default route has not been specified in the routing file.');
}
- $test = ucfirst($this->translate_uri_dashes === TRUE ? str_replace('-', '_', $segments[0]) : $segments[0]);
-
- // Does the requested controller exist in the root folder?
- if (file_exists(APPPATH.'controllers/'.$test.'.php'))
+ // Is the method being specified?
+ if (sscanf($this->default_controller, '%[^/]/%s', $class, $method) !== 2)
{
- return $segments;
+ $method = 'index';
}
- // Is the controller in a sub-folder?
- if (is_dir(APPPATH.'controllers/'.$segments[0]))
+ if ( ! file_exists(APPPATH.'controllers/'.$this->directory.ucfirst($class).'.php'))
{
- // Set the directory and remove it from the segment array
- $this->set_directory(array_shift($segments));
- if (count($segments) > 0)
- {
- $test = ucfirst($this->translate_uri_dashes === TRUE ? str_replace('-', '_', $segments[0]) : $segments[0]);
+ // This will trigger 404 later
+ return;
+ }
- // Does the requested controller exist in the sub-directory?
- if ( ! file_exists(APPPATH.'controllers/'.$this->directory.$test.'.php'))
- {
- if ( ! empty($this->routes['404_override']))
- {
- $this->directory = '';
- return explode('/', $this->routes['404_override'], 2);
- }
- else
- {
- show_404($this->directory.$segments[0]);
- }
- }
- }
- else
- {
- // Is the method being specified in the route?
- $segments = explode('/', $this->default_controller);
- if ( ! file_exists(APPPATH.'controllers/'.$this->directory.ucfirst($segments[0]).'.php'))
- {
- $this->directory = '';
- }
- }
+ $this->set_class($class);
+ $this->set_method($method);
- return $segments;
- }
+ // Assign routed segments, index starting from 1
+ $this->uri->rsegments = array(
+ 1 => $class,
+ 2 => $method
+ );
- // If we've gotten this far it means that the URI does not correlate to a valid
- // controller class. We will now see if there is an override
- if ( ! empty($this->routes['404_override']))
+ log_message('debug', 'No URI present. Default controller set.');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Validate request
+ *
+ * Attempts validate the URI request and determine the controller path.
+ *
+ * @used-by CI_Router::_set_request()
+ * @param array $segments URI segments
+ * @return mixed URI segments
+ */
+ protected function _validate_request($segments)
+ {
+ $c = count($segments);
+ // Loop through our segments and return as soon as a controller
+ // is found or when such a directory doesn't exist
+ while ($c-- > 0)
{
- if (sscanf($this->routes['404_override'], '%[^/]/%s', $class, $method) !== 2)
+ $test = $this->directory
+ .ucfirst($this->translate_uri_dashes === TRUE ? str_replace('-', '_', $segments[0]) : $segments[0]);
+
+ if ( ! file_exists(APPPATH.'controllers/'.$test.'.php') && is_dir(APPPATH.'controllers/'.$this->directory.$segments[0]))
{
- $method = 'index';
+ $this->set_directory(array_shift($segments), TRUE);
+ continue;
}
- return array($class, $method);
+ return $segments;
}
- // Nothing else to do at this point but show a 404
- show_404($segments[0]);
+ // This means that all segments were actually directories
+ return $segments;
}
// --------------------------------------------------------------------
@@ -345,15 +353,42 @@ class CI_Router {
// Turn the segment array into a URI string
$uri = implode('/', $this->uri->segments);
+ // Get HTTP verb
+ $http_verb = isset($_SERVER['REQUEST_METHOD']) ? strtolower($_SERVER['REQUEST_METHOD']) : 'cli';
+
// Is there a literal match? If so we're done
- if (isset($this->routes[$uri]) && is_string($this->routes[$uri]))
+ if (isset($this->routes[$uri]))
{
- return $this->_set_request(explode('/', $this->routes[$uri]));
+ // Check default routes format
+ if (is_string($this->routes[$uri]))
+ {
+ $this->_set_request(explode('/', $this->routes[$uri]));
+ return;
+ }
+ // Is there a matching http verb?
+ elseif (is_array($this->routes[$uri]) && isset($this->routes[$uri][$http_verb]))
+ {
+ $this->_set_request(explode('/', $this->routes[$uri][$http_verb]));
+ return;
+ }
}
// Loop through the route array looking for wildcards
foreach ($this->routes as $key => $val)
{
+ // Check if route format is using http verb
+ if (is_array($val))
+ {
+ if (isset($val[$http_verb]))
+ {
+ $val = $val[$http_verb];
+ }
+ else
+ {
+ continue;
+ }
+ }
+
// Convert wildcards to RegEx
$key = str_replace(array(':any', ':num'), array('[^/]+', '[0-9]+'), $key);
@@ -404,13 +439,14 @@ class CI_Router {
$val = preg_replace('#^'.$key.'$#', $val, $uri);
}
- return $this->_set_request(explode('/', $val));
+ $this->_set_request(explode('/', $val));
+ return;
}
}
// If we got this far it means we didn't encounter a
// matching route so we'll set the site default route
- $this->_set_request($this->uri->segments);
+ $this->_set_request(array_values($this->uri->segments));
}
// --------------------------------------------------------------------
@@ -471,11 +507,19 @@ class CI_Router {
* Set directory name
*
* @param string $dir Directory name
+ * @param bool $appent Whether we're appending rather then setting the full value
* @return void
*/
- public function set_directory($dir)
+ public function set_directory($dir, $append = FALSE)
{
- $this->directory = str_replace(array('/', '.'), '', $dir).'/';
+ if ($append !== TRUE OR empty($this->directory))
+ {
+ $this->directory = str_replace('.', '', trim($dir, '/')).'/';
+ }
+ else
+ {
+ $this->directory .= str_replace('.', '', trim($dir, '/')).'/';
+ }
}
// --------------------------------------------------------------------
@@ -494,38 +538,6 @@ class CI_Router {
return $this->directory;
}
- // --------------------------------------------------------------------
-
- /**
- * Set controller overrides
- *
- * @param array $routing Route overrides
- * @return void
- */
- public function _set_overrides($routing)
- {
- if ( ! is_array($routing))
- {
- return;
- }
-
- if (isset($routing['directory']))
- {
- $this->set_directory($routing['directory']);
- }
-
- if ( ! empty($routing['controller']))
- {
- $this->set_class($routing['controller']);
- }
-
- if (isset($routing['function']))
- {
- $routing['function'] = empty($routing['function']) ? 'index' : $routing['function'];
- $this->set_method($routing['function']);
- }
- }
-
}
/* End of file Router.php */
diff --git a/system/core/Security.php b/system/core/Security.php
index 70cf3e013..faa52d746 100644
--- a/system/core/Security.php
+++ b/system/core/Security.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -62,6 +62,19 @@ class CI_Security {
);
/**
+ * HTML5 entities
+ *
+ * @var array
+ */
+ public $html5_entities = array(
+ '&colon;' => ':',
+ '&lpar;' => '(',
+ '&rpar;' => ')',
+ '&newline;' => "\n",
+ '&tab;' => "\t"
+ );
+
+ /**
* XSS Hash
*
* Random Hash for protecting URLs.
@@ -117,7 +130,6 @@ class CI_Security {
'document.write' => '[removed]',
'.parentNode' => '[removed]',
'.innerHTML' => '[removed]',
- 'window.location' => '[removed]',
'-moz-binding' => '[removed]',
'<!--' => '&lt;!--',
'-->' => '--&gt;',
@@ -132,9 +144,13 @@ class CI_Security {
*/
protected $_never_allowed_regex = array(
'javascript\s*:',
+ '(document|(document\.)?window)\.(location|on\w*)',
'expression\s*(\(|&\#40;)', // CSS and IE
'vbscript\s*:', // IE, surprise!
- 'Redirect\s+302',
+ 'wscript\s*:', // IE
+ 'jscript\s*:', // IE
+ 'vbs\s*:', // IE
+ 'Redirect\s+30\d',
"([\"'])?data\s*:[^\\1]*?base64[^\\1]*?,[^\\1]*?\\1?"
);
@@ -343,7 +359,11 @@ class CI_Security {
*
* Note: Use rawurldecode() so it does not remove plus signs
*/
- $str = rawurldecode($str);
+ do
+ {
+ $str = rawurldecode($str);
+ }
+ while (preg_match('/%[0-9a-f]{2,}/i', $str));
/*
* Convert character entities to ASCII
@@ -402,8 +422,9 @@ class CI_Security {
* These words are compacted back to their correct state.
*/
$words = array(
- 'javascript', 'expression', 'vbscript', 'script', 'base64',
- 'applet', 'alert', 'document', 'write', 'cookie', 'window'
+ 'javascript', 'expression', 'vbscript', 'jscript', 'wscript',
+ 'vbs', 'script', 'base64', 'applet', 'alert', 'document',
+ 'write', 'cookie', 'window', 'confirm', 'prompt'
);
foreach ($words as $word)
@@ -420,6 +441,12 @@ class CI_Security {
* We used to do some version comparisons and use of stripos for PHP5,
* but it is dog slow compared to these simplified non-capturing
* preg_match(), especially if the pattern exists in the string
+ *
+ * Note: It was reported that not only space characters, but all in
+ * the following pattern can be parsed as separators between a tag name
+ * and its attributes: [\d\s"\'`;,\/\=\(\x00\x0B\x09\x0C]
+ * ... however, remove_invisible_characters() above already strips the
+ * hex-encoded ones, so we'll skip them below.
*/
do
{
@@ -427,12 +454,12 @@ class CI_Security {
if (preg_match('/<a/i', $str))
{
- $str = preg_replace_callback('#<a\s+([^>]*?)(?:>|$)#si', array($this, '_js_link_removal'), $str);
+ $str = preg_replace_callback('#<a[\s\d"\'`;/=,\(\\\\]+([^>]*?)(?:>|$)#si', array($this, '_js_link_removal'), $str);
}
if (preg_match('/<img/i', $str))
{
- $str = preg_replace_callback('#<img\s+([^>]*?)(?:\s?/?>|$)#si', array($this, '_js_img_removal'), $str);
+ $str = preg_replace_callback('#<img[\s\d"\'`;/=,\(\\\\]+([^>]*?)(?:\s?/?>|$)#si', array($this, '_js_img_removal'), $str);
}
if (preg_match('/script|xss/i', $str))
@@ -456,7 +483,7 @@ class CI_Security {
* So this: <blink>
* Becomes: &lt;blink&gt;
*/
- $naughty = 'alert|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|isindex|layer|link|meta|object|plaintext|style|script|textarea|title|video|xml|xss';
+ $naughty = 'alert|prompt|confirm|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|button|select|isindex|layer|link|meta|keygen|object|plaintext|style|script|textarea|title|math|video|svg|xml|xss';
$str = preg_replace_callback('#<(/*\s*)('.$naughty.')([^><]*)([><]*)#is', array($this, '_sanitize_naughty_html'), $str);
/*
@@ -471,7 +498,7 @@ class CI_Security {
* For example: eval('some code')
* Becomes: eval&#40;'some code'&#41;
*/
- $str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si',
+ $str = preg_replace('#(alert|prompt|confirm|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si',
'\\1\\2&#40;\\3&#41;',
$str);
@@ -551,13 +578,13 @@ class CI_Security {
do
{
- $matches = $matches1 = 0;
+ $m1 = $m2 = 0;
+ $str = preg_replace('/(&#x0*[0-9a-f]{2,5})(?![0-9a-f;])/iS', '$1;', $str, -1, $m1);
+ $str = preg_replace('/(&#\d{2,4})(?![0-9;])/S', '$1;', $str, -1, $m2);
$str = html_entity_decode($str, ENT_COMPAT, $charset);
- $str = preg_replace('~&#x(0*[0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str, -1, $matches);
- $str = preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str, -1, $matches1);
}
- while ($matches OR $matches1);
+ while ($m1 OR $m2);
return $str;
}
@@ -603,7 +630,7 @@ class CI_Security {
*/
public function strip_image_tags($str)
{
- return preg_replace(array('#<img\s+.*?src\s*=\s*["\'](.+?)["\'].*?\>#', '#<img\s+.*?src\s*=\s*(.+?).*?\>#'), '\\1', $str);
+ return preg_replace(array('#<img[\s/]+.*?src\s*=\s*["\'](.+?)["\'].*?\>#', '#<img[\s/]+.*?src\s*=\s*(.+?).*?\>#'), '\\1', $str);
}
// ----------------------------------------------------------------
@@ -648,8 +675,7 @@ class CI_Security {
*/
protected function _remove_evil_attributes($str, $is_image)
{
- // All javascript event handlers (e.g. onload, onclick, onmouseover), style, and xmlns
- $evil_attributes = array('on\w*', 'style', 'xmlns', 'formaction');
+ $evil_attributes = array('on\w*', 'style', 'xmlns', 'formaction', 'form', 'xlink:href');
if ($is_image === TRUE)
{
@@ -665,7 +691,7 @@ class CI_Security {
$attribs = array();
// find occurrences of illegal attribute strings with quotes (042 and 047 are octal quotes)
- preg_match_all('/('.implode('|', $evil_attributes).')\s*=\s*(\042|\047)([^\\2]*?)(\\2)/is', $str, $matches, PREG_SET_ORDER);
+ preg_match_all('/(?<!\w)('.implode('|', $evil_attributes).')\s*=\s*(\042|\047)([^\\2]*?)(\\2)/is', $str, $matches, PREG_SET_ORDER);
foreach ($matches as $attr)
{
@@ -673,7 +699,7 @@ class CI_Security {
}
// find occurrences of illegal attribute strings without quotes
- preg_match_all('/('.implode('|', $evil_attributes).')\s*=\s*([^\s>]*)/is', $str, $matches, PREG_SET_ORDER);
+ preg_match_all('/(?<!\w)('.implode('|', $evil_attributes).')\s*=\s*([^\s>]*)/is', $str, $matches, PREG_SET_ORDER);
foreach ($matches as $attr)
{
@@ -727,7 +753,7 @@ class CI_Security {
protected function _js_link_removal($match)
{
return str_replace($match[1],
- preg_replace('#href=.*?(?:alert\(|alert&\#40;|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|<script|<xss|data\s*:)#si',
+ preg_replace('#href=.*?(?:(?:alert|prompt|confirm)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|<script|<xss|data\s*:)#si',
'',
$this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]))
),
@@ -752,7 +778,7 @@ class CI_Security {
protected function _js_img_removal($match)
{
return str_replace($match[1],
- preg_replace('#src=.*?(?:alert\(|alert&\#40;|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si',
+ preg_replace('#src=.*?(?:(?:alert|prompt|confirm)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si',
'',
$this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]))
),
@@ -810,7 +836,14 @@ class CI_Security {
*/
protected function _decode_entity($match)
{
- return $this->entity_decode($match[0], strtoupper(config_item('charset')));
+ // entity_decode() won't convert dangerous HTML5 entities
+ // (it could, but ENT_HTML5 is only available since PHP 5.4),
+ // so we'll do that here
+ return str_ireplace(
+ array_keys($this->html5_entities),
+ array_values($this->html5_entities),
+ $this->entity_decode($match[0], strtoupper(config_item('charset')))
+ );
}
// --------------------------------------------------------------------
@@ -837,14 +870,15 @@ class CI_Security {
* Add a semicolon if missing. We do this to enable
* the conversion of entities to ASCII later.
*/
- $str = preg_replace('#(&\#?[0-9a-z]{2,})([\x00-\x20])*;?#i', '\\1;\\2', $str);
+ $str = preg_replace('/(&#\d{2,4})(?![0-9;])/', '$1;', $str);
+ $str = preg_replace('/(&[a-z]{2,})(?![a-z;])/i', '$1;', $str);
/*
* Validate UTF16 two byte encoding (x00)
*
* Just as above, adds a semicolon if missing.
*/
- $str = preg_replace('#(&\#x?)([0-9A-F]+);?#i', '\\1\\2;', $str);
+ $str = preg_replace('/(&#x0*[0-9a-f]{2,5})(?![0-9a-f;])/i', '$1;', $str);
/*
* Un-Protect GET variables in URLs
@@ -884,7 +918,7 @@ class CI_Security {
{
if ($this->_csrf_hash === '')
{
- // If the cookie exists we will use it's value.
+ // If the cookie exists we will use its value.
// We don't necessarily want to regenerate it with
// each page load since a page could contain embedded
// sub-pages causing this feature to fail
@@ -894,7 +928,7 @@ class CI_Security {
return $this->_csrf_hash = $_COOKIE[$this->_csrf_cookie_name];
}
- $this->_csrf_hash = md5(uniqid(rand(), TRUE));
+ $this->_csrf_hash = md5(uniqid(mt_rand(), TRUE));
$this->csrf_set_cookie();
}
diff --git a/system/core/URI.php b/system/core/URI.php
index bc086d223..15d6263be 100644
--- a/system/core/URI.php
+++ b/system/core/URI.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -44,21 +44,21 @@ class CI_URI {
*
* @var array
*/
- public $keyval = array();
+ public $keyval = array();
/**
* Current URI string
*
* @var string
*/
- public $uri_string;
+ public $uri_string = '';
/**
* List of URI segments
*
* @var array
*/
- public $segments = array();
+ public $segments = array();
/**
* Re-indexed list of URI segments
@@ -67,90 +67,67 @@ class CI_URI {
*
* @var array
*/
- public $rsegments = array();
+ public $rsegments = array();
/**
- * Class constructor
+ * Permitted URI chars
*
- * Simply globalizes the $RTR object. The front
- * loads the Router class early on so it's not available
- * normally as other classes are.
+ * PCRE character group allowed in URI segments
*
- * @return void
+ * @var string
*/
- public function __construct()
- {
- $this->config =& load_class('Config', 'core');
- log_message('debug', 'URI Class Initialized');
- }
-
- // --------------------------------------------------------------------
+ protected $_permitted_uri_chars;
/**
- * Fetch URI String
+ * Class constructor
*
- * @used-by CI_Router
* @return void
*/
- public function _fetch_uri_string()
+ public function __construct()
{
- $protocol = strtoupper($this->config->item('uri_protocol'));
+ $this->config =& load_class('Config', 'core');
- if ($protocol === 'AUTO')
+ // 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)
{
- // Is the request coming from the command line?
- if ($this->_is_cli_request())
+ $this->_permitted_uri_chars = $this->config->item('permitted_uri_chars');
+
+ // If it's a CLI request, ignore the configuration
+ if (is_cli() OR ($protocol = strtoupper($this->config->item('uri_protocol'))) === 'CLI')
{
$this->_set_uri_string($this->_parse_argv());
- return;
}
-
- // Is there a PATH_INFO variable? This should be the easiest solution.
- if (isset($_SERVER['PATH_INFO']))
+ elseif ($protocol === 'AUTO')
{
- $this->_set_uri_string($_SERVER['PATH_INFO']);
- return;
+ // Is there a PATH_INFO variable? This should be the easiest solution.
+ if (isset($_SERVER['PATH_INFO']))
+ {
+ $this->_set_uri_string($_SERVER['PATH_INFO']);
+ }
+ // No PATH_INFO? Let's try REQUST_URI or QUERY_STRING then
+ elseif (($uri = $this->_parse_request_uri()) !== '' OR ($uri = $this->_parse_query_string()) !== '')
+ {
+ $this->_set_uri_string($uri);
+ }
+ // As a last ditch effor, let's try using the $_GET array
+ elseif (is_array($_GET) && count($_GET) === 1 && trim(key($_GET), '/') !== '')
+ {
+ $this->_set_uri_string(key($_GET));
+ }
}
-
- // Let's try REQUEST_URI then, this will work in most situations
- if (($uri = $this->_parse_request_uri()) !== '')
+ elseif (method_exists($this, ($method = '_parse_'.strtolower($protocol))))
{
- $this->_set_uri_string($uri);
- return;
+ $this->_set_uri_string($this->$method());
}
-
- // No REQUEST_URI either?... What about QUERY_STRING?
- if (($uri = $this->_parse_query_string()) !== '')
+ else
{
+ $uri = isset($_SERVER[$protocol]) ? $_SERVER[$protocol] : @getenv($protocol);
$this->_set_uri_string($uri);
- return;
- }
-
- // As a last ditch effort let's try using the $_GET array
- if (is_array($_GET) && count($_GET) === 1 && trim(key($_GET), '/') !== '')
- {
- $this->_set_uri_string(key($_GET));
- return;
}
-
- // We've exhausted all our options...
- $this->uri_string = '';
- return;
}
- if ($protocol === 'CLI')
- {
- $this->_set_uri_string($this->_parse_argv());
- return;
- }
- elseif (method_exists($this, ($method = '_parse_'.strtolower($protocol))))
- {
- $this->_set_uri_string($this->$method());
- return;
- }
-
- $uri = isset($_SERVER[$protocol]) ? $_SERVER[$protocol] : @getenv($protocol);
- $this->_set_uri_string($uri);
+ log_message('debug', 'URI Class Initialized');
}
// --------------------------------------------------------------------
@@ -165,6 +142,35 @@ class CI_URI {
{
// Filter out control characters and trim slashes
$this->uri_string = trim(remove_invisible_characters($str, FALSE), '/');
+
+ if ($this->uri_string !== '')
+ {
+ // Remove the URL suffix, if present
+ if (($suffix = (string) $this->config->item('url_suffix')) !== '')
+ {
+ $slen = strlen($suffix);
+
+ if (substr($this->uri_string, -$slen) === $suffix)
+ {
+ $this->uri_string = substr($this->uri_string, 0, -$slen);
+ }
+ }
+
+ $this->segments[0] = NULL;
+ // Populate the segments array
+ foreach (explode('/', preg_replace('|/*(.+?)/*$|', '\\1', $this->uri_string)) as $val)
+ {
+ // Filter segments for security
+ $val = trim($this->filter_uri($val));
+
+ if ($val !== '')
+ {
+ $this->segments[] = $val;
+ }
+ }
+
+ unset($this->segments[0]);
+ }
}
// --------------------------------------------------------------------
@@ -225,36 +231,10 @@ class CI_URI {
// --------------------------------------------------------------------
/**
- * Remove relative directory (../) and multi slashes (///)
- *
- * Do some final cleaning of the URI and return it, currently only used in self::_parse_request_uri()
- *
- * @param string $url
- * @return string
- */
- protected function _remove_relative_directory($uri)
- {
- $uris = array();
- $tok = strtok($uri, '/');
- while ($tok !== FALSE)
- {
- if (( ! empty($tok) OR $tok === '0') && $tok !== '..')
- {
- $uris[] = $tok;
- }
- $tok = strtok('/');
- }
- return implode('/', $uris);
- }
-
- // --------------------------------------------------------------------
-
- /**
* Parse QUERY_STRING
*
* Will parse QUERY_STRING and automatically detect the URI from it.
*
- * @used-by CI_URI::_fetch_uri_string()
* @return string
*/
protected function _parse_query_string()
@@ -280,23 +260,6 @@ class CI_URI {
// --------------------------------------------------------------------
/**
- * Is CLI Request?
- *
- * Duplicate of method from the Input class to test to see if
- * a request was made from the command line.
- *
- * @see CI_Input::is_cli_request()
- * @used-by CI_URI::_fetch_uri_string()
- * @return bool
- */
- protected function _is_cli_request()
- {
- return (PHP_SAPI === 'cli') OR defined('STDIN');
- }
-
- // --------------------------------------------------------------------
-
- /**
* Parse CLI arguments
*
* Take each command line argument and assume it is a URI segment.
@@ -312,104 +275,52 @@ class CI_URI {
// --------------------------------------------------------------------
/**
- * Filter URI
+ * Remove relative directory (../) and multi slashes (///)
*
- * Filters segments for malicious characters.
+ * Do some final cleaning of the URI and return it, currently only used in self::_parse_request_uri()
*
- * @used-by CI_Router
- * @param string $str
+ * @param string $url
* @return string
*/
- public function _filter_uri($str)
+ protected function _remove_relative_directory($uri)
{
- if ($str !== '' && $this->config->item('permitted_uri_chars') != '' && $this->config->item('enable_query_strings') === FALSE)
+ $uris = array();
+ $tok = strtok($uri, '/');
+ while ($tok !== FALSE)
{
- // preg_quote() in PHP 5.3 escapes -, so the str_replace() and addition of - to preg_quote() is to maintain backwards
- // compatibility as many are unaware of how characters in the permitted_uri_chars will be parsed as a regex pattern
- if ( ! preg_match('|^['.str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-')).']+$|i', $str))
+ if (( ! empty($tok) OR $tok === '0') && $tok !== '..')
{
- show_error('The URI you submitted has disallowed characters.', 400);
+ $uris[] = $tok;
}
+ $tok = strtok('/');
}
- // Convert programatic characters to entities and return
- return str_replace(
- array('$', '(', ')', '%28', '%29'), // Bad
- array('&#36;', '&#40;', '&#41;', '&#40;', '&#41;'), // Good
- $str);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Remove URL suffix
- *
- * Removes the suffix from the URL if needed.
- *
- * @used-by CI_Router
- * @return void
- */
- public function _remove_url_suffix()
- {
- $suffix = (string) $this->config->item('url_suffix');
-
- if ($suffix === '')
- {
- return;
- }
-
- $slen = strlen($suffix);
-
- if (substr($this->uri_string, -$slen) === $suffix)
- {
- $this->uri_string = substr($this->uri_string, 0, -$slen);
- }
+ return implode('/', $uris);
}
// --------------------------------------------------------------------
/**
- * Explode URI segments
+ * Filter URI
*
- * The individual segments will be stored in the $this->segments array.
+ * Filters segments for malicious characters.
*
- * @see CI_URI::$segments
- * @used-by CI_Router
- * @return void
+ * @param string $str
+ * @return string
*/
- public function _explode_segments()
+ public function filter_uri($str)
{
- foreach (explode('/', preg_replace('|/*(.+?)/*$|', '\\1', $this->uri_string)) as $val)
+ if ( ! empty($str) && ! empty($this->_permitted_uri_chars) && ! preg_match('/^['.$this->_permitted_uri_chars.']+$/i'.(UTF8_ENABLED ? 'u' : ''), $str))
{
- // Filter segments for security
- $val = trim($this->_filter_uri($val));
-
- if ($val !== '')
- {
- $this->segments[] = $val;
- }
+ show_error('The URI you submitted has disallowed characters.', 400);
}
- }
- // --------------------------------------------------------------------
-
- /**
- * Re-index Segments
- *
- * Re-indexes the CI_URI::$segment array so that it starts at 1 rather
- * than 0. Doing so makes it simpler to use methods like
- * CI_URI::segment(n) since there is a 1:1 relationship between the
- * segment array and the actual segments.
- *
- * @used-by CI_Router
- * @return void
- */
- public function _reindex_segments()
- {
- array_unshift($this->segments, NULL);
- array_unshift($this->rsegments, NULL);
- unset($this->segments[0]);
- unset($this->rsegments[0]);
+ // Convert programatic characters to entities and return
+ return str_replace(
+ array('$', '(', ')', '%28', '%29'), // Bad
+ array('&#36;', '&#40;', '&#41;', '&#40;', '&#41;'), // Good
+ $str
+ );
}
// --------------------------------------------------------------------
@@ -720,12 +631,7 @@ class CI_URI {
{
global $RTR;
- if (($dir = $RTR->directory) === '/')
- {
- $dir = '';
- }
-
- return $dir.implode('/', $this->rsegment_array());
+ return ltrim($RTR->directory, '/').implode('/', $this->rsegments);
}
}
diff --git a/system/core/Utf8.php b/system/core/Utf8.php
index a78616d40..6ca1a02ca 100644
--- a/system/core/Utf8.php
+++ b/system/core/Utf8.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.0
@@ -48,28 +48,10 @@ class CI_Utf8 {
*/
public function __construct()
{
- log_message('debug', 'Utf8 Class Initialized');
-
- $charset = strtoupper(config_item('charset'));
-
- // set internal encoding for multibyte string functions if necessary
- // and set a flag so we don't have to repeatedly use extension_loaded()
- // or function_exists()
- if (extension_loaded('mbstring'))
- {
- define('MB_ENABLED', TRUE);
- mb_internal_encoding($charset);
- }
- else
- {
- define('MB_ENABLED', FALSE);
- }
-
if (
- @preg_match('/./u', 'é') === 1 // PCRE must support UTF-8
- && function_exists('iconv') // iconv must be installed
- && MB_ENABLED === TRUE // mbstring must be enabled
- && $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
+ && strnatcasecmp(config_item('charset'), 'UTF-8') === 0 // Application charset must be UTF-8
)
{
define('UTF8_ENABLED', TRUE);
@@ -80,6 +62,8 @@ class CI_Utf8 {
define('UTF8_ENABLED', FALSE);
log_message('debug', 'UTF-8 Support Disabled');
}
+
+ log_message('debug', 'Utf8 Class Initialized');
}
// --------------------------------------------------------------------
@@ -98,7 +82,14 @@ class CI_Utf8 {
{
if ($this->_is_ascii($str) === FALSE)
{
- $str = @iconv('UTF-8', 'UTF-8//IGNORE', $str);
+ if (ICONV_ENABLED)
+ {
+ $str = @iconv('UTF-8', 'UTF-8//IGNORE', $str);
+ }
+ elseif (MB_ENABLED)
+ {
+ $str = mb_convert_encoding($str, 'UTF-8', 'UTF-8');
+ }
}
return $str;
@@ -134,7 +125,7 @@ class CI_Utf8 {
*/
public function convert_to_utf8($str, $encoding)
{
- if (function_exists('iconv'))
+ if (ICONV_ENABLED)
{
return @iconv($encoding, 'UTF-8', $str);
}
diff --git a/system/core/compat/index.html b/system/core/compat/index.html
new file mode 100644
index 000000000..c942a79ce
--- /dev/null
+++ b/system/core/compat/index.html
@@ -0,0 +1,10 @@
+<html>
+<head>
+ <title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/system/core/compat/mbstring.php b/system/core/compat/mbstring.php
new file mode 100644
index 000000000..91ea8017c
--- /dev/null
+++ b/system/core/compat/mbstring.php
@@ -0,0 +1,141 @@
+<?php
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.2.4 or newer
+ *
+ * NOTICE OF LICENSE
+ *
+ * Licensed under the Open Software License version 3.0
+ *
+ * This source file is subject to the Open Software License (OSL 3.0) that is
+ * bundled with this package in the files license.txt / license.rst. It is
+ * also available through the world wide web at this URL:
+ * http://opensource.org/licenses/OSL-3.0
+ * If you did not receive a copy of the license and are unable to obtain it
+ * through the world wide web, please send an email to
+ * licensing@ellislab.com so we can send you a copy immediately.
+ *
+ * @package CodeIgniter
+ * @author EllisLab Dev Team
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
+ * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
+ * @link http://codeigniter.com
+ * @since Version 3.0
+ * @filesource
+ */
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/**
+ * PHP ext/mbstring compatibility package
+ *
+ * @package CodeIgniter
+ * @subpackage CodeIgniter
+ * @category Compatibility
+ * @author Andrey Andreev
+ * @link http://codeigniter.com/user_guide/
+ * @link http://php.net/mbstring
+ */
+
+// ------------------------------------------------------------------------
+
+if (MB_ENABLED === TRUE)
+{
+ return;
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('mb_strlen'))
+{
+ /**
+ * mb_strlen()
+ *
+ * WARNING: This function WILL fall-back to strlen()
+ * if iconv is not available!
+ *
+ * @link http://php.net/mb_strlen
+ * @param string $str
+ * @param string $encoding
+ * @return string
+ */
+ function mb_strlen($str, $encoding = NULL)
+ {
+ if (ICONV_ENABLED === TRUE)
+ {
+ return iconv_strlen($str, isset($charset) ? $charset : config_item('charset'));
+ }
+
+ log_message('debug', 'Compatibility (mbstring): iconv_strlen() is not available, falling back to strlen().');
+ return strlen($str);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('mb_strpos'))
+{
+ /**
+ * mb_strpos()
+ *
+ * WARNING: This function WILL fall-back to strpos()
+ * if iconv is not available!
+ *
+ * @link http://php.net/mb_strpos()
+ * @param string $haystack
+ * @param string $needle
+ * @param int $offset
+ * @param string $encoding
+ * @return mixed
+ */
+ function mb_strpos($haystack, $needle, $offset = 0, $encoding = NULL)
+ {
+ if (ICONV_ENABLED === TRUE)
+ {
+ return iconv_strpos($haystack, $needle, $offset, isset($encoding) ? $encoding : config_item('charset'));
+ }
+
+ log_message('debug', 'Compatibility (mbstring): iconv_strpos() is not available, falling back to strpos().');
+ return strpos($haystack, $needle, $offset);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('mb_substr'))
+{
+ /**
+ * mb_substr()
+ *
+ * WARNING: This function WILL fall-back to substr()
+ * if iconv is not available.
+ *
+ * @link http://php.net/mb_substr
+ * @param string $str
+ * @param int $start
+ * @param int $length
+ * @param string $encoding
+ * @return string
+ */
+ function mb_substr($str, $start, $length = NULL, $encoding = NULL)
+ {
+ if (ICONV_ENABLED === TRUE)
+ {
+ isset($encoding) OR $encoding = config_item('charset');
+ return iconv_substr(
+ $str,
+ $start,
+ isset($length) ? $length : iconv_strlen($str, $encoding), // NULL doesn't work
+ $encoding
+ );
+ }
+
+ log_message('debug', 'Compatibility (mbstring): iconv_substr() is not available, falling back to substr().');
+ return isset($length)
+ ? substr($str, $start, $length)
+ : substr($str, $start);
+ }
+}
+
+/* End of file mbstring.php */
+/* Location: ./system/core/compat/mbstring.php */ \ No newline at end of file
diff --git a/system/core/compat/password.php b/system/core/compat/password.php
new file mode 100644
index 000000000..92fdedb99
--- /dev/null
+++ b/system/core/compat/password.php
@@ -0,0 +1,216 @@
+<?php
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.2.4 or newer
+ *
+ * NOTICE OF LICENSE
+ *
+ * Licensed under the Open Software License version 3.0
+ *
+ * This source file is subject to the Open Software License (OSL 3.0) that is
+ * bundled with this package in the files license.txt / license.rst. It is
+ * also available through the world wide web at this URL:
+ * http://opensource.org/licenses/OSL-3.0
+ * If you did not receive a copy of the license and are unable to obtain it
+ * through the world wide web, please send an email to
+ * licensing@ellislab.com so we can send you a copy immediately.
+ *
+ * @package CodeIgniter
+ * @author EllisLab Dev Team
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
+ * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
+ * @link http://codeigniter.com
+ * @since Version 3.0
+ * @filesource
+ */
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/**
+ * PHP ext/standard/password compatibility package
+ *
+ * @package CodeIgniter
+ * @subpackage CodeIgniter
+ * @category Compatibility
+ * @author Andrey Andreev
+ * @link http://codeigniter.com/user_guide/
+ * @link http://php.net/password
+ */
+
+// ------------------------------------------------------------------------
+
+if (is_php('5.5') OR ! is_php('5.3.7') OR ! defined('CRYPT_BLOWFISH') OR CRYPT_BLOWFISH !== 1)
+{
+ return;
+}
+
+// ------------------------------------------------------------------------
+
+defined('PASSWORD_BCRYPT') OR define('PASSWORD_BCRYPT', 1);
+defined('PASSWORD_DEFAULT') OR define('PASSWORD_DEFAULT', PASSWORD_BCRYPT);
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('password_get_info'))
+{
+ /**
+ * password_get_info()
+ *
+ * @link http://php.net/password_get_info
+ * @param string $hash
+ * @return array
+ */
+ function password_get_info($hash)
+ {
+ return (strlen($hash) < 60 OR sscanf($hash, '$2y$%d', $hash) !== 1)
+ ? array('algo' => 0, 'algoName' => 'unknown', 'options' => array())
+ : array('algo' => 1, 'algoName' => 'bcrypt', 'options' => array('cost' => $hash));
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('password_hash'))
+{
+ /**
+ * password_hash()
+ *
+ * @link http://php.net/password_hash
+ * @param string $password
+ * @param int $algo
+ * @param array $options
+ * @return mixed
+ */
+ function password_hash($password, $algo, array $options = array())
+ {
+ if ($algo !== 1)
+ {
+ trigger_error('password_hash(): Unknown hashing algorithm: '.(int) $algo, E_USER_WARNING);
+ return NULL;
+ }
+
+ if (isset($options['cost']) && ($options['cost'] < 4 OR $options['cost'] > 31))
+ {
+ trigger_error('password_hash(): Invalid bcrypt cost parameter specified: '.(int) $options['cost'], E_USER_WARNING);
+ return NULL;
+ }
+
+ if (isset($options['salt']) && strlen($options['salt']) < 22)
+ {
+ trigger_error('password_hash(): Provided salt is too short: '.strlen($options['salt']).' expecting 22', E_USER_WARNING);
+ return NULL;
+ }
+ elseif ( ! isset($options['salt']))
+ {
+ if (defined('MCRYPT_DEV_URANDOM'))
+ {
+ $options['salt'] = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);
+ }
+ elseif (function_exists('openssl_random_pseudo_bytes'))
+ {
+ $options['salt'] = openssl_random_pseudo_bytes(16);
+ }
+ elseif (DIRECTORY_SEPARATOR === '/' && (is_readable($dev = '/dev/arandom') OR is_readable($dev = '/dev/urandom')))
+ {
+ if (($fp = fopen($dev, 'rb')) === FALSE)
+ {
+ log_message('error', 'compat/password: Unable to open '.$dev.' for reading.');
+ return FALSE;
+ }
+
+ $options['salt'] = '';
+ for ($read = 0; $read < 16; $read = strlen($options['salt']))
+ {
+ if (($read = fread($fp, 16 - $read)) === FALSE)
+ {
+ log_message('error', 'compat/password: Error while reading from '.$dev.'.');
+ return FALSE;
+ }
+ $options['salt'] .= $read;
+ }
+
+ fclose($fp);
+ }
+ else
+ {
+ log_message('error', 'compat/password: No CSPRNG available.');
+ return FALSE;
+ }
+
+ $options['salt'] = str_replace('+', '.', rtrim(base64_encode($options['salt']), '='));
+ }
+ elseif ( ! preg_match('#^[a-zA-Z0-9./]+$#D', $options['salt']))
+ {
+ $options['salt'] = str_replace('+', '.', rtrim(base64_encode($options['salt']), '='));
+ }
+
+ isset($options['cost']) OR $options['cost'] = 10;
+ return crypt($password, sprintf('$2y$%02d$%s', $options['cost'], $options['salt']));
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('password_needs_rehash'))
+{
+ /**
+ * password_needs_rehash()
+ *
+ * @link http://php.net/password_needs_rehash
+ * @param string $hash
+ * @param int $algo
+ * @param array $options
+ * @return bool
+ */
+ function password_needs_rehash($hash, $algo, array $options = array())
+ {
+ $info = password_get_info($hash);
+
+ if ($algo !== $info['algo'])
+ {
+ return TRUE;
+ }
+ elseif ($algo === 1)
+ {
+ $options['cost'] = isset($options['cost']) ? (int) $options['cost'] : 10;
+ return ($info['options']['cost'] !== $options['cost']);
+ }
+
+ // Odd at first glance, but according to a comment in PHP's own unit tests,
+ // because it is an unknown algorithm - it's valid and therefore doesn't
+ // need rehashing.
+ return FALSE;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('password_verify'))
+{
+ /**
+ * password_verify()
+ *
+ * @link http://php.net/password_verify
+ * @param string $password
+ * @param string $hash
+ * @return bool
+ */
+ function password_verify($password, $hash)
+ {
+ if (strlen($hash) !== 60 OR strlen($password = crypt($password, $hash)) !== 60)
+ {
+ return FALSE;
+ }
+
+ $compare = 0;
+ for ($i = 0; $i < 60; $i++)
+ {
+ $compare |= (ord($password[$i]) ^ ord($hash[$i]));
+ }
+
+ return ($compare === 0);
+ }
+}
+
+/* End of file password.php */
+/* Location: ./system/core/compat/password.php */ \ No newline at end of file
diff --git a/system/database/DB.php b/system/database/DB.php
index 8742800c8..7e6cd7466 100644
--- a/system/database/DB.php
+++ b/system/database/DB.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -206,11 +206,6 @@ function &DB($params = '', $query_builder_override = NULL)
$DB->initialize();
}
- if ( ! empty($params['stricton']))
- {
- $DB->query('SET SESSION sql_mode="STRICT_ALL_TABLES"');
- }
-
return $DB;
}
diff --git a/system/database/DB_cache.php b/system/database/DB_cache.php
index 921e68655..0ef0ae52f 100644
--- a/system/database/DB_cache.php
+++ b/system/database/DB_cache.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index 53decf014..aeeb2d0f3 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -624,7 +624,14 @@ abstract class CI_DB_driver {
// if transactions are enabled. If we don't call this here
// the error message will trigger an exit, causing the
// transactions to remain in limbo.
- $this->_trans_depth > 0 && $this->trans_complete();
+ if ($this->_trans_depth !== 0)
+ {
+ do
+ {
+ $this->trans_complete();
+ }
+ while ($this->_trans_depth !== 0);
+ }
// Display errors
return $this->display_error(array('Error Number: '.$error['code'], $error['message'], $sql));
@@ -917,7 +924,7 @@ abstract class CI_DB_driver {
*/
public function is_write_type($sql)
{
- return (bool) preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s+/i', $sql);
+ return (bool) preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s/i', $sql);
}
// --------------------------------------------------------------------
@@ -1135,7 +1142,7 @@ abstract class CI_DB_driver {
else
{
/* We have no other choice but to just get the first element's key.
- * Due to array_shift() accepting it's argument by reference, if
+ * Due to array_shift() accepting its argument by reference, if
* E_STRICT is on, this would trigger a warning. So we'll have to
* assign it first.
*/
@@ -1414,7 +1421,7 @@ abstract class CI_DB_driver {
*/
protected function _has_operator($str)
{
- return (bool) preg_match('/(<|>|!|=|\sIS NULL|\sIS NOT NULL|\sBETWEEN|\sLIKE|\sIN\s*\(|\s)/i', trim($str));
+ return (bool) preg_match('/(<|>|!|=|\sIS NULL|\sIS NOT NULL|\sEXISTS|\sBETWEEN|\sLIKE|\sIN\s*\(|\s)/i', trim($str));
}
// --------------------------------------------------------------------
@@ -1440,6 +1447,8 @@ abstract class CI_DB_driver {
'\s*>\s*', // >
'\s+IS NULL', // IS NULL
'\s+IS NOT NULL', // IS NOT NULL
+ '\s+EXISTS\s*\([^\)]+\)', // EXISTS(sql)
+ '\s+NOT EXISTS\s*\([^\)]+\)', // NOT EXISTS(sql)
'\s+BETWEEN\s+\S+\s+AND\s+\S+', // BETWEEN value AND value
'\s+IN\s*\([^\)]+\)', // IN(list)
'\s+NOT IN\s*\([^\)]+\)', // NOT IN (list)
@@ -1476,7 +1485,7 @@ abstract class CI_DB_driver {
}
return (func_num_args() > 1)
- ? call_user_func_array($function, array_splice(func_get_args(), 1))
+ ? call_user_func_array($function, array_slice(func_get_args(), 1))
: call_user_func($function);
}
diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php
index d52029ecd..4eeb74a9c 100644
--- a/system/database/DB_forge.php
+++ b/system/database/DB_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -314,9 +314,10 @@ abstract class CI_DB_forge {
*
* @param string $table Table name
* @param bool $if_not_exists Whether to add IF NOT EXISTS condition
+ * @param array $attributes Associative array of table attributes
* @return bool
*/
- public function create_table($table = '', $if_not_exists = FALSE)
+ public function create_table($table = '', $if_not_exists = FALSE, array $attributes = array())
{
if ($table === '')
{
@@ -332,7 +333,7 @@ abstract class CI_DB_forge {
show_error('Field information is required.');
}
- $sql = $this->_create_table($table, $if_not_exists);
+ $sql = $this->_create_table($table, $if_not_exists, $attributes);
if (is_bool($sql))
{
@@ -368,9 +369,10 @@ abstract class CI_DB_forge {
*
* @param string $table Table name
* @param bool $if_not_exists Whether to add 'IF NOT EXISTS' condition
+ * @param array $attributes Associative array of table attributes
* @return mixed
*/
- protected function _create_table($table, $if_not_exists)
+ protected function _create_table($table, $if_not_exists, $attributes)
{
if ($if_not_exists === TRUE && $this->_create_table_if === FALSE)
{
@@ -406,10 +408,11 @@ abstract class CI_DB_forge {
}
// _create_table will usually have the following format: "%s %s (%s\n)"
- $sql = sprintf($this->_create_table.';',
+ $sql = sprintf($this->_create_table.'%s;',
$sql,
$this->db->escape_identifiers($table),
- $columns
+ $columns,
+ $this->_create_table_attr($attributes)
);
return $sql;
@@ -418,6 +421,29 @@ abstract class CI_DB_forge {
// --------------------------------------------------------------------
/**
+ * CREATE TABLE attributes
+ *
+ * @param array $attributes Associative array of table attributes
+ * @return string
+ */
+ protected function _create_table_attr($attributes)
+ {
+ $sql = '';
+
+ foreach (array_keys($attributes) as $key)
+ {
+ if (is_string($key))
+ {
+ $sql .= ' '.strtoupper($key).' '.$attributes[$key];
+ }
+ }
+
+ return $sql;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* Drop Table
*
* @param string $table_name Table name
@@ -740,6 +766,18 @@ abstract class CI_DB_forge {
'_literal' => FALSE
);
+ if ($create_table === FALSE)
+ {
+ if (isset($attributes['AFTER']))
+ {
+ $field['after'] = $attributes['AFTER'];
+ }
+ elseif (isset($attributes['FIRST']))
+ {
+ $field['first'] = (bool) $attributes['FIRST'];
+ }
+ }
+
$this->_attr_default($attributes, $field);
if (isset($attributes['NULL']))
@@ -748,11 +786,15 @@ abstract class CI_DB_forge {
{
$field['null'] = empty($this->_null) ? '' : ' '.$this->_null;
}
- elseif ($create_table === TRUE)
+ else
{
$field['null'] = ' NOT NULL';
}
}
+ elseif ($create_table === TRUE)
+ {
+ $field['null'] = ' NOT NULL';
+ }
$this->_attr_auto_increment($attributes, $field);
$this->_attr_unique($attributes, $field);
@@ -968,7 +1010,6 @@ abstract class CI_DB_forge {
*/
protected function _process_indexes($table)
{
- $table = $this->db->escape_identifiers($table);
$sqls = array();
for ($i = 0, $c = count($this->keys); $i < $c; $i++)
@@ -992,7 +1033,7 @@ abstract class CI_DB_forge {
is_array($this->keys[$i]) OR $this->keys[$i] = array($this->keys[$i]);
- $sqls[] = 'CREATE INDEX '.$this->db->escape_identifiers(implode('_', $this->keys[$i]))
+ $sqls[] = 'CREATE INDEX '.$this->db->escape_identifiers($table.'_'.implode('_', $this->keys[$i]))
.' ON '.$this->db->escape_identifiers($table)
.' ('.implode(', ', $this->db->escape_identifiers($this->keys[$i])).');';
}
diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php
index a36501eb6..085c615e5 100644
--- a/system/database/DB_query_builder.php
+++ b/system/database/DB_query_builder.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -263,7 +263,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$select = explode(',', $select);
}
- // If the escape value was not set will will base it on the global setting
+ // If the escape value was not set, we will base it on the global setting
is_bool($escape) OR $escape = $this->_protect_identifiers;
foreach ($select as $val)
@@ -1338,7 +1338,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* returned by an Query Builder query.
*
* @param string
- * @return string
+ * @return int
*/
public function count_all_results($table = '')
{
@@ -2291,7 +2291,12 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
{
for ($i = 0, $c = count($this->$qb_key); $i < $c; $i++)
{
- if ($this->{$qb_key}[$i]['escape'] === FALSE)
+ // Is this condition already compiled?
+ if (is_string($this->{$qb_key}[$i]))
+ {
+ continue;
+ }
+ elseif ($this->{$qb_key}[$i]['escape'] === FALSE)
{
$this->{$qb_key}[$i] = $this->{$qb_key}[$i]['condition'];
continue;
@@ -2361,6 +2366,12 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
{
for ($i = 0, $c = count($this->qb_groupby); $i < $c; $i++)
{
+ // Is it already compiled?
+ if (is_string($this->qb_groupby[$i]))
+ {
+ continue;
+ }
+
$this->qb_groupby[$i] = ($this->qb_groupby[$i]['escape'] === FALSE OR $this->_is_literal($this->qb_groupby[$i]['field']))
? $this->qb_groupby[$i]['field']
: $this->protect_identifiers($this->qb_groupby[$i]['field']);
@@ -2545,17 +2556,34 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
{
return;
}
+ elseif (in_array('select', $this->qb_cache_exists, TRUE))
+ {
+ $qb_no_escape = $this->qb_cache_no_escape;
+ }
- foreach ($this->qb_cache_exists as $val)
+ foreach (array_unique($this->qb_cache_exists) as $val) // select, from, etc.
{
$qb_variable = 'qb_'.$val;
$qb_cache_var = 'qb_cache_'.$val;
+ $qb_new = $this->$qb_cache_var;
- if (count($this->$qb_cache_var) === 0)
+ for ($i = 0, $c = count($this->$qb_variable); $i < $c; $i++)
{
- continue;
+ if ( ! in_array($this->{$qb_variable}[$i], $qb_new, TRUE))
+ {
+ $qb_new[] = $this->{$qb_variable}[$i];
+ if ($val === 'select')
+ {
+ $qb_no_escape[] = $this->qb_no_escape[$i];
+ }
+ }
+ }
+
+ $this->$qb_variable = $qb_new;
+ if ($val === 'select')
+ {
+ $this->qb_no_escape = $qb_no_escape;
}
- $this->$qb_variable = array_merge($this->$qb_variable, array_diff($this->$qb_cache_var, $this->$qb_variable));
}
// If we are "protecting identifiers" we need to examine the "from"
@@ -2564,8 +2592,6 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
{
$this->_track_aliases($this->qb_from);
}
-
- $this->qb_no_escape = array_merge($this->qb_no_escape, array_diff($this->qb_cache_no_escape, $this->qb_no_escape));
}
// --------------------------------------------------------------------
diff --git a/system/database/DB_result.php b/system/database/DB_result.php
index 41a851777..6aa4e92b6 100644
--- a/system/database/DB_result.php
+++ b/system/database/DB_result.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/DB_utility.php b/system/database/DB_utility.php
index 9f953d4ac..11c5e116b 100644
--- a/system/database/DB_utility.php
+++ b/system/database/DB_utility.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -282,8 +282,7 @@ abstract class CI_DB_utility {
extract($params);
// Load the xml helper
- $CI =& get_instance();
- $CI->load->helper('xml');
+ get_instance()->load->helper('xml');
// Generate the result
$xml = '<'.$root.'>'.$newline;
diff --git a/system/database/drivers/cubrid/cubrid_driver.php b/system/database/drivers/cubrid/cubrid_driver.php
index 51bbbdb47..0db51735c 100644
--- a/system/database/drivers/cubrid/cubrid_driver.php
+++ b/system/database/drivers/cubrid/cubrid_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.1
diff --git a/system/database/drivers/cubrid/cubrid_forge.php b/system/database/drivers/cubrid/cubrid_forge.php
index 554f31ec7..807dd6d02 100644
--- a/system/database/drivers/cubrid/cubrid_forge.php
+++ b/system/database/drivers/cubrid/cubrid_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.1
diff --git a/system/database/drivers/cubrid/cubrid_result.php b/system/database/drivers/cubrid/cubrid_result.php
index 67d5beda5..76a479a18 100644
--- a/system/database/drivers/cubrid/cubrid_result.php
+++ b/system/database/drivers/cubrid/cubrid_result.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.1
diff --git a/system/database/drivers/cubrid/cubrid_utility.php b/system/database/drivers/cubrid/cubrid_utility.php
index 472b7b042..54e6b4a01 100644
--- a/system/database/drivers/cubrid/cubrid_utility.php
+++ b/system/database/drivers/cubrid/cubrid_utility.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.1
diff --git a/system/database/drivers/ibase/ibase_driver.php b/system/database/drivers/ibase/ibase_driver.php
index 745011056..4cff5f448 100644
--- a/system/database/drivers/ibase/ibase_driver.php
+++ b/system/database/drivers/ibase/ibase_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 3.0
diff --git a/system/database/drivers/ibase/ibase_forge.php b/system/database/drivers/ibase/ibase_forge.php
index e3f714688..19ac86c37 100644
--- a/system/database/drivers/ibase/ibase_forge.php
+++ b/system/database/drivers/ibase/ibase_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 3.0
diff --git a/system/database/drivers/ibase/ibase_result.php b/system/database/drivers/ibase/ibase_result.php
index 1ab1e2ada..1f89db65d 100644
--- a/system/database/drivers/ibase/ibase_result.php
+++ b/system/database/drivers/ibase/ibase_result.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/ibase/ibase_utility.php b/system/database/drivers/ibase/ibase_utility.php
index 4f9b1d19e..a17b19ea8 100644
--- a/system/database/drivers/ibase/ibase_utility.php
+++ b/system/database/drivers/ibase/ibase_utility.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 3.0
diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php
index 0836fa802..655aa7148 100644
--- a/system/database/drivers/mssql/mssql_driver.php
+++ b/system/database/drivers/mssql/mssql_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -311,7 +311,7 @@ class CI_DB_mssql_driver extends CI_DB {
.' FROM '.$this->escape_identifiers('sysobjects')
.' WHERE '.$this->escape_identifiers('type')." = 'U'";
- if ($prefix_limit !== FALSE AND $this->dbprefix !== '')
+ if ($prefix_limit !== FALSE && $this->dbprefix !== '')
{
$sql .= ' AND '.$this->escape_identifiers('name')." LIKE '".$this->escape_like_str($this->dbprefix)."%' "
.sprintf($this->_like_escape_str, $this->_like_escape_chr);
diff --git a/system/database/drivers/mssql/mssql_forge.php b/system/database/drivers/mssql/mssql_forge.php
index c03db5773..eeb01ba68 100644
--- a/system/database/drivers/mssql/mssql_forge.php
+++ b/system/database/drivers/mssql/mssql_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/mssql/mssql_result.php b/system/database/drivers/mssql/mssql_result.php
index b6e5f2b17..cce93740f 100644
--- a/system/database/drivers/mssql/mssql_result.php
+++ b/system/database/drivers/mssql/mssql_result.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/mssql/mssql_utility.php b/system/database/drivers/mssql/mssql_utility.php
index 5007e88b8..97212bd6c 100644
--- a/system/database/drivers/mssql/mssql_utility.php
+++ b/system/database/drivers/mssql/mssql_utility.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php
index b94642b35..499d42691 100644
--- a/system/database/drivers/mysql/mysql_driver.php
+++ b/system/database/drivers/mysql/mysql_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -66,6 +66,15 @@ class CI_DB_mysql_driver extends CI_DB {
*/
public $delete_hack = TRUE;
+ /**
+ * Strict ON flag
+ *
+ * Whether we're running in strict SQL mode.
+ *
+ * @var bool
+ */
+ public $stricton = FALSE;
+
// --------------------------------------------------------------------
/**
@@ -126,6 +135,11 @@ class CI_DB_mysql_driver extends CI_DB {
: FALSE;
}
+ if ($this->stricton && is_resource($this->conn_id))
+ {
+ $this->simple_query('SET SESSION sql_mode="STRICT_ALL_TABLES"');
+ }
+
return $this->conn_id;
}
diff --git a/system/database/drivers/mysql/mysql_forge.php b/system/database/drivers/mysql/mysql_forge.php
index e251c0ea6..cc886e8ac 100644
--- a/system/database/drivers/mysql/mysql_forge.php
+++ b/system/database/drivers/mysql/mysql_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -82,16 +82,34 @@ class CI_DB_mysql_forge extends CI_DB_forge {
// --------------------------------------------------------------------
/**
- * Class constructor
+ * CREATE TABLE attributes
*
- * @param object &$db Database object
- * @return void
+ * @param array $attributes Associative array of table attributes
+ * @return string
*/
- public function __construct(&$db)
+ protected function _create_table_attr($attributes)
{
- parent::__construct($db);
+ $sql = '';
+
+ foreach (array_keys($attributes) as $key)
+ {
+ if (is_string($key))
+ {
+ $sql .= ' '.strtoupper($key).' = '.$attributes[$key];
+ }
+ }
- $this->_create_table .= ' DEFAULT CHARSET '.$this->db->char_set.' COLLATE '.$this->db->dbcollat;
+ if ( ! empty($this->db->char_set) && ! strpos($sql, 'CHARACTER SET') && ! strpos($sql, 'CHARSET'))
+ {
+ $sql .= ' DEFAULT CHARACTER SET = '.$this->db->char_set;
+ }
+
+ if ( ! empty($this->db->dbcollat) && ! strpos($sql, 'COLLATE'))
+ {
+ $sql .= ' COLLATE = '.$this->db->dbcollat;
+ }
+
+ return $sql;
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/mysql/mysql_result.php b/system/database/drivers/mysql/mysql_result.php
index a2affcb58..c232b5c90 100644
--- a/system/database/drivers/mysql/mysql_result.php
+++ b/system/database/drivers/mysql/mysql_result.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/mysql/mysql_utility.php b/system/database/drivers/mysql/mysql_utility.php
index ea8702708..91de8710e 100644
--- a/system/database/drivers/mysql/mysql_utility.php
+++ b/system/database/drivers/mysql/mysql_utility.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php
index 0f3c6fc62..083b0c621 100644
--- a/system/database/drivers/mysqli/mysqli_driver.php
+++ b/system/database/drivers/mysqli/mysqli_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -66,6 +66,15 @@ class CI_DB_mysqli_driver extends CI_DB {
*/
public $delete_hack = TRUE;
+ /**
+ * Strict ON flag
+ *
+ * Whether we're running in strict SQL mode.
+ *
+ * @var bool
+ */
+ public $stricton = FALSE;
+
// --------------------------------------------------------------------
/**
@@ -93,6 +102,11 @@ class CI_DB_mysqli_driver extends CI_DB {
$client_flags = ($this->compress === TRUE) ? MYSQLI_CLIENT_COMPRESS : 0;
$mysqli = mysqli_init();
+ if ($this->stricton)
+ {
+ $mysqli->options(MYSQLI_INIT_COMMAND, 'SET SESSION sql_mode="STRICT_ALL_TABLES"');
+ }
+
return @$mysqli->real_connect($hostname, $this->username, $this->password, $this->database, $port, NULL, $client_flags)
? $mysqli : FALSE;
}
diff --git a/system/database/drivers/mysqli/mysqli_forge.php b/system/database/drivers/mysqli/mysqli_forge.php
index d1e5e20ff..3a19405d2 100644
--- a/system/database/drivers/mysqli/mysqli_forge.php
+++ b/system/database/drivers/mysqli/mysqli_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -82,16 +82,34 @@ class CI_DB_mysqli_forge extends CI_DB_forge {
// --------------------------------------------------------------------
/**
- * Class constructor
+ * CREATE TABLE attributes
*
- * @param object &$db Database object
- * @return void
+ * @param array $attributes Associative array of table attributes
+ * @return string
*/
- public function __construct(&$db)
+ protected function _create_table_attr($attributes)
{
- parent::__construct($db);
+ $sql = '';
+
+ foreach (array_keys($attributes) as $key)
+ {
+ if (is_string($key))
+ {
+ $sql .= ' '.strtoupper($key).' = '.$attributes[$key];
+ }
+ }
- $this->_create_table .= ' DEFAULT CHARSET '.$this->db->char_set.' COLLATE '.$this->db->dbcollat;
+ if ( ! empty($this->db->char_set) && ! strpos($sql, 'CHARACTER SET') && ! strpos($sql, 'CHARSET'))
+ {
+ $sql .= ' DEFAULT CHARACTER SET = '.$this->db->char_set;
+ }
+
+ if ( ! empty($this->db->dbcollat) && ! strpos($sql, 'COLLATE'))
+ {
+ $sql .= ' COLLATE = '.$this->db->dbcollat;
+ }
+
+ return $sql;
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/mysqli/mysqli_result.php b/system/database/drivers/mysqli/mysqli_result.php
index 3fe05f9c5..7f5792ae5 100644
--- a/system/database/drivers/mysqli/mysqli_result.php
+++ b/system/database/drivers/mysqli/mysqli_result.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/mysqli/mysqli_utility.php b/system/database/drivers/mysqli/mysqli_utility.php
index ef113e5e2..1c9475761 100644
--- a/system/database/drivers/mysqli/mysqli_utility.php
+++ b/system/database/drivers/mysqli/mysqli_utility.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php
index 020a3a4ba..f309a8272 100644
--- a/system/database/drivers/oci8/oci8_driver.php
+++ b/system/database/drivers/oci8/oci8_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -344,7 +344,7 @@ class CI_DB_oci8_driver extends CI_DB {
$have_cursor = TRUE;
}
}
- $sql = trim($sql, ',') . '); END;';
+ $sql = trim($sql, ',').'); END;';
$this->stmt_id = FALSE;
$this->_set_stmt_id($sql);
diff --git a/system/database/drivers/oci8/oci8_forge.php b/system/database/drivers/oci8/oci8_forge.php
index 341f9dd3b..d63846f55 100644
--- a/system/database/drivers/oci8/oci8_forge.php
+++ b/system/database/drivers/oci8/oci8_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/oci8/oci8_result.php b/system/database/drivers/oci8/oci8_result.php
index ce09b62bc..177646273 100644
--- a/system/database/drivers/oci8/oci8_result.php
+++ b/system/database/drivers/oci8/oci8_result.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/oci8/oci8_utility.php b/system/database/drivers/oci8/oci8_utility.php
index 70b8bdb86..856125b17 100644
--- a/system/database/drivers/oci8/oci8_utility.php
+++ b/system/database/drivers/oci8/oci8_utility.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/odbc/odbc_driver.php b/system/database/drivers/odbc/odbc_driver.php
index 45e91cbc5..662a1063a 100644
--- a/system/database/drivers/odbc/odbc_driver.php
+++ b/system/database/drivers/odbc/odbc_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -222,7 +222,7 @@ class CI_DB_odbc_driver extends CI_DB {
*/
public function affected_rows()
{
- return @odbc_num_rows($this->conn_id);
+ return @odbc_num_rows($this->result_id);
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/odbc/odbc_forge.php b/system/database/drivers/odbc/odbc_forge.php
index 2a477a5b6..dbf9949c9 100644
--- a/system/database/drivers/odbc/odbc_forge.php
+++ b/system/database/drivers/odbc/odbc_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/odbc/odbc_result.php b/system/database/drivers/odbc/odbc_result.php
index 474143e41..5b2df3943 100644
--- a/system/database/drivers/odbc/odbc_result.php
+++ b/system/database/drivers/odbc/odbc_result.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/odbc/odbc_utility.php b/system/database/drivers/odbc/odbc_utility.php
index a012c4ef9..00b6186db 100644
--- a/system/database/drivers/odbc/odbc_utility.php
+++ b/system/database/drivers/odbc/odbc_utility.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/pdo/pdo_driver.php b/system/database/drivers/pdo/pdo_driver.php
index 184a8df33..49612b972 100644
--- a/system/database/drivers/pdo/pdo_driver.php
+++ b/system/database/drivers/pdo/pdo_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.1.0
@@ -92,7 +92,7 @@ class CI_DB_pdo_driver extends CI_DB {
{
$this->subdriver = '4d';
}
- elseif ( ! in_array($this->subdriver, array('4d', 'cubrid', 'dblib', 'firebird', 'ibm', 'informix', 'mysql', 'oci', 'odbc', 'sqlite', 'sqlsrv'), TRUE))
+ elseif ( ! in_array($this->subdriver, array('4d', 'cubrid', 'dblib', 'firebird', 'ibm', 'informix', 'mysql', 'oci', 'odbc', 'pgsql', 'sqlite', 'sqlsrv'), TRUE))
{
log_message('error', 'PDO: Invalid or non-existent subdriver');
@@ -117,7 +117,6 @@ class CI_DB_pdo_driver extends CI_DB {
{
$this->options[PDO::ATTR_PERSISTENT] = $persistent;
- // Connecting...
try
{
return @new PDO($this->dsn, $this->username, $this->password, $this->options);
diff --git a/system/database/drivers/pdo/pdo_forge.php b/system/database/drivers/pdo/pdo_forge.php
index ccd39ca97..4bc854692 100644
--- a/system/database/drivers/pdo/pdo_forge.php
+++ b/system/database/drivers/pdo/pdo_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.1.0
diff --git a/system/database/drivers/pdo/pdo_result.php b/system/database/drivers/pdo/pdo_result.php
index 761348eb2..904bdd5b3 100644
--- a/system/database/drivers/pdo/pdo_result.php
+++ b/system/database/drivers/pdo/pdo_result.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/pdo/pdo_utility.php b/system/database/drivers/pdo/pdo_utility.php
index bd78cd8b4..f3c8e2dc4 100644
--- a/system/database/drivers/pdo/pdo_utility.php
+++ b/system/database/drivers/pdo/pdo_utility.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.1.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php b/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php
index e94c0bfff..590a33275 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 3.0.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php b/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php
index c49549961..97255ed78 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.1.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php b/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php
index 1dbd385e5..d2d1fd57e 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 3.0.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php b/system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php
index 1ee17035d..ed93d24ca 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.1.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php b/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php
index 95203e236..379fc0794 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 3.0.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php b/system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php
index 516b6f2c5..271c00dbf 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.1.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php b/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php
index abb3d4511..cbee19e8c 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 3.0.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php b/system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php
index a43397378..d754c2782 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.1.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php b/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php
index 5670da75f..030fae036 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 3.0.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php b/system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php
index ed7f4cc97..fc3579fe2 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.1.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php b/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php
index c126b5b52..f28cce1d9 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 3.0.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_informix_forge.php b/system/database/drivers/pdo/subdrivers/pdo_informix_forge.php
index fca8c22a7..a2d0bdda8 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_informix_forge.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_informix_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.1.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php b/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php
index ff486fc5a..70c405c78 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 3.0.0
@@ -55,6 +55,15 @@ class CI_DB_pdo_mysql_driver extends CI_DB_pdo_driver {
*/
public $compress = FALSE;
+ /**
+ * Strict ON flag
+ *
+ * Whether we're running in strict SQL mode.
+ *
+ * @var bool
+ */
+ public $stricton = FALSE;
+
// --------------------------------------------------------------------
/**
@@ -114,6 +123,18 @@ class CI_DB_pdo_mysql_driver extends CI_DB_pdo_driver {
.(empty($this->dbcollat) ? '' : ' COLLATE '.$this->dbcollat);
}
+ if ($this->stricton)
+ {
+ if (empty($this->options[PDO::MYSQL_ATTR_INIT_COMMAND]))
+ {
+ $this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET SESSION sql_mode="STRICT_ALL_TABLES"';
+ }
+ else
+ {
+ $this->options[PDO::MYSQL_ATTR_INIT_COMMAND] .= ', @@session.sql_mode = "STRICT_ALL_TABLES"';
+ }
+ }
+
if ($this->compress === TRUE)
{
$this->options[PDO::MYSQL_ATTR_COMPRESS] = TRUE;
diff --git a/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php b/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php
index 74689d91e..d2e1e2828 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.1.0
@@ -96,16 +96,34 @@ class CI_DB_pdo_mysql_forge extends CI_DB_pdo_forge {
// --------------------------------------------------------------------
/**
- * Class constructor
+ * CREATE TABLE attributes
*
- * @param object &$db Database object
- * @return void
+ * @param array $attributes Associative array of table attributes
+ * @return string
*/
- public function __construct(&$db)
+ protected function _create_table_attr($attributes)
{
- parent::__construct($db);
+ $sql = '';
+
+ foreach (array_keys($attributes) as $key)
+ {
+ if (is_string($key))
+ {
+ $sql .= ' '.strtoupper($key).' = '.$attributes[$key];
+ }
+ }
- $this->_create_table .= ' DEFAULT CHARSET '.$this->db->char_set.' COLLATE '.$this->db->dbcollat;
+ if ( ! empty($this->db->char_set) && ! strpos($sql, 'CHARACTER SET') && ! strpos($sql, 'CHARSET'))
+ {
+ $sql .= ' DEFAULT CHARACTER SET = '.$this->db->char_set;
+ }
+
+ if ( ! empty($this->db->dbcollat) && ! strpos($sql, 'COLLATE'))
+ {
+ $sql .= ' COLLATE = '.$this->db->dbcollat;
+ }
+
+ return $sql;
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php b/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php
index 4b3053c3c..6fef078c5 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 3.0.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php b/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php
index 4ace1bc4e..dbbff5b2d 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.1.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php b/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php
index 773180ee2..c95fe18d8 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 3.0.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_odbc_forge.php b/system/database/drivers/pdo/subdrivers/pdo_odbc_forge.php
index 3d00c8831..e7feacd0c 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_odbc_forge.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_odbc_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.1.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php b/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php
index fda3f238b..0e25bc5b4 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 3.0.0
@@ -84,6 +84,12 @@ class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver {
empty($this->port) OR $this->dsn .= ';port='.$this->port;
empty($this->database) OR $this->dsn .= ';dbname='.$this->database;
+
+ if ( ! empty($this->username))
+ {
+ $this->dsn .= ';username='.$this->username;
+ empty($this->password) OR $this->dsn .= ';password='.$this->password;
+ }
}
}
@@ -137,7 +143,7 @@ class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver {
*/
public function is_write_type($sql)
{
- return (bool) preg_match('/^\s*"?(SET|INSERT(?![^\)]+\)\s+RETURNING)|UPDATE(?!.*\sRETURNING)|DELETE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s+/i', str_replace(array("\r\n", "\r", "\n"), ' ', $sql));
+ return (bool) preg_match('/^\s*"?(SET|INSERT(?![^\)]+\)\s+RETURNING)|UPDATE(?!.*\sRETURNING)|DELETE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s/i', str_replace(array("\r\n", "\r", "\n"), ' ', $sql));
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php b/system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php
index 630cd527d..cdaa20265 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.1.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php b/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php
index 6cad6797c..a91f00bc9 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 3.0.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php b/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php
index b451d056a..b43e3238d 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.1.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php
index 722e22636..ba004d5d8 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 3.0.0
diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php
index dbaff7762..3a903c723 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.1.0
diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php
index b72fb873a..7d17f799e 100644
--- a/system/database/drivers/postgre/postgre_driver.php
+++ b/system/database/drivers/postgre/postgre_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -318,7 +318,7 @@ class CI_DB_postgre_driver extends CI_DB {
*/
public function is_write_type($sql)
{
- return (bool) preg_match('/^\s*"?(SET|INSERT(?![^\)]+\)\s+RETURNING)|UPDATE(?!.*\sRETURNING)|DELETE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s+/i', str_replace(array("\r\n", "\r", "\n"), ' ', $sql));
+ return (bool) preg_match('/^\s*"?(SET|INSERT(?![^\)]+\)\s+RETURNING)|UPDATE(?!.*\sRETURNING)|DELETE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s/i', str_replace(array("\r\n", "\r", "\n"), ' ', $sql));
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/postgre/postgre_forge.php b/system/database/drivers/postgre/postgre_forge.php
index 97b82776d..8bfb66c43 100644
--- a/system/database/drivers/postgre/postgre_forge.php
+++ b/system/database/drivers/postgre/postgre_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/postgre/postgre_result.php b/system/database/drivers/postgre/postgre_result.php
index 592078171..ec484e940 100644
--- a/system/database/drivers/postgre/postgre_result.php
+++ b/system/database/drivers/postgre/postgre_result.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/postgre/postgre_utility.php b/system/database/drivers/postgre/postgre_utility.php
index a082e33b8..fe7e3b682 100644
--- a/system/database/drivers/postgre/postgre_utility.php
+++ b/system/database/drivers/postgre/postgre_utility.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/sqlite/sqlite_driver.php b/system/database/drivers/sqlite/sqlite_driver.php
index 6a3397f6f..9928aedb7 100644
--- a/system/database/drivers/sqlite/sqlite_driver.php
+++ b/system/database/drivers/sqlite/sqlite_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/sqlite/sqlite_forge.php b/system/database/drivers/sqlite/sqlite_forge.php
index 1823227db..f80b5e71b 100644
--- a/system/database/drivers/sqlite/sqlite_forge.php
+++ b/system/database/drivers/sqlite/sqlite_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/sqlite/sqlite_result.php b/system/database/drivers/sqlite/sqlite_result.php
index b73105486..8279c315d 100644
--- a/system/database/drivers/sqlite/sqlite_result.php
+++ b/system/database/drivers/sqlite/sqlite_result.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/sqlite/sqlite_utility.php b/system/database/drivers/sqlite/sqlite_utility.php
index 8825cd5b6..7ad040e9a 100644
--- a/system/database/drivers/sqlite/sqlite_utility.php
+++ b/system/database/drivers/sqlite/sqlite_utility.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/sqlite3/sqlite3_driver.php b/system/database/drivers/sqlite3/sqlite3_driver.php
index 4d131c31a..30c38ec47 100644
--- a/system/database/drivers/sqlite3/sqlite3_driver.php
+++ b/system/database/drivers/sqlite3/sqlite3_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/sqlite3/sqlite3_forge.php b/system/database/drivers/sqlite3/sqlite3_forge.php
index 6aa42cf4b..0eed05908 100644
--- a/system/database/drivers/sqlite3/sqlite3_forge.php
+++ b/system/database/drivers/sqlite3/sqlite3_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/sqlite3/sqlite3_result.php b/system/database/drivers/sqlite3/sqlite3_result.php
index 87ad64d7a..fb2fc4e89 100644
--- a/system/database/drivers/sqlite3/sqlite3_result.php
+++ b/system/database/drivers/sqlite3/sqlite3_result.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/sqlite3/sqlite3_utility.php b/system/database/drivers/sqlite3/sqlite3_utility.php
index 565d7d954..49dcf3d12 100644
--- a/system/database/drivers/sqlite3/sqlite3_utility.php
+++ b/system/database/drivers/sqlite3/sqlite3_utility.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/sqlsrv/sqlsrv_driver.php b/system/database/drivers/sqlsrv/sqlsrv_driver.php
index 09e6b8c9a..a723b78bc 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_driver.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.0.3
@@ -48,6 +48,18 @@ class CI_DB_sqlsrv_driver extends CI_DB {
*/
public $dbdriver = 'sqlsrv';
+ /**
+ * Scrollable flag
+ *
+ * Determines what cursor type to use when executing queries.
+ *
+ * FALSE or SQLSRV_CURSOR_FORWARD would increase performance,
+ * but would disable num_rows() (and possibly insert_id())
+ *
+ * @var mixed
+ */
+ public $scrollable;
+
// --------------------------------------------------------------------
/**
@@ -70,6 +82,27 @@ class CI_DB_sqlsrv_driver extends CI_DB {
// --------------------------------------------------------------------
/**
+ * Class constructor
+ *
+ * @param array $params
+ * @return void
+ */
+ public function __construct($params)
+ {
+ parent::__construct($params);
+
+ // This is only supported as of SQLSRV 3.0
+ if ($this->scrollable === NULL)
+ {
+ $this->scrollable = defined('SQLSRV_CURSOR_CLIENT_BUFFERED')
+ ? SQLSRV_CURSOR_CLIENT_BUFFERED
+ : FALSE;
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* Database connection
*
* @param bool $pooling
@@ -154,9 +187,9 @@ class CI_DB_sqlsrv_driver extends CI_DB {
*/
protected function _execute($sql)
{
- return ($this->is_write_type($sql) && stripos($sql, 'INSERT') === FALSE)
+ return ($this->scrollable === FALSE OR $this->is_write_type($sql))
? sqlsrv_query($this->conn_id, $sql)
- : sqlsrv_query($this->conn_id, $sql, NULL, array('Scrollable' => SQLSRV_CURSOR_STATIC));
+ : sqlsrv_query($this->conn_id, $sql, NULL, array('Scrollable' => $this->scrollable));
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/sqlsrv/sqlsrv_forge.php b/system/database/drivers/sqlsrv/sqlsrv_forge.php
index cced5b98f..79386843f 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_forge.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_forge.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.0.3
diff --git a/system/database/drivers/sqlsrv/sqlsrv_result.php b/system/database/drivers/sqlsrv/sqlsrv_result.php
index 3c8148f1b..71c429e51 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_result.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_result.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -39,15 +39,45 @@ defined('BASEPATH') OR exit('No direct script access allowed');
class CI_DB_sqlsrv_result extends CI_DB_result {
/**
+ * Scrollable flag
+ *
+ * @var mixed
+ */
+ public $scrollable;
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Constructor
+ *
+ * @param object $driver_object
+ * @return void
+ */
+ public function __construct(&$driver_object)
+ {
+ parent::__construct($driver_object);
+
+ $this->scrollable = $driver_object->scrollable;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* Number of rows in the result set
*
* @return int
*/
public function num_rows()
{
+ // sqlsrv_num_rows() doesn't work with the FORWARD and DYNAMIC cursors (FALSE is the same as FORWARD)
+ if ( ! in_array($this->scrollable, array(FALSE, SQLSRV_CURSOR_FORWARD, SQLSRV_CURSOR_DYNAMIC), TRUE))
+ {
+ return parent::num_rows();
+ }
+
return is_int($this->num_rows)
? $this->num_rows
- : $this->num_rows = @sqlsrv_num_rows($this->result_id);
+ : $this->num_rows = sqlsrv_num_rows($this->result_id);
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/sqlsrv/sqlsrv_utility.php b/system/database/drivers/sqlsrv/sqlsrv_utility.php
index d75e6a6da..b6a1fe449 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_utility.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_utility.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.0.3
diff --git a/system/helpers/array_helper.php b/system/helpers/array_helper.php
index 7b62da68f..1cdbcdfcf 100644
--- a/system/helpers/array_helper.php
+++ b/system/helpers/array_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php
index 29911dc17..13926774e 100644
--- a/system/helpers/captcha_helper.php
+++ b/system/helpers/captcha_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -82,7 +82,7 @@ if ( ! function_exists('create_captcha'))
}
if ($img_path === '' OR $img_url === ''
- OR ! @is_dir($img_path) OR ! is_writeable($img_path)
+ OR ! @is_dir($img_path) OR ! is_really_writable($img_path)
OR ! extension_loaded('gd'))
{
return FALSE;
@@ -126,9 +126,9 @@ if ( ! function_exists('create_captcha'))
// Determine angle and position
// -----------------------------------
$length = strlen($word);
- $angle = ($length >= 6) ? rand(-($length-6), ($length-6)) : 0;
- $x_axis = rand(6, (360/$length)-16);
- $y_axis = ($angle >= 0) ? rand($img_height, $img_width) : rand(6, $img_height);
+ $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
// PHP.net recommends imagecreatetruecolor(), but it isn't always available
@@ -183,13 +183,13 @@ if ( ! function_exists('create_captcha'))
if ($use_font === FALSE)
{
$font_size = 5;
- $x = rand(0, $img_width / ($length / 3));
+ $x = mt_rand(0, $img_width / ($length / 3));
$y = 0;
}
else
{
$font_size = 16;
- $x = rand(0, $img_width / ($length / 1.5));
+ $x = mt_rand(0, $img_width / ($length / 1.5));
$y = $font_size + 2;
}
@@ -197,13 +197,13 @@ if ( ! function_exists('create_captcha'))
{
if ($use_font === FALSE)
{
- $y = rand(0 , $img_height / 2);
+ $y = mt_rand(0 , $img_height / 2);
imagestring($im, $font_size, $x, $y, $word[$i], $colors['text']);
$x += ($font_size * 2);
}
else
{
- $y = rand($img_height / 2, $img_height - 3);
+ $y = mt_rand($img_height / 2, $img_height - 3);
imagettftext($im, $font_size, $angle, $x, $y, $colors['text'], $font_path, $word[$i]);
$x += $font_size;
}
@@ -215,12 +215,12 @@ if ( ! function_exists('create_captcha'))
// -----------------------------------
// Generate the image
// -----------------------------------
- $img_name = $now.'.jpg';
- ImageJPEG($im, $img_path.$img_name);
- $img = '<img src="'.$img_url.$img_name.'" style="width: '.$img_width.'; height: '.$img_height .'; border: 0;" alt=" " />';
+ $img_filename = $now.'.jpg';
+ ImageJPEG($im, $img_path.$img_filename);
+ $img = '<img src="'.$img_url.$img_filename.'" style="width: '.$img_width.'; height: '.$img_height .'; border: 0;" alt=" " />';
ImageDestroy($im);
- return array('word' => $word, 'time' => $now, 'image' => $img);
+ 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 e5cf6b1d6..a08bec398 100644
--- a/system/helpers/cookie_helper.php
+++ b/system/helpers/cookie_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -56,11 +56,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 = FALSE, $httponly = FALSE)
+ function set_cookie($name, $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE)
{
// Set the config file options
- $CI =& get_instance();
- $CI->input->set_cookie($name, $value, $expire, $domain, $path, $prefix, $secure, $httponly);
+ get_instance()->input->set_cookie($name, $value, $expire, $domain, $path, $prefix, $secure, $httponly);
}
}
@@ -75,11 +74,11 @@ if ( ! function_exists('get_cookie'))
* @param bool
* @return mixed
*/
- function get_cookie($index = '', $xss_clean = FALSE)
+ function get_cookie($index, $xss_clean = NULL)
{
- $CI =& get_instance();
+ is_bool($xss_clean) OR $xss_clean = (config_item('global_xss_filtering') === TRUE);
$prefix = isset($_COOKIE[$index]) ? '' : config_item('cookie_prefix');
- return $CI->input->cookie($prefix.$index, $xss_clean);
+ return get_instance()->input->cookie($prefix.$index, $xss_clean);
}
}
@@ -96,7 +95,7 @@ if ( ! function_exists('delete_cookie'))
* @param string the cookie prefix
* @return void
*/
- function delete_cookie($name = '', $domain = '', $path = '/', $prefix = '')
+ function delete_cookie($name, $domain = '', $path = '/', $prefix = '')
{
set_cookie($name, '', '', $domain, $path, $prefix);
}
diff --git a/system/helpers/date_helper.php b/system/helpers/date_helper.php
index c3a8d3c9e..56e5c46aa 100644
--- a/system/helpers/date_helper.php
+++ b/system/helpers/date_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/helpers/directory_helper.php b/system/helpers/directory_helper.php
index 81ffd1579..84ad35894 100644
--- a/system/helpers/directory_helper.php
+++ b/system/helpers/directory_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -69,7 +69,7 @@ if ( ! function_exists('directory_map'))
continue;
}
- @is_dir($source_dir.$file) AND $file .= DIRECTORY_SEPARATOR;
+ @is_dir($source_dir.$file) && $file .= DIRECTORY_SEPARATOR;
if (($directory_depth < 1 OR $new_depth > 0) && @is_dir($source_dir.$file))
{
diff --git a/system/helpers/download_helper.php b/system/helpers/download_helper.php
index 4fe6a0e88..ffe5ff997 100644
--- a/system/helpers/download_helper.php
+++ b/system/helpers/download_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -120,7 +120,7 @@ if ( ! function_exists('force_download'))
// Clean output buffer
if (ob_get_level() !== 0 && @ob_end_clean() === FALSE)
{
- ob_clean();
+ @ob_clean();
}
// Generate the server headers
diff --git a/system/helpers/email_helper.php b/system/helpers/email_helper.php
index d2e6f5491..e93f35705 100644
--- a/system/helpers/email_helper.php
+++ b/system/helpers/email_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php
index 4b45a62d0..575b87479 100644
--- a/system/helpers/file_helper.php
+++ b/system/helpers/file_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -79,11 +79,19 @@ if ( ! function_exists('write_file'))
}
flock($fp, LOCK_EX);
- fwrite($fp, $data);
+
+ for ($written = 0, $length = strlen($data); $written < $length; $written += $result)
+ {
+ if (($result = fwrite($fp, substr($data, $written))) === FALSE)
+ {
+ break;
+ }
+ }
+
flock($fp, LOCK_UN);
fclose($fp);
- return TRUE;
+ return is_int($result);
}
}
@@ -290,8 +298,7 @@ if ( ! function_exists('get_file_info'))
$fileinfo['readable'] = is_readable($file);
break;
case 'writable':
- // There are known problems using is_weritable on IIS. It may not be reliable - consider fileperms()
- $fileinfo['writable'] = is_writable($file);
+ $fileinfo['writable'] = is_really_writable($file);
break;
case 'executable':
$fileinfo['executable'] = is_executable($file);
diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php
index 4700da7d7..40852faf8 100644
--- a/system/helpers/form_helper.php
+++ b/system/helpers/form_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -316,8 +316,9 @@ if ( ! function_exists('form_dropdown'))
{
isset($name['options']) OR $name['options'] = array();
isset($name['selected']) OR $name['selected'] = array();
+ isset($name['extra']) OR $name['extra'] = '';
- return form_dropdown($name['name'], $name['options'], $name['selected'], $extra);
+ return form_dropdown($name['name'], $name['options'], $name['selected'], $name['extra']);
}
is_array($selected) OR $selected = array($selected);
@@ -328,10 +329,7 @@ if ( ! function_exists('form_dropdown'))
$selected = array($_POST[$name]);
}
- if ($extra != '')
- {
- $extra = ' '.$extra;
- }
+ $extra = _attributes_to_string($extra);
$multiple = (count($selected) > 1 && strpos($extra, 'multiple') === FALSE) ? ' multiple="multiple"' : '';
@@ -684,9 +682,20 @@ if ( ! function_exists('set_select'))
{
return ($default === TRUE) ? ' selected="selected"' : '';
}
- elseif (is_array($input) && in_array($value, $input, TRUE))
+
+ $value = (string) $value;
+ if (is_array($input))
{
- return ' selected="selected"';
+ // Note: in_array('', array(0)) returns TRUE, do not use it
+ foreach ($input as &$v)
+ {
+ if ($value === $v)
+ {
+ return ' selected="selected"';
+ }
+ }
+
+ return '';
}
return ($input === $value) ? ' selected="selected"' : '';
@@ -720,9 +729,20 @@ if ( ! function_exists('set_checkbox'))
{
return ($default === TRUE) ? ' checked="checked"' : '';
}
- elseif (is_array($input) && in_array($value, $input, TRUE))
+
+ $value = (string) $value;
+ if (is_array($input))
{
- return ' checked="checked"';
+ // Note: in_array('', array(0)) returns TRUE, do not use it
+ foreach ($input as &$v)
+ {
+ if ($value === $v)
+ {
+ return ' checked="checked"';
+ }
+ }
+
+ return '';
}
return ($input === $value) ? ' checked="checked"' : '';
@@ -757,7 +777,7 @@ if ( ! function_exists('set_radio'))
return ($default === TRUE) ? ' checked="checked"' : '';
}
- return ($input === $value) ? ' checked="checked"' : '';
+ return ($input === (string) $value) ? ' checked="checked"' : '';
}
}
diff --git a/system/helpers/html_helper.php b/system/helpers/html_helper.php
index ece39584b..604d1144a 100644
--- a/system/helpers/html_helper.php
+++ b/system/helpers/html_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -199,15 +199,13 @@ if ( ! function_exists('img'))
{
if ($k === 'src' && strpos($v, '://') === FALSE)
{
- $CI =& get_instance();
-
if ($index_page === TRUE)
{
- $img .= ' src="'.$CI->config->site_url($v).'"';
+ $img .= ' src="'.get_instance()->config->site_url($v).'"';
}
else
{
- $img .= ' src="'.$CI->config->slash_item('base_url').$v.'"';
+ $img .= ' src="'.get_instance()->config->slash_item('base_url').$v.'"';
}
}
else
diff --git a/system/helpers/inflector_helper.php b/system/helpers/inflector_helper.php
index a133cdddb..b44594e2a 100644
--- a/system/helpers/inflector_helper.php
+++ b/system/helpers/inflector_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -188,7 +188,7 @@ if ( ! function_exists('underscore'))
*/
function underscore($str)
{
- return preg_replace('/[\s]+/', '_', strtolower(trim($str)));
+ return preg_replace('/[\s]+/', '_', trim(MB_ENABLED ? mb_strtolower($str) : strtolower($str)));
}
}
@@ -207,7 +207,7 @@ if ( ! function_exists('humanize'))
*/
function humanize($str, $separator = '_')
{
- return ucwords(preg_replace('/['.$separator.']+/', ' ', strtolower(trim($str))));
+ return ucwords(preg_replace('/['.$separator.']+/', ' ', trim(MB_ENABLED ? mb_strtolower($str) : strtolower($str))));
}
}
@@ -223,12 +223,13 @@ if ( ! function_exists('is_countable'))
*/
function is_countable($word)
{
- return ! in_array(strtolower($word),
- array(
- 'equipment', 'information', 'rice', 'money',
- 'species', 'series', 'fish', 'meta'
- )
- );
+ return ! in_array(
+ strtolower($word),
+ array(
+ 'equipment', 'information', 'rice', 'money',
+ 'species', 'series', 'fish', 'meta'
+ )
+ );
}
}
diff --git a/system/helpers/language_helper.php b/system/helpers/language_helper.php
index 4d571a71c..baea849b1 100644
--- a/system/helpers/language_helper.php
+++ b/system/helpers/language_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -52,8 +52,7 @@ if ( ! function_exists('lang'))
*/
function lang($line, $for = '', $attributes = array())
{
- $CI =& get_instance();
- $line = $CI->lang->line($line);
+ $line = get_instance()->lang->line($line);
if ($for !== '')
{
diff --git a/system/helpers/number_helper.php b/system/helpers/number_helper.php
index 5ebdc946f..7d3bb2797 100644
--- a/system/helpers/number_helper.php
+++ b/system/helpers/number_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/helpers/path_helper.php b/system/helpers/path_helper.php
index 3f4f7e9fb..ae1f0bf33 100644
--- a/system/helpers/path_helper.php
+++ b/system/helpers/path_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/helpers/security_helper.php b/system/helpers/security_helper.php
index 4bb94a201..848cf4623 100644
--- a/system/helpers/security_helper.php
+++ b/system/helpers/security_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -49,8 +49,7 @@ if ( ! function_exists('xss_clean'))
*/
function xss_clean($str, $is_image = FALSE)
{
- $CI =& get_instance();
- return $CI->security->xss_clean($str, $is_image);
+ return get_instance()->security->xss_clean($str, $is_image);
}
}
@@ -66,8 +65,7 @@ if ( ! function_exists('sanitize_filename'))
*/
function sanitize_filename($filename)
{
- $CI =& get_instance();
- return $CI->security->sanitize_filename($filename);
+ return get_instance()->security->sanitize_filename($filename);
}
}
@@ -107,8 +105,7 @@ if ( ! function_exists('strip_image_tags'))
*/
function strip_image_tags($str)
{
- $CI =& get_instance();
- return $CI->security->strip_image_tags($str);
+ return get_instance()->security->strip_image_tags($str);
}
}
diff --git a/system/helpers/smiley_helper.php b/system/helpers/smiley_helper.php
index d9a693493..57debffa9 100644
--- a/system/helpers/smiley_helper.php
+++ b/system/helpers/smiley_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/helpers/string_helper.php b/system/helpers/string_helper.php
index 12f818fda..a1daa1efe 100644
--- a/system/helpers/string_helper.php
+++ b/system/helpers/string_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -188,7 +188,7 @@ if ( ! function_exists('random_string'))
*
* Useful for generating passwords or hashes.
*
- * @param string type of random string. basic, alpha, alunum, numeric, nozero, unique, md5, encrypt and sha1
+ * @param string type of random string. basic, alpha, alnum, numeric, nozero, unique, md5, encrypt and sha1
* @param int number of characters
* @return string
*/
diff --git a/system/helpers/text_helper.php b/system/helpers/text_helper.php
index b2351db95..76e1735b5 100644
--- a/system/helpers/text_helper.php
+++ b/system/helpers/text_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -85,7 +85,7 @@ if ( ! function_exists('character_limiter'))
*/
function character_limiter($str, $n = 500, $end_char = '&#8230;')
{
- if (strlen($str) < $n)
+ if (mb_strlen($str) < $n)
{
return $str;
}
@@ -93,7 +93,7 @@ if ( ! function_exists('character_limiter'))
// a bit complicated, but faster than preg_replace with \s+
$str = preg_replace('/ {2,}/', ' ', str_replace(array("\r", "\n", "\t", "\x0B", "\x0C"), ' ', $str));
- if (strlen($str) <= $n)
+ if (mb_strlen($str) <= $n)
{
return $str;
}
@@ -103,10 +103,10 @@ if ( ! function_exists('character_limiter'))
{
$out .= $val.' ';
- if (strlen($out) >= $n)
+ if (mb_strlen($out) >= $n)
{
$out = trim($out);
- return (strlen($out) === strlen($str)) ? $out : $out.$end_char;
+ return (mb_strlen($out) === mb_strlen($str)) ? $out : $out.$end_char;
}
}
}
@@ -127,7 +127,7 @@ if ( ! function_exists('ascii_to_entities'))
function ascii_to_entities($str)
{
$out = '';
- for ($i = 0, $s = strlen($str), $count = 1, $temp = array(); $i < $s; $i++)
+ for ($i = 0, $s = strlen($str) - 1, $count = 1, $temp = array(); $i <= $s; $i++)
{
$ordinal = ord($str[$i]);
@@ -164,6 +164,11 @@ if ( ! function_exists('ascii_to_entities'))
$count = 1;
$temp = array();
}
+ // If this is the last iteration, just output whatever we have
+ elseif ($i === $s)
+ {
+ $out .= '&#'.implode(';', $temp).';';
+ }
}
}
@@ -329,25 +334,17 @@ if ( ! function_exists('highlight_phrase'))
*
* Highlights a phrase within a text string
*
- * @param string the text string
- * @param string the phrase you'd like to highlight
- * @param string the openging tag to precede the phrase with
- * @param string the closing tag to end the phrase with
+ * @param string $str the text string
+ * @param string $phrase the phrase you'd like to highlight
+ * @param string $tag_open the openging tag to precede the phrase with
+ * @param string $tag_close the closing tag to end the phrase with
* @return string
*/
- function highlight_phrase($str, $phrase, $tag_open = '<strong>', $tag_close = '</strong>')
+ function highlight_phrase($str, $phrase, $tag_open = '<mark>', $tag_close = '</mark>')
{
- if ($str === '')
- {
- return '';
- }
-
- if ($phrase !== '')
- {
- return preg_replace('/('.preg_quote($phrase, '/').')/i', $tag_open.'\\1'.$tag_close, $str);
- }
-
- return $str;
+ return ($str !== '' && $phrase !== '')
+ ? preg_replace('/('.preg_quote($phrase, '/').')/i', $tag_open.'\\1'.$tag_close, $str)
+ : $str;
}
}
@@ -448,14 +445,14 @@ if ( ! function_exists('word_wrap'))
{
// Is the line within the allowed character count?
// If so we'll join it to the output and continue
- if (strlen($line) <= $charlim)
+ if (mb_strlen($line) <= $charlim)
{
$output .= $line."\n";
continue;
}
$temp = '';
- while ((strlen($line)) > $charlim)
+ while (mb_strlen($line) > $charlim)
{
// If the over-length word is a URL we won't wrap it
if (preg_match('!\[url.+\]|://|wwww.!', $line))
@@ -464,8 +461,8 @@ if ( ! function_exists('word_wrap'))
}
// Trim the word down
- $temp .= substr($line, 0, $charlim - 1);
- $line = substr($line, $charlim - 1);
+ $temp .= mb_substr($line, 0, $charlim - 1);
+ $line = mb_substr($line, $charlim - 1);
}
// If $temp contains data it means we had to split up an over-length
@@ -515,21 +512,21 @@ if ( ! function_exists('ellipsize'))
$str = trim(strip_tags($str));
// Is the string long enough to ellipsize?
- if (strlen($str) <= $max_length)
+ if (mb_strlen($str) <= $max_length)
{
return $str;
}
- $beg = substr($str, 0, floor($max_length * $position));
+ $beg = mb_substr($str, 0, floor($max_length * $position));
$position = ($position > 1) ? 1 : $position;
if ($position === 1)
{
- $end = substr($str, 0, -($max_length - strlen($beg)));
+ $end = mb_substr($str, 0, -($max_length - mb_strlen($beg)));
}
else
{
- $end = substr($str, -($max_length - strlen($beg)));
+ $end = mb_substr($str, -($max_length - mb_strlen($beg)));
}
return $beg.$ellipsis.$end;
diff --git a/system/helpers/typography_helper.php b/system/helpers/typography_helper.php
index e4a8d3bc0..cd3827c8b 100644
--- a/system/helpers/typography_helper.php
+++ b/system/helpers/typography_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php
index fbb4a1b24..a9790e5c4 100644
--- a/system/helpers/url_helper.php
+++ b/system/helpers/url_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -52,14 +52,7 @@ if ( ! function_exists('site_url'))
*/
function site_url($uri = '', $protocol = NULL)
{
- $uri = get_instance()->config->site_url($uri);
-
- if (isset($protocol))
- {
- return $protocol.substr($uri, strpos($uri, '://'));
- }
-
- return $uri;
+ return get_instance()->config->site_url($uri, $protocol);
}
}
@@ -80,14 +73,7 @@ if ( ! function_exists('base_url'))
*/
function base_url($uri = '', $protocol = NULL)
{
- $uri = get_instance()->config->base_url($uri);
-
- if (isset($protocol))
- {
- return $protocol.substr($uri, strpos($uri, '://'));
- }
-
- return $uri;
+ return get_instance()->config->base_url($uri, $protocol);
}
}
@@ -123,8 +109,7 @@ if ( ! function_exists('uri_string'))
*/
function uri_string()
{
- $CI =& get_instance();
- return $CI->uri->uri_string();
+ return get_instance()->uri->uri_string();
}
}
@@ -141,8 +126,7 @@ if ( ! function_exists('index_page'))
*/
function index_page()
{
- $CI =& get_instance();
- return $CI->config->item('index_page');
+ return get_instance()->config->item('index_page');
}
}
@@ -548,11 +532,16 @@ if ( ! function_exists('redirect'))
}
elseif ($method !== 'refresh' && (empty($code) OR ! is_numeric($code)))
{
- // Reference: http://en.wikipedia.org/wiki/Post/Redirect/Get
- $code = (isset($_SERVER['REQUEST_METHOD'], $_SERVER['SERVER_PROTOCOL'])
- && $_SERVER['REQUEST_METHOD'] === 'POST'
- && $_SERVER['SERVER_PROTOCOL'] === 'HTTP/1.1')
- ? 303 : 302;
+ 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
+ : 307;
+ }
+ else
+ {
+ $code = 302;
+ }
}
switch ($method)
diff --git a/system/helpers/xml_helper.php b/system/helpers/xml_helper.php
index 84069a689..4c38b6988 100644
--- a/system/helpers/xml_helper.php
+++ b/system/helpers/xml_helper.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/language/english/calendar_lang.php b/system/language/english/calendar_lang.php
index 4c2aa8c86..0fc949476 100644
--- a/system/language/english/calendar_lang.php
+++ b/system/language/english/calendar_lang.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/language/english/date_lang.php b/system/language/english/date_lang.php
index 3f9f7a0d3..f0822d4bb 100644
--- a/system/language/english/date_lang.php
+++ b/system/language/english/date_lang.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/language/english/db_lang.php b/system/language/english/db_lang.php
index 62de80337..4e2b808a7 100644
--- a/system/language/english/db_lang.php
+++ b/system/language/english/db_lang.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/language/english/email_lang.php b/system/language/english/email_lang.php
index 1eec470e0..bcd0cee70 100644
--- a/system/language/english/email_lang.php
+++ b/system/language/english/email_lang.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/language/english/form_validation_lang.php b/system/language/english/form_validation_lang.php
index 7c0277c25..9156ebef0 100644
--- a/system/language/english/form_validation_lang.php
+++ b/system/language/english/form_validation_lang.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/language/english/ftp_lang.php b/system/language/english/ftp_lang.php
index ae4086ff3..8453653a8 100644
--- a/system/language/english/ftp_lang.php
+++ b/system/language/english/ftp_lang.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -26,18 +26,18 @@
*/
defined('BASEPATH') OR exit('No direct script access allowed');
-$lang['ftp_no_connection'] = 'Unable to locate a valid connection ID. Please make sure you are connected before peforming any file routines.';
+$lang['ftp_no_connection'] = 'Unable to locate a valid connection ID. Please make sure you are connected before performing any file routines.';
$lang['ftp_unable_to_connect'] = 'Unable to connect to your FTP server using the supplied hostname.';
$lang['ftp_unable_to_login'] = 'Unable to login to your FTP server. Please check your username and password.';
-$lang['ftp_unable_to_makdir'] = 'Unable to create the directory you have specified.';
+$lang['ftp_unable_to_mkdir'] = 'Unable to create the directory you have specified.';
$lang['ftp_unable_to_changedir'] = 'Unable to change directories.';
-$lang['ftp_unable_to_chmod'] = 'Unable to set file permissions. Please check your path. Note: This feature is only available in PHP 5 or higher.';
+$lang['ftp_unable_to_chmod'] = 'Unable to set file permissions. Please check your path.';
$lang['ftp_unable_to_upload'] = 'Unable to upload the specified file. Please check your path.';
$lang['ftp_unable_to_download'] = 'Unable to download the specified file. Please check your path.';
-$lang['ftp_no_source_file'] = 'Unable to locate the source file. Please check your path.';
+$lang['ftp_no_source_file'] = 'Unable to locate the source file. Please check your path.';
$lang['ftp_unable_to_rename'] = 'Unable to rename the file.';
$lang['ftp_unable_to_delete'] = 'Unable to delete the file.';
-$lang['ftp_unable_to_move'] = 'Unable to move the file. Please make sure the destination directory exists.';
+$lang['ftp_unable_to_move'] = 'Unable to move the file. Please make sure the destination directory exists.';
/* End of file ftp_lang.php */
/* Location: ./system/language/english/ftp_lang.php */ \ No newline at end of file
diff --git a/system/language/english/imglib_lang.php b/system/language/english/imglib_lang.php
index a27d31651..c1c95bea6 100644
--- a/system/language/english/imglib_lang.php
+++ b/system/language/english/imglib_lang.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/language/english/migration_lang.php b/system/language/english/migration_lang.php
index 54f9e769b..8e8b606c0 100644
--- a/system/language/english/migration_lang.php
+++ b/system/language/english/migration_lang.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 3.0
diff --git a/system/language/english/number_lang.php b/system/language/english/number_lang.php
index 2f37358d7..eb78931b1 100644
--- a/system/language/english/number_lang.php
+++ b/system/language/english/number_lang.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/language/english/pagination_lang.php b/system/language/english/pagination_lang.php
new file mode 100644
index 000000000..ffee2d972
--- /dev/null
+++ b/system/language/english/pagination_lang.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.2.4 or newer
+ *
+ * NOTICE OF LICENSE
+ *
+ * Licensed under the Open Software License version 3.0
+ *
+ * This source file is subject to the Open Software License (OSL 3.0) that is
+ * bundled with this package in the files license.txt / license.rst. It is
+ * also available through the world wide web at this URL:
+ * http://opensource.org/licenses/OSL-3.0
+ * If you did not receive a copy of the license and are unable to obtain it
+ * through the world wide web, please send an email to
+ * licensing@ellislab.com so we can send you a copy immediately.
+ *
+ * @package CodeIgniter
+ * @author EllisLab Dev Team
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
+ * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+$lang['pagination_first_link'] = '&lsaquo; First';
+$lang['pagination_next_link'] = '&gt;';
+$lang['pagination_prev_link'] = '&lt;';
+$lang['pagination_last_link'] = 'Last &rsaquo;';
+
+/* End of file pagination_lang.php */
+/* Location: ./system/language/english/pagination_lang.php */ \ No newline at end of file
diff --git a/system/language/english/profiler_lang.php b/system/language/english/profiler_lang.php
index 0ed5f4cb0..af3b0c808 100644
--- a/system/language/english/profiler_lang.php
+++ b/system/language/english/profiler_lang.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/language/english/unit_test_lang.php b/system/language/english/unit_test_lang.php
index ea986ec36..d7a984dee 100644
--- a/system/language/english/unit_test_lang.php
+++ b/system/language/english/unit_test_lang.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/language/english/upload_lang.php b/system/language/english/upload_lang.php
index 5b07c4e30..2b60a064c 100644
--- a/system/language/english/upload_lang.php
+++ b/system/language/english/upload_lang.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/libraries/Cache/Cache.php b/system/libraries/Cache/Cache.php
index 537897eaf..f9768b10c 100644
--- a/system/libraries/Cache/Cache.php
+++ b/system/libraries/Cache/Cache.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.0
@@ -150,14 +150,15 @@ class CI_Cache extends CI_Driver_Library {
/**
* Cache Save
*
- * @param string $id Cache ID
- * @param mixed $data Data to store
- * @param int $ttl = 60 Cache TTL (in seconds)
+ * @param string $id Cache ID
+ * @param mixed $data Data to store
+ * @param int $ttl Cache TTL (in seconds)
+ * @param bool $raw Whether to store the raw value
* @return bool TRUE on success, FALSE on failure
*/
- public function save($id, $data, $ttl = 60)
+ public function save($id, $data, $ttl = 60, $raw = FALSE)
{
- return $this->{$this->_adapter}->save($this->key_prefix.$id, $data, $ttl);
+ return $this->{$this->_adapter}->save($this->key_prefix.$id, $data, $ttl, $raw);
}
// ------------------------------------------------------------------------
@@ -176,6 +177,34 @@ class CI_Cache extends CI_Driver_Library {
// ------------------------------------------------------------------------
/**
+ * 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 $this->{$this->_adapter}->increment($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 $this->{$this->_adapter}->decrement($id, $offset);
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
* Clean the cache
*
* @return bool TRUE on success, FALSE on failure
diff --git a/system/libraries/Cache/drivers/Cache_apc.php b/system/libraries/Cache/drivers/Cache_apc.php
index a84e7d2d3..d062103bd 100644
--- a/system/libraries/Cache/drivers/Cache_apc.php
+++ b/system/libraries/Cache/drivers/Cache_apc.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.0
@@ -51,8 +51,14 @@ class CI_Cache_apc extends CI_Driver {
$success = FALSE;
$data = apc_fetch($id, $success);
- return ($success === TRUE && is_array($data))
- ? unserialize($data[0]) : FALSE;
+ if ($success === TRUE)
+ {
+ return is_array($data)
+ ? unserialize($data[0])
+ : $data;
+ }
+
+ return FALSE;
}
// ------------------------------------------------------------------------
@@ -60,16 +66,21 @@ class CI_Cache_apc extends CI_Driver {
/**
* Cache Save
*
- * @param string Unique Key
- * @param mixed Data to store
- * @param int Length of time (in seconds) to cache the data
- *
- * @return bool true on success/false on failure
+ * @param string $id Cache ID
+ * @param mixed $data Data to store
+ * @param int $ttol 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)
+ public function save($id, $data, $ttl = 60, $raw = FALSE)
{
$ttl = (int) $ttl;
- return apc_store($id, array(serialize($data), time(), $ttl), $ttl);
+
+ return apc_store(
+ $id,
+ ($raw === TRUE ? $data : array(serialize($data), time(), $ttl)),
+ $ttl
+ );
}
// ------------------------------------------------------------------------
@@ -88,6 +99,34 @@ class CI_Cache_apc extends CI_Driver {
// ------------------------------------------------------------------------
/**
+ * 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 apc_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 apc_dec($id, $offset);
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
* Clean the cache
*
* @return bool false on failure/true on success
diff --git a/system/libraries/Cache/drivers/Cache_dummy.php b/system/libraries/Cache/drivers/Cache_dummy.php
index d9af3773b..521b9e6dd 100644
--- a/system/libraries/Cache/drivers/Cache_dummy.php
+++ b/system/libraries/Cache/drivers/Cache_dummy.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.0
@@ -58,9 +58,10 @@ class CI_Cache_dummy extends CI_Driver {
* @param string Unique Key
* @param mixed Data to store
* @param int Length of time (in seconds) to cache the data
+ * @param bool Whether to store the raw value
* @return bool TRUE, Simulating success
*/
- public function save($id, $data, $ttl = 60)
+ public function save($id, $data, $ttl = 60, $raw = FALSE)
{
return TRUE;
}
@@ -81,6 +82,34 @@ class CI_Cache_dummy extends CI_Driver {
// ------------------------------------------------------------------------
/**
+ * 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 TRUE;
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * 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 TRUE;
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
* Clean the cache
*
* @return bool TRUE, simulating success
diff --git a/system/libraries/Cache/drivers/Cache_file.php b/system/libraries/Cache/drivers/Cache_file.php
index 769bd5a26..c6aa848fe 100644
--- a/system/libraries/Cache/drivers/Cache_file.php
+++ b/system/libraries/Cache/drivers/Cache_file.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.0
@@ -62,25 +62,13 @@ class CI_Cache_file extends CI_Driver {
/**
* Fetch from cache
*
- * @param mixed unique key id
- * @return mixed data on success/false on failure
+ * @param string $id Cache ID
+ * @return mixed Data on success, FALSE on failure
*/
public function get($id)
{
- if ( ! file_exists($this->_cache_path.$id))
- {
- return FALSE;
- }
-
- $data = unserialize(file_get_contents($this->_cache_path.$id));
-
- if ($data['ttl'] > 0 && time() > $data['time'] + $data['ttl'])
- {
- unlink($this->_cache_path.$id);
- return FALSE;
- }
-
- return $data['data'];
+ $data = $this->_get($id);
+ return is_array($data) ? $data['data'] : FALSE;
}
// ------------------------------------------------------------------------
@@ -88,13 +76,13 @@ class CI_Cache_file extends CI_Driver {
/**
* Save into cache
*
- * @param string unique key
- * @param mixed data to store
- * @param int length of time (in seconds) the cache is valid
- * - Default is 60 seconds
- * @return bool true on success/false on failure
+ * @param string $id Cache ID
+ * @param mixed $data Data to store
+ * @param int $ttl Time to live in seconds
+ * @param bool $raw Whether to store the raw value (unused)
+ * @return bool TRUE on success, FALSE on failure
*/
- public function save($id, $data, $ttl = 60)
+ public function save($id, $data, $ttl = 60, $raw = FALSE)
{
$contents = array(
'time' => time(),
@@ -127,6 +115,54 @@ class CI_Cache_file extends CI_Driver {
// ------------------------------------------------------------------------
/**
+ * Increment a raw value
+ *
+ * @param string $id Cache ID
+ * @param int $offset Step/value to add
+ * @return New value on success, FALSE on failure
+ */
+ public function increment($id, $offset = 1)
+ {
+ $data = $this->_get($id);
+
+ if ($data === FALSE OR ! is_int($data['data']))
+ {
+ return FALSE;
+ }
+
+ $new_value = $data['data'] + $offset;
+ return $this->save($id, $new_value, $data['ttl'])
+ ? $new_value
+ : FALSE;
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Decrement a raw value
+ *
+ * @param string $id Cache ID
+ * @param int $offset Step/value to reduce by
+ * @return New value on success, FALSE on failure
+ */
+ public function decrement($id, $offset = 1)
+ {
+ $data = $this->_get($id);
+
+ if ($data === FALSE OR ! is_int($data['data']))
+ {
+ return FALSE;
+ }
+
+ $new_value = $data['data'] - $offset;
+ return $this->save($id, $new_value, $data['ttl'])
+ ? $new_value
+ : FALSE;
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
* Clean the Cache
*
* @return bool false on failure/true on success
@@ -200,6 +236,34 @@ class CI_Cache_file extends CI_Driver {
return is_really_writable($this->_cache_path);
}
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get all data
+ *
+ * Internal method to get all the relevant data about a cache item
+ *
+ * @param string $id Cache ID
+ * @return mixed Data array on success or FALSE on failure
+ */
+ protected function _get($id)
+ {
+ if ( ! file_exists($this->_cache_path.$id))
+ {
+ return FALSE;
+ }
+
+ $data = unserialize(file_get_contents($this->_cache_path.$id));
+
+ if ($data['ttl'] > 0 && time() > $data['time'] + $data['ttl'])
+ {
+ unlink($this->_cache_path.$id);
+ return FALSE;
+ }
+
+ return $data;
+ }
+
}
/* End of file Cache_file.php */
diff --git a/system/libraries/Cache/drivers/Cache_memcached.php b/system/libraries/Cache/drivers/Cache_memcached.php
index d2a3a489d..bed606afb 100644
--- a/system/libraries/Cache/drivers/Cache_memcached.php
+++ b/system/libraries/Cache/drivers/Cache_memcached.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.0
@@ -60,14 +60,14 @@ class CI_Cache_memcached extends CI_Driver {
/**
* Fetch from cache
*
- * @param mixed unique key id
- * @return mixed data on success/false on failure
+ * @param string $id Cache ID
+ * @return mixed Data on success, FALSE on failure
*/
public function get($id)
{
$data = $this->_memcached->get($id);
- return is_array($data) ? $data[0] : FALSE;
+ return is_array($data) ? $data[0] : $data;
}
// ------------------------------------------------------------------------
@@ -75,20 +75,26 @@ class CI_Cache_memcached extends CI_Driver {
/**
* Save
*
- * @param string unique identifier
- * @param mixed data being cached
- * @param int time to live
- * @return bool true on success, false on failure
+ * @param string $id Cache ID
+ * @param mixed $data Data being cached
+ * @param int $ttl Time to live
+ * @param bool $raw Whether to store the raw value
+ * @return bool TRUE on success, FALSE on failure
*/
- public function save($id, $data, $ttl = 60)
+ public function save($id, $data, $ttl = 60, $raw = FALSE)
{
+ if ($raw !== TRUE)
+ {
+ $data = array($data, time(), $ttl);
+ }
+
if (get_class($this->_memcached) === 'Memcached')
{
- return $this->_memcached->set($id, array($data, time(), $ttl), $ttl);
+ return $this->_memcached->set($id, $data, $ttl);
}
elseif (get_class($this->_memcached) === 'Memcache')
{
- return $this->_memcached->set($id, array($data, time(), $ttl), 0, $ttl);
+ return $this->_memcached->set($id, $data, 0, $ttl);
}
return FALSE;
@@ -110,6 +116,34 @@ class CI_Cache_memcached extends CI_Driver {
// ------------------------------------------------------------------------
/**
+ * 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 $this->_memcached->increment($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 $this->_memcached->decrement($id, $offset);
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
* Clean the Cache
*
* @return bool false on failure/true on success
diff --git a/system/libraries/Cache/drivers/Cache_redis.php b/system/libraries/Cache/drivers/Cache_redis.php
index 40823fcb4..1c76426c5 100644
--- a/system/libraries/Cache/drivers/Cache_redis.php
+++ b/system/libraries/Cache/drivers/Cache_redis.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 3.0
@@ -44,6 +44,7 @@ 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,
@@ -62,7 +63,7 @@ class CI_Cache_redis extends CI_Driver
/**
* Get cache
*
- * @param string Cache key identifier
+ * @param string Cache ID
* @return mixed
*/
public function get($key)
@@ -75,16 +76,17 @@ class CI_Cache_redis extends CI_Driver
/**
* Save cache
*
- * @param string Cache key identifier
- * @param mixed Data to save
- * @param int Time to live
- * @return bool
+ * @param string $id Cache ID
+ * @param mixed $data Data to save
+ * @param int $ttl Time to live in seconds
+ * @param bool $raw Whether to store the raw value (unused)
+ * @return bool TRUE on success, FALSE on failure
*/
- public function save($key, $value, $ttl = NULL)
+ public function save($id, $data, $ttl = 60, $raw = FALSE)
{
return ($ttl)
- ? $this->_redis->setex($key, $ttl, $value)
- : $this->_redis->set($key, $value);
+ ? $this->_redis->setex($id, $ttl, $data)
+ : $this->_redis->set($id, $data);
}
// ------------------------------------------------------------------------
@@ -103,6 +105,38 @@ class CI_Cache_redis extends CI_Driver
// ------------------------------------------------------------------------
/**
+ * 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 $this->_redis->exists($id)
+ ? $this->_redis->incr($id, $offset)
+ : FALSE;
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * 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 $this->_redis->exists($id)
+ ? $this->_redis->decr($id, $offset)
+ : FALSE;
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
* Clean cache
*
* @return bool
@@ -163,8 +197,7 @@ class CI_Cache_redis extends CI_Driver
{
if (extension_loaded('redis'))
{
- $this->_setup_redis();
- return TRUE;
+ return $this->_setup_redis();
}
else
{
@@ -200,17 +233,33 @@ class CI_Cache_redis extends CI_Driver
try
{
- $this->_redis->connect($config['host'], $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('debug', 'Cache: Redis connection refused. Check the config.');
+ return FALSE;
+ }
}
catch (RedisException $e)
{
- show_error('Redis connection refused. ' . $e->getMessage());
+ log_message('debug', 'Cache: Redis connection refused ('.$e->getMessage().')');
+ return FALSE;
}
if (isset($config['password']))
{
$this->_redis->auth($config['password']);
}
+
+ return TRUE;
}
// ------------------------------------------------------------------------
diff --git a/system/libraries/Cache/drivers/Cache_wincache.php b/system/libraries/Cache/drivers/Cache_wincache.php
index 80d3ac13d..f412a538d 100644
--- a/system/libraries/Cache/drivers/Cache_wincache.php
+++ b/system/libraries/Cache/drivers/Cache_wincache.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 3.0
@@ -46,8 +46,8 @@ class CI_Cache_wincache extends CI_Driver {
* 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
+ * @param string $id Cache Ide
+ * @return mixed Value that is stored/FALSE on failure
*/
public function get($id)
{
@@ -63,12 +63,13 @@ class CI_Cache_wincache extends CI_Driver {
/**
* Cache Save
*
- * @param string Unique Key
- * @param mixed Data to store
- * @param int Length of time (in seconds) to cache the data
+ * @param string $id Cache ID
+ * @param mixed $data Data to store
+ * @param int $ttl Time to live (in seconds)
+ * @param bool $raw Whether to store the raw value (unused)
* @return bool true on success/false on failure
*/
- public function save($id, $data, $ttl = 60)
+ public function save($id, $data, $ttl = 60, $raw = FALSE)
{
return wincache_ucache_set($id, $data, $ttl);
}
@@ -89,6 +90,40 @@ class CI_Cache_wincache extends CI_Driver {
// ------------------------------------------------------------------------
/**
+ * 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)
+ {
+ $success = FALSE;
+ $value = wincache_ucache_inc($id, $offset, $success);
+
+ return ($success === TRUE) ? $value : FALSE;
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * 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)
+ {
+ $success = FALSE;
+ $value = wincache_ucache_dec($id, $offset, $success);
+
+ return ($success === TRUE) ? $value : FALSE;
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
* Clean the cache
*
* @return bool false on failure/true on success
diff --git a/system/libraries/Calendar.php b/system/libraries/Calendar.php
index 23d8ffb42..30f393318 100644
--- a/system/libraries/Calendar.php
+++ b/system/libraries/Calendar.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -96,6 +96,13 @@ class CI_Calendar {
public $next_prev_url = '';
/**
+ * Show days of other months
+ *
+ * @var bool
+ */
+ public $show_other_days = FALSE;
+
+ /**
* Class constructor
*
* Loads the calendar language file and sets the default time reference.
@@ -132,7 +139,7 @@ class CI_Calendar {
* Accepts an associative array as input, containing display preferences
*
* @param array config preferences
- * @return void
+ * @return CI_Calendar
*/
public function initialize($config = array())
{
@@ -143,6 +150,14 @@ class CI_Calendar {
$this->$key = $val;
}
}
+
+ // Set the next_prev_url to the controller if required but not defined
+ if ($this->show_next_prev === TRUE && empty($this->next_prev_url))
+ {
+ $this->next_prev_url = $this->CI->config->site_url($this->CI->router->class.'/'.$this->CI->router->method);
+ }
+
+ return $this;
}
// --------------------------------------------------------------------
@@ -261,10 +276,10 @@ class CI_Calendar {
for ($i = 0; $i < 7; $i++)
{
- $out .= ($is_current_month === TRUE && $day == $cur_day) ? $this->temp['cal_cell_start_today'] : $this->temp['cal_cell_start'];
-
if ($day > 0 && $day <= $total_days)
{
+ $out .= ($is_current_month === TRUE && $day == $cur_day) ? $this->temp['cal_cell_start_today'] : $this->temp['cal_cell_start'];
+
if (isset($data[$day]))
{
// Cells with content
@@ -279,14 +294,34 @@ class CI_Calendar {
$this->temp['cal_cell_no_content_today'] : $this->temp['cal_cell_no_content'];
$out .= str_replace('{day}', $day, $temp);
}
+
+ $out .= ($is_current_month === TRUE && $day == $cur_day) ? $this->temp['cal_cell_end_today'] : $this->temp['cal_cell_end'];
+ }
+ elseif ($this->show_other_days === TRUE)
+ {
+ $out .= $this->temp['cal_cell_start_other'];
+
+ if ($day <= 0)
+ {
+ // Day of previous month
+ $prev_month = $this->adjust_date($month - 1, $year);
+ $prev_month_days = $this->get_total_days($prev_month['month'], $prev_month['year']);
+ $out .= str_replace('{day}', $prev_month_days + $day, $this->temp['cal_cell_other']);
+ }
+ else
+ {
+ // Day of next month
+ $out .= str_replace('{day}', $day - $total_days, $this->temp['cal_cell_other']);
+ }
+
+ $out .= $this->temp['cal_cell_end_other'];
}
else
{
// Blank cells
- $out .= $this->temp['cal_cell_blank'];
+ $out .= $this->temp['cal_cell_start'].$this->temp['cal_cell_blank'].$this->temp['cal_cell_end'];
}
- $out .= ($is_current_month === TRUE && $day == $cur_day) ? $this->temp['cal_cell_end_today'] : $this->temp['cal_cell_end'];
$day++;
}
@@ -329,7 +364,7 @@ class CI_Calendar {
* Get Day Names
*
* Returns an array of day names (Sunday, Monday, etc.) based
- * on the type. Options: long, short, abrev
+ * on the type. Options: long, short, abr
*
* @param string
* @return array
@@ -457,13 +492,16 @@ class CI_Calendar {
'cal_row_start' => '<tr>',
'cal_cell_start' => '<td>',
'cal_cell_start_today' => '<td>',
+ 'cal_cell_start_other' => '<td style="color: #666;">',
'cal_cell_content' => '<a href="{content}">{day}</a>',
'cal_cell_content_today' => '<a href="{content}"><strong>{day}</strong></a>',
'cal_cell_no_content' => '{day}',
'cal_cell_no_content_today' => '<strong>{day}</strong>',
'cal_cell_blank' => '&nbsp;',
+ 'cal_cell_other' => '{day}',
'cal_cell_end' => '</td>',
'cal_cell_end_today' => '</td>',
+ 'cal_cell_end_other' => '</td>',
'cal_row_end' => '</tr>',
'table_close' => '</table>'
);
@@ -477,7 +515,7 @@ class CI_Calendar {
* Harvests the data within the template {pseudo-variables}
* used to display the calendar
*
- * @return void
+ * @return CI_Calendar
*/
public function parse_template()
{
@@ -485,12 +523,12 @@ class CI_Calendar {
if ($this->template === '')
{
- return;
+ return $this;
}
$today = array('cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today');
- foreach (array('table_open', 'table_close', 'heading_row_start', 'heading_previous_cell', 'heading_title_cell', 'heading_next_cell', 'heading_row_end', 'week_row_start', 'week_day_cell', 'week_row_end', 'cal_row_start', 'cal_cell_start', 'cal_cell_content', 'cal_cell_no_content', 'cal_cell_blank', 'cal_cell_end', 'cal_row_end', 'cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today') as $val)
+ foreach (array('table_open', 'table_close', 'heading_row_start', 'heading_previous_cell', 'heading_title_cell', 'heading_next_cell', 'heading_row_end', 'week_row_start', 'week_day_cell', 'week_row_end', 'cal_row_start', 'cal_cell_start', 'cal_cell_content', 'cal_cell_no_content', 'cal_cell_blank', 'cal_cell_end', 'cal_row_end', 'cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today', 'cal_cell_start_other', 'cal_cell_other', 'cal_cell_end_other') as $val)
{
if (preg_match('/\{'.$val.'\}(.*?)\{\/'.$val.'\}/si', $this->template, $match))
{
@@ -501,6 +539,8 @@ class CI_Calendar {
$this->temp[$val] = $this->temp[substr($val, 0, -6)];
}
}
+
+ return $this;
}
}
diff --git a/system/libraries/Cart.php b/system/libraries/Cart.php
index edc300bd7..5b05974e4 100644
--- a/system/libraries/Cart.php
+++ b/system/libraries/Cart.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2006 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2006 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -61,8 +61,6 @@ class CI_Cart {
public $product_name_safe = TRUE;
// --------------------------------------------------------------------------
- // Protected variables. Do not change!
- // --------------------------------------------------------------------------
/**
* Reference to CodeIgniter instance
@@ -323,10 +321,10 @@ class CI_Cart {
/**
* Update the cart
*
- * This function permits the quantity of a given item to be changed.
+ * 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
- * product ID and quantity for each item.
+ * rowid and quantity for each item.
*
* @param array
* @return bool
@@ -350,7 +348,19 @@ class CI_Cart {
}
else
{
- $this->_cart_contents[$items['rowid']]['qty'] = $items['qty'];
+ // 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;
diff --git a/system/libraries/Driver.php b/system/libraries/Driver.php
index 1bc365cbc..d2e41d6dd 100644
--- a/system/libraries/Driver.php
+++ b/system/libraries/Driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2006 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2006 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index efdbfd7c1..93c19de5e 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -710,18 +710,42 @@ class CI_Email {
/**
* Assign file attachments
*
- * @param string $filename
+ * @param string $file Can be local path, URL or buffered content
* @param string $disposition = 'attachment'
* @param string $newname = NULL
* @param string $mime = ''
* @return CI_Email
*/
- public function attach($filename, $disposition = '', $newname = NULL, $mime = '')
+ public function attach($file, $disposition = '', $newname = NULL, $mime = '')
{
+ if ($mime === '')
+ {
+ if (strpos($file, '://') === FALSE && ! file_exists($file))
+ {
+ $this->_set_error_message('lang:email_attachment_missing', $file);
+ return FALSE;
+ }
+
+ if ( ! $fp = @fopen($file, FOPEN_READ))
+ {
+ $this->_set_error_message('lang:email_attachment_unreadable', $file);
+ return FALSE;
+ }
+
+ $file_content = stream_get_contents($fp);
+ $mime = $this->_mime_types(pathinfo($file, PATHINFO_EXTENSION));
+ fclose($fp);
+ }
+ else
+ {
+ $file_content =& $file; // buffered file
+ }
+
$this->_attachments[] = array(
- 'name' => array($filename, $newname),
+ 'name' => array($file, $newname),
'disposition' => empty($disposition) ? 'attachment' : $disposition, // Can also be 'inline' Not sure if it matters
- 'type' => $mime
+ 'type' => $mime,
+ 'content' => chunk_split(base64_encode($file_content))
);
return $this;
@@ -730,6 +754,35 @@ class CI_Email {
// --------------------------------------------------------------------
/**
+ * Set and return attachment Content-ID
+ *
+ * Useful for attached inline pictures
+ *
+ * @param string $filename
+ * @return string
+ */
+ public function attachment_cid($filename)
+ {
+ if ($this->multipart !== 'related')
+ {
+ $this->multipart = 'related'; // Thunderbird need this for inline images
+ }
+
+ for ($i = 0, $c = count($this->_attachments); $i < $c; $i++)
+ {
+ if ($this->_attachments[$i]['name'][0] === $filename)
+ {
+ $this->_attachments[$i]['cid'] = uniqid(basename($this->_attachments[$i]['name'][0]).'@');
+ return $this->_attachments[$i]['cid'];
+ }
+ }
+
+ return FALSE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* Add a Header Item
*
* @param string
@@ -769,7 +822,7 @@ class CI_Email {
* @param string
* @return CI_Email
*/
- public function set_alt_message($str = '')
+ public function set_alt_message($str)
{
$this->alt_message = (string) $str;
return $this;
@@ -1361,47 +1414,22 @@ class CI_Email {
$filename = $this->_attachments[$i]['name'][0];
$basename = ($this->_attachments[$i]['name'][1] === NULL)
? basename($filename) : $this->_attachments[$i]['name'][1];
- $ctype = $this->_attachments[$i]['type'];
- $file_content = '';
-
- if ($ctype === '')
- {
- if ( ! file_exists($filename))
- {
- $this->_set_error_message('lang:email_attachment_missing', $filename);
- return FALSE;
- }
-
- $file = filesize($filename) +1;
-
- if ( ! $fp = fopen($filename, FOPEN_READ))
- {
- $this->_set_error_message('lang:email_attachment_unreadable', $filename);
- return FALSE;
- }
-
- $ctype = $this->_mime_types(pathinfo($filename, PATHINFO_EXTENSION));
- $file_content = fread($fp, $file);
- fclose($fp);
- }
- else
- {
- $file_content =& $this->_attachments[$i]['name'][0];
- }
$attachment[$z++] = '--'.$this->_atc_boundary.$this->newline
- .'Content-type: '.$ctype.'; '
+ .'Content-type: '.$this->_attachments[$i]['type'].'; '
.'name="'.$basename.'"'.$this->newline
.'Content-Disposition: '.$this->_attachments[$i]['disposition'].';'.$this->newline
- .'Content-Transfer-Encoding: base64'.$this->newline;
+ .'Content-Transfer-Encoding: base64'.$this->newline
+ .(empty($this->_attachments[$i]['cid']) ? '' : 'Content-ID: <'.$this->_attachments[$i]['cid'].'>'.$this->newline);
- $attachment[$z++] = chunk_split(base64_encode($file_content));
+ $attachment[$z++] = $this->_attachments[$i]['content'];
}
$body .= implode($this->newline, $attachment).$this->newline.'--'.$this->_atc_boundary.'--';
$this->_finalbody = ($this->_get_protocol() === 'mail')
? $body
: $hdr.$this->newline.$this->newline.$body;
+
return TRUE;
}
@@ -1516,7 +1544,7 @@ class CI_Email {
{
return mb_encode_mimeheader($str, $this->charset, 'Q', $this->crlf);
}
- elseif (extension_loaded('iconv'))
+ elseif (ICONV_ENABLED === TRUE)
{
$output = @iconv_mime_encode('', $str,
array(
@@ -1545,9 +1573,9 @@ class CI_Email {
isset($chars) OR $chars = strlen($str);
$output = '=?'.$this->charset.'?Q?';
- for ($i = 0, $length = strlen($output), $iconv = extension_loaded('iconv'); $i < $chars; $i++)
+ for ($i = 0, $length = strlen($output); $i < $chars; $i++)
{
- $chr = ($this->charset === 'UTF-8' && $iconv === TRUE)
+ $chr = ($this->charset === 'UTF-8' && ICONV_ENABLED === TRUE)
? '='.implode('=', str_split(strtoupper(bin2hex(iconv_substr($str, $i, 1, $this->charset))), 2))
: '='.strtoupper(bin2hex($str[$i]));
@@ -2069,7 +2097,16 @@ class CI_Email {
*/
protected function _send_data($data)
{
- if ( ! fwrite($this->_smtp_connect, $data.$this->newline))
+ $data .= $this->newline;
+ for ($written = 0, $length = strlen($data); $written < $length; $written += $result)
+ {
+ if (($result = fwrite($this->_smtp_connect, substr($data, $written))) === FALSE)
+ {
+ break;
+ }
+ }
+
+ if ($result === FALSE)
{
$this->_set_error_message('lang:email_smtp_data_failure', $data);
return FALSE;
diff --git a/system/libraries/Encrypt.php b/system/libraries/Encrypt.php
index 8ac5420de..f72bd2302 100644
--- a/system/libraries/Encrypt.php
+++ b/system/libraries/Encrypt.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/libraries/Encryption.php b/system/libraries/Encryption.php
new file mode 100644
index 000000000..3ce9f1b95
--- /dev/null
+++ b/system/libraries/Encryption.php
@@ -0,0 +1,887 @@
+<?php
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.2.4 or newer
+ *
+ * NOTICE OF LICENSE
+ *
+ * Licensed under the Open Software License version 3.0
+ *
+ * This source file is subject to the Open Software License (OSL 3.0) that is
+ * bundled with this package in the files license.txt / license.rst. It is
+ * also available through the world wide web at this URL:
+ * http://opensource.org/licenses/OSL-3.0
+ * If you did not receive a copy of the license and are unable to obtain it
+ * through the world wide web, please send an email to
+ * licensing@ellislab.com so we can send you a copy immediately.
+ *
+ * @package CodeIgniter
+ * @author EllisLab Dev Team
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
+ * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
+ * @link http://codeigniter.com
+ * @since Version 3.0
+ * @filesource
+ */
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/**
+ * CodeIgniter Encryption Class
+ *
+ * Provides two-way keyed encryption via PHP's MCrypt and/or OpenSSL extensions.
+ *
+ * @package CodeIgniter
+ * @subpackage Libraries
+ * @category Libraries
+ * @author Andrey Andreev
+ * @link http://codeigniter.com/user_guide/libraries/encryption.html
+ */
+class CI_Encryption {
+
+ /**
+ * Encryption cipher
+ *
+ * @var string
+ */
+ protected $_cipher = 'aes-128';
+
+ /**
+ * Cipher mode
+ *
+ * @var string
+ */
+ protected $_mode = 'cbc';
+
+ /**
+ * Cipher handle
+ *
+ * @var mixed
+ */
+ protected $_handle;
+
+ /**
+ * Encryption key
+ *
+ * @var string
+ */
+ protected $_key;
+
+ /**
+ * PHP extension to be used
+ *
+ * @var string
+ */
+ protected $_driver;
+
+ /**
+ * List of usable drivers (PHP extensions)
+ *
+ * @var array
+ */
+ protected $_drivers = array();
+
+ /**
+ * List of available modes
+ *
+ * @var array
+ */
+ protected $_modes = array(
+ 'mcrypt' => array(
+ 'cbc' => 'cbc',
+ 'ecb' => 'ecb',
+ 'ofb' => 'nofb',
+ 'ofb8' => 'ofb',
+ 'cfb' => 'ncfb',
+ 'cfb8' => 'cfb',
+ 'ctr' => 'ctr',
+ 'stream' => 'stream'
+ ),
+ 'openssl' => array(
+ 'cbc' => 'cbc',
+ 'ecb' => 'ecb',
+ 'ofb' => 'ofb',
+ 'cfb' => 'cfb',
+ 'cfb8' => 'cfb8',
+ 'ctr' => 'ctr',
+ 'stream' => '',
+ 'gcm' => 'gcm',
+ 'xts' => 'xts'
+ )
+ );
+
+ /**
+ * List of supported HMAC algorightms
+ *
+ * name => digest size pairs
+ *
+ * @var array
+ */
+ protected $_digests = array(
+ 'sha224' => 28,
+ 'sha256' => 32,
+ 'sha384' => 48,
+ 'sha512' => 64
+ );
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Class constructor
+ *
+ * @param array $params Configuration parameters
+ * @return void
+ */
+ public function __construct(array $params = array())
+ {
+ $this->_drivers = array(
+ 'mcrypt' => defined('MCRYPT_DEV_URANDOM'),
+ // While OpenSSL is available for PHP 5.3.0, an IV parameter
+ // for the encrypt/decrypt functions is only available since 5.3.3
+ 'openssl' => (is_php('5.3.3') && extension_loaded('openssl'))
+ );
+
+ if ( ! $this->_drivers['mcrypt'] && ! $this->_drivers['openssl'])
+ {
+ return show_error('Encryption: Unable to find an available encryption driver.');
+ }
+
+ $this->initialize($params);
+ if ( ! isset($this->_key) && strlen($key = config_item('encryption_key')) > 0)
+ {
+ $this->_key = $key;
+ }
+
+ log_message('debug', 'Encryption Class Initialized');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Initialize
+ *
+ * @param array $params Configuration parameters
+ * @return CI_Encryption
+ */
+ public function initialize(array $params)
+ {
+ if ( ! empty($params['driver']))
+ {
+ if (isset($this->_drivers[$params['driver']]))
+ {
+ if ($this->_drivers[$params['driver']])
+ {
+ $this->_driver = $params['driver'];
+ }
+ else
+ {
+ log_message('error', "Encryption: Driver '".$params['driver']."' is not available.");
+ }
+ }
+ else
+ {
+ log_message('error', "Encryption: Unknown driver '".$params['driver']."' cannot be configured.");
+ }
+ }
+
+ if (empty($this->_driver))
+ {
+ $this->_driver = ($this->_drivers['openssl'] === TRUE)
+ ? 'openssl'
+ : 'mcrypt';
+
+ log_message('debug', "Encryption: Auto-configured driver '".$this->_driver."'.");
+ }
+
+ empty($params['key']) OR $this->_key = $params['key'];
+ $this->{'_'.$this->_driver.'_initialize'}($params);
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Initialize MCrypt
+ *
+ * @param array $params Configuration parameters
+ * @return void
+ */
+ protected function _mcrypt_initialize($params)
+ {
+ if ( ! empty($params['cipher']))
+ {
+ $params['cipher'] = strtolower($params['cipher']);
+ $this->_cipher_alias($params['cipher']);
+
+ if ( ! in_array($params['cipher'], mcrypt_list_algorithms(), TRUE))
+ {
+ log_message('error', 'Encryption: MCrypt cipher '.strtoupper($params['cipher']).' is not available.');
+ }
+ else
+ {
+ $this->_cipher = $params['cipher'];
+ }
+ }
+
+ if ( ! empty($params['mode']))
+ {
+ $params['mode'] = strtolower($params['mode']);
+ if ( ! isset($this->_modes['mcrypt'][$params['mode']]))
+ {
+ log_message('error', 'Encryption: MCrypt mode '.strtotupper($params['mode']).' is not available.');
+ }
+ else
+ {
+ $this->_mode = $this->_modes['mcrypt'][$params['mode']];
+ }
+ }
+
+ if (isset($this->_cipher, $this->_mode))
+ {
+ if (is_resource($this->_handle)
+ && (strtolower(mcrypt_enc_get_algorithms_name($this->_handle)) !== $this->_cipher
+ OR strtolower(mcrypt_enc_get_modes_name($this->_handle)) !== $this->_mode)
+ )
+ {
+ mcrypt_module_close($this->_handle);
+ }
+
+ if ($this->_handle = mcrypt_module_open($this->_cipher, '', $this->_mode, ''))
+ {
+ log_message('debug', 'Encryption: MCrypt cipher '.strtoupper($this->_cipher).' initialized in '.strtoupper($this->_mode).' mode.');
+ }
+ else
+ {
+ log_message('error', 'Encryption: Unable to initialize MCrypt with cipher '.strtoupper($this->_cipher).' in '.strtoupper($this->_mode).' mode.');
+ }
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Initialize OpenSSL
+ *
+ * @param array $params Configuration parameters
+ * @return void
+ */
+ protected function _openssl_initialize($params)
+ {
+ if ( ! empty($params['cipher']))
+ {
+ $params['cipher'] = strtolower($params['cipher']);
+ $this->_cipher_alias($params['cipher']);
+ $this->_cipher = $params['cipher'];
+ }
+
+ if ( ! empty($params['mode']))
+ {
+ $params['mode'] = strtolower($params['mode']);
+ if ( ! isset($this->_modes['openssl'][$params['mode']]))
+ {
+ log_message('error', 'Encryption: OpenSSL mode '.strtotupper($params['mode']).' is not available.');
+ }
+ else
+ {
+ $this->_mode = $this->_modes['openssl'][$params['mode']];
+ }
+ }
+
+ if (isset($this->_cipher, $this->_mode))
+ {
+ // This is mostly for the stream mode, which doesn't get suffixed in OpenSSL
+ $handle = empty($this->_mode)
+ ? $this->_cipher
+ : $this->_cipher.'-'.$this->_mode;
+
+ if ( ! in_array($handle, openssl_get_cipher_methods(), TRUE))
+ {
+ $this->_handle = NULL;
+ log_message('error', 'Encryption: Unable to initialize OpenSSL with method '.strtoupper($handle).'.');
+ }
+ else
+ {
+ $this->_handle = $handle;
+ log_message('debug', 'Encryption: OpenSSL initialized with method '.strtoupper($handle).'.');
+ }
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Encrypt
+ *
+ * @param string $data Input data
+ * @param array $params Input parameters
+ * @return string
+ */
+ public function encrypt($data, array $params = NULL)
+ {
+ if (($params = $this->_get_params($params)) === FALSE)
+ {
+ return FALSE;
+ }
+
+ isset($params['key']) OR $params['key'] = $this->hkdf($this->_key, 'sha512', NULL, strlen($this->_key), 'encryption');
+
+ if (($data = $this->{'_'.$this->_driver.'_encrypt'}($data, $params)) === FALSE)
+ {
+ return FALSE;
+ }
+
+ $params['base64'] && $data = base64_encode($data);
+
+ if (isset($params['hmac_digest']))
+ {
+ isset($params['hmac_key']) OR $params['hmac_key'] = $this->hkdf($this->_key, 'sha512', NULL, NULL, 'authentication');
+ return hash_hmac($params['hmac_digest'], $data, $params['hmac_key'], ! $params['base64']).$data;
+ }
+
+ return $data;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Encrypt via MCrypt
+ *
+ * @param string $data Input data
+ * @param array $params Input parameters
+ * @return string
+ */
+ protected function _mcrypt_encrypt($data, $params)
+ {
+ if ( ! is_resource($params['handle']))
+ {
+ return FALSE;
+ }
+ elseif ( ! isset($params['iv']))
+ {
+ // The greater-than-1 comparison is mostly a work-around for a bug,
+ // where 1 is returned for ARCFour instead of 0.
+ $params['iv'] = (($iv_size = mcrypt_enc_get_iv_size($params['handle'])) > 1)
+ ? mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM)
+ : NULL;
+ }
+
+ // CAST-128 compatibility (http://tools.ietf.org/rfc/rfc2144.txt)
+ //
+ // RFC2144 says that keys shorter than 16 bytes are to be padded with
+ // zero bytes to 16 bytes, but (surprise) MCrypt doesn't do that.
+ if ($params['cipher'] === 'cast-128' && ($kl = strlen($params['key'])) < 16)
+ {
+ $params['key'] .= str_repeat("\x0", 16 - $kl);
+ }
+
+ if (mcrypt_generic_init($params['handle'], $params['key'], $params['iv']) < 0)
+ {
+ if ($params['handle'] !== $this->_handle)
+ {
+ mcrypt_module_close($params['handle']);
+ }
+
+ return FALSE;
+ }
+
+ // Use PKCS#7 padding in order to ensure compatibility with OpenSSL
+ // and other implementations outside of PHP.
+ if (in_array(strtolower(mcrypt_enc_get_modes_name($params['handle'])), array('cbc', 'ecb'), TRUE))
+ {
+ $block_size = mcrypt_enc_get_block_size($params['handle']);
+ $pad = $block_size - (strlen($data) % $block_size);
+ $data .= str_repeat(chr($pad), $pad);
+ }
+
+ // Work-around for yet another strange behavior in MCrypt.
+ //
+ // When encrypting in ECB mode, the IV is ignored. Yet
+ // mcrypt_enc_get_iv_size() returns a value larger than 0
+ // even if ECB is used AND mcrypt_generic_init() complains
+ // if you don't pass an IV with length equal to the said
+ // return value.
+ //
+ // This probably would've been fine (even though still wasteful),
+ // but OpenSSL isn't that dumb and we need to make the process
+ // portable, so ...
+ $data = (mcrypt_enc_get_modes_name($params['handle']) !== 'ECB')
+ ? $params['iv'].mcrypt_generic($params['handle'], $data)
+ : mcrypt_generic($params['handle'], $data);
+
+ mcrypt_generic_deinit($params['handle']);
+ if ($params['handle'] !== $this->_handle)
+ {
+ mcrypt_module_close($params['handle']);
+ }
+
+ return $data;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Encrypt via OpenSSL
+ *
+ * @param string $data Input data
+ * @param array $params Input parameters
+ * @return string
+ */
+ protected function _openssl_encrypt($data, $params)
+ {
+ if (empty($params['handle']))
+ {
+ return FALSE;
+ }
+ elseif ( ! isset($params['iv']))
+ {
+ $params['iv'] = ($iv_size = openssl_cipher_iv_length($params['handle']))
+ ? openssl_random_pseudo_bytes($iv_size)
+ : NULL;
+ }
+
+ $data = openssl_encrypt(
+ $data,
+ $params['handle'],
+ $params['key'],
+ 1, // DO NOT TOUCH!
+ $params['iv']
+ );
+
+ if ($data === FALSE)
+ {
+ return FALSE;
+ }
+
+ return $params['iv'].$data;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Decrypt
+ *
+ * @param string $data Encrypted data
+ * @param array $params Input parameters
+ * @return string
+ */
+ public function decrypt($data, array $params = NULL)
+ {
+ if (($params = $this->_get_params($params)) === FALSE)
+ {
+ return FALSE;
+ }
+
+ if (isset($params['hmac_digest']))
+ {
+ // This might look illogical, but it is done during encryption as well ...
+ // The 'base64' value is effectively an inverted "raw data" parameter
+ $digest_size = ($params['base64'])
+ ? $this->_digests[$params['hmac_digest']] * 2
+ : $this->_digests[$params['hmac_digest']];
+
+ if (strlen($data) <= $digest_size)
+ {
+ return FALSE;
+ }
+
+ $hmac_input = substr($data, 0, $digest_size);
+ $data = substr($data, $digest_size);
+
+ isset($params['hmac_key']) OR $params['hmac_key'] = $this->hkdf($this->_key, 'sha512', NULL, NULL, 'authentication');
+ $hmac_check = hash_hmac($params['hmac_digest'], $data, $params['hmac_key'], ! $params['base64']);
+
+ // Time-attack-safe comparison
+ $diff = 0;
+ for ($i = 0; $i < $digest_size; $i++)
+ {
+ $diff |= ord($hmac_input[$i]) ^ ord($hmac_check[$i]);
+ }
+
+ if ($diff !== 0)
+ {
+ return FALSE;
+ }
+ }
+
+ if ($params['base64'])
+ {
+ $data = base64_decode($data);
+ }
+
+ if (isset($params['iv']) && strncmp($params['iv'], $data, $iv_size = strlen($params['iv'])) === 0)
+ {
+ $data = substr($data, $iv_size);
+ }
+
+ isset($params['key']) OR $params['key'] = $this->hkdf($this->_key, 'sha512', NULL, strlen($this->_key), 'encryption');
+
+ return $this->{'_'.$this->_driver.'_decrypt'}($data, $params);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Decrypt via MCrypt
+ *
+ * @param string $data Encrypted data
+ * @param array $params Input parameters
+ * @return string
+ */
+ protected function _mcrypt_decrypt($data, $params)
+ {
+ if ( ! is_resource($params['handle']))
+ {
+ return FALSE;
+ }
+ elseif ( ! isset($params['iv']))
+ {
+ // The greater-than-1 comparison is mostly a work-around for a bug,
+ // where 1 is returned for ARCFour instead of 0.
+ if (($iv_size = mcrypt_enc_get_iv_size($params['handle'])) > 1)
+ {
+ if (mcrypt_enc_get_modes_name($params['handle']) !== 'ECB')
+ {
+ $params['iv'] = substr($data, 0, $iv_size);
+ $data = substr($data, $iv_size);
+ }
+ else
+ {
+ // MCrypt is dumb and this is ignored, only size matters
+ $params['iv'] = str_repeat("\x0", $iv_size);
+ }
+ }
+ else
+ {
+ $params['iv'] = NULL;
+ }
+ }
+
+ // CAST-128 compatibility (http://tools.ietf.org/rfc/rfc2144.txt)
+ //
+ // RFC2144 says that keys shorter than 16 bytes are to be padded with
+ // zero bytes to 16 bytes, but (surprise) MCrypt doesn't do that.
+ if ($params['cipher'] === 'cast-128' && ($kl = strlen($params['key'])) < 16)
+ {
+ $params['key'] .= str_repeat("\x0", 16 - $kl);
+ }
+
+ if (mcrypt_generic_init($params['handle'], $params['key'], $params['iv']) < 0)
+ {
+ if ($params['handle'] !== $this->_handle)
+ {
+ mcrypt_module_close($params['handle']);
+ }
+
+ return FALSE;
+ }
+
+ $data = mdecrypt_generic($params['handle'], $data);
+ // Remove PKCS#7 padding, if necessary
+ if (in_array(strtolower(mcrypt_enc_get_modes_name($params['handle'])), array('cbc', 'ecb'), TRUE))
+ {
+ $data = substr($data, 0, -ord($data[strlen($data)-1]));
+ }
+
+ mcrypt_generic_deinit($params['handle']);
+ if ($params['handle'] !== $this->_handle)
+ {
+ mcrypt_module_close($params['handle']);
+ }
+
+ return $data;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Decrypt via OpenSSL
+ *
+ * @param string $data Encrypted data
+ * @param array $params Input parameters
+ * @return string
+ */
+ protected function _openssl_decrypt($data, $params)
+ {
+ if ( ! isset($params['iv']))
+ {
+ if ($iv_size = openssl_cipher_iv_length($params['handle']))
+ {
+ $params['iv'] = substr($data, 0, $iv_size);
+ $data = substr($data, $iv_size);
+ }
+ else
+ {
+ $params['iv'] = NULL;
+ }
+ }
+
+ return empty($params['handle'])
+ ? FALSE
+ : openssl_decrypt(
+ $data,
+ $params['handle'],
+ $params['key'],
+ 1, // DO NOT TOUCH!
+ $params['iv']
+ );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Get params
+ *
+ * @param array $params Input parameters
+ * @return array
+ */
+ protected function _get_params($params)
+ {
+ if (empty($params))
+ {
+ return isset($this->_cipher, $this->_mode, $this->_key, $this->_handle)
+ ? array(
+ 'handle' => $this->_handle,
+ 'cipher' => $this->_cipher,
+ 'mode' => $this->_mode,
+ 'key' => NULL,
+ 'base64' => TRUE,
+ 'hmac_digest' => ($this->_mode !== 'gcm' ? 'sha512' : NULL),
+ 'hmac_key' => NULL
+ )
+ : FALSE;
+ }
+ elseif ( ! isset($params['cipher'], $params['mode'], $params['key']))
+ {
+ return FALSE;
+ }
+
+ if (isset($params['mode']))
+ {
+ $params['mode'] = strtolower($params['mode']);
+ if ( ! isset($this->_modes[$this->_driver][$params['mode']]))
+ {
+ return FALSE;
+ }
+ else
+ {
+ $params['mode'] = $this->_modes[$this->_driver][$params['mode']];
+ }
+ }
+
+ if ($params['mode'] === 'gcm' OR (isset($params['hmac']) && $params['hmac'] === FALSE))
+ {
+ $params['hmac_digest'] = $params['hmac_key'] = NULL;
+ }
+ else
+ {
+ if ( ! isset($params['hmac_key']))
+ {
+ return FALSE;
+ }
+ elseif (isset($params['hmac_digest']))
+ {
+ $params['hmac_digest'] = strtolower($params['hmac_digest']);
+ if ( ! isset($this->_digests[$params['hmac_digest']]))
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ $params['hmac_digest'] = 'sha512';
+ }
+ }
+
+ $params = array(
+ 'handle' => NULL,
+ 'cipher' => $params['cipher'],
+ 'mode' => $params['mode'],
+ 'key' => $params['key'],
+ 'iv' => isset($params['iv']) ? $params['iv'] : NULL,
+ 'base64' => isset($params['raw_data']) ? ! $params['raw_data'] : FALSE,
+ 'hmac_digest' => $params['hmac_digest'],
+ 'hmac_key' => $params['hmac_key']
+ );
+
+ $this->_cipher_alias($params['cipher']);
+ $params['handle'] = ($params['cipher'] !== $this->_cipher OR $params['mode'] !== $this->_mode)
+ ? $this->{'_'.$this->_driver.'_get_handle'}($params['cipher'], $params['mode'])
+ : $this->_handle;
+
+ return $params;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Get MCrypt handle
+ *
+ * @param string $cipher Cipher name
+ * @param string $mode Encryption mode
+ * @return resource
+ */
+ protected function _mcrypt_get_handle($cipher, $mode)
+ {
+ return mcrypt_module_open($cipher, '', $mode, '');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Get OpenSSL handle
+ *
+ * @param string $cipher Cipher name
+ * @param string $mode Encryption mode
+ * @return string
+ */
+ protected function _openssl_get_handle($cipher, $mode)
+ {
+ // OpenSSL methods aren't suffixed with '-stream' for this mode
+ return ($mode === 'stream')
+ ? $cipher
+ : $cipher.'-'.$mode;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Cipher alias
+ *
+ * Tries to translate cipher names between MCrypt and OpenSSL's "dialects".
+ *
+ * @param string $cipher Cipher name
+ * @return void
+ */
+ protected function _cipher_alias(&$cipher)
+ {
+ static $dictionary;
+
+ if (empty($dictionary))
+ {
+ $dictionary = array(
+ 'mcrypt' => array(
+ 'aes-128' => 'rijndael-128',
+ 'aes-192' => 'rijndael-128',
+ 'aes-256' => 'rijndael-128',
+ 'des3-ede3' => 'tripledes',
+ 'bf' => 'blowfish',
+ 'cast5' => 'cast-128',
+ 'rc4' => 'arcfour',
+ 'rc4-40' => 'arcfour'
+ ),
+ 'openssl' => array(
+ 'rijndael-128' => 'aes-128',
+ 'tripledes' => 'des-ede3',
+ 'blowfish' => 'bf',
+ 'cast-128' => 'cast5',
+ 'arcfour' => 'rc4-40',
+ 'rc4' => 'rc4-40'
+ )
+ );
+
+ // Notes:
+ //
+ // - Rijndael-128 is, at the same time all three of AES-128,
+ // AES-192 and AES-256. The only difference between them is
+ // the key size. Rijndael-192, Rijndael-256 on the other hand
+ // also have different block sizes and are NOT AES-compatible.
+ //
+ // - Blowfish is said to be supporting key sizes between
+ // 4 and 56 bytes, but it appears that between MCrypt and
+ // OpenSSL, only those of 16 and more bytes are compatible.
+ // Also, don't know what MCrypt's 'blowfish-compat' is.
+ //
+ // - CAST-128/CAST5 produces a longer cipher when encrypted via
+ // OpenSSL, but (strangely enough) can be decrypted by either
+ // extension anyway.
+ // Also, RFC2144 says that the cipher supports key sizes
+ // between 5 and 16 bytes by the implementation actually
+ // zero-padding them to 16 bytes, but MCrypt doesn't do that.
+ //
+ // - RC4 (ARCFour) has a strange implementation under OpenSSL.
+ // Its 'rc4-40' cipher method seems to work flawlessly, yet
+ // there's another one, 'rc4' that only works with a 16-byte key.
+ //
+ // - DES is compatible, but doesn't need an alias.
+ //
+ // Other seemingly matching ciphers between MCrypt, OpenSSL:
+ //
+ // - RC2 is NOT compatible and only an obscure forum post
+ // confirms that it is MCrypt's fault.
+ }
+
+ if (isset($dictionary[$this->_driver][$cipher]))
+ {
+ $cipher = $dictionary[$this->_driver][$cipher];
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * HKDF
+ *
+ * @link https://tools.ietf.org/rfc/rfc5869.txt
+ * @param $key Input key
+ * @param $digest A SHA-2 hashing algorithm
+ * @param $salt Optional salt
+ * @param $length Output length (defaults to the selected digest size)
+ * @param $info Optional context/application-specific info
+ * @return string A pseudo-random key
+ */
+ public function hkdf($key, $digest = 'sha512', $salt = NULL, $length = NULL, $info = '')
+ {
+ if ( ! isset($this->_digests[$digest]))
+ {
+ return FALSE;
+ }
+
+ if (empty($length) OR ! is_int($length))
+ {
+ $length = $this->_digests[$digest];
+ }
+ elseif ($length > (255 * $this->_digests[$digest]))
+ {
+ return FALSE;
+ }
+
+ isset($salt) OR $salt = str_repeat("\0", $this->_digests[$digest]);
+
+ $prk = hash_hmac($digest, $key, $salt, TRUE);
+ $key = '';
+ for ($key_block = '', $block_index = 1; strlen($key) < $length; $block_index++)
+ {
+ $key_block = hash_hmac($digest, $key_block.$info.chr($block_index), $prk, TRUE);
+ $key .= $key_block;
+ }
+
+ return substr($key, 0, $length);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * __get() magic
+ *
+ * @param string $key Property name
+ * @return mixed
+ */
+ public function __get($key)
+ {
+ // Because aliases
+ if ($key === 'mode')
+ {
+ return array_search($this->_mode, $this->_modes[$this->_driver], TRUE);
+ }
+ elseif (in_array($key, array('cipher', 'driver', 'drivers', 'digests'), TRUE))
+ {
+ return $this->{'_'.$key};
+ }
+
+ return NULL;
+ }
+
+}
+
+/* End of file Encryption.php */
+/* Location: ./system/libraries/Encryption.php */ \ No newline at end of file
diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php
index 8b9bfa897..0c4f94914 100644
--- a/system/libraries/Form_validation.php
+++ b/system/libraries/Form_validation.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -144,14 +144,16 @@ class CI_Form_validation {
* Set Rules
*
* This function takes an array of field names and validation
- * rules as input, validates the info, and stores it
+ * rules as input, any custom error messages, validates the info,
+ * and stores it
*
* @param mixed $field
* @param string $label
* @param mixed $rules
+ * @param array $errors
* @return CI_Form_validation
*/
- public function set_rules($field, $label = '', $rules = '')
+ public function set_rules($field, $label = '', $rules = '', $errors = array())
{
// No reason to set rules if we have no POST data
// or a validation array has not been specified
@@ -175,8 +177,11 @@ class CI_Form_validation {
// If the field label wasn't passed we use the field name
$label = isset($row['label']) ? $row['label'] : $row['field'];
+ // Add the custom error message array
+ $errors = (isset($row['errors']) && is_array($row['errors'])) ? $row['errors'] : array();
+
// Here we go!
- $this->set_rules($row['field'], $label, $row['rules']);
+ $this->set_rules($row['field'], $label, $row['rules'], $errors);
}
return $this;
@@ -224,6 +229,7 @@ class CI_Form_validation {
'field' => $field,
'label' => $label,
'rules' => $rules,
+ 'errors' => $errors,
'is_array' => $is_array,
'keys' => $indexes,
'postdata' => NULL,
@@ -246,14 +252,16 @@ class CI_Form_validation {
* each array due to the limitations of CI's singleton
*
* @param array $data
- * @return void
+ * @return CI_Form_validation
*/
- public function set_data($data = '')
+ public function set_data(array $data)
{
- if ( ! empty($data) && is_array($data))
+ if ( ! empty($data))
{
$this->validation_data = $data;
}
+
+ return $this;
}
// --------------------------------------------------------------------
@@ -304,12 +312,12 @@ class CI_Form_validation {
*
* Gets the error message associated with a particular field
*
- * @param string the field name
- * @param string the html start tag
- * @param strign the html end tag
+ * @param string $field Field name
+ * @param string $prefix HTML start tag
+ * @param string $suffix HTML end tag
* @return string
*/
- public function error($field = '', $prefix = '', $suffix = '')
+ public function error($field, $prefix = '', $suffix = '')
{
if (empty($this->_field_data[$field]['error']))
{
@@ -414,18 +422,15 @@ class CI_Form_validation {
return FALSE;
}
- // Is there a validation rule for the particular URI being accessed?
- $uri = ($group === '') ? trim($this->CI->uri->ruri_string(), '/') : $group;
-
- if ($uri !== '' && isset($this->_config_rules[$uri]))
+ if (empty($group))
{
- $this->set_rules($this->_config_rules[$uri]);
- }
- else
- {
- $this->set_rules($this->_config_rules);
+ // 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;
}
+ $this->set_rules(isset($this->_config_rules[$group]) ? $this->_config_rules[$group] : $this->_config_rules);
+
// Were we able to set the rules correctly?
if (count($this->_field_data) === 0)
{
@@ -605,7 +610,12 @@ class CI_Form_validation {
// Set the message type
$type = in_array('required', $rules) ? 'required' : 'isset';
- if (isset($this->_error_messages[$type]))
+ // Check if a custom message is defined
+ if (isset($this->_field_data[$row['field']]['errors'][$type]))
+ {
+ $line = $this->_field_data[$row['field']]['errors'][$type];
+ }
+ elseif (isset($this->_error_messages[$type]))
{
$line = $this->_error_messages[$type];
}
@@ -749,7 +759,12 @@ class CI_Form_validation {
// Did the rule test negatively? If so, grab the error.
if ($result === FALSE)
{
- if ( ! isset($this->_error_messages[$rule]))
+ // Check if a custom message is defined
+ if (isset($this->_field_data[$row['field']]['errors'][$rule]))
+ {
+ $line = $this->_field_data[$row['field']]['errors'][$rule];
+ }
+ elseif ( ! isset($this->_error_messages[$rule]))
{
if (FALSE === ($line = $this->CI->lang->line('form_validation_'.$rule))
// DEPRECATED support for non-prefixed keys
@@ -898,12 +913,19 @@ class CI_Form_validation {
}
$field = $this->_field_data[$field]['postdata'];
+ $value = (string) $value;
if (is_array($field))
{
- if ( ! in_array($value, $field))
+ // Note: in_array('', array(0)) returns TRUE, do not use it
+ foreach ($field as &$v)
{
- return '';
+ if ($value === $v)
+ {
+ return ' selected="selected"';
+ }
}
+
+ return '';
}
elseif (($field === '' OR $value === '') OR ($field !== $value))
{
@@ -934,12 +956,19 @@ class CI_Form_validation {
}
$field = $this->_field_data[$field]['postdata'];
+ $value = (string) $value;
if (is_array($field))
{
- if ( ! in_array($value, $field))
+ // Note: in_array('', array(0)) returns TRUE, do not use it
+ foreach ($field as &$v)
{
- return '';
+ if ($value === $v)
+ {
+ return ' checked="checked"';
+ }
}
+
+ return '';
}
elseif (($field === '' OR $value === '') OR ($field !== $value))
{
@@ -1509,7 +1538,7 @@ class CI_Form_validation {
* Prevents subsequent validation routines from being affected by the
* results of any previous validation routine due to the CI singleton.
*
- * @return void
+ * @return CI_Form_validation
*/
public function reset_validation()
{
@@ -1518,6 +1547,7 @@ class CI_Form_validation {
$this->_error_array = array();
$this->_error_messages = array();
$this->error_string = '';
+ return $this;
}
}
diff --git a/system/libraries/Ftp.php b/system/libraries/Ftp.php
index dc6bbd226..ef3b7d70d 100644
--- a/system/libraries/Ftp.php
+++ b/system/libraries/Ftp.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -214,12 +214,12 @@ class CI_FTP {
* Internally, this parameter is only used by the "mirror" function below.
*
* @param string $path
- * @param bool $supress_debug
+ * @param bool $suppress_debug
* @return bool
*/
- public function changedir($path = '', $supress_debug = FALSE)
+ public function changedir($path, $suppress_debug = FALSE)
{
- if ($path === '' OR ! $this->_is_conn())
+ if ( ! $this->_is_conn())
{
return FALSE;
}
@@ -228,7 +228,7 @@ class CI_FTP {
if ($result === FALSE)
{
- if ($this->debug === TRUE && $supress_debug === FALSE)
+ if ($this->debug === TRUE && $suppress_debug === FALSE)
{
$this->_error('ftp_unable_to_changedir');
}
@@ -247,7 +247,7 @@ class CI_FTP {
* @param int $permissions
* @return bool
*/
- public function mkdir($path = '', $permissions = NULL)
+ public function mkdir($path, $permissions = NULL)
{
if ($path === '' OR ! $this->_is_conn())
{
@@ -260,7 +260,7 @@ class CI_FTP {
{
if ($this->debug === TRUE)
{
- $this->_error('ftp_unable_to_makdir');
+ $this->_error('ftp_unable_to_mkdir');
}
return FALSE;
}
@@ -392,7 +392,7 @@ class CI_FTP {
{
if ($this->debug === TRUE)
{
- $this->_error('ftp_unable_to_' . ($move === FALSE ? 'rename' : 'move'));
+ $this->_error('ftp_unable_to_'.($move === FALSE ? 'rename' : 'move'));
}
return FALSE;
}
diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php
index b6a11a3a5..db45a80fc 100644
--- a/system/libraries/Image_lib.php
+++ b/system/libraries/Image_lib.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -1245,22 +1245,37 @@ class CI_Image_lib {
// offset flips itself automatically
if ($this->wm_vrt_alignment === 'B')
+ {
$this->wm_vrt_offset = $this->wm_vrt_offset * -1;
+ }
if ($this->wm_hor_alignment === 'R')
+ {
$this->wm_hor_offset = $this->wm_hor_offset * -1;
+ }
// Set font width and height
// These are calculated differently depending on
// whether we are using the true type font or not
if ($this->wm_use_truetype === TRUE)
{
- if ($this->wm_font_size === '')
+ if (empty($this->wm_font_size))
{
$this->wm_font_size = 17;
}
- $fontwidth = $this->wm_font_size-($this->wm_font_size/4);
+ if (function_exists('imagettfbbox'))
+ {
+ $temp = imagettfbbox($this->wm_font_size, 0, $this->wm_font_path, $this->wm_text);
+ $temp = $temp[2] - $temp[0];
+
+ $fontwidth = $temp / strlen($this->wm_text);
+ }
+ else
+ {
+ $fontwidth = $this->wm_font_size - ($this->wm_font_size / 4);
+ }
+
$fontheight = $this->wm_font_size;
$this->wm_vrt_offset += $this->wm_font_size;
}
@@ -1368,45 +1383,45 @@ class CI_Image_lib {
public function image_create_gd($path = '', $image_type = '')
{
if ($path === '')
+ {
$path = $this->full_src_path;
+ }
if ($image_type === '')
+ {
$image_type = $this->image_type;
+ }
switch ($image_type)
{
- case 1 :
- if ( ! function_exists('imagecreatefromgif'))
- {
- $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
- return FALSE;
- }
+ case 1 :
+ if ( ! function_exists('imagecreatefromgif'))
+ {
+ $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
+ return FALSE;
+ }
- return imagecreatefromgif($path);
- break;
+ return imagecreatefromgif($path);
case 2 :
- if ( ! function_exists('imagecreatefromjpeg'))
- {
- $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
- return FALSE;
- }
+ if ( ! function_exists('imagecreatefromjpeg'))
+ {
+ $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
+ return FALSE;
+ }
- return imagecreatefromjpeg($path);
- break;
+ return imagecreatefromjpeg($path);
case 3 :
- if ( ! function_exists('imagecreatefrompng'))
- {
- $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
- return FALSE;
- }
-
- return imagecreatefrompng($path);
- break;
+ if ( ! function_exists('imagecreatefrompng'))
+ {
+ $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
+ return FALSE;
+ }
+ return imagecreatefrompng($path);
+ default:
+ $this->set_error(array('imglib_unsupported_imagecreate'));
+ return FALSE;
}
-
- $this->set_error(array('imglib_unsupported_imagecreate'));
- return FALSE;
}
// --------------------------------------------------------------------
diff --git a/system/libraries/Javascript.php b/system/libraries/Javascript.php
index 26a16850c..c71a4204e 100644
--- a/system/libraries/Javascript.php
+++ b/system/libraries/Javascript.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -34,6 +34,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @category Javascript
* @author EllisLab Dev Team
* @link http://codeigniter.com/user_guide/libraries/javascript.html
+ * @deprecated 3.0.0 This was never a good idea in the first place.
*/
class CI_Javascript {
diff --git a/system/libraries/Javascript/Jquery.php b/system/libraries/Javascript/Jquery.php
index ab78e8b2e..1cc3d2c21 100644
--- a/system/libraries/Javascript/Jquery.php
+++ b/system/libraries/Javascript/Jquery.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/libraries/Migration.php b/system/libraries/Migration.php
index cc6fe48f0..932b06ef0 100644
--- a/system/libraries/Migration.php
+++ b/system/libraries/Migration.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2006 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2006 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 3.0
diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php
index 10fb29dbd..f2d38a852 100644
--- a/system/libraries/Pagination.php
+++ b/system/libraries/Pagination.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -304,6 +304,16 @@ class CI_Pagination {
*/
public function __construct($params = array())
{
+ $CI =& get_instance();
+ $CI->load->language('pagination');
+ foreach (array('first_link', 'next_link', 'prev_link', 'last_link') as $key)
+ {
+ if (($val = $CI->lang->line('pagination_'.$key)) !== FALSE)
+ {
+ $this->$key = $val;
+ }
+ }
+
$this->initialize($params);
log_message('debug', 'Pagination Class Initialized');
}
@@ -314,9 +324,9 @@ class CI_Pagination {
* Initialize Preferences
*
* @param array $params Initialization parameters
- * @return void
+ * @return CI_Pagination
*/
- public function initialize($params = array())
+ public function initialize(array $params = array())
{
if (isset($params['attributes']) && is_array($params['attributes']))
{
@@ -332,16 +342,15 @@ class CI_Pagination {
unset($params['anchor_class']);
}
- if (count($params) > 0)
+ foreach ($params as $key => $val)
{
- foreach ($params as $key => $val)
+ if (property_exists($this, $this->$key))
{
- if (isset($this->$key))
- {
- $this->$key = $val;
- }
+ $this->$key = $val;
}
}
+
+ return $this;
}
// --------------------------------------------------------------------
@@ -354,7 +363,8 @@ class CI_Pagination {
public function create_links()
{
// If our item count or per-page total is zero there is no need to continue.
- if ($this->total_rows === 0 OR $this->per_page === 0)
+ // Note: DO NOT change the operator to === here!
+ if ($this->total_rows == 0 OR $this->per_page == 0)
{
return '';
}
@@ -393,30 +403,32 @@ class CI_Pagination {
}
// Put together our base and first URLs.
- $this->base_url = trim($this->base_url);
+ // Note: DO NOT append to the properties as that would break successive calls
+ $base_url = trim($this->base_url);
+ $first_url = $this->first_url;
$query_string = '';
- $query_string_sep = (strpos($this->base_url, '?') === FALSE) ? '?' : '&amp;';
+ $query_string_sep = (strpos($base_url, '?') === FALSE) ? '?' : '&amp;';
// Are we using query strings?
if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE)
{
// If a custom first_url hasn't been specified, we'll create one from
// the base_url, but without the page item.
- if ($this->first_url === '')
+ if ($first_url === '')
{
- $this->first_url = $this->base_url;
+ $first_url = $base_url;
// If we saved any GET items earlier, make sure they're appended.
if ( ! empty($get))
{
- $this->first_url .= $query_string_sep.http_build_query($get);
+ $first_url .= $query_string_sep.http_build_query($get);
}
}
// Add the page segment to the end of the query string, where the
// page number will be appended.
- $this->base_url .= $query_string_sep.http_build_query(array_merge($get, array($this->query_string_segment => '')));
+ $base_url .= $query_string_sep.http_build_query(array_merge($get, array($this->query_string_segment => '')));
}
else
{
@@ -430,17 +442,17 @@ class CI_Pagination {
// Does the base_url have the query string in it?
// If we're supposed to save it, remove it so we can append it later.
- if ($this->reuse_query_string === TRUE && ($base_query_pos = strpos($this->base_url, '?')) !== FALSE)
+ if ($this->reuse_query_string === TRUE && ($base_query_pos = strpos($base_url, '?')) !== FALSE)
{
- $this->base_url = substr($this->base_url, 0, $base_query_pos);
+ $base_url = substr($base_url, 0, $base_query_pos);
}
- if ($this->first_url === '')
+ if ($first_url === '')
{
- $this->first_url = $this->base_url.$query_string;
+ $first_url = $base_url.$query_string;
}
- $this->base_url = rtrim($this->base_url, '/').'/';
+ $base_url = rtrim($base_url, '/').'/';
}
// Determine the current page number.
@@ -516,8 +528,8 @@ class CI_Pagination {
// Take the general parameters, and squeeze this pagination-page attr in for JS frameworks.
$attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, 1);
- $output .= $this->first_tag_open.'<a href="'.$this->first_url.'"'.$attributes.$this->_attr_rel('start').'>'
- .$this->first_link.'</a>'.$this->first_tag_close;
+ $output .= $this->first_tag_open.'<a href="'.$first_url.'"'.$attributes.$this->_attr_rel('start').'>'
+ .$first_link.'</a>'.$this->first_tag_close;
}
// Render the "Previous" link.
@@ -530,13 +542,13 @@ class CI_Pagination {
if ($i === $base_page)
{
// First page
- $output .= $this->prev_tag_open.'<a href="'.$this->first_url.'"'.$attributes.$this->_attr_rel('prev').'>'
+ $output .= $this->prev_tag_open.'<a href="'.$first_url.'"'.$attributes.$this->_attr_rel('prev').'>'
.$this->prev_link.'</a>'.$this->prev_tag_close;
}
else
{
$append = $this->prefix.$i.$this->suffix;
- $output .= $this->prev_tag_open.'<a href="'.$this->base_url.$append.'"'.$attributes.$this->_attr_rel('prev').'>'
+ $output .= $this->prev_tag_open.'<a href="'.$base_url.$append.'"'.$attributes.$this->_attr_rel('prev').'>'
.$this->prev_link.'</a>'.$this->prev_tag_close;
}
@@ -562,13 +574,13 @@ class CI_Pagination {
elseif ($i === $base_page)
{
// First page
- $output .= $this->num_tag_open.'<a href="'.$this->first_url.'"'.$attributes.$this->_attr_rel('start').'>'
+ $output .= $this->num_tag_open.'<a href="'.$first_url.'"'.$attributes.$this->_attr_rel('start').'>'
.$loop.'</a>'.$this->num_tag_close;
}
else
{
$append = $this->prefix.$i.$this->suffix;
- $output .= $this->num_tag_open.'<a href="'.$this->base_url.$append.'"'.$attributes.$this->_attr_rel('start').'>'
+ $output .= $this->num_tag_open.'<a href="'.$base_url.$append.'"'.$attributes.$this->_attr_rel('start').'>'
.$loop.'</a>'.$this->num_tag_close;
}
}
@@ -582,7 +594,7 @@ class CI_Pagination {
$attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, (int) $i);
- $output .= $this->next_tag_open.'<a href="'.$this->base_url.$this->prefix.$i.$this->suffix.'"'.$attributes
+ $output .= $this->next_tag_open.'<a href="'.$base_url.$this->prefix.$i.$this->suffix.'"'.$attributes
.$this->_attr_rel('next').'>'.$this->next_link.'</a>'.$this->next_tag_close;
}
@@ -593,7 +605,7 @@ class CI_Pagination {
$attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, (int) $i);
- $output .= $this->last_tag_open.'<a href="'.$this->base_url.$this->prefix.$i.$this->suffix.'"'.$attributes.'>'
+ $output .= $this->last_tag_open.'<a href="'.$base_url.$this->prefix.$i.$this->suffix.'"'.$attributes.'>'
.$this->last_link.'</a>'.$this->last_tag_close;
}
diff --git a/system/libraries/Parser.php b/system/libraries/Parser.php
index c1f1ad73b..d23a53423 100644
--- a/system/libraries/Parser.php
+++ b/system/libraries/Parser.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -187,26 +187,34 @@ class CI_Parser {
*/
protected function _parse_pair($variable, $data, $string)
{
- if (FALSE === ($match = $this->_match_pair($string, $variable)))
+ if (FALSE === ($matches = $this->_match_pair($string, $variable)))
{
return $string;
}
$str = '';
- foreach ($data as $row)
+ $search = $replace = array();
+ foreach ($matches as $match)
{
- $temp = $match[1];
- foreach ($row as $key => $val)
+ $str = '';
+ foreach ($data as $row)
{
- $temp = is_array($val)
+ $temp = $match[1];
+ foreach ($row as $key => $val)
+ {
+ $temp = is_array($val)
? $this->_parse_pair($key, $val, $temp)
: $this->_parse_single($key, $val, $temp);
+ }
+
+ $str .= $temp;
}
- $str .= $temp;
+ $search[] = $match[0];
+ $replace[] = $str;
}
- return str_replace($match[0], $str, $string);
+ return str_replace($search, $replace, $string);
}
// --------------------------------------------------------------------
@@ -214,14 +222,14 @@ class CI_Parser {
/**
* Matches a variable pair
*
- * @param string
- * @param string
+ * @param string $string
+ * @param string $variable
* @return mixed
*/
protected function _match_pair($string, $variable)
{
- return preg_match('|'.preg_quote($this->l_delim).$variable.preg_quote($this->r_delim).'(.+?)'.preg_quote($this->l_delim).'/'.$variable.preg_quote($this->r_delim).'|s',
- $string, $match)
+ return preg_match_all('|'.preg_quote($this->l_delim).$variable.preg_quote($this->r_delim).'(.+?)'.preg_quote($this->l_delim).'/'.$variable.preg_quote($this->r_delim).'|s',
+ $string, $match, PREG_SET_ORDER)
? $match : FALSE;
}
diff --git a/system/libraries/Profiler.php b/system/libraries/Profiler.php
index 9e9e7d08d..810a025a4 100644
--- a/system/libraries/Profiler.php
+++ b/system/libraries/Profiler.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -278,6 +278,7 @@ class CI_Profiler {
}
$output .= "</table>\n</fieldset>";
+ $count++;
}
return $output;
@@ -307,10 +308,7 @@ class CI_Profiler {
foreach ($_GET as $key => $val)
{
- if ( ! is_numeric($key))
- {
- $key = "'".$key."'";
- }
+ is_int($key) OR $key = "'".$key."'";
$output .= '<tr><td style="width:50%;color:#000;background-color:#ddd;padding:5px;">&#36;_GET['
.$key.']&nbsp;&nbsp; </td><td style="width:50%;padding:5px;color:#cd6e00;font-weight:normal;background-color:#ddd;">'
@@ -338,7 +336,7 @@ class CI_Profiler {
."\n"
.'<legend style="color:#009900;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_post_data')."&nbsp;&nbsp;</legend>\n";
- if (count($_POST) === 0)
+ if (count($_POST) === 0 && count($_FILES) === 0)
{
$output .= '<div style="color:#009900;font-weight:normal;padding:4px 0 4px 0;">'.$this->CI->lang->line('profiler_no_post').'</div>';
}
@@ -348,10 +346,7 @@ class CI_Profiler {
foreach ($_POST as $key => $val)
{
- if ( ! is_numeric($key))
- {
- $key = "'".$key."'";
- }
+ is_int($key) OR $key = "'".$key."'";
$output .= '<tr><td style="width:50%;padding:5px;color:#000;background-color:#ddd;">&#36;_POST['
.$key.']&nbsp;&nbsp; </td><td style="width:50%;padding:5px;color:#009900;font-weight:normal;background-color:#ddd;">';
@@ -368,6 +363,21 @@ class CI_Profiler {
$output .= "</td></tr>\n";
}
+ foreach ($_FILES as $key => $val)
+ {
+ is_int($key) OR $key = "'".$key."'";
+
+ $output .= '<tr><td style="width:50%;padding:5px;color:#000;background-color:#ddd;">&#36;_FILES['
+ .$key.']&nbsp;&nbsp; </td><td style="width:50%;padding:5px;color:#009900;font-weight:normal;background-color:#ddd;">';
+
+ if (is_array($val) OR is_object($val))
+ {
+ $output .= '<pre>'.htmlspecialchars(stripslashes(print_r($val, TRUE))).'</pre>';
+ }
+
+ $output .= "</td></tr>\n";
+ }
+
$output .= "</table>\n";
}
@@ -506,7 +516,7 @@ class CI_Profiler {
.'<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_session_data').'&nbsp;&nbsp;(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_session_data\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show').'</span>)</legend>'
.'<table style="width:100%;display:none;" id="ci_profiler_session_data">';
- foreach ($this->CI->session->all_userdata() as $key => $val)
+ foreach ($this->CI->session->userdata() as $key => $val)
{
if (is_array($val) OR is_object($val))
{
diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php
index 659a0269e..905352bb3 100644
--- a/system/libraries/Session/Session.php
+++ b/system/libraries/Session/Session.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.0
@@ -102,10 +102,10 @@ class CI_Session extends CI_Driver_Library {
*/
public function __construct(array $params = array())
{
- $CI =& get_instance();
+ $_config =& get_instance()->config;
// No sessions under CLI
- if ($CI->input->is_cli_request())
+ if (is_cli())
{
return;
}
@@ -113,7 +113,7 @@ class CI_Session extends CI_Driver_Library {
log_message('debug', 'CI_Session Class Initialized');
// Add possible extra entries to our valid drivers list
- $drivers = isset($params['sess_valid_drivers']) ? $params['sess_valid_drivers'] : $CI->config->item('sess_valid_drivers');
+ $drivers = isset($params['sess_valid_drivers']) ? $params['sess_valid_drivers'] : $_config->item('sess_valid_drivers');
if ( ! empty($drivers))
{
$drivers = array_map('strtolower', (array) $drivers);
@@ -121,7 +121,7 @@ class CI_Session extends CI_Driver_Library {
}
// Get driver to load
- $driver = isset($params['sess_driver']) ? $params['sess_driver'] : $CI->config->item('sess_driver');
+ $driver = isset($params['sess_driver']) ? $params['sess_driver'] : $_config->item('sess_driver');
if ( ! $driver)
{
log_message('debug', "Session: No driver name is configured, defaulting to 'cookie'.");
@@ -238,9 +238,14 @@ class CI_Session extends CI_Driver_Library {
* @param string Item key
* @return string Item value or NULL if not found
*/
- public function userdata($item)
+ public function userdata($item = NULL)
{
- return isset($this->userdata[$item]) ? $this->userdata[$item] : NULL;
+ if (isset($item))
+ {
+ return isset($this->userdata[$item]) ? $this->userdata[$item] : NULL;
+ }
+
+ return isset($this->userdata) ? $this->userdata : array();
}
// ------------------------------------------------------------------------
@@ -248,35 +253,12 @@ class CI_Session extends CI_Driver_Library {
/**
* Fetch all session data
*
+ * @deprecated 3.0.0 Use userdata() with no parameters instead
* @return array User data array
*/
public function all_userdata()
{
- return isset($this->userdata) ? $this->userdata : NULL;
- }
-
- // ------------------------------------------------------------------------
-
- /**
- * Fetch all flashdata
- *
- * @return array Flash data array
- */
- public function all_flashdata()
- {
- $out = array();
-
- // loop through all userdata
- foreach ($this->all_userdata() as $key => $val)
- {
- // if it contains flashdata, add it
- if (strpos($key, self::FLASHDATA_KEY.self::FLASHDATA_OLD) !== FALSE)
- {
- $key = str_replace(self::FLASHDATA_KEY.self::FLASHDATA_OLD, '', $key);
- $out[$key] = $val;
- }
- }
- return $out;
+ return isset($this->userdata) ? $this->userdata : array();
}
// ------------------------------------------------------------------------
@@ -288,7 +270,7 @@ class CI_Session extends CI_Driver_Library {
* @param string Item value or empty string
* @return void
*/
- public function set_userdata($newdata = array(), $newval = '')
+ public function set_userdata($newdata, $newval = '')
{
// Wrap params as array if singular
if (is_string($newdata))
@@ -317,7 +299,7 @@ class CI_Session extends CI_Driver_Library {
* @param mixed Item name or array of item names
* @return void
*/
- public function unset_userdata($newdata = array())
+ public function unset_userdata($newdata)
{
// Wrap single name as array
if (is_string($newdata))
@@ -360,7 +342,7 @@ class CI_Session extends CI_Driver_Library {
* @param string Item value or empty string
* @return void
*/
- public function set_flashdata($newdata = array(), $newval = '')
+ public function set_flashdata($newdata, $newval = '')
{
// Wrap item as array if singular
if (is_string($newdata))
@@ -417,11 +399,25 @@ class CI_Session extends CI_Driver_Library {
* @param string Item key
* @return string
*/
- public function flashdata($key)
+ public function flashdata($key = NULL)
{
- // Prepend key and retrieve value
- $flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key;
- return $this->userdata($flashdata_key);
+ if (isset($key))
+ {
+ return $this->userdata(self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key);
+ }
+
+ // Get our flashdata items from userdata
+ $out = array();
+ foreach ($this->userdata() as $key => $val)
+ {
+ if (strpos($key, self::FLASHDATA_KEY.self::FLASHDATA_OLD) !== FALSE)
+ {
+ $key = str_replace(self::FLASHDATA_KEY.self::FLASHDATA_OLD, '', $key);
+ $out[$key] = $val;
+ }
+ }
+
+ return $out;
}
// ------------------------------------------------------------------------
@@ -434,7 +430,7 @@ class CI_Session extends CI_Driver_Library {
* @param int Item lifetime in seconds or 0 for default
* @return void
*/
- public function set_tempdata($newdata = array(), $newval = '', $expire = 0)
+ public function set_tempdata($newdata, $newval = '', $expire = 0)
{
// Set expiration time
$expire = time() + ($expire ? $expire : self::TEMP_EXP_DEF);
@@ -475,7 +471,7 @@ class CI_Session extends CI_Driver_Library {
* @param mixed Item name or array of item names
* @return void
*/
- public function unset_tempdata($newdata = array())
+ public function unset_tempdata($newdata)
{
// Get expirations list
$expirations = $this->userdata(self::EXPIRATION_KEY);
@@ -514,11 +510,25 @@ class CI_Session extends CI_Driver_Library {
* @param string Item key
* @return string
*/
- public function tempdata($key)
+ public function tempdata($key = NULL)
{
- // Prepend key and return value
- $tempdata_key = self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key;
- return $this->userdata($tempdata_key);
+ if (isset($key))
+ {
+ return $this->userdata(self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key);
+ }
+
+ // Get our tempdata items from userdata
+ $out = array();
+ foreach ($this->userdata() as $key => $val)
+ {
+ if (strpos($key, self::FLASHDATA_KEY.self::FLASHDATA_EXP) !== FALSE)
+ {
+ $key = str_replace(self::FLASHDATA_KEY.self::FLASHDATA_EXP, '', $key);
+ $out[$key] = $val;
+ }
+ }
+
+ return $out;
}
// ------------------------------------------------------------------------
@@ -531,13 +541,12 @@ class CI_Session extends CI_Driver_Library {
*/
protected function _flashdata_mark()
{
- foreach ($this->all_userdata() as $name => $value)
+ foreach ($this->userdata() as $name => $value)
{
$parts = explode(self::FLASHDATA_NEW, $name);
if (count($parts) === 2)
{
- $new_name = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$parts[1];
- $this->set_userdata($new_name, $value);
+ $this->set_userdata(self::FLASHDATA_KEY.self::FLASHDATA_OLD.$parts[1], $value);
$this->unset_userdata($name);
}
}
@@ -552,7 +561,7 @@ class CI_Session extends CI_Driver_Library {
*/
protected function _flashdata_sweep()
{
- $userdata = $this->all_userdata();
+ $userdata = $this->userdata();
foreach (array_keys($userdata) as $key)
{
if (strpos($key, self::FLASHDATA_OLD))
@@ -581,7 +590,7 @@ class CI_Session extends CI_Driver_Library {
// Unset expired elements
$now = time();
- $userdata = $this->all_userdata();
+ $userdata = $this->userdata();
foreach (array_keys($userdata) as $key)
{
if (strpos($key, self::FLASHDATA_EXP) && $expirations[$key] < $now)
diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php
index d3d22d03a..566c40bd8 100644
--- a/system/libraries/Session/drivers/Session_cookie.php
+++ b/system/libraries/Session/drivers/Session_cookie.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -165,6 +165,8 @@ class CI_Session_cookie extends CI_Session_driver {
*/
public $now;
+ // ------------------------------------------------------------------------
+
/**
* Default userdata keys
*
@@ -185,6 +187,15 @@ class CI_Session_cookie extends CI_Session_driver {
protected $data_dirty = FALSE;
/**
+ * Standardize newlines flag
+ *
+ * @var bool
+ */
+ protected $_standardize_newlines;
+
+ // ------------------------------------------------------------------------
+
+ /**
* Initialize session driver object
*
* @return void
@@ -209,9 +220,11 @@ class CI_Session_cookie extends CI_Session_driver {
'sess_time_to_update',
'time_reference',
'cookie_prefix',
- 'encryption_key'
+ 'encryption_key',
);
+ $this->_standardize_newlines = (bool) config_item('standardize_newlines');
+
foreach ($prefs as $key)
{
$this->$key = isset($this->_parent->params[$key])
@@ -227,7 +240,7 @@ class CI_Session_cookie extends CI_Session_driver {
// Do we need encryption? If so, load the encryption class
if ($this->sess_encrypt_cookie === TRUE)
{
- $this->CI->load->library('encrypt');
+ $this->CI->load->library('encryption');
}
// Check for database
@@ -370,34 +383,45 @@ class CI_Session_cookie extends CI_Session_driver {
return FALSE;
}
- $len = strlen($session) - 40;
-
- if ($len < 0)
+ if ($this->sess_encrypt_cookie === TRUE)
{
- log_message('debug', 'The session cookie was not signed.');
- return FALSE;
+ $session = $this->CI->encryption->decrypt($session);
+ if ($session === FALSE)
+ {
+ log_message('error', 'Session: Unable to decrypt the session cookie, possibly due to a HMAC mismatch.');
+ return FALSE;
+ }
}
+ else
+ {
+ if (($len = strlen($session) - 40) <= 0)
+ {
+ log_message('error', 'Session: The session cookie was not signed.');
+ return FALSE;
+ }
- // Check cookie authentication
- $hmac = substr($session, $len);
- $session = substr($session, 0, $len);
+ // Check cookie authentication
+ $hmac = substr($session, $len);
+ $session = substr($session, 0, $len);
- if ($hmac !== hash_hmac('sha1', $session, $this->encryption_key))
- {
- log_message('error', 'The session cookie data did not match what was expected.');
- $this->sess_destroy();
- return FALSE;
- }
+ // Time-attack-safe comparison
+ $hmac_check = hash_hmac('sha1', $session, $this->encryption_key);
+ $diff = 0;
+ for ($i = 0; $i < 40; $i++)
+ {
+ $diff |= ord($hmac[$i]) ^ ord($hmac_check[$i]);
+ }
- // Check for encryption
- if ($this->sess_encrypt_cookie === TRUE)
- {
- // Decrypt the cookie data
- $session = $this->CI->encrypt->decode($session);
+ if ($diff !== 0)
+ {
+ log_message('error', 'Session: HMAC mismatch. The session cookie data did not match what was expected.');
+ $this->sess_destroy();
+ return FALSE;
+ }
}
// Unserialize the session array
- $session = $this->_unserialize($session);
+ $session = @unserialize($session);
// Is the session data we unserialized an array with the correct format?
if ( ! is_array($session) OR ! isset($session['session_id'], $session['ip_address'], $session['user_agent'], $session['last_activity']))
@@ -472,7 +496,7 @@ class CI_Session_cookie extends CI_Session_driver {
$row = $query->row();
if ( ! empty($row->user_data))
{
- $custom_data = $this->_unserialize($row->user_data);
+ $custom_data = unserialize(trim($row->user_data));
if (is_array($custom_data))
{
@@ -608,7 +632,7 @@ class CI_Session_cookie extends CI_Session_driver {
if ( ! empty($userdata))
{
// Serialize the custom data array so we can store it
- $set['user_data'] = $this->_serialize($userdata);
+ $set['user_data'] = serialize($userdata);
}
// Reset query builder values.
@@ -695,16 +719,28 @@ class CI_Session_cookie extends CI_Session_driver {
? array_intersect_key($this->userdata, $this->defaults)
: $this->userdata;
+ // The Input class will do this and since we use HMAC verification,
+ // unless we standardize here as well, the hash won't match.
+ if ($this->_standardize_newlines)
+ {
+ foreach (array_keys($this->userdata) as $key)
+ {
+ $this->userdata[$key] = preg_replace('/(?:\r\n|[\r\n])/', PHP_EOL, $this->userdata[$key]);
+ }
+ }
+
// Serialize the userdata for the cookie
- $cookie_data = $this->_serialize($cookie_data);
+ $cookie_data = serialize($cookie_data);
if ($this->sess_encrypt_cookie === TRUE)
{
- $cookie_data = $this->CI->encrypt->encode($cookie_data);
+ $cookie_data = $this->CI->encryption->encrypt($cookie_data);
+ }
+ else
+ {
+ // Require message authentication
+ $cookie_data .= hash_hmac('sha1', $cookie_data, $this->encryption_key);
}
-
- // Require message authentication
- $cookie_data .= hash_hmac('sha1', $cookie_data, $this->encryption_key);
$expire = ($this->sess_expire_on_close === TRUE) ? 0 : $this->sess_expiration + time();
@@ -737,93 +773,6 @@ class CI_Session_cookie extends CI_Session_driver {
// ------------------------------------------------------------------------
/**
- * Serialize an array
- *
- * This function first converts any slashes found in the array to a temporary
- * marker, so when it gets unserialized the slashes will be preserved
- *
- * @param mixed Data to serialize
- * @return string Serialized data
- */
- protected function _serialize($data)
- {
- if (is_array($data))
- {
- array_walk_recursive($data, array(&$this, '_escape_slashes'));
- }
- elseif (is_string($data))
- {
- $data = str_replace('\\', '{{slash}}', $data);
- }
-
- return serialize($data);
- }
-
- // ------------------------------------------------------------------------
-
- /**
- * Escape slashes
- *
- * This function converts any slashes found into a temporary marker
- *
- * @param string Value
- * @param string Key
- * @return void
- */
- protected function _escape_slashes(&$val, $key)
- {
- if (is_string($val))
- {
- $val = str_replace('\\', '{{slash}}', $val);
- }
- }
-
- // ------------------------------------------------------------------------
-
- /**
- * Unserialize
- *
- * This function unserializes a data string, then converts any
- * temporary slash markers back to actual slashes
- *
- * @param mixed Data to unserialize
- * @return mixed Unserialized data
- */
- protected function _unserialize($data)
- {
- $data = @unserialize(trim($data));
-
- if (is_array($data))
- {
- array_walk_recursive($data, array(&$this, '_unescape_slashes'));
- return $data;
- }
-
- return is_string($data) ? str_replace('{{slash}}', '\\', $data) : $data;
- }
-
- // ------------------------------------------------------------------------
-
- /**
- * Unescape slashes
- *
- * This function converts any slash markers back into actual slashes
- *
- * @param string Value
- * @param string Key
- * @return void
- */
- protected function _unescape_slashes(&$val, $key)
- {
- if (is_string($val))
- {
- $val = str_replace('{{slash}}', '\\', $val);
- }
- }
-
- // ------------------------------------------------------------------------
-
- /**
* Garbage collection
*
* This deletes expired session rows from database
@@ -841,7 +790,7 @@ class CI_Session_cookie extends CI_Session_driver {
$probability = ini_get('session.gc_probability');
$divisor = ini_get('session.gc_divisor');
- if ((mt_rand(0, $divisor) / $divisor) < $probability)
+ if (mt_rand(1, $divisor) <= $probability)
{
$expire = $this->now - $this->sess_expiration;
$this->CI->db->delete($this->sess_table_name, 'last_activity < '.$expire);
diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php
index c237ad059..4104652b8 100644
--- a/system/libraries/Session/drivers/Session_native.php
+++ b/system/libraries/Session/drivers/Session_native.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/libraries/Table.php b/system/libraries/Table.php
index b77fcf19d..ff96d9275 100644
--- a/system/libraries/Table.php
+++ b/system/libraries/Table.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.3.1
@@ -93,7 +93,7 @@ class CI_Table {
*
* @var function
*/
- public $function = FALSE;
+ public $function = NULL;
/**
* Set the template from the table config file if it exists
@@ -117,7 +117,7 @@ class CI_Table {
/**
* Set the template
*
- * @param array
+ * @param array $template
* @return bool
*/
public function set_template($template)
@@ -139,12 +139,12 @@ class CI_Table {
* Can be passed as an array or discreet params
*
* @param mixed
- * @return void
+ * @return CI_Table
*/
public function set_heading($args = array())
{
- $args = func_get_args();
- $this->heading = $this->_prep_args($args);
+ $this->heading = $this->_prep_args(func_get_args());
+ return $this;
}
// --------------------------------------------------------------------
@@ -155,9 +155,9 @@ class CI_Table {
* columns. This allows a single array with many elements to be
* displayed in a table that has a fixed column count.
*
- * @param array
- * @param int
- * @return void
+ * @param array $array
+ * @param int $col_limit
+ * @return array
*/
public function make_columns($array = array(), $col_limit = 0)
{
@@ -202,12 +202,13 @@ class CI_Table {
*
* Can be passed as an array or discreet params
*
- * @param mixed
- * @return void
+ * @param mixed $value
+ * @return CI_Table
*/
public function set_empty($value)
{
$this->empty_cells = $value;
+ return $this;
}
// --------------------------------------------------------------------
@@ -218,12 +219,12 @@ class CI_Table {
* Can be passed as an array or discreet params
*
* @param mixed
- * @return void
+ * @return CI_Table
*/
public function add_row($args = array())
{
- $args = func_get_args();
- $this->rows[] = $this->_prep_args($args);
+ $this->rows[] = $this->_prep_args(func_get_args());
+ return $this;
}
// --------------------------------------------------------------------
@@ -241,26 +242,14 @@ class CI_Table {
// If there is no $args[0], skip this and treat as an associative array
// This can happen if there is only a single key, for example this is passed to table->generate
// array(array('foo'=>'bar'))
- if (isset($args[0]) && count($args) === 1 && is_array($args[0]))
+ if (isset($args[0]) && count($args) === 1 && is_array($args[0]) && ! isset($args[0]['data']))
{
- // args sent as indexed array
- if ( ! isset($args[0]['data']))
- {
- foreach ($args[0] as $key => $val)
- {
- $args[$key] = (is_array($val) && isset($val['data'])) ? $val : array('data' => $val);
- }
- }
+ $args = $args[0];
}
- else
+
+ foreach ($args as $key => $val)
{
- foreach ($args as $key => $val)
- {
- if ( ! is_array($val))
- {
- $args[$key] = array('data' => $val);
- }
- }
+ is_array($val) OR $args[$key] = array('data' => $val);
}
return $args;
@@ -271,8 +260,8 @@ class CI_Table {
/**
* Add a table caption
*
- * @param string
- * @return void
+ * @param string $caption
+ * @return CI_Table
*/
public function set_caption($caption)
{
@@ -284,28 +273,27 @@ class CI_Table {
/**
* Generate the table
*
- * @param mixed
+ * @param mixed $table_data
* @return string
*/
public function generate($table_data = NULL)
{
// The table data can optionally be passed to this function
// either as a database result object or an array
- if ($table_data !== NULL)
+ if ( ! empty($table_data))
{
- if (is_object($table_data))
+ if ($table_data instanceof CI_DB_result)
{
- $this->_set_from_object($table_data);
+ $this->_set_from_db_result($table_data);
}
elseif (is_array($table_data))
{
- $set_heading = (count($this->heading) !== 0 OR $this->auto_heading !== FALSE);
- $this->_set_from_array($table_data, $set_heading);
+ $this->_set_from_array($table_data);
}
}
// Is there anything to display? No? Smite them!
- if (count($this->heading) === 0 && count($this->rows) === 0)
+ if (empty($this->heading) && empty($this->rows))
{
return 'Undefined table data';
}
@@ -313,8 +301,11 @@ class CI_Table {
// Compile and validate the template date
$this->_compile_template();
- // set a custom cell manipulation function to a locally scoped variable so its callable
- $function = $this->function;
+ // Validate a possibly existing custom cell manipulation function
+ if (isset($this->function) && ! is_callable($this->function))
+ {
+ $this->function = NULL;
+ }
// Build the table!
@@ -323,11 +314,11 @@ class CI_Table {
// Add any caption here
if ($this->caption)
{
- $out .= $this->newline.'<caption>'.$this->caption.'</caption>'.$this->newline;
+ $out .= '<caption>'.$this->caption.'</caption>'.$this->newline;
}
// Is there a table heading to display?
- if (count($this->heading) > 0)
+ if ( ! empty($this->heading))
{
$out .= $this->template['thead_open'].$this->newline.$this->template['heading_row_start'].$this->newline;
@@ -350,7 +341,7 @@ class CI_Table {
}
// Build the table rows
- if (count($this->rows) > 0)
+ if ( ! empty($this->rows))
{
$out .= $this->template['tbody_open'].$this->newline;
@@ -386,9 +377,9 @@ class CI_Table {
{
$out .= $this->empty_cells;
}
- elseif ($function !== FALSE && is_callable($function))
+ elseif (isset($this->function))
{
- $out .= call_user_func($function, $cell);
+ $out .= call_user_func($this->function, $cell);
}
else
{
@@ -417,13 +408,14 @@ class CI_Table {
/**
* Clears the table arrays. Useful if multiple tables are being generated
*
- * @return void
+ * @return CI_Table
*/
public function clear()
{
- $this->rows = array();
- $this->heading = array();
- $this->auto_heading = TRUE;
+ $this->rows = array();
+ $this->heading = array();
+ $this->auto_heading = TRUE;
+ return $this;
}
// --------------------------------------------------------------------
@@ -431,34 +423,20 @@ class CI_Table {
/**
* Set table data from a database result object
*
- * @param object
+ * @param CI_DB_result $db_result Database result object
* @return void
*/
- protected function _set_from_object($query)
+ protected function _set_from_db_result($object)
{
- if ( ! is_object($query))
- {
- return;
- }
-
// First generate the headings from the table column names
- if (count($this->heading) === 0)
+ if ($this->auto_heading === TRUE && empty($this->heading))
{
- if ( ! is_callable(array($query, 'list_fields')))
- {
- return;
- }
-
- $this->heading = $this->_prep_args($query->list_fields());
+ $this->heading = $this->_prep_args($object->list_fields());
}
- // Next blast through the result array and build out the rows
- if ($query->num_rows() > 0)
+ foreach ($object->result_array() as $row)
{
- foreach ($query->result_array() as $row)
- {
- $this->rows[] = $this->_prep_args($row);
- }
+ $this->rows[] = $this->_prep_args($row);
}
}
@@ -467,29 +445,19 @@ class CI_Table {
/**
* Set table data from an array
*
- * @param array
- * @param bool
+ * @param array $data
* @return void
*/
- protected function _set_from_array($data, $set_heading = TRUE)
+ protected function _set_from_array($data)
{
- if ( ! is_array($data) OR count($data) === 0)
+ if ($this->auto_heading === TRUE && empty($this->heading))
{
- return FALSE;
+ $this->heading = $this->_prep_args(array_shift($data));
}
- $i = 0;
- foreach ($data as $row)
+ foreach ($data as &$row)
{
- // If a heading hasn't already been set we'll use the first row of the array as the heading
- if ($i++ === 0 && count($data) > 1 && count($this->heading) === 0 && $set_heading === TRUE)
- {
- $this->heading = $this->_prep_args($row);
- }
- else
- {
- $this->rows[] = $this->_prep_args($row);
- }
+ $this->rows[] = $this->_prep_args($row);
}
}
@@ -528,31 +496,31 @@ class CI_Table {
protected function _default_template()
{
return array(
- 'table_open' => '<table border="0" cellpadding="4" cellspacing="0">',
+ 'table_open' => '<table border="0" cellpadding="4" cellspacing="0">',
- 'thead_open' => '<thead>',
- 'thead_close' => '</thead>',
+ 'thead_open' => '<thead>',
+ 'thead_close' => '</thead>',
- 'heading_row_start' => '<tr>',
- 'heading_row_end' => '</tr>',
- 'heading_cell_start' => '<th>',
- 'heading_cell_end' => '</th>',
+ 'heading_row_start' => '<tr>',
+ 'heading_row_end' => '</tr>',
+ 'heading_cell_start' => '<th>',
+ 'heading_cell_end' => '</th>',
- 'tbody_open' => '<tbody>',
- 'tbody_close' => '</tbody>',
+ 'tbody_open' => '<tbody>',
+ 'tbody_close' => '</tbody>',
- 'row_start' => '<tr>',
- 'row_end' => '</tr>',
- 'cell_start' => '<td>',
- 'cell_end' => '</td>',
+ 'row_start' => '<tr>',
+ 'row_end' => '</tr>',
+ 'cell_start' => '<td>',
+ 'cell_end' => '</td>',
- 'row_alt_start' => '<tr>',
- 'row_alt_end' => '</tr>',
- 'cell_alt_start' => '<td>',
- 'cell_alt_end' => '</td>',
+ 'row_alt_start' => '<tr>',
+ 'row_alt_end' => '</tr>',
+ 'cell_alt_start' => '<td>',
+ 'cell_alt_end' => '</td>',
- 'table_close' => '</table>'
- );
+ 'table_close' => '</table>'
+ );
}
}
diff --git a/system/libraries/Trackback.php b/system/libraries/Trackback.php
index 5a45be8dd..9fa4a8edb 100644
--- a/system/libraries/Trackback.php
+++ b/system/libraries/Trackback.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -181,7 +181,14 @@ class CI_Trackback {
if ($val !== 'url' && MB_ENABLED === TRUE)
{
- $_POST[$val] = mb_convert_encoding($_POST[$val], $this->charset, $this->data['charset']);
+ if (MB_ENABLED === TRUE)
+ {
+ $_POST[$val] = mb_convert_encoding($_POST[$val], $this->charset, $this->data['charset']);
+ }
+ elseif (ICONV_ENABLED === TRUE)
+ {
+ $_POST[$val] = @iconv($this->data['charset'], $this->charset.'//IGNORE', $_POST[$val]);
+ }
}
$_POST[$val] = ($val !== 'url') ? $this->convert_xml(strip_tags($_POST[$val])) : strip_tags($_POST[$val]);
diff --git a/system/libraries/Typography.php b/system/libraries/Typography.php
index dd79e850a..d5e4ee06b 100644
--- a/system/libraries/Typography.php
+++ b/system/libraries/Typography.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/libraries/Unit_test.php b/system/libraries/Unit_test.php
index 7a67c7276..cc882bc72 100644
--- a/system/libraries/Unit_test.php
+++ b/system/libraries/Unit_test.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.3.1
@@ -81,7 +81,15 @@ class CI_Unit_test {
*
* @var array
*/
- protected $_test_items_visible = array();
+ protected $_test_items_visible = array(
+ 'test_name',
+ 'test_datatype',
+ 'res_datatype',
+ 'result',
+ 'file',
+ 'line',
+ 'notes'
+ );
// --------------------------------------------------------------------
@@ -92,17 +100,6 @@ class CI_Unit_test {
*/
public function __construct()
{
- // These are the default items visible when a test is run.
- $this->_test_items_visible = array (
- 'test_name',
- 'test_datatype',
- 'res_datatype',
- 'result',
- 'file',
- 'line',
- 'notes'
- );
-
log_message('debug', 'Unit Testing Class Initialized');
}
@@ -113,10 +110,10 @@ class CI_Unit_test {
*
* Runs the supplied tests
*
- * @param array
+ * @param array $items
* @return void
*/
- public function set_test_items($items = array())
+ public function set_test_items($items)
{
if ( ! empty($items) && is_array($items))
{
@@ -230,7 +227,7 @@ class CI_Unit_test {
*
* Causes the evaluation to use === rather than ==
*
- * @param bool
+ * @param bool $state
* @return void
*/
public function use_strict($state = TRUE)
@@ -288,6 +285,7 @@ class CI_Unit_test {
{
$val = $line;
}
+
$temp[$CI->lang->line('ut_'.$key, FALSE)] = $val;
}
@@ -396,4 +394,4 @@ function is_false($test)
}
/* End of file Unit_test.php */
-/* Location: ./system/libraries/Unit_test.php */
+/* Location: ./system/libraries/Unit_test.php */ \ No newline at end of file
diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php
index 060973847..983d832fd 100644
--- a/system/libraries/Upload.php
+++ b/system/libraries/Upload.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -234,6 +234,13 @@ class CI_Upload {
public $xss_clean = FALSE;
/**
+ * Apache mod_mime fix flag
+ *
+ * @var bool
+ */
+ public $mod_mime_fix = TRUE;
+
+ /**
* Temporary filename prefix
*
* @var string
@@ -256,6 +263,13 @@ class CI_Upload {
*/
protected $_file_name_override = '';
+ /**
+ * CI Singleton
+ *
+ * @var object
+ */
+ protected $CI;
+
// --------------------------------------------------------------------
/**
@@ -272,6 +286,7 @@ class CI_Upload {
}
$this->mimes =& get_mimes();
+ $this->CI =& get_instance();
log_message('debug', 'Upload Class Initialized');
}
@@ -314,6 +329,7 @@ class CI_Upload {
'remove_spaces' => TRUE,
'detect_mime' => TRUE,
'xss_clean' => FALSE,
+ 'mod_mime_fix' => TRUE,
'temp_prefix' => 'temp_file_',
'client_name' => ''
);
@@ -471,8 +487,7 @@ class CI_Upload {
}
// Sanitize the file name for security
- $CI =& get_instance();
- $this->file_name = $CI->security->sanitize_filename($this->file_name);
+ $this->file_name = $this->CI->security->sanitize_filename($this->file_name);
// Truncate the file name if it's too long
if ($this->max_filename > 0)
@@ -1073,8 +1088,7 @@ class CI_Upload {
return FALSE;
}
- $CI =& get_instance();
- return $CI->security->xss_clean($data, TRUE);
+ return $this->CI->security->xss_clean($data, TRUE);
}
// --------------------------------------------------------------------
@@ -1087,17 +1101,13 @@ class CI_Upload {
*/
public function set_error($msg)
{
- $CI =& get_instance();
- $CI->lang->load('upload');
+ $this->CI->lang->load('upload');
- if ( ! is_array($msg))
- {
- $msg = array($msg);
- }
+ is_array($msg) OR $msg = array($msg);
foreach ($msg as $val)
{
- $msg = ($CI->lang->line($val) === FALSE) ? $val : $CI->lang->line($val);
+ $msg = ($this->CI->lang->line($val) === FALSE) ? $val : $this->CI->lang->line($val);
$this->error_msg[] = $msg;
log_message('error', $msg);
}
@@ -1148,7 +1158,7 @@ class CI_Upload {
*/
protected function _prep_filename($filename)
{
- if (strpos($filename, '.') === FALSE OR $this->allowed_types === '*')
+ if ($this->mod_mime_fix === FALSE OR $this->allowed_types === '*' OR strpos($filename, '.') === FALSE)
{
return $filename;
}
diff --git a/system/libraries/User_agent.php b/system/libraries/User_agent.php
index 50ac9be98..9bab8666e 100644
--- a/system/libraries/User_agent.php
+++ b/system/libraries/User_agent.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -145,6 +145,15 @@ class CI_User_agent {
public $robot = '';
/**
+ * HTTP Referer
+ *
+ * @var mixed
+ */
+ public $referer;
+
+ // --------------------------------------------------------------------
+
+ /**
* Constructor
*
* Sets the User Agent and runs the compilation routine
@@ -282,7 +291,7 @@ class CI_User_agent {
{
foreach ($this->browsers as $key => $val)
{
- if (preg_match('|'.preg_quote($key).'.*?([0-9\.]+)|i', $this->agent, $match))
+ if (preg_match('|'.$key.'.*?([0-9\.]+)|i', $this->agent, $match))
{
$this->is_browser = TRUE;
$this->version = $match[1];
@@ -358,7 +367,7 @@ class CI_User_agent {
{
if ((count($this->languages) === 0) && ! empty($_SERVER['HTTP_ACCEPT_LANGUAGE']))
{
- $this->languages = explode(',', preg_replace('/(;q=[0-9\.]+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_LANGUAGE']))));
+ $this->languages = explode(',', preg_replace('/(;\s?q=[0-9\.]+)|\s/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_LANGUAGE']))));
}
if (count($this->languages) === 0)
@@ -378,7 +387,7 @@ class CI_User_agent {
{
if ((count($this->charsets) === 0) && ! empty($_SERVER['HTTP_ACCEPT_CHARSET']))
{
- $this->charsets = explode(',', preg_replace('/(;q=.+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_CHARSET']))));
+ $this->charsets = explode(',', preg_replace('/(;\s?q=.+)|\s/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_CHARSET']))));
}
if (count($this->charsets) === 0)
@@ -471,24 +480,22 @@ class CI_User_agent {
*/
public function is_referral()
{
- static $result;
-
- if ( ! isset($result))
+ if ( ! isset($this->referer))
{
if (empty($_SERVER['HTTP_REFERER']))
{
- $result = FALSE;
+ $this->referer = FALSE;
}
else
{
$referer_host = @parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST);
$own_host = parse_url(config_item('base_url'), PHP_URL_HOST);
- $result = ($referer_host && $referer_host !== $own_host);
+ $this->referer = ($referer_host && $referer_host !== $own_host);
}
}
- return $result;
+ return $this->referer;
}
// --------------------------------------------------------------------
@@ -634,6 +641,34 @@ class CI_User_agent {
return in_array(strtolower($charset), $this->charsets(), TRUE);
}
+ // --------------------------------------------------------------------
+
+ /**
+ * Parse a custom user-agent string
+ *
+ * @param string $string
+ * @return void
+ */
+ public function parse($string)
+ {
+ // Reset values
+ $this->is_browser = FALSE;
+ $this->is_robot = FALSE;
+ $this->is_mobile = FALSE;
+ $this->browser = '';
+ $this->version = '';
+ $this->mobile = '';
+ $this->robot = '';
+
+ // Set the new user-agent string and parse it, unless empty
+ $this->agent = $string;
+
+ if ( ! empty($string))
+ {
+ $this->_compile_data();
+ }
+ }
+
}
/* End of file User_agent.php */
diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php
index 16c5b0ed8..83dc00e45 100644
--- a/system/libraries/Xmlrpc.php
+++ b/system/libraries/Xmlrpc.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -348,6 +348,11 @@ class CI_Xmlrpc {
$parts = parse_url($url);
+ if (isset($parts['user'], $parts['pass']))
+ {
+ $parts['host'] = $parts['user'].':'.$parts['pass'].'@'.$parts['host'];
+ }
+
$path = isset($parts['path']) ? $parts['path'] : '/';
if ( ! empty($parts['query']))
@@ -569,6 +574,21 @@ class XML_RPC_Client extends CI_Xmlrpc
public $port = 80;
/**
+ *
+ * Server username
+ *
+ * @var string
+ */
+ public $username;
+
+ /**
+ * Server password
+ *
+ * @var string
+ */
+ public $password;
+
+ /**
* Proxy hostname
*
* @var string
@@ -626,8 +646,16 @@ class XML_RPC_Client extends CI_Xmlrpc
{
parent::__construct();
+ $url = parse_url('http://'.$server);
+
+ if (isset($url['user'], $url['pass']))
+ {
+ $this->username = $url['user'];
+ $this->password = $url['pass'];
+ }
+
$this->port = $port;
- $this->server = $server;
+ $this->server = $url['host'];
$this->path = $path;
$this->proxy = $proxy;
$this->proxy_port = $proxy_port;
@@ -691,11 +719,20 @@ class XML_RPC_Client extends CI_Xmlrpc
$op = 'POST '.$this->path.' HTTP/1.0'.$r
.'Host: '.$this->server.$r
.'Content-Type: text/xml'.$r
+ .(isset($this->username, $this->password) ? 'Authorization: Basic '.base64_encode($this->username.':'.$this->password).$r : '')
.'User-Agent: '.$this->xmlrpcName.$r
.'Content-Length: '.strlen($msg->payload).$r.$r
.$msg->payload;
- if ( ! fwrite($fp, $op, strlen($op)))
+ for ($written = 0, $length = strlen($op); $written < $length; $written += $result)
+ {
+ if (($result = fwrite($fp, substr($op, $written))) === FALSE)
+ {
+ break;
+ }
+ }
+
+ if ($result === FALSE)
{
error_log($this->xmlrpcstr['http_error']);
return new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']);
@@ -855,10 +892,10 @@ class XML_RPC_Response
/**
* Decode
*
- * @param mixed
+ * @param mixed $array
* @return array
*/
- public function decode($array = FALSE)
+ public function decode($array = NULL)
{
$CI =& get_instance();
@@ -870,9 +907,9 @@ class XML_RPC_Response
{
$array[$key] = $this->decode($array[$key]);
}
- else
+ elseif ($this->xss_clean)
{
- $array[$key] = ($this->xss_clean) ? $CI->security->xss_clean($array[$key]) : $array[$key];
+ $array[$key] = $CI->security->xss_clean($array[$key]);
}
}
@@ -885,9 +922,9 @@ class XML_RPC_Response
{
$result = $this->decode($result);
}
- else
+ elseif ($this->xss_clean)
{
- $result = ($this->xss_clean) ? $CI->security->xss_clean($result) : $result;
+ $result = $CI->security->xss_clean($result);
}
return $result;
@@ -1084,15 +1121,15 @@ class XML_RPC_Message extends CI_Xmlrpc
//-------------------------------------
$parser = xml_parser_create($this->xmlrpc_defencoding);
-
- $this->xh[$parser] = array(
- 'isf' => 0,
- 'ac' => '',
- 'headers' => array(),
- 'stack' => array(),
- 'valuestack' => array(),
- 'isf_reason' => 0
- );
+ $pname = (string) $parser;
+ $this->xh[$pname] = array(
+ 'isf' => 0,
+ 'ac' => '',
+ 'headers' => array(),
+ 'stack' => array(),
+ 'valuestack' => array(),
+ 'isf_reason' => 0
+ );
xml_set_object($parser, $this);
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, TRUE);
@@ -1108,7 +1145,7 @@ class XML_RPC_Message extends CI_Xmlrpc
{
break;
}
- $this->xh[$parser]['headers'][] = $line;
+ $this->xh[$pname]['headers'][] = $line;
}
$data = implode("\r\n", $lines);
@@ -1126,18 +1163,18 @@ class XML_RPC_Message extends CI_Xmlrpc
xml_parser_free($parser);
// Got ourselves some badness, it seems
- if ($this->xh[$parser]['isf'] > 1)
+ if ($this->xh[$pname]['isf'] > 1)
{
if ($this->debug === TRUE)
{
- echo "---Invalid Return---\n".$this->xh[$parser]['isf_reason']."---Invalid Return---\n\n";
+ echo "---Invalid Return---\n".$this->xh[$pname]['isf_reason']."---Invalid Return---\n\n";
}
- return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
+ return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return'].' '.$this->xh[$pname]['isf_reason']);
}
- elseif ( ! is_object($this->xh[$parser]['value']))
+ elseif ( ! is_object($this->xh[$pname]['value']))
{
- return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
+ return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return'].' '.$this->xh[$pname]['isf_reason']);
}
// Display XML content for debugging
@@ -1145,10 +1182,10 @@ class XML_RPC_Message extends CI_Xmlrpc
{
echo '<pre>';
- if (count($this->xh[$parser]['headers'] > 0))
+ if (count($this->xh[$pname]['headers'] > 0))
{
echo "---HEADERS---\n";
- foreach ($this->xh[$parser]['headers'] as $header)
+ foreach ($this->xh[$pname]['headers'] as $header)
{
echo $header."\n";
}
@@ -1156,13 +1193,13 @@ class XML_RPC_Message extends CI_Xmlrpc
}
echo "---DATA---\n".htmlspecialchars($data)."\n---END DATA---\n\n---PARSED---\n";
- var_dump($this->xh[$parser]['value']);
+ var_dump($this->xh[$pname]['value']);
echo "\n---END PARSED---</pre>";
}
// Send response
- $v = $this->xh[$parser]['value'];
- if ($this->xh[$parser]['isf'])
+ $v = $this->xh[$pname]['value'];
+ if ($this->xh[$pname]['isf'])
{
$errno_v = $v->me['struct']['faultCode'];
$errstr_v = $v->me['struct']['faultString'];
@@ -1181,7 +1218,7 @@ class XML_RPC_Message extends CI_Xmlrpc
$r = new XML_RPC_Response($v);
}
- $r->headers = $this->xh[$parser]['headers'];
+ $r->headers = $this->xh[$pname]['headers'];
return $r;
}
@@ -1212,6 +1249,8 @@ class XML_RPC_Message extends CI_Xmlrpc
*/
public function open_tag($the_parser, $name)
{
+ $the_parser = (string) $the_parser;
+
// If invalid nesting, then return
if ($this->xh[$the_parser]['isf'] > 1) return;
@@ -1311,6 +1350,8 @@ class XML_RPC_Message extends CI_Xmlrpc
*/
public function closing_tag($the_parser, $name)
{
+ $the_parser = (string) $the_parser;
+
if ($this->xh[$the_parser]['isf'] > 1) return;
// Remove current element from stack and set variable
@@ -1443,6 +1484,8 @@ class XML_RPC_Message extends CI_Xmlrpc
*/
public function character_data($the_parser, $data)
{
+ $the_parser = (string) $the_parser;
+
if ($this->xh[$the_parser]['isf'] > 1) return; // XML Fault found already
// If a value has not been found
@@ -1480,14 +1523,14 @@ class XML_RPC_Message extends CI_Xmlrpc
/**
* Output parameters
*
- * @param array
+ * @param array $array
* @return array
*/
- public function output_parameters($array = FALSE)
+ public function output_parameters(array $array = array())
{
$CI =& get_instance();
- if (is_array($array))
+ if ( ! empty($array))
{
while (list($key) = each($array))
{
@@ -1495,11 +1538,11 @@ class XML_RPC_Message extends CI_Xmlrpc
{
$array[$key] = $this->output_parameters($array[$key]);
}
- else
+ elseif ($key !== 'bits' && $this->xss_clean)
{
// 'bits' is for the MetaWeblog API image bits
// @todo - this needs to be made more general purpose
- $array[$key] = ($key === 'bits' OR $this->xss_clean === FALSE) ? $array[$key] : $CI->security->xss_clean($array[$key]);
+ $array[$key] = $CI->security->xss_clean($array[$key]);
}
}
@@ -1684,7 +1727,7 @@ class XML_RPC_Values extends CI_Xmlrpc
{
if ($this->mytype !== 0)
{
- echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';
+ echo '<strong>XML_RPC_Values</strong>: already initialized as a ['.$this->kindOf().']<br />';
return 0;
}
@@ -1705,7 +1748,7 @@ class XML_RPC_Values extends CI_Xmlrpc
{
if ($this->mytype !== 0)
{
- echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';
+ echo '<strong>XML_RPC_Values</strong>: already initialized as a ['.$this->kindOf().']<br />';
return 0;
}
$this->mytype = $this->xmlrpcTypes['struct'];
diff --git a/system/libraries/Xmlrpcs.php b/system/libraries/Xmlrpcs.php
index d263d789d..e8e06d756 100644
--- a/system/libraries/Xmlrpcs.php
+++ b/system/libraries/Xmlrpcs.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -384,17 +384,13 @@ class CI_Xmlrpcs extends CI_Xmlrpc {
{
return call_user_func(array($this, $method_parts[1]), $m);
}
+ elseif ($this->object === FALSE)
+ {
+ return get_instance()->$method_parts[1]($m);
+ }
else
{
- if ($this->object === FALSE)
- {
- $CI =& get_instance();
- return $CI->$method_parts[1]($m);
- }
- else
- {
- return $this->object->$method_parts[1]($m);
- }
+ return $this->object->$method_parts[1]($m);
}
}
else
diff --git a/system/libraries/Zip.php b/system/libraries/Zip.php
index 6608f050e..40b661abc 100644
--- a/system/libraries/Zip.php
+++ b/system/libraries/Zip.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -103,12 +103,12 @@ class CI_Zip {
*
* Lets you add a virtual directory into which you can place files.
*
- * @param mixed the directory name. Can be string or array
+ * @param mixed $directory the directory name. Can be string or array
* @return void
*/
public function add_dir($directory)
{
- foreach ( (array) $directory as $dir)
+ foreach ((array) $directory as $dir)
{
if ( ! preg_match('|.+/$|', $dir))
{
@@ -127,7 +127,7 @@ class CI_Zip {
*
* If this is a newly created file/dir, we will set the time to 'now'
*
- * @param string path to file
+ * @param string $dir path to file
* @return array filemtime/filemdate
*/
protected function _get_mod_time($dir)
@@ -146,9 +146,9 @@ class CI_Zip {
/**
* Add Directory
*
- * @param string the directory name
- * @param int
- * @param int
+ * @param string $dir the directory name
+ * @param int $file_mtime
+ * @param int $file_mdate
* @return void
*/
protected function _add_dir($dir, $file_mtime, $file_mdate)
@@ -199,8 +199,8 @@ class CI_Zip {
* in the filename it will be placed within a directory. Make
* sure you use add_dir() first to create the folder.
*
- * @param mixed
- * @param string
+ * @param mixed $filepath A single filepath or an array of file => data pairs
+ * @param string $data Single file contents
* @return void
*/
public function add_data($filepath, $data = NULL)
@@ -225,10 +225,10 @@ class CI_Zip {
/**
* Add Data to Zip
*
- * @param string the file name/path
- * @param string the data to be encoded
- * @param int
- * @param int
+ * @param string $filepath the file name/path
+ * @param string $data the data to be encoded
+ * @param int $file_mtime
+ * @param int $file_mdate
* @return void
*/
protected function _add_data($filepath, $data, $file_mtime, $file_mdate)
@@ -278,23 +278,26 @@ class CI_Zip {
/**
* Read the contents of a file and add it to the zip
*
- * @param string
- * @param bool
+ * @param string $path
+ * @param bool $archive_filepath
* @return bool
*/
- public function read_file($path, $preserve_filepath = FALSE)
+ public function read_file($path, $archive_filepath = FALSE)
{
- if ( ! file_exists($path))
+ if (file_exists($path) && FALSE !== ($data = file_get_contents($path)))
{
- return FALSE;
- }
-
- if (FALSE !== ($data = file_get_contents($path)))
- {
- $name = str_replace('\\', '/', $path);
- if ($preserve_filepath === FALSE)
+ if (is_string($archive_filepath))
{
- $name = preg_replace('|.*/(.+)|', '\\1', $name);
+ $name = str_replace('\\', '/', $archive_filepath);
+ }
+ else
+ {
+ $name = str_replace('\\', '/', $path);
+
+ if ($archive_filepath === FALSE)
+ {
+ $name = preg_replace('|.*/(.+)|', '\\1', $name);
+ }
}
$this->add_data($name, $data);
@@ -313,9 +316,9 @@ class CI_Zip {
* sub-folders) and creates a zip based on it. Whatever directory structure
* is in the original file path will be recreated in the zip file.
*
- * @param string path to source
- * @param bool
- * @param bool
+ * @param string $path path to source directory
+ * @param bool $preserve_filepath
+ * @param string $root_path
* @return bool
*/
public function read_dir($path, $preserve_filepath = TRUE, $root_path = NULL)
@@ -389,7 +392,7 @@ class CI_Zip {
*
* Lets you write a file
*
- * @param string the file name
+ * @param string $filepath the file name
* @return bool
*/
public function archive($filepath)
@@ -400,11 +403,19 @@ class CI_Zip {
}
flock($fp, LOCK_EX);
- fwrite($fp, $this->get_zip());
+
+ for ($written = 0, $data = $this->get_zip(), $length = strlen($data); $written < $length; $written += $result)
+ {
+ if (($result = fwrite($fp, substr($data, $written))) === FALSE)
+ {
+ break;
+ }
+ }
+
flock($fp, LOCK_UN);
fclose($fp);
- return TRUE;
+ return is_int($result);
}
// --------------------------------------------------------------------
@@ -412,7 +423,7 @@ class CI_Zip {
/**
* Download
*
- * @param string the file name
+ * @param string $filename the file name
* @return void
*/
public function download($filename = 'backup.zip')
@@ -422,8 +433,7 @@ class CI_Zip {
$filename .= '.zip';
}
- $CI =& get_instance();
- $CI->load->helper('download');
+ get_instance()->load->helper('download');
$get_zip = $this->get_zip();
$zip_content =& $get_zip;