summaryrefslogtreecommitdiffstats
path: root/system
diff options
context:
space:
mode:
Diffstat (limited to 'system')
-rwxr-xr-xsystem/core/CodeIgniter.php22
-rw-r--r--system/core/Common.php30
-rwxr-xr-xsystem/core/Input.php50
-rwxr-xr-xsystem/core/Lang.php4
-rwxr-xr-xsystem/core/Loader.php4
-rwxr-xr-xsystem/core/Security.php83
-rwxr-xr-xsystem/core/URI.php4
-rw-r--r--system/database/DB_active_rec.php8
-rw-r--r--system/database/DB_cache.php2
-rw-r--r--system/database/DB_driver.php28
-rw-r--r--system/database/DB_forge.php2
-rw-r--r--system/database/DB_utility.php2
-rw-r--r--system/database/drivers/mysql/mysql_driver.php21
-rw-r--r--system/database/drivers/mysql/mysql_result.php17
-rw-r--r--system/database/drivers/mysqli/mysqli_driver.php23
-rw-r--r--system/database/drivers/mysqli/mysqli_result.php19
-rw-r--r--system/database/drivers/oci8/oci8_driver.php37
-rw-r--r--system/database/drivers/oci8/oci8_result.php17
-rw-r--r--system/database/drivers/odbc/odbc_driver.php4
-rw-r--r--system/database/drivers/pdo/index.html10
-rw-r--r--system/database/drivers/pdo/pdo_driver.php792
-rw-r--r--system/database/drivers/pdo/pdo_forge.php266
-rw-r--r--system/database/drivers/pdo/pdo_result.php171
-rw-r--r--system/database/drivers/pdo/pdo_utility.php103
-rw-r--r--system/helpers/date_helper.php230
-rw-r--r--system/helpers/form_helper.php7
-rw-r--r--system/helpers/html_helper.php2
-rw-r--r--system/helpers/string_helper.php9
-rw-r--r--system/helpers/typography_helper.php5
-rwxr-xr-x[-rw-r--r--]system/helpers/url_helper.php4
-rw-r--r--system/language/english/migration_lang.php2
-rw-r--r--system/libraries/Cache/drivers/Cache_file.php11
-rw-r--r--system/libraries/Cache/drivers/Cache_memcached.php92
-rw-r--r--system/libraries/Email.php37
-rw-r--r--system/libraries/Form_validation.php2
-rw-r--r--system/libraries/Image_lib.php2
-rw-r--r--system/libraries/Log.php21
-rw-r--r--system/libraries/Migration.php31
-rw-r--r--system/libraries/Pagination.php53
-rw-r--r--system/libraries/Profiler.php6
-rw-r--r--system/libraries/Session.php3
-rw-r--r--system/libraries/Sha1.php4
-rw-r--r--system/libraries/Table.php4
-rw-r--r--system/libraries/Typography.php4
-rw-r--r--system/libraries/Unit_test.php4
-rw-r--r--system/libraries/Upload.php120
-rw-r--r--system/libraries/User_agent.php4
47 files changed, 2006 insertions, 370 deletions
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php
index 0a1391d18..9f88384b1 100755
--- a/system/core/CodeIgniter.php
+++ b/system/core/CodeIgniter.php
@@ -33,27 +33,7 @@
* @var string
*
*/
- /**
- * CodeIgniter Version
- *
- * @var string
- *
- */
- define('CI_VERSION', '2.0.2');
-
-/**
- * CodeIgniter Branch (Core = TRUE, Reactor = FALSE)
- *
- * @var boolean
- *
- */
- /**
- * CodeIgniter Branch (Core = TRUE, Reactor = FALSE)
- *
- * @var string
- *
- */
- define('CI_CORE', FALSE);
+ define('CI_VERSION', '2.1.0-dev');
/*
* ------------------------------------------------------
diff --git a/system/core/Common.php b/system/core/Common.php
index db9fbeb9f..d79375475 100644
--- a/system/core/Common.php
+++ b/system/core/Common.php
@@ -132,9 +132,9 @@ if ( ! function_exists('load_class'))
$name = FALSE;
- // Look for the class first in the native system/libraries folder
- // thenin the local application/libraries folder
- foreach (array(BASEPATH, APPPATH) as $path)
+ // Look for the class first in the local application/libraries folder
+ // then in the native system/libraries folder
+ foreach (array(APPPATH, BASEPATH) as $path)
{
if (file_exists($path.$directory.'/'.$class.'.php'))
{
@@ -536,5 +536,29 @@ if ( ! function_exists('remove_invisible_characters'))
}
}
+// ------------------------------------------------------------------------
+
+/**
+* Returns HTML escaped variable
+*
+* @access public
+* @param mixed
+* @return mixed
+*/
+if ( ! function_exists('html_escape'))
+{
+ function html_escape($var)
+ {
+ if (is_array($var))
+ {
+ return array_map('html_escape', $var);
+ }
+ else
+ {
+ return htmlspecialchars($var, ENT_QUOTES, config_item('charset'));
+ }
+ }
+}
+
/* End of file Common.php */
/* Location: ./system/core/Common.php */ \ No newline at end of file
diff --git a/system/core/Input.php b/system/core/Input.php
index 5a033e7b8..6f8442107 100755
--- a/system/core/Input.php
+++ b/system/core/Input.php
@@ -110,13 +110,13 @@ class CI_Input {
*
* This is a helper function to retrieve values from global arrays
*
- * @access private
+ * @access protected
* @param array
* @param string
* @param bool
* @return string
*/
- function _fetch_from_array(&$array, $index = '', $xss_clean = FALSE)
+ protected function _fetch_from_array(&$array, $index = '', $xss_clean = FALSE)
{
if ( ! isset($array[$index]))
{
@@ -141,7 +141,7 @@ class CI_Input {
* @param bool
* @return string
*/
- function get($index = NULL, $xss_clean = FALSE)
+ public function get($index = NULL, $xss_clean = FALSE)
{
// Check if a field has been provided
if ($index === NULL AND ! empty($_GET))
@@ -169,7 +169,7 @@ class CI_Input {
* @param bool
* @return string
*/
- function post($index = NULL, $xss_clean = FALSE)
+ public function post($index = NULL, $xss_clean = FALSE)
{
// Check if a field has been provided
if ($index === NULL AND ! empty($_POST))
@@ -198,7 +198,7 @@ class CI_Input {
* @param bool XSS cleaning
* @return string
*/
- function get_post($index = '', $xss_clean = FALSE)
+ public function get_post($index = '', $xss_clean = FALSE)
{
if ( ! isset($_POST[$index]) )
{
@@ -220,7 +220,7 @@ class CI_Input {
* @param bool
* @return string
*/
- function cookie($index = '', $xss_clean = FALSE)
+ public function cookie($index = '', $xss_clean = FALSE)
{
return $this->_fetch_from_array($_COOKIE, $index, $xss_clean);
}
@@ -243,7 +243,7 @@ class CI_Input {
* @param bool true makes the cookie secure
* @return void
*/
- function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE)
+ public function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE)
{
if (is_array($name))
{
@@ -296,7 +296,7 @@ class CI_Input {
* @param bool
* @return string
*/
- function server($index = '', $xss_clean = FALSE)
+ public function server($index = '', $xss_clean = FALSE)
{
return $this->_fetch_from_array($_SERVER, $index, $xss_clean);
}
@@ -309,7 +309,7 @@ class CI_Input {
* @access public
* @return string
*/
- function ip_address()
+ public function ip_address()
{
if ($this->ip_address !== FALSE)
{
@@ -323,13 +323,13 @@ class CI_Input {
$this->ip_address = in_array($_SERVER['REMOTE_ADDR'], $proxies) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
}
- elseif ($this->server('REMOTE_ADDR') AND $this->server('HTTP_CLIENT_IP'))
+ elseif (! $this->server('HTTP_CLIENT_IP') AND $this->server('REMOTE_ADDR'))
{
- $this->ip_address = $_SERVER['HTTP_CLIENT_IP'];
+ $this->ip_address = $_SERVER['REMOTE_ADDR'];
}
- elseif ($this->server('REMOTE_ADDR'))
+ elseif ($this->server('REMOTE_ADDR') AND $this->server('HTTP_CLIENT_IP'))
{
- $this->ip_address = $_SERVER['REMOTE_ADDR'];
+ $this->ip_address = $_SERVER['HTTP_CLIENT_IP'];
}
elseif ($this->server('HTTP_CLIENT_IP'))
{
@@ -369,10 +369,16 @@ class CI_Input {
*
* @access public
* @param string
- * @return string
+ * @return bool
*/
- function valid_ip($ip)
+ public function valid_ip($ip)
{
+ // if php version >= 5.2, use filter_var to check validate ip.
+ if (function_exists('filter_var'))
+ {
+ return (bool) filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
+ }
+
$ip_segments = explode('.', $ip);
// Always 4 segments needed
@@ -407,7 +413,7 @@ class CI_Input {
* @access public
* @return string
*/
- function user_agent()
+ public function user_agent()
{
if ($this->user_agent !== FALSE)
{
@@ -435,7 +441,7 @@ class CI_Input {
* @access private
* @return void
*/
- function _sanitize_globals()
+ private function _sanitize_globals()
{
// It would be "wrong" to unset any of these GLOBALS.
$protected = array('_SERVER', '_GET', '_POST', '_FILES', '_REQUEST',
@@ -536,7 +542,7 @@ class CI_Input {
* @param string
* @return string
*/
- function _clean_input_data($str)
+ private function _clean_input_data($str)
{
if (is_array($str))
{
@@ -549,7 +555,7 @@ class CI_Input {
}
// We strip slashes if magic quotes is on to keep things consistent
- if (function_exists('get_magic_quotes_gpc') AND get_magic_quotes_gpc())
+ if (function_exists('get_magic_quotes_gpc') AND @get_magic_quotes_gpc())
{
$str = stripslashes($str);
}
@@ -594,7 +600,7 @@ class CI_Input {
* @param string
* @return string
*/
- function _clean_input_keys($str)
+ private function _clean_input_keys($str)
{
if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str))
{
@@ -618,6 +624,7 @@ class CI_Input {
* In Apache, you can simply call apache_request_headers(), however for
* people running other webservers the function is undefined.
*
+ * @access public
* @param bool XSS cleaning
*
* @return array
@@ -661,6 +668,7 @@ class CI_Input {
*
* Returns the value of a single member of the headers class member
*
+ * @access public
* @param string array key for $this->headers
* @param boolean XSS Clean or not
* @return mixed FALSE on failure, string on success
@@ -692,6 +700,7 @@ class CI_Input {
*
* Test to see if a request contains the HTTP_X_REQUESTED_WITH header
*
+ * @access public
* @return boolean
*/
public function is_ajax_request()
@@ -706,6 +715,7 @@ class CI_Input {
*
* Test to see if a request was made from the command line
*
+ * @access public
* @return boolean
*/
public function is_cli_request()
diff --git a/system/core/Lang.php b/system/core/Lang.php
index 5ac671838..d61d1029a 100755
--- a/system/core/Lang.php
+++ b/system/core/Lang.php
@@ -112,7 +112,7 @@ class CI_Lang {
}
- if ( ! isset($lang))
+ if ( ! isset($lang) OR ! is_array($lang))
{
log_message('error', 'Language file contains no data: language/'.$idiom.'/'.$langfile);
return;
@@ -124,7 +124,7 @@ class CI_Lang {
}
$this->is_loaded[] = $langfile;
- $this->language = array_merge($this->language, $lang);
+ $this->language = $this->language + $lang;
unset($lang);
log_message('debug', 'Language file loaded: language/'.$idiom.'/'.$langfile);
diff --git a/system/core/Loader.php b/system/core/Loader.php
index e7fa3d3f6..de0fc06d2 100755
--- a/system/core/Loader.php
+++ b/system/core/Loader.php
@@ -127,7 +127,7 @@ class CI_Loader {
$this->_ci_library_paths = array(APPPATH, BASEPATH);
$this->_ci_helper_paths = array(APPPATH, BASEPATH);
$this->_ci_model_paths = array(APPPATH);
- $this->_ci_view_paths = array(APPPATH.'views/' => TRUE);
+ $this->_ci_view_paths = array(VIEWPATH => TRUE);
log_message('debug', "Loader Class Initialized");
}
@@ -1106,7 +1106,7 @@ class CI_Loader {
* @param array
* @return void
*/
- private function _ci_autoloader()
+ protected function _ci_autoloader()
{
if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'))
{
diff --git a/system/core/Security.php b/system/core/Security.php
index dcc680a11..65338ced3 100755
--- a/system/core/Security.php
+++ b/system/core/Security.php
@@ -33,6 +33,7 @@ class CI_Security {
* @access protected
*/
protected $_xss_hash = '';
+
/**
* Random Hash for Cross Site Request Forgery Protection Cookie
*
@@ -40,6 +41,7 @@ class CI_Security {
* @access protected
*/
protected $_csrf_hash = '';
+
/**
* Expiration time for Cross Site Request Forgery Protection Cookie
* Defaults to two hours (in seconds)
@@ -48,6 +50,7 @@ class CI_Security {
* @access protected
*/
protected $_csrf_expire = 7200;
+
/**
* Token name for Cross Site Request Forgery Protection Cookie
*
@@ -55,6 +58,7 @@ class CI_Security {
* @access protected
*/
protected $_csrf_token_name = 'ci_csrf_token';
+
/**
* Cookie name for Cross Site Request Forgery Protection Cookie
*
@@ -62,12 +66,14 @@ class CI_Security {
* @access protected
*/
protected $_csrf_cookie_name = 'ci_csrf_token';
+
/**
* List of never allowed strings
*
* @var array
* @access protected
*/
+
protected $_never_allowed_str = array(
'document.cookie' => '[removed]',
'document.write' => '[removed]',
@@ -80,7 +86,6 @@ class CI_Security {
'<![CDATA[' => '&lt;![CDATA['
);
- /* never allowed, regex replacement */
/**
* List of never allowed regex replacement
*
@@ -135,6 +140,16 @@ class CI_Security {
return $this->csrf_set_cookie();
}
+ // Check if URI has been whitelisted from CSRF checks
+ if ($exclude_uris = config_item('csrf_exclude_uris'))
+ {
+ $uri = load_class('URI', 'core');
+ if (in_array($uri->uri_string(), $exclude_uris))
+ {
+ return $this;
+ }
+ }
+
// Do the tokens exist in both the _POST and _COOKIE arrays?
if ( ! isset($_POST[$this->_csrf_token_name]) OR
! isset($_COOKIE[$this->_csrf_cookie_name]))
@@ -154,10 +169,11 @@ class CI_Security {
// Nothing should last forever
unset($_COOKIE[$this->_csrf_cookie_name]);
+ $this->_csrf_hash = '';
$this->_csrf_set_hash();
$this->csrf_set_cookie();
- log_message('debug', "CSRF token verified ");
+ log_message('debug', "CSRF token verified");
return $this;
}
@@ -172,7 +188,7 @@ class CI_Security {
public function csrf_set_cookie()
{
$expire = time() + $this->_csrf_expire;
- $secure_cookie = (config_item('cookie_secure') === TRUE) ? 1 : 0;
+ $secure_cookie = (bool) config_item('cookie_secure');
if ($secure_cookie)
{
@@ -369,16 +385,11 @@ class CI_Security {
foreach ($words as $word)
{
- $temp = '';
-
- for ($i = 0, $wordlen = strlen($word); $i < $wordlen; $i++)
- {
- $temp .= substr($word, $i, 1)."\s*";
- }
+ $word = implode("\s*", str_split($word)) . "\s*";
// We only want to do this when it is followed by a non-word character
// That way valid stuff like "dealer to" does not become "dealerto"
- $str = preg_replace_callback('#('.substr($temp, 0, -3).')(\W)#is', array($this, '_compact_exploded_words'), $str);
+ $str = preg_replace_callback('#('.substr($word, 0, -3).')(\W)#is', array($this, '_compact_exploded_words'), $str);
}
/*
@@ -457,7 +468,7 @@ class CI_Security {
if ($is_image === TRUE)
{
- return ($str == $converted_string) ? TRUE: FALSE;
+ return ($str === $converted_string) ? TRUE : FALSE;
}
log_message('debug', "XSS Filtering completed");
@@ -497,48 +508,30 @@ class CI_Security {
*
* This function is a replacement for html_entity_decode()
*
- * In some versions of PHP the native function does not work
- * when UTF-8 is the specified character set, so this gives us
- * a work-around. More info here:
- * http://bugs.php.net/bug.php?id=25670
- *
- * NOTE: html_entity_decode() has a bug in some PHP versions when UTF-8 is the
- * character set, and the PHP developers said they were not back porting the
- * fix to versions other than PHP 5.x.
- *
* @param string
* @param string
* @return string
*/
- public function entity_decode($str, $charset='UTF-8')
+ public function entity_decode($str, $charset = NULL)
{
- if (stristr($str, '&') === FALSE) return $str;
-
- // The reason we are not using html_entity_decode() by itself is because
- // while it is not technically correct to leave out the semicolon
- // at the end of an entity most browsers will still interpret the entity
- // correctly. html_entity_decode() does not convert entities without
- // semicolons, so we are left with our own little solution here. Bummer.
-
- if (function_exists('html_entity_decode') &&
- (strtolower($charset) != 'utf-8'))
+ if (strpos($str, '&') === FALSE)
{
- $str = html_entity_decode($str, ENT_COMPAT, $charset);
- $str = preg_replace('~&#x(0*[0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str);
- return preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str);
+ return $str;
}
- // Numeric Entities
- $str = preg_replace('~&#x(0*[0-9a-f]{2,5});{0,1}~ei', 'chr(hexdec("\\1"))', $str);
- $str = preg_replace('~&#([0-9]{2,4});{0,1}~e', 'chr(\\1)', $str);
-
- // Literal Entities - Slightly slow so we do another check
- if (stristr($str, '&') === FALSE)
+ if (empty($charset))
{
- $str = strtr($str, array_flip(get_html_translation_table(HTML_ENTITIES)));
+ $charset = config_item('charset');
}
- return $str;
+ // The reason we are not using html_entity_decode() by itself is because
+ // while it is not technically correct to leave out the semicolon
+ // at the end of an entity most browsers will still interpret the entity
+ // correctly. html_entity_decode() does not convert entities without
+ // semicolons, so we are left with our own little solution here. Bummer.
+ $str = html_entity_decode($str, ENT_COMPAT, $charset);
+ $str = preg_replace('~&#x(0*[0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str);
+ return preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str);
}
// --------------------------------------------------------------------
@@ -862,14 +855,14 @@ class CI_Security {
return $this->_csrf_hash = $_COOKIE[$this->_csrf_cookie_name];
}
- return $this->_csrf_hash = md5(uniqid(rand(), TRUE));
+ $this->_csrf_hash = md5(uniqid(rand(), TRUE));
+ $this->csrf_set_cookie();
}
return $this->_csrf_hash;
}
}
-// END Security Class
/* End of file Security.php */
-/* Location: ./system/libraries/Security.php */
+/* Location: ./system/core/Security.php */
diff --git a/system/core/URI.php b/system/core/URI.php
index a3ae20cc3..8946bc76b 100755
--- a/system/core/URI.php
+++ b/system/core/URI.php
@@ -175,7 +175,7 @@ class CI_URI {
* @access private
* @return string
*/
- private function _detect_uri()
+ protected function _detect_uri()
{
if ( ! isset($_SERVER['REQUEST_URI']) OR ! isset($_SERVER['SCRIPT_NAME']))
{
@@ -232,7 +232,7 @@ class CI_URI {
* @access private
* @return string
*/
- private function _parse_cli_args()
+ protected function _parse_cli_args()
{
$args = array_slice($_SERVER['argv'], 1);
diff --git a/system/database/DB_active_rec.php b/system/database/DB_active_rec.php
index a16363c68..0dd48cca9 100644
--- a/system/database/DB_active_rec.php
+++ b/system/database/DB_active_rec.php
@@ -196,7 +196,7 @@ class CI_DB_active_record extends CI_DB_driver {
$alias = $this->_create_alias_from_table(trim($select));
}
- $sql = $type.'('.$this->_protect_identifiers(trim($select)).') AS '.$alias;
+ $sql = $this->_protect_identifiers($type.'('.trim($select).')').' AS '.$this->_protect_identifiers(trim($alias));
$this->ar_select[] = $sql;
@@ -872,11 +872,11 @@ class CI_DB_active_record extends CI_DB_driver {
* @param integer the offset value
* @return object
*/
- public function limit($value, $offset = '')
+ public function limit($value, $offset = NULL)
{
$this->ar_limit = $value;
- if ($offset != '')
+ if ( ! is_null($offset))
{
$this->ar_offset = (int) $offset;
}
@@ -894,7 +894,7 @@ class CI_DB_active_record extends CI_DB_driver {
*/
public function offset($offset)
{
- $this->ar_offset = $offset;
+ $this->ar_offset = (int) $offset;
return $this;
}
diff --git a/system/database/DB_cache.php b/system/database/DB_cache.php
index 3bf065ca5..ad1c28d72 100644
--- a/system/database/DB_cache.php
+++ b/system/database/DB_cache.php
@@ -33,7 +33,7 @@ class CI_DB_Cache {
* Grabs the CI super object instance so we can access it.
*
*/
- function CI_DB_Cache(&$db)
+ function __construct(&$db)
{
// Assign the main CI object to $this->CI
// and load the file helper since we use it a lot
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index f3e824daa..d7b63b9dc 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -78,7 +78,7 @@ class CI_DB_driver {
*
* @param array
*/
- function CI_DB_driver($params)
+ function __construct($params)
{
if (is_array($params))
{
@@ -218,7 +218,7 @@ class CI_DB_driver {
// Some DBs have functions that return the version, and don't run special
// SQL queries per se. In these instances, just return the result.
- $driver_version_exceptions = array('oci8', 'sqlite', 'cubrid');
+ $driver_version_exceptions = array('oci8', 'sqlite', 'cubrid', 'pdo');
if (in_array($this->dbdriver, $driver_version_exceptions))
{
@@ -251,9 +251,10 @@ class CI_DB_driver {
{
if ($sql == '')
{
+ log_message('error', 'Invalid query: '.$sql);
+
if ($this->db_debug)
{
- log_message('error', 'Invalid query: '.$sql);
return $this->display_error('db_invalid_query');
}
return FALSE;
@@ -306,21 +307,23 @@ class CI_DB_driver {
// This will trigger a rollback if transactions are being used
$this->_trans_status = FALSE;
+ // Grab the error number and message now, as we might run some
+ // additional queries before displaying the error
+ $error_no = $this->_error_number();
+ $error_msg = $this->_error_message();
+
+ // Log errors
+ log_message('error', 'Query error: '.$error_msg);
+
if ($this->db_debug)
{
- // grab the error number and message now, as we might run some
- // additional queries before displaying the error
- $error_no = $this->_error_number();
- $error_msg = $this->_error_message();
-
// We call this function in order to roll-back queries
// if transactions are enabled. If we don't call this here
// the error message will trigger an exit, causing the
// transactions to remain in limbo.
$this->trans_complete();
- // Log and display errors
- log_message('error', 'Query error: '.$error_msg);
+ // Display errors
return $this->display_error(
array(
'Error Number: '.$error_no,
@@ -947,6 +950,7 @@ class CI_DB_driver {
foreach ($where as $key => $val)
{
$prefix = (count($dest) == 0) ? '' : ' AND ';
+ $key = $this->_protect_identifiers($key);
if ($val !== '')
{
@@ -1162,7 +1166,7 @@ class CI_DB_driver {
if ($native == TRUE)
{
- $message = $error;
+ $message = (array) $error;
}
else
{
@@ -1387,4 +1391,4 @@ class CI_DB_driver {
/* End of file DB_driver.php */
-/* Location: ./system/database/DB_driver.php */ \ No newline at end of file
+/* Location: ./system/database/DB_driver.php */
diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php
index 0dd29c238..6bc40411b 100644
--- a/system/database/DB_forge.php
+++ b/system/database/DB_forge.php
@@ -35,7 +35,7 @@ class CI_DB_forge {
* Grabs the CI super object instance so we can access it.
*
*/
- function CI_DB_forge()
+ function __construct()
{
// Assign the main database object to $this->db
$CI =& get_instance();
diff --git a/system/database/DB_utility.php b/system/database/DB_utility.php
index a5f174f0a..52196b7ce 100644
--- a/system/database/DB_utility.php
+++ b/system/database/DB_utility.php
@@ -33,7 +33,7 @@ class CI_DB_utility extends CI_DB_forge {
* Grabs the CI super object instance so we can access it.
*
*/
- function CI_DB_utility()
+ function __construct()
{
// Assign the main database object to $this->db
$CI =& get_instance();
diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php
index 872504564..dc020c624 100644
--- a/system/database/drivers/mysql/mysql_driver.php
+++ b/system/database/drivers/mysql/mysql_driver.php
@@ -56,7 +56,7 @@ class CI_DB_mysql_driver extends CI_DB {
// whether SET NAMES must be used to set the character set
var $use_set_names;
-
+
/**
* Non-persistent database connection
*
@@ -135,20 +135,9 @@ class CI_DB_mysql_driver extends CI_DB {
*/
function db_set_charset($charset, $collation)
{
- if ( ! isset($this->use_set_names))
- {
- // mysql_set_charset() requires PHP >= 5.2.3 and MySQL >= 5.0.7, use SET NAMES as fallback
- $this->use_set_names = (version_compare(PHP_VERSION, '5.2.3', '>=') && version_compare(mysql_get_server_info(), '5.0.7', '>=')) ? FALSE : TRUE;
- }
-
- if ($this->use_set_names === TRUE)
- {
- return @mysql_query("SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'", $this->conn_id);
- }
- else
- {
- return @mysql_set_charset($charset, $this->conn_id);
- }
+ return function_exists('mysql_set_charset')
+ ? @mysql_set_charset($charset, $this->conn_id)
+ : @mysql_query("SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'", $this->conn_id);
}
// --------------------------------------------------------------------
@@ -441,7 +430,7 @@ class CI_DB_mysql_driver extends CI_DB {
*/
function _field_data($table)
{
- return "SELECT * FROM ".$table." LIMIT 1";
+ return "DESCRIBE ".$table;
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/mysql/mysql_result.php b/system/database/drivers/mysql/mysql_result.php
index 507389603..6ceaf4b9b 100644
--- a/system/database/drivers/mysql/mysql_result.php
+++ b/system/database/drivers/mysql/mysql_result.php
@@ -84,14 +84,19 @@ class CI_DB_mysql_result extends CI_DB_result {
function field_data()
{
$retval = array();
- while ($field = mysql_fetch_field($this->result_id))
+ while ($field = mysql_fetch_object($this->result_id))
{
+ preg_match('/([a-zA-Z]+)(\((\d+)\))?/i', $field->Type, $matches);
+
+ $type = $matches[1];
+ $length = isset($matches[3]) ? (int) $matches[3] : NULL;
+
$F = new stdClass();
- $F->name = $field->name;
- $F->type = $field->type;
- $F->default = $field->def;
- $F->max_length = $field->max_length;
- $F->primary_key = $field->primary_key;
+ $F->name = $field->Field;
+ $F->type = $type;
+ $F->default = $field->Default;
+ $F->max_length = $length;
+ $F->primary_key = ( $field->Key == 'PRI' ? 1 : 0 );
$retval[] = $F;
}
diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php
index ddcaff323..abef80fbd 100644
--- a/system/database/drivers/mysqli/mysqli_driver.php
+++ b/system/database/drivers/mysqli/mysqli_driver.php
@@ -56,7 +56,7 @@ class CI_DB_mysqli_driver extends CI_DB {
// whether SET NAMES must be used to set the character set
var $use_set_names;
-
+
// --------------------------------------------------------------------
/**
@@ -135,20 +135,9 @@ class CI_DB_mysqli_driver extends CI_DB {
*/
function _db_set_charset($charset, $collation)
{
- if ( ! isset($this->use_set_names))
- {
- // mysqli_set_charset() requires MySQL >= 5.0.7, use SET NAMES as fallback
- $this->use_set_names = (version_compare(mysqli_get_server_info($this->conn_id), '5.0.7', '>=')) ? FALSE : TRUE;
- }
-
- if ($this->use_set_names === TRUE)
- {
- return @mysqli_query($this->conn_id, "SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'");
- }
- else
- {
- return @mysqli_set_charset($this->conn_id, $charset);
- }
+ return function_exists('mysqli_set_charset')
+ ? @mysqli_set_charset($this->conn_id, $charset)
+ : @mysqli_query($this->conn_id, "SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'");
}
// --------------------------------------------------------------------
@@ -442,7 +431,7 @@ class CI_DB_mysqli_driver extends CI_DB {
*/
function _field_data($table)
{
- return "SELECT * FROM ".$table." LIMIT 1";
+ return "DESCRIBE ".$table;
}
// --------------------------------------------------------------------
@@ -570,7 +559,7 @@ class CI_DB_mysqli_driver extends CI_DB {
{
return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES ".implode(', ', $values);
}
-
+
// --------------------------------------------------------------------
/**
diff --git a/system/database/drivers/mysqli/mysqli_result.php b/system/database/drivers/mysqli/mysqli_result.php
index c4d8f5d58..bbfb8481a 100644
--- a/system/database/drivers/mysqli/mysqli_result.php
+++ b/system/database/drivers/mysqli/mysqli_result.php
@@ -84,21 +84,26 @@ class CI_DB_mysqli_result extends CI_DB_result {
function field_data()
{
$retval = array();
- while ($field = mysqli_fetch_field($this->result_id))
+ while ($field = mysqli_fetch_object($this->result_id))
{
+ preg_match('/([a-zA-Z]+)(\((\d+)\))?/i', $field->Type, $matches);
+
+ $type = $matches[1];
+ $length = isset($matches[3]) ? (int) $matches[3] : NULL;
+
$F = new stdClass();
- $F->name = $field->name;
- $F->type = $field->type;
- $F->default = $field->def;
- $F->max_length = $field->max_length;
- $F->primary_key = ($field->flags & MYSQLI_PRI_KEY_FLAG) ? 1 : 0;
+ $F->name = $field->Field;
+ $F->type = $type;
+ $F->default = $field->Default;
+ $F->max_length = $length;
+ $F->primary_key = ( $field->Key == 'PRI' ? 1 : 0 );
$retval[] = $F;
}
return $retval;
}
-
+
// --------------------------------------------------------------------
/**
diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php
index 42cfaaefb..1cf063ec1 100644
--- a/system/database/drivers/oci8/oci8_driver.php
+++ b/system/database/drivers/oci8/oci8_driver.php
@@ -79,7 +79,7 @@ class CI_DB_oci8_driver extends CI_DB {
*/
function db_connect()
{
- return @ocilogon($this->username, $this->password, $this->hostname);
+ return @ocilogon($this->username, $this->password, $this->hostname, $this->char_set);
}
// --------------------------------------------------------------------
@@ -92,7 +92,7 @@ class CI_DB_oci8_driver extends CI_DB {
*/
function db_pconnect()
{
- return @ociplogon($this->username, $this->password, $this->hostname);
+ return @ociplogon($this->username, $this->password, $this->hostname, $this->char_set);
}
// --------------------------------------------------------------------
@@ -136,7 +136,7 @@ class CI_DB_oci8_driver extends CI_DB {
*/
function db_set_charset($charset, $collation)
{
- // @todo - add support if needed
+ // this is done upon connect
return TRUE;
}
@@ -404,6 +404,7 @@ class CI_DB_oci8_driver extends CI_DB {
}
$str = remove_invisible_characters($str);
+ $str = str_replace("'", "''", $str);
// escape LIKE condition wildcards
if ($like === TRUE)
@@ -642,6 +643,34 @@ class CI_DB_oci8_driver extends CI_DB {
// --------------------------------------------------------------------
/**
+ * Insert_batch statement
+ *
+ * Generates a platform-specific insert string from the supplied data
+ *
+ * @access public
+ * @param string the table name
+ * @param array the insert keys
+ * @param array the insert values
+ * @return string
+ */
+ function _insert_batch($table, $keys, $values)
+ {
+ $keys = implode(', ', $keys);
+ $sql = "INSERT ALL\n";
+
+ for ($i = 0, $c = count($values); $i < $c; $i++)
+ {
+ $sql .= ' INTO ' . $table . ' (' . $keys . ') VALUES ' . $values[$i] . "\n";
+ }
+
+ $sql .= 'SELECT * FROM dual';
+
+ return $sql;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* Update statement
*
* Generates a platform-specific update string from the supplied data
@@ -775,4 +804,4 @@ class CI_DB_oci8_driver extends CI_DB {
/* End of file oci8_driver.php */
-/* Location: ./system/database/drivers/oci8/oci8_driver.php */ \ No newline at end of file
+/* Location: ./system/database/drivers/oci8/oci8_driver.php */
diff --git a/system/database/drivers/oci8/oci8_result.php b/system/database/drivers/oci8/oci8_result.php
index 88531b436..2713f6f12 100644
--- a/system/database/drivers/oci8/oci8_result.php
+++ b/system/database/drivers/oci8/oci8_result.php
@@ -42,15 +42,18 @@ class CI_DB_oci8_result extends CI_DB_result {
*/
function num_rows()
{
- $rowcount = count($this->result_array());
- @ociexecute($this->stmt_id);
-
- if ($this->curs_id)
+ if ($this->num_rows === 0 && count($this->result_array()) > 0)
{
- @ociexecute($this->curs_id);
+ $this->num_rows = count($this->result_array());
+ @ociexecute($this->stmt_id);
+
+ if ($this->curs_id)
+ {
+ @ociexecute($this->curs_id);
+ }
}
- return $rowcount;
+ return $this->num_rows;
}
// --------------------------------------------------------------------
@@ -246,4 +249,4 @@ class CI_DB_oci8_result extends CI_DB_result {
/* End of file oci8_result.php */
-/* Location: ./system/database/drivers/oci8/oci8_result.php */ \ No newline at end of file
+/* Location: ./system/database/drivers/oci8/oci8_result.php */
diff --git a/system/database/drivers/odbc/odbc_driver.php b/system/database/drivers/odbc/odbc_driver.php
index 5e764e071..bcd7937d9 100644
--- a/system/database/drivers/odbc/odbc_driver.php
+++ b/system/database/drivers/odbc/odbc_driver.php
@@ -48,9 +48,9 @@ class CI_DB_odbc_driver extends CI_DB {
var $_random_keyword;
- function CI_DB_odbc_driver($params)
+ function __construct($params)
{
- parent::CI_DB($params);
+ parent::__construct($params);
$this->_random_keyword = ' RND('.time().')'; // database specific random keyword
}
diff --git a/system/database/drivers/pdo/index.html b/system/database/drivers/pdo/index.html
new file mode 100644
index 000000000..c942a79ce
--- /dev/null
+++ b/system/database/drivers/pdo/index.html
@@ -0,0 +1,10 @@
+<html>
+<head>
+ <title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/system/database/drivers/pdo/pdo_driver.php b/system/database/drivers/pdo/pdo_driver.php
new file mode 100644
index 000000000..19e069b06
--- /dev/null
+++ b/system/database/drivers/pdo/pdo_driver.php
@@ -0,0 +1,792 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.1.6 or newer
+ *
+ * @package CodeIgniter
+ * @author ExpressionEngine Dev Team
+ * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 2.1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * PDO Database Adapter Class
+ *
+ * Note: _DB is an extender class that the app controller
+ * creates dynamically based on whether the active record
+ * class is being used or not.
+ *
+ * @package CodeIgniter
+ * @subpackage Drivers
+ * @category Database
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_pdo_driver extends CI_DB {
+
+ var $dbdriver = 'pdo';
+
+ // the character used to excape - not necessary for PDO
+ var $_escape_char = '';
+ var $_like_escape_str;
+ var $_like_escape_chr;
+
+
+ /**
+ * The syntax to count rows is slightly different across different
+ * database engines, so this string appears in each driver and is
+ * used for the count_all() and count_all_results() functions.
+ */
+ var $_count_string = "SELECT COUNT(*) AS ";
+ var $_random_keyword;
+
+
+ function __construct($params)
+ {
+ parent::__construct($params);
+
+ // clause and character used for LIKE escape sequences
+ if (strpos($this->hostname, 'mysql') !== FALSE)
+ {
+ $this->_like_escape_str = '';
+ $this->_like_escape_chr = '';
+ }
+ else if (strpos($this->hostname, 'odbc') !== FALSE)
+ {
+ $this->_like_escape_str = " {escape '%s'} ";
+ $this->_like_escape_chr = '!';
+ }
+ else
+ {
+ $this->_like_escape_str = " ESCAPE '%s' ";
+ $this->_like_escape_chr = '!';
+ }
+
+ $this->hostname = $this->hostname . ";dbname=".$this->database;
+ $this->trans_enabled = FALSE;
+
+ $this->_random_keyword = ' RND('.time().')'; // database specific random keyword
+ }
+
+ /**
+ * Non-persistent database connection
+ *
+ * @access private called by the base class
+ * @return resource
+ */
+ function db_connect()
+ {
+ return new PDO($this->hostname,$this->username,$this->password, array(
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT
+ ));
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Persistent database connection
+ *
+ * @access private called by the base class
+ * @return resource
+ */
+ function db_pconnect()
+ {
+ return new PDO($this->hostname,$this->username,$this->password, array(
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT,
+ PDO::ATTR_PERSISTENT => true
+ ));
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Reconnect
+ *
+ * Keep / reestablish the db connection if no queries have been
+ * sent for a length of time exceeding the server's idle timeout
+ *
+ * @access public
+ * @return void
+ */
+ function reconnect()
+ {
+ if ($this->db->db_debug)
+ {
+ return $this->db->display_error('db_unsuported_feature');
+ }
+ return FALSE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Select the database
+ *
+ * @access private called by the base class
+ * @return resource
+ */
+ function db_select()
+ {
+ // Not needed for PDO
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Set client character set
+ *
+ * @access public
+ * @param string
+ * @param string
+ * @return resource
+ */
+ function db_set_charset($charset, $collation)
+ {
+ // @todo - add support if needed
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Version number query string
+ *
+ * @access public
+ * @return string
+ */
+ function _version()
+ {
+ return $this->conn_id->getAttribute(PDO::ATTR_CLIENT_VERSION);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Execute the query
+ *
+ * @access private called by the base class
+ * @param string an SQL query
+ * @return object
+ */
+ function _execute($sql)
+ {
+ $sql = $this->_prep_query($sql);
+ $result_id = $this->conn_id->query($sql);
+
+ if (is_object($result_id))
+ {
+ $this->affect_rows = $result_id->rowCount();
+ }
+ else
+ {
+ $this->affect_rows = 0;
+ }
+
+ return $result_id;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Prep the query
+ *
+ * If needed, each database adapter can prep the query string
+ *
+ * @access private called by execute()
+ * @param string an SQL query
+ * @return string
+ */
+ function _prep_query($sql)
+ {
+ return $sql;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Begin Transaction
+ *
+ * @access public
+ * @return bool
+ */
+ function trans_begin($test_mode = FALSE)
+ {
+ if ( ! $this->trans_enabled)
+ {
+ return TRUE;
+ }
+
+ // When transactions are nested we only begin/commit/rollback the outermost ones
+ if ($this->_trans_depth > 0)
+ {
+ return TRUE;
+ }
+
+ // Reset the transaction failure flag.
+ // If the $test_mode flag is set to TRUE transactions will be rolled back
+ // even if the queries produce a successful result.
+ $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
+
+ return $this->conn_id->beginTransaction();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Commit Transaction
+ *
+ * @access public
+ * @return bool
+ */
+ function trans_commit()
+ {
+ if ( ! $this->trans_enabled)
+ {
+ return TRUE;
+ }
+
+ // When transactions are nested we only begin/commit/rollback the outermost ones
+ if ($this->_trans_depth > 0)
+ {
+ return TRUE;
+ }
+
+ $ret = $this->conn->commit();
+ return $ret;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Rollback Transaction
+ *
+ * @access public
+ * @return bool
+ */
+ function trans_rollback()
+ {
+ if ( ! $this->trans_enabled)
+ {
+ return TRUE;
+ }
+
+ // When transactions are nested we only begin/commit/rollback the outermost ones
+ if ($this->_trans_depth > 0)
+ {
+ return TRUE;
+ }
+
+ $ret = $this->conn_id->rollBack();
+ return $ret;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Escape String
+ *
+ * @access public
+ * @param string
+ * @param bool whether or not the string will be used in a LIKE condition
+ * @return string
+ */
+ function escape_str($str, $like = FALSE)
+ {
+ if (is_array($str))
+ {
+ foreach ($str as $key => $val)
+ {
+ $str[$key] = $this->escape_str($val, $like);
+ }
+
+ return $str;
+ }
+
+ //Escape the string
+ $str = $this->conn_id->quote($str);
+
+ //If there are duplicated quotes, trim them away
+ if (strpos($str, "'") === 0)
+ {
+ $str = substr($str, 1, -1);
+ }
+
+ // escape LIKE condition wildcards
+ if ($like === TRUE)
+ {
+ $str = str_replace( array('%', '_', $this->_like_escape_chr),
+ array($this->_like_escape_chr.'%', $this->_like_escape_chr.'_', $this->_like_escape_chr.$this->_like_escape_chr),
+ $str);
+ }
+
+ return $str;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Affected Rows
+ *
+ * @access public
+ * @return integer
+ */
+ function affected_rows()
+ {
+ return $this->affect_rows;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Insert ID
+ *
+ * @access public
+ * @return integer
+ */
+ function insert_id($name=NULL)
+ {
+ //Convenience method for postgres insertid
+ if (strpos($this->hostname, 'pgsql') !== FALSE)
+ {
+ $v = $this->_version();
+
+ $table = func_num_args() > 0 ? func_get_arg(0) : NULL;
+
+ if ($table == NULL && $v >= '8.1')
+ {
+ $sql='SELECT LASTVAL() as ins_id';
+ }
+ $query = $this->query($sql);
+ $row = $query->row();
+ return $row->ins_id;
+ }
+ else
+ {
+ return $this->conn_id->lastInsertId($name);
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * "Count All" query
+ *
+ * Generates a platform-specific query string that counts all records in
+ * the specified database
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+ function count_all($table = '')
+ {
+ if ($table == '')
+ {
+ return 0;
+ }
+
+ $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows') . " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
+
+ if ($query->num_rows() == 0)
+ {
+ return 0;
+ }
+
+ $row = $query->row();
+ $this->_reset_select();
+ return (int) $row->numrows;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Show table query
+ *
+ * Generates a platform-specific query string so that the table names can be fetched
+ *
+ * @access private
+ * @param boolean
+ * @return string
+ */
+ function _list_tables($prefix_limit = FALSE)
+ {
+ $sql = "SHOW TABLES FROM `".$this->database."`";
+
+ if ($prefix_limit !== FALSE AND $this->dbprefix != '')
+ {
+ //$sql .= " LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
+ return FALSE; // not currently supported
+ }
+
+ return $sql;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Show column query
+ *
+ * Generates a platform-specific query string so that the column names can be fetched
+ *
+ * @access public
+ * @param string the table name
+ * @return string
+ */
+ function _list_columns($table = '')
+ {
+ return "SHOW COLUMNS FROM ".$table;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Field data query
+ *
+ * Generates a platform-specific query so that the column data can be retrieved
+ *
+ * @access public
+ * @param string the table name
+ * @return object
+ */
+ function _field_data($table)
+ {
+ return "SELECT TOP 1 FROM ".$table;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * The error message string
+ *
+ * @access private
+ * @return string
+ */
+ function _error_message()
+ {
+ $error_array = $this->conn_id->errorInfo();
+ return $error_array[2];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * The error message number
+ *
+ * @access private
+ * @return integer
+ */
+ function _error_number()
+ {
+ return $this->conn_id->errorCode();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Escape the SQL Identifiers
+ *
+ * This function escapes column and table names
+ *
+ * @access private
+ * @param string
+ * @return string
+ */
+ function _escape_identifiers($item)
+ {
+ if ($this->_escape_char == '')
+ {
+ return $item;
+ }
+
+ foreach ($this->_reserved_identifiers as $id)
+ {
+ if (strpos($item, '.'.$id) !== FALSE)
+ {
+ $str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
+
+ // remove duplicates if the user already included the escape
+ return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
+ }
+ }
+
+ if (strpos($item, '.') !== FALSE)
+ {
+ $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
+
+ }
+ else
+ {
+ $str = $this->_escape_char.$item.$this->_escape_char;
+ }
+
+ // remove duplicates if the user already included the escape
+ return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * From Tables
+ *
+ * This function implicitly groups FROM tables so there is no confusion
+ * about operator precedence in harmony with SQL standards
+ *
+ * @access public
+ * @param type
+ * @return type
+ */
+ function _from_tables($tables)
+ {
+ if ( ! is_array($tables))
+ {
+ $tables = array($tables);
+ }
+
+ return (count($tables) == 1) ? $tables[0] : '('.implode(', ', $tables).')';
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Insert statement
+ *
+ * Generates a platform-specific insert string from the supplied data
+ *
+ * @access public
+ * @param string the table name
+ * @param array the insert keys
+ * @param array the insert values
+ * @return string
+ */
+ function _insert($table, $keys, $values)
+ {
+ return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Insert_batch statement
+ *
+ * Generates a platform-specific insert string from the supplied data
+ *
+ * @access public
+ * @param string the table name
+ * @param array the insert keys
+ * @param array the insert values
+ * @return string
+ */
+ function _insert_batch($table, $keys, $values)
+ {
+ return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES ".implode(', ', $values);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Update statement
+ *
+ * Generates a platform-specific update string from the supplied data
+ *
+ * @access public
+ * @param string the table name
+ * @param array the update data
+ * @param array the where clause
+ * @param array the orderby clause
+ * @param array the limit clause
+ * @return string
+ */
+ function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+ {
+ foreach ($values as $key => $val)
+ {
+ $valstr[] = $key." = ".$val;
+ }
+
+ $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+
+ $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
+
+ $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
+
+ $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
+
+ $sql .= $orderby.$limit;
+
+ return $sql;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Update_Batch statement
+ *
+ * Generates a platform-specific batch update string from the supplied data
+ *
+ * @access public
+ * @param string the table name
+ * @param array the update data
+ * @param array the where clause
+ * @return string
+ */
+ function _update_batch($table, $values, $index, $where = NULL)
+ {
+ $ids = array();
+ $where = ($where != '' AND count($where) >=1) ? implode(" ", $where).' AND ' : '';
+
+ foreach ($values as $key => $val)
+ {
+ $ids[] = $val[$index];
+
+ foreach (array_keys($val) as $field)
+ {
+ if ($field != $index)
+ {
+ $final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field];
+ }
+ }
+ }
+
+ $sql = "UPDATE ".$table." SET ";
+ $cases = '';
+
+ foreach ($final as $k => $v)
+ {
+ $cases .= $k.' = CASE '."\n";
+ foreach ($v as $row)
+ {
+ $cases .= $row."\n";
+ }
+
+ $cases .= 'ELSE '.$k.' END, ';
+ }
+
+ $sql .= substr($cases, 0, -2);
+
+ $sql .= ' WHERE '.$where.$index.' IN ('.implode(',', $ids).')';
+
+ return $sql;
+ }
+
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Truncate statement
+ *
+ * Generates a platform-specific truncate string from the supplied data
+ * If the database does not support the truncate() command
+ * This function maps to "DELETE FROM table"
+ *
+ * @access public
+ * @param string the table name
+ * @return string
+ */
+ function _truncate($table)
+ {
+ return $this->_delete($table);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Delete statement
+ *
+ * Generates a platform-specific delete string from the supplied data
+ *
+ * @access public
+ * @param string the table name
+ * @param array the where clause
+ * @param string the limit clause
+ * @return string
+ */
+ function _delete($table, $where = array(), $like = array(), $limit = FALSE)
+ {
+ $conditions = '';
+
+ if (count($where) > 0 OR count($like) > 0)
+ {
+ $conditions = "\nWHERE ";
+ $conditions .= implode("\n", $this->ar_where);
+
+ if (count($where) > 0 && count($like) > 0)
+ {
+ $conditions .= " AND ";
+ }
+ $conditions .= implode("\n", $like);
+ }
+
+ $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+
+ return "DELETE FROM ".$table.$conditions.$limit;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Limit string
+ *
+ * Generates a platform-specific LIMIT clause
+ *
+ * @access public
+ * @param string the sql query string
+ * @param integer the number of rows to limit the query to
+ * @param integer the offset value
+ * @return string
+ */
+ function _limit($sql, $limit, $offset)
+ {
+ if (strpos($this->hostname, 'cubrid') !== FALSE || strpos($this->hostname, 'sqlite') !== FALSE)
+ {
+ if ($offset == 0)
+ {
+ $offset = '';
+ }
+ else
+ {
+ $offset .= ", ";
+ }
+
+ return $sql."LIMIT ".$offset.$limit;
+ }
+ else
+ {
+ $sql .= "LIMIT ".$limit;
+
+ if ($offset > 0)
+ {
+ $sql .= " OFFSET ".$offset;
+ }
+
+ return $sql;
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Close DB Connection
+ *
+ * @access public
+ * @param resource
+ * @return void
+ */
+ function _close($conn_id)
+ {
+ $this->conn_id = null;
+ }
+
+
+}
+
+
+
+/* End of file pdo_driver.php */
+/* Location: ./system/database/drivers/pdo/pdo_driver.php */ \ No newline at end of file
diff --git a/system/database/drivers/pdo/pdo_forge.php b/system/database/drivers/pdo/pdo_forge.php
new file mode 100644
index 000000000..5516873c0
--- /dev/null
+++ b/system/database/drivers/pdo/pdo_forge.php
@@ -0,0 +1,266 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.1.6 or newer
+ *
+ * @package CodeIgniter
+ * @author ExpressionEngine Dev Team
+ * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 2.1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * PDO Forge Class
+ *
+ * @category Database
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/database/
+ */
+class CI_DB_pdo_forge extends CI_DB_forge {
+
+ /**
+ * Create database
+ *
+ * @access private
+ * @param string the database name
+ * @return bool
+ */
+ function _create_database()
+ {
+ // PDO has no "create database" command since it's
+ // designed to connect to an existing database
+ if ($this->db->db_debug)
+ {
+ return $this->db->display_error('db_unsuported_feature');
+ }
+ return FALSE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Drop database
+ *
+ * @access private
+ * @param string the database name
+ * @return bool
+ */
+ function _drop_database($name)
+ {
+ // PDO has no "drop database" command since it's
+ // designed to connect to an existing database
+ if ($this->db->db_debug)
+ {
+ return $this->db->display_error('db_unsuported_feature');
+ }
+ return FALSE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Create Table
+ *
+ * @access private
+ * @param string the table name
+ * @param array the fields
+ * @param mixed primary key(s)
+ * @param mixed key(s)
+ * @param boolean should 'IF NOT EXISTS' be added to the SQL
+ * @return bool
+ */
+ function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+ {
+ $sql = 'CREATE TABLE ';
+
+ if ($if_not_exists === TRUE)
+ {
+ $sql .= 'IF NOT EXISTS ';
+ }
+
+ $sql .= $this->db->_escape_identifiers($table)." (";
+ $current_field_count = 0;
+
+ foreach ($fields as $field=>$attributes)
+ {
+ // Numeric field names aren't allowed in databases, so if the key is
+ // numeric, we know it was assigned by PHP and the developer manually
+ // entered the field information, so we'll simply add it to the list
+ if (is_numeric($field))
+ {
+ $sql .= "\n\t$attributes";
+ }
+ else
+ {
+ $attributes = array_change_key_case($attributes, CASE_UPPER);
+
+ $sql .= "\n\t".$this->db->_protect_identifiers($field);
+
+ $sql .= ' '.$attributes['TYPE'];
+
+ if (array_key_exists('CONSTRAINT', $attributes))
+ {
+ $sql .= '('.$attributes['CONSTRAINT'].')';
+ }
+
+ if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
+ {
+ $sql .= ' UNSIGNED';
+ }
+
+ if (array_key_exists('DEFAULT', $attributes))
+ {
+ $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';
+ }
+
+ if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)
+ {
+ $sql .= ' NULL';
+ }
+ else
+ {
+ $sql .= ' NOT NULL';
+ }
+
+ if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)
+ {
+ $sql .= ' AUTO_INCREMENT';
+ }
+ }
+
+ // don't add a comma on the end of the last field
+ if (++$current_field_count < count($fields))
+ {
+ $sql .= ',';
+ }
+ }
+
+ if (count($primary_keys) > 0)
+ {
+ $primary_keys = $this->db->_protect_identifiers($primary_keys);
+ $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";
+ }
+
+ if (is_array($keys) && count($keys) > 0)
+ {
+ foreach ($keys as $key)
+ {
+ if (is_array($key))
+ {
+ $key = $this->db->_protect_identifiers($key);
+ }
+ else
+ {
+ $key = array($this->db->_protect_identifiers($key));
+ }
+
+ $sql .= ",\n\tFOREIGN KEY (" . implode(', ', $key) . ")";
+ }
+ }
+
+ $sql .= "\n)";
+
+ return $sql;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Drop Table
+ *
+ * @access private
+ * @return bool
+ */
+ function _drop_table($table)
+ {
+ // Not a supported PDO feature
+ if ($this->db->db_debug)
+ {
+ return $this->db->display_error('db_unsuported_feature');
+ }
+ return FALSE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Alter table query
+ *
+ * Generates a platform-specific query so that a table can be altered
+ * Called by add_column(), drop_column(), and column_alter(),
+ *
+ * @access private
+ * @param string the ALTER type (ADD, DROP, CHANGE)
+ * @param string the column name
+ * @param string the table name
+ * @param string the column definition
+ * @param string the default value
+ * @param boolean should 'NOT NULL' be added
+ * @param string the field after which we should add the new field
+ * @return object
+ */
+ function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+ {
+ $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name);
+
+ // DROP has everything it needs now.
+ if ($alter_type == 'DROP')
+ {
+ return $sql;
+ }
+
+ $sql .= " $column_definition";
+
+ if ($default_value != '')
+ {
+ $sql .= " DEFAULT \"$default_value\"";
+ }
+
+ if ($null === NULL)
+ {
+ $sql .= ' NULL';
+ }
+ else
+ {
+ $sql .= ' NOT NULL';
+ }
+
+ if ($after_field != '')
+ {
+ $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);
+ }
+
+ return $sql;
+
+ }
+
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Rename a table
+ *
+ * Generates a platform-specific query so that a table can be renamed
+ *
+ * @access private
+ * @param string the old table name
+ * @param string the new table name
+ * @return string
+ */
+ function _rename_table($table_name, $new_table_name)
+ {
+ $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);
+ return $sql;
+ }
+
+
+}
+
+/* End of file pdo_forge.php */
+/* Location: ./system/database/drivers/pdo/pdo_forge.php */ \ No newline at end of file
diff --git a/system/database/drivers/pdo/pdo_result.php b/system/database/drivers/pdo/pdo_result.php
new file mode 100644
index 000000000..e3ae0da4b
--- /dev/null
+++ b/system/database/drivers/pdo/pdo_result.php
@@ -0,0 +1,171 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.1.6 or newer
+ *
+ * @package CodeIgniter
+ * @author ExpressionEngine Dev Team
+ * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 2.1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * PDO Result Class
+ *
+ * This class extends the parent result class: CI_DB_result
+ *
+ * @category Database
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_pdo_result extends CI_DB_result {
+
+ /**
+ * Number of rows in the result set
+ *
+ * @access public
+ * @return integer
+ */
+ function num_rows()
+ {
+ return $this->result_id->rowCount();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Number of fields in the result set
+ *
+ * @access public
+ * @return integer
+ */
+ function num_fields()
+ {
+ return $this->result_id->columnCount();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch Field Names
+ *
+ * Generates an array of column names
+ *
+ * @access public
+ * @return array
+ */
+ function list_fields()
+ {
+ if ($this->db->db_debug)
+ {
+ return $this->db->display_error('db_unsuported_feature');
+ }
+ return FALSE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Field data
+ *
+ * Generates an array of objects containing field meta-data
+ *
+ * @access public
+ * @return array
+ */
+ function field_data()
+ {
+ $data = array();
+
+ try
+ {
+ for($i = 0; $i < $this->num_fields(); $i++)
+ {
+ $data[] = $this->result_id->getColumnMeta($i);
+ }
+
+ return $data;
+ }
+ catch (Exception $e)
+ {
+ if ($this->db->db_debug)
+ {
+ return $this->db->display_error('db_unsuported_feature');
+ }
+ return FALSE;
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Free the result
+ *
+ * @return null
+ */
+ function free_result()
+ {
+ if (is_object($this->result_id))
+ {
+ $this->result_id = FALSE;
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Data Seek
+ *
+ * Moves the internal pointer to the desired offset. We call
+ * this internally before fetching results to make sure the
+ * result set starts at zero
+ *
+ * @access private
+ * @return array
+ */
+ function _data_seek($n = 0)
+ {
+ return FALSE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Result - associative array
+ *
+ * Returns the result set as an array
+ *
+ * @access private
+ * @return array
+ */
+ function _fetch_assoc()
+ {
+ return $this->result_id->fetch(PDO::FETCH_ASSOC);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Result - object
+ *
+ * Returns the result set as an object
+ *
+ * @access private
+ * @return object
+ */
+ function _fetch_object()
+ {
+ return $this->result_id->fetchObject();
+ }
+
+}
+
+
+/* End of file pdo_result.php */
+/* Location: ./system/database/drivers/pdo/pdo_result.php */ \ No newline at end of file
diff --git a/system/database/drivers/pdo/pdo_utility.php b/system/database/drivers/pdo/pdo_utility.php
new file mode 100644
index 000000000..50b9746de
--- /dev/null
+++ b/system/database/drivers/pdo/pdo_utility.php
@@ -0,0 +1,103 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.1.6 or newer
+ *
+ * @package CodeIgniter
+ * @author ExpressionEngine Dev Team
+ * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 2.1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * PDO Utility Class
+ *
+ * @category Database
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/database/
+ */
+class CI_DB_pdo_utility extends CI_DB_utility {
+
+ /**
+ * List databases
+ *
+ * @access private
+ * @return bool
+ */
+ function _list_databases()
+ {
+ // Not sure if PDO lets you list all databases...
+ if ($this->db->db_debug)
+ {
+ return $this->db->display_error('db_unsuported_feature');
+ }
+ return FALSE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Optimize table query
+ *
+ * Generates a platform-specific query so that a table can be optimized
+ *
+ * @access private
+ * @param string the table name
+ * @return object
+ */
+ function _optimize_table($table)
+ {
+ // Not a supported PDO feature
+ if ($this->db->db_debug)
+ {
+ return $this->db->display_error('db_unsuported_feature');
+ }
+ return FALSE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Repair table query
+ *
+ * Generates a platform-specific query so that a table can be repaired
+ *
+ * @access private
+ * @param string the table name
+ * @return object
+ */
+ function _repair_table($table)
+ {
+ // Not a supported PDO feature
+ if ($this->db->db_debug)
+ {
+ return $this->db->display_error('db_unsuported_feature');
+ }
+ return FALSE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * PDO Export
+ *
+ * @access private
+ * @param array Preferences
+ * @return mixed
+ */
+ function _backup($params = array())
+ {
+ // Currently unsupported
+ return $this->db->display_error('db_unsuported_feature');
+ }
+
+}
+
+/* End of file pdo_utility.php */
+/* Location: ./system/database/drivers/pdo/pdo_utility.php */ \ No newline at end of file
diff --git a/system/helpers/date_helper.php b/system/helpers/date_helper.php
index 553e8d7ee..e14bc2f94 100644
--- a/system/helpers/date_helper.php
+++ b/system/helpers/date_helper.php
@@ -54,10 +54,8 @@ if ( ! function_exists('now'))
return $system_time;
}
- else
- {
- return time();
- }
+
+ return time();
}
}
@@ -85,12 +83,18 @@ if ( ! function_exists('mdate'))
function mdate($datestr = '', $time = '')
{
if ($datestr == '')
- return '';
+ {
+ return '';
+ }
- if ($time == '')
- $time = now();
+ $time = ($time == '') ? now() : $time;
+
+ $datestr = str_replace(
+ '%\\',
+ '',
+ preg_replace("/([a-z]+?){1}/i", "\\\\\\1", $datestr)
+ );
- $datestr = str_replace('%\\', '', preg_replace("/([a-z]+?){1}/i", "\\\\\\1", $datestr));
return date($datestr, $time);
}
}
@@ -162,14 +166,7 @@ if ( ! function_exists('timespan'))
$time = time();
}
- if ($time <= $seconds)
- {
- $seconds = 1;
- }
- else
- {
- $seconds = $time - $seconds;
- }
+ $seconds = ($time <= $seconds) ? 1 : $time - $seconds;
$str = '';
$years = floor($seconds / 31536000);
@@ -303,9 +300,18 @@ if ( ! function_exists('local_to_gmt'))
function local_to_gmt($time = '')
{
if ($time == '')
+ {
$time = time();
-
- return mktime( gmdate("H", $time), gmdate("i", $time), gmdate("s", $time), gmdate("m", $time), gmdate("d", $time), gmdate("Y", $time));
+ }
+
+ return mktime(
+ gmdate("H", $time),
+ gmdate("i", $time),
+ gmdate("s", $time),
+ gmdate("m", $time),
+ gmdate("d", $time),
+ gmdate("Y", $time)
+ );
}
}
@@ -366,14 +372,14 @@ if ( ! function_exists('mysql_to_unix'))
$time = str_replace(' ', '', $time);
// YYYYMMDDHHMMSS
- return mktime(
- substr($time, 8, 2),
- substr($time, 10, 2),
- substr($time, 12, 2),
- substr($time, 4, 2),
- substr($time, 6, 2),
- substr($time, 0, 4)
- );
+ return mktime(
+ substr($time, 8, 2),
+ substr($time, 10, 2),
+ substr($time, 12, 2),
+ substr($time, 4, 2),
+ substr($time, 6, 2),
+ substr($time, 0, 4)
+ );
}
}
@@ -475,13 +481,19 @@ if ( ! function_exists('human_to_unix'))
$ampm = strtolower($split['2']);
if (substr($ampm, 0, 1) == 'p' AND $hour < 12)
- $hour = $hour + 12;
+ {
+ $hour = $hour + 12;
+ }
if (substr($ampm, 0, 1) == 'a' AND $hour == 12)
+ {
$hour = '00';
-
+ }
+
if (strlen($hour) == 1)
- $hour = '0'.$hour;
+ {
+ $hour = '0'.$hour;
+ }
}
return mktime($hour, $min, $sec, $month, $day, $year);
@@ -491,6 +503,73 @@ if ( ! function_exists('human_to_unix'))
// ------------------------------------------------------------------------
/**
+ * Turns many "reasonably-date-like" strings into something
+ * that is actually useful. This only works for dates after unix epoch.
+ *
+ * @access public
+ * @param string The terribly formatted date-like string
+ * @param string Date format to return (same as php date function)
+ * @return string
+ */
+if ( ! function_exists('nice_date'))
+{
+ function nice_date($bad_date = '', $format = FALSE)
+ {
+ if (empty($bad_date))
+ {
+ return 'Unknown';
+ }
+
+ // Date like: YYYYMM
+ if (preg_match('/^\d{6}$/', $bad_date))
+ {
+ if (in_array(substr($bad_date, 0, 2),array('19', '20')))
+ {
+ $year = substr($bad_date, 0, 4);
+ $month = substr($bad_date, 4, 2);
+ }
+ else
+ {
+ $month = substr($bad_date, 0, 2);
+ $year = substr($bad_date, 2, 4);
+ }
+
+ return date($format, strtotime($year . '-' . $month . '-01'));
+ }
+
+ // Date Like: YYYYMMDD
+ if (preg_match('/^\d{8}$/',$bad_date))
+ {
+ $month = substr($bad_date, 0, 2);
+ $day = substr($bad_date, 2, 2);
+ $year = substr($bad_date, 4, 4);
+
+ return date($format, strtotime($month . '/01/' . $year));
+ }
+
+ // Date Like: MM-DD-YYYY __or__ M-D-YYYY (or anything in between)
+ if (preg_match('/^\d{1,2}-\d{1,2}-\d{4}$/',$bad_date))
+ {
+ list($m, $d, $y) = explode('-', $bad_date);
+ return date($format, strtotime("{$y}-{$m}-{$d}"));
+ }
+
+ // Any other kind of string, when converted into UNIX time,
+ // produces "0 seconds after epoc..." is probably bad...
+ // return "Invalid Date".
+ if (date('U', strtotime($bad_date)) == '0')
+ {
+ return "Invalid Date";
+ }
+
+ // It's probably a valid-ish date format already
+ return date($format, strtotime($bad_date));
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
* Timezone Menu
*
* Generates a drop-down menu of timezones.
@@ -508,8 +587,7 @@ if ( ! function_exists('timezone_menu'))
$CI =& get_instance();
$CI->lang->load('date');
- if ($default == 'GMT')
- $default = 'UTC';
+ $default = ($default == 'GMT') ? 'UTC' : $default;
$menu = '<select name="'.$name.'"';
@@ -552,60 +630,58 @@ if ( ! function_exists('timezones'))
// some items appear to be in the wrong order
$zones = array(
- 'UM12' => -12,
- 'UM11' => -11,
- 'UM10' => -10,
- 'UM95' => -9.5,
- 'UM9' => -9,
- 'UM8' => -8,
- 'UM7' => -7,
- 'UM6' => -6,
- 'UM5' => -5,
- 'UM45' => -4.5,
- 'UM4' => -4,
- 'UM35' => -3.5,
- 'UM3' => -3,
- 'UM2' => -2,
- 'UM1' => -1,
- 'UTC' => 0,
- 'UP1' => +1,
- 'UP2' => +2,
- 'UP3' => +3,
- 'UP35' => +3.5,
- 'UP4' => +4,
- 'UP45' => +4.5,
- 'UP5' => +5,
- 'UP55' => +5.5,
- 'UP575' => +5.75,
- 'UP6' => +6,
- 'UP65' => +6.5,
- 'UP7' => +7,
- 'UP8' => +8,
- 'UP875' => +8.75,
- 'UP9' => +9,
- 'UP95' => +9.5,
- 'UP10' => +10,
- 'UP105' => +10.5,
- 'UP11' => +11,
- 'UP115' => +11.5,
- 'UP12' => +12,
- 'UP1275' => +12.75,
- 'UP13' => +13,
- 'UP14' => +14
- );
+ 'UM12' => -12,
+ 'UM11' => -11,
+ 'UM10' => -10,
+ 'UM95' => -9.5,
+ 'UM9' => -9,
+ 'UM8' => -8,
+ 'UM7' => -7,
+ 'UM6' => -6,
+ 'UM5' => -5,
+ 'UM45' => -4.5,
+ 'UM4' => -4,
+ 'UM35' => -3.5,
+ 'UM3' => -3,
+ 'UM2' => -2,
+ 'UM1' => -1,
+ 'UTC' => 0,
+ 'UP1' => +1,
+ 'UP2' => +2,
+ 'UP3' => +3,
+ 'UP35' => +3.5,
+ 'UP4' => +4,
+ 'UP45' => +4.5,
+ 'UP5' => +5,
+ 'UP55' => +5.5,
+ 'UP575' => +5.75,
+ 'UP6' => +6,
+ 'UP65' => +6.5,
+ 'UP7' => +7,
+ 'UP8' => +8,
+ 'UP875' => +8.75,
+ 'UP9' => +9,
+ 'UP95' => +9.5,
+ 'UP10' => +10,
+ 'UP105' => +10.5,
+ 'UP11' => +11,
+ 'UP115' => +11.5,
+ 'UP12' => +12,
+ 'UP1275' => +12.75,
+ 'UP13' => +13,
+ 'UP14' => +14
+ );
if ($tz == '')
{
return $zones;
}
-
- if ($tz == 'GMT')
- $tz = 'UTC';
-
+
+ $tz = ($tz == 'GMT') ? 'UTC' : $tz;
+
return ( ! isset($zones[$tz])) ? 0 : $zones[$tz];
}
}
-
/* End of file date_helper.php */
/* Location: ./system/helpers/date_helper.php */ \ No newline at end of file
diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php
index d9305c00b..130daee6a 100644
--- a/system/helpers/form_helper.php
+++ b/system/helpers/form_helper.php
@@ -642,11 +642,8 @@ if ( ! function_exists('form_prep'))
{
return $str;
}
-
- $str = htmlspecialchars($str);
-
- // In case htmlspecialchars misses these.
- $str = str_replace(array("'", '"'), array("&#39;", "&quot;"), $str);
+
+ $str = html_escape($str);
if ($field_name != '')
{
diff --git a/system/helpers/html_helper.php b/system/helpers/html_helper.php
index b64b60650..10a288e6a 100644
--- a/system/helpers/html_helper.php
+++ b/system/helpers/html_helper.php
@@ -365,7 +365,7 @@ if ( ! function_exists('link_tag'))
$link .= '/>';
}
-
+ $link .= "\n";
return $link;
}
diff --git a/system/helpers/string_helper.php b/system/helpers/string_helper.php
index 9fa69f46c..dd8ffaddb 100644
--- a/system/helpers/string_helper.php
+++ b/system/helpers/string_helper.php
@@ -215,12 +215,9 @@ if ( ! function_exists('random_string'))
case 'nozero' : $pool = '123456789';
break;
}
-
- $str = '';
- for ($i=0; $i < $len; $i++)
- {
- $str .= substr($pool, mt_rand(0, strlen($pool) -1), 1);
- }
+
+ $str = substr(str_shuffle(str_repeat($pool, ceil($len/strlen($pool)))),0,$len);
+
return $str;
break;
case 'unique' :
diff --git a/system/helpers/typography_helper.php b/system/helpers/typography_helper.php
index 19b4eec03..e8cb037a8 100644
--- a/system/helpers/typography_helper.php
+++ b/system/helpers/typography_helper.php
@@ -39,9 +39,7 @@ if ( ! function_exists('nl2br_except_pre'))
function nl2br_except_pre($str)
{
$CI =& get_instance();
-
$CI->load->library('typography');
-
return $CI->typography->nl2br_except_pre($str);
}
}
@@ -78,11 +76,12 @@ if ( ! function_exists('auto_typography'))
*
* @access public
* @param string
+ * @param string
* @return string
*/
if ( ! function_exists('entity_decode'))
{
- function entity_decode($str, $charset='UTF-8')
+ function entity_decode($str, $charset = NULL)
{
global $SEC;
return $SEC->entity_decode($str, $charset);
diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php
index 9f4b85248..c524dddd1 100644..100755
--- a/system/helpers/url_helper.php
+++ b/system/helpers/url_helper.php
@@ -512,7 +512,7 @@ if ( ! function_exists('url_title'))
$str = strtolower($str);
}
- return trim(stripslashes($str));
+ return trim(trim(stripslashes($str)), $replace);
}
}
@@ -527,7 +527,7 @@ if ( ! function_exists('url_title'))
*
* @access public
* @param string the URL
- * @param string the method: location or redirect
+ * @param string the method: location or refresh
* @return string
*/
if ( ! function_exists('redirect'))
diff --git a/system/language/english/migration_lang.php b/system/language/english/migration_lang.php
index 4763ca243..94cb882fb 100644
--- a/system/language/english/migration_lang.php
+++ b/system/language/english/migration_lang.php
@@ -5,7 +5,7 @@ $lang['migration_not_found'] = "This migration could not be found.";
$lang['migration_multiple_version'] = "This are multiple migrations with the same version number: %d.";
$lang['migration_class_doesnt_exist'] = "The migration class \"%s\" could not be found.";
$lang['migration_missing_up_method'] = "The migration class \"%s\" is missing an 'up' method.";
-$lang['migration_missing_down_method'] = "The migration class \"%s\" is missing an 'up' method.";
+$lang['migration_missing_down_method'] = "The migration class \"%s\" is missing a 'down' method.";
$lang['migration_invalid_filename'] = "Migration \"%s\" has an invalid filename.";
diff --git a/system/libraries/Cache/drivers/Cache_file.php b/system/libraries/Cache/drivers/Cache_file.php
index 6c37e7005..2a89faf09 100644
--- a/system/libraries/Cache/drivers/Cache_file.php
+++ b/system/libraries/Cache/drivers/Cache_file.php
@@ -107,7 +107,14 @@ class CI_Cache_file extends CI_Driver {
*/
public function delete($id)
{
- return unlink($this->_cache_path.$id);
+ if (file_exists($this->_cache_path.$id))
+ {
+ return unlink($this->_cache_path.$id);
+ }
+ else
+ {
+ return FALSE;
+ }
}
// ------------------------------------------------------------------------
@@ -192,4 +199,4 @@ class CI_Cache_file extends CI_Driver {
// End Class
/* End of file Cache_file.php */
-/* Location: ./system/libraries/Cache/drivers/Cache_file.php */ \ No newline at end of file
+/* Location: ./system/libraries/Cache/drivers/Cache_file.php */
diff --git a/system/libraries/Cache/drivers/Cache_memcached.php b/system/libraries/Cache/drivers/Cache_memcached.php
index ec2fd216a..95bdcb350 100644
--- a/system/libraries/Cache/drivers/Cache_memcached.php
+++ b/system/libraries/Cache/drivers/Cache_memcached.php
@@ -10,19 +10,19 @@
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 2.0
- * @filesource
+ * @filesource
*/
// ------------------------------------------------------------------------
/**
- * CodeIgniter Memcached Caching Class
+ * CodeIgniter Memcached Caching Class
*
* @package CodeIgniter
* @subpackage Libraries
* @category Core
* @author ExpressionEngine Dev Team
- * @link
+ * @link
*/
class CI_Cache_memcached extends CI_Driver {
@@ -37,18 +37,18 @@ class CI_Cache_memcached extends CI_Driver {
)
);
- // ------------------------------------------------------------------------
+ // ------------------------------------------------------------------------
/**
* Fetch from cache
*
* @param mixed unique key id
* @return mixed data on success/false on failure
- */
+ */
public function get($id)
- {
+ {
$data = $this->_memcached->get($id);
-
+
return (is_array($data)) ? $data[0] : FALSE;
}
@@ -64,11 +64,20 @@ class CI_Cache_memcached extends CI_Driver {
*/
public function save($id, $data, $ttl = 60)
{
- return $this->_memcached->add($id, array($data, time(), $ttl), $ttl);
+ if (get_class($this->_memcached) == 'Memcached')
+ {
+ return $this->_memcached->set($id, array($data, time(), $ttl), $ttl);
+ }
+ else if (get_class($this->_memcached) == 'Memcache')
+ {
+ return $this->_memcached->set($id, array($data, time(), $ttl), 0, $ttl);
+ }
+
+ return FALSE;
}
// ------------------------------------------------------------------------
-
+
/**
* Delete from Cache
*
@@ -81,7 +90,7 @@ class CI_Cache_memcached extends CI_Driver {
}
// ------------------------------------------------------------------------
-
+
/**
* Clean the Cache
*
@@ -106,7 +115,7 @@ class CI_Cache_memcached extends CI_Driver {
}
// ------------------------------------------------------------------------
-
+
/**
* Get Cache Metadata
*
@@ -140,6 +149,7 @@ class CI_Cache_memcached extends CI_Driver {
{
// Try to load memcached server info from the config file.
$CI =& get_instance();
+
if ($CI->config->load('memcached', TRUE, TRUE))
{
if (is_array($CI->config->config['memcached']))
@@ -149,11 +159,24 @@ class CI_Cache_memcached extends CI_Driver {
foreach ($CI->config->config['memcached'] as $name => $conf)
{
$this->_memcache_conf[$name] = $conf;
- }
- }
+ }
+ }
+ }
+
+ if (class_exists('Memcached'))
+ {
+ $this->_memcached = new Memcached();
+ }
+ else if (class_exists('Memcache'))
+ {
+ $this->_memcached = new Memcache();
+ }
+ else
+ {
+ log_message('error', 'Failed to create object for Memcached Cache; extension not loaded?');
+
+ return FALSE;
}
-
- $this->_memcached = new Memcached();
foreach ($this->_memcache_conf as $name => $cache_server)
{
@@ -161,26 +184,42 @@ class CI_Cache_memcached extends CI_Driver {
{
$cache_server['hostname'] = $this->_default_options['default_host'];
}
-
+
if ( ! array_key_exists('port', $cache_server))
{
$cache_server['port'] = $this->_default_options['default_port'];
}
-
+
if ( ! array_key_exists('weight', $cache_server))
{
$cache_server['weight'] = $this->_default_options['default_weight'];
}
-
- $this->_memcached->addServer(
- $cache_server['hostname'], $cache_server['port'], $cache_server['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
*
@@ -189,15 +228,14 @@ class CI_Cache_memcached extends CI_Driver {
*/
public function is_supported()
{
- if ( ! extension_loaded('memcached'))
+ if ( ! extension_loaded('memcached') && ! extension_loaded('memcache'))
{
log_message('error', 'The Memcached Extension must be loaded to use Memcached Cache.');
-
+
return FALSE;
}
-
- $this->_setup_memcached();
- return TRUE;
+
+ return $this->_setup_memcached();
}
// ------------------------------------------------------------------------
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index e28c23a04..ef20e1978 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -36,6 +36,7 @@ class CI_Email {
var $smtp_pass = ""; // SMTP Password
var $smtp_port = "25"; // SMTP Port
var $smtp_timeout = 5; // SMTP Timeout in seconds
+ var $smtp_crypto = ""; // SMTP Encryption. Can be null, tls or ssl.
var $wordwrap = TRUE; // TRUE/FALSE Turns word-wrap on/off
var $wrapchars = "76"; // Number of characters to wrap at.
var $mailtype = "text"; // text/html Defines email formatting
@@ -138,6 +139,7 @@ class CI_Email {
* Initialize the Email Data
*
* @access public
+ * @param bool
* @return void
*/
public function clear($clear_attachments = FALSE)
@@ -452,7 +454,7 @@ class CI_Email {
*/
public function set_alt_message($str = '')
{
- $this->alt_message = $str;
+ $this->alt_message = (string) $str;
return $this;
}
@@ -477,12 +479,12 @@ class CI_Email {
* Set Wordwrap
*
* @access public
- * @param string
+ * @param bool
* @return void
*/
public function set_wordwrap($wordwrap = TRUE)
{
- $this->wordwrap = ($wordwrap === FALSE) ? FALSE : TRUE;
+ $this->wordwrap = (bool) $wordwrap;
return $this;
}
@@ -1666,7 +1668,14 @@ class CI_Email {
*/
protected function _smtp_connect()
{
- $this->_smtp_connect = fsockopen($this->smtp_host,
+ $ssl = NULL;
+
+ if ($this->smtp_crypto == 'ssl')
+ {
+ $ssl = 'ssl://';
+ }
+
+ $this->_smtp_connect = fsockopen($ssl.$this->smtp_host,
$this->smtp_port,
$errno,
$errstr,
@@ -1679,6 +1688,20 @@ class CI_Email {
}
$this->_set_error_message($this->_get_smtp_data());
+
+ if ($this->smtp_crypto == 'tls')
+ {
+ $this->_send_command('hello');
+ $this->_send_command('starttls');
+ $crypto = stream_socket_enable_crypto($this->_smtp_connect, TRUE, STREAM_CRYPTO_METHOD_TLS_CLIENT);
+ }
+
+ if ($crypto !== TRUE)
+ {
+ $this->_set_error_message('lang:email_smtp_error', $this->_get_smtp_data());
+ return FALSE;
+ }
+
return $this->_send_command('hello');
}
@@ -1705,6 +1728,12 @@ class CI_Email {
$resp = 250;
break;
+ case 'starttls' :
+
+ $this->_send_data('STARTTLS');
+
+ $resp = 220;
+ break;
case 'from' :
$this->_send_data('MAIL FROM:<'.$data.'>');
diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php
index a34809e05..c78583f4f 100644
--- a/system/libraries/Form_validation.php
+++ b/system/libraries/Form_validation.php
@@ -1079,7 +1079,7 @@ class CI_Form_validation {
*
* @access public
* @param string
- * @return string
+ * @return bool
*/
public function valid_ip($ip)
{
diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php
index 8902f524d..a8a0387d8 100644
--- a/system/libraries/Image_lib.php
+++ b/system/libraries/Image_lib.php
@@ -1334,7 +1334,7 @@ class CI_Image_lib {
return FALSE;
}
- $vals = @getimagesize($path);
+ $vals = getimagesize($path);
$types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');
diff --git a/system/libraries/Log.php b/system/libraries/Log.php
index 9f1db76ba..bf10d4727 100644
--- a/system/libraries/Log.php
+++ b/system/libraries/Log.php
@@ -27,10 +27,12 @@
class CI_Log {
protected $_log_path;
- protected $_threshold = 1;
- protected $_date_fmt = 'Y-m-d H:i:s';
- protected $_enabled = TRUE;
- protected $_levels = array('ERROR' => '1', 'DEBUG' => '2', 'INFO' => '3', 'ALL' => '4');
+ protected $_threshold = 1;
+ protected $_threshold_max = 0;
+ protected $_threshold_array = array();
+ protected $_date_fmt = 'Y-m-d H:i:s';
+ protected $_enabled = TRUE;
+ protected $_levels = array('ERROR' => '1', 'DEBUG' => '2', 'INFO' => '3', 'ALL' => '4');
/**
* Constructor
@@ -50,6 +52,11 @@ class CI_Log {
{
$this->_threshold = $config['log_threshold'];
}
+ elseif (is_array($config['log_threshold']))
+ {
+ $this->_threshold = $this->_threshold_max;
+ $this->_threshold_array = array_flip($config['log_threshold']);
+ }
if ($config['log_date_format'] != '')
{
@@ -80,9 +87,13 @@ class CI_Log {
if ( ! isset($this->_levels[$level]) OR ($this->_levels[$level] > $this->_threshold))
{
- return FALSE;
+ if (empty($this->_threshold_array) OR ! isset($this->_threshold_array[$this->_levels[$level]]))
+ {
+ return FALSE;
+ }
}
+
$filepath = $this->_log_path.'log-'.date('Y-m-d').'.php';
$message = '';
diff --git a/system/libraries/Migration.php b/system/libraries/Migration.php
index 3943ec130..840cefe08 100644
--- a/system/libraries/Migration.php
+++ b/system/libraries/Migration.php
@@ -32,7 +32,9 @@ class CI_Migration {
protected $_migration_enabled = FALSE;
protected $_migration_path = NULL;
protected $_migration_version = 0;
-
+ protected $_migration_table = 'migrations';
+ protected $_migration_auto_latest = FALSE;
+
protected $_error_string = '';
public function __construct($config = array())
@@ -57,7 +59,7 @@ class CI_Migration {
}
// If not set, set it
- $this->_migration_path == '' OR $this->_migration_path = APPPATH . 'migrations/';
+ $this->_migration_path == '' AND $this->_migration_path = APPPATH . 'migrations/';
// Add trailing slash if not set
$this->_migration_path = rtrim($this->_migration_path, '/').'/';
@@ -68,16 +70,31 @@ class CI_Migration {
// They'll probably be using dbforge
$this->load->dbforge();
+ // Make sure the migration table name was set.
+ if (empty($this->_migration_table))
+ {
+ show_error('Migrations configuration file (migration.php) must have "migration_table" set.');
+ }
+
// If the migrations table is missing, make it
- if ( ! $this->db->table_exists('migrations'))
+ if ( ! $this->db->table_exists($this->_migration_table))
{
$this->dbforge->add_field(array(
'version' => array('type' => 'INT', 'constraint' => 3),
));
- $this->dbforge->create_table('migrations', TRUE);
+ $this->dbforge->create_table($this->_migration_table, TRUE);
- $this->db->insert('migrations', array('version' => 0));
+ $this->db->insert($this->_migration_table, array('version' => 0));
+ }
+
+ // Do we auto migrate to the latest migration?
+ if ( $this->_migration_auto_latest == TRUE )
+ {
+ if ( ! $this->latest() )
+ {
+ show_error($this->error_string());
+ }
}
}
@@ -299,7 +316,7 @@ class CI_Migration {
*/
protected function _get_version()
{
- $row = $this->db->get('migrations')->row();
+ $row = $this->db->get($this->_migration_table)->row();
return $row ? $row->version : 0;
}
@@ -314,7 +331,7 @@ class CI_Migration {
*/
protected function _update_version($migrations)
{
- return $this->db->update('migrations', array(
+ return $this->db->update($this->_migration_table, array(
'version' => $migrations
));
}
diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php
index cc62e660b..eff754a1b 100644
--- a/system/libraries/Pagination.php
+++ b/system/libraries/Pagination.php
@@ -34,6 +34,7 @@ class CI_Pagination {
var $per_page = 10; // Max number of items you want shown per page
var $num_links = 2; // Number of "digit" links to show before/after the currently viewed page
var $cur_page = 0; // The current page being viewed
+ var $use_page_numbers = FALSE; // Use page number for segment instead of offset
var $first_link = '&lsaquo; First';
var $next_link = '&gt;';
var $prev_link = '&lt;';
@@ -128,12 +129,15 @@ class CI_Pagination {
return '';
}
+ // Set the base page index for starting page number
+ $base_page = ($this->use_page_numbers) ? 1 : 0;
+
// Determine the current page number.
$CI =& get_instance();
if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE)
{
- if ($CI->input->get($this->query_string_segment) != 0)
+ if ($CI->input->get($this->query_string_segment) != $base_page)
{
$this->cur_page = $CI->input->get($this->query_string_segment);
@@ -143,7 +147,7 @@ class CI_Pagination {
}
else
{
- if ($CI->uri->segment($this->uri_segment) != 0)
+ if ($CI->uri->segment($this->uri_segment) != $base_page)
{
$this->cur_page = $CI->uri->segment($this->uri_segment);
@@ -151,6 +155,12 @@ class CI_Pagination {
$this->cur_page = (int) $this->cur_page;
}
}
+
+ // Set current page to 1 if using page numbers instead of offset
+ if ($this->use_page_numbers AND $this->cur_page == 0)
+ {
+ $this->cur_page = $base_page;
+ }
$this->num_links = (int)$this->num_links;
@@ -161,18 +171,32 @@ class CI_Pagination {
if ( ! is_numeric($this->cur_page))
{
- $this->cur_page = 0;
+ $this->cur_page = $base_page;
}
// Is the page number beyond the result range?
// If so we show the last page
- if ($this->cur_page > $this->total_rows)
+ if ($this->use_page_numbers)
{
- $this->cur_page = ($num_pages - 1) * $this->per_page;
+ if ($this->cur_page > $num_pages)
+ {
+ $this->cur_page = $num_pages;
+ }
+ }
+ else
+ {
+ if ($this->cur_page > $this->total_rows)
+ {
+ $this->cur_page = ($num_pages - 1) * $this->per_page;
+ }
}
$uri_page_number = $this->cur_page;
- $this->cur_page = floor(($this->cur_page/$this->per_page) + 1);
+
+ if ( ! $this->use_page_numbers)
+ {
+ $this->cur_page = floor(($this->cur_page/$this->per_page) + 1);
+ }
// Calculate the start and end numbers. These determine
// which number to start and end the digit links with
@@ -203,9 +227,9 @@ class CI_Pagination {
// Render the "previous" link
if ($this->prev_link !== FALSE AND $this->cur_page != 1)
{
- $i = $uri_page_number - $this->per_page;
+ $i = ($this->use_page_numbers) ? $uri_page_number - 1 : $uri_page_number - $this->per_page;
- if ($i == 0 && $this->first_url != '')
+ if (($i == 0 OR ($this->use_page_numbers && $i == 1)) AND $this->first_url != '')
{
$output .= $this->prev_tag_open.'<a '.$this->anchor_class.'href="'.$this->first_url.'">'.$this->prev_link.'</a>'.$this->prev_tag_close;
}
@@ -223,9 +247,9 @@ class CI_Pagination {
// Write the digit links
for ($loop = $start -1; $loop <= $end; $loop++)
{
- $i = ($loop * $this->per_page) - $this->per_page;
+ $i = ($this->use_page_numbers) ? $loop : ($loop * $this->per_page) - $this->per_page;
- if ($i >= 0)
+ if ($i >= $base_page)
{
if ($this->cur_page == $loop)
{
@@ -233,7 +257,7 @@ class CI_Pagination {
}
else
{
- $n = ($i == 0) ? '' : $i;
+ $n = ($i == $base_page) ? '' : $i;
if ($n == '' && $this->first_url != '')
{
@@ -253,13 +277,16 @@ class CI_Pagination {
// Render the "next" link
if ($this->next_link !== FALSE AND $this->cur_page < $num_pages)
{
- $output .= $this->next_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$this->prefix.($this->cur_page * $this->per_page).$this->suffix.'">'.$this->next_link.'</a>'.$this->next_tag_close;
+ $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;
}
// Render the "Last" link
if ($this->last_link !== FALSE AND ($this->cur_page + $this->num_links) < $num_pages)
{
- $i = (($num_pages * $this->per_page) - $this->per_page);
+ $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;
}
diff --git a/system/libraries/Profiler.php b/system/libraries/Profiler.php
index 082a5ee1d..ac58129a9 100644
--- a/system/libraries/Profiler.php
+++ b/system/libraries/Profiler.php
@@ -493,7 +493,7 @@ class CI_Profiler {
*
* @return string
*/
- private function _compile_session_data()
+ protected function _compile_session_data()
{
if ( ! isset($this->CI->session))
{
@@ -506,7 +506,7 @@ class CI_Profiler {
foreach ($this->CI->session->all_userdata() as $key => $val)
{
- if (is_array($val))
+ if (is_array($val) || is_object($val))
{
$val = print_r($val, TRUE);
}
@@ -555,4 +555,4 @@ class CI_Profiler {
// END CI_Profiler class
/* End of file Profiler.php */
-/* Location: ./system/libraries/Profiler.php */ \ No newline at end of file
+/* Location: ./system/libraries/Profiler.php */
diff --git a/system/libraries/Session.php b/system/libraries/Session.php
index 2c8a80163..8ee08c5b2 100644
--- a/system/libraries/Session.php
+++ b/system/libraries/Session.php
@@ -317,7 +317,8 @@ class CI_Session {
'session_id' => md5(uniqid($sessid, TRUE)),
'ip_address' => $this->CI->input->ip_address(),
'user_agent' => substr($this->CI->input->user_agent(), 0, 120),
- 'last_activity' => $this->now
+ 'last_activity' => $this->now,
+ 'user_data' => ''
);
diff --git a/system/libraries/Sha1.php b/system/libraries/Sha1.php
index 1a657572b..8e991f54a 100644
--- a/system/libraries/Sha1.php
+++ b/system/libraries/Sha1.php
@@ -40,7 +40,7 @@
* @subpackage Libraries
* @category Encryption
* @author ExpressionEngine Dev Team
- * @link http://codeigniter.com/user_guide/general/encryption.html
+ * @link http://codeigniter.com/user_guide/libraries/encryption.html
*/
class CI_SHA1 {
@@ -248,4 +248,4 @@ class CI_SHA1 {
// END CI_SHA
/* End of file Sha1.php */
-/* Location: ./system/libraries/Sha1.php */ \ No newline at end of file
+/* Location: ./system/libraries/Sha1.php */
diff --git a/system/libraries/Table.php b/system/libraries/Table.php
index def696776..c14da727e 100644
--- a/system/libraries/Table.php
+++ b/system/libraries/Table.php
@@ -24,7 +24,7 @@
* @subpackage Libraries
* @category HTML Tables
* @author ExpressionEngine Dev Team
- * @link http://codeigniter.com/user_guide/libraries/uri.html
+ * @link http://codeigniter.com/user_guide/libraries/table.html
*/
class CI_Table {
@@ -528,4 +528,4 @@ class CI_Table {
/* End of file Table.php */
-/* Location: ./system/libraries/Table.php */ \ No newline at end of file
+/* Location: ./system/libraries/Table.php */
diff --git a/system/libraries/Typography.php b/system/libraries/Typography.php
index 734cec104..f061311b0 100644
--- a/system/libraries/Typography.php
+++ b/system/libraries/Typography.php
@@ -22,7 +22,7 @@
* @access private
* @category Helpers
* @author ExpressionEngine Dev Team
- * @link http://codeigniter.com/user_guide/helpers/
+ * @link http://codeigniter.com/user_guide/libraries/typography.html
*/
class CI_Typography {
@@ -407,4 +407,4 @@ class CI_Typography {
// END Typography Class
/* End of file Typography.php */
-/* Location: ./system/libraries/Typography.php */ \ No newline at end of file
+/* Location: ./system/libraries/Typography.php */
diff --git a/system/libraries/Unit_test.php b/system/libraries/Unit_test.php
index 5bd7e801a..d9bc8ef6b 100644
--- a/system/libraries/Unit_test.php
+++ b/system/libraries/Unit_test.php
@@ -24,7 +24,7 @@
* @subpackage Libraries
* @category UnitTesting
* @author ExpressionEngine Dev Team
- * @link http://codeigniter.com/user_guide/libraries/uri.html
+ * @link http://codeigniter.com/user_guide/libraries/unit_testing.html
*/
class CI_Unit_test {
@@ -380,4 +380,4 @@ function is_false($test)
/* End of file Unit_test.php */
-/* Location: ./system/libraries/Unit_test.php */ \ No newline at end of file
+/* Location: ./system/libraries/Unit_test.php */
diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php
index 3177424c4..045283f96 100644
--- a/system/libraries/Upload.php
+++ b/system/libraries/Upload.php
@@ -30,6 +30,7 @@ class CI_Upload {
public $max_width = 0;
public $max_height = 0;
public $max_filename = 0;
+ public $max_filename_increment = 100;
public $allowed_types = "";
public $file_temp = "";
public $file_name = "";
@@ -80,31 +81,32 @@ class CI_Upload {
public function initialize($config = array())
{
$defaults = array(
- 'max_size' => 0,
- 'max_width' => 0,
- 'max_height' => 0,
- 'max_filename' => 0,
- 'allowed_types' => "",
- 'file_temp' => "",
- 'file_name' => "",
- 'orig_name' => "",
- 'file_type' => "",
- 'file_size' => "",
- 'file_ext' => "",
- 'upload_path' => "",
- 'overwrite' => FALSE,
- 'encrypt_name' => FALSE,
- 'is_image' => FALSE,
- 'image_width' => '',
- 'image_height' => '',
- 'image_type' => '',
- 'image_size_str' => '',
- 'error_msg' => array(),
- 'mimes' => array(),
- 'remove_spaces' => TRUE,
- 'xss_clean' => FALSE,
- 'temp_prefix' => "temp_file_",
- 'client_name' => ''
+ 'max_size' => 0,
+ 'max_width' => 0,
+ 'max_height' => 0,
+ 'max_filename' => 0,
+ 'max_filename_increment' => 100,
+ 'allowed_types' => "",
+ 'file_temp' => "",
+ 'file_name' => "",
+ 'orig_name' => "",
+ 'file_type' => "",
+ 'file_size' => "",
+ 'file_ext' => "",
+ 'upload_path' => "",
+ 'overwrite' => FALSE,
+ 'encrypt_name' => FALSE,
+ 'is_image' => FALSE,
+ 'image_width' => '',
+ 'image_height' => '',
+ 'image_type' => '',
+ 'image_size_str' => '',
+ 'error_msg' => array(),
+ 'mimes' => array(),
+ 'remove_spaces' => TRUE,
+ 'xss_clean' => FALSE,
+ 'temp_prefix' => "temp_file_",
+ 'client_name' => ''
);
@@ -196,7 +198,8 @@ class CI_Upload {
// Set the uploaded data as class variables
$this->file_temp = $_FILES[$field]['tmp_name'];
$this->file_size = $_FILES[$field]['size'];
- $this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$field]['type']);
+ $this->_file_mime_type($_FILES[$field]);
+ $this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $this->file_type);
$this->file_type = strtolower(trim(stripslashes($this->file_type), '"'));
$this->file_name = $this->_prep_filename($_FILES[$field]['name']);
$this->file_ext = $this->get_extension($this->file_name);
@@ -402,7 +405,7 @@ class CI_Upload {
$filename = str_replace($this->file_ext, '', $filename);
$new_filename = '';
- for ($i = 1; $i < 100; $i++)
+ for ($i = 1; $i < $this->max_filename_increment; $i++)
{
if ( ! file_exists($path.$filename.$i.$this->file_ext))
{
@@ -1006,8 +1009,69 @@ class CI_Upload {
// --------------------------------------------------------------------
+ /**
+ * File MIME type
+ *
+ * Detects the (actual) MIME type of the uploaded file, if possible.
+ * The input array is expected to be $_FILES[$field]
+ *
+ * @param array
+ * @return void
+ */
+ protected function _file_mime_type($file)
+ {
+ // Use if the Fileinfo extension, if available (only versions above 5.3 support the FILEINFO_MIME_TYPE flag)
+ if (is_php('5.3') && function_exists('finfo_file'))
+ {
+ $finfo = new finfo(FILEINFO_MIME_TYPE);
+ if ($finfo !== FALSE) // This is possible, if there is no magic MIME database file found on the system
+ {
+ $file_type = $finfo->file($file['tmp_name']);
+
+ /* According to the comments section of the PHP manual page,
+ * it is possible that this function returns an empty string
+ * for some files (e.g. if they don't exist in the magic MIME database)
+ */
+ if (strlen($file_type) > 1)
+ {
+ $this->file_type = $file_type;
+ return;
+ }
+ }
+ }
+
+ // Fall back to the deprecated mime_content_type(), if available
+ if (function_exists('mime_content_type'))
+ {
+ $this->file_type = @mime_content_type($file['tmp_name']);
+ return;
+ }
+
+ /* This is an ugly hack, but UNIX-type systems provide a native way to detect the file type,
+ * which is still more secure than depending on the value of $_FILES[$field]['type'].
+ *
+ * Notes:
+ * - a 'W' in the substr() expression bellow, would mean that we're using Windows
+ * - many system admins would disable the exec() function due to security concerns, hence the function_exists() check
+ */
+ if (DIRECTORY_SEPARATOR !== '\\' && function_exists('exec'))
+ {
+ $output = array();
+ @exec('file --brief --mime-type ' . escapeshellarg($file['tmp_path']), $output, $return_code);
+ if ($return_code === 0 && strlen($output[0]) > 0) // A return status code != 0 would mean failed execution
+ {
+ $this->file_type = rtrim($output[0]);
+ return;
+ }
+ }
+
+ $this->file_type = $file['type'];
+ }
+
+ // --------------------------------------------------------------------
+
}
// END Upload Class
/* End of file Upload.php */
-/* Location: ./system/libraries/Upload.php */ \ No newline at end of file
+/* Location: ./system/libraries/Upload.php */
diff --git a/system/libraries/User_agent.php b/system/libraries/User_agent.php
index 0b77a7d42..2cdaf509d 100644
--- a/system/libraries/User_agent.php
+++ b/system/libraries/User_agent.php
@@ -18,7 +18,7 @@
/**
* User Agent Class
*
- * Identifies the platform, browser, robot, or mobile devise of the browsing agent
+ * Identifies the platform, browser, robot, or mobile device of the browsing agent
*
* @package CodeIgniter
* @subpackage Libraries
@@ -546,4 +546,4 @@ class CI_User_agent {
/* End of file User_agent.php */
-/* Location: ./system/libraries/User_agent.php */ \ No newline at end of file
+/* Location: ./system/libraries/User_agent.php */