summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--application/config/autoload.php23
-rw-r--r--application/config/config.php7
-rw-r--r--application/config/constants.php1
-rw-r--r--application/config/database.php1
-rw-r--r--application/config/migration.php6
-rw-r--r--application/config/mimes.php4
-rw-r--r--application/config/smileys.php1
-rw-r--r--application/config/user_agents.php3
-rw-r--r--system/core/Input.php18
-rw-r--r--system/core/Router.php2
-rw-r--r--system/database/DB_driver.php2
-rw-r--r--system/database/DB_forge.php9
-rw-r--r--system/database/DB_query_builder.php5
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php1
-rw-r--r--system/database/drivers/sqlite3/sqlite3_driver.php2
-rw-r--r--system/database/drivers/sqlite3/sqlite3_forge.php3
-rw-r--r--system/helpers/url_helper.php6
-rw-r--r--system/libraries/Cache/Cache.php9
-rw-r--r--system/libraries/Cache/drivers/Cache_memcached.php142
-rw-r--r--system/libraries/Cache/drivers/Cache_redis.php125
-rw-r--r--system/libraries/Email.php22
-rw-r--r--system/libraries/Form_validation.php11
-rw-r--r--system/libraries/Unit_test.php56
-rw-r--r--system/libraries/Upload.php57
-rw-r--r--system/libraries/Xmlrpc.php22
-rw-r--r--user_guide_src/source/changelog.rst31
-rw-r--r--user_guide_src/source/database/forge.rst4
-rw-r--r--user_guide_src/source/database/utilities.rst4
-rw-r--r--user_guide_src/source/general/security.rst4
-rw-r--r--user_guide_src/source/libraries/email.rst2
-rw-r--r--user_guide_src/source/libraries/unit_testing.rst1
-rw-r--r--user_guide_src/source/overview/at_a_glance.rst4
33 files changed, 316 insertions, 274 deletions
diff --git a/application/config/autoload.php b/application/config/autoload.php
index 72f855c8b..4bc6bf0ad 100644
--- a/application/config/autoload.php
+++ b/application/config/autoload.php
@@ -39,16 +39,15 @@ defined('BASEPATH') OR exit('No direct script access allowed');
| $autoload['packages'] = array(APPPATH.'third_party', '/usr/local/shared');
|
*/
-
$autoload['packages'] = array();
-
/*
| -------------------------------------------------------------------
| Auto-load Libraries
| -------------------------------------------------------------------
-| These are the classes located in the system/libraries folder
-| or in your application/libraries folder.
+| These are the classes located in system/libraries/ or your
+| application/libraries/ directory, with the addition of the
+| 'database' library, which is somewhat of a special case.
|
| Prototype:
|
@@ -59,26 +58,23 @@ $autoload['packages'] = array();
|
| $autoload['libraries'] = array('user_agent' => 'ua');
*/
-
$autoload['libraries'] = array();
-
/*
| -------------------------------------------------------------------
| Auto-load Drivers
| -------------------------------------------------------------------
-| These classes are located in the system/libraries folder or in your
-| application/libraries folder within their own subdirectory. They
+| These classes are located in system/libraries/ or in your
+| application/libraries/ directory, but are also placed inside their
+| own subdirectory and they extend the CI_Driver_Library class. They
| offer multiple interchangeable driver options.
|
| Prototype:
|
| $autoload['drivers'] = array('cache');
*/
-
$autoload['drivers'] = array();
-
/*
| -------------------------------------------------------------------
| Auto-load Helper Files
@@ -87,10 +83,8 @@ $autoload['drivers'] = array();
|
| $autoload['helper'] = array('url', 'file');
*/
-
$autoload['helper'] = array();
-
/*
| -------------------------------------------------------------------
| Auto-load Config files
@@ -103,10 +97,8 @@ $autoload['helper'] = array();
| config files. Otherwise, leave it blank.
|
*/
-
$autoload['config'] = array();
-
/*
| -------------------------------------------------------------------
| Auto-load Language files
@@ -119,10 +111,8 @@ $autoload['config'] = array();
| "codeigniter_lang.php" would be referenced as array('codeigniter');
|
*/
-
$autoload['language'] = array();
-
/*
| -------------------------------------------------------------------
| Auto-load Models
@@ -136,5 +126,4 @@ $autoload['language'] = array();
|
| $autoload['model'] = array('first_model' => 'first');
*/
-
$autoload['model'] = array();
diff --git a/application/config/config.php b/application/config/config.php
index 94e5d28a9..86ca312b7 100644
--- a/application/config/config.php
+++ b/application/config/config.php
@@ -58,7 +58,6 @@ $config['uri_protocol'] = 'REQUEST_URI';
|
| http://codeigniter.com/user_guide/general/urls.html
*/
-
$config['url_suffix'] = '';
/*
@@ -155,7 +154,6 @@ $config['composer_autoload'] = FALSE;
*/
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';
-
/*
|--------------------------------------------------------------------------
| Enable Query Strings
@@ -325,7 +323,7 @@ $config['encryption_key'] = '';
|
| 'sess_save_path'
|
-| The location to save sessions to, driver dependant.
+| The location to save sessions to, driver dependent.
|
| For the 'files' driver, it's a path to a writable directory.
| WARNING: Only absolute paths are supported!
@@ -388,7 +386,7 @@ $config['cookie_httponly'] = FALSE;
|--------------------------------------------------------------------------
|
| Determines whether to standardize newline characters in input data,
-| meaning to replace \r\n, \r, \n occurences with the PHP_EOL value.
+| meaning to replace \r\n, \r, \n occurrences with the PHP_EOL value.
|
| This is particularly useful for portability between UNIX-based OSes,
| (usually \n) and Windows (\r\n).
@@ -478,7 +476,6 @@ $config['time_reference'] = 'local';
*/
$config['rewrite_short_tags'] = FALSE;
-
/*
|--------------------------------------------------------------------------
| Reverse Proxy IPs
diff --git a/application/config/constants.php b/application/config/constants.php
index 01096c74a..48283e223 100644
--- a/application/config/constants.php
+++ b/application/config/constants.php
@@ -27,7 +27,6 @@ define('DIR_WRITE_MODE', 0755);
| These modes are used when working with fopen()/popen()
|
*/
-
define('FOPEN_READ', 'rb');
define('FOPEN_READ_WRITE', 'r+b');
define('FOPEN_WRITE_CREATE_DESTRUCTIVE', 'wb'); // truncates existing file data, use with care
diff --git a/application/config/database.php b/application/config/database.php
index fc3a5e5b6..84aab9169 100644
--- a/application/config/database.php
+++ b/application/config/database.php
@@ -58,7 +58,6 @@ defined('BASEPATH') OR exit('No direct script access allowed');
| The $query_builder variables lets you determine whether or not to load
| the query builder class.
*/
-
$active_group = 'default';
$query_builder = TRUE;
diff --git a/application/config/migration.php b/application/config/migration.php
index 083bf287c..4b585a65c 100644
--- a/application/config/migration.php
+++ b/application/config/migration.php
@@ -21,12 +21,12 @@ $config['migration_enabled'] = FALSE;
| Migration file names may be based on a sequential identifier or on
| a timestamp. Options are:
|
-| 'sequential' = Default migration naming (001_add_blog.php)
+| 'sequential' = Sequential migration naming (001_add_blog.php)
| 'timestamp' = Timestamp migration naming (20121031104401_add_blog.php)
| Use timestamp format YYYYMMDDHHIISS.
|
-| If this configuration value is missing the Migration library defaults
-| to 'sequential' for backward compatibility.
+| Note: If this configuration value is missing the Migration library
+| defaults to 'sequential' for backward compatibility with CI2.
|
*/
$config['migration_type'] = 'timestamp';
diff --git a/application/config/mimes.php b/application/config/mimes.php
index 78d8e53e3..1f591ba6b 100644
--- a/application/config/mimes.php
+++ b/application/config/mimes.php
@@ -9,7 +9,6 @@ defined('BASEPATH') OR exit('No direct script access allowed');
| Upload class to help identify allowed file types.
|
*/
-
return array(
'hqx' => array('application/mac-binhex40', 'application/mac-binhex', 'application/x-binhex40', 'application/x-mac-binhex40'),
'cpt' => 'application/mac-compactpro',
@@ -154,5 +153,6 @@ return array(
'svg' => array('image/svg+xml', 'application/xml', 'text/xml'),
'vcf' => 'text/x-vcard',
'srt' => array('text/srt', 'text/plain'),
- 'vtt' => array('text/vtt', 'text/plain')
+ 'vtt' => array('text/vtt', 'text/plain'),
+ 'ico' => array('image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon')
);
diff --git a/application/config/smileys.php b/application/config/smileys.php
index 1428d68bc..1eeba4776 100644
--- a/application/config/smileys.php
+++ b/application/config/smileys.php
@@ -13,7 +13,6 @@ defined('BASEPATH') OR exit('No direct script access allowed');
| http://codeigniter.com/user_guide/helpers/smiley_helper.html
|
*/
-
$smileys = array(
// smiley image name width height alt
diff --git a/application/config/user_agents.php b/application/config/user_agents.php
index 2fd955435..1129dbacd 100644
--- a/application/config/user_agents.php
+++ b/application/config/user_agents.php
@@ -10,7 +10,6 @@ defined('BASEPATH') OR exit('No direct script access allowed');
| mobile device data. The array keys are used to identify the device
| and the array values are used to set the actual name of the item.
*/
-
$platforms = array(
'windows nt 10.0' => 'Windows 10',
'windows nt 6.3' => 'Windows 8.1',
@@ -199,7 +198,7 @@ $robots = array(
'bingbot' => 'Bing',
'slurp' => 'Inktomi Slurp',
'yahoo' => 'Yahoo',
- 'askjeeves' => 'AskJeeves',
+ 'ask jeeves' => 'Ask Jeeves',
'fastcrawler' => 'FastCrawler',
'infoseek' => 'InfoSeek Robot 1.0',
'lycos' => 'Lycos',
diff --git a/system/core/Input.php b/system/core/Input.php
index 12332cf51..b0bbb7b8d 100644
--- a/system/core/Input.php
+++ b/system/core/Input.php
@@ -799,19 +799,27 @@ class CI_Input {
*/
public function get_request_header($index, $xss_clean = FALSE)
{
- if (empty($this->headers))
+ static $headers;
+
+ if ( ! isset($headers))
{
- $this->request_headers();
+ empty($this->headers) OR $this->request_headers();
+ foreach ($this->headers as $key => $value)
+ {
+ $headers[strtolower($key)] = $value;
+ }
}
- if ( ! isset($this->headers[$index]))
+ $index = strtolower($index);
+
+ if ( ! isset($headers[$index]))
{
return NULL;
}
return ($xss_clean === TRUE)
- ? $this->security->xss_clean($this->headers[$index])
- : $this->headers[$index];
+ ? $this->security->xss_clean($headers[$index])
+ : $headers[$index];
}
// --------------------------------------------------------------------
diff --git a/system/core/Router.php b/system/core/Router.php
index f91d3f6ec..051000533 100644
--- a/system/core/Router.php
+++ b/system/core/Router.php
@@ -105,7 +105,7 @@ class CI_Router {
/**
* Enable query strings flag
*
- * Determines wether to use GET parameters or segment URIs
+ * Determines whether to use GET parameters or segment URIs
*
* @var bool
*/
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index 64ee880c8..d2bce5c97 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -1751,7 +1751,7 @@ abstract class CI_DB_driver {
//
// Added exception for single quotes as well, we don't want to alter
// literal strings. -- Narf
- if (strpos($item, '(') !== FALSE OR strpos($item, "'") !== FALSE)
+ if (strcspn($item, "()'") !== strlen($item))
{
return $item;
}
diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php
index f6ee2a63a..865498fb5 100644
--- a/system/database/DB_forge.php
+++ b/system/database/DB_forge.php
@@ -239,7 +239,7 @@ abstract class CI_DB_forge {
*/
public function add_key($key, $primary = FALSE)
{
- if ($primary === TRUE && is_array($key))
+ if (is_array($key))
{
foreach ($key as $one)
{
@@ -453,12 +453,7 @@ abstract class CI_DB_forge {
return ($this->db->db_debug) ? $this->db->display_error('db_table_name_required') : FALSE;
}
- $query = $this->_drop_table($this->db->dbprefix.$table_name, $if_exists);
- if ($query === FALSE)
- {
- return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE;
- }
- elseif ($query === TRUE)
+ if (($query = $this->_drop_table($this->db->dbprefix.$table_name, $if_exists)) === TRUE)
{
return TRUE;
}
diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php
index 8251f4558..a8b5b3579 100644
--- a/system/database/DB_query_builder.php
+++ b/system/database/DB_query_builder.php
@@ -2092,10 +2092,13 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
}
elseif (is_array($table))
{
+ empty($where) && $reset_data = FALSE;
+
foreach ($table as $single_table)
{
$this->delete($single_table, $where, $limit, $reset_data);
}
+
return;
}
else
@@ -2326,7 +2329,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
// Split multiple conditions
$conditions = preg_split(
- '/(\s*AND\s+|\s*OR\s+)/i',
+ '/((^|\s+)AND\s+|(^|\s+)OR\s+)/i',
$this->{$qb_key}[$i]['condition'],
-1,
PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY
diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php b/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php
index d5ca741fd..409e6501b 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php
@@ -140,7 +140,7 @@ class CI_DB_pdo_sqlite_driver extends CI_DB_pdo_driver {
}
$this->data_cache['field_names'][$table] = array();
- foreach ($result as $row)
+ foreach ($result->result_array() as $row)
{
$this->data_cache['field_names'][$table][] = $row['name'];
}
diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php b/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php
index 28faaddb7..15afbdef5 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php
@@ -89,6 +89,7 @@ class CI_DB_pdo_sqlite_forge extends CI_DB_pdo_forge {
if (version_compare($this->db->version(), '3.3', '<'))
{
$this->_create_table_if = FALSE;
+ $this->_drop_table_if = FALSE;
}
}
diff --git a/system/database/drivers/sqlite3/sqlite3_driver.php b/system/database/drivers/sqlite3/sqlite3_driver.php
index a7c6420bb..31e37de91 100644
--- a/system/database/drivers/sqlite3/sqlite3_driver.php
+++ b/system/database/drivers/sqlite3/sqlite3_driver.php
@@ -266,7 +266,7 @@ class CI_DB_sqlite3_driver extends CI_DB {
}
$this->data_cache['field_names'][$table] = array();
- foreach ($result as $row)
+ foreach ($result->result_array() as $row)
{
$this->data_cache['field_names'][$table][] = $row['name'];
}
diff --git a/system/database/drivers/sqlite3/sqlite3_forge.php b/system/database/drivers/sqlite3/sqlite3_forge.php
index 69f65b6f3..24690ba20 100644
--- a/system/database/drivers/sqlite3/sqlite3_forge.php
+++ b/system/database/drivers/sqlite3/sqlite3_forge.php
@@ -74,7 +74,8 @@ class CI_DB_sqlite3_forge extends CI_DB_forge {
if (version_compare($this->db->version(), '3.3', '<'))
{
- $this->create_table_if = FALSE;
+ $this->_create_table_if = FALSE;
+ $this->_drop_table_if = FALSE;
}
}
diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php
index 5f8c6ce67..d65f92f1b 100644
--- a/system/helpers/url_helper.php
+++ b/system/helpers/url_helper.php
@@ -474,7 +474,7 @@ if ( ! function_exists('url_title'))
* @param string $str Input string
* @param string $separator Word separator
* (usually '-' or '_')
- * @param bool $lowercase Wether to transform the output string to lowercase
+ * @param bool $lowercase Whether to transform the output string to lowercase
* @return string
*/
function url_title($str, $separator = '-', $lowercase = FALSE)
@@ -492,7 +492,7 @@ if ( ! function_exists('url_title'))
$trans = array(
'&.+?;' => '',
- '[^a-z0-9 _-]' => '',
+ '[^\w\d _-]' => '',
'\s+' => $separator,
'('.$q_separator.')+' => $separator
);
@@ -500,7 +500,7 @@ if ( ! function_exists('url_title'))
$str = strip_tags($str);
foreach ($trans as $key => $val)
{
- $str = preg_replace('#'.$key.'#i', $val, $str);
+ $str = preg_replace('#'.$key.'#i'.(UTF8_ENABLED ? 'u' : ''), $val, $str);
}
if ($lowercase === TRUE)
diff --git a/system/libraries/Cache/Cache.php b/system/libraries/Cache/Cache.php
index 215a7c528..0c87a5628 100644
--- a/system/libraries/Cache/Cache.php
+++ b/system/libraries/Cache/Cache.php
@@ -178,7 +178,7 @@ class CI_Cache extends CI_Driver_Library {
*/
public function increment($id, $offset = 1)
{
- return $this->{$this->_adapter}->increment($id, $offset);
+ return $this->{$this->_adapter}->increment($this->key_prefix.$id, $offset);
}
// ------------------------------------------------------------------------
@@ -192,7 +192,7 @@ class CI_Cache extends CI_Driver_Library {
*/
public function decrement($id, $offset = 1)
{
- return $this->{$this->_adapter}->decrement($id, $offset);
+ return $this->{$this->_adapter}->decrement($this->key_prefix.$id, $offset);
}
// ------------------------------------------------------------------------
@@ -243,14 +243,13 @@ class CI_Cache extends CI_Driver_Library {
*/
public function is_supported($driver)
{
- static $support = array();
+ static $support;
- if ( ! isset($support[$driver]))
+ if ( ! isset($support, $support[$driver]))
{
$support[$driver] = $this->{$driver}->is_supported();
}
return $support[$driver];
}
-
}
diff --git a/system/libraries/Cache/drivers/Cache_memcached.php b/system/libraries/Cache/drivers/Cache_memcached.php
index b90b561c9..111e2109d 100644
--- a/system/libraries/Cache/drivers/Cache_memcached.php
+++ b/system/libraries/Cache/drivers/Cache_memcached.php
@@ -68,6 +68,76 @@ class CI_Cache_memcached extends CI_Driver {
)
);
+ // ------------------------------------------------------------------------
+
+ /**
+ * Class constructor
+ *
+ * Setup Memcache(d)
+ *
+ * @return void
+ */
+ public function __construct()
+ {
+ // Try to load memcached server info from the config file.
+ $CI =& get_instance();
+ $defaults = $this->_memcache_conf['default'];
+
+ if ($CI->config->load('memcached', TRUE, TRUE))
+ {
+ if (is_array($CI->config->config['memcached']))
+ {
+ $this->_memcache_conf = array();
+
+ foreach ($CI->config->config['memcached'] as $name => $conf)
+ {
+ $this->_memcache_conf[$name] = $conf;
+ }
+ }
+ }
+
+ if (class_exists('Memcached', FALSE))
+ {
+ $this->_memcached = new Memcached();
+ }
+ elseif (class_exists('Memcache', FALSE))
+ {
+ $this->_memcached = new Memcache();
+ }
+ else
+ {
+ throw new RuntimeException('Cache: Failed to create Memcache(d) object; extension not loaded?');
+ }
+
+ foreach ($this->_memcache_conf as $cache_server)
+ {
+ isset($cache_server['hostname']) OR $cache_server['hostname'] = $defaults['host'];
+ isset($cache_server['port']) OR $cache_server['port'] = $defaults['port'];
+ isset($cache_server['weight']) OR $cache_server['weight'] = $defaults['weight'];
+
+ if (get_class($this->_memcached) === 'Memcache')
+ {
+ // Third parameter is persistance and defaults to TRUE.
+ $this->_memcached->addServer(
+ $cache_server['hostname'],
+ $cache_server['port'],
+ TRUE,
+ $cache_server['weight']
+ );
+ }
+ else
+ {
+ $this->_memcached->addServer(
+ $cache_server['hostname'],
+ $cache_server['port'],
+ $cache_server['weight']
+ );
+ }
+ }
+ }
+
+ // ------------------------------------------------------------------------
+
/**
* Fetch from cache
*
@@ -205,75 +275,6 @@ class CI_Cache_memcached extends CI_Driver {
// ------------------------------------------------------------------------
/**
- * Setup memcached.
- *
- * @return bool
- */
- protected function _setup_memcached()
- {
- // Try to load memcached server info from the config file.
- $CI =& get_instance();
- $defaults = $this->_memcache_conf['default'];
-
- if ($CI->config->load('memcached', TRUE, TRUE))
- {
- if (is_array($CI->config->config['memcached']))
- {
- $this->_memcache_conf = array();
-
- foreach ($CI->config->config['memcached'] as $name => $conf)
- {
- $this->_memcache_conf[$name] = $conf;
- }
- }
- }
-
- if (class_exists('Memcached', FALSE))
- {
- $this->_memcached = new Memcached();
- }
- elseif (class_exists('Memcache', FALSE))
- {
- $this->_memcached = new Memcache();
- }
- else
- {
- log_message('error', 'Failed to create object for Memcached Cache; extension not loaded?');
- return FALSE;
- }
-
- foreach ($this->_memcache_conf as $cache_server)
- {
- isset($cache_server['hostname']) OR $cache_server['hostname'] = $defaults['host'];
- isset($cache_server['port']) OR $cache_server['port'] = $defaults['port'];
- isset($cache_server['weight']) OR $cache_server['weight'] = $defaults['weight'];
-
- if (get_class($this->_memcached) === 'Memcache')
- {
- // Third parameter is persistance and defaults to TRUE.
- $this->_memcached->addServer(
- $cache_server['hostname'],
- $cache_server['port'],
- TRUE,
- $cache_server['weight']
- );
- }
- else
- {
- $this->_memcached->addServer(
- $cache_server['hostname'],
- $cache_server['port'],
- $cache_server['weight']
- );
- }
- }
-
- return TRUE;
- }
-
- // ------------------------------------------------------------------------
-
- /**
* Is supported
*
* Returns FALSE if memcached is not supported on the system.
@@ -289,7 +290,6 @@ class CI_Cache_memcached extends CI_Driver {
return FALSE;
}
- return $this->_setup_memcached();
+ return TRUE;
}
-
}
diff --git a/system/libraries/Cache/drivers/Cache_redis.php b/system/libraries/Cache/drivers/Cache_redis.php
index 66966ba16..d7dca1973 100644
--- a/system/libraries/Cache/drivers/Cache_redis.php
+++ b/system/libraries/Cache/drivers/Cache_redis.php
@@ -79,6 +79,63 @@ class CI_Cache_redis extends CI_Driver
// ------------------------------------------------------------------------
/**
+ * Class constructor
+ *
+ * Setup Redis
+ *
+ * Loads Redis config file if present. Will halt execution
+ * if a Redis connection can't be established.
+ *
+ * @return void
+ * @see Redis::connect()
+ */
+ public function __construct()
+ {
+ $config = array();
+ $CI =& get_instance();
+
+ if ($CI->config->load('redis', TRUE, TRUE))
+ {
+ $config = $CI->config->item('redis');
+ }
+
+ $config = array_merge(self::$_default_config, $config);
+ $this->_redis = new Redis();
+
+ try
+ {
+ 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)
+ {
+ throw new RuntimeException('Cache: Redis connection failed. Check your configuration.');
+ }
+ }
+ catch (RedisException $e)
+ {
+ throw new RuntimeException('Cache: Redis connection refused ('.$e->getMessage().')');
+ }
+
+ if (isset($config['password']) && ! $this->_redis->auth($config['password']))
+ {
+ throw new RuntimeException('Cache: Redis authentication failed.');
+ }
+
+ // Initialize the index of serialized values.
+ $serialized = $this->_redis->sMembers('_ci_redis_serialized');
+ empty($serialized) OR $this->_serialized = array_flip($serialized);
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
* Get cache
*
* @param string Cache ID
@@ -247,73 +304,6 @@ class CI_Cache_redis extends CI_Driver
return FALSE;
}
- return $this->_setup_redis();
- }
-
- // ------------------------------------------------------------------------
-
- /**
- * Setup Redis config and connection
- *
- * Loads Redis config file if present. Will halt execution
- * if a Redis connection can't be established.
- *
- * @return bool
- * @see Redis::connect()
- */
- protected function _setup_redis()
- {
- $config = array();
- $CI =& get_instance();
-
- if ($CI->config->load('redis', TRUE, TRUE))
- {
- $config = $CI->config->item('redis');
- }
-
- $config = array_merge(self::$_default_config, $config);
-
- $this->_redis = new Redis();
-
- try
- {
- 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)
- {
- log_message('debug', 'Cache: Redis connection refused ('.$e->getMessage().')');
- return FALSE;
- }
-
- if (isset($config['password']))
- {
- if ( ! $this->_redis->auth($config['password']))
- {
- log_message('debug', 'Cache: Redis authentication failed.');
- return FALSE;
- }
- }
-
- // Initialize the index of serialized values.
- $serialized = $this->_redis->sMembers('_ci_redis_serialized');
- if ( ! empty($serialized))
- {
- $this->_serialized = array_flip($serialized);
- }
-
return TRUE;
}
@@ -333,5 +323,4 @@ class CI_Cache_redis extends CI_Driver
$this->_redis->close();
}
}
-
}
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index 66b5803dd..57693e1c7 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -2126,12 +2126,32 @@ class CI_Email {
protected function _send_data($data)
{
$data .= $this->newline;
- for ($written = 0, $length = strlen($data); $written < $length; $written += $result)
+ for ($written = $timestamp = 0, $length = strlen($data); $written < $length; $written += $result)
{
if (($result = fwrite($this->_smtp_connect, substr($data, $written))) === FALSE)
{
break;
}
+ // See https://bugs.php.net/bug.php?id=39598 and http://php.net/manual/en/function.fwrite.php#96951
+ elseif ($result === 0)
+ {
+ if ($timestamp === 0)
+ {
+ $timestamp = time();
+ }
+ elseif ($timestamp < (time() - $this->smtp_timeout))
+ {
+ $result = FALSE;
+ break;
+ }
+
+ usleep(250000);
+ continue;
+ }
+ else
+ {
+ $timestamp = 0;
+ }
}
if ($result === FALSE)
diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php
index 7599602c0..d9ecc45f9 100644
--- a/system/libraries/Form_validation.php
+++ b/system/libraries/Form_validation.php
@@ -618,6 +618,12 @@ class CI_Form_validation {
$rules = array(1 => $rule);
break;
}
+ elseif (is_array($rule) && isset($rule[0], $rule[1]) && is_callable($rule[1]))
+ {
+ $callback = TRUE;
+ $rules = array(array($rule[0], $rule[1]));
+ break;
+ }
}
if ( ! $callback)
@@ -815,11 +821,10 @@ class CI_Form_validation {
// Callable rules might not have named error messages
if ( ! is_string($rule))
{
- return;
+ $line = $this->CI->lang->line('form_validation_error_message_not_set').'(Anonymous function)';
}
-
// Check if a custom message is defined
- if (isset($this->_field_data[$row['field']]['errors'][$rule]))
+ elseif (isset($this->_field_data[$row['field']]['errors'][$rule]))
{
$line = $this->_field_data[$row['field']]['errors'][$rule];
}
diff --git a/system/libraries/Unit_test.php b/system/libraries/Unit_test.php
index 7b744adc6..3f986f3e8 100644
--- a/system/libraries/Unit_test.php
+++ b/system/libraries/Unit_test.php
@@ -55,14 +55,14 @@ class CI_Unit_test {
*
* @var bool
*/
- public $active = TRUE;
+ public $active = TRUE;
/**
* Test results
*
* @var array
*/
- public $results = array();
+ public $results = array();
/**
* Strict comparison flag
@@ -71,21 +71,21 @@ class CI_Unit_test {
*
* @var bool
*/
- public $strict = FALSE;
+ public $strict = FALSE;
/**
* Template
*
* @var string
*/
- protected $_template = NULL;
+ protected $_template = NULL;
/**
* Template rows
*
* @var string
*/
- protected $_template_rows = NULL;
+ protected $_template_rows = NULL;
/**
* List of visible test items
@@ -93,13 +93,13 @@ class CI_Unit_test {
* @var array
*/
protected $_test_items_visible = array(
- 'test_name',
- 'test_datatype',
- 'res_datatype',
- 'result',
- 'file',
- 'line',
- 'notes'
+ 'test_name',
+ 'test_datatype',
+ 'res_datatype',
+ 'result',
+ 'file',
+ 'line',
+ 'notes'
);
// --------------------------------------------------------------------
@@ -152,7 +152,7 @@ class CI_Unit_test {
return FALSE;
}
- if (in_array($expected, array('is_object', 'is_string', 'is_bool', 'is_true', 'is_false', 'is_int', 'is_numeric', 'is_float', 'is_double', 'is_array', 'is_null'), TRUE))
+ if (in_array($expected, array('is_object', 'is_string', 'is_bool', 'is_true', 'is_false', 'is_int', 'is_numeric', 'is_float', 'is_double', 'is_array', 'is_null', 'is_resource'), TRUE))
{
$expected = str_replace('is_double', 'is_float', $expected);
$result = $expected($test);
@@ -167,14 +167,14 @@ class CI_Unit_test {
$back = $this->_backtrace();
$report = array (
- 'test_name' => $test_name,
- 'test_datatype' => gettype($test),
- 'res_datatype' => $extype,
- 'result' => ($result === TRUE) ? 'passed' : 'failed',
- 'file' => $back['file'],
- 'line' => $back['line'],
- 'notes' => $notes
- );
+ 'test_name' => $test_name,
+ 'test_datatype' => gettype($test),
+ 'res_datatype' => $extype,
+ 'result' => ($result === TRUE) ? 'passed' : 'failed',
+ 'file' => $back['file'],
+ 'line' => $back['line'],
+ 'notes' => $notes
+ );
$this->results[] = $report;
@@ -291,10 +291,12 @@ class CI_Unit_test {
{
continue;
}
-
- if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$val), FALSE)))
+ elseif (in_array($key, array('test_name', 'test_datatype', 'test_res_datatype', 'result'), TRUE))
{
- $val = $line;
+ if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$val), FALSE)))
+ {
+ $val = $line;
+ }
}
$temp[$CI->lang->line('ut_'.$key, FALSE)] = $val;
@@ -334,9 +336,9 @@ class CI_Unit_test {
{
$back = debug_backtrace();
return array(
- 'file' => (isset($back[1]['file']) ? $back[1]['file'] : ''),
- 'line' => (isset($back[1]['line']) ? $back[1]['line'] : '')
- );
+ 'file' => (isset($back[1]['file']) ? $back[1]['file'] : ''),
+ 'line' => (isset($back[1]['line']) ? $back[1]['line'] : '')
+ );
}
// --------------------------------------------------------------------
diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php
index f5534a7f7..51232f8a7 100644
--- a/system/libraries/Upload.php
+++ b/system/libraries/Upload.php
@@ -397,7 +397,7 @@ class CI_Upload {
if ( ! isset($_file))
{
- $this->set_error('upload_no_file_selected');
+ $this->set_error('upload_no_file_selected', 'debug');
return FALSE;
}
@@ -416,28 +416,28 @@ class CI_Upload {
switch ($error)
{
case UPLOAD_ERR_INI_SIZE:
- $this->set_error('upload_file_exceeds_limit');
+ $this->set_error('upload_file_exceeds_limit', 'info');
break;
case UPLOAD_ERR_FORM_SIZE:
- $this->set_error('upload_file_exceeds_form_limit');
+ $this->set_error('upload_file_exceeds_form_limit', 'info');
break;
case UPLOAD_ERR_PARTIAL:
- $this->set_error('upload_file_partial');
+ $this->set_error('upload_file_partial', 'debug');
break;
case UPLOAD_ERR_NO_FILE:
- $this->set_error('upload_no_file_selected');
+ $this->set_error('upload_no_file_selected', 'debug');
break;
case UPLOAD_ERR_NO_TMP_DIR:
- $this->set_error('upload_no_temp_directory');
+ $this->set_error('upload_no_temp_directory', 'error');
break;
case UPLOAD_ERR_CANT_WRITE:
- $this->set_error('upload_unable_to_write_file');
+ $this->set_error('upload_unable_to_write_file', 'error');
break;
case UPLOAD_ERR_EXTENSION:
- $this->set_error('upload_stopped_by_extension');
+ $this->set_error('upload_stopped_by_extension', 'debug');
break;
default:
- $this->set_error('upload_no_file_selected');
+ $this->set_error('upload_no_file_selected', 'debug');
break;
}
@@ -463,7 +463,7 @@ class CI_Upload {
// Is the file type allowed to be uploaded?
if ( ! $this->is_allowed_filetype())
{
- $this->set_error('upload_invalid_filetype');
+ $this->set_error('upload_invalid_filetype', 'debug');
return FALSE;
}
@@ -485,7 +485,7 @@ class CI_Upload {
if ( ! $this->is_allowed_filetype(TRUE))
{
- $this->set_error('upload_invalid_filetype');
+ $this->set_error('upload_invalid_filetype', 'debug');
return FALSE;
}
}
@@ -499,7 +499,7 @@ class CI_Upload {
// Is the file size within the allowed maximum?
if ( ! $this->is_allowed_filesize())
{
- $this->set_error('upload_invalid_filesize');
+ $this->set_error('upload_invalid_filesize', 'info');
return FALSE;
}
@@ -507,7 +507,7 @@ class CI_Upload {
// Note: This can fail if the server has an open_basedir restriction.
if ( ! $this->is_allowed_dimensions())
{
- $this->set_error('upload_invalid_dimensions');
+ $this->set_error('upload_invalid_dimensions', 'info');
return FALSE;
}
@@ -533,15 +533,9 @@ class CI_Upload {
* If it returns false there was a problem.
*/
$this->orig_name = $this->file_name;
-
- if ($this->overwrite === FALSE)
+ if (FALSE === ($this->file_name = $this->set_filename($this->upload_path, $this->file_name)))
{
- $this->file_name = $this->set_filename($this->upload_path, $this->file_name);
-
- if ($this->file_name === FALSE)
- {
- return FALSE;
- }
+ return FALSE;
}
/*
@@ -552,7 +546,7 @@ class CI_Upload {
*/
if ($this->xss_clean && $this->do_xss_clean() === FALSE)
{
- $this->set_error('upload_unable_to_write_file');
+ $this->set_error('upload_unable_to_write_file', 'error');
return FALSE;
}
@@ -567,7 +561,7 @@ class CI_Upload {
{
if ( ! @move_uploaded_file($this->file_temp, $this->upload_path.$this->file_name))
{
- $this->set_error('upload_destination_error');
+ $this->set_error('upload_destination_error', 'error');
return FALSE;
}
}
@@ -656,7 +650,7 @@ class CI_Upload {
$filename = md5(uniqid(mt_rand())).$this->file_ext;
}
- if ( ! file_exists($path.$filename))
+ if ($this->overwrite === TRUE OR ! file_exists($path.$filename))
{
return $filename;
}
@@ -675,7 +669,7 @@ class CI_Upload {
if ($new_filename === '')
{
- $this->set_error('upload_bad_filename');
+ $this->set_error('upload_bad_filename', 'debug');
return FALSE;
}
else
@@ -875,7 +869,7 @@ class CI_Upload {
if (empty($this->allowed_types) OR ! is_array($this->allowed_types))
{
- $this->set_error('upload_no_file_types');
+ $this->set_error('upload_no_file_types', 'debug');
return FALSE;
}
@@ -974,7 +968,7 @@ class CI_Upload {
{
if ($this->upload_path === '')
{
- $this->set_error('upload_no_filepath');
+ $this->set_error('upload_no_filepath', 'error');
return FALSE;
}
@@ -985,13 +979,13 @@ class CI_Upload {
if ( ! is_dir($this->upload_path))
{
- $this->set_error('upload_no_filepath');
+ $this->set_error('upload_no_filepath', 'error');
return FALSE;
}
if ( ! is_really_writable($this->upload_path))
{
- $this->set_error('upload_not_writable');
+ $this->set_error('upload_not_writable', 'error');
return FALSE;
}
@@ -1121,17 +1115,16 @@ class CI_Upload {
* @param string $msg
* @return CI_Upload
*/
- public function set_error($msg)
+ public function set_error($msg, $log_level = 'error')
{
$this->_CI->lang->load('upload');
is_array($msg) OR $msg = array($msg);
-
foreach ($msg as $val)
{
$msg = ($this->_CI->lang->line($val) === FALSE) ? $val : $this->_CI->lang->line($val);
$this->error_msg[] = $msg;
- log_message('error', $msg);
+ log_message($log_level, $msg);
}
return $this;
diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php
index 8fbc18f04..55555f56f 100644
--- a/system/libraries/Xmlrpc.php
+++ b/system/libraries/Xmlrpc.php
@@ -735,12 +735,32 @@ class XML_RPC_Client extends CI_Xmlrpc
.'Content-Length: '.strlen($msg->payload).$r.$r
.$msg->payload;
- for ($written = 0, $length = strlen($op); $written < $length; $written += $result)
+ for ($written = $timestamp = 0, $length = strlen($op); $written < $length; $written += $result)
{
if (($result = fwrite($fp, substr($op, $written))) === FALSE)
{
break;
}
+ // See https://bugs.php.net/bug.php?id=39598 and http://php.net/manual/en/function.fwrite.php#96951
+ elseif ($result === 0)
+ {
+ if ($timestamp === 0)
+ {
+ $timestamp = time();
+ }
+ elseif ($timestamp < (time() - $this->timeout))
+ {
+ $result = FALSE;
+ break;
+ }
+
+ usleep(250000);
+ continue;
+ }
+ else
+ {
+ $timestamp = 0;
+ }
}
if ($result === FALSE)
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index ee1e36521..4fe3b94ff 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -12,14 +12,23 @@ Release Date: Not Released
- Added DoS mitigation to :php:func:`hash_pbkdf2()` :doc:`compatibility function <general/compatibility_functions>`.
- Database
-
+
- Added ``list_fields()`` support for SQLite ('sqlite3' and 'pdo_sqlite' drivers).
+- Libraries
+
+ - :doc:`File Uploading Library <libraries/file_uploading>` changes:
+
+ - Changed method ``set_error()`` to accept a custom log level (defaults to 'error').
+ - Errors "no_file_selected", "file_partial", "stopped_by_extension", "no_file_types", "invalid_filetype", "bad_filename" are now logged at the 'debug' level.
+ - Errors "file_exceeds_limit", "file_exceeds_form_limit", "invalid_filesize", "invalid_dimensions" are now logged at the 'info' level.
+
+ - Added 'is_resource' to the available expectations in :doc:`Unit Testing Library <libraries/unit_testing>`.
+
- Helpers
-
- - :doc:`Form Helper <helpers/form_helper>` changes include:
- - Made all form helpers consistent by allowing an array to be passed for extra attributes.
+ - Added Unicode support to :doc:`URL Helper <helpers/url_helper>` function :php:func:`url_title()`.
+ - Added support for passing the "extra" parameter as an array to all :doc:`Form Helper <helpers/form_helper>` functions that use it.
Bug fixes for 3.0.1
-------------------
@@ -28,7 +37,7 @@ Bug fixes for 3.0.1
- Fixed a bug (#3744) - Redis :doc:`Caching <libraries/caching>` driver didn't handle authentication failures properly.
- Fixed a bug (#3761) - :doc:`URL Helper <helpers/url_helper>` function :php:func:`anchor()` didn't work with array inputs.
- Fixed a bug (#3773) - ``db_select()`` didn't work for MySQL with the PDO :doc:`Database <database/index>` driver.
-- Fixed a bug (#3771) - :doc:`Form Validation Library <libraries/form_validation>` was looking for a 'form_validation_' prefix when trying to translate field name labels.
+- Fixed a bug (#3771) - :doc:`Form Validation Library <libraries/form_validation>` was looking for a 'form_validation\_' prefix when trying to translate field name labels.
- Fixed a bug (#3787) - :doc:`FTP Library <libraries/ftp>` method ``delete_dir()`` failed when the target has subdirectories.
- Fixed a bug (#3801) - :doc:`Output Library <libraries/output>` method ``_display_cache()`` incorrectly looked for the last modified time of a directory instead of the cache file.
- Fixed a bug (#3816) - :doc:`Form Validation Library <libraries/form_validation>` treated empty string values as non-existing ones.
@@ -36,6 +45,18 @@ Bug fixes for 3.0.1
- Fixed a bug (#3846) - :doc:`Image Manipulation Library <libraries/image_lib>` method `image_mirror_gd()` didn't properly initialize its variables.
- Fixed a bug (#3854) - `field_data()` didn't work properly with the Oracle (OCI8) database driver.
- Fixed a bug in the :doc:`Database Utility Class <database/utilities>` method ``csv_from_result()`` didn't work with a whitespace CSV delimiter.
+- Fixed a bug (#3890) - :doc:`Input Library <libraries/input>` method ``get_request_header()`` treated header names as case-sensitive.
+- Fixed a bug (#3903) - :doc:`Form Validation Library <libraries/form_validation>` ignored "unnamed" closure validation rules.
+- Fixed a bug (#3904) - :doc:`Form Validation Library <libraries/form_validation>` ignored "named" callback rules when the field is empty and there's no 'required' rule.
+- Fixed a bug (#3922) - :doc:`Email <libraries/email>` and :doc:`XML-RPC <libraries/xmlrpc>` libraries could enter an infinite loop due to `PHP bug #39598 <https://bugs.php.net/bug.php?id=39598>`_.
+- Fixed a bug (#3913) - :doc:`Cache Library <libraries/caching>` didn't work with the direct ``$this->cache->$driver_name->method()`` syntax with Redis and Memcache(d).
+- Fixed a bug (#3932) - :doc:`Query Builder <database/query_builder>` didn't properly compile WHERE and HAVING conditions for field names that end with "and", "or".
+- Fixed a bug in :doc:`Query Builder <database/query_builder>` where ``delete()`` didn't properly work on multiple tables with a WHERE condition previously set via ``where()``.
+- Fixed a bug (#3952) - :doc:`Database <database/index>` method ``list_fields()`` didn't work with SQLite3.
+- Fixed a bug (#3955) - :doc:`Cache Library <libraries/caching>` methods ``increment()`` and ``decrement()`` ignored the 'key_prefix' setting.
+- Fixed a bug (#3963) - :doc:`Unit Testing Library <libraries/unit_testing>` wrongly tried to translate filenames, line numbers and notes values in test results.
+- Fixed a bug (#3965) - :doc:`File Uploading Library <libraries/file_uploading>` ignored the "encrypt_name" setting when "overwrite" is enabled.
+- Fixed a bug (#3968) - :doc:`Database Forge <database/forge>` method ``add_key()`` didn't treat array inputs as composite keys unless it's a PRIMARY KEY.
Version 3.0.0
=============
diff --git a/user_guide_src/source/database/forge.rst b/user_guide_src/source/database/forge.rst
index a4edada5c..646e3a56e 100644
--- a/user_guide_src/source/database/forge.rst
+++ b/user_guide_src/source/database/forge.rst
@@ -143,13 +143,15 @@ string into the field definitions with add_field()
$this->dbforge->add_field("label varchar(100) NOT NULL DEFAULT 'default label'");
+.. note:: Passing raw strings as fields cannot be followed by ``add_key()`` calls on those fields.
+
.. note:: Multiple calls to add_field() are cumulative.
Creating an id field
--------------------
There is a special exception for creating id fields. A field with type
-id will automatically be assinged as an INT(9) auto_incrementing
+id will automatically be assigned as an INT(9) auto_incrementing
Primary Key.
::
diff --git a/user_guide_src/source/database/utilities.rst b/user_guide_src/source/database/utilities.rst
index 81b949dd7..2fa5239c8 100644
--- a/user_guide_src/source/database/utilities.rst
+++ b/user_guide_src/source/database/utilities.rst
@@ -180,7 +180,7 @@ backup data can be compressed in either Zip or Gzip format.
.. note:: For Interbase/Firebird databases, the backup file name is the only parameter.
- Eg. $this->dbutil->backup('db_backup_filename');
+ $this->dbutil->backup('db_backup_filename');
.. note:: Due to the limited execution time and memory available to PHP,
backing up very large databases may not be possible. If your database is
@@ -197,7 +197,7 @@ Usage Example
$this->load->dbutil();
// Backup your entire database and assign it to a variable
- $backup =& $this->dbutil->backup();
+ $backup = $this->dbutil->backup();
// Load the file helper and write the file to your server
$this->load->helper('file');
diff --git a/user_guide_src/source/general/security.rst b/user_guide_src/source/general/security.rst
index fcfe4c24b..d4120d162 100644
--- a/user_guide_src/source/general/security.rst
+++ b/user_guide_src/source/general/security.rst
@@ -61,7 +61,7 @@ data from the SERVER array, you are encouraged to practice this three
step approach:
#. Validate the data to ensure it conforms to the correct type, length,
- size, etc. (sometimes this step can replace step one)
+ size, etc.
#. Filter the data as if it were tainted.
#. Escape the data before submitting it into your database or outputting
it to a browser.
@@ -199,4 +199,4 @@ file to restrict access to those resources.
CodeIgniter will have an index.html file in all of its
directories in an attempt to hide some of this data, but have
it in mind that this is not enough to prevent a serious
-attacker. \ No newline at end of file
+attacker.
diff --git a/user_guide_src/source/libraries/email.rst b/user_guide_src/source/libraries/email.rst
index 54fb53f44..eadfcfd5c 100644
--- a/user_guide_src/source/libraries/email.rst
+++ b/user_guide_src/source/libraries/email.rst
@@ -373,7 +373,7 @@ Class Reference
foreach ($list as $address)
{
$this->email->to($address);
- $cid = $this->email->attach_cid($filename);
+ $cid = $this->email->attachment_cid($filename);
$this->email->message('<img src='cid:". $cid ."' alt="photo1" />');
$this->email->send();
}
diff --git a/user_guide_src/source/libraries/unit_testing.rst b/user_guide_src/source/libraries/unit_testing.rst
index 026781cb7..57934cba3 100644
--- a/user_guide_src/source/libraries/unit_testing.rst
+++ b/user_guide_src/source/libraries/unit_testing.rst
@@ -76,6 +76,7 @@ result. Here is a list of allowed comparison types:
- is_double
- is_array
- is_null
+- is_resource
Generating Reports
==================
diff --git a/user_guide_src/source/overview/at_a_glance.rst b/user_guide_src/source/overview/at_a_glance.rst
index facbedaee..ce195c211 100644
--- a/user_guide_src/source/overview/at_a_glance.rst
+++ b/user_guide_src/source/overview/at_a_glance.rst
@@ -16,8 +16,8 @@ for a given task.
CodeIgniter is Free
===================
-CodeIgniter is licensed under an Apache/BSD-style open source license so
-you can use it however you please. For more information please read the
+CodeIgniter is licensed under the MIT license so you can use it however
+you please. For more information please read the
:doc:`license agreement <../license>`.
CodeIgniter is Light Weight