summaryrefslogtreecommitdiffstats
path: root/system
diff options
context:
space:
mode:
Diffstat (limited to 'system')
-rw-r--r--[-rwxr-xr-x]system/core/Benchmark.php0
-rw-r--r--[-rwxr-xr-x]system/core/CodeIgniter.php0
-rw-r--r--system/core/Common.php2
-rw-r--r--[-rwxr-xr-x]system/core/Config.php0
-rw-r--r--[-rwxr-xr-x]system/core/Exceptions.php0
-rw-r--r--[-rwxr-xr-x]system/core/Hooks.php0
-rw-r--r--[-rwxr-xr-x]system/core/Input.php20
-rw-r--r--[-rwxr-xr-x]system/core/Lang.php0
-rw-r--r--system/core/Loader.php2
-rw-r--r--[-rwxr-xr-x]system/core/Model.php0
-rw-r--r--[-rwxr-xr-x]system/core/Output.php0
-rw-r--r--[-rwxr-xr-x]system/core/Router.php0
-rw-r--r--[-rwxr-xr-x]system/core/Security.php0
-rw-r--r--[-rwxr-xr-x]system/core/URI.php20
-rw-r--r--[-rwxr-xr-x]system/database/DB.php0
-rw-r--r--system/database/DB_driver.php105
-rw-r--r--system/database/DB_forge.php54
-rw-r--r--system/database/DB_query_builder.php117
-rw-r--r--system/database/DB_utility.php13
-rw-r--r--system/database/drivers/cubrid/cubrid_utility.php6
-rw-r--r--system/database/drivers/interbase/interbase_forge.php8
-rw-r--r--system/database/drivers/mssql/mssql_driver.php25
-rw-r--r--system/database/drivers/mysqli/mysqli_utility.php119
-rw-r--r--system/database/drivers/postgre/postgre_driver.php9
-rw-r--r--system/database/drivers/sqlite/sqlite_forge.php8
-rw-r--r--system/database/drivers/sqlite3/sqlite3_forge.php8
-rw-r--r--system/database/drivers/sqlsrv/sqlsrv_driver.php27
-rw-r--r--system/database/drivers/sqlsrv/sqlsrv_forge.php2
-rw-r--r--system/database/drivers/sqlsrv/sqlsrv_result.php2
-rw-r--r--system/database/drivers/sqlsrv/sqlsrv_utility.php2
-rw-r--r--system/libraries/Cache/Cache.php5
-rw-r--r--system/libraries/Cache/drivers/Cache_file.php6
-rw-r--r--system/libraries/Cache/drivers/Cache_redis.php236
-rw-r--r--system/libraries/Email.php2
-rw-r--r--system/libraries/Encrypt.php1
-rw-r--r--system/libraries/Form_validation.php11
-rw-r--r--system/libraries/Pagination.php112
-rw-r--r--system/libraries/Upload.php14
38 files changed, 767 insertions, 169 deletions
diff --git a/system/core/Benchmark.php b/system/core/Benchmark.php
index 2fabdf46e..2fabdf46e 100755..100644
--- a/system/core/Benchmark.php
+++ b/system/core/Benchmark.php
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php
index 8159b19f5..8159b19f5 100755..100644
--- a/system/core/CodeIgniter.php
+++ b/system/core/CodeIgniter.php
diff --git a/system/core/Common.php b/system/core/Common.php
index c08755c91..1708653e7 100644
--- a/system/core/Common.php
+++ b/system/core/Common.php
@@ -240,7 +240,7 @@ if ( ! function_exists('get_config'))
}
// Is the config file in the environment folder?
- if (defined(ENVIRONMENT) && file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php'))
+ if (defined('ENVIRONMENT') && file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php'))
{
require($file_path);
}
diff --git a/system/core/Config.php b/system/core/Config.php
index 3de1bcb96..3de1bcb96 100755..100644
--- a/system/core/Config.php
+++ b/system/core/Config.php
diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php
index 8c32085fe..8c32085fe 100755..100644
--- a/system/core/Exceptions.php
+++ b/system/core/Exceptions.php
diff --git a/system/core/Hooks.php b/system/core/Hooks.php
index 29fd88201..29fd88201 100755..100644
--- a/system/core/Hooks.php
+++ b/system/core/Hooks.php
diff --git a/system/core/Input.php b/system/core/Input.php
index b986c4973..162e40c85 100755..100644
--- a/system/core/Input.php
+++ b/system/core/Input.php
@@ -376,14 +376,26 @@ class CI_Input {
/**
* Validate IP Address
*
- * Updated version suggested by Geert De Deckere
- *
* @param string
+ * @param string 'ipv4' or 'ipv6'
* @return bool
*/
- public function valid_ip($ip)
+ public function valid_ip($ip, $which = '')
{
- return (bool) filter_var($ip, FILTER_VALIDATE_IP);
+ switch (strtolower($which))
+ {
+ case 'ipv4':
+ $which = FILTER_FLAG_IPV4;
+ break;
+ case 'ipv6':
+ $which = FILTER_FLAG_IPV6;
+ break;
+ default:
+ $which = NULL;
+ break;
+ }
+
+ return (bool) filter_var($ip, FILTER_VALIDATE_IP, $which);
}
// --------------------------------------------------------------------
diff --git a/system/core/Lang.php b/system/core/Lang.php
index 3001f1b13..3001f1b13 100755..100644
--- a/system/core/Lang.php
+++ b/system/core/Lang.php
diff --git a/system/core/Loader.php b/system/core/Loader.php
index 09e948714..94739c74a 100644
--- a/system/core/Loader.php
+++ b/system/core/Loader.php
@@ -668,7 +668,7 @@ class CI_Loader {
* @param bool
* @return void
*/
- public function add_package_path($path, $view_cascade=TRUE)
+ public function add_package_path($path, $view_cascade = TRUE)
{
$path = rtrim($path, '/').'/';
diff --git a/system/core/Model.php b/system/core/Model.php
index 9bc9f879f..9bc9f879f 100755..100644
--- a/system/core/Model.php
+++ b/system/core/Model.php
diff --git a/system/core/Output.php b/system/core/Output.php
index 5588ffe8e..5588ffe8e 100755..100644
--- a/system/core/Output.php
+++ b/system/core/Output.php
diff --git a/system/core/Router.php b/system/core/Router.php
index 5bc053045..5bc053045 100755..100644
--- a/system/core/Router.php
+++ b/system/core/Router.php
diff --git a/system/core/Security.php b/system/core/Security.php
index 4593a1090..4593a1090 100755..100644
--- a/system/core/Security.php
+++ b/system/core/Security.php
diff --git a/system/core/URI.php b/system/core/URI.php
index a575bc36e..2e661ed4c 100755..100644
--- a/system/core/URI.php
+++ b/system/core/URI.php
@@ -119,7 +119,7 @@ class CI_URI {
}
// No PATH_INFO?... What about QUERY_STRING?
- $path = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
+ $path = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
if (trim($path, '/') !== '')
{
$this->_set_uri_string($path);
@@ -163,7 +163,7 @@ class CI_URI {
* @param string
* @return void
*/
- public function _set_uri_string($str)
+ protected function _set_uri_string($str)
{
// Filter out control characters
$str = remove_invisible_characters($str, FALSE);
@@ -177,8 +177,8 @@ class CI_URI {
/**
* Detects the URI
*
- * This function will detect the URI automatically and fix the query string
- * if necessary.
+ * This function will detect the URI automatically
+ * and fix the query string if necessary.
*
* @return string
*/
@@ -189,7 +189,6 @@ class CI_URI {
return '';
}
- $uri = $_SERVER['REQUEST_URI'];
if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0)
{
$uri = substr($uri, strlen($_SERVER['SCRIPT_NAME']));
@@ -198,14 +197,19 @@ class CI_URI {
{
$uri = substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME'])));
}
+ else
+ {
+ $uri = $_SERVER['REQUEST_URI'];
+ }
// This section ensures that even on servers that require the URI to be in the query string (Nginx) a correct
// URI is found, and also fixes the QUERY_STRING server var and $_GET array.
- if (strncmp($uri, '?/', 2) === 0)
+ if (strpos($uri, '?/') === 0)
{
$uri = substr($uri, 2);
}
- $parts = preg_split('#\?#i', $uri, 2);
+
+ $parts = explode('?', $uri, 2);
$uri = $parts[0];
if (isset($parts[1]))
{
@@ -223,7 +227,7 @@ class CI_URI {
return '/';
}
- $uri = parse_url($uri, PHP_URL_PATH);
+ $uri = parse_url('pseudo://hostname/'.$uri, PHP_URL_PATH);
// Do some final cleaning of the URI and return it
return str_replace(array('//', '../'), '/', trim($uri, '/'));
diff --git a/system/database/DB.php b/system/database/DB.php
index 00d14b43e..00d14b43e 100755..100644
--- a/system/database/DB.php
+++ b/system/database/DB.php
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index 65f1f18d0..d056bdb90 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -596,35 +596,53 @@ abstract class CI_DB_driver {
*/
public function compile_binds($sql, $binds)
{
- if (strpos($sql, $this->bind_marker) === FALSE)
+ if (empty($binds) OR empty($this->bind_marker) OR strpos($sql, $this->bind_marker) === FALSE)
{
return $sql;
}
-
- if ( ! is_array($binds))
+ elseif ( ! is_array($binds))
{
$binds = array($binds);
+ $bind_count = 1;
+ }
+ else
+ {
+ // Make sure we're using numeric keys
+ $binds = array_values($binds);
+ $bind_count = count($binds);
}
- // Get the sql segments around the bind markers
- $segments = explode($this->bind_marker, $sql);
+ // We'll need the marker length later
+ $ml = strlen($this->bind_marker);
- // The count of bind should be 1 less then the count of segments
- // If there are more bind arguments trim it down
- if (count($binds) >= count($segments))
+ // Make sure not to replace a chunk inside a string that happens to match the bind marker
+ if ($c = preg_match_all("/'[^']*'/i", $sql, $matches))
{
- $binds = array_slice($binds, 0, count($segments)-1);
+ $c = preg_match_all('/'.preg_quote($this->bind_marker).'/i',
+ str_replace($matches[0],
+ str_replace($this->bind_marker, str_repeat(' ', $ml), $matches[0]),
+ $sql, $c),
+ $matches, PREG_OFFSET_CAPTURE);
+
+ // Bind values' count must match the count of markers in the query
+ if ($bind_count !== $c)
+ {
+ return $sql;
+ }
+ }
+ elseif (($c = preg_match_all('/'.preg_quote($this->bind_marker).'/i', $sql, $matches, PREG_OFFSET_CAPTURE)) !== $bind_count)
+ {
+ return $sql;
}
- // Construct the binded query
- $result = $segments[0];
- $i = 0;
- foreach ($binds as $bind)
+ do
{
- $result .= $this->escape($bind).$segments[++$i];
+ $c--;
+ $sql = substr_replace($sql, $this->escape($binds[$c]), $matches[0][$c][1], $ml);
}
+ while ($c !== 0);
- return $result;
+ return $sql;
}
// --------------------------------------------------------------------
@@ -1062,7 +1080,7 @@ abstract class CI_DB_driver {
*/
protected function _has_operator($str)
{
- return (bool) preg_match('/(\s|<|>|!|=|IS NULL|IS NOT NULL)/i', trim($str));
+ return (bool) preg_match('/(\s|<|>|!|=|IS NULL|IS NOT NULL|BETWEEN)/i', trim($str));
}
// --------------------------------------------------------------------
@@ -1300,36 +1318,63 @@ abstract class CI_DB_driver {
$escaped_array = array();
foreach ($item as $k => $v)
{
- $escaped_array[$this->protect_identifiers($k)] = $this->protect_identifiers($v);
+ $escaped_array[$this->protect_identifiers($k)] = $this->protect_identifiers($v, $prefix_single, $protect_identifiers, $field_exists);
}
return $escaped_array;
}
+ // This is basically a bug fix for queries that use MAX, MIN, etc.
+ // If a parenthesis is found we know that we do not need to
+ // escape the data or add a prefix. There's probably a more graceful
+ // way to deal with this, but I'm not thinking of it -- Rick
+ if (strpos($item, '(') !== FALSE)
+ {
+ return $item;
+ }
+
// Convert tabs or multiple spaces into single spaces
- $item = preg_replace('/[\t ]+/', ' ', $item);
+ $item = preg_replace('/\s+/', ' ', $item);
+
+ static $preg_ec = array();
+
+ if (empty($preg_ec))
+ {
+ if (is_array($this->_escape_char))
+ {
+ $preg_ec = array(preg_quote($this->_escape_char[0]), preg_quote($this->_escape_char[1]));
+ }
+ else
+ {
+ $preg_ec[0] = $preg_ec[1] = preg_quote($this->_escape_char);
+ }
+ }
// If the item has an alias declaration we remove it and set it aside.
// Basically we remove everything to the right of the first space
- if (strpos($item, ' ') !== FALSE)
+ preg_match('/^(('.$preg_ec[0].'[^'.$preg_ec[1].']+'.$preg_ec[1].')|([^'.$preg_ec[0].'][^\s]+))( AS)*(.+)*$/i', $item, $matches);
+
+ if (isset($matches[4]))
{
- $alias = strstr($item, ' ');
- $item = substr($item, 0, - strlen($alias));
+ $item = $matches[1];
+
+ // Escape the alias, if needed
+ if ($protect_identifiers === TRUE)
+ {
+ $alias = empty($matches[5])
+ ? ' '.$this->escape_identifiers(ltrim($matches[4]))
+ : $matches[4].' '.$this->escape_identifiers(ltrim($matches[5]));
+ }
+ else
+ {
+ $alias = $matches[4].$matches[5];
+ }
}
else
{
$alias = '';
}
- // This is basically a bug fix for queries that use MAX, MIN, etc.
- // If a parenthesis is found we know that we do not need to
- // escape the data or add a prefix. There's probably a more graceful
- // way to deal with this, but I'm not thinking of it -- Rick
- if (strpos($item, '(') !== FALSE)
- {
- return $item.$alias;
- }
-
// Break the string apart if it contains periods, then insert the table prefix
// in the correct location, assuming the period doesn't indicate that we're dealing
// with an alias. While we're at it, we will escape the components
diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php
index ff5eb3fe6..9b7639289 100644
--- a/system/database/DB_forge.php
+++ b/system/database/DB_forge.php
@@ -72,6 +72,11 @@ abstract class CI_DB_forge {
return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE;
}
+ if ( ! empty($this->db->data_cache['db_names']))
+ {
+ $this->db->data_cache['db_names'][] = $db_name;
+ }
+
return TRUE;
}
@@ -99,6 +104,15 @@ abstract class CI_DB_forge {
return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE;
}
+ if ( ! empty($this->db->data_cache['db_names']))
+ {
+ $key = array_search(strtolower($db_name), array_map('strtolower', $this->db->data_cache['db_names']), TRUE);
+ if ($key !== FALSE)
+ {
+ unset($this->db->data_cache['db_names'][$key]);
+ }
+ }
+
return TRUE;
}
@@ -209,7 +223,18 @@ abstract class CI_DB_forge {
$sql = $this->_create_table($this->db->dbprefix.$table, $this->fields, $this->primary_keys, $this->keys, $if_not_exists);
$this->_reset();
- return is_bool($sql) ? $sql : $this->db->query($sql);
+
+ if (is_bool($sql))
+ {
+ return $sql;
+ }
+
+ if (($result = $this->db->query($sql)) !== FALSE && ! empty($this->db->data_cache['table_names']))
+ {
+ $this->db->data_cache['table_names'][] = $$this->db->dbprefix.$table;
+ }
+
+ return $result;
}
// --------------------------------------------------------------------
@@ -231,7 +256,19 @@ abstract class CI_DB_forge {
return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
}
- return $this->db->query(sprintf($this->_drop_table, $this->db->escape_identifiers($this->db->dbprefix.$table_name)));
+ $result = $this->db->query(sprintf($this->_drop_table, $this->db->escape_identifiers($this->db->dbprefix.$table_name)));
+
+ // Update table list cache
+ if ($result && ! empty($this->db->data_cache['table_names']))
+ {
+ $key = array_search(strtolower($this->db->dbprefix.$table_name), array_map('strtolower', $this->db->data_cache['table_names']), TRUE);
+ if ($key !== FALSE)
+ {
+ unset($this->db->data_cache['table_names'][$key]);
+ }
+ }
+
+ return $result;
}
// --------------------------------------------------------------------
@@ -255,10 +292,21 @@ abstract class CI_DB_forge {
return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
}
- return $this->db->query(sprintf($this->_rename_table,
+ $result = $this->db->query(sprintf($this->_rename_table,
$this->db->escape_identifiers($this->db->dbprefix.$table_name),
$this->db->escape_identifiers($this->db->dbprefix.$new_table_name))
);
+
+ if ($result && ! empty($this->db->data_cache['table_names']))
+ {
+ $key = array_search(strtolower($this->db->dbprefix.$table_name), array_map('strtolower', $this->db->data_cache['table_names']), TRUE);
+ if ($key !== FALSE)
+ {
+ $this->db->data_cache['table_names'][$key] = $this->db->dbprefix.$new_table_name;
+ }
+ }
+
+ return $result;
}
// --------------------------------------------------------------------
diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php
index 3ed556212..488b294e4 100644
--- a/system/database/DB_query_builder.php
+++ b/system/database/DB_query_builder.php
@@ -53,7 +53,6 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
protected $qb_keys = array();
protected $qb_limit = FALSE;
protected $qb_offset = FALSE;
- protected $qb_order = FALSE;
protected $qb_orderby = array();
protected $qb_set = array();
protected $qb_wherein = array();
@@ -84,6 +83,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* Generates the SELECT portion of the query
*
* @param string
+ * @param mixed
* @return object
*/
public function select($select = '*', $escape = NULL)
@@ -93,6 +93,9 @@ 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
+ is_bool($escape) OR $escape = $this->_protect_identifiers;
+
foreach ($select as $val)
{
$val = trim($val);
@@ -321,15 +324,16 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* @param string
* @param string the join condition
* @param string the type of join
+ * @param string wether not to try to escape identifiers
* @return object
*/
- public function join($table, $cond, $type = '')
+ public function join($table, $cond, $type = '', $escape = TRUE)
{
if ($type !== '')
{
$type = strtoupper(trim($type));
- if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER')))
+ if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER'), TRUE))
{
$type = '';
}
@@ -343,12 +347,39 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
// in the protect_identifiers to know whether to add a table prefix
$this->_track_aliases($table);
- // Strip apart the condition and protect the identifiers
- if (preg_match('/([\[\w\.]+)([\W\s]+)(.+)/', $cond, $match))
+ // Split multiple conditions
+ if ($escape === TRUE && preg_match_all('/\sAND\s|\sOR\s/i', $cond, $m, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
+ {
+ $newcond = '';
+ $m[0][] = array('', strlen($cond));
+
+ for ($i = 0, $c = count($m[0]), $s = 0;
+ $i < $c;
+ $s += $m[0][$i][1] + strlen($m[0][$i][0]), $i++)
+ {
+ $temp = substr($cond, $s, $m[0][$i][1]);
+
+ $newcond .= preg_match('/([\[\w\.-]+)([\W\s]+)(.+)/i', $temp, $match)
+ ? $this->protect_identifiers($match[1]).$match[2].$this->protect_identifiers($match[3])
+ : $temp;
+
+ $newcond .= $m[0][$i][0];
+ }
+
+ $cond = $newcond;
+ }
+ // Split apart the condition and protect the identifiers
+ elseif ($escape === TRUE && preg_match('/([\[\w\.-]+)([\W\s]+)(.+)/i', $cond, $match))
{
$cond = $this->protect_identifiers($match[1]).$match[2].$this->protect_identifiers($match[3]);
}
+ // Do we want to escape the table name?
+ if ($escape === TRUE)
+ {
+ $table = $this->protect_identifiers($table, TRUE, NULL, FALSE);
+ }
+
// Assemble the JOIN statement
$this->qb_join[] = $join = $type.'JOIN '.$this->protect_identifiers($table, TRUE, NULL, FALSE).' ON '.$cond;
@@ -371,6 +402,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
*
* @param mixed
* @param mixed
+ * @param bool
* @return object
*/
public function where($key, $value = NULL, $escape = TRUE)
@@ -388,6 +420,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
*
* @param mixed
* @param mixed
+ * @param bool
* @return object
*/
public function or_where($key, $value = NULL, $escape = TRUE)
@@ -405,6 +438,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* @param mixed
* @param mixed
* @param string
+ * @param mixed
* @return object
*/
protected function _where($key, $value = NULL, $type = 'AND ', $escape = NULL)
@@ -417,15 +451,16 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
}
// If the escape value was not set will will base it on the global setting
- if ( ! is_bool($escape))
- {
- $escape = $this->_protect_identifiers;
- }
+ $escape = $this->_protect_identifiers;
foreach ($key as $k => $v)
{
$prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0) ? '' : $type;
+ $k = $this->_has_operator($k)
+ ? $this->protect_identifiers(substr($k, 0, strpos(rtrim($k), ' ')), FALSE, $escape).strchr(rtrim($k), ' ')
+ : $this->protect_identifiers($k, FALSE, $escape);
+
if (is_null($v) && ! $this->_has_operator($k))
{
// value appears not to have been set, assign the test to IS NULL
@@ -436,7 +471,6 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
{
if ($escape === TRUE)
{
- $k = $this->protect_identifiers($k, FALSE, $escape);
$v = ' '.$this->escape($v);
}
@@ -445,10 +479,6 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$k .= ' = ';
}
}
- else
- {
- $k = $this->protect_identifiers($k, FALSE, $escape);
- }
$this->qb_where[] = $prefix.$k.$v;
if ($this->qb_caching === TRUE)
@@ -547,7 +577,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
{
if ($key === NULL OR $values === NULL)
{
- return;
+ return $this;
}
$type = $this->_group_get_type($type);
@@ -853,6 +883,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
*
* @param string
* @param string
+ * @param bool
* @return object
*/
public function having($key, $value = '', $escape = TRUE)
@@ -869,6 +900,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
*
* @param string
* @param string
+ * @param bool
* @return object
*/
public function or_having($key, $value = '', $escape = TRUE)
@@ -885,6 +917,8 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
*
* @param string
* @param string
+ * @param string
+ * @param bool
* @return object
*/
protected function _having($key, $value = '', $type = 'AND ', $escape = TRUE)
@@ -943,7 +977,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
}
elseif (trim($direction) !== '')
{
- $direction = (in_array(strtoupper(trim($direction)), array('ASC', 'DESC'), TRUE)) ? ' '.$direction : ' ASC';
+ $direction = in_array(strtoupper(trim($direction)), array('ASC', 'DESC'), TRUE) ? ' '.$direction : ' ASC';
}
@@ -955,7 +989,9 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$part = trim($part);
if ( ! in_array($part, $this->qb_aliased_tables))
{
- $part = $this->protect_identifiers(trim($part));
+ $part = preg_match('/^(.+)\s+(ASC|DESC)$/i', $part, $matches)
+ ? $this->protect_identifiers(rtrim($matches[1])).' '.$matches[2]
+ : $this->protect_identifiers($part);
}
$temp[] = $part;
@@ -963,12 +999,11 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$orderby = implode(', ', $temp);
}
- elseif ($direction !== $this->_random_keyword)
+ elseif ($direction !== $this->_random_keyword && $escape === TRUE)
{
- if ($escape === TRUE)
- {
- $orderby = $this->protect_identifiers($orderby);
- }
+ $orderby = preg_match('/^(.+)\s+(ASC|DESC)$/i', $orderby, $matches)
+ ? $this->protect_identifiers(rtrim($matches[1])).' '.$matches[2]
+ : $this->protect_identifiers($orderby);
}
$this->qb_orderby[] = $orderby_statement = $orderby.$direction;
@@ -995,7 +1030,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
{
$this->qb_limit = (int) $value;
- if ( ! is_null($offset))
+ if ( ! empty($offset))
{
$this->qb_offset = (int) $offset;
}
@@ -1070,7 +1105,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$this->from($table);
}
- $select = $this->_compile_select();
+ $select = $this->_compile_select();
if ($reset === TRUE)
{
@@ -1093,7 +1128,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* @param string the offset clause
* @return object
*/
- public function get($table = '', $limit = null, $offset = null)
+ public function get($table = '', $limit = NULL, $offset = NULL)
{
if ($table !== '')
{
@@ -1101,7 +1136,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$this->from($table);
}
- if ( ! is_null($limit))
+ if ( ! empty($limit))
{
$this->limit($limit, $offset);
}
@@ -1166,7 +1201,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$this->where($where);
}
- if ( ! is_null($limit))
+ if ( ! empty($limit))
{
$this->limit($limit, $offset);
}
@@ -1275,11 +1310,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
ksort($row); // puts $row in the same order as our keys
- if ($escape === FALSE)
- {
- $this->qb_set[] = '('.implode(',', $row).')';
- }
- else
+ if ($escape !== FALSE)
{
$clean = array();
foreach ($row as $value)
@@ -1287,8 +1318,10 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$clean[] = $this->escape($value);
}
- $this->qb_set[] = '('.implode(',', $clean).')';
+ $row = $clean;
}
+
+ $this->qb_set[] = '('.implode(',', $row).')';
}
foreach ($keys as $k)
@@ -1553,7 +1586,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$this->where($where);
}
- if ($limit != NULL)
+ if ( ! empty($limit))
{
$this->limit($limit);
}
@@ -1874,7 +1907,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$this->where($where);
}
- if ($limit != NULL)
+ if ( ! empty($limit))
{
$this->limit($limit);
}
@@ -1915,7 +1948,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
return 'DELETE FROM '.$table
.(count($conditions) > 0 ? ' WHERE '.implode(' AND ', $conditions) : '')
- .($limit ? ' LIMIT '.$limit : '');
+ .($limit ? ' LIMIT '.(int) $limit : '');
}
// --------------------------------------------------------------------
@@ -1985,7 +2018,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
if (strpos($table, ' ') !== FALSE)
{
// if the alias is written with the AS keyword, remove it
- $table = preg_replace('/ AS /i', ' ', $table);
+ $table = preg_replace('/\s+AS\s+/i', ' ', $table);
// Grab the alias
$table = trim(strrchr($table, ' '));
@@ -2088,10 +2121,6 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
if (count($this->qb_orderby) > 0)
{
$sql .= "\nORDER BY ".implode(', ', $this->qb_orderby);
- if ($this->qb_order !== FALSE)
- {
- $sql .= ($this->qb_order === 'desc') ? ' DESC' : ' ASC';
- }
}
// Write the "LIMIT" portion of the query
@@ -2321,8 +2350,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
'qb_no_escape' => array(),
'qb_distinct' => FALSE,
'qb_limit' => FALSE,
- 'qb_offset' => FALSE,
- 'qb_order' => FALSE
+ 'qb_offset' => FALSE
)
);
}
@@ -2345,8 +2373,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
'qb_like' => array(),
'qb_orderby' => array(),
'qb_keys' => array(),
- 'qb_limit' => FALSE,
- 'qb_order' => FALSE
+ 'qb_limit' => FALSE
)
);
}
diff --git a/system/database/DB_utility.php b/system/database/DB_utility.php
index 02c921834..6a3b40779 100644
--- a/system/database/DB_utility.php
+++ b/system/database/DB_utility.php
@@ -35,7 +35,6 @@
abstract class CI_DB_utility extends CI_DB_forge {
public $db;
- public $data_cache = array();
// Platform specific SQL strings
// Just setting those defaults to FALSE as they are mostly MySQL-specific
@@ -60,29 +59,29 @@ abstract class CI_DB_utility extends CI_DB_forge {
public function list_databases()
{
// Is there a cached result?
- if (isset($this->data_cache['db_names']))
+ if (isset($this->db->data_cache['db_names']))
{
- return $this->data_cache['db_names'];
+ return $this->db->data_cache['db_names'];
}
elseif ($this->_list_databases === FALSE)
{
return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
}
- $this->data_cache['db_names'] = array();
+ $this->db->data_cache['db_names'] = array();
$query = $this->db->query($this->_list_databases);
if ($query === FALSE)
{
- return $this->data_cache['db_names'];
+ return $this->db->data_cache['db_names'];
}
for ($i = 0, $c = count($query); $i < $c; $i++)
{
- $this->data_cache['db_names'] = current($query[$i]);
+ $this->db->data_cache['db_names'] = current($query[$i]);
}
- return $this->data_cache['db_names'];
+ return $this->db->data_cache['db_names'];
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/cubrid/cubrid_utility.php b/system/database/drivers/cubrid/cubrid_utility.php
index c8cee99b6..ea8feb4e2 100644
--- a/system/database/drivers/cubrid/cubrid_utility.php
+++ b/system/database/drivers/cubrid/cubrid_utility.php
@@ -41,12 +41,12 @@ class CI_DB_cubrid_utility extends CI_DB_utility {
*/
public function list_databases()
{
- if (isset($this->data_cache['db_names']))
+ if (isset($this->db->data_cache['db_names']))
{
- return $this->data_cache['db_names'];
+ return $this->db->data_cache['db_names'];
}
- return $this->data_cache['db_names'] = cubrid_list_dbs($this->db->conn_id);
+ return $this->db->data_cache['db_names'] = cubrid_list_dbs($this->db->conn_id);
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/interbase/interbase_forge.php b/system/database/drivers/interbase/interbase_forge.php
index 3f9967f1f..d1b006e80 100644
--- a/system/database/drivers/interbase/interbase_forge.php
+++ b/system/database/drivers/interbase/interbase_forge.php
@@ -67,6 +67,14 @@ class CI_DB_interbase_forge extends CI_DB_forge {
{
return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE;
}
+ elseif ( ! empty($this->db->data_cache['db_names']))
+ {
+ $key = array_search(strtolower($this->db->database), array_map('strtolower', $this->db->data_cache['db_names']), TRUE);
+ if ($key !== FALSE)
+ {
+ unset($this->db->data_cache['db_names'][$key]);
+ }
+ }
return TRUE;
}
diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php
index 87094e76e..47dc55844 100644
--- a/system/database/drivers/mssql/mssql_driver.php
+++ b/system/database/drivers/mssql/mssql_driver.php
@@ -504,7 +504,30 @@ class CI_DB_mssql_driver extends CI_DB {
*/
protected function _limit($sql, $limit, $offset)
{
- return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.($limit + $offset).' ', $sql);
+ // As of SQL Server 2012 (11.0.*) OFFSET is supported
+ if (version_compare($this->version(), '11', '>='))
+ {
+ return $sql.' OFFSET '.(int) $offset.' ROWS FETCH NEXT '.(int) $limit.' ROWS ONLY';
+ }
+
+ $limit = $offset + $limit;
+
+ // As of SQL Server 2005 (9.0.*) ROW_NUMBER() is supported,
+ // however an ORDER BY clause is required for it to work
+ if (version_compare($this->version(), '9', '>=') && $offset && ! empty($this->qb_orderby))
+ {
+ $orderby = 'ORDER BY '.implode(', ', $this->qb_orderby);
+
+ // We have to strip the ORDER BY clause
+ $sql = trim(substr($sql, 0, strrpos($sql, 'ORDER BY '.$orderby)));
+
+ return 'SELECT '.(count($this->qb_select) === 0 ? '*' : implode(', ', $this->qb_select))." FROM (\n"
+ .preg_replace('/^(SELECT( DISTINCT)?)/i', '\\1 ROW_NUMBER() OVER('.$orderby.') AS '.$this->escape_identifiers('CI_rownum').', ', $sql)
+ ."\n) ".$this->escape_identifiers('CI_subquery')
+ ."\nWHERE ".$this->escape_identifiers('CI_rownum').' BETWEEN '.((int) $offset + 1).' AND '.$limit;
+ }
+
+ return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$limit.' ', $sql);
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/mysqli/mysqli_utility.php b/system/database/drivers/mysqli/mysqli_utility.php
index 27d4ef817..5d2bdbce0 100644
--- a/system/database/drivers/mysqli/mysqli_utility.php
+++ b/system/database/drivers/mysqli/mysqli_utility.php
@@ -46,9 +46,124 @@ class CI_DB_mysqli_utility extends CI_DB_utility {
*/
protected function _backup($params = array())
{
- // Currently unsupported
- return $this->db->display_error('db_unsuported_feature');
+ if (count($params) === 0)
+ {
+ return FALSE;
+ }
+
+ // Extract the prefs for simplicity
+ extract($params);
+
+ // Build the output
+ $output = '';
+ foreach ( (array) $tables as $table)
+ {
+ // Is the table in the "ignore" list?
+ if (in_array($table, (array) $ignore, TRUE))
+ {
+ continue;
+ }
+
+ // Get the table schema
+ $query = $this->db->query('SHOW CREATE TABLE '.$this->db->escape_identifiers($this->db->database.'.'.$table));
+
+ // No result means the table name was invalid
+ if ($query === FALSE)
+ {
+ continue;
+ }
+
+ // Write out the table schema
+ $output .= '#'.$newline.'# TABLE STRUCTURE FOR: '.$table.$newline.'#'.$newline.$newline;
+
+ if ($add_drop === TRUE)
+ {
+ $output .= 'DROP TABLE IF EXISTS '.$this->db->protect_identifiers($table).';'.$newline.$newline;
+ }
+
+ $i = 0;
+ $result = $query->result_array();
+ foreach ($result[0] as $val)
+ {
+ if ($i++ % 2)
+ {
+ $output .= $val.';'.$newline.$newline;
+ }
+ }
+
+ // If inserts are not needed we're done...
+ if ($add_insert === FALSE)
+ {
+ continue;
+ }
+
+ // Grab all the data from the current table
+ $query = $this->db->query('SELECT * FROM '.$this->db->protect_identifiers($table));
+
+ if ($query->num_rows() === 0)
+ {
+ continue;
+ }
+
+ // Fetch the field names and determine if the field is an
+ // integer type. We use this info to decide whether to
+ // surround the data with quotes or not
+
+ $i = 0;
+ $field_str = '';
+ $is_int = array();
+ while ($field = $query->result_id->fetch_field())
+ {
+ // Most versions of MySQL store timestamp as a string
+ $is_int[$i] = in_array(strtolower($field->type),
+ array('tinyint', 'smallint', 'mediumint', 'int', 'bigint'), //, 'timestamp'),
+ TRUE);
+
+ // Create a string of field names
+ $field_str .= $this->db->escape_identifiers($field->name).', ';
+ $i++;
+ }
+
+ // Trim off the end comma
+ $field_str = preg_replace('/, $/' , '', $field_str);
+
+ // Build the insert string
+ foreach ($query->result_array() as $row)
+ {
+ $val_str = '';
+
+ $i = 0;
+ foreach ($row as $v)
+ {
+ // Is the value NULL?
+ if ($v === NULL)
+ {
+ $val_str .= 'NULL';
+ }
+ else
+ {
+ // Escape the data if it's not an integer
+ $val_str .= ($is_int[$i] === FALSE) ? $this->db->escape($v) : $v;
+ }
+
+ // Append a comma
+ $val_str .= ', ';
+ $i++;
+ }
+
+ // Remove the comma at the end of the string
+ $val_str = preg_replace('/, $/' , '', $val_str);
+
+ // Build the INSERT string
+ $output .= 'INSERT INTO '.$this->db->protect_identifiers($table).' ('.$field_str.') VALUES ('.$val_str.');'.$newline;
+ }
+
+ $output .= $newline.$newline;
+ }
+
+ return $output;
}
+
}
/* End of file mysqli_utility.php */
diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php
index 7375fbf71..ad9ac9000 100644
--- a/system/database/drivers/postgre/postgre_driver.php
+++ b/system/database/drivers/postgre/postgre_driver.php
@@ -615,6 +615,10 @@ class CI_DB_postgre_driver extends CI_DB {
{
$prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0) ? '' : $type;
+ $k = $this->_has_operator($k)
+ ? $this->protect_identifiers(substr($k, 0, strpos(rtrim($k), ' ')), FALSE, $escape).strchr(rtrim($k), ' ')
+ : $this->protect_identifiers($k, FALSE, $escape);
+
if (is_null($v) && ! $this->_has_operator($k))
{
// value appears not to have been set, assign the test to IS NULL
@@ -625,7 +629,6 @@ class CI_DB_postgre_driver extends CI_DB {
{
if ($escape === TRUE)
{
- $k = $this->protect_identifiers($k, FALSE, $escape);
$v = ' '.$this->escape($v);
}
elseif (is_bool($v))
@@ -638,10 +641,6 @@ class CI_DB_postgre_driver extends CI_DB {
$k .= ' = ';
}
}
- else
- {
- $k = $this->protect_identifiers($k, FALSE, $escape);
- }
$this->qb_where[] = $prefix.$k.$v;
if ($this->qb_caching === TRUE)
diff --git a/system/database/drivers/sqlite/sqlite_forge.php b/system/database/drivers/sqlite/sqlite_forge.php
index 71eed7df4..e02e327f3 100644
--- a/system/database/drivers/sqlite/sqlite_forge.php
+++ b/system/database/drivers/sqlite/sqlite_forge.php
@@ -61,6 +61,14 @@ class CI_DB_sqlite_forge extends CI_DB_forge {
{
return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE;
}
+ elseif ( ! empty($this->db->data_cache['db_names']))
+ {
+ $key = array_search(strtolower($this->db->database), array_map('strtolower', $this->db->data_cache['db_names']), TRUE);
+ if ($key !== FALSE)
+ {
+ unset($this->db->data_cache['db_names'][$key]);
+ }
+ }
return TRUE;
}
diff --git a/system/database/drivers/sqlite3/sqlite3_forge.php b/system/database/drivers/sqlite3/sqlite3_forge.php
index f8bd11656..6a76ba929 100644
--- a/system/database/drivers/sqlite3/sqlite3_forge.php
+++ b/system/database/drivers/sqlite3/sqlite3_forge.php
@@ -66,6 +66,14 @@ class CI_DB_sqlite3_forge extends CI_DB_forge {
{
return $this->db->db_debug ? $this->db->display_error('db_unable_to_drop') : FALSE;
}
+ elseif ( ! empty($this->db->data_cache['db_names']))
+ {
+ $key = array_search(strtolower($this->db->database), array_map('strtolower', $this->db->data_cache['db_names']), TRUE);
+ if ($key !== FALSE)
+ {
+ unset($this->db->data_cache['db_names'][$key]);
+ }
+ }
return TRUE;
}
diff --git a/system/database/drivers/sqlsrv/sqlsrv_driver.php b/system/database/drivers/sqlsrv/sqlsrv_driver.php
index 655a9e90b..825c02452 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_driver.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_driver.php
@@ -21,7 +21,7 @@
* @copyright Copyright (c) 2008 - 2012, 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
+ * @since Version 2.0.3
* @filesource
*/
@@ -463,9 +463,28 @@ class CI_DB_sqlsrv_driver extends CI_DB {
protected function _limit($sql, $limit, $offset)
{
// As of SQL Server 2012 (11.0.*) OFFSET is supported
- return version_compare($this->version(), '11', '>=')
- ? $sql.' OFFSET '.(int) $offset.' ROWS FETCH NEXT '.(int) $limit.' ROWS ONLY'
- : preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.($limit + $offset).' ', $sql);
+ if (version_compare($this->version(), '11', '>='))
+ {
+ return $sql.' OFFSET '.(int) $offset.' ROWS FETCH NEXT '.(int) $limit.' ROWS ONLY';
+ }
+
+ $limit = $offset + $limit;
+
+ // An ORDER BY clause is required for ROW_NUMBER() to work
+ if ($offset && ! empty($this->qb_orderby))
+ {
+ $orderby = 'ORDER BY '.implode(', ', $this->qb_orderby);
+
+ // We have to strip the ORDER BY clause
+ $sql = trim(substr($sql, 0, strrpos($sql, 'ORDER BY '.$orderby)));
+
+ return 'SELECT '.(count($this->qb_select) === 0 ? '*' : implode(', ', $this->qb_select))." FROM (\n"
+ .preg_replace('/^(SELECT( DISTINCT)?)/i', '\\1 ROW_NUMBER() OVER('.$orderby.') AS '.$this->escape_identifiers('CI_rownum').', ', $sql)
+ ."\n) ".$this->escape_identifiers('CI_subquery')
+ ."\nWHERE ".$this->escape_identifiers('CI_rownum').' BETWEEN '.((int) $offset + 1).' AND '.$limit;
+ }
+
+ return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$limit.' ', $sql);
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/sqlsrv/sqlsrv_forge.php b/system/database/drivers/sqlsrv/sqlsrv_forge.php
index e6f7e1ac1..ccdb36929 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_forge.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_forge.php
@@ -21,7 +21,7 @@
* @copyright Copyright (c) 2008 - 2012, 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
+ * @since Version 2.0.3
* @filesource
*/
diff --git a/system/database/drivers/sqlsrv/sqlsrv_result.php b/system/database/drivers/sqlsrv/sqlsrv_result.php
index f802383d2..f9d5a0d29 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_result.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_result.php
@@ -21,7 +21,7 @@
* @copyright Copyright (c) 2008 - 2012, 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
+ * @since Version 2.0.3
* @filesource
*/
diff --git a/system/database/drivers/sqlsrv/sqlsrv_utility.php b/system/database/drivers/sqlsrv/sqlsrv_utility.php
index 5a71b1628..d518cc15a 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_utility.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_utility.php
@@ -21,7 +21,7 @@
* @copyright Copyright (c) 2008 - 2012, 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
+ * @since Version 2.0.3
* @filesource
*/
diff --git a/system/libraries/Cache/Cache.php b/system/libraries/Cache/Cache.php
index 53f9f81a7..4395cf411 100644
--- a/system/libraries/Cache/Cache.php
+++ b/system/libraries/Cache/Cache.php
@@ -41,11 +41,12 @@ class CI_Cache extends CI_Driver_Library {
*
* @var array
*/
- protected $valid_drivers = array(
+ protected $valid_drivers = array(
'cache_apc',
+ 'cache_dummy',
'cache_file',
'cache_memcached',
- 'cache_dummy',
+ 'cache_redis',
'cache_wincache'
);
diff --git a/system/libraries/Cache/drivers/Cache_file.php b/system/libraries/Cache/drivers/Cache_file.php
index 5170de821..08231963e 100644
--- a/system/libraries/Cache/drivers/Cache_file.php
+++ b/system/libraries/Cache/drivers/Cache_file.php
@@ -26,7 +26,7 @@
*/
/**
- * CodeIgniter Memcached Caching Class
+ * CodeIgniter File Caching Class
*
* @package CodeIgniter
* @subpackage Libraries
@@ -171,13 +171,13 @@ class CI_Cache_file extends CI_Driver {
{
$mtime = filemtime($this->_cache_path.$id);
- if ( ! isset($data['data']['ttl']))
+ if ( ! isset($data['ttl']))
{
return FALSE;
}
return array(
- 'expire' => $mtime + $data['data']['ttl'],
+ 'expire' => $mtime + $data['ttl'],
'mtime' => $mtime
);
}
diff --git a/system/libraries/Cache/drivers/Cache_redis.php b/system/libraries/Cache/drivers/Cache_redis.php
new file mode 100644
index 000000000..e4a26b5f0
--- /dev/null
+++ b/system/libraries/Cache/drivers/Cache_redis.php
@@ -0,0 +1,236 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * 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) 2006 - 2012 EllisLab, Inc.
+ * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
+ * @link http://codeigniter.com
+ * @since Version 3.0
+ * @filesource
+ */
+
+/**
+ * CodeIgniter Redis Caching Class
+ *
+ * @package CodeIgniter
+ * @subpackage Libraries
+ * @category Core
+ * @author Anton Lindqvist <anton@qvister.se>
+ * @link
+ */
+class CI_Cache_redis extends CI_Driver
+{
+ /**
+ * Default config
+ *
+ * @static
+ * @var array
+ */
+ protected static $_default_config = array(
+ 'host' => '127.0.0.1',
+ 'password' => NULL,
+ 'port' => 6379,
+ 'timeout' => 0
+ );
+
+ /**
+ * Redis connection
+ *
+ * @var Redis
+ */
+ protected $_redis;
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get cache
+ *
+ * @param string Cache key identifier
+ * @return mixed
+ */
+ public function get($key)
+ {
+ return $this->_redis->get($key);
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Save cache
+ *
+ * @param string Cache key identifier
+ * @param mixed Data to save
+ * @param int Time to live
+ * @return bool
+ */
+ public function save($key, $value, $ttl = NULL)
+ {
+ return ($ttl)
+ ? $this->_redis->setex($key, $ttl, $value)
+ : $this->_redis->set($key, $value);
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Delete from cache
+ *
+ * @param string Cache key
+ * @return bool
+ */
+ public function delete($key)
+ {
+ return ($this->_redis->delete($key) === 1);
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Clean cache
+ *
+ * @return bool
+ * @see Redis::flushDB()
+ */
+ public function clean()
+ {
+ return $this->_redis->flushDB();
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get cache driver info
+ *
+ * @param string Not supported in Redis.
+ * Only included in order to offer a
+ * consistent cache API.
+ * @return array
+ * @see Redis::info()
+ */
+ public function cache_info($type = NULL)
+ {
+ return $this->_redis->info();
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get cache metadata
+ *
+ * @param string Cache key
+ * @return array
+ */
+ public function get_metadata($key)
+ {
+ $value = $this->get($key);
+
+ if ($value)
+ {
+ return array(
+ 'expire' => time() + $this->_redis->ttl($key),
+ 'data' => $value
+ );
+ }
+
+ return FALSE;
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Check if Redis driver is supported
+ *
+ * @return bool
+ */
+ public function is_supported()
+ {
+ if (extension_loaded('redis'))
+ {
+ $this->_setup_redis();
+ return TRUE;
+ }
+ else
+ {
+ log_message('error', 'The Redis extension must be loaded to use Redis cache.');
+ return FALSE;
+ }
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * 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
+ {
+ $this->_redis->connect($config['host'], $config['port'], $config['timeout']);
+ }
+ catch (RedisException $e)
+ {
+ show_error('Redis connection refused. ' . $e->getMessage());
+ }
+
+ if (isset($config['password']))
+ {
+ $this->_redis->auth($config['password']);
+ }
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+
+ * Class destructor
+ *
+ * Closes the connection to Redis if present.
+ *
+ * @return void
+ */
+ public function __destruct()
+ {
+ if ($this->_redis)
+ {
+ $this->_redis->close();
+ }
+ }
+
+}
+
+/* End of file Cache_redis.php */
+/* Location: ./system/libraries/Cache/drivers/Cache_redis.php */ \ No newline at end of file
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index c70144f7c..09f217530 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -1599,7 +1599,7 @@ class CI_Email {
$this->_debug_msg[] = '<pre>'.$cmd.': '.$reply.'</pre>';
- if (substr($reply, 0, 3) !== $resp)
+ if ( (int) substr($reply, 0, 3) !== $resp)
{
$this->_set_error_message('lang:email_smtp_error', $reply);
return FALSE;
diff --git a/system/libraries/Encrypt.php b/system/libraries/Encrypt.php
index ce5e030b0..8ffd93aea 100644
--- a/system/libraries/Encrypt.php
+++ b/system/libraries/Encrypt.php
@@ -213,6 +213,7 @@ class CI_Encrypt {
$dec = base64_decode($string);
if (($dec = $this->mcrypt_decode($dec, $key)) === FALSE)
{
+ $this->set_mode($current_mode);
return FALSE;
}
diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php
index 225325d6f..6cbe032c7 100644
--- a/system/libraries/Form_validation.php
+++ b/system/libraries/Form_validation.php
@@ -187,6 +187,12 @@ class CI_Form_validation {
return $this;
}
+ // Convert an array of rules to a string
+ if (is_array($rules))
+ {
+ $rules = implode('|', $rules);
+ }
+
// No fields? Nothing to do...
if ( ! is_string($field) OR ! is_string($rules) OR $field === '')
{
@@ -1089,11 +1095,12 @@ class CI_Form_validation {
* Validate IP Address
*
* @param string
+ * @param string 'ipv4' or 'ipv6' to validate a specific IP format
* @return bool
*/
- public function valid_ip($ip)
+ public function valid_ip($ip, $which = '')
{
- return $this->CI->input->valid_ip($ip);
+ return $this->CI->input->valid_ip($ip, $which);
}
// --------------------------------------------------------------------
diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php
index a91159c98..cdec736ff 100644
--- a/system/libraries/Pagination.php
+++ b/system/libraries/Pagination.php
@@ -36,38 +36,39 @@
*/
class CI_Pagination {
- protected $base_url = ''; // The page we are linking to
- protected $prefix = ''; // A custom prefix added to the path.
- protected $suffix = ''; // A custom suffix added to the path.
- protected $total_rows = 0; // Total number of items (database results)
- protected $per_page = 10; // Max number of items you want shown per page
- protected $num_links = 2; // Number of "digit" links to show before/after the currently viewed page
- protected $cur_page = 0; // The current page being viewed
- protected $use_page_numbers = FALSE; // Use page number for segment instead of offset
- protected $first_link = '&lsaquo; First';
- protected $next_link = '&gt;';
- protected $prev_link = '&lt;';
- protected $last_link = 'Last &rsaquo;';
- protected $uri_segment = 3;
- protected $full_tag_open = '';
- protected $full_tag_close = '';
- protected $first_tag_open = '';
- protected $first_tag_close = '&nbsp;';
- protected $last_tag_open = '&nbsp;';
- protected $last_tag_close = '';
- protected $first_url = ''; // Alternative URL for the First Page.
- protected $cur_tag_open = '&nbsp;<strong>';
- protected $cur_tag_close = '</strong>';
- protected $next_tag_open = '&nbsp;';
- protected $next_tag_close = '&nbsp;';
- protected $prev_tag_open = '&nbsp;';
- protected $prev_tag_close = '';
- protected $num_tag_open = '&nbsp;';
- protected $num_tag_close = '';
- protected $page_query_string = FALSE;
- protected $query_string_segment = 'per_page';
- protected $display_pages = TRUE;
- protected $anchor_class = '';
+ public $base_url = ''; // The page we are linking to
+ public $prefix = ''; // A custom prefix added to the path.
+ public $suffix = ''; // A custom suffix added to the path.
+ public $total_rows = 0; // Total number of items (database results)
+ public $per_page = 10; // Max number of items you want shown per page
+ public $num_links = 2; // Number of "digit" links to show before/after the currently viewed page
+ public $cur_page = 0; // The current page being viewed
+ public $use_page_numbers = FALSE; // Use page number for segment instead of offset
+ public $first_link = '&lsaquo; First';
+ public $next_link = '&gt;';
+ public $prev_link = '&lt;';
+ public $last_link = 'Last &rsaquo;';
+ public $uri_segment = 3;
+ public $full_tag_open = '';
+ public $full_tag_close = '';
+ public $first_tag_open = '';
+ public $first_tag_close = '&nbsp;';
+ public $last_tag_open = '&nbsp;';
+ public $last_tag_close = '';
+ public $first_url = ''; // Alternative URL for the First Page.
+ public $cur_tag_open = '&nbsp;<strong>';
+ public $cur_tag_close = '</strong>';
+ public $next_tag_open = '&nbsp;';
+ public $next_tag_close = '&nbsp;';
+ public $prev_tag_open = '&nbsp;';
+ public $prev_tag_close = '';
+ public $num_tag_open = '&nbsp;';
+ public $num_tag_close = '';
+ public $page_query_string = FALSE;
+ public $query_string_segment = 'per_page';
+ public $display_pages = TRUE;
+ public $anchor_class = '';
+ public $attr_rel = TRUE;
/**
* Constructor
@@ -97,7 +98,7 @@ class CI_Pagination {
{
if ($key === 'anchor_class')
{
- $this->anchor_class = ($val !== '') ? 'class="'.$val.'" ' : '';
+ $this->anchor_class = ($val) ? 'class="'.$val.'" ' : '';
}
elseif (isset($this->$key))
{
@@ -145,7 +146,7 @@ class CI_Pagination {
if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE)
{
- if ($CI->input->get($this->query_string_segment) !== $base_page)
+ if ($CI->input->get($this->query_string_segment) != $base_page)
{
$this->cur_page = (int) $CI->input->get($this->query_string_segment);
}
@@ -212,7 +213,8 @@ class CI_Pagination {
if ($this->first_link !== FALSE && $this->cur_page > ($this->num_links + 1))
{
$first_url = ($this->first_url === '') ? $this->base_url : $this->first_url;
- $output .= $this->first_tag_open.'<a '.$this->anchor_class.'href="'.$first_url.'">'.$this->first_link.'</a>'.$this->first_tag_close;
+ $output .= $this->first_tag_open.'<a '.$this->anchor_class.'href="'.$first_url.'"'.$this->_attr_rel('start').'>'
+ .$this->first_link.'</a>'.$this->first_tag_close;
}
// Render the "previous" link
@@ -222,12 +224,14 @@ class CI_Pagination {
if ($i === $base_page && $this->first_url !== '')
{
- $output .= $this->prev_tag_open.'<a '.$this->anchor_class.'href="'.$this->first_url.'">'.$this->prev_link.'</a>'.$this->prev_tag_close;
+ $output .= $this->prev_tag_open.'<a '.$this->anchor_class.'href="'.$this->first_url.'"'.$this->_attr_rel('prev').'>'
+ .$this->prev_link.'</a>'.$this->prev_tag_close;
}
else
{
$i = ($i === $base_page) ? '' : $this->prefix.$i.$this->suffix;
- $output .= $this->prev_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$i.'">'.$this->prev_link.'</a>'.$this->prev_tag_close;
+ $output .= $this->prev_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$i.'"'.$this->_attr_rel('prev').'>'
+ .$this->prev_link.'</a>'.$this->prev_tag_close;
}
}
@@ -252,13 +256,15 @@ class CI_Pagination {
if ($n === '' && $this->first_url !== '')
{
- $output .= $this->num_tag_open.'<a '.$this->anchor_class.'href="'.$this->first_url.'">'.$loop.'</a>'.$this->num_tag_close;
+ $output .= $this->num_tag_open.'<a '.$this->anchor_class.'href="'.$this->first_url.'"'.$this->_attr_rel('start').'>'
+ .$loop.'</a>'.$this->num_tag_close;
}
else
{
$n = ($n === '') ? '' : $this->prefix.$n.$this->suffix;
- $output .= $this->num_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$n.'">'.$loop.'</a>'.$this->num_tag_close;
+ $output .= $this->num_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$n.'"'.$this->_attr_rel().'>'
+ .$loop.'</a>'.$this->num_tag_close;
}
}
}
@@ -270,7 +276,8 @@ class CI_Pagination {
{
$i = ($this->use_page_numbers) ? $this->cur_page + 1 : $this->cur_page * $this->per_page;
- $output .= $this->next_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$this->prefix.$i.$this->suffix.'">'.$this->next_link.'</a>'.$this->next_tag_close;
+ $output .= $this->next_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$this->prefix.$i.$this->suffix.'"'.$this->_attr_rel('next').'>'
+ .$this->next_link.'</a>'.$this->next_tag_close;
}
// Render the "Last" link
@@ -278,7 +285,8 @@ class CI_Pagination {
{
$i = ($this->use_page_numbers) ? $num_pages : ($num_pages * $this->per_page) - $this->per_page;
- $output .= $this->last_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$this->prefix.$i.$this->suffix.'">'.$this->last_link.'</a>'.$this->last_tag_close;
+ $output .= $this->last_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$this->prefix.$i.$this->suffix.'"'.$this->_attr_rel().'>'
+ .$this->last_link.'</a>'.$this->last_tag_close;
}
// Kill double slashes. Note: Sometimes we can end up with a double slash
@@ -289,6 +297,28 @@ class CI_Pagination {
return $this->full_tag_open.$output.$this->full_tag_close;
}
+ // --------------------------------------------------------------------
+
+ /**
+ * Add "rel" attribute
+ *
+ * @param string
+ * @return string
+ */
+ protected function _attr_rel($value = '')
+ {
+ if (empty($this->attr_rel) OR ($this->attr_rel === TRUE && empty($value)))
+ {
+ return '';
+ }
+ elseif ( ! is_bool($this->attr_rel))
+ {
+ $value = $this->attr_rel;
+ }
+
+ return ' rel="'.$value.'"';
+ }
+
}
/* End of file Pagination.php */
diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php
index 1f6aeeb6b..c96daaf15 100644
--- a/system/libraries/Upload.php
+++ b/system/libraries/Upload.php
@@ -347,11 +347,12 @@ class CI_Upload {
* Returns an associative array containing all of the information
* related to the upload, allowing the developer easy access in one array.
*
- * @return array
+ * @param string
+ * @return mixed
*/
- public function data()
+ public function data($index = NULL)
{
- return array(
+ $data = array(
'file_name' => $this->file_name,
'file_type' => $this->file_type,
'file_path' => $this->upload_path,
@@ -367,6 +368,13 @@ class CI_Upload {
'image_type' => $this->image_type,
'image_size_str' => $this->image_size_str,
);
+
+ if ( ! empty($index))
+ {
+ return isset($data[$index]) ? $data[$index] : NULL;
+ }
+
+ return $data;
}
// --------------------------------------------------------------------