Merge branch 'feature/form_helper' of github.com:darkhouse/CodeIgniter into feature/form_helpers_extra_array
Manually fixed conflicts in:
user_guide_src/source/changelog.rst
diff --git a/application/config/autoload.php b/application/config/autoload.php
index 72f855c..4bc6bf0 100644
--- a/application/config/autoload.php
+++ b/application/config/autoload.php
@@ -39,16 +39,15 @@
| $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['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['helper'] = array('url', 'file');
*/
-
$autoload['helper'] = array();
-
/*
| -------------------------------------------------------------------
| Auto-load Config files
@@ -103,10 +97,8 @@
| config files. Otherwise, leave it blank.
|
*/
-
$autoload['config'] = array();
-
/*
| -------------------------------------------------------------------
| Auto-load Language files
@@ -119,10 +111,8 @@
| "codeigniter_lang.php" would be referenced as array('codeigniter');
|
*/
-
$autoload['language'] = array();
-
/*
| -------------------------------------------------------------------
| Auto-load Models
@@ -136,5 +126,4 @@
|
| $autoload['model'] = array('first_model' => 'first');
*/
-
$autoload['model'] = array();
diff --git a/application/config/config.php b/application/config/config.php
index 94e5d28..86ca312 100644
--- a/application/config/config.php
+++ b/application/config/config.php
@@ -58,7 +58,6 @@
|
| http://codeigniter.com/user_guide/general/urls.html
*/
-
$config['url_suffix'] = '';
/*
@@ -155,7 +154,6 @@
*/
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';
-
/*
|--------------------------------------------------------------------------
| Enable Query Strings
@@ -325,7 +323,7 @@
|
| '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 @@
|--------------------------------------------------------------------------
|
| 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['rewrite_short_tags'] = FALSE;
-
/*
|--------------------------------------------------------------------------
| Reverse Proxy IPs
diff --git a/application/config/constants.php b/application/config/constants.php
index 01096c7..48283e2 100644
--- a/application/config/constants.php
+++ b/application/config/constants.php
@@ -27,7 +27,6 @@
| 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 fc3a5e5..84aab91 100644
--- a/application/config/database.php
+++ b/application/config/database.php
@@ -58,7 +58,6 @@
| 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 083bf28..4b585a6 100644
--- a/application/config/migration.php
+++ b/application/config/migration.php
@@ -21,12 +21,12 @@
| 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 78d8e53..1f591ba 100644
--- a/application/config/mimes.php
+++ b/application/config/mimes.php
@@ -9,7 +9,6 @@
| 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 @@
'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 1428d68..1eeba47 100644
--- a/application/config/smileys.php
+++ b/application/config/smileys.php
@@ -13,7 +13,6 @@
| 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 2fd9554..1129dba 100644
--- a/application/config/user_agents.php
+++ b/application/config/user_agents.php
@@ -10,7 +10,6 @@
| 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 @@
'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 12332cf..b0bbb7b 100644
--- a/system/core/Input.php
+++ b/system/core/Input.php
@@ -799,19 +799,27 @@
*/
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 f91d3f6..0510005 100644
--- a/system/core/Router.php
+++ b/system/core/Router.php
@@ -105,7 +105,7 @@
/**
* 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 64ee880..d2bce5c 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -1751,7 +1751,7 @@
//
// 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 f6ee2a6..865498f 100644
--- a/system/database/DB_forge.php
+++ b/system/database/DB_forge.php
@@ -239,7 +239,7 @@
*/
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 @@
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 8251f45..a8b5b35 100644
--- a/system/database/DB_query_builder.php
+++ b/system/database/DB_query_builder.php
@@ -2092,10 +2092,13 @@
}
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 @@
// 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 d5ca741..409e650 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 @@
}
$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 28faadd..15afbde 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 @@
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 a7c6420..31e37de 100644
--- a/system/database/drivers/sqlite3/sqlite3_driver.php
+++ b/system/database/drivers/sqlite3/sqlite3_driver.php
@@ -266,7 +266,7 @@
}
$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 69f65b6..24690ba 100644
--- a/system/database/drivers/sqlite3/sqlite3_forge.php
+++ b/system/database/drivers/sqlite3/sqlite3_forge.php
@@ -74,7 +74,8 @@
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 5f8c6ce..d65f92f 100644
--- a/system/helpers/url_helper.php
+++ b/system/helpers/url_helper.php
@@ -474,7 +474,7 @@
* @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 @@
$trans = array(
'&.+?;' => '',
- '[^a-z0-9 _-]' => '',
+ '[^\w\d _-]' => '',
'\s+' => $separator,
'('.$q_separator.')+' => $separator
);
@@ -500,7 +500,7 @@
$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 215a7c5..0c87a56 100644
--- a/system/libraries/Cache/Cache.php
+++ b/system/libraries/Cache/Cache.php
@@ -178,7 +178,7 @@
*/
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 @@
*/
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 @@
*/
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 b90b561..111e210 100644
--- a/system/libraries/Cache/drivers/Cache_memcached.php
+++ b/system/libraries/Cache/drivers/Cache_memcached.php
@@ -68,6 +68,76 @@
)
);
+ // ------------------------------------------------------------------------
+
+ /**
+ * 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 @@
// ------------------------------------------------------------------------
/**
- * 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 @@
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 66966ba..d7dca19 100644
--- a/system/libraries/Cache/drivers/Cache_redis.php
+++ b/system/libraries/Cache/drivers/Cache_redis.php
@@ -79,6 +79,63 @@
// ------------------------------------------------------------------------
/**
+ * 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 @@
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 @@
$this->_redis->close();
}
}
-
}
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index 66b5803..57693e1 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -2126,12 +2126,32 @@
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 7599602..d9ecc45 100644
--- a/system/libraries/Form_validation.php
+++ b/system/libraries/Form_validation.php
@@ -618,6 +618,12 @@
$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 @@
// 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 7b744ad..3f986f3 100644
--- a/system/libraries/Unit_test.php
+++ b/system/libraries/Unit_test.php
@@ -55,14 +55,14 @@
*
* @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 @@
*
* @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 @@
* @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 @@
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 @@
$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 @@
{
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 @@
{
$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 f5534a7..51232f8 100644
--- a/system/libraries/Upload.php
+++ b/system/libraries/Upload.php
@@ -397,7 +397,7 @@
if ( ! isset($_file))
{
- $this->set_error('upload_no_file_selected');
+ $this->set_error('upload_no_file_selected', 'debug');
return FALSE;
}
@@ -416,28 +416,28 @@
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 @@
// 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 @@
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 @@
// 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 @@
// 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 @@
* 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 @@
*/
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 @@
{
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 @@
$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 @@
if ($new_filename === '')
{
- $this->set_error('upload_bad_filename');
+ $this->set_error('upload_bad_filename', 'debug');
return FALSE;
}
else
@@ -875,7 +869,7 @@
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 @@
{
if ($this->upload_path === '')
{
- $this->set_error('upload_no_filepath');
+ $this->set_error('upload_no_filepath', 'error');
return FALSE;
}
@@ -985,13 +979,13 @@
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 @@
* @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 8fbc18f..55555f5 100644
--- a/system/libraries/Xmlrpc.php
+++ b/system/libraries/Xmlrpc.php
@@ -735,12 +735,32 @@
.'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 ee1e365..4fe3b94 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -12,14 +12,23 @@
- 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).
-- Helpers
-
- - :doc:`Form Helper <helpers/form_helper>` changes include:
+- Libraries
- - Made all form helpers consistent by allowing an array to be passed for extra attributes.
+ - :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
+
+ - 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 @@
- 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 @@
- 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 a4edada..646e3a5 100644
--- a/user_guide_src/source/database/forge.rst
+++ b/user_guide_src/source/database/forge.rst
@@ -143,13 +143,15 @@
$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 81b949d..2fa5239 100644
--- a/user_guide_src/source/database/utilities.rst
+++ b/user_guide_src/source/database/utilities.rst
@@ -180,7 +180,7 @@
.. 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 @@
$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 fcfe4c2..d4120d1 100644
--- a/user_guide_src/source/general/security.rst
+++ b/user_guide_src/source/general/security.rst
@@ -61,7 +61,7 @@
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 @@
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 54fb53f..eadfcfd 100644
--- a/user_guide_src/source/libraries/email.rst
+++ b/user_guide_src/source/libraries/email.rst
@@ -373,7 +373,7 @@
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 026781c..57934cb 100644
--- a/user_guide_src/source/libraries/unit_testing.rst
+++ b/user_guide_src/source/libraries/unit_testing.rst
@@ -76,6 +76,7 @@
- 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 facbeda..ce195c2 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 @@
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