From 47598daa8c32dbbd72db83dc33f2ce91b3f6f7b0 Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Mon, 12 Apr 2010 18:00:20 +0000 Subject: [PATCH] upgrade to codeigniter 1.7.2 for f12 the notation being now unsupported, this still needs to be taken care of --- application/config/autoload.php | 11 - application/config/config.php | 13 + application/config/doctypes.php | 15 + application/config/mimes.php | 2 +- application/config/smileys.php | 4 +- application/config/user_agents.php | 14 +- application/errors/error_404.php | 1 - codeigniter/Base4.php | 2 +- codeigniter/Base5.php | 2 +- codeigniter/CodeIgniter.php | 12 +- codeigniter/Common.php | 146 +++- codeigniter/Compat.php | 2 +- database/DB.php | 4 +- database/DB_active_rec.php | 76 +- database/DB_cache.php | 2 +- database/DB_driver.php | 111 ++- database/DB_forge.php | 58 +- database/DB_result.php | 2 +- database/DB_utility.php | 6 +- database/drivers/mssql/mssql_driver.php | 80 +- database/drivers/mssql/mssql_forge.php | 2 +- database/drivers/mssql/mssql_result.php | 2 +- database/drivers/mssql/mssql_utility.php | 2 +- database/drivers/mysql/mysql_driver.php | 77 +- database/drivers/mysql/mysql_forge.php | 2 +- database/drivers/mysql/mysql_result.php | 2 +- database/drivers/mysql/mysql_utility.php | 2 +- database/drivers/mysqli/mysqli_driver.php | 93 ++- database/drivers/mysqli/mysqli_forge.php | 2 +- database/drivers/mysqli/mysqli_result.php | 2 +- database/drivers/mysqli/mysqli_utility.php | 2 +- database/drivers/oci8/oci8_driver.php | 74 +- database/drivers/oci8/oci8_forge.php | 2 +- database/drivers/oci8/oci8_result.php | 2 +- database/drivers/oci8/oci8_utility.php | 2 +- database/drivers/odbc/odbc_driver.php | 80 +- database/drivers/odbc/odbc_forge.php | 2 +- database/drivers/odbc/odbc_result.php | 2 +- database/drivers/odbc/odbc_utility.php | 2 +- database/drivers/postgre/postgre_driver.php | 79 +- database/drivers/postgre/postgre_forge.php | 2 +- database/drivers/postgre/postgre_result.php | 2 +- database/drivers/postgre/postgre_utility.php | 2 +- database/drivers/sqlite/sqlite_driver.php | 74 +- database/drivers/sqlite/sqlite_forge.php | 2 +- database/drivers/sqlite/sqlite_result.php | 2 +- database/drivers/sqlite/sqlite_utility.php | 2 +- helpers/array_helper.php | 2 +- helpers/compatibility_helper.php | 2 +- helpers/cookie_helper.php | 12 +- helpers/date_helper.php | 4 +- helpers/directory_helper.php | 12 +- helpers/download_helper.php | 2 +- helpers/email_helper.php | 2 +- helpers/file_helper.php | 31 +- helpers/form_helper.php | 130 ++- helpers/html_helper.php | 104 ++- helpers/inflector_helper.php | 6 +- helpers/language_helper.php | 2 +- helpers/number_helper.php | 2 +- helpers/path_helper.php | 2 +- helpers/security_helper.php | 8 +- helpers/smiley_helper.php | 142 +++- helpers/string_helper.php | 2 +- helpers/text_helper.php | 39 +- helpers/typography_helper.php | 7 +- helpers/url_helper.php | 27 +- helpers/xml_helper.php | 2 +- index.html | 10 + language/english/email_lang.php | 1 + language/english/imglib_lang.php | 1 + libraries/Benchmark.php | 2 +- libraries/Calendar.php | 4 +- libraries/Cart.php | 550 +++++++++++++ libraries/Config.php | 4 +- libraries/Controller.php | 4 +- libraries/Email.php | 584 ++++++++------ libraries/Encrypt.php | 2 +- libraries/Exceptions.php | 8 +- libraries/Form_validation.php | 46 +- libraries/Ftp.php | 196 ++--- libraries/Hooks.php | 60 +- libraries/Image_lib.php | 616 +++++++------- libraries/Input.php | 796 ++++++++++--------- libraries/Language.php | 33 +- libraries/Loader.php | 11 +- libraries/Log.php | 2 +- libraries/Model.php | 2 +- libraries/Output.php | 77 +- libraries/Pagination.php | 44 +- libraries/Parser.php | 2 +- libraries/Profiler.php | 6 +- libraries/Router.php | 28 +- libraries/Session.php | 198 ++--- libraries/Sha1.php | 4 +- libraries/Table.php | 2 +- libraries/Trackback.php | 9 +- libraries/Typography.php | 186 +++-- libraries/URI.php | 150 ++-- libraries/Unit_test.php | 2 +- libraries/Upload.php | 30 +- libraries/User_agent.php | 2 +- libraries/Validation.php | 2 +- libraries/Xmlrpc.php | 30 +- libraries/Xmlrpcs.php | 20 +- libraries/Zip.php | 2 +- plugins/captcha_pi.php | 2 +- plugins/js_calendar_pi.php | 2 +- scaffolding/Scaffolding.php | 2 +- 109 files changed, 3454 insertions(+), 1900 deletions(-) create mode 100644 application/config/doctypes.php create mode 100644 index.html create mode 100644 libraries/Cart.php diff --git a/application/config/autoload.php b/application/config/autoload.php index fc08553..1745d5c 100644 --- a/application/config/autoload.php +++ b/application/config/autoload.php @@ -111,17 +111,6 @@ $autoload['language'] = array(); $autoload['model'] = array(); -/* -| ------------------------------------------------------------------- -| Auto-load Core Libraries -| ------------------------------------------------------------------- -| -| DEPRECATED: Use $autoload['libraries'] above instead. -| -*/ -// $autoload['core'] = array(); - - /* End of file autoload.php */ /* Location: ./system/application/config/autoload.php */ \ No newline at end of file diff --git a/application/config/config.php b/application/config/config.php index d770823..6059915 100644 --- a/application/config/config.php +++ b/application/config/config.php @@ -312,6 +312,19 @@ $config['time_reference'] = 'local'; $config['rewrite_short_tags'] = FALSE; +/* +|-------------------------------------------------------------------------- +| Reverse Proxy IPs +|-------------------------------------------------------------------------- +| +| If your server is behind a reverse proxy, you must whitelist the proxy IP +| addresses from which CodeIgniter should trust the HTTP_X_FORWARDED_FOR +| header in order to properly identify the visitor's IP address. +| Comma-delimited, e.g. '10.0.1.200,10.0.1.201' +| +*/ +$config['proxy_ips'] = ''; + /* End of file config.php */ /* Location: ./system/application/config/config.php */ diff --git a/application/config/doctypes.php b/application/config/doctypes.php new file mode 100644 index 0000000..9d510ab --- /dev/null +++ b/application/config/doctypes.php @@ -0,0 +1,15 @@ + '', + 'xhtml1-strict' => '', + 'xhtml1-trans' => '', + 'xhtml1-frame' => '', + 'html5' => '', + 'html4-strict' => '', + 'html4-trans' => '', + 'html4-frame' => '' + ); + +/* End of file doctypes.php */ +/* Location: application/config/doctypes.php */ \ No newline at end of file diff --git a/application/config/mimes.php b/application/config/mimes.php index 10acfad..438f610 100644 --- a/application/config/mimes.php +++ b/application/config/mimes.php @@ -29,7 +29,7 @@ $mimes = array( 'hqx' => 'application/mac-binhex40', 'smi' => 'application/smil', 'smil' => 'application/smil', 'mif' => 'application/vnd.mif', - 'xls' => array('application/excel', 'application/vnd.ms-excel'), + 'xls' => array('application/excel', 'application/vnd.ms-excel', 'application/msexcel'), 'ppt' => array('application/powerpoint', 'application/vnd.ms-powerpoint'), 'wbxml' => 'application/wbxml', 'wmlc' => 'application/wmlc', diff --git a/application/config/smileys.php b/application/config/smileys.php index b1988cd..7f3aba5 100644 --- a/application/config/smileys.php +++ b/application/config/smileys.php @@ -57,9 +57,9 @@ $smileys = array( ':coolcheese:' => array('shade_cheese.gif', '19', '19', 'cool cheese'), ':vampire:' => array('vampire.gif', '19', '19', 'vampire'), ':snake:' => array('snake.gif', '19', '19', 'snake'), - ':exclaim:' => array('exclaim.gif', '19', '19', 'excaim'), + ':exclaim:' => array('exclaim.gif', '19', '19', 'excaim'), ':question:' => array('question.gif', '19', '19', 'question') // no comma after last item - + ); /* End of file smileys.php */ diff --git a/application/config/user_agents.php b/application/config/user_agents.php index f07f6b9..f15b007 100644 --- a/application/config/user_agents.php +++ b/application/config/user_agents.php @@ -59,8 +59,8 @@ $browsers = array( 'Camino' => 'Camino', 'Netscape' => 'Netscape', 'OmniWeb' => 'OmniWeb', - 'Mozilla' => 'Mozilla', 'Safari' => 'Safari', + 'Mozilla' => 'Mozilla', 'Konqueror' => 'Konqueror', 'icab' => 'iCab', 'Lynx' => 'Lynx', @@ -86,7 +86,7 @@ $mobiles = array( // 'ericsson' => 'Ericsson', // 'blackberry' => 'BlackBerry', // 'motorola' => 'Motorola' - + // Phones and Manufacturers 'motorola' => "Motorola", 'nokia' => "Nokia", @@ -121,7 +121,7 @@ $mobiles = array( 'spv' => "SPV", 'zte' => "ZTE", 'sendo' => "Sendo", - + // Operating Systems 'symbian' => "Symbian", 'SymbianOS' => "SymbianOS", @@ -129,15 +129,15 @@ $mobiles = array( 'palm' => "Palm", 'series60' => "Symbian S60", 'windows ce' => "Windows CE", - - // Browsers + + // Browsers 'obigo' => "Obigo", 'netfront' => "Netfront Browser", 'openwave' => "Openwave Browser", 'mobilexplorer' => "Mobile Explorer", 'operamini' => "Opera Mini", 'opera mini' => "Opera Mini", - + // Other 'digital paths' => "Digital Paths", 'avantgo' => "AvantGo", @@ -146,7 +146,7 @@ $mobiles = array( 'vodafone' => "Vodafone", 'docomo' => "NTT DoCoMo", 'o2' => "O2", - + // Fallback 'mobile' => "Generic Mobile", 'wireless' => "Generic Mobile", diff --git a/application/errors/error_404.php b/application/errors/error_404.php index bfe9444..1c513a2 100644 --- a/application/errors/error_404.php +++ b/application/errors/error_404.php @@ -1,4 +1,3 @@ - 404 Page Not Found diff --git a/codeigniter/Base4.php b/codeigniter/Base4.php index a95c281..91a4350 100644 --- a/codeigniter/Base4.php +++ b/codeigniter/Base4.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.3 diff --git a/codeigniter/Base5.php b/codeigniter/Base5.php index aa90355..a2cca72 100644 --- a/codeigniter/Base5.php +++ b/codeigniter/Base5.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.3 diff --git a/codeigniter/CodeIgniter.php b/codeigniter/CodeIgniter.php index fa4bf77..dac137b 100644 --- a/codeigniter/CodeIgniter.php +++ b/codeigniter/CodeIgniter.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -28,7 +28,7 @@ */ // CI Version -define('CI_VERSION', '1.7.0'); +define('CI_VERSION', '1.7.2'); /* * ------------------------------------------------------ @@ -57,7 +57,11 @@ require(APPPATH.'config/constants'.EXT); * ------------------------------------------------------ */ set_error_handler('_exception_handler'); -set_magic_quotes_runtime(0); // Kill magic quotes + +if ( ! is_php('5.3')) +{ + @set_magic_quotes_runtime(0); // Kill magic quotes +} /* * ------------------------------------------------------ @@ -130,7 +134,7 @@ $LANG =& load_class('Language'); * Note: The Loader class needs to be included first * */ -if (floor(phpversion()) < 5) +if ( ! is_php('5.0.0')) { load_class('Loader', FALSE); require(BASEPATH.'codeigniter/Base4'.EXT); diff --git a/codeigniter/Common.php b/codeigniter/Common.php index 3c75f5e..eb9dce6 100644 --- a/codeigniter/Common.php +++ b/codeigniter/Common.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -16,16 +16,27 @@ // ------------------------------------------------------------------------ /** - * Common Functions - * - * Loads the base classes and executes the request. - * - * @package CodeIgniter - * @subpackage codeigniter - * @category Common Functions - * @author ExpressionEngine Dev Team - * @link http://codeigniter.com/user_guide/ - */ +* Determines if the current version of PHP is greater then the supplied value +* +* Since there are a few places where we conditionally test for PHP > 5 +* we'll set a static variable. +* +* @access public +* @param string +* @return bool +*/ +function is_php($version = '5.0.0') +{ + static $_is_php; + $version = (string)$version; + + if ( ! isset($_is_php[$version])) + { + $_is_php[$version] = (version_compare(PHP_VERSION, $version) < 0) ? FALSE : TRUE; + } + + return $_is_php[$version]; +} // ------------------------------------------------------------------------ @@ -127,16 +138,34 @@ function &load_class($class, $instantiate = TRUE) if ($is_subclass == TRUE) { $name = config_item('subclass_prefix').$class; - $objects[$class] =& new $name(); + + $objects[$class] =& instantiate_class(new $name()); return $objects[$class]; } $name = ($class != 'Controller') ? 'CI_'.$class : $class; - - $objects[$class] =& new $name(); + + $objects[$class] =& instantiate_class(new $name()); return $objects[$class]; } +/** + * Instantiate Class + * + * Returns a new class object by reference, used by load_class() and the DB class. + * Required to retain PHP 4 compatibility and also not make PHP 5.3 cry. + * + * Use: $obj =& instantiate_class(new Foo()); + * + * @access public + * @param object + * @return object + */ +function &instantiate_class(&$class_object) +{ + return $class_object; +} + /** * Loads the main config.php file * @@ -203,10 +232,10 @@ function config_item($item) * @access public * @return void */ -function show_error($message) +function show_error($message, $status_code = 500) { $error =& load_class('Exceptions'); - echo $error->show_error('An Error Was Encountered', $message); + echo $error->show_error('An Error Was Encountered', $message, 'error_general', $status_code); exit; } @@ -252,6 +281,91 @@ function log_message($level = 'error', $message, $php_error = FALSE) $LOG->write_log($level, $message, $php_error); } + +/** + * Set HTTP Status Header + * + * @access public + * @param int the status code + * @param string + * @return void + */ +function set_status_header($code = 200, $text = '') +{ + $stati = array( + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative Information', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Found', + 304 => 'Not Modified', + 305 => 'Use Proxy', + 307 => 'Temporary Redirect', + + 400 => 'Bad Request', + 401 => 'Unauthorized', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Timeout', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Request Entity Too Large', + 414 => 'Request-URI Too Long', + 415 => 'Unsupported Media Type', + 416 => 'Requested Range Not Satisfiable', + 417 => 'Expectation Failed', + + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Timeout', + 505 => 'HTTP Version Not Supported' + ); + + if ($code == '' OR ! is_numeric($code)) + { + show_error('Status codes must be numeric', 500); + } + + if (isset($stati[$code]) AND $text == '') + { + $text = $stati[$code]; + } + + if ($text == '') + { + show_error('No status text available. Please check your status code number or supply your own message text.', 500); + } + + $server_protocol = (isset($_SERVER['SERVER_PROTOCOL'])) ? $_SERVER['SERVER_PROTOCOL'] : FALSE; + + if (substr(php_sapi_name(), 0, 3) == 'cgi') + { + header("Status: {$code} {$text}", TRUE); + } + elseif ($server_protocol == 'HTTP/1.1' OR $server_protocol == 'HTTP/1.0') + { + header($server_protocol." {$code} {$text}", TRUE, $code); + } + else + { + header("HTTP/1.1 {$code} {$text}", TRUE, $code); + } +} + + /** * Exception Handler * diff --git a/codeigniter/Compat.php b/codeigniter/Compat.php index 6100956..958ab4c 100644 --- a/codeigniter/Compat.php +++ b/codeigniter/Compat.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/DB.php b/database/DB.php index ca0cfc2..0f734d7 100644 --- a/database/DB.php +++ b/database/DB.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -130,7 +130,7 @@ function &DB($params = '', $active_record_override = FALSE) // Instantiate the DB adapter $driver = 'CI_DB_'.$params['dbdriver'].'_driver'; - $DB =& new $driver($params); + $DB =& instantiate_class(new $driver($params)); if ($DB->autoinit == TRUE) { diff --git a/database/DB_active_rec.php b/database/DB_active_rec.php index 4cc54a7..0702199 100644 --- a/database/DB_active_rec.php +++ b/database/DB_active_rec.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -267,16 +267,38 @@ class CI_DB_active_record extends CI_DB_driver { { foreach ((array)$from as $val) { - // Extract any aliases that might exist. We use this information - // in the _protect_identifiers to know whether to add a table prefix - $this->_track_aliases($val); + if (strpos($val, ',') !== FALSE) + { + foreach (explode(',', $val) as $v) + { + $v = trim($v); + $this->_track_aliases($v); - $this->ar_from[] = $this->_protect_identifiers($val, TRUE, NULL, FALSE); - - if ($this->ar_caching === TRUE) + $this->ar_from[] = $this->_protect_identifiers($v, TRUE, NULL, FALSE); + + if ($this->ar_caching === TRUE) + { + $this->ar_cache_from[] = $this->_protect_identifiers($v, TRUE, NULL, FALSE); + $this->ar_cache_exists[] = 'from'; + } + } + + } + else { - $this->ar_cache_from[] = $this->_protect_identifiers($val, TRUE, NULL, FALSE); - $this->ar_cache_exists[] = 'from'; + $val = trim($val); + + // Extract any aliases that might exist. We use this information + // in the _protect_identifiers to know whether to add a table prefix + $this->_track_aliases($val); + + $this->ar_from[] = $this->_protect_identifiers($val, TRUE, NULL, FALSE); + + if ($this->ar_caching === TRUE) + { + $this->ar_cache_from[] = $this->_protect_identifiers($val, TRUE, NULL, FALSE); + $this->ar_cache_exists[] = 'from'; + } } } @@ -685,7 +707,7 @@ class CI_DB_active_record extends CI_DB_driver { $prefix = (count($this->ar_like) == 0) ? '' : $type; - $v = $this->escape_str($v); + $v = $this->escape_like_str($v); if ($side == 'before') { @@ -700,6 +722,12 @@ class CI_DB_active_record extends CI_DB_driver { $like_statement = $prefix." $k $not LIKE '%{$v}%'"; } + // some platforms require an escape sequence definition for LIKE wildcards + if ($this->_like_escape_str != '') + { + $like_statement = $like_statement.sprintf($this->_like_escape_str, $this->_like_escape_char); + } + $this->ar_like[] = $like_statement; if ($this->ar_caching === TRUE) { @@ -873,8 +901,30 @@ class CI_DB_active_record extends CI_DB_driver { { $direction = (in_array(strtoupper(trim($direction)), array('ASC', 'DESC'), TRUE)) ? ' '.$direction : ' ASC'; } - - $orderby_statement = $this->_protect_identifiers($orderby).$direction; + + + if (strpos($orderby, ',') !== FALSE) + { + $temp = array(); + foreach (explode(',', $orderby) as $part) + { + $part = trim($part); + if ( ! in_array($part, $this->ar_aliased_tables)) + { + $part = $this->_protect_identifiers(trim($part)); + } + + $temp[] = $part; + } + + $orderby = implode(', ', $temp); + } + else if ($direction != $this->_random_keyword) + { + $orderby = $this->_protect_identifiers($orderby); + } + + $orderby_statement = $orderby.$direction; $this->ar_orderby[] = $orderby_statement; if ($this->ar_caching === TRUE) @@ -1330,7 +1380,7 @@ class CI_DB_active_record extends CI_DB_driver { $this->limit($limit); } - if (count($this->ar_where) == 0 && count($this->ar_like) == 0) + if (count($this->ar_where) == 0 && count($this->ar_wherein) == 0 && count($this->ar_like) == 0) { if ($this->db_debug) { diff --git a/database/DB_cache.php b/database/DB_cache.php index 70a2d95..8b0ad4f 100644 --- a/database/DB_cache.php +++ b/database/DB_cache.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/DB_driver.php b/database/DB_driver.php index fae8c28..014dfd4 100644 --- a/database/DB_driver.php +++ b/database/DB_driver.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -613,7 +613,7 @@ class CI_DB_driver { */ function is_write_type($sql) { - if ( ! preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|LOAD DATA|COPY|ALTER|GRANT|REVOKE|LOCK|UNLOCK)\s+/i', $sql)) + if ( ! preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD DATA|COPY|ALTER|GRANT|REVOKE|LOCK|UNLOCK)\s+/i', $sql)) { return FALSE; } @@ -670,25 +670,45 @@ class CI_DB_driver { * * @access public * @param string - * @return integer + * @return mixed */ function escape($str) - { - switch (gettype($str)) + { + if (is_string($str)) { - case 'string' : $str = "'".$this->escape_str($str)."'"; - break; - case 'boolean' : $str = ($str === FALSE) ? 0 : 1; - break; - default : $str = ($str === NULL) ? 'NULL' : $str; - break; - } + $str = "'".$this->escape_str($str)."'"; + } + elseif (is_bool($str)) + { + $str = ($str === FALSE) ? 0 : 1; + } + elseif (is_null($str)) + { + $str = 'NULL'; + } return $str; } // -------------------------------------------------------------------- + + /** + * Escape LIKE String + * + * Calls the individual driver for platform + * specific escaping for LIKE conditions + * + * @access public + * @param string + * @return mixed + */ + function escape_like_str($str) + { + return $this->escape_str($str, TRUE); + } + // -------------------------------------------------------------------- + /** * Primary * @@ -1086,12 +1106,15 @@ class CI_DB_driver { { return TRUE; } - - if ( ! @include(BASEPATH.'database/DB_cache'.EXT)) + + if ( ! class_exists('CI_DB_Cache')) { - return $this->cache_off(); + if ( ! @include(BASEPATH.'database/DB_cache'.EXT)) + { + return $this->cache_off(); + } } - + $this->CACHE = new CI_DB_Cache($this); // pass db object to support multiple db connections and returned db objects return TRUE; } @@ -1196,19 +1219,40 @@ class CI_DB_driver { { $protect_identifiers = $this->_protect_identifiers; } - + + if (is_array($item)) + { + $escaped_array = array(); + + foreach($item as $k => $v) + { + $escaped_array[$this->_protect_identifiers($k)] = $this->_protect_identifiers($v); + } + + return $escaped_array; + } + // Convert tabs or multiple spaces into single spaces - $item = preg_replace('/[\t| ]+/', ' ', $item); + $item = preg_replace('/[\t ]+/', ' ', $item); // If the item has an alias declaration we remove it and set it aside. // Basically we remove everything to the right of the first space $alias = ''; if (strpos($item, ' ') !== FALSE) - { + { $alias = strstr($item, " "); $item = substr($item, 0, - strlen($alias)); } + // This is basically a bug fix for queries that use MAX, MIN, etc. + // If a parenthesis is found we know that we do not need to + // escape the data or add a prefix. There's probably a more graceful + // way to deal with this, but I'm not thinking of it -- Rick + if (strpos($item, '(') !== FALSE) + { + return $item.$alias; + } + // Break the string apart if it contains periods, then insert the table prefix // in the correct location, assuming the period doesn't indicate that we're dealing // with an alias. While we're at it, we will escape the components @@ -1218,9 +1262,9 @@ class CI_DB_driver { // Does the first segment of the exploded item match // one of the aliases previously identified? If so, - // we have nothing more to do other then escape the item + // we have nothing more to do other than escape the item if (in_array($parts[0], $this->ar_aliased_tables)) - { + { if ($protect_identifiers === TRUE) { foreach ($parts as $key => $val) @@ -1265,7 +1309,13 @@ class CI_DB_driver { { $i++; } - + + // Verify table prefix and replace if necessary + if ($this->swap_pre != '' && strncmp($parts[$i], $this->swap_pre, strlen($this->swap_pre)) === 0) + { + $parts[$i] = preg_replace("/^".$this->swap_pre."(\S+?)/", $this->dbprefix."\\1", $parts[$i]); + } + // We only add the table prefix if it does not already exist if (substr($parts[$i], 0, strlen($this->dbprefix)) != $this->dbprefix) { @@ -1284,25 +1334,22 @@ class CI_DB_driver { return $item.$alias; } - // This is basically a bug fix for queries that use MAX, MIN, etc. - // If a parenthesis is found we know that we do not need to - // escape the data or add a prefix. There's probably a more graceful - // way to deal with this, but I'm not thinking of it -- Rick - if (strpos($item, '(') !== FALSE) - { - return $item.$alias; - } - // Is there a table prefix? If not, no need to insert it if ($this->dbprefix != '') { + // Verify table prefix and replace if necessary + if ($this->swap_pre != '' && strncmp($item, $this->swap_pre, strlen($this->swap_pre)) === 0) + { + $item = preg_replace("/^".$this->swap_pre."(\S+?)/", $this->dbprefix."\\1", $item); + } + // Do we prefix an item with no segments? if ($prefix_single == TRUE AND substr($item, 0, strlen($this->dbprefix)) != $this->dbprefix) { $item = $this->dbprefix.$item; } } - + if ($protect_identifiers === TRUE AND ! in_array($item, $this->_reserved_identifiers)) { $item = $this->_escape_identifiers($item); diff --git a/database/DB_forge.php b/database/DB_forge.php index f708910..4050e30 100644 --- a/database/DB_forge.php +++ b/database/DB_forge.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -257,18 +257,28 @@ class CI_DB_forge { } // add field info into field array, but we can only do one at a time - // so only grab the first field in the event there are more then one - $this->add_field(array_slice($field, 0, 1)); + // so we cycle through - if (count($this->fields) == 0) - { - show_error('Field information is required.'); - } + foreach ($field as $k => $v) + { + $this->add_field(array($k => $field[$k])); - $sql = $this->_alter_table('ADD', $this->db->dbprefix.$table, $this->fields, $after_field); + if (count($this->fields) == 0) + { + show_error('Field information is required.'); + } + + $sql = $this->_alter_table('ADD', $this->db->dbprefix.$table, $this->fields, $after_field); - $this->_reset(); - return $this->db->query($sql); + $this->_reset(); + + if ($this->db->query($sql) === FALSE) + { + return FALSE; + } + } + + return TRUE; } // -------------------------------------------------------------------- @@ -318,18 +328,28 @@ class CI_DB_forge { } // add field info into field array, but we can only do one at a time - // so only grab the first field in the event there are more then one - $this->add_field(array_slice($field, 0, 1)); + // so we cycle through - if (count($this->fields) == 0) - { - show_error('Field information is required.'); - } + foreach ($field as $k => $v) + { + $this->add_field(array($k => $field[$k])); - $sql = $this->_alter_table('CHANGE', $this->db->dbprefix.$table, $this->fields); + if (count($this->fields) == 0) + { + show_error('Field information is required.'); + } + + $sql = $this->_alter_table('CHANGE', $this->db->dbprefix.$table, $this->fields); - $this->_reset(); - return $this->db->query($sql); + $this->_reset(); + + if ($this->db->query($sql) === FALSE) + { + return FALSE; + } + } + + return TRUE; } // -------------------------------------------------------------------- diff --git a/database/DB_result.php b/database/DB_result.php index 4128141..4614e29 100644 --- a/database/DB_result.php +++ b/database/DB_result.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/DB_utility.php b/database/DB_utility.php index 195e4c4..33c68fa 100644 --- a/database/DB_utility.php +++ b/database/DB_utility.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -175,7 +175,7 @@ class CI_DB_utility extends CI_DB_forge { */ function csv_from_result($query, $delim = ",", $newline = "\n", $enclosure = '"') { - if ( ! is_object($query) OR ! method_exists($query, 'field_names')) + if ( ! is_object($query) OR ! method_exists($query, 'list_fields')) { show_error('You must submit a valid result object'); } @@ -217,7 +217,7 @@ class CI_DB_utility extends CI_DB_forge { */ function xml_from_result($query, $params = array()) { - if ( ! is_object($query) OR ! method_exists($query, 'field_names')) + if ( ! is_object($query) OR ! method_exists($query, 'list_fields')) { show_error('You must submit a valid result object'); } diff --git a/database/drivers/mssql/mssql_driver.php b/database/drivers/mssql/mssql_driver.php index a3adabc..97ac971 100644 --- a/database/drivers/mssql/mssql_driver.php +++ b/database/drivers/mssql/mssql_driver.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -34,6 +34,11 @@ class CI_DB_mssql_driver extends CI_DB { // The character used for escaping var $_escape_char = ''; + + // clause and character used for LIKE escape sequences + var $_like_escape_str = " ESCAPE '%s' "; + 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 @@ -77,7 +82,23 @@ class CI_DB_mssql_driver extends CI_DB { } // -------------------------------------------------------------------- + + /** + * 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() + { + // not implemented in MSSQL + } + // -------------------------------------------------------------------- + /** * Select the database * @@ -225,15 +246,36 @@ class CI_DB_mssql_driver extends CI_DB { * * @access public * @param string + * @param bool whether or not the string will be used in a LIKE condition * @return string */ - function escape_str($str) + function escape_str($str, $like = FALSE) { + if (is_array($str)) + { + foreach($str as $key => $val) + { + $str[$key] = $this->escape_str($val, $like); + } + + return $str; + } + // Access the CI object $CI =& get_instance(); // Escape single quotes - return str_replace("'", "''", $CI->input->_remove_invisible_characters($str)); + $str = str_replace("'", "''", $CI->input->_remove_invisible_characters($str)); + + // 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; } // -------------------------------------------------------------------- @@ -314,15 +356,19 @@ class CI_DB_mssql_driver extends CI_DB { 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)); + { + 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'; + { + return 0; + } $row = $query->row(); - return $row->numrows; + return (int) $row->numrows; } // -------------------------------------------------------------------- @@ -343,7 +389,7 @@ class CI_DB_mssql_driver extends CI_DB { // for future compatibility if ($prefix_limit !== FALSE AND $this->dbprefix != '') { - //$sql .= " LIKE '".$this->dbprefix."%'"; + //$sql .= " LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_char); return FALSE; // not currently supported } @@ -392,8 +438,7 @@ class CI_DB_mssql_driver extends CI_DB { */ function _error_message() { - // Are errros even supported in MS SQL? - return ''; + return mssql_get_last_message(); } // -------------------------------------------------------------------- @@ -427,7 +472,18 @@ class CI_DB_mssql_driver extends CI_DB { { 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; diff --git a/database/drivers/mssql/mssql_forge.php b/database/drivers/mssql/mssql_forge.php index 512fc47..632b4d9 100644 --- a/database/drivers/mssql/mssql_forge.php +++ b/database/drivers/mssql/mssql_forge.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/drivers/mssql/mssql_result.php b/database/drivers/mssql/mssql_result.php index e9679cb..a56a3a9 100644 --- a/database/drivers/mssql/mssql_result.php +++ b/database/drivers/mssql/mssql_result.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/drivers/mssql/mssql_utility.php b/database/drivers/mssql/mssql_utility.php index 38118ac..9fa257a 100644 --- a/database/drivers/mssql/mssql_utility.php +++ b/database/drivers/mssql/mssql_utility.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/drivers/mysql/mysql_driver.php b/database/drivers/mysql/mysql_driver.php index d10a5f0..fe18598 100644 --- a/database/drivers/mysql/mysql_driver.php +++ b/database/drivers/mysql/mysql_driver.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -34,7 +34,11 @@ class CI_DB_mysql_driver extends CI_DB { // The character used for escaping var $_escape_char = '`'; - + + // clause and character used for LIKE escape sequences - not used in MySQL + var $_like_escape_str = ''; + var $_like_escape_chr = ''; + /** * Whether to use the MySQL "delete hack" which allows the number * of affected rows to be shown. Uses a preg_replace when enabled, @@ -86,6 +90,25 @@ class CI_DB_mysql_driver extends CI_DB { // -------------------------------------------------------------------- + /** + * 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 (mysql_ping($this->conn_id) === FALSE) + { + $this->conn_id = FALSE; + } + } + + // -------------------------------------------------------------------- + /** * Select the database * @@ -256,15 +279,16 @@ class CI_DB_mysql_driver extends CI_DB { * * @access public * @param string + * @param bool whether or not the string will be used in a LIKE condition * @return string */ - function escape_str($str) + function escape_str($str, $like = FALSE) { if (is_array($str)) { foreach($str as $key => $val) { - $str[$key] = $this->escape_str($val); + $str[$key] = $this->escape_str($val, $like); } return $str; @@ -272,16 +296,24 @@ class CI_DB_mysql_driver extends CI_DB { if (function_exists('mysql_real_escape_string') AND is_resource($this->conn_id)) { - return mysql_real_escape_string($str, $this->conn_id); + $str = mysql_real_escape_string($str, $this->conn_id); } elseif (function_exists('mysql_escape_string')) { - return mysql_escape_string($str); + $str = mysql_escape_string($str); } else { - return addslashes($str); + $str = addslashes($str); + } + + // escape LIKE condition wildcards + if ($like === TRUE) + { + $str = str_replace(array('%', '_'), array('\\%', '\\_'), $str); } + + return $str; } // -------------------------------------------------------------------- @@ -325,15 +357,19 @@ class CI_DB_mysql_driver extends CI_DB { function count_all($table = '') { if ($table == '') - return '0'; + { + return 0; + } - $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE)); - + $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'; + { + return 0; + } $row = $query->row(); - return (int)$row->numrows; + return (int) $row->numrows; } // -------------------------------------------------------------------- @@ -353,7 +389,7 @@ class CI_DB_mysql_driver extends CI_DB { if ($prefix_limit !== FALSE AND $this->dbprefix != '') { - $sql .= " LIKE '".$this->dbprefix."%'"; + $sql .= " LIKE '".$this->escape_like_str($this->dbprefix)."%'"; } return $sql; @@ -434,7 +470,18 @@ class CI_DB_mysql_driver extends CI_DB { { 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; @@ -443,7 +490,7 @@ class CI_DB_mysql_driver extends CI_DB { { $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); } diff --git a/database/drivers/mysql/mysql_forge.php b/database/drivers/mysql/mysql_forge.php index d8cb77e..d343b36 100644 --- a/database/drivers/mysql/mysql_forge.php +++ b/database/drivers/mysql/mysql_forge.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/drivers/mysql/mysql_result.php b/database/drivers/mysql/mysql_result.php index 673aeac..2e95507 100644 --- a/database/drivers/mysql/mysql_result.php +++ b/database/drivers/mysql/mysql_result.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/drivers/mysql/mysql_utility.php b/database/drivers/mysql/mysql_utility.php index 003b1dd..2c8b264 100644 --- a/database/drivers/mysql/mysql_utility.php +++ b/database/drivers/mysql/mysql_utility.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/drivers/mysqli/mysqli_driver.php b/database/drivers/mysqli/mysqli_driver.php index 07a07d3..488b074 100644 --- a/database/drivers/mysqli/mysqli_driver.php +++ b/database/drivers/mysqli/mysqli_driver.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -35,6 +35,10 @@ class CI_DB_mysqli_driver extends CI_DB { // The character used for escaping var $_escape_char = '`'; + // clause and character used for LIKE escape sequences - not used in MySQL + 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 @@ -60,7 +64,15 @@ class CI_DB_mysqli_driver extends CI_DB { */ function db_connect() { - return @mysqli_connect($this->hostname, $this->username, $this->password, $this->database, $this->port); + if ($this->port != '') + { + return @mysqli_connect($this->hostname, $this->username, $this->password, $this->database, $this->port); + } + else + { + return @mysqli_connect($this->hostname, $this->username, $this->password, $this->database); + } + } // -------------------------------------------------------------------- @@ -78,6 +90,25 @@ class CI_DB_mysqli_driver extends CI_DB { // -------------------------------------------------------------------- + /** + * 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 (mysqli_ping($this->conn_id) === FALSE) + { + $this->conn_id = FALSE; + } + } + + // -------------------------------------------------------------------- + /** * Select the database * @@ -249,22 +280,41 @@ class CI_DB_mysqli_driver extends CI_DB { * * @access public * @param string + * @param bool whether or not the string will be used in a LIKE condition * @return string */ - function escape_str($str) + function escape_str($str, $like = FALSE) { + if (is_array($str)) + { + foreach($str as $key => $val) + { + $str[$key] = $this->escape_str($val, $like); + } + + return $str; + } + if (function_exists('mysqli_real_escape_string') AND is_object($this->conn_id)) { - return mysqli_real_escape_string($this->conn_id, $str); + $str = mysqli_real_escape_string($this->conn_id, $str); } elseif (function_exists('mysql_escape_string')) { - return mysql_escape_string($str); + $str = mysql_escape_string($str); } else { - return addslashes($str); + $str = addslashes($str); + } + + // escape LIKE condition wildcards + if ($like === TRUE) + { + $str = str_replace(array('%', '_'), array('\\%', '\\_'), $str); } + + return $str; } // -------------------------------------------------------------------- @@ -308,15 +358,19 @@ class CI_DB_mysqli_driver extends CI_DB { 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)); - + { + 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'; + { + return 0; + } $row = $query->row(); - return $row->numrows; + return (int) $row->numrows; } // -------------------------------------------------------------------- @@ -336,7 +390,7 @@ class CI_DB_mysqli_driver extends CI_DB { if ($prefix_limit !== FALSE AND $this->dbprefix != '') { - $sql .= " LIKE '".$this->dbprefix."%'"; + $sql .= " LIKE '".$this->escape_like_str($this->dbprefix)."%'"; } return $sql; @@ -417,7 +471,18 @@ class CI_DB_mysqli_driver extends CI_DB { { 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; diff --git a/database/drivers/mysqli/mysqli_forge.php b/database/drivers/mysqli/mysqli_forge.php index 99c2ebc..0992274 100644 --- a/database/drivers/mysqli/mysqli_forge.php +++ b/database/drivers/mysqli/mysqli_forge.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/drivers/mysqli/mysqli_result.php b/database/drivers/mysqli/mysqli_result.php index 5b1f793..00fc0db 100644 --- a/database/drivers/mysqli/mysqli_result.php +++ b/database/drivers/mysqli/mysqli_result.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/drivers/mysqli/mysqli_utility.php b/database/drivers/mysqli/mysqli_utility.php index c1d191d..7ebda4c 100644 --- a/database/drivers/mysqli/mysqli_utility.php +++ b/database/drivers/mysqli/mysqli_utility.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/drivers/oci8/oci8_driver.php b/database/drivers/oci8/oci8_driver.php index c4e1306..6145719 100644 --- a/database/drivers/oci8/oci8_driver.php +++ b/database/drivers/oci8/oci8_driver.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -47,7 +47,11 @@ class CI_DB_oci8_driver extends CI_DB { // The character used for excaping var $_escape_char = '"'; - + + // clause and character used for LIKE escape sequences + var $_like_escape_str = " escape '%s' "; + 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 @@ -93,6 +97,22 @@ class CI_DB_oci8_driver extends CI_DB { // -------------------------------------------------------------------- + /** + * 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() + { + // not implemented in oracle + } + + // -------------------------------------------------------------------- + /** * Select the database * @@ -368,14 +388,35 @@ class CI_DB_oci8_driver extends CI_DB { * * @access public * @param string + * @param bool whether or not the string will be used in a LIKE condition * @return string */ - function escape_str($str) + function escape_str($str, $like = FALSE) { + if (is_array($str)) + { + foreach($str as $key => $val) + { + $str[$key] = $this->escape_str($val, $like); + } + + return $str; + } + // Access the CI object $CI =& get_instance(); - return $CI->_remove_invisible_characters($str); + $str = $CI->input->_remove_invisible_characters($str); + + // 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; } // -------------------------------------------------------------------- @@ -420,17 +461,19 @@ class CI_DB_oci8_driver extends CI_DB { function count_all($table = '') { if ($table == '') - return '0'; + { + return 0; + } - $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE)); + $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows') . " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE)); if ($query == FALSE) - { + { return 0; - } + } $row = $query->row(); - return $row->NUMROWS; + return (int) $row->numrows; } // -------------------------------------------------------------------- @@ -450,7 +493,7 @@ class CI_DB_oci8_driver extends CI_DB { if ($prefix_limit !== FALSE AND $this->dbprefix != '') { - $sql .= " WHERE TABLE_NAME LIKE '".$this->dbprefix."%'"; + $sql .= " WHERE TABLE_NAME LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_char); } return $sql; @@ -533,6 +576,17 @@ class CI_DB_oci8_driver extends CI_DB { { 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) { diff --git a/database/drivers/oci8/oci8_forge.php b/database/drivers/oci8/oci8_forge.php index bbc11f3..c3e9cb9 100644 --- a/database/drivers/oci8/oci8_forge.php +++ b/database/drivers/oci8/oci8_forge.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/drivers/oci8/oci8_result.php b/database/drivers/oci8/oci8_result.php index 7d7cd1c..1d0b7db 100644 --- a/database/drivers/oci8/oci8_result.php +++ b/database/drivers/oci8/oci8_result.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/drivers/oci8/oci8_utility.php b/database/drivers/oci8/oci8_utility.php index cf6e9e6..c8049c2 100644 --- a/database/drivers/oci8/oci8_utility.php +++ b/database/drivers/oci8/oci8_utility.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/drivers/odbc/odbc_driver.php b/database/drivers/odbc/odbc_driver.php index 6404d54..dacbaab 100644 --- a/database/drivers/odbc/odbc_driver.php +++ b/database/drivers/odbc/odbc_driver.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -34,7 +34,11 @@ class CI_DB_odbc_driver extends CI_DB { // the character used to excape - not necessary for ODBC var $_escape_char = ''; - + + // clause and character used for LIKE escape sequences + var $_like_escape_str = " {escape '%s'} "; + 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 @@ -77,6 +81,22 @@ class CI_DB_odbc_driver extends CI_DB { // -------------------------------------------------------------------- + /** + * 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() + { + // not implemented in odbc + } + + // -------------------------------------------------------------------- + /** * Select the database * @@ -237,15 +257,36 @@ class CI_DB_odbc_driver extends CI_DB { * * @access public * @param string + * @param bool whether or not the string will be used in a LIKE condition * @return string */ - function escape_str($str) + function escape_str($str, $like = FALSE) { + if (is_array($str)) + { + foreach($str as $key => $val) + { + $str[$key] = $this->escape_str($val, $like); + } + + return $str; + } + // Access the CI object $CI =& get_instance(); - + // ODBC doesn't require escaping - return $CI->_remove_invisible_characters($str); + $str = $CI->input->_remove_invisible_characters($str); + + // 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; } // -------------------------------------------------------------------- @@ -289,15 +330,19 @@ class CI_DB_odbc_driver extends CI_DB { 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)); - + { + 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'; + { + return 0; + } $row = $query->row(); - return $row->numrows; + return (int) $row->numrows; } // -------------------------------------------------------------------- @@ -317,7 +362,7 @@ class CI_DB_odbc_driver extends CI_DB { if ($prefix_limit !== FALSE AND $this->dbprefix != '') { - //$sql .= " LIKE '".$this->dbprefix."%'"; + //$sql .= " LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_char); return FALSE; // not currently supported } @@ -399,6 +444,17 @@ class CI_DB_odbc_driver extends CI_DB { { 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) { diff --git a/database/drivers/odbc/odbc_forge.php b/database/drivers/odbc/odbc_forge.php index 5305afb..99cb282 100644 --- a/database/drivers/odbc/odbc_forge.php +++ b/database/drivers/odbc/odbc_forge.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/drivers/odbc/odbc_result.php b/database/drivers/odbc/odbc_result.php index 9a59cfc..d6f1501 100644 --- a/database/drivers/odbc/odbc_result.php +++ b/database/drivers/odbc/odbc_result.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/drivers/odbc/odbc_utility.php b/database/drivers/odbc/odbc_utility.php index 67aee64..85707a0 100644 --- a/database/drivers/odbc/odbc_utility.php +++ b/database/drivers/odbc/odbc_utility.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/drivers/postgre/postgre_driver.php b/database/drivers/postgre/postgre_driver.php index b141978..9258da6 100644 --- a/database/drivers/postgre/postgre_driver.php +++ b/database/drivers/postgre/postgre_driver.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -34,6 +34,10 @@ class CI_DB_postgre_driver extends CI_DB { var $_escape_char = '"'; + // clause and character used for LIKE escape sequences + var $_like_escape_str = " ESCAPE '%s' "; + 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 @@ -97,6 +101,25 @@ class CI_DB_postgre_driver extends CI_DB { // -------------------------------------------------------------------- + /** + * 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 (pg_ping($this->conn_id) === FALSE) + { + $this->conn_id = FALSE; + } + } + + // -------------------------------------------------------------------- + /** * Select the database * @@ -253,11 +276,32 @@ class CI_DB_postgre_driver extends CI_DB { * * @access public * @param string + * @param bool whether or not the string will be used in a LIKE condition * @return string */ - function escape_str($str) - { - return pg_escape_string($str); + function escape_str($str, $like = FALSE) + { + if (is_array($str)) + { + foreach($str as $key => $val) + { + $str[$key] = $this->escape_str($val, $like); + } + + return $str; + } + + $str = pg_escape_string($str); + + // 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; } // -------------------------------------------------------------------- @@ -329,15 +373,19 @@ class CI_DB_postgre_driver extends CI_DB { function count_all($table = '') { if ($table == '') - return '0'; + { + return 0; + } + + $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows') . " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE)); - $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'; + { + return 0; + } $row = $query->row(); - return $row->numrows; + return (int) $row->numrows; } // -------------------------------------------------------------------- @@ -357,7 +405,7 @@ class CI_DB_postgre_driver extends CI_DB { if ($prefix_limit !== FALSE AND $this->dbprefix != '') { - $sql .= " AND table_name LIKE '".$this->dbprefix."%'"; + $sql .= " AND table_name LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_char); } return $sql; @@ -438,6 +486,17 @@ class CI_DB_postgre_driver extends CI_DB { { 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) { diff --git a/database/drivers/postgre/postgre_forge.php b/database/drivers/postgre/postgre_forge.php index 72c2dd7..471dd80 100644 --- a/database/drivers/postgre/postgre_forge.php +++ b/database/drivers/postgre/postgre_forge.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/drivers/postgre/postgre_result.php b/database/drivers/postgre/postgre_result.php index 3206c13..8e45eb1 100644 --- a/database/drivers/postgre/postgre_result.php +++ b/database/drivers/postgre/postgre_result.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/drivers/postgre/postgre_utility.php b/database/drivers/postgre/postgre_utility.php index 06292f2..235954f 100644 --- a/database/drivers/postgre/postgre_utility.php +++ b/database/drivers/postgre/postgre_utility.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/drivers/sqlite/sqlite_driver.php b/database/drivers/sqlite/sqlite_driver.php index 968bb3f..0cb7997 100644 --- a/database/drivers/sqlite/sqlite_driver.php +++ b/database/drivers/sqlite/sqlite_driver.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -37,6 +37,10 @@ class CI_DB_sqlite_driver extends CI_DB { // The character used to escape with - not needed for SQLite var $_escape_char = ''; + // clause and character used for LIKE escape sequences + var $_like_escape_str = " ESCAPE '%s' "; + 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 @@ -95,6 +99,22 @@ class CI_DB_sqlite_driver extends CI_DB { // -------------------------------------------------------------------- + /** + * 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() + { + // not implemented in SQLite + } + + // -------------------------------------------------------------------- + /** * Select the database * @@ -253,11 +273,32 @@ class CI_DB_sqlite_driver extends CI_DB { * * @access public * @param string + * @param bool whether or not the string will be used in a LIKE condition * @return string */ - function escape_str($str) + function escape_str($str, $like = FALSE) { - return sqlite_escape_string($str); + if (is_array($str)) + { + foreach($str as $key => $val) + { + $str[$key] = $this->escape_str($val, $like); + } + + return $str; + } + + $str = sqlite_escape_string($str); + + // 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; } // -------------------------------------------------------------------- @@ -301,15 +342,19 @@ class CI_DB_sqlite_driver extends CI_DB { 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)); + { + 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'; + { + return 0; + } $row = $query->row(); - return $row->numrows; + return (int) $row->numrows; } // -------------------------------------------------------------------- @@ -329,7 +374,7 @@ class CI_DB_sqlite_driver extends CI_DB { if ($prefix_limit !== FALSE AND $this->dbprefix != '') { - $sql .= " AND 'name' LIKE '".$this->dbprefix."%'"; + $sql .= " AND 'name' LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_char); } return $sql; } @@ -410,6 +455,17 @@ class CI_DB_sqlite_driver extends CI_DB { { 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) { diff --git a/database/drivers/sqlite/sqlite_forge.php b/database/drivers/sqlite/sqlite_forge.php index 73630de..0688ba3 100644 --- a/database/drivers/sqlite/sqlite_forge.php +++ b/database/drivers/sqlite/sqlite_forge.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/drivers/sqlite/sqlite_result.php b/database/drivers/sqlite/sqlite_result.php index bed1698..c1c24c7 100644 --- a/database/drivers/sqlite/sqlite_result.php +++ b/database/drivers/sqlite/sqlite_result.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/database/drivers/sqlite/sqlite_utility.php b/database/drivers/sqlite/sqlite_utility.php index c067403..f66464e 100644 --- a/database/drivers/sqlite/sqlite_utility.php +++ b/database/drivers/sqlite/sqlite_utility.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/helpers/array_helper.php b/helpers/array_helper.php index 411d309..39d0c88 100644 --- a/helpers/array_helper.php +++ b/helpers/array_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/helpers/compatibility_helper.php b/helpers/compatibility_helper.php index 3b37cea..c217f7f 100644 --- a/helpers/compatibility_helper.php +++ b/helpers/compatibility_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/helpers/cookie_helper.php b/helpers/cookie_helper.php index d906882..7607ffb 100644 --- a/helpers/cookie_helper.php +++ b/helpers/cookie_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -108,7 +108,15 @@ if ( ! function_exists('get_cookie')) function get_cookie($index = '', $xss_clean = FALSE) { $CI =& get_instance(); - return $CI->input->cookie($index, $xss_clean); + + $prefix = ''; + + if ( ! isset($_COOKIE[$index]) && config_item('cookie_prefix') != '') + { + $prefix = config_item('cookie_prefix'); + } + + return $CI->input->cookie($prefix.$index, $xss_clean); } } diff --git a/helpers/date_helper.php b/helpers/date_helper.php index dbd7e0e..fae9e66 100644 --- a/helpers/date_helper.php +++ b/helpers/date_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -460,7 +460,7 @@ if ( ! function_exists('human_to_unix')) $hour = (strlen($ex['0']) == 1) ? '0'.$ex['0'] : $ex['0']; $min = (strlen($ex['1']) == 1) ? '0'.$ex['1'] : $ex['1']; - if (isset($ex['2']) AND ereg("[0-9]{1,2}", $ex['2'])) + if (isset($ex['2']) && preg_match('/[0-9]{1,2}/', $ex['2'])) { $sec = (strlen($ex['2']) == 1) ? '0'.$ex['2'] : $ex['2']; } diff --git a/helpers/directory_helper.php b/helpers/directory_helper.php index be36590..a6fb784 100644 --- a/helpers/directory_helper.php +++ b/helpers/directory_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -41,7 +41,7 @@ */ if ( ! function_exists('directory_map')) { - function directory_map($source_dir, $top_level_only = FALSE) + function directory_map($source_dir, $top_level_only = FALSE, $hidden = FALSE) { if ($fp = @opendir($source_dir)) { @@ -50,7 +50,7 @@ if ( ! function_exists('directory_map')) while (FALSE !== ($file = readdir($fp))) { - if (strncmp($file, '.', 1) == 0) + if (($hidden == FALSE && strncmp($file, '.', 1) == 0) OR ($file == '.' OR $file == '..')) { continue; } @@ -59,7 +59,7 @@ if ( ! function_exists('directory_map')) { $temp_array = array(); - $temp_array = directory_map($source_dir.$file.DIRECTORY_SEPARATOR); + $temp_array = directory_map($source_dir.$file.DIRECTORY_SEPARATOR, $top_level_only, $hidden); $filedata[$file] = $temp_array; } @@ -72,6 +72,10 @@ if ( ! function_exists('directory_map')) closedir($fp); return $filedata; } + else + { + return FALSE; + } } } diff --git a/helpers/download_helper.php b/helpers/download_helper.php index ce2dd48..a8f7b1a 100644 --- a/helpers/download_helper.php +++ b/helpers/download_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/helpers/email_helper.php b/helpers/email_helper.php index af1fdb9..df602b1 100644 --- a/helpers/email_helper.php +++ b/helpers/email_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/helpers/file_helper.php b/helpers/file_helper.php index 8078d96..0d7b5d5 100644 --- a/helpers/file_helper.php +++ b/helpers/file_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -22,7 +22,7 @@ * @subpackage Helpers * @category Helpers * @author ExpressionEngine Dev Team - * @link http://codeigniter.com/user_guide/helpers/file_helper.html + * @link http://codeigniter.com/user_guide/helpers/file_helpers.html */ // ------------------------------------------------------------------------ @@ -121,8 +121,8 @@ if ( ! function_exists('delete_files')) function delete_files($path, $del_dir = FALSE, $level = 0) { // Trim the trailing slash - $path = preg_replace("|^(.+?)/*$|", "\\1", $path); - + $path = rtrim($path, DIRECTORY_SEPARATOR); + if ( ! $current_dir = @opendir($path)) return; @@ -130,17 +130,17 @@ if ( ! function_exists('delete_files')) { if ($filename != "." and $filename != "..") { - if (is_dir($path.'/'.$filename)) + if (is_dir($path.DIRECTORY_SEPARATOR.$filename)) { // Ignore empty folders if (substr($filename, 0, 1) != '.') { - delete_files($path.'/'.$filename, $del_dir, $level + 1); - } + delete_files($path.DIRECTORY_SEPARATOR.$filename, $del_dir, $level + 1); + } } else { - unlink($path.'/'.$filename); + unlink($path.DIRECTORY_SEPARATOR.$filename); } } } @@ -190,7 +190,6 @@ if ( ! function_exists('get_filenames')) } elseif (strncmp($file, '.', 1) !== 0) { - $_filedata[] = ($include_path == TRUE) ? $source_dir.$file : $file; } } @@ -223,9 +222,9 @@ if ( ! function_exists('get_dir_file_info')) { function get_dir_file_info($source_dir, $include_path = FALSE, $_recursion = FALSE) { - $_filedata = array(); + static $_filedata = array(); $relative_path = $source_dir; - + if ($fp = @opendir($source_dir)) { // reset the array and make sure $source_dir has a trailing slash on the initial call @@ -267,8 +266,8 @@ if ( ! function_exists('get_dir_file_info')) * Returns FALSE if the file cannot be found. * * @access public -* @param string path to file -* @param mixed array or comma separated string of information returned +* @param string path to file +* @param mixed array or comma separated string of information returned * @return array */ if ( ! function_exists('get_file_info')) @@ -291,7 +290,7 @@ if ( ! function_exists('get_file_info')) switch ($key) { case 'name': - $fileinfo['name'] = substr(strrchr($file, '/'), 1); + $fileinfo['name'] = substr(strrchr($file, DIRECTORY_SEPARATOR), 1); break; case 'server_path': $fileinfo['server_path'] = $file; @@ -342,9 +341,9 @@ if ( ! function_exists('get_mime_by_extension')) function get_mime_by_extension($file) { $extension = substr(strrchr($file, '.'), 1); - + global $mimes; - + if ( ! is_array($mimes)) { if ( ! require_once(APPPATH.'config/mimes.php')) diff --git a/helpers/form_helper.php b/helpers/form_helper.php index c002c6f..c5e977a 100644 --- a/helpers/form_helper.php +++ b/helpers/form_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -103,19 +103,35 @@ if ( ! function_exists('form_open_multipart')) */ if ( ! function_exists('form_hidden')) { - function form_hidden($name, $value = '') + function form_hidden($name, $value = '', $recursing = FALSE) { - if ( ! is_array($name)) + static $form; + + if ($recursing === FALSE) { - return ''; + $form = "\n"; } - $form = ''; + if (is_array($name)) + { + foreach ($name as $key => $val) + { + form_hidden($key, $val, TRUE); + } + return $form; + } - foreach ($name as $name => $value) + if ( ! is_array($value)) + { + $form .= ''."\n"; + } + else { - $form .= "\n"; - $form .= ''; + foreach ($value as $k => $v) + { + $k = (is_int($k)) ? '' : $k; + form_hidden($name.'['.$k.']', $v, TRUE); + } } return $form; @@ -223,13 +239,39 @@ if ( ! function_exists('form_textarea')) $val = $data['value']; unset($data['value']); // textareas don't use the value attribute } - - return ""; + + $name = (is_array($data)) ? $data['name'] : $data; + return ""; } } // ------------------------------------------------------------------------ +/** + * Multi-select menu + * + * @access public + * @param string + * @param array + * @param mixed + * @param string + * @return type + */ +if (! function_exists('form_multiselect')) +{ + function form_multiselect($name = '', $options = array(), $selected = array(), $extra = '') + { + if ( ! strpos($extra, 'multiple')) + { + $extra .= ' multiple="multiple"'; + } + + return form_dropdown($name, $options, $selected, $extra); + } +} + +// -------------------------------------------------------------------- + /** * Drop-down Menu * @@ -264,15 +306,30 @@ if ( ! function_exists('form_dropdown')) $multiple = (count($selected) > 1 && strpos($extra, 'multiple') === FALSE) ? ' multiple="multiple"' : ''; $form = ''; @@ -409,7 +466,7 @@ if ( ! function_exists('form_button')) { function form_button($data = '', $content = '', $extra = '') { - $defaults = array('name' => (( ! is_array($data)) ? $data : ''), 'type' => 'submit'); + $defaults = array('name' => (( ! is_array($data)) ? $data : ''), 'type' => 'button'); if ( is_array($data) AND isset($data['content'])) { @@ -536,8 +593,10 @@ if ( ! function_exists('form_close')) */ if ( ! function_exists('form_prep')) { - function form_prep($str = '') + function form_prep($str = '', $field_name = '') { + static $prepped_fields = array(); + // if the field name is an array we do this recursively if (is_array($str)) { @@ -554,22 +613,25 @@ if ( ! function_exists('form_prep')) return ''; } - $temp = '__TEMP_AMPERSANDS__'; - - // Replace entities to temporary markers so that - // htmlspecialchars won't mess them up - $str = preg_replace("/&#(\d+);/", "$temp\\1;", $str); - $str = preg_replace("/&(\w+);/", "$temp\\1;", $str); - + // we've already prepped a field with this name + // @todo need to figure out a way to namespace this so + // that we know the *exact* field and not just one with + // the same name + if (isset($prepped_fields[$field_name])) + { + return $str; + } + $str = htmlspecialchars($str); // In case htmlspecialchars misses these. $str = str_replace(array("'", '"'), array("'", """), $str); - // Decode the temp markers back to entities - $str = preg_replace("/$temp(\d+);/","&#\\1;",$str); - $str = preg_replace("/$temp(\w+);/","&\\1;",$str); - + if ($field_name != '') + { + $prepped_fields[$field_name] = $str; + } + return $str; } } @@ -598,10 +660,10 @@ if ( ! function_exists('set_value')) return $default; } - return form_prep($_POST[$field]); + return form_prep($_POST[$field], $field); } - return form_prep($OBJ->set_value($field, $default)); + return form_prep($OBJ->set_value($field, $default), $field); } } @@ -629,7 +691,7 @@ if ( ! function_exists('set_select')) { if ( ! isset($_POST[$field])) { - if (count($_POST) === 0) + if (count($_POST) === 0 AND $default == TRUE) { return ' selected="selected"'; } @@ -684,7 +746,7 @@ if ( ! function_exists('set_checkbox')) { if ( ! isset($_POST[$field])) { - if (count($_POST) === 0) + if (count($_POST) === 0 AND $default == TRUE) { return ' checked="checked"'; } @@ -739,7 +801,7 @@ if ( ! function_exists('set_radio')) { if ( ! isset($_POST[$field])) { - if (count($_POST) === 0) + if (count($_POST) === 0 AND $default == TRUE) { return ' checked="checked"'; } @@ -857,12 +919,12 @@ if ( ! function_exists('_parse_form_attributes')) } $att = ''; - + foreach ($default as $key => $val) { if ($key == 'value') { - $val = form_prep($val); + $val = form_prep($val, $default['name']); } $att .= $key . '="' . $val . '" '; diff --git a/helpers/html_helper.php b/helpers/html_helper.php index 8cad736..427d1ce 100644 --- a/helpers/html_helper.php +++ b/helpers/html_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -37,7 +37,7 @@ * @param string * @param integer * @return string - */ + */ if ( ! function_exists('heading')) { function heading($data = '', $h = '1') @@ -57,7 +57,7 @@ if ( ! function_exists('heading')) * @param array * @param mixed * @return string - */ + */ if ( ! function_exists('ul')) { function ul($list, $attributes = '') @@ -77,7 +77,7 @@ if ( ! function_exists('ul')) * @param array * @param mixed * @return string - */ + */ if ( ! function_exists('ol')) { function ol($list, $attributes = '') @@ -95,11 +95,11 @@ if ( ! function_exists('ol')) * * @access private * @param string - * @param mixed - * @param mixed - * @param intiger + * @param mixed + * @param mixed + * @param intiger * @return string - */ + */ if ( ! function_exists('_list')) { function _list($type = 'ul', $list, $attributes = '', $depth = 0) @@ -109,10 +109,10 @@ if ( ! function_exists('_list')) { return $list; } - + // Set the indentation based on the depth $out = str_repeat(" ", $depth); - + // Were any attributes submitted? If so generate a string if (is_array($attributes)) { @@ -123,21 +123,21 @@ if ( ! function_exists('_list')) } $attributes = $atts; } - + // Write the opening list tag $out .= "<".$type.$attributes.">\n"; - // Cycle through the list elements. If an array is + // Cycle through the list elements. If an array is // encountered we will recursively call _list() static $_last_list_item = ''; foreach ($list as $key => $val) - { + { $_last_list_item = $key; $out .= str_repeat(" ", $depth + 2); $out .= "
  • "; - + if ( ! is_array($val)) { $out .= $val; @@ -149,19 +149,19 @@ if ( ! function_exists('_list')) $out .= str_repeat(" ", $depth + 2); } - $out .= "
  • \n"; + $out .= "\n"; } // Set the indentation for the closing tag $out .= str_repeat(" ", $depth); - + // Write the closing list tag $out .= "\n"; return $out; } } - + // ------------------------------------------------------------------------ /** @@ -170,7 +170,7 @@ if ( ! function_exists('_list')) * @access public * @param integer * @return string - */ + */ if ( ! function_exists('br')) { function br($num = 1) @@ -178,7 +178,7 @@ if ( ! function_exists('br')) return str_repeat("
    ", $num); } } - + // ------------------------------------------------------------------------ /** @@ -189,7 +189,7 @@ if ( ! function_exists('br')) * @access public * @param mixed * @return string - */ + */ if ( ! function_exists('img')) { function img($src = '', $index_page = FALSE) @@ -200,7 +200,7 @@ if ( ! function_exists('img')) } $img = '$v) { @@ -231,6 +231,46 @@ if ( ! function_exists('img')) // ------------------------------------------------------------------------ +/** + * Doctype + * + * Generates a page document type declaration + * + * Valid options are xhtml-11, xhtml-strict, xhtml-trans, xhtml-frame, + * html4-strict, html4-trans, and html4-frame. Values are saved in the + * doctypes config file. + * + * @access public + * @param string type The doctype to be generated + * @return string + */ +if ( ! function_exists('doctype')) +{ + function doctype($type = 'xhtml1-strict') + { + global $_doctypes; + + if ( ! is_array($_doctypes)) + { + if ( ! require_once(APPPATH.'config/doctypes.php')) + { + return FALSE; + } + } + + if (isset($_doctypes[$type])) + { + return $_doctypes[$type]; + } + else + { + return FALSE; + } + } +} + +// ------------------------------------------------------------------------ + /** * Link * @@ -242,9 +282,9 @@ if ( ! function_exists('img')) * @param string type * @param string title * @param string media - * @param boolean should index_page be added to the css path + * @param boolean should index_page be added to the css path * @return string - */ + */ if ( ! function_exists('link_tag')) { function link_tag($href = '', $rel = 'stylesheet', $type = 'text/css', $title = '', $media = '', $index_page = FALSE) @@ -273,7 +313,7 @@ if ( ! function_exists('link_tag')) $link .= "$k=\"$v\" "; } } - + $link .= "/>"; } else @@ -290,9 +330,9 @@ if ( ! function_exists('link_tag')) { $link .= ' href="'.$CI->config->slash_item('base_url').$href.'" '; } - + $link .= 'rel="'.$rel.'" type="'.$type.'" '; - + if ($media != '') { $link .= 'media="'.$media.'" '; @@ -302,11 +342,11 @@ if ( ! function_exists('link_tag')) { $link .= 'title="'.$title.'" '; } - + $link .= '/>'; } - + return $link; } } @@ -319,7 +359,7 @@ if ( ! function_exists('link_tag')) * @access public * @param array * @return string - */ + */ if ( ! function_exists('meta')) { function meta($name = '', $content = '', $type = 'name', $newline = "\n") @@ -338,7 +378,7 @@ if ( ! function_exists('meta')) $name = array($name); } } - + $str = ''; foreach ($name as $meta) { @@ -346,7 +386,7 @@ if ( ! function_exists('meta')) $name = ( ! isset($meta['name'])) ? '' : $meta['name']; $content = ( ! isset($meta['content'])) ? '' : $meta['content']; $newline = ( ! isset($meta['newline'])) ? "\n" : $meta['newline']; - + $str .= ''.$newline; } @@ -362,7 +402,7 @@ if ( ! function_exists('meta')) * @access public * @param integer * @return string - */ + */ if ( ! function_exists('nbs')) { function nbs($num = 1) diff --git a/helpers/inflector_helper.php b/helpers/inflector_helper.php index 9393f11..e65968a 100644 --- a/helpers/inflector_helper.php +++ b/helpers/inflector_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -87,7 +87,9 @@ if ( ! function_exists('plural')) if ($end == 'y') { - $str = substr($str, 0, strlen($str)-1).'ies'; + // Y preceded by vowel => regular plural + $vowels = array('a', 'e', 'i', 'o', 'u'); + $str = in_array(substr($str, -2, 1), $vowels) ? $str.'s' : substr($str, 0, -1).'ies'; } elseif ($end == 's') { diff --git a/helpers/language_helper.php b/helpers/language_helper.php index 2091fd4..e97a8c7 100644 --- a/helpers/language_helper.php +++ b/helpers/language_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/helpers/number_helper.php b/helpers/number_helper.php index aeca8b2..a041a60 100644 --- a/helpers/number_helper.php +++ b/helpers/number_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/helpers/path_helper.php b/helpers/path_helper.php index da5df98..502fae4 100644 --- a/helpers/path_helper.php +++ b/helpers/path_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/helpers/security_helper.php b/helpers/security_helper.php index 0e2ba78..9cc70aa 100644 --- a/helpers/security_helper.php +++ b/helpers/security_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -32,15 +32,15 @@ * * @access public * @param string - * @param string the character set of your data + * @param bool whether or not the content is an image file * @return string */ if ( ! function_exists('xss_clean')) { - function xss_clean($str, $charset = 'ISO-8859-1') + function xss_clean($str, $is_image = FALSE) { $CI =& get_instance(); - return $CI->input->xss_clean($str, $charset); + return $CI->input->xss_clean($str, $is_image); } } diff --git a/helpers/smiley_helper.php b/helpers/smiley_helper.php index ce7eb8b..f085e53 100644 --- a/helpers/smiley_helper.php +++ b/helpers/smiley_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -28,29 +28,91 @@ // ------------------------------------------------------------------------ /** - * JS Insert Smiley + * Smiley Javascript * - * Generates the javascrip function needed to insert smileys into a form field + * Returns the javascript required for the smiley insertion. Optionally takes + * an array of aliases to loosely couple the smiley array to the view. * * @access public - * @param string form name - * @param string field name - * @return string + * @param mixed alias name or array of alias->field_id pairs + * @param string field_id if alias name was passed in + * @return array */ -if ( ! function_exists('js_insert_smiley')) +if ( ! function_exists('smiley_js')) { - function js_insert_smiley($form_name = '', $form_field = '') - { - return << - function insert_smiley(smiley) + function smiley_js($alias = '', $field_id = '') { - document.{$form_name}.{$form_field}.value += " " + smiley; - } - + static $do_setup = TRUE; + + $r = ''; + + if ($alias != '' && ! is_array($alias)) + { + $alias = array($alias => $field_id); + } + + if ($do_setup === TRUE) + { + $do_setup = FALSE; + + $m = array(); + + if (is_array($alias)) + { + foreach($alias as $name => $id) + { + $m[] = '"'.$name.'" : "'.$id.'"'; + } + } + + $m = '{'.implode(',', $m).'}'; + + $r .= << $id) + { + $r .= 'smiley_map["'.$name.'"] = "'.$id.'";'."\n"; + } + } + } + + return ''; } } + // ------------------------------------------------------------------------ /** @@ -65,8 +127,15 @@ EOF; */ if ( ! function_exists('get_clickable_smileys')) { - function get_clickable_smileys($image_url = '', $smileys = NULL) + function get_clickable_smileys($image_url, $alias = '', $smileys = NULL) { + // For backward compatibility with js_insert_smiley + + if (is_array($alias)) + { + $smileys = $alias; + } + if ( ! is_array($smileys)) { if (FALSE === ($smileys = _get_smiley_array())) @@ -76,8 +145,8 @@ if ( ! function_exists('get_clickable_smileys')) } // Add a trailing slash to the file path if needed - $image_url = preg_replace("/(.+?)\/*$/", "\\1/", $image_url); - + $image_url = rtrim($image_url, '/').'/'; + $used = array(); foreach ($smileys as $key => $val) { @@ -89,12 +158,12 @@ if ( ! function_exists('get_clickable_smileys')) { continue; } - - $link[] = "\"".$smileys[$key][3]."\""; - + + $link[] = "\"".$smileys[$key][3]."\""; + $used[$smileys[$key][0]] = TRUE; } - + return $link; } } @@ -170,6 +239,35 @@ if ( ! function_exists('_get_smiley_array')) } } +// ------------------------------------------------------------------------ + +/** + * JS Insert Smiley + * + * Generates the javascript function needed to insert smileys into a form field + * + * DEPRECATED as of version 1.7.2, use smiley_js instead + * + * @access public + * @param string form name + * @param string field name + * @return string + */ +if ( ! function_exists('js_insert_smiley')) +{ + function js_insert_smiley($form_name = '', $form_field = '') + { + return << + function insert_smiley(smiley) + { + document.{$form_name}.{$form_field}.value += " " + smiley; + } + +EOF; + } +} + /* End of file smiley_helper.php */ /* Location: ./system/helpers/smiley_helper.php */ \ No newline at end of file diff --git a/helpers/string_helper.php b/helpers/string_helper.php index 319002e..3f7f09a 100644 --- a/helpers/string_helper.php +++ b/helpers/string_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/helpers/text_helper.php b/helpers/text_helper.php index 6e61f77..06910e4 100644 --- a/helpers/text_helper.php +++ b/helpers/text_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -87,14 +87,16 @@ if ( ! function_exists('character_limiter')) { return $str; } - + $out = ""; foreach (explode(' ', trim($str)) as $val) { - $out .= $val.' '; + $out .= $val.' '; + if (strlen($out) >= $n) { - return trim($out).$end_char; + $out = trim($out); + return (strlen($out) == strlen($str)) ? $out : $out.$end_char; } } } @@ -125,7 +127,17 @@ if ( ! function_exists('ascii_to_entities')) if ($ordinal < 128) { - $out .= $str[$i]; + /* + If the $temp array has a value but we have moved on, then it seems only + fair that we output that entity and restart $temp before continuing. -Paul + */ + if (count($temp) == 1) + { + $out .= '&#'.array_shift($temp).';'; + $count = 1; + } + + $out .= $str[$i]; } else { @@ -230,21 +242,28 @@ if ( ! function_exists('word_censor')) { return $str; } + + $str = ' '.$str.' '; + + // \w, \b and a few others do not match on a unicode character + // set for performance reasons. As a result words like über + // will not match on a word boundary. Instead, we'll assume that + // a bad word will be bookended by any of these characters. + $delim = '[-_\'\"`(){}<>\[\]|!?@#%&,.:;^~*+=\/ 0-9\n\r\t]'; - $str = ' '.$str.' '; foreach ($censored as $badword) { if ($replacement != '') { - $str = preg_replace("/\b(".str_replace('\*', '\w*?', preg_quote($badword, '/')).")\b/i", $replacement, $str); + $str = preg_replace("/({$delim})(".str_replace('\*', '\w*?', preg_quote($badword, '/')).")({$delim})/i", "\\1{$replacement}\\3", $str); } else { - $str = preg_replace("/\b(".str_replace('\*', '\w*?', preg_quote($badword, '/')).")\b/ie", "str_repeat('#', strlen('\\1'))", $str); + $str = preg_replace("/({$delim})(".str_replace('\*', '\w*?', preg_quote($badword, '/')).")({$delim})/ie", "'\\1'.str_repeat('#', strlen('\\2')).'\\3'", $str); } } - - return trim($str); + + return trim($str); } } diff --git a/helpers/typography_helper.php b/helpers/typography_helper.php index 9cbedbb..2706d53 100644 --- a/helpers/typography_helper.php +++ b/helpers/typography_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -54,17 +54,16 @@ if ( ! function_exists('nl2br_except_pre')) * * @access public * @param string - * @param bool whether to allow javascript event handlers * @param bool whether to reduce multiple instances of double newlines to two * @return string */ if ( ! function_exists('auto_typography')) { - function auto_typography($str, $strip_js_event_handlers = TRUE, $reduce_linebreaks = FALSE) + function auto_typography($str, $reduce_linebreaks = FALSE) { $CI =& get_instance(); $CI->load->library('typography'); - return $CI->typography->auto_typography($str, $strip_js_event_handlers, $reduce_linebreaks); + return $CI->typography->auto_typography($str, $reduce_linebreaks); } } diff --git a/helpers/url_helper.php b/helpers/url_helper.php index fd13dc2..546552a 100644 --- a/helpers/url_helper.php +++ b/helpers/url_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -382,7 +382,7 @@ if ( ! function_exists('auto_link')) { $pop = ($popup == TRUE) ? " target=\"_blank\" " : ""; - for ($i = 0; $i < sizeof($matches['0']); $i++) + for ($i = 0; $i < count($matches['0']); $i++) { $period = ''; if (preg_match("|\.$|", $matches['6'][$i])) @@ -406,9 +406,9 @@ if ( ! function_exists('auto_link')) if ($type != 'url') { - if (preg_match_all("/([a-zA-Z0-9_\.\-\+Å]+)@([a-zA-Z0-9\-]+)\.([a-zA-Z0-9\-\.]*)/i", $str, $matches)) + if (preg_match_all("/([a-zA-Z0-9_\.\-\+]+)@([a-zA-Z0-9\-]+)\.([a-zA-Z0-9\-\.]*)/i", $str, $matches)) { - for ($i = 0; $i < sizeof($matches['0']); $i++) + for ($i = 0; $i < count($matches['0']); $i++) { $period = ''; if (preg_match("|\.$|", $matches['3'][$i])) @@ -471,7 +471,7 @@ if ( ! function_exists('prep_url')) */ if ( ! function_exists('url_title')) { - function url_title($str, $separator = 'dash') + function url_title($str, $separator = 'dash', $lowercase = FALSE) { if ($separator == 'dash') { @@ -491,7 +491,8 @@ if ( ! function_exists('url_title')) '[^a-z0-9\-\._]' => '', $replace.'+' => $replace, $replace.'$' => $replace, - '^'.$replace => $replace + '^'.$replace => $replace, + '\.+$' => '' ); $str = strip_tags($str); @@ -501,6 +502,11 @@ if ( ! function_exists('url_title')) $str = preg_replace("#".$key."#i", $val, $str); } + if ($lowercase === TRUE) + { + $str = strtolower($str); + } + return trim(stripslashes($str)); } } @@ -523,11 +529,16 @@ if ( ! function_exists('redirect')) { function redirect($uri = '', $method = 'location', $http_response_code = 302) { + if ( ! preg_match('#^https?://#i', $uri)) + { + $uri = site_url($uri); + } + switch($method) { - case 'refresh' : header("Refresh:0;url=".site_url($uri)); + case 'refresh' : header("Refresh:0;url=".$uri); break; - default : header("Location: ".site_url($uri), TRUE, $http_response_code); + default : header("Location: ".$uri, TRUE, $http_response_code); break; } exit; diff --git a/helpers/xml_helper.php b/helpers/xml_helper.php index 90cce3d..2a4c808 100644 --- a/helpers/xml_helper.php +++ b/helpers/xml_helper.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/index.html b/index.html new file mode 100644 index 0000000..c942a79 --- /dev/null +++ b/index.html @@ -0,0 +1,10 @@ + + + 403 Forbidden + + + +

    Directory access is forbidden.

    + + + \ No newline at end of file diff --git a/language/english/email_lang.php b/language/english/email_lang.php index 9324277..e3bd113 100644 --- a/language/english/email_lang.php +++ b/language/english/email_lang.php @@ -17,6 +17,7 @@ $lang['email_failed_smtp_login'] = "Failed to send AUTH LOGIN command. Error: %s $lang['email_smtp_auth_un'] = "Failed to authenticate username. Error: %s"; $lang['email_smtp_auth_pw'] = "Failed to authenticate password. Error: %s"; $lang['email_smtp_data_failure'] = "Unable to send data: %s"; +$lang['email_exit_status'] = "Exit status code: %s"; /* End of file email_lang.php */ diff --git a/language/english/imglib_lang.php b/language/english/imglib_lang.php index a587c0b..66505da 100644 --- a/language/english/imglib_lang.php +++ b/language/english/imglib_lang.php @@ -17,6 +17,7 @@ $lang['imglib_writing_failed_gif'] = "GIF image."; $lang['imglib_invalid_path'] = "The path to the image is not correct."; $lang['imglib_copy_failed'] = "The image copy routine failed."; $lang['imglib_missing_font'] = "Unable to find a font to use."; +$lang['imglib_save_failed'] = "Unable to save the image. Please make sure the image and file directory are writable."; /* End of file imglib_lang.php */ diff --git a/libraries/Benchmark.php b/libraries/Benchmark.php index fec5071..695029e 100644 --- a/libraries/Benchmark.php +++ b/libraries/Benchmark.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/libraries/Calendar.php b/libraries/Calendar.php index ca4b9d5..68d4022 100644 --- a/libraries/Calendar.php +++ b/libraries/Calendar.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -270,7 +270,7 @@ class CI_Calendar { } else { - $month_names = array('01' => 'cal_january', '02' => 'cal_february', '03' => 'cal_march', '04' => 'cal_april', '05' => 'cal_may', '06' => 'cal_june', '07' => 'cal_july', '08' => 'cal_august', '09' => 'cal_september', '10' => 'cal_october', '11' => 'cal_november', '12' => 'cal_december'); + $month_names = array('01' => 'cal_january', '02' => 'cal_february', '03' => 'cal_march', '04' => 'cal_april', '05' => 'cal_mayl', '06' => 'cal_june', '07' => 'cal_july', '08' => 'cal_august', '09' => 'cal_september', '10' => 'cal_october', '11' => 'cal_november', '12' => 'cal_december'); } $month = $month_names[$month]; diff --git a/libraries/Cart.php b/libraries/Cart.php new file mode 100644 index 0000000..2eb8b75 --- /dev/null +++ b/libraries/Cart.php @@ -0,0 +1,550 @@ +CI =& get_instance(); + + // Are any config settings being passed manually? If so, set them + $config = array(); + if (count($params) > 0) + { + foreach ($params as $key => $val) + { + $config[$key] = $val; + } + } + + // Load the Sessions class + $this->CI->load->library('session', $config); + + // Grab the shopping cart array from the session table, if it exists + if ($this->CI->session->userdata('cart_contents') !== FALSE) + { + $this->_cart_contents = $this->CI->session->userdata('cart_contents'); + } + else + { + // No cart exists so we'll set some base values + $this->_cart_contents['cart_total'] = 0; + $this->_cart_contents['total_items'] = 0; + } + + log_message('debug', "Cart Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Insert items into the cart and save it to the session table + * + * @access public + * @param array + * @return bool + */ + function insert($items = array()) + { + // Was any cart data passed? No? Bah... + if ( ! is_array($items) OR count($items) == 0) + { + log_message('error', 'The insert method must be passed an array containing data.'); + return FALSE; + } + + // You can either insert a single product using a one-dimensional array, + // or multiple products using a multi-dimensional one. The way we + // determine the array type is by looking for a required array key named "id" + // at the top level. If it's not found, we will assume it's a multi-dimensional array. + + $save_cart = FALSE; + if (isset($items['id'])) + { + if ($this->_insert($items) == TRUE) + { + $save_cart = TRUE; + } + } + else + { + foreach ($items as $val) + { + if (is_array($val) AND isset($val['id'])) + { + if ($this->_insert($val) == TRUE) + { + $save_cart = TRUE; + } + } + } + } + + // Save the cart data if the insert was successful + if ($save_cart == TRUE) + { + $this->_save_cart(); + return TRUE; + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Insert + * + * @access private + * @param array + * @return bool + */ + function _insert($items = array()) + { + // Was any cart data passed? No? Bah... + if ( ! is_array($items) OR count($items) == 0) + { + log_message('error', 'The insert method must be passed an array containing data.'); + return FALSE; + } + + // -------------------------------------------------------------------- + + // Does the $items array contain an id, quantity, price, and name? These are required + if ( ! isset($items['id']) OR ! isset($items['qty']) OR ! isset($items['price']) OR ! isset($items['name'])) + { + log_message('error', 'The cart array must contain a product ID, quantity, price, and name.'); + return FALSE; + } + + // -------------------------------------------------------------------- + + // Prep the quantity. It can only be a number. Duh... + $items['qty'] = trim(preg_replace('/([^0-9])/i', '', $items['qty'])); + // Trim any leading zeros + $items['qty'] = trim(preg_replace('/(^[0]+)/i', '', $items['qty'])); + + // If the quantity is zero or blank there's nothing for us to do + if ( ! is_numeric($items['qty']) OR $items['qty'] == 0) + { + return FALSE; + } + + // -------------------------------------------------------------------- + + // Validate the product ID. It can only be alpha-numeric, dashes, underscores or periods + // Not totally sure we should impose this rule, but it seems prudent to standardize IDs. + // Note: These can be user-specified by setting the $this->product_id_rules variable. + if ( ! preg_match("/^[".$this->product_id_rules."]+$/i", $items['id'])) + { + log_message('error', 'Invalid product ID. The product ID can only contain alpha-numeric characters, dashes, and underscores'); + return FALSE; + } + + // -------------------------------------------------------------------- + + // Validate the product name. It can only be alpha-numeric, dashes, underscores, colons or periods. + // Note: These can be user-specified by setting the $this->product_name_rules variable. + if ( ! preg_match("/^[".$this->product_name_rules."]+$/i", $items['name'])) + { + log_message('error', 'An invalid name was submitted as the product name: '.$items['name'].' The name can only contain alpha-numeric characters, dashes, underscores, colons, and spaces'); + return FALSE; + } + + // -------------------------------------------------------------------- + + // Prep the price. Remove anything that isn't a number or decimal point. + $items['price'] = trim(preg_replace('/([^0-9\.])/i', '', $items['price'])); + // Trim any leading zeros + $items['price'] = trim(preg_replace('/(^[0]+)/i', '', $items['price'])); + + // Is the price a valid number? + if ( ! is_numeric($items['price'])) + { + log_message('error', 'An invalid price was submitted for product ID: '.$items['id']); + return FALSE; + } + + // -------------------------------------------------------------------- + + // We now need to create a unique identifier for the item being inserted into the cart. + // Every time something is added to the cart it is stored in the master cart array. + // Each row in the cart array, however, must have a unique index that identifies not only + // a particular product, but makes it possible to store identical products with different options. + // For example, what if someone buys two identical t-shirts (same product ID), but in + // different sizes? The product ID (and other attributes, like the name) will be identical for + // both sizes because it's the same shirt. The only difference will be the size. + // Internally, we need to treat identical submissions, but with different options, as a unique product. + // Our solution is to convert the options array to a string and MD5 it along with the product ID. + // This becomes the unique "row ID" + if (isset($items['options']) AND count($items['options']) > 0) + { + $rowid = md5($items['id'].implode('', $items['options'])); + } + else + { + // No options were submitted so we simply MD5 the product ID. + // Technically, we don't need to MD5 the ID in this case, but it makes + // sense to standardize the format of array indexes for both conditions + $rowid = md5($items['id']); + } + + // -------------------------------------------------------------------- + + // Now that we have our unique "row ID", we'll add our cart items to the master array + + // let's unset this first, just to make sure our index contains only the data from this submission + unset($this->_cart_contents[$rowid]); + + // Create a new index with our new row ID + $this->_cart_contents[$rowid]['rowid'] = $rowid; + + // And add the new items to the cart array + foreach ($items as $key => $val) + { + $this->_cart_contents[$rowid][$key] = $val; + } + + // Woot! + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Update the cart + * + * This function permits the quantity of a given item to be changed. + * Typically it is called from the "view cart" page if a user makes + * changes to the quantity before checkout. That array must contain the + * product ID and quantity for each item. + * + * @access public + * @param array + * @param string + * @return bool + */ + function update($items = array()) + { + // Was any cart data passed? + if ( ! is_array($items) OR count($items) == 0) + { + return FALSE; + } + + // You can either update a single product using a one-dimensional array, + // or multiple products using a multi-dimensional one. The way we + // determine the array type is by looking for a required array key named "id". + // If it's not found we assume it's a multi-dimensional array + $save_cart = FALSE; + if (isset($items['rowid']) AND isset($items['qty'])) + { + if ($this->_update($items) == TRUE) + { + $save_cart = TRUE; + } + } + else + { + foreach ($items as $val) + { + if (is_array($val) AND isset($val['rowid']) AND isset($val['qty'])) + { + if ($this->_update($val) == TRUE) + { + $save_cart = TRUE; + } + } + } + } + + // Save the cart data if the insert was successful + if ($save_cart == TRUE) + { + $this->_save_cart(); + return TRUE; + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Update the cart + * + * This function permits the quantity of a given item to be changed. + * Typically it is called from the "view cart" page if a user makes + * changes to the quantity before checkout. That array must contain the + * product ID and quantity for each item. + * + * @access private + * @param array + * @return bool + */ + function _update($items = array()) + { + // Without these array indexes there is nothing we can do + if ( ! isset($items['qty']) OR ! isset($items['rowid']) OR ! isset($this->_cart_contents[$items['rowid']])) + { + return FALSE; + } + + // Prep the quantity + $items['qty'] = preg_replace('/([^0-9])/i', '', $items['qty']); + + // Is the quantity a number? + if ( ! is_numeric($items['qty'])) + { + return FALSE; + } + + // Is the new quantity different than what is already saved in the cart? + // If it's the same there's nothing to do + if ($this->_cart_contents[$items['rowid']]['qty'] == $items['qty']) + { + return FALSE; + } + + // Is the quantity zero? If so we will remove the item from the cart. + // If the quantity is greater than zero we are updating + if ($items['qty'] == 0) + { + unset($this->_cart_contents[$items['rowid']]); + } + else + { + $this->_cart_contents[$items['rowid']]['qty'] = $items['qty']; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Save the cart array to the session DB + * + * @access private + * @return bool + */ + function _save_cart() + { + // Unset these so our total can be calculated correctly below + unset($this->_cart_contents['total_items']); + unset($this->_cart_contents['cart_total']); + + // Lets add up the individual prices and set the cart sub-total + $total = 0; + foreach ($this->_cart_contents as $key => $val) + { + // We make sure the array contains the proper indexes + if ( ! is_array($val) OR ! isset($val['price']) OR ! isset($val['qty'])) + { + continue; + } + + $total += ($val['price'] * $val['qty']); + + // Set the subtotal + $this->_cart_contents[$key]['subtotal'] = ($this->_cart_contents[$key]['price'] * $this->_cart_contents[$key]['qty']); + } + + // Set the cart total and total items. + $this->_cart_contents['total_items'] = count($this->_cart_contents); + $this->_cart_contents['cart_total'] = $total; + + // Is our cart empty? If so we delete it from the session + if (count($this->_cart_contents) <= 2) + { + $this->CI->session->unset_userdata('cart_contents'); + + // Nothing more to do... coffee time! + return FALSE; + } + + // If we made it this far it means that our cart has data. + // Let's pass it to the Session class so it can be stored + $this->CI->session->set_userdata(array('cart_contents' => $this->_cart_contents)); + + // Woot! + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Cart Total + * + * @access public + * @return integer + */ + function total() + { + return $this->_cart_contents['cart_total']; + } + + // -------------------------------------------------------------------- + + /** + * Total Items + * + * Returns the total item count + * + * @access public + * @return integer + */ + function total_items() + { + return $this->_cart_contents['total_items']; + } + + // -------------------------------------------------------------------- + + /** + * Cart Contents + * + * Returns the entire cart array + * + * @access public + * @return array + */ + function contents() + { + $cart = $this->_cart_contents; + + // Remove these so they don't create a problem when showing the cart table + unset($cart['total_items']); + unset($cart['cart_total']); + + return $cart; + } + + // -------------------------------------------------------------------- + + /** + * Has options + * + * Returns TRUE if the rowid passed to this function correlates to an item + * that has options associated with it. + * + * @access public + * @return array + */ + function has_options($rowid = '') + { + if ( ! isset($this->_cart_contents[$rowid]['options']) OR count($this->_cart_contents[$rowid]['options']) === 0) + { + return FALSE; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Product options + * + * Returns the an array of options, for a particular product row ID + * + * @access public + * @return array + */ + function product_options($rowid = '') + { + if ( ! isset($this->_cart_contents[$rowid]['options'])) + { + return array(); + } + + return $this->_cart_contents[$rowid]['options']; + } + + // -------------------------------------------------------------------- + + /** + * Format Number + * + * Returns the supplied number with commas and a decimal point. + * + * @access public + * @return integer + */ + function format_number($n = '') + { + if ($n == '') + { + return ''; + } + + // Remove anything that isn't a number or decimal point. + $n = trim(preg_replace('/([^0-9\.])/i', '', $n)); + + return number_format($n, 2, '.', ','); + } + + // -------------------------------------------------------------------- + + /** + * Destroy the cart + * + * Empties the cart and kills the session + * + * @access public + * @return null + */ + function destroy() + { + unset($this->_cart_contents); + + $this->_cart_contents['cart_total'] = 0; + $this->_cart_contents['total_items'] = 0; + + $this->CI->session->unset_userdata('cart_contents'); + } + + +} +// END Cart Class + +/* End of file Cart.php */ +/* Location: ./system/libraries/Cart.php */ \ No newline at end of file diff --git a/libraries/Config.php b/libraries/Config.php index 027f6bf..4ef2786 100644 --- a/libraries/Config.php +++ b/libraries/Config.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -203,7 +203,7 @@ class CI_Config { else { $suffix = ($this->item('url_suffix') == FALSE) ? '' : $this->item('url_suffix'); - return $this->slash_item('base_url').$this->slash_item('index_page').preg_replace("|^/*(.+?)/*$|", "\\1", $uri).$suffix; + return $this->slash_item('base_url').$this->slash_item('index_page').trim($uri, '/').$suffix; } } diff --git a/libraries/Controller.php b/libraries/Controller.php index db156c8..5e93de3 100644 --- a/libraries/Controller.php +++ b/libraries/Controller.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -18,7 +18,7 @@ /** * CodeIgniter Application Controller Class * - * This class object is the super class the every library in + * This class object is the super class that every library in * CodeIgniter will be assigned to. * * @package CodeIgniter diff --git a/libraries/Email.php b/libraries/Email.php index 7bcb1d8..5858159 100644 --- a/libraries/Email.php +++ b/libraries/Email.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -48,7 +48,7 @@ class CI_Email { var $crlf = "\n"; // The RFC 2045 compliant CRLF for quoted-printable is "\r\n". Apparently some servers, // even on the receiving end think they need to muck with CRLFs, so using "\n", while // distasteful, is the only thing that seems to work for all environments. - var $send_multipart = TRUE; // TRUE/FALSE - Yahoo does not like multipart alternative, so this is an override. Set to FALSE for Yahoo. + var $send_multipart = TRUE; // TRUE/FALSE - Yahoo does not like multipart alternative, so this is an override. Set to FALSE for Yahoo. var $bcc_batch_mode = FALSE; // TRUE/FALSE Turns on/off Bcc batch feature var $bcc_batch_size = 200; // If bcc_batch_mode = TRUE, sets max number of Bccs in each batch var $_safe_mode = FALSE; @@ -83,17 +83,17 @@ class CI_Email { * The constructor can be passed an array of config values */ function CI_Email($config = array()) - { + { if (count($config) > 0) { $this->initialize($config); - } + } else { - $this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE; + $this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE; $this->_safe_mode = ((boolean)@ini_get("safe_mode") === FALSE) ? FALSE : TRUE; } - + log_message('debug', "Email Class Initialized"); } @@ -122,14 +122,14 @@ class CI_Email { else { $this->$key = $val; - } + } } } - - $this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE; + + $this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE; $this->_safe_mode = ((boolean)@ini_get("safe_mode") === FALSE) ? FALSE : TRUE; } - + // -------------------------------------------------------------------- /** @@ -137,7 +137,7 @@ class CI_Email { * * @access public * @return void - */ + */ function clear($clear_attachments = FALSE) { $this->_subject = ""; @@ -157,9 +157,9 @@ class CI_Email { $this->_attach_name = array(); $this->_attach_type = array(); $this->_attach_disp = array(); - } + } } - + // -------------------------------------------------------------------- /** @@ -169,7 +169,7 @@ class CI_Email { * @param string * @param string * @return void - */ + */ function from($from, $name = '') { if (preg_match( '/\<(.*)\>/', $from, $match)) @@ -181,16 +181,26 @@ class CI_Email { { $this->validate_email($this->_str_to_array($from)); } - - if ($name != '' && strncmp($name, '"', 1) != 0) + + // prepare the display name + if ($name != '') { - $name = '"'.$name.'"'; + // only use Q encoding if there are characters that would require it + if ( ! preg_match('/[\200-\377]/', $name)) + { + // add slashes for non-printing characters, slashes, and double quotes, and surround it in double quotes + $name = '"'.addcslashes($name, "\0..\37\177'\"\\").'"'; + } + else + { + $name = $this->_prep_q_encoding($name, TRUE); + } } - + $this->_set_header('From', $name.' <'.$from.'>'); $this->_set_header('Return-Path', '<'.$from.'>'); } - + // -------------------------------------------------------------------- /** @@ -200,7 +210,7 @@ class CI_Email { * @param string * @param string * @return void - */ + */ function reply_to($replyto, $name = '') { if (preg_match( '/\<(.*)\>/', $replyto, $match)) @@ -210,7 +220,7 @@ class CI_Email { if ($this->validate) { - $this->validate_email($this->_str_to_array($replyto)); + $this->validate_email($this->_str_to_array($replyto)); } if ($name == '') @@ -226,7 +236,7 @@ class CI_Email { $this->_set_header('Reply-To', $name.' <'.$replyto.'>'); $this->_replyto_flag = TRUE; } - + // -------------------------------------------------------------------- /** @@ -235,17 +245,17 @@ class CI_Email { * @access public * @param string * @return void - */ + */ function to($to) { $to = $this->_str_to_array($to); $to = $this->clean_email($to); - + if ($this->validate) { $this->validate_email($to); } - + if ($this->_get_protocol() != 'mail') { $this->_set_header('To', implode(", ", $to)); @@ -259,9 +269,9 @@ class CI_Email { break; case 'mail' : $this->_recipients = implode(", ", $to); break; - } + } } - + // -------------------------------------------------------------------- /** @@ -270,9 +280,9 @@ class CI_Email { * @access public * @param string * @return void - */ + */ function cc($cc) - { + { $cc = $this->_str_to_array($cc); $cc = $this->clean_email($cc); @@ -288,7 +298,7 @@ class CI_Email { $this->_cc_array = $cc; } } - + // -------------------------------------------------------------------- /** @@ -298,7 +308,7 @@ class CI_Email { * @param string * @param string * @return void - */ + */ function bcc($bcc, $limit = '') { if ($limit != '' && is_numeric($limit)) @@ -324,7 +334,7 @@ class CI_Email { $this->_set_header('Bcc', implode(", ", $bcc)); } } - + // -------------------------------------------------------------------- /** @@ -333,22 +343,13 @@ class CI_Email { * @access public * @param string * @return void - */ + */ function subject($subject) { - if (strpos($subject, "\r") !== FALSE OR strpos($subject, "\n") !== FALSE) - { - $subject = str_replace(array("\r\n", "\r", "\n"), '', $subject); - } - - if (strpos($subject, "\t")) - { - $subject = str_replace("\t", ' ', $subject); - } - - $this->_set_header('Subject', trim($subject)); + $subject = $this->_prep_q_encoding($subject); + $this->_set_header('Subject', $subject); } - + // -------------------------------------------------------------------- /** @@ -357,12 +358,12 @@ class CI_Email { * @access public * @param string * @return void - */ + */ function message($body) { - $this->_body = stripslashes(rtrim(str_replace("\r", "", $body))); - } - + $this->_body = stripslashes(rtrim(str_replace("\r", "", $body))); + } + // -------------------------------------------------------------------- /** @@ -370,10 +371,10 @@ class CI_Email { * * @access public * @param string - * @return string + * @return void */ function attach($filename, $disposition = 'attachment') - { + { $this->_attach_name[] = $filename; $this->_attach_type[] = $this->_mime_types(next(explode('.', basename($filename)))); $this->_attach_disp[] = $disposition; // Can also be 'inline' Not sure if it matters @@ -388,12 +389,12 @@ class CI_Email { * @param string * @param string * @return void - */ + */ function _set_header($header, $value) { $this->_headers[$header] = $value; } - + // -------------------------------------------------------------------- /** @@ -402,7 +403,7 @@ class CI_Email { * @access private * @param string * @return array - */ + */ function _str_to_array($email) { if ( ! is_array($email)) @@ -419,7 +420,7 @@ class CI_Email { } return $email; } - + // -------------------------------------------------------------------- /** @@ -428,12 +429,12 @@ class CI_Email { * @access public * @param string * @return void - */ + */ function set_alt_message($str = '') { $this->alt_message = ($str == '') ? '' : $str; } - + // -------------------------------------------------------------------- /** @@ -442,12 +443,12 @@ class CI_Email { * @access public * @param string * @return void - */ + */ function set_mailtype($type = 'text') { $this->mailtype = ($type == 'html') ? 'html' : 'text'; } - + // -------------------------------------------------------------------- /** @@ -456,12 +457,12 @@ class CI_Email { * @access public * @param string * @return void - */ + */ function set_wordwrap($wordwrap = TRUE) { $this->wordwrap = ($wordwrap === FALSE) ? FALSE : TRUE; } - + // -------------------------------------------------------------------- /** @@ -470,12 +471,12 @@ class CI_Email { * @access public * @param string * @return void - */ + */ function set_protocol($protocol = 'mail') { $this->protocol = ( ! in_array($protocol, $this->_protocols, TRUE)) ? 'mail' : strtolower($protocol); } - + // -------------------------------------------------------------------- /** @@ -484,7 +485,7 @@ class CI_Email { * @access public * @param integer * @return void - */ + */ function set_priority($n = 3) { if ( ! is_numeric($n)) @@ -492,16 +493,16 @@ class CI_Email { $this->priority = 3; return; } - + if ($n < 1 OR $n > 5) { $this->priority = 3; return; } - + $this->priority = $n; } - + // -------------------------------------------------------------------- /** @@ -510,18 +511,18 @@ class CI_Email { * @access public * @param string * @return void - */ + */ function set_newline($newline = "\n") { if ($newline != "\n" AND $newline != "\r\n" AND $newline != "\r") { - $this->newline = "\n"; + $this->newline = "\n"; return; } - - $this->newline = $newline; + + $this->newline = $newline; } - + // -------------------------------------------------------------------- /** @@ -530,18 +531,18 @@ class CI_Email { * @access public * @param string * @return void - */ + */ function set_crlf($crlf = "\n") { if ($crlf != "\n" AND $crlf != "\r\n" AND $crlf != "\r") { - $this->crlf = "\n"; + $this->crlf = "\n"; return; } - - $this->crlf = $crlf; + + $this->crlf = $crlf; } - + // -------------------------------------------------------------------- /** @@ -549,13 +550,13 @@ class CI_Email { * * @access private * @return void - */ + */ function _set_boundaries() { $this->_alt_boundary = "B_ALT_".uniqid(''); // multipart/alternative $this->_atc_boundary = "B_ATC_".uniqid(''); // attachment boundary } - + // -------------------------------------------------------------------- /** @@ -563,16 +564,16 @@ class CI_Email { * * @access private * @return string - */ + */ function _get_message_id() { $from = $this->_headers['Return-Path']; $from = str_replace(">", "", $from); $from = str_replace("<", "", $from); - - return "<".uniqid('').strstr($from, '@').">"; + + return "<".uniqid('').strstr($from, '@').">"; } - + // -------------------------------------------------------------------- /** @@ -581,7 +582,7 @@ class CI_Email { * @access private * @param bool * @return string - */ + */ function _get_protocol($return = TRUE) { $this->protocol = strtolower($this->protocol); @@ -592,7 +593,7 @@ class CI_Email { return $this->protocol; } } - + // -------------------------------------------------------------------- /** @@ -601,7 +602,7 @@ class CI_Email { * @access private * @param bool * @return string - */ + */ function _get_encoding($return = TRUE) { $this->_encoding = ( ! in_array($this->_encoding, $this->_bit_depths)) ? '8bit' : $this->_encoding; @@ -613,10 +614,10 @@ class CI_Email { $this->_encoding = '7bit'; } } - + if ($return == TRUE) { - return $this->_encoding; + return $this->_encoding; } } @@ -627,9 +628,9 @@ class CI_Email { * * @access private * @return string - */ + */ function _get_content_type() - { + { if ($this->mailtype == 'html' && count($this->_attach_name) == 0) { return 'html'; @@ -647,7 +648,7 @@ class CI_Email { return 'plain'; } } - + // -------------------------------------------------------------------- /** @@ -655,7 +656,7 @@ class CI_Email { * * @access private * @return string - */ + */ function _set_date() { $timezone = date("Z"); @@ -665,7 +666,7 @@ class CI_Email { return sprintf("%s %s%04d", date("D, j M Y H:i:s"), $operator, $timezone); } - + // -------------------------------------------------------------------- /** @@ -673,12 +674,12 @@ class CI_Email { * * @access private * @return string - */ + */ function _get_mime_message() { return "This is a multi-part message in MIME format.".$this->newline."Your email application may not support this format."; } - + // -------------------------------------------------------------------- /** @@ -687,9 +688,9 @@ class CI_Email { * @access public * @param string * @return bool - */ + */ function validate_email($email) - { + { if ( ! is_array($email)) { $this->_set_error_message('email_must_be_array'); @@ -704,8 +705,10 @@ class CI_Email { return FALSE; } } - } - + + return TRUE; + } + // -------------------------------------------------------------------- /** @@ -714,12 +717,12 @@ class CI_Email { * @access public * @param string * @return bool - */ + */ function valid_email($address) { return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $address)) ? FALSE : TRUE; } - + // -------------------------------------------------------------------- /** @@ -728,7 +731,7 @@ class CI_Email { * @access public * @param string * @return string - */ + */ function clean_email($email) { if ( ! is_array($email)) @@ -742,7 +745,7 @@ class CI_Email { return $email; } } - + $clean_email = array(); foreach ($email as $addy) @@ -753,13 +756,13 @@ class CI_Email { } else { - $clean_email[] = $addy; + $clean_email[] = $addy; } } return $clean_email; } - + // -------------------------------------------------------------------- /** @@ -772,7 +775,7 @@ class CI_Email { * * @access private * @return string - */ + */ function _get_alt_message() { if ($this->alt_message != "") @@ -796,18 +799,18 @@ class CI_Email { for ($i = 20; $i >= 3; $i--) { $n = ""; - + for ($x = 1; $x <= $i; $x ++) { $n .= "\n"; } - $body = str_replace($n, "\n\n", $body); + $body = str_replace($n, "\n\n", $body); } return $this->word_wrap($body, '76'); } - + // -------------------------------------------------------------------- /** @@ -817,7 +820,7 @@ class CI_Email { * @param string * @param integer * @return string - */ + */ function word_wrap($str, $charlim = '') { // Se the character limit @@ -832,10 +835,10 @@ class CI_Email { // Standardize newlines if (strpos($str, "\r") !== FALSE) { - $str = str_replace(array("\r\n", "\r"), "\n", $str); + $str = str_replace(array("\r\n", "\r"), "\n", $str); } - // If the current word is surrounded by {unwrap} tags we'll + // If the current word is surrounded by {unwrap} tags we'll // strip the entire chunk and replace it with a marker. $unwrap = array(); if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches)) @@ -847,25 +850,25 @@ class CI_Email { } } - // Use PHP's native function to do the initial wordwrap. - // We set the cut flag to FALSE so that any individual words that are + // Use PHP's native function to do the initial wordwrap. + // We set the cut flag to FALSE so that any individual words that are // too long get left alone. In the next step we'll deal with them. $str = wordwrap($str, $charlim, "\n", FALSE); // Split the string into individual lines of text and cycle through them $output = ""; - foreach (explode("\n", $str) as $line) + foreach (explode("\n", $str) as $line) { // Is the line within the allowed character count? // If so we'll join it to the output and continue if (strlen($line) <= $charlim) { - $output .= $line.$this->newline; + $output .= $line.$this->newline; continue; } $temp = ''; - while((strlen($line)) > $charlim) + while((strlen($line)) > $charlim) { // If the over-length word is a URL we won't wrap it if (preg_match("!\[url.+\]|://|wwww.!", $line)) @@ -877,8 +880,8 @@ class CI_Email { $temp .= substr($line, 0, $charlim-1); $line = substr($line, $charlim-1); } - - // If $temp contains data it means we had to split up an over-length + + // If $temp contains data it means we had to split up an over-length // word into smaller chunks so we'll add it back to our current line if ($temp != '') { @@ -894,16 +897,16 @@ class CI_Email { // Put our markers back if (count($unwrap) > 0) - { + { foreach ($unwrap as $key => $val) { $output = str_replace("{{unwrapped".$key."}}", $val, $output); } } - return $output; + return $output; } - + // -------------------------------------------------------------------- /** @@ -912,7 +915,7 @@ class CI_Email { * @access private * @param string * @return string - */ + */ function _build_headers() { $this->_set_header('X-Sender', $this->clean_email($this->_headers['From'])); @@ -921,7 +924,7 @@ class CI_Email { $this->_set_header('Message-ID', $this->_get_message_id()); $this->_set_header('Mime-Version', '1.0'); } - + // -------------------------------------------------------------------- /** @@ -936,7 +939,7 @@ class CI_Email { { $this->_subject = $this->_headers['Subject']; unset($this->_headers['Subject']); - } + } reset($this->_headers); $this->_header_str = ""; @@ -953,10 +956,10 @@ class CI_Email { if ($this->_get_protocol() == 'mail') { - $this->_header_str = substr($this->_header_str, 0, -1); + $this->_header_str = rtrim($this->_header_str); } } - + // -------------------------------------------------------------------- /** @@ -964,23 +967,23 @@ class CI_Email { * * @access private * @return void - */ + */ function _build_message() { if ($this->wordwrap === TRUE AND $this->mailtype != 'html') { $this->_body = $this->word_wrap($this->_body); } - + $this->_set_boundaries(); $this->_write_headers(); $hdr = ($this->_get_protocol() == 'mail') ? $this->newline : ''; - + switch ($this->_get_content_type()) { case 'plain' : - + $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline; $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding(); @@ -988,7 +991,7 @@ class CI_Email { { $this->_header_str .= $hdr; $this->_finalbody = $this->_body; - + return; } @@ -996,21 +999,21 @@ class CI_Email { $this->_finalbody = $hdr; return; - + break; case 'html' : - + if ($this->send_multipart === FALSE) { $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline; $hdr .= "Content-Transfer-Encoding: quoted-printable"; } else - { - $hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline; + { + $hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline . $this->newline; $hdr .= $this->_get_mime_message() . $this->newline . $this->newline; $hdr .= "--" . $this->_alt_boundary . $this->newline; - + $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline; $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline; $hdr .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline; @@ -1025,12 +1028,12 @@ class CI_Email { { $this->_header_str .= $hdr; $this->_finalbody = $this->_body . $this->newline . $this->newline; - + if ($this->send_multipart !== FALSE) { $this->_finalbody .= "--" . $this->_alt_boundary . "--"; } - + return; } @@ -1047,18 +1050,18 @@ class CI_Email { break; case 'plain-attach' : - - $hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline; + + $hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline . $this->newline; $hdr .= $this->_get_mime_message() . $this->newline . $this->newline; $hdr .= "--" . $this->_atc_boundary . $this->newline; - + $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline; $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding(); if ($this->_get_protocol() == 'mail') { $this->_header_str .= $hdr; - + $body = $this->_body . $this->newline . $this->newline; } @@ -1067,18 +1070,18 @@ class CI_Email { break; case 'html-attach' : - - $hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline; + + $hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline . $this->newline; $hdr .= $this->_get_mime_message() . $this->newline . $this->newline; $hdr .= "--" . $this->_atc_boundary . $this->newline; - + $hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline .$this->newline; $hdr .= "--" . $this->_alt_boundary . $this->newline; $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline; $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline; $hdr .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline; - + $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline; $hdr .= "Content-Transfer-Encoding: quoted-printable"; @@ -1086,8 +1089,8 @@ class CI_Email { if ($this->_get_protocol() == 'mail') { - $this->_header_str .= $hdr; - + $this->_header_str .= $hdr; + $body = $this->_body . $this->newline . $this->newline; $body .= "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline; } @@ -1113,7 +1116,7 @@ class CI_Email { { $this->_set_error_message('email_attachment_missing', $filename); return FALSE; - } + } $h = "--".$this->_atc_boundary.$this->newline; $h .= "Content-type: ".$ctype."; "; @@ -1123,31 +1126,31 @@ class CI_Email { $attachment[$z++] = $h; $file = filesize($filename) +1; - + if ( ! $fp = fopen($filename, FOPEN_READ)) { $this->_set_error_message('email_attachment_unreadable', $filename); return FALSE; } - + $attachment[$z++] = chunk_split(base64_encode(fread($fp, $file))); fclose($fp); } if ($this->_get_protocol() == 'mail') { - $this->_finalbody = $body . implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--"; - + $this->_finalbody = $body . implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--"; + return; } - $this->_finalbody = $hdr.implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--"; + $this->_finalbody = $hdr.implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--"; - return; + return; } - + // -------------------------------------------------------------------- - + /** * Prep Quoted Printable * @@ -1174,7 +1177,7 @@ class CI_Email { // kill nulls $str = preg_replace('/\x00+/', '', $str); - + // Standardize newlines if (strpos($str, "\r") !== FALSE) { @@ -1241,19 +1244,91 @@ class CI_Email { // -------------------------------------------------------------------- + /** + * Prep Q Encoding + * + * Performs "Q Encoding" on a string for use in email headers. It's related + * but not identical to quoted-printable, so it has its own method + * + * @access public + * @param str + * @param bool // set to TRUE for processing From: headers + * @return str + */ + function _prep_q_encoding($str, $from = FALSE) + { + $str = str_replace(array("\r", "\n"), array('', ''), $str); + + // Line length must not exceed 76 characters, so we adjust for + // a space, 7 extra characters =??Q??=, and the charset that we will add to each line + $limit = 75 - 7 - strlen($this->charset); + + // these special characters must be converted too + $convert = array('_', '=', '?'); + + if ($from === TRUE) + { + $convert[] = ','; + $convert[] = ';'; + } + + $output = ''; + $temp = ''; + + for ($i = 0, $length = strlen($str); $i < $length; $i++) + { + // Grab the next character + $char = substr($str, $i, 1); + $ascii = ord($char); + + // convert ALL non-printable ASCII characters and our specials + if ($ascii < 32 OR $ascii > 126 OR in_array($char, $convert)) + { + $char = '='.dechex($ascii); + } + + // handle regular spaces a bit more compactly than =20 + if ($ascii == 32) + { + $char = '_'; + } + + // If we're at the character limit, add the line to the output, + // reset our temp variable, and keep on chuggin' + if ((strlen($temp) + strlen($char)) >= $limit) + { + $output .= $temp.$this->crlf; + $temp = ''; + } + + // Add the character to our temporary line + $temp .= $char; + } + + $str = $output.$temp; + + // wrap each line with the shebang, charset, and transfer encoding + // the preceding space on successive lines is required for header "folding" + $str = trim(preg_replace('/^(.*)$/m', ' =?'.$this->charset.'?Q?$1?=', $str)); + + return $str; + } + + // -------------------------------------------------------------------- + /** * Send Email * * @access public * @return bool - */ + */ function send() - { + { if ($this->_replyto_flag == FALSE) { $this->reply_to($this->_headers['From']); } - + if (( ! isset($this->_recipients) AND ! isset($this->_headers['To'])) AND ( ! isset($this->_bcc_array) AND ! isset($this->_headers['Bcc'])) AND ( ! isset($this->_headers['Cc']))) @@ -1281,7 +1356,7 @@ class CI_Email { return TRUE; } } - + // -------------------------------------------------------------------- /** @@ -1289,7 +1364,7 @@ class CI_Email { * * @access public * @return bool - */ + */ function batch_bcc_send() { $float = $this->bcc_batch_size -1; @@ -1306,12 +1381,12 @@ class CI_Email { } if ($i == $float) - { + { $chunk[] = substr($set, 1); $float = $float + $this->bcc_batch_size; $set = ""; } - + if ($i == count($this->_bcc_array)-1) { $chunk[] = substr($set, 1); @@ -1325,7 +1400,7 @@ class CI_Email { $bcc = $this->_str_to_array($chunk[$i]); $bcc = $this->clean_email($bcc); - + if ($this->protocol != 'smtp') { $this->_set_header('Bcc', implode(", ", $bcc)); @@ -1334,12 +1409,12 @@ class CI_Email { { $this->_bcc_array = $bcc; } - + $this->_build_message(); $this->_spool_email(); } } - + // -------------------------------------------------------------------- /** @@ -1347,12 +1422,12 @@ class CI_Email { * * @access private * @return void - */ + */ function _unwrap_specials() { $this->_finalbody = preg_replace_callback("/\{unwrap\}(.*?)\{\/unwrap\}/si", array($this, '_remove_nl_callback'), $this->_finalbody); } - + // -------------------------------------------------------------------- /** @@ -1360,17 +1435,17 @@ class CI_Email { * * @access private * @return string - */ + */ function _remove_nl_callback($matches) { if (strpos($matches[1], "\r") !== FALSE OR strpos($matches[1], "\n") !== FALSE) { $matches[1] = str_replace(array("\r\n", "\r", "\n"), '', $matches[1]); } - + return $matches[1]; } - + // -------------------------------------------------------------------- /** @@ -1378,7 +1453,7 @@ class CI_Email { * * @access private * @return bool - */ + */ function _spool_email() { $this->_unwrap_specials(); @@ -1386,26 +1461,26 @@ class CI_Email { switch ($this->_get_protocol()) { case 'mail' : - + if ( ! $this->_send_with_mail()) { - $this->_set_error_message('email_send_failure_phpmail'); + $this->_set_error_message('email_send_failure_phpmail'); return FALSE; } break; case 'sendmail' : - + if ( ! $this->_send_with_sendmail()) { - $this->_set_error_message('email_send_failure_sendmail'); + $this->_set_error_message('email_send_failure_sendmail'); return FALSE; } break; case 'smtp' : - + if ( ! $this->_send_with_smtp()) { - $this->_set_error_message('email_send_failure_smtp'); + $this->_set_error_message('email_send_failure_smtp'); return FALSE; } break; @@ -1414,8 +1489,8 @@ class CI_Email { $this->_set_error_message('email_sent', $this->_get_protocol()); return TRUE; - } - + } + // -------------------------------------------------------------------- /** @@ -1423,9 +1498,9 @@ class CI_Email { * * @access private * @return bool - */ + */ function _send_with_mail() - { + { if ($this->_safe_mode == TRUE) { if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str)) @@ -1451,7 +1526,7 @@ class CI_Email { } } } - + // -------------------------------------------------------------------- /** @@ -1459,24 +1534,37 @@ class CI_Email { * * @access private * @return bool - */ + */ function _send_with_sendmail() { $fp = @popen($this->mailpath . " -oi -f ".$this->clean_email($this->_headers['From'])." -t", 'w'); - if ( ! is_resource($fp)) - { - $this->_set_error_message('email_no_socket'); + if ($fp === FALSE OR $fp === NULL) + { + // server probably has popen disabled, so nothing we can do to get a verbose error. return FALSE; } - + fputs($fp, $this->_header_str); fputs($fp, $this->_finalbody); - pclose($fp) >> 8 & 0xFF; + + $status = pclose($fp); + + if (version_compare(PHP_VERSION, '4.2.3') == -1) + { + $status = $status >> 8 & 0xFF; + } + + if ($status != 0) + { + $this->_set_error_message('email_exit_status', $status); + $this->_set_error_message('email_no_socket'); + return FALSE; + } return TRUE; } - + // -------------------------------------------------------------------- /** @@ -1484,11 +1572,11 @@ class CI_Email { * * @access private * @return bool - */ + */ function _send_with_smtp() - { + { if ($this->smtp_host == '') - { + { $this->_set_error_message('email_no_hostname'); return FALSE; } @@ -1502,7 +1590,7 @@ class CI_Email { { $this->_send_command('to', $val); } - + if (count($this->_cc_array) > 0) { foreach($this->_cc_array as $val) @@ -1534,18 +1622,18 @@ class CI_Email { $reply = $this->_get_smtp_data(); - $this->_set_error_message($reply); + $this->_set_error_message($reply); if (strncmp($reply, '250', 3) != 0) { - $this->_set_error_message('email_smtp_error', $reply); + $this->_set_error_message('email_smtp_error', $reply); return FALSE; } $this->_send_command('quit'); return TRUE; - } - + } + // -------------------------------------------------------------------- /** @@ -1554,7 +1642,7 @@ class CI_Email { * @access private * @param string * @return string - */ + */ function _smtp_connect() { $this->_smtp_connect = fsockopen($this->smtp_host, @@ -1564,7 +1652,7 @@ class CI_Email { $this->smtp_timeout); if( ! is_resource($this->_smtp_connect)) - { + { $this->_set_error_message('email_smtp_error', $errno." ".$errstr); return FALSE; } @@ -1572,7 +1660,7 @@ class CI_Email { $this->_set_error_message($this->_get_smtp_data()); return $this->_send_command('hello'); } - + // -------------------------------------------------------------------- /** @@ -1582,7 +1670,7 @@ class CI_Email { * @param string * @param string * @return string - */ + */ function _send_command($cmd, $data = '') { switch ($cmd) @@ -1597,22 +1685,22 @@ class CI_Email { $resp = 250; break; case 'from' : - + $this->_send_data('MAIL FROM:<'.$data.'>'); $resp = 250; break; case 'to' : - + $this->_send_data('RCPT TO:<'.$data.'>'); - $resp = 250; + $resp = 250; break; case 'data' : - + $this->_send_data('DATA'); - $resp = 354; + $resp = 354; break; case 'quit' : @@ -1622,7 +1710,7 @@ class CI_Email { break; } - $reply = $this->_get_smtp_data(); + $reply = $this->_get_smtp_data(); $this->_debug_msg[] = "
    ".$cmd.": ".$reply."
    "; @@ -1631,15 +1719,15 @@ class CI_Email { $this->_set_error_message('email_smtp_error', $reply); return FALSE; } - + if ($cmd == 'quit') { fclose($this->_smtp_connect); } - + return TRUE; } - + // -------------------------------------------------------------------- /** @@ -1647,14 +1735,14 @@ class CI_Email { * * @access private * @return bool - */ + */ function _smtp_authenticate() - { + { if ( ! $this->_smtp_auth) { return TRUE; } - + if ($this->smtp_user == "" AND $this->smtp_pass == "") { $this->_set_error_message('email_no_smtp_unpw'); @@ -1663,37 +1751,37 @@ class CI_Email { $this->_send_data('AUTH LOGIN'); - $reply = $this->_get_smtp_data(); + $reply = $this->_get_smtp_data(); if (strncmp($reply, '334', 3) != 0) { - $this->_set_error_message('email_failed_smtp_login', $reply); + $this->_set_error_message('email_failed_smtp_login', $reply); return FALSE; } $this->_send_data(base64_encode($this->smtp_user)); - $reply = $this->_get_smtp_data(); + $reply = $this->_get_smtp_data(); if (strncmp($reply, '334', 3) != 0) { - $this->_set_error_message('email_smtp_auth_un', $reply); + $this->_set_error_message('email_smtp_auth_un', $reply); return FALSE; } $this->_send_data(base64_encode($this->smtp_pass)); - $reply = $this->_get_smtp_data(); + $reply = $this->_get_smtp_data(); if (strncmp($reply, '235', 3) != 0) { - $this->_set_error_message('email_smtp_auth_pw', $reply); + $this->_set_error_message('email_smtp_auth_pw', $reply); return FALSE; } - + return TRUE; } - + // -------------------------------------------------------------------- /** @@ -1701,12 +1789,12 @@ class CI_Email { * * @access private * @return bool - */ + */ function _send_data($data) { if ( ! fwrite($this->_smtp_connect, $data . $this->newline)) { - $this->_set_error_message('email_smtp_data_failure', $data); + $this->_set_error_message('email_smtp_data_failure', $data); return FALSE; } else @@ -1714,7 +1802,7 @@ class CI_Email { return TRUE; } } - + // -------------------------------------------------------------------- /** @@ -1722,7 +1810,7 @@ class CI_Email { * * @access private * @return string - */ + */ function _get_smtp_data() { $data = ""; @@ -1730,7 +1818,7 @@ class CI_Email { while ($str = fgets($this->_smtp_connect, 512)) { $data .= $str; - + if (substr($str, 3, 1) == " ") { break; @@ -1739,7 +1827,7 @@ class CI_Email { return $data; } - + // -------------------------------------------------------------------- /** @@ -1749,10 +1837,10 @@ class CI_Email { * @return string */ function _get_hostname() - { - return (isset($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : 'localhost.localdomain'; + { + return (isset($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : 'localhost.localdomain'; } - + // -------------------------------------------------------------------- /** @@ -1767,12 +1855,12 @@ class CI_Email { { return $this->_IP; } - + $cip = (isset($_SERVER['HTTP_CLIENT_IP']) AND $_SERVER['HTTP_CLIENT_IP'] != "") ? $_SERVER['HTTP_CLIENT_IP'] : FALSE; $rip = (isset($_SERVER['REMOTE_ADDR']) AND $_SERVER['REMOTE_ADDR'] != "") ? $_SERVER['REMOTE_ADDR'] : FALSE; $fip = (isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND $_SERVER['HTTP_X_FORWARDED_FOR'] != "") ? $_SERVER['HTTP_X_FORWARDED_FOR'] : FALSE; - - if ($cip && $rip) $this->_IP = $cip; + + if ($cip && $rip) $this->_IP = $cip; elseif ($rip) $this->_IP = $rip; elseif ($cip) $this->_IP = $cip; elseif ($fip) $this->_IP = $fip; @@ -1794,7 +1882,7 @@ class CI_Email { return $this->_IP; } - + // -------------------------------------------------------------------- /** @@ -1802,7 +1890,7 @@ class CI_Email { * * @access public * @return string - */ + */ function print_debugger() { $msg = ''; @@ -1815,10 +1903,10 @@ class CI_Email { } } - $msg .= "
    ".$this->_header_str."\n".htmlspecialchars($this->_subject)."\n".htmlspecialchars($this->_finalbody).'
    '; + $msg .= "
    ".$this->_header_str."\n".htmlspecialchars($this->_subject)."\n".htmlspecialchars($this->_finalbody).'
    '; return $msg; - } - + } + // -------------------------------------------------------------------- /** @@ -1827,22 +1915,22 @@ class CI_Email { * @access private * @param string * @return string - */ + */ function _set_error_message($msg, $val = '') { $CI =& get_instance(); $CI->lang->load('email'); - + if (FALSE === ($line = $CI->lang->line($msg))) - { + { $this->_debug_msg[] = str_replace('%s', $val, $msg)."
    "; - } + } else { $this->_debug_msg[] = str_replace('%s', $val, $line)."
    "; - } + } } - + // -------------------------------------------------------------------- /** diff --git a/libraries/Encrypt.php b/libraries/Encrypt.php index 4edfaa7..95c758f 100644 --- a/libraries/Encrypt.php +++ b/libraries/Encrypt.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/libraries/Exceptions.php b/libraries/Exceptions.php index 541fd1a..9c655a1 100644 --- a/libraries/Exceptions.php +++ b/libraries/Exceptions.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -94,7 +94,7 @@ class CI_Exceptions { $message = "The page you requested was not found."; log_message('error', '404 Page Not Found --> '.$page); - echo $this->show_error($heading, $message, 'error_404'); + echo $this->show_error($heading, $message, 'error_404', 404); exit; } @@ -113,8 +113,10 @@ class CI_Exceptions { * @param string the template name * @return string */ - function show_error($heading, $message, $template = 'error_general') + function show_error($heading, $message, $template = 'error_general', $status_code = 500) { + set_status_header($status_code); + $message = '

    '.implode('

    ', ( ! is_array($message)) ? array($message) : $message).'

    '; if (ob_get_level() > $this->ob_level + 1) diff --git a/libraries/Form_validation.php b/libraries/Form_validation.php index 528d410..1497d85 100644 --- a/libraries/Form_validation.php +++ b/libraries/Form_validation.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -57,7 +57,7 @@ class CI_Form_validation { mb_internal_encoding($this->CI->config->item('charset')); } - log_message('debug', "Validation Class Initialized"); + log_message('debug', "Form Validation Class Initialized"); } // -------------------------------------------------------------------- @@ -416,45 +416,36 @@ class CI_Form_validation { } else { - $post = '$_POST["'; + // start with a reference + $post_ref =& $_POST; + // before we assign values, make a reference to the right POST key if (count($row['keys']) == 1) { - $post .= current($row['keys']); - $post .= '"]'; + $post_ref =& $post_ref[current($row['keys'])]; } else { - $i = 0; foreach ($row['keys'] as $val) { - if ($i == 0) - { - $post .= $val.'"]'; - $i++; - continue; - } - - $post .= '["'.$val.'"]'; + $post_ref =& $post_ref[$val]; } } - + if (is_array($row['postdata'])) - { + { $array = array(); foreach ($row['postdata'] as $k => $v) { $array[$k] = $this->prep_for_form($v); } - - $post .= ' = $array;'; + + $post_ref = $array; } else - { - $post .= ' = "'.$this->prep_for_form($row['postdata']).'";'; + { + $post_ref = $this->prep_for_form($row['postdata']); } - - eval($post); } } } @@ -610,7 +601,7 @@ class CI_Form_validation { // If the field isn't required and we just processed a callback we'll move on... if ( ! in_array('required', $rules, TRUE) AND $result !== FALSE) { - return; + continue; } } else @@ -662,7 +653,14 @@ class CI_Form_validation { { $line = $this->_error_messages[$rule]; } - + + // Is the parameter we are inserting into the error message the name + // of another field? If so we need to grab its "field label" + if (isset($this->_field_data[$param]) AND isset($this->_field_data[$param]['label'])) + { + $param = $this->_field_data[$param]['label']; + } + // Build the error message $message = sprintf($line, $this->_translate_fieldname($row['label']), $param); diff --git a/libraries/Ftp.php b/libraries/Ftp.php index db65877..6fb1704 100644 --- a/libraries/Ftp.php +++ b/libraries/Ftp.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -23,7 +23,7 @@ * @category Libraries * @author ExpressionEngine Dev Team * @link http://codeigniter.com/user_guide/libraries/ftp.html - */ + */ class CI_FTP { var $hostname = ''; @@ -39,13 +39,13 @@ class CI_FTP { * Constructor - Sets Preferences * * The constructor can be passed an array of config values - */ + */ function CI_FTP($config = array()) - { + { if (count($config) > 0) { $this->initialize($config); - } + } log_message('debug', "FTP Class Initialized"); } @@ -58,7 +58,7 @@ class CI_FTP { * @access public * @param array * @return void - */ + */ function initialize($config = array()) { foreach ($config as $key => $val) @@ -68,7 +68,7 @@ class CI_FTP { $this->$key = $val; } } - + // Prep the hostname $this->hostname = preg_replace('|.+?://|', '', $this->hostname); } @@ -81,38 +81,38 @@ class CI_FTP { * @access public * @param array the connection values * @return bool - */ + */ function connect($config = array()) - { + { if (count($config) > 0) { $this->initialize($config); - } - + } + if (FALSE === ($this->conn_id = @ftp_connect($this->hostname, $this->port))) { if ($this->debug == TRUE) { $this->_error('ftp_unable_to_connect'); - } + } return FALSE; } - + if ( ! $this->_login()) { if ($this->debug == TRUE) { $this->_error('ftp_unable_to_login'); - } + } return FALSE; } - + // Set passive mode if needed if ($this->passive == TRUE) { ftp_pasv($this->conn_id, TRUE); } - + return TRUE; } @@ -123,7 +123,7 @@ class CI_FTP { * * @access private * @return bool - */ + */ function _login() { return @ftp_login($this->conn_id, $this->username, $this->password); @@ -136,7 +136,7 @@ class CI_FTP { * * @access private * @return bool - */ + */ function _is_conn() { if ( ! is_resource($this->conn_id)) @@ -144,7 +144,7 @@ class CI_FTP { if ($this->debug == TRUE) { $this->_error('ftp_no_connection'); - } + } return FALSE; } return TRUE; @@ -154,40 +154,40 @@ class CI_FTP { /** - * Change direcotry + * Change directory * * The second parameter lets us momentarily turn off debugging so that - * this function can be used to test for the existance of a folder + * this function can be used to test for the existence of a folder * without throwing an error. There's no FTP equivalent to is_dir() - * so we do it by trying to change to a particular directory. - * Internally, this paramter is only used by the "mirror" function below. + * so we do it by trying to change to a particular directory. + * Internally, this parameter is only used by the "mirror" function below. * * @access public * @param string * @param bool * @return bool - */ + */ function changedir($path = '', $supress_debug = FALSE) { if ($path == '' OR ! $this->_is_conn()) { return FALSE; } - + $result = @ftp_chdir($this->conn_id, $path); - + if ($result === FALSE) { if ($this->debug == TRUE AND $supress_debug == FALSE) { $this->_error('ftp_unable_to_changedir'); - } - return FALSE; + } + return FALSE; } - + return TRUE; } - + // -------------------------------------------------------------------- /** @@ -196,23 +196,23 @@ class CI_FTP { * @access public * @param string * @return bool - */ + */ function mkdir($path = '', $permissions = NULL) { if ($path == '' OR ! $this->_is_conn()) { return FALSE; } - + $result = @ftp_mkdir($this->conn_id, $path); - + if ($result === FALSE) { if ($this->debug == TRUE) { $this->_error('ftp_unable_to_makdir'); - } - return FALSE; + } + return FALSE; } // Set file permissions if needed @@ -220,10 +220,10 @@ class CI_FTP { { $this->chmod($path, (int)$permissions); } - + return TRUE; } - + // -------------------------------------------------------------------- /** @@ -234,7 +234,7 @@ class CI_FTP { * @param string * @param string * @return bool - */ + */ function upload($locpath, $rempath, $mode = 'auto', $permissions = NULL) { if ( ! $this->_is_conn()) @@ -247,7 +247,7 @@ class CI_FTP { $this->_error('ftp_no_source_file'); return FALSE; } - + // Set the mode if not specified if ($mode == 'auto') { @@ -255,26 +255,26 @@ class CI_FTP { $ext = $this->_getext($locpath); $mode = $this->_settype($ext); } - + $mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY; - + $result = @ftp_put($this->conn_id, $rempath, $locpath, $mode); - + if ($result === FALSE) { if ($this->debug == TRUE) { $this->_error('ftp_unable_to_upload'); - } - return FALSE; + } + return FALSE; } - + // Set file permissions if needed if ( ! is_null($permissions)) { $this->chmod($rempath, (int)$permissions); } - + return TRUE; } @@ -288,7 +288,7 @@ class CI_FTP { * @param string * @param bool * @return bool - */ + */ function rename($old_file, $new_file, $move = FALSE) { if ( ! $this->_is_conn()) @@ -297,21 +297,21 @@ class CI_FTP { } $result = @ftp_rename($this->conn_id, $old_file, $new_file); - + if ($result === FALSE) { if ($this->debug == TRUE) { $msg = ($move == FALSE) ? 'ftp_unable_to_rename' : 'ftp_unable_to_move'; - + $this->_error($msg); - } - return FALSE; + } + return FALSE; } - + return TRUE; } - + // -------------------------------------------------------------------- /** @@ -321,7 +321,7 @@ class CI_FTP { * @param string * @param string * @return bool - */ + */ function move($old_file, $new_file) { return $this->rename($old_file, $new_file, TRUE); @@ -335,7 +335,7 @@ class CI_FTP { * @access public * @param string * @return bool - */ + */ function delete_file($filepath) { if ( ! $this->_is_conn()) @@ -344,16 +344,16 @@ class CI_FTP { } $result = @ftp_delete($this->conn_id, $filepath); - + if ($result === FALSE) { if ($this->debug == TRUE) - { + { $this->_error('ftp_unable_to_delete'); - } - return FALSE; + } + return FALSE; } - + return TRUE; } @@ -366,7 +366,7 @@ class CI_FTP { * @access public * @param string * @return bool - */ + */ function delete_dir($filepath) { if ( ! $this->_is_conn()) @@ -376,13 +376,13 @@ class CI_FTP { // Add a trailing slash to the file path if needed $filepath = preg_replace("/(.+?)\/*$/", "\\1/", $filepath); - + $list = $this->list_files($filepath); - + if ($list !== FALSE AND count($list) > 0) { foreach ($list as $item) - { + { // If we can't delete the item it's probaly a folder so // we'll recursively call delete_dir() if ( ! @ftp_delete($this->conn_id, $item)) @@ -391,18 +391,18 @@ class CI_FTP { } } } - + $result = @ftp_rmdir($this->conn_id, $filepath); - + if ($result === FALSE) { if ($this->debug == TRUE) - { + { $this->_error('ftp_unable_to_delete'); - } - return FALSE; + } + return FALSE; } - + return TRUE; } @@ -415,7 +415,7 @@ class CI_FTP { * @param string the file path * @param string the permissions * @return bool - */ + */ function chmod($path, $perm) { if ( ! $this->_is_conn()) @@ -429,21 +429,21 @@ class CI_FTP { if ($this->debug == TRUE) { $this->_error('ftp_unable_to_chmod'); - } - return FALSE; + } + return FALSE; } - + $result = @ftp_chmod($this->conn_id, $perm, $path); - + if ($result === FALSE) { if ($this->debug == TRUE) { $this->_error('ftp_unable_to_chmod'); - } - return FALSE; + } + return FALSE; } - + return TRUE; } @@ -454,7 +454,7 @@ class CI_FTP { * * @access public * @return array - */ + */ function list_files($path = '.') { if ( ! $this->_is_conn()) @@ -466,7 +466,7 @@ class CI_FTP { } // ------------------------------------------------------------------------ - + /** * Read a directory and recreate it remotely * @@ -478,7 +478,7 @@ class CI_FTP { * @param string path to source with trailing slash * @param string path to destination - include the base folder with trailing slash * @return bool - */ + */ function mirror($locpath, $rempath) { if ( ! $this->_is_conn()) @@ -498,12 +498,12 @@ class CI_FTP { return FALSE; } } - + // Recursively read the local directory while (FALSE !== ($file = readdir($fp))) { if (@is_dir($locpath.$file) && substr($file, 0, 1) != '.') - { + { $this->mirror($locpath.$file."/", $rempath.$file."/"); } elseif (substr($file, 0, 1) != ".") @@ -511,47 +511,47 @@ class CI_FTP { // Get the file extension so we can se the upload type $ext = $this->_getext($file); $mode = $this->_settype($ext); - + $this->upload($locpath.$file, $rempath.$file, $mode); } } return TRUE; } - + return FALSE; } // -------------------------------------------------------------------- - + /** * Extract the file extension * * @access private * @param string * @return string - */ + */ function _getext($filename) { if (FALSE === strpos($filename, '.')) { return 'txt'; } - + $x = explode('.', $filename); return end($x); - } + } // -------------------------------------------------------------------- - + /** * Set the upload type * * @access private * @param string * @return string - */ + */ function _settype($ext) { $text_types = array( @@ -569,13 +569,13 @@ class CI_FTP { 'log', 'xml' ); - - + + return (in_array($ext, $text_types)) ? 'ascii' : 'binary'; } // ------------------------------------------------------------------------ - + /** * Close the connection * @@ -583,7 +583,7 @@ class CI_FTP { * @param string path to source * @param string path to destination * @return bool - */ + */ function close() { if ( ! $this->_is_conn()) @@ -595,19 +595,19 @@ class CI_FTP { } // ------------------------------------------------------------------------ - + /** * Display error message * * @access private * @param string * @return bool - */ + */ function _error($line) { $CI =& get_instance(); $CI->lang->load('ftp'); - show_error($CI->lang->line($line)); + show_error($CI->lang->line($line)); } diff --git a/libraries/Hooks.php b/libraries/Hooks.php index 76584a7..0b5d468 100644 --- a/libraries/Hooks.php +++ b/libraries/Hooks.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -28,21 +28,21 @@ * @link http://codeigniter.com/user_guide/libraries/encryption.html */ class CI_Hooks { - + var $enabled = FALSE; var $hooks = array(); var $in_progress = FALSE; - + /** * Constructor * */ function CI_Hooks() { - $this->_initialize(); + $this->_initialize(); log_message('debug', "Hooks Class Initialized"); } - + // -------------------------------------------------------------------- /** @@ -50,24 +50,24 @@ class CI_Hooks { * * @access private * @return void - */ + */ function _initialize() { $CFG =& load_class('Config'); - + // If hooks are not enabled in the config file // there is nothing else to do - + if ($CFG->item('enable_hooks') == FALSE) { return; } - + // Grab the "hooks" definition file. // If there are no hooks, we're done. - + @include(APPPATH.'config/hooks'.EXT); - + if ( ! isset($hook) OR ! is_array($hook)) { return; @@ -76,7 +76,7 @@ class CI_Hooks { $this->hooks =& $hook; $this->enabled = TRUE; } - + // -------------------------------------------------------------------- /** @@ -94,7 +94,7 @@ class CI_Hooks { { return FALSE; } - + if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0])) { foreach ($this->hooks[$which] as $val) @@ -106,7 +106,7 @@ class CI_Hooks { { $this->_run_hook($this->hooks[$which]); } - + return TRUE; } @@ -127,14 +127,14 @@ class CI_Hooks { { return FALSE; } - + // ----------------------------------- // Safety - Prevents run-away loops // ----------------------------------- - + // If the script being called happens to have the same // hook call within it a loop can happen - + if ($this->in_progress == TRUE) { return; @@ -143,27 +143,27 @@ class CI_Hooks { // ----------------------------------- // Set file path // ----------------------------------- - + if ( ! isset($data['filepath']) OR ! isset($data['filename'])) { return FALSE; } - + $filepath = APPPATH.$data['filepath'].'/'.$data['filename']; - + if ( ! file_exists($filepath)) { return FALSE; } - + // ----------------------------------- // Set class/function name // ----------------------------------- - + $class = FALSE; $function = FALSE; $params = ''; - + if (isset($data['class']) AND $data['class'] != '') { $class = $data['class']; @@ -178,29 +178,29 @@ class CI_Hooks { { $params = $data['params']; } - + if ($class === FALSE AND $function === FALSE) { return FALSE; } - + // ----------------------------------- // Set the in_progress flag // ----------------------------------- $this->in_progress = TRUE; - + // ----------------------------------- // Call the requested class and/or function // ----------------------------------- - + if ($class !== FALSE) { if ( ! class_exists($class)) { require($filepath); } - + $HOOK = new $class; $HOOK->$function($params); } @@ -210,10 +210,10 @@ class CI_Hooks { { require($filepath); } - + $function($params); } - + $this->in_progress = FALSE; return TRUE; } diff --git a/libraries/Image_lib.php b/libraries/Image_lib.php index c5ebc8f..169c6e4 100644 --- a/libraries/Image_lib.php +++ b/libraries/Image_lib.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -25,11 +25,11 @@ * @link http://codeigniter.com/user_guide/libraries/image_lib.html */ class CI_Image_lib { - + var $image_library = 'gd2'; // Can be: imagemagick, netpbm, gd, gd2 var $library_path = ''; var $dynamic_output = FALSE; // Whether to send to browser or write to disk - var $source_image = ''; + var $source_image = ''; var $new_image = ''; var $width = ''; var $height = ''; @@ -41,7 +41,7 @@ class CI_Image_lib { var $rotation_angle = ''; var $x_axis = ''; var $y_axis = ''; - + // Watermark Vars var $wm_text = ''; // Watermark text if graphic is not used var $wm_type = 'text'; // Type of watermarking. Options: text/overlay @@ -59,7 +59,7 @@ class CI_Image_lib { var $wm_shadow_color = ''; // Dropshadow color var $wm_shadow_distance = 2; // Dropshadow distance var $wm_opacity = 50; // Image opacity: 1 - 100 Only works with image - + // Private Vars var $source_folder = ''; var $dest_folder = ''; @@ -74,27 +74,27 @@ class CI_Image_lib { var $copy_fnc = 'imagecopyresampled'; var $error_msg = array(); var $wm_use_drop_shadow = FALSE; - var $wm_use_truetype = FALSE; - + var $wm_use_truetype = FALSE; + /** * Constructor * * @access public * @param string * @return void - */ + */ function CI_Image_lib($props = array()) { if (count($props) > 0) { $this->initialize($props); } - + log_message('debug', "Image Lib Class Initialized"); } - + // -------------------------------------------------------------------- - + /** * Initialize image properties * @@ -102,11 +102,11 @@ class CI_Image_lib { * * @access public * @return void - */ + */ function clear() { $props = array('source_folder', 'dest_folder', 'source_image', 'full_src_path', 'full_dst_path', 'new_image', 'image_type', 'size_str', 'quality', 'orig_width', 'orig_height', 'rotation_angle', 'x_axis', 'y_axis', 'create_fnc', 'copy_fnc', 'wm_overlay_path', 'wm_use_truetype', 'dynamic_output', 'wm_font_size', 'wm_text', 'wm_vrt_alignment', 'wm_hor_alignment', 'wm_padding', 'wm_hor_offset', 'wm_vrt_offset', 'wm_font_color', 'wm_use_drop_shadow', 'wm_shadow_color', 'wm_shadow_distance', 'wm_opacity'); - + foreach ($props as $val) { $this->$val = ''; @@ -115,16 +115,16 @@ class CI_Image_lib { // special consideration for master_dim $this->master_dim = 'auto'; } - + // -------------------------------------------------------------------- - + /** * initialize image preferences * * @access public * @param array - * @return void - */ + * @return bool + */ function initialize($props = array()) { /* @@ -147,9 +147,9 @@ class CI_Image_lib { if ($this->source_image == '') { $this->set_error('imglib_source_image_required'); - return FALSE; + return FALSE; } - + /* * Is getimagesize() Available? * @@ -157,15 +157,15 @@ class CI_Image_lib { * Note: We need to figure out how to determine image * properties using ImageMagick and NetPBM * - */ + */ if ( ! function_exists('getimagesize')) { $this->set_error('imglib_gd_required_for_props'); - return FALSE; + return FALSE; } - + $this->image_library = strtolower($this->image_library); - + /* * Set the full server path * @@ -173,7 +173,7 @@ class CI_Image_lib { * Either way, we'll try use realpath to generate the * full server path in order to more reliably read it. * - */ + */ if (function_exists('realpath') AND @realpath($this->source_image) !== FALSE) { $full_source_path = str_replace("\\", "/", realpath($this->source_image)); @@ -182,16 +182,16 @@ class CI_Image_lib { { $full_source_path = $this->source_image; } - + $x = explode('/', $full_source_path); $this->source_image = end($x); $this->source_folder = str_replace($this->source_image, '', $full_source_path); - + // Set the Image Properties if ( ! $this->get_image_properties($this->source_folder.$this->source_image)) { - return FALSE; - } + return FALSE; + } /* * Assign the "new" image name/path @@ -201,7 +201,7 @@ class CI_Image_lib { * it means we are altering the original. We'll * set the destination filename and path accordingly. * - */ + */ if ($this->new_image == '') { $this->dest_image = $this->source_image; @@ -224,7 +224,7 @@ class CI_Image_lib { { $full_dest_path = $this->new_image; } - + // Is there a file name? if ( ! preg_match("#\.(jpg|jpeg|gif|png)$#i", $full_dest_path)) { @@ -249,18 +249,18 @@ class CI_Image_lib { * We'll also split the destination image name * so we can insert the thumbnail marker if needed. * - */ + */ if ($this->create_thumb === FALSE OR $this->thumb_marker == '') { $this->thumb_marker = ''; } $xp = $this->explode_name($this->dest_image); - + $filename = $xp['name']; $file_ext = $xp['ext']; - - $this->full_src_path = $this->source_folder.$this->source_image; + + $this->full_src_path = $this->source_folder.$this->source_image; $this->full_dst_path = $this->dest_folder.$filename.$this->thumb_marker.$file_ext; /* @@ -270,7 +270,7 @@ class CI_Image_lib { * might not be in correct proportion with the source * image's width/height. We'll recalculate it here. * - */ + */ if ($this->maintain_ratio === TRUE && ($this->width != '' AND $this->height != '')) { $this->image_reproportion(); @@ -283,23 +283,23 @@ class CI_Image_lib { * not submitted we will use the values * from the actual file * - */ + */ if ($this->width == '') $this->width = $this->orig_width; - + if ($this->height == '') $this->height = $this->orig_height; - + // Set the quality $this->quality = trim(str_replace("%", "", $this->quality)); - + if ($this->quality == '' OR $this->quality == 0 OR ! is_numeric($this->quality)) $this->quality = 90; - + // Set the x/y coordinates $this->x_axis = ($this->x_axis == '' OR ! is_numeric($this->x_axis)) ? 0 : $this->x_axis; $this->y_axis = ($this->y_axis == '' OR ! is_numeric($this->y_axis)) ? 0 : $this->y_axis; - + // Watermark-related Stuff... if ($this->wm_font_color != '') { @@ -308,7 +308,7 @@ class CI_Image_lib { $this->wm_font_color = '#'.$this->wm_font_color; } } - + if ($this->wm_shadow_color != '') { if (strlen($this->wm_shadow_color) == 6) @@ -316,12 +316,12 @@ class CI_Image_lib { $this->wm_shadow_color = '#'.$this->wm_shadow_color; } } - + if ($this->wm_overlay_path != '') { $this->wm_overlay_path = str_replace("\\", "/", realpath($this->wm_overlay_path)); } - + if ($this->wm_shadow_color != '') { $this->wm_use_drop_shadow = TRUE; @@ -334,9 +334,9 @@ class CI_Image_lib { return TRUE; } - + // -------------------------------------------------------------------- - + /** * Image Resize * @@ -345,21 +345,21 @@ class CI_Image_lib { * * @access public * @return bool - */ + */ function resize() { $protocol = 'image_process_'.$this->image_library; - - if (eregi("gd2$", $protocol)) + + if (preg_match('/gd2$/i', $protocol)) { $protocol = 'image_process_gd'; } - + return $this->$protocol('resize'); } - + // -------------------------------------------------------------------- - + /** * Image Crop * @@ -368,21 +368,21 @@ class CI_Image_lib { * * @access public * @return bool - */ + */ function crop() { $protocol = 'image_process_'.$this->image_library; - - if (eregi("gd2$", $protocol)) + + if (preg_match('/gd2$/i', $protocol)) { $protocol = 'image_process_gd'; } - + return $this->$protocol('crop'); } - + // -------------------------------------------------------------------- - + /** * Image Rotate * @@ -391,18 +391,18 @@ class CI_Image_lib { * * @access public * @return bool - */ + */ function rotate() { - // Allowed rotation values - $degs = array(90, 180, 270, 'vrt', 'hor'); - - if ($this->rotation_angle == '' OR ! in_array($this->rotation_angle, $degs, TRUE)) + // Allowed rotation values + $degs = array(90, 180, 270, 'vrt', 'hor'); + + if ($this->rotation_angle == '' OR ! in_array($this->rotation_angle, $degs)) { $this->set_error('imglib_rotation_angle_required'); - return FALSE; + return FALSE; } - + // Reassign the width and height if ($this->rotation_angle == 90 OR $this->rotation_angle == 270) { @@ -414,28 +414,28 @@ class CI_Image_lib { $this->width = $this->orig_width; $this->height = $this->orig_height; } - + // Choose resizing function if ($this->image_library == 'imagemagick' OR $this->image_library == 'netpbm') { $protocol = 'image_process_'.$this->image_library; - + return $this->$protocol('rotate'); } - + if ($this->rotation_angle == 'hor' OR $this->rotation_angle == 'vrt') { return $this->image_mirror_gd(); } else - { + { return $this->image_rotate_gd(); } } - + // -------------------------------------------------------------------- - + /** * Image Process Using GD/GD2 * @@ -444,16 +444,16 @@ class CI_Image_lib { * @access public * @param string * @return bool - */ + */ function image_process_gd($action = 'resize') - { + { $v2_override = FALSE; // If the target width/height match the source, AND if the new file name is not equal to the old file name // we'll simply make a copy of the original with the new name... assuming dynamic rendering is off. if ($this->dynamic_output === FALSE) { - if ($this->orig_width == $this->width AND $this->orig_height == $this->height) + if ($this->orig_width == $this->width AND $this->orig_height == $this->height) { if ($this->source_image != $this->new_image) { @@ -462,35 +462,35 @@ class CI_Image_lib { @chmod($this->full_dst_path, DIR_WRITE_MODE); } } - + return TRUE; } } - + // Let's set up our values based on the action if ($action == 'crop') { // Reassign the source width/height if cropping $this->orig_width = $this->width; - $this->orig_height = $this->height; - + $this->orig_height = $this->height; + // GD 2.0 has a cropping bug so we'll test for it if ($this->gd_version() !== FALSE) { - $gd_version = str_replace('0', '', $this->gd_version()); + $gd_version = str_replace('0', '', $this->gd_version()); $v2_override = ($gd_version == 2) ? TRUE : FALSE; } } else - { + { // If resizing the x/y axis must be zero $this->x_axis = 0; $this->y_axis = 0; } - + // Create the image handle if ( ! ($src_img = $this->image_create_gd())) - { + { return FALSE; } @@ -501,21 +501,21 @@ class CI_Image_lib { // below should that ever prove inaccurate. // // if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor') AND $v2_override == FALSE) - if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor')) + if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor')) { $create = 'imagecreatetruecolor'; $copy = 'imagecopyresampled'; } else { - $create = 'imagecreate'; + $create = 'imagecreate'; $copy = 'imagecopyresized'; } - + $dst_img = $create($this->width, $this->height); $copy($dst_img, $src_img, 0, 0, $this->x_axis, $this->y_axis, $this->width, $this->height, $this->orig_width, $this->orig_height); - // Show the image + // Show the image if ($this->dynamic_output == TRUE) { $this->image_display_gd($dst_img); @@ -532,15 +532,15 @@ class CI_Image_lib { // Kill the file handles imagedestroy($dst_img); imagedestroy($src_img); - + // Set the file to 777 @chmod($this->full_dst_path, DIR_WRITE_MODE); - + return TRUE; } - + // -------------------------------------------------------------------- - + /** * Image Process Using ImageMagick * @@ -549,7 +549,7 @@ class CI_Image_lib { * @access public * @param string * @return bool - */ + */ function image_process_imagemagick($action = 'resize') { // Do we have a vaild library path? @@ -558,17 +558,17 @@ class CI_Image_lib { $this->set_error('imglib_libpath_invalid'); return FALSE; } - - if ( ! eregi("convert$", $this->library_path)) + + if ( ! preg_match("/convert$/i", $this->library_path)) { - if ( ! eregi("/$", $this->library_path)) $this->library_path .= "/"; - + $this->library_path = rtrim($this->library_path, '/').'/'; + $this->library_path .= 'convert'; } - + // Execute the command $cmd = $this->library_path." -quality ".$this->quality; - + if ($action == 'crop') { $cmd .= " -crop ".$this->width."x".$this->height."+".$this->x_axis."+".$this->y_axis." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1"; @@ -583,34 +583,34 @@ class CI_Image_lib { break; default : $angle = '-rotate '.$this->rotation_angle; break; - } - + } + $cmd .= " ".$angle." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1"; } else // Resize { $cmd .= " -resize ".$this->width."x".$this->height." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1"; } - + $retval = 1; - + @exec($cmd, $output, $retval); - // Did it work? + // Did it work? if ($retval > 0) { $this->set_error('imglib_image_process_failed'); return FALSE; } - + // Set the file to 777 @chmod($this->full_dst_path, DIR_WRITE_MODE); - + return TRUE; } - + // -------------------------------------------------------------------- - + /** * Image Process Using NetPBM * @@ -619,7 +619,7 @@ class CI_Image_lib { * @access public * @param string * @return bool - */ + */ function image_process_netpbm($action = 'resize') { if ($this->library_path == '') @@ -627,7 +627,7 @@ class CI_Image_lib { $this->set_error('imglib_libpath_invalid'); return FALSE; } - + // Build the resizing command switch ($this->image_type) { @@ -637,14 +637,14 @@ class CI_Image_lib { break; case 2 : $cmd_in = 'jpegtopnm'; - $cmd_out = 'ppmtojpeg'; + $cmd_out = 'ppmtojpeg'; break; case 3 : $cmd_in = 'pngtopnm'; $cmd_out = 'ppmtopng'; break; } - + if ($action == 'crop') { $cmd_inner = 'pnmcut -left '.$this->x_axis.' -top '.$this->y_axis.' -width '.$this->width.' -height '.$this->height; @@ -664,47 +664,47 @@ class CI_Image_lib { case 'hor' : $angle = 'lr'; break; } - + $cmd_inner = 'pnmflip -'.$angle.' '; } else // Resize { $cmd_inner = 'pnmscale -xysize '.$this->width.' '.$this->height; } - + $cmd = $this->library_path.$cmd_in.' '.$this->full_src_path.' | '.$cmd_inner.' | '.$cmd_out.' > '.$this->dest_folder.'netpbm.tmp'; - + $retval = 1; - + @exec($cmd, $output, $retval); - + // Did it work? if ($retval > 0) { $this->set_error('imglib_image_process_failed'); return FALSE; } - + // With NetPBM we have to create a temporary image. // If you try manipulating the original it fails so // we have to rename the temp file. copy ($this->dest_folder.'netpbm.tmp', $this->full_dst_path); unlink ($this->dest_folder.'netpbm.tmp'); @chmod($this->full_dst_path, DIR_WRITE_MODE); - + return TRUE; } - + // -------------------------------------------------------------------- - + /** * Image Rotate Using GD * * @access public * @return bool - */ + */ function image_rotate_gd() - { + { // Is Image Rotation Supported? // this function is only supported as of PHP 4.3 if ( ! function_exists('imagerotate')) @@ -712,23 +712,23 @@ class CI_Image_lib { $this->set_error('imglib_rotate_unsupported'); return FALSE; } - + // Create the image handle if ( ! ($src_img = $this->image_create_gd())) - { + { return FALSE; } - // Set the background color + // Set the background color // This won't work with transparent PNG files so we are // going to have to figure out how to determine the color // of the alpha channel in a future release. - + $white = imagecolorallocate($src_img, 255, 255, 255); // Rotate it! $dst_img = imagerotate($src_img, $this->rotation_angle, $white); - + // Save the Image if ($this->dynamic_output == TRUE) { @@ -746,16 +746,16 @@ class CI_Image_lib { // Kill the file handles imagedestroy($dst_img); imagedestroy($src_img); - + // Set the file to 777 - + @chmod($this->full_dst_path, DIR_WRITE_MODE); - + return true; } - + // -------------------------------------------------------------------- - + /** * Create Mirror Image using GD * @@ -763,32 +763,32 @@ class CI_Image_lib { * * @access public * @return bool - */ + */ function image_mirror_gd() - { + { if ( ! $src_img = $this->image_create_gd()) { return FALSE; } - + $width = $this->orig_width; $height = $this->orig_height; - + if ($this->rotation_angle == 'hor') { for ($i = 0; $i < $height; $i++) { $left = 0; $right = $width-1; - + while ($left < $right) { $cl = imagecolorat($src_img, $left, $i); $cr = imagecolorat($src_img, $right, $i); - + imagesetpixel($src_img, $left, $i, $cr); imagesetpixel($src_img, $right, $i, $cl); - + $left++; $right--; } @@ -800,20 +800,20 @@ class CI_Image_lib { { $top = 0; $bot = $height-1; - + while ($top < $bot) { $ct = imagecolorat($src_img, $i, $top); $cb = imagecolorat($src_img, $i, $bot); - + imagesetpixel($src_img, $i, $top, $cb); imagesetpixel($src_img, $i, $bot, $ct); - + $top++; $bot--; } - } - } + } + } // Show the image if ($this->dynamic_output == TRUE) @@ -828,18 +828,18 @@ class CI_Image_lib { return FALSE; } } - + // Kill the file handles imagedestroy($src_img); - + // Set the file to 777 @chmod($this->full_dst_path, DIR_WRITE_MODE); - + return TRUE; } - + // -------------------------------------------------------------------- - + /** * Image Watermark * @@ -849,7 +849,7 @@ class CI_Image_lib { * @access public * @param string * @return bool - */ + */ function watermark() { if ($this->wm_type == 'overlay') @@ -861,49 +861,49 @@ class CI_Image_lib { return $this->text_watermark(); } } - + // -------------------------------------------------------------------- - + /** * Watermark - Graphic Version * * @access public * @return bool - */ + */ function overlay_watermark() { if ( ! function_exists('imagecolortransparent')) { $this->set_error('imglib_gd_required'); - return FALSE; + return FALSE; } - + // Fetch source image properties $this->get_image_properties(); // Fetch watermark image properties - $props = $this->get_image_properties($this->wm_overlay_path, TRUE); + $props = $this->get_image_properties($this->wm_overlay_path, TRUE); $wm_img_type = $props['image_type']; $wm_width = $props['width']; $wm_height = $props['height']; - - // Create two image resources + + // Create two image resources $wm_img = $this->image_create_gd($this->wm_overlay_path, $wm_img_type); $src_img = $this->image_create_gd($this->full_src_path); - - // Reverse the offset if necessary + + // Reverse the offset if necessary // When the image is positioned at the bottom // we don't want the vertical offset to push it // further down. We want the reverse, so we'll // invert the offset. Same with the horizontal // offset when the image is at the right - + $this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1)); $this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1)); - + if ($this->wm_vrt_alignment == 'B') $this->wm_vrt_offset = $this->wm_vrt_offset * -1; - + if ($this->wm_hor_alignment == 'R') $this->wm_hor_offset = $this->wm_hor_offset * -1; @@ -926,23 +926,23 @@ class CI_Image_lib { switch ($this->wm_hor_alignment) { case 'L': - break; + break; case 'C': $x_axis += ($this->orig_width / 2) - ($wm_width / 2); break; case 'R': $x_axis += $this->orig_width - $wm_width; break; } - - // Build the finalized image + + // Build the finalized image if ($wm_img_type == 3 AND function_exists('imagealphablending')) { @imagealphablending($src_img, TRUE); - } + } // Set RGB values for text and shadow $rgba = imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp); $alpha = ($rgba & 0x7F000000) >> 24; - + // make a best guess as to whether we're dealing with an image with alpha transparency or no/binary transparency if ($alpha > 0) { @@ -953,9 +953,9 @@ class CI_Image_lib { { // set our RGB value from above to be transparent and merge the images with the specified opacity imagecolortransparent($wm_img, imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp)); - imagecopymerge($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height, $this->wm_opacity); + imagecopymerge($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height, $this->wm_opacity); } - + // Output the image if ($this->dynamic_output == TRUE) { @@ -968,49 +968,49 @@ class CI_Image_lib { return FALSE; } } - + imagedestroy($src_img); imagedestroy($wm_img); - + return TRUE; } - + // -------------------------------------------------------------------- - + /** * Watermark - Text Version * * @access public * @return bool - */ + */ function text_watermark() { if ( ! ($src_img = $this->image_create_gd())) - { + { return FALSE; } - + if ($this->wm_use_truetype == TRUE AND ! file_exists($this->wm_font_path)) { $this->set_error('imglib_missing_font'); return FALSE; } - - // Fetch source image properties - $this->get_image_properties(); - - // Set RGB values for text and shadow + + // Fetch source image properties + $this->get_image_properties(); + + // Set RGB values for text and shadow $this->wm_font_color = str_replace('#', '', $this->wm_font_color); $this->wm_shadow_color = str_replace('#', '', $this->wm_shadow_color); - + $R1 = hexdec(substr($this->wm_font_color, 0, 2)); $G1 = hexdec(substr($this->wm_font_color, 2, 2)); $B1 = hexdec(substr($this->wm_font_color, 4, 2)); - + $R2 = hexdec(substr($this->wm_shadow_color, 0, 2)); $G2 = hexdec(substr($this->wm_shadow_color, 2, 2)); $B2 = hexdec(substr($this->wm_shadow_color, 4, 2)); - + $txt_color = imagecolorclosest($src_img, $R1, $G1, $B1); $drp_color = imagecolorclosest($src_img, $R2, $G2, $B2); @@ -1020,10 +1020,10 @@ class CI_Image_lib { // further down. We want the reverse, so we'll // invert the offset. Note: The horizontal // offset flips itself automatically - + if ($this->wm_vrt_alignment == 'B') $this->wm_vrt_offset = $this->wm_vrt_offset * -1; - + if ($this->wm_hor_alignment == 'R') $this->wm_hor_offset = $this->wm_hor_offset * -1; @@ -1034,7 +1034,7 @@ class CI_Image_lib { { if ($this->wm_font_size == '') $this->wm_font_size = '17'; - + $fontwidth = $this->wm_font_size-($this->wm_font_size/4); $fontheight = $this->wm_font_size; $this->wm_vrt_offset += $this->wm_font_size; @@ -1052,10 +1052,10 @@ class CI_Image_lib { // Set verticle alignment if ($this->wm_use_drop_shadow == FALSE) $this->wm_shadow_distance = 0; - + $this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1)); $this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1)); - + switch ($this->wm_vrt_alignment) { case "T" : @@ -1065,10 +1065,10 @@ class CI_Image_lib { case "B": $y_axis += ($this->orig_height - $fontheight - $this->wm_shadow_distance - ($fontheight/2)); break; } - + $x_shad = $x_axis + $this->wm_shadow_distance; $y_shad = $y_axis + $this->wm_shadow_distance; - + // Set horizontal alignment switch ($this->wm_hor_alignment) { @@ -1085,10 +1085,10 @@ class CI_Image_lib { $x_axis += floor(($this->orig_width -$fontwidth*strlen($this->wm_text))/2); break; } - + // Add the text to the source image if ($this->wm_use_truetype) - { + { if ($this->wm_use_drop_shadow) imagettftext($src_img, $this->wm_font_size, 0, $x_shad, $y_shad, $drp_color, $this->wm_font_path, $this->wm_text); imagettftext($src_img, $this->wm_font_size, 0, $x_axis, $y_axis, $txt_color, $this->wm_font_path, $this->wm_text); @@ -1099,7 +1099,7 @@ class CI_Image_lib { imagestring($src_img, $this->wm_font_size, $x_shad, $y_shad, $this->wm_text, $drp_color); imagestring($src_img, $this->wm_font_size, $x_axis, $y_axis, $this->wm_text, $txt_color); } - + // Output the final image if ($this->dynamic_output == TRUE) { @@ -1109,14 +1109,14 @@ class CI_Image_lib { { $this->image_save_gd($src_img); } - + imagedestroy($src_img); - + return TRUE; } - + // -------------------------------------------------------------------- - + /** * Create Image - GD * @@ -1126,16 +1126,16 @@ class CI_Image_lib { * @access public * @param string * @return resource - */ + */ function image_create_gd($path = '', $image_type = '') { if ($path == '') $path = $this->full_src_path; - + if ($image_type == '') $image_type = $this->image_type; - - + + switch ($image_type) { case 1 : @@ -1144,7 +1144,7 @@ class CI_Image_lib { $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported')); return FALSE; } - + return imagecreatefromgif($path); break; case 2 : @@ -1153,27 +1153,27 @@ class CI_Image_lib { $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported')); return FALSE; } - + return imagecreatefromjpeg($path); break; case 3 : if ( ! function_exists('imagecreatefrompng')) { - $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported')); + $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported')); return FALSE; } - + return imagecreatefrompng($path); - break; - + break; + } - + $this->set_error(array('imglib_unsupported_imagecreate')); return FALSE; } - + // -------------------------------------------------------------------- - + /** * Write image file to disk - GD * @@ -1183,68 +1183,80 @@ class CI_Image_lib { * @access public * @param resource * @return bool - */ + */ function image_save_gd($resource) - { + { switch ($this->image_type) { case 1 : if ( ! function_exists('imagegif')) { $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported')); - return FALSE; + return FALSE; + } + + if ( ! @imagegif($resource, $this->full_dst_path)) + { + $this->set_error('imglib_save_failed'); + return FALSE; } - - @imagegif($resource, $this->full_dst_path); break; case 2 : if ( ! function_exists('imagejpeg')) { $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported')); - return FALSE; + return FALSE; } - + if (phpversion() == '4.4.1') { @touch($this->full_dst_path); // PHP 4.4.1 bug #35060 - workaround } - - @imagejpeg($resource, $this->full_dst_path, $this->quality); + + if ( ! @imagejpeg($resource, $this->full_dst_path, $this->quality)) + { + $this->set_error('imglib_save_failed'); + return FALSE; + } break; case 3 : if ( ! function_exists('imagepng')) { $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported')); - return FALSE; + return FALSE; + } + + if ( ! @imagepng($resource, $this->full_dst_path)) + { + $this->set_error('imglib_save_failed'); + return FALSE; } - - @imagepng($resource, $this->full_dst_path); break; default : $this->set_error(array('imglib_unsupported_imagecreate')); - return FALSE; - break; + return FALSE; + break; } - + return TRUE; - } - + } + // -------------------------------------------------------------------- - + /** * Dynamically outputs an image * * @access public * @param resource * @return void - */ + */ function image_display_gd($resource) - { + { header("Content-Disposition: filename={$this->source_image};"); header("Content-Type: {$this->mime_type}"); header('Content-Transfer-Encoding: binary'); header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT'); - + switch ($this->image_type) { case 1 : imagegif($resource); @@ -1254,12 +1266,12 @@ class CI_Image_lib { case 3 : imagepng($resource); break; default : echo 'Unable to display the image'; - break; - } + break; + } } - + // -------------------------------------------------------------------- - + /** * Re-proportion Image Width/Height * @@ -1272,25 +1284,25 @@ class CI_Image_lib { * * @access public * @return void - */ + */ function image_reproportion() { if ( ! is_numeric($this->width) OR ! is_numeric($this->height) OR $this->width == 0 OR $this->height == 0) return; - + if ( ! is_numeric($this->orig_width) OR ! is_numeric($this->orig_height) OR $this->orig_width == 0 OR $this->orig_height == 0) return; - - $new_width = ceil($this->orig_width*$this->height/$this->orig_height); + + $new_width = ceil($this->orig_width*$this->height/$this->orig_height); $new_height = ceil($this->width*$this->orig_height/$this->orig_width); - + $ratio = (($this->orig_height/$this->orig_width) - ($this->height/$this->width)); - + if ($this->master_dim != 'width' AND $this->master_dim != 'height') { $this->master_dim = ($ratio < 0) ? 'width' : 'height'; } - + if (($this->width != $new_width) AND ($this->height != $new_height)) { if ($this->master_dim == 'height') @@ -1302,10 +1314,10 @@ class CI_Image_lib { $this->height = $new_height; } } - } - + } + // -------------------------------------------------------------------- - + /** * Get image properties * @@ -1314,27 +1326,27 @@ class CI_Image_lib { * @access public * @param string * @return mixed - */ + */ function get_image_properties($path = '', $return = FALSE) { // For now we require GD but we should // find a way to determine this using IM or NetPBM - + if ($path == '') $path = $this->full_src_path; - + if ( ! file_exists($path)) { - $this->set_error('imglib_invalid_path'); - return FALSE; + $this->set_error('imglib_invalid_path'); + return FALSE; } - + $vals = @getimagesize($path); - + $types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png'); - + $mime = (isset($types[$vals['2']])) ? 'image/'.$types[$vals['2']] : 'image/jpg'; - + if ($return == TRUE) { $v['width'] = $vals['0']; @@ -1342,21 +1354,21 @@ class CI_Image_lib { $v['image_type'] = $vals['2']; $v['size_str'] = $vals['3']; $v['mime_type'] = $mime; - + return $v; } - + $this->orig_width = $vals['0']; $this->orig_height = $vals['1']; $this->image_type = $vals['2']; $this->size_str = $vals['3']; $this->mime_type = $mime; - + return TRUE; } - + // -------------------------------------------------------------------- - + /** * Size calculator * @@ -1374,25 +1386,27 @@ class CI_Image_lib { * @access public * @param array * @return array - */ + */ function size_calculator($vals) { if ( ! is_array($vals)) + { return; - + } + $allowed = array('new_width', 'new_height', 'width', 'height'); - + foreach ($allowed as $item) { if ( ! isset($vals[$item]) OR $vals[$item] == '') $vals[$item] = 0; } - + if ($vals['width'] == 0 OR $vals['height'] == 0) { return $vals; } - + if ($vals['new_width'] == 0) { $vals['new_width'] = ceil($vals['width']*$vals['new_height']/$vals['height']); @@ -1401,12 +1415,12 @@ class CI_Image_lib { { $vals['new_height'] = ceil($vals['new_width']*$vals['height']/$vals['width']); } - + return $vals; } - + // -------------------------------------------------------------------- - + /** * Explode source_image * @@ -1420,39 +1434,23 @@ class CI_Image_lib { * @access public * @param array * @return array - */ + */ function explode_name($source_image) { - $x = explode('.', $source_image); - $ret['ext'] = '.'.end($x); - - $name = ''; - - $ct = count($x)-1; - - for ($i = 0; $i < $ct; $i++) - { - $name .= $x[$i]; - - if ($i < ($ct - 1)) - { - $name .= '.'; - } - } + $ext = strrchr($source_image, '.'); + $name = ($ext === FALSE) ? $source_image : substr($source_image, 0, -strlen($ext)); - $ret['name'] = $name; - - return $ret; - } - + return array('ext' => $ext, 'name' => $name); + } + // -------------------------------------------------------------------- - + /** * Is GD Installed? * * @access public * @return bool - */ + */ function gd_loaded() { if ( ! extension_loaded('gd')) @@ -1462,54 +1460,54 @@ class CI_Image_lib { return FALSE; } } - + return TRUE; } - + // -------------------------------------------------------------------- - + /** * Get GD version * * @access public * @return mixed - */ + */ function gd_version() { if (function_exists('gd_info')) { $gd_version = @gd_info(); $gd_version = preg_replace("/\D/", "", $gd_version['GD Version']); - + return $gd_version; } - + return FALSE; } - + // -------------------------------------------------------------------- - + /** * Set error message * * @access public * @param string * @return void - */ + */ function set_error($msg) { $CI =& get_instance(); $CI->lang->load('imglib'); - + if (is_array($msg)) { foreach ($msg as $val) { - + $msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val); $this->error_msg[] = $msg; log_message('error', $msg); - } + } } else { @@ -1518,24 +1516,24 @@ class CI_Image_lib { log_message('error', $msg); } } - + // -------------------------------------------------------------------- - + /** * Show error messages * * @access public * @param string * @return string - */ + */ function display_errors($open = '

    ', $close = '

    ') - { + { $str = ''; foreach ($this->error_msg as $val) { $str .= $open.$val.$close; } - + return $str; } diff --git a/libraries/Input.php b/libraries/Input.php index ee4bb1c..e7bf727 100644 --- a/libraries/Input.php +++ b/libraries/Input.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -32,7 +32,7 @@ class CI_Input { var $ip_address = FALSE; var $user_agent = FALSE; var $allow_get_array = FALSE; - + /* never allowed, string replacement */ var $never_allowed_str = array( 'document.cookie' => '[removed]', @@ -47,19 +47,20 @@ class CI_Input { ); /* never allowed, regex replacement */ var $never_allowed_regex = array( - "javascript\s*:" => '[removed]', - "expression\s*\(" => '[removed]', // CSS and IE - "Redirect\s+302" => '[removed]' + "javascript\s*:" => '[removed]', + "expression\s*(\(|&\#40;)" => '[removed]', // CSS and IE + "vbscript\s*:" => '[removed]', // IE, surprise! + "Redirect\s+302" => '[removed]' ); - + /** - * Constructor - * - * Sets whether to globally enable the XSS processing - * and whether to allow the $_GET array - * - * @access public - */ + * Constructor + * + * Sets whether to globally enable the XSS processing + * and whether to allow the $_GET array + * + * @access public + */ function CI_Input() { log_message('debug', "Input Class Initialized"); @@ -73,19 +74,19 @@ class CI_Input { // -------------------------------------------------------------------- /** - * Sanitize Globals - * - * This function does the following: - * - * Unsets $_GET data (if query strings are not enabled) - * - * Unsets all globals if register_globals is enabled - * - * Standardizes newline characters to \n - * - * @access private - * @return void - */ + * Sanitize Globals + * + * This function does the following: + * + * Unsets $_GET data (if query strings are not enabled) + * + * Unsets all globals if register_globals is enabled + * + * Standardizes newline characters to \n + * + * @access private + * @return void + */ function _sanitize_globals() { // Would kind of be "wrong" to unset any of these GLOBALS @@ -111,7 +112,7 @@ class CI_Input { { unset($GLOBALS[$key]); } - + if (is_array($val)) { foreach($val as $k => $v) @@ -138,7 +139,7 @@ class CI_Input { // Clean $_POST Data $_POST = $this->_clean_input_data($_POST); - + // Clean $_COOKIE Data // Also get rid of specially treated cookies that might be set by a server // or silly application, that are of no use to a CI application anyway @@ -156,15 +157,15 @@ class CI_Input { // -------------------------------------------------------------------- /** - * Clean Input Data - * - * This is a helper function. It escapes data and - * standardizes newline characters to \n - * - * @access private - * @param string - * @return string - */ + * Clean Input Data + * + * This is a helper function. It escapes data and + * standardizes newline characters to \n + * + * @access private + * @param string + * @return string + */ function _clean_input_data($str) { if (is_array($str)) @@ -194,46 +195,46 @@ class CI_Input { { $str = str_replace(array("\r\n", "\r"), "\n", $str); } - + return $str; } // -------------------------------------------------------------------- /** - * Clean Keys - * - * This is a helper function. To prevent malicious users - * from trying to exploit keys we make sure that keys are - * only named with alpha-numeric text and a few other items. - * - * @access private - * @param string - * @return string - */ + * Clean Keys + * + * This is a helper function. To prevent malicious users + * from trying to exploit keys we make sure that keys are + * only named with alpha-numeric text and a few other items. + * + * @access private + * @param string + * @return string + */ function _clean_input_keys($str) { - if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str)) - { + if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str)) + { exit('Disallowed Key Characters.'); - } + } return $str; } // -------------------------------------------------------------------- - + /** - * Fetch from array - * - * This is a helper function to retrieve values from global arrays - * - * @access private - * @param array - * @param string - * @param bool - * @return string - */ + * Fetch from array + * + * This is a helper function to retrieve values from global arrays + * + * @access private + * @param array + * @param string + * @param bool + * @return string + */ function _fetch_from_array(&$array, $index = '', $xss_clean = FALSE) { if ( ! isset($array[$index])) @@ -250,15 +251,15 @@ class CI_Input { } // -------------------------------------------------------------------- - + /** - * Fetch an item from the GET array - * - * @access public - * @param string - * @param bool - * @return string - */ + * Fetch an item from the GET array + * + * @access public + * @param string + * @param bool + * @return string + */ function get($index = '', $xss_clean = FALSE) { return $this->_fetch_from_array($_GET, $index, $xss_clean); @@ -267,13 +268,13 @@ class CI_Input { // -------------------------------------------------------------------- /** - * Fetch an item from the POST array - * - * @access public - * @param string - * @param bool - * @return string - */ + * Fetch an item from the POST array + * + * @access public + * @param string + * @param bool + * @return string + */ function post($index = '', $xss_clean = FALSE) { return $this->_fetch_from_array($_POST, $index, $xss_clean); @@ -282,15 +283,15 @@ class CI_Input { // -------------------------------------------------------------------- /** - * Fetch an item from either the GET array or the POST - * - * @access public - * @param string The index key - * @param bool XSS cleaning - * @return string - */ + * Fetch an item from either the GET array or the POST + * + * @access public + * @param string The index key + * @param bool XSS cleaning + * @return string + */ function get_post($index = '', $xss_clean = FALSE) - { + { if ( ! isset($_POST[$index]) ) { return $this->get($index, $xss_clean); @@ -298,19 +299,19 @@ class CI_Input { else { return $this->post($index, $xss_clean); - } + } } // -------------------------------------------------------------------- /** - * Fetch an item from the COOKIE array - * - * @access public - * @param string - * @param bool - * @return string - */ + * Fetch an item from the COOKIE array + * + * @access public + * @param string + * @param bool + * @return string + */ function cookie($index = '', $xss_clean = FALSE) { return $this->_fetch_from_array($_COOKIE, $index, $xss_clean); @@ -319,13 +320,13 @@ class CI_Input { // -------------------------------------------------------------------- /** - * Fetch an item from the SERVER array - * - * @access public - * @param string - * @param bool - * @return string - */ + * Fetch an item from the SERVER array + * + * @access public + * @param string + * @param bool + * @return string + */ function server($index = '', $xss_clean = FALSE) { return $this->_fetch_from_array($_SERVER, $index, $xss_clean); @@ -334,33 +335,40 @@ class CI_Input { // -------------------------------------------------------------------- /** - * Fetch the IP Address - * - * @access public - * @return string - */ + * Fetch the IP Address + * + * @access public + * @return string + */ function ip_address() { if ($this->ip_address !== FALSE) { return $this->ip_address; } + + if (config_item('proxy_ips') != '' && $this->server('HTTP_X_FORWARDED_FOR') && $this->server('REMOTE_ADDR')) + { + $proxies = preg_split('/[\s,]/', config_item('proxy_ips'), -1, PREG_SPLIT_NO_EMPTY); + $proxies = is_array($proxies) ? $proxies : array($proxies); - if ($this->server('REMOTE_ADDR') AND $this->server('HTTP_CLIENT_IP')) + $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')) { - $this->ip_address = $_SERVER['HTTP_CLIENT_IP']; + $this->ip_address = $_SERVER['HTTP_CLIENT_IP']; } elseif ($this->server('REMOTE_ADDR')) { - $this->ip_address = $_SERVER['REMOTE_ADDR']; + $this->ip_address = $_SERVER['REMOTE_ADDR']; } elseif ($this->server('HTTP_CLIENT_IP')) { - $this->ip_address = $_SERVER['HTTP_CLIENT_IP']; + $this->ip_address = $_SERVER['HTTP_CLIENT_IP']; } elseif ($this->server('HTTP_X_FORWARDED_FOR')) { - $this->ip_address = $_SERVER['HTTP_X_FORWARDED_FOR']; + $this->ip_address = $_SERVER['HTTP_X_FORWARDED_FOR']; } if ($this->ip_address === FALSE) @@ -372,28 +380,28 @@ class CI_Input { if (strstr($this->ip_address, ',')) { $x = explode(',', $this->ip_address); - $this->ip_address = end($x); + $this->ip_address = trim(end($x)); } if ( ! $this->valid_ip($this->ip_address)) { $this->ip_address = '0.0.0.0'; } - + return $this->ip_address; } // -------------------------------------------------------------------- /** - * Validate IP Address - * - * Updated version suggested by Geert De Deckere - * - * @access public - * @param string - * @return string - */ + * Validate IP Address + * + * Updated version suggested by Geert De Deckere + * + * @access public + * @param string + * @return string + */ function valid_ip($ip) { $ip_segments = explode('.', $ip); @@ -425,11 +433,11 @@ class CI_Input { // -------------------------------------------------------------------- /** - * User Agent - * - * @access public - * @return string - */ + * User Agent + * + * @access public + * @return string + */ function user_agent() { if ($this->user_agent !== FALSE) @@ -445,12 +453,12 @@ class CI_Input { // -------------------------------------------------------------------- /** - * Filename Security - * - * @access public - * @param string - * @return string - */ + * Filename Security + * + * @access public + * @param string + * @return string + */ function filename_security($str) { $bad = array( @@ -494,179 +502,179 @@ class CI_Input { // -------------------------------------------------------------------- /** - * XSS Clean - * - * Sanitizes data so that Cross Site Scripting Hacks can be - * prevented. This function does a fair amount of work but - * it is extremely thorough, designed to prevent even the - * most obscure XSS attempts. Nothing is ever 100% foolproof, - * of course, but I haven't been able to get anything passed - * the filter. - * - * Note: This function should only be used to deal with data - * upon submission. It's not something that should - * be used for general runtime processing. - * - * This function was based in part on some code and ideas I - * got from Bitflux: http://blog.bitflux.ch/wiki/XSS_Prevention - * - * To help develop this script I used this great list of - * vulnerabilities along with a few other hacks I've - * harvested from examining vulnerabilities in other programs: - * http://ha.ckers.org/xss.html - * - * @access public - * @param string - * @return string - */ + * XSS Clean + * + * Sanitizes data so that Cross Site Scripting Hacks can be + * prevented. This function does a fair amount of work but + * it is extremely thorough, designed to prevent even the + * most obscure XSS attempts. Nothing is ever 100% foolproof, + * of course, but I haven't been able to get anything passed + * the filter. + * + * Note: This function should only be used to deal with data + * upon submission. It's not something that should + * be used for general runtime processing. + * + * This function was based in part on some code and ideas I + * got from Bitflux: http://blog.bitflux.ch/wiki/XSS_Prevention + * + * To help develop this script I used this great list of + * vulnerabilities along with a few other hacks I've + * harvested from examining vulnerabilities in other programs: + * http://ha.ckers.org/xss.html + * + * @access public + * @param string + * @return string + */ function xss_clean($str, $is_image = FALSE) { /* - * Is the string an array? - * - */ + * Is the string an array? + * + */ if (is_array($str)) { while (list($key) = each($str)) { $str[$key] = $this->xss_clean($str[$key]); } - + return $str; } /* - * Remove Invisible Characters - */ + * Remove Invisible Characters + */ $str = $this->_remove_invisible_characters($str); /* - * Protect GET variables in URLs - */ - - // 901119URL5918AMP18930PROTECT8198 - + * Protect GET variables in URLs + */ + + // 901119URL5918AMP18930PROTECT8198 + $str = preg_replace('|\&([a-z\_0-9]+)\=([a-z\_0-9]+)|i', $this->xss_hash()."\\1=\\2", $str); /* - * Validate standard character entities - * - * Add a semicolon if missing. We do this to enable - * the conversion of entities to ASCII later. - * - */ - $str = preg_replace('#(&\#?[0-9a-z]{2,})[\x00-\x20]*;?#i', "\\1;", $str); + * Validate standard character entities + * + * Add a semicolon if missing. We do this to enable + * the conversion of entities to ASCII later. + * + */ + $str = preg_replace('#(&\#?[0-9a-z]{2,})([\x00-\x20])*;?#i', "\\1;\\2", $str); /* - * Validate UTF16 two byte encoding (x00) - * - * Just as above, adds a semicolon if missing. - * - */ + * Validate UTF16 two byte encoding (x00) + * + * Just as above, adds a semicolon if missing. + * + */ $str = preg_replace('#(&\#x?)([0-9A-F]+);?#i',"\\1\\2;",$str); /* - * Un-Protect GET variables in URLs - */ + * Un-Protect GET variables in URLs + */ $str = str_replace($this->xss_hash(), '&', $str); /* - * URL Decode - * - * Just in case stuff like this is submitted: - * - * Google - * - * Note: Use rawurldecode() so it does not remove plus signs - * - */ + * URL Decode + * + * Just in case stuff like this is submitted: + * + * Google + * + * Note: Use rawurldecode() so it does not remove plus signs + * + */ $str = rawurldecode($str); - + /* - * Convert character entities to ASCII - * - * This permits our tests below to work reliably. - * We only convert entities that are within tags since - * these are the ones that will pose security problems. - * - */ + * Convert character entities to ASCII + * + * This permits our tests below to work reliably. + * We only convert entities that are within tags since + * these are the ones that will pose security problems. + * + */ $str = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, '_convert_attribute'), $str); - + $str = preg_replace_callback("/<\w+.*?(?=>|<|$)/si", array($this, '_html_entity_decode_callback'), $str); /* - * Remove Invisible Characters Again! - */ + * Remove Invisible Characters Again! + */ $str = $this->_remove_invisible_characters($str); - + /* - * Convert all tabs to spaces - * - * This prevents strings like this: ja vascript - * NOTE: we deal with spaces between characters later. - * NOTE: preg_replace was found to be amazingly slow here on large blocks of data, - * so we use str_replace. - * - */ - + * Convert all tabs to spaces + * + * This prevents strings like this: ja vascript + * NOTE: we deal with spaces between characters later. + * NOTE: preg_replace was found to be amazingly slow here on large blocks of data, + * so we use str_replace. + * + */ + if (strpos($str, "\t") !== FALSE) { $str = str_replace("\t", ' ', $str); } - + /* - * Capture converted string for later comparison - */ + * Capture converted string for later comparison + */ $converted_string = $str; - + /* - * Not Allowed Under Any Conditions - */ - + * Not Allowed Under Any Conditions + */ + foreach ($this->never_allowed_str as $key => $val) { $str = str_replace($key, $val, $str); } - + foreach ($this->never_allowed_regex as $key => $val) { $str = preg_replace("#".$key."#i", $val, $str); } /* - * Makes PHP tags safe - * - * Note: XML tags are inadvertently replaced too: - * - * '), array('<?php', '<?PHP', '<?', '?>'), $str); + $str = str_replace(array(''), array('<?', '?>'), $str); } - + /* - * Compact any exploded words - * - * This corrects words like: j a v a s c r i p t - * These words are compacted back to their correct state. - * - */ + * Compact any exploded words + * + * This corrects words like: j a v a s c r i p t + * These words are compacted back to their correct state. + * + */ $words = array('javascript', 'expression', 'vbscript', 'script', 'applet', 'alert', 'document', 'write', 'cookie', 'window'); foreach ($words as $word) { $temp = ''; - + for ($i = 0, $wordlen = strlen($word); $i < $wordlen; $i++) { $temp .= substr($word, $i, 1)."\s*"; @@ -676,26 +684,26 @@ class CI_Input { // 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); } - + /* - * Remove disallowed Javascript in links or img tags - * We used to do some version comparisons and use of stripos for PHP5, but it is dog slow compared - * to these simplified non-capturing preg_match(), especially if the pattern exists in the string - */ + * Remove disallowed Javascript in links or img tags + * We used to do some version comparisons and use of stripos for PHP5, but it is dog slow compared + * to these simplified non-capturing preg_match(), especially if the pattern exists in the string + */ do { $original = $str; - + if (preg_match("/]*?)(>|$)#si", array($this, '_js_link_removal'), $str); } - + if (preg_match("/]*?)(\s?/?>|$)#si", array($this, '_js_img_removal'), $str); } - + if (preg_match("/script/i", $str) OR preg_match("/xss/i", $str)) { $str = preg_replace("#<(/*)(script|xss)(.*?)\>#si", '[removed]', $str); @@ -706,78 +714,78 @@ class CI_Input { unset($original); /* - * Remove JavaScript Event Handlers - * - * Note: This code is a little blunt. It removes - * the event handler and anything up to the closing >, - * but it's unlikely to be a problem. - * - */ + * Remove JavaScript Event Handlers + * + * Note: This code is a little blunt. It removes + * the event handler and anything up to the closing >, + * but it's unlikely to be a problem. + * + */ $event_handlers = array('[^a-z_\-]on\w*','xmlns'); if ($is_image === TRUE) { /* - * Adobe Photoshop puts XML metadata into JFIF images, including namespacing, - * so we have to allow this for images. -Paul - */ + * Adobe Photoshop puts XML metadata into JFIF images, including namespacing, + * so we have to allow this for images. -Paul + */ unset($event_handlers[array_search('xmlns', $event_handlers)]); } $str = preg_replace("#<([^><]+?)(".implode('|', $event_handlers).")(\s*=\s*[^><]*)([><]*)#i", "<\\1\\4", $str); /* - * Sanitize naughty HTML elements - * - * If a tag containing any of the words in the list - * below is found, the tag gets converted to entities. - * - * So this: - * Becomes: <blink> - * - */ + * Sanitize naughty HTML elements + * + * If a tag containing any of the words in the list + * below is found, the tag gets converted to entities. + * + * So this: + * Becomes: <blink> + * + */ $naughty = 'alert|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|isindex|layer|link|meta|object|plaintext|style|script|textarea|title|video|xml|xss'; $str = preg_replace_callback('#<(/*\s*)('.$naughty.')([^><]*)([><]*)#is', array($this, '_sanitize_naughty_html'), $str); /* - * Sanitize naughty scripting elements - * - * Similar to above, only instead of looking for - * tags it looks for PHP and JavaScript commands - * that are disallowed. Rather than removing the - * code, it simply converts the parenthesis to entities - * rendering the code un-executable. - * - * For example: eval('some code') - * Becomes: eval('some code') - * - */ + * Sanitize naughty scripting elements + * + * Similar to above, only instead of looking for + * tags it looks for PHP and JavaScript commands + * that are disallowed. Rather than removing the + * code, it simply converts the parenthesis to entities + * rendering the code un-executable. + * + * For example: eval('some code') + * Becomes: eval('some code') + * + */ $str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2(\\3)", $str); - + /* - * Final clean up - * - * This adds a bit of extra precaution in case - * something got through the above filters - * - */ + * Final clean up + * + * This adds a bit of extra precaution in case + * something got through the above filters + * + */ foreach ($this->never_allowed_str as $key => $val) { $str = str_replace($key, $val, $str); } - + foreach ($this->never_allowed_regex as $key => $val) { $str = preg_replace("#".$key."#i", $val, $str); } /* - * Images are Handled in a Special Way - * - Essentially, we want to know that after all of the character conversion is done whether - * any unwanted, likely XSS, code was found. If not, we return TRUE, as the image is clean. - * However, if the string post-conversion does not matched the string post-removal of XSS, - * then it fails, as there was unwanted XSS code found and removed/changed during processing. - */ + * Images are Handled in a Special Way + * - Essentially, we want to know that after all of the character conversion is done whether + * any unwanted, likely XSS, code was found. If not, we return TRUE, as the image is clean. + * However, if the string post-conversion does not matched the string post-removal of XSS, + * then it fails, as there was unwanted XSS code found and removed/changed during processing. + */ if ($is_image === TRUE) { @@ -790,7 +798,7 @@ class CI_Input { return FALSE; } } - + log_message('debug', "XSS Filtering completed"); return $str; } @@ -798,11 +806,11 @@ class CI_Input { // -------------------------------------------------------------------- /** - * Random Hash for protecting URLs - * - * @access public - * @return string - */ + * Random Hash for protecting URLs + * + * @access public + * @return string + */ function xss_hash() { if ($this->xss_hash == '') @@ -819,21 +827,21 @@ class CI_Input { } // -------------------------------------------------------------------- - + /** - * Remove Invisible Characters - * - * This prevents sandwiching null characters - * between ascii characters, like Java\0script. - * - * @access public - * @param string - * @return string - */ + * Remove Invisible Characters + * + * This prevents sandwiching null characters + * between ascii characters, like Java\0script. + * + * @access public + * @param string + * @return string + */ function _remove_invisible_characters($str) { static $non_displayables; - + if ( ! isset($non_displayables)) { // every control character except newline (dec 10), carriage return (dec 13), and horizontal tab (dec 09), @@ -857,58 +865,58 @@ class CI_Input { } // -------------------------------------------------------------------- - + /** - * Compact Exploded Words - * - * Callback function for xss_clean() to remove whitespace from - * things like j a v a s c r i p t - * - * @access public - * @param type - * @return type - */ + * Compact Exploded Words + * + * Callback function for xss_clean() to remove whitespace from + * things like j a v a s c r i p t + * + * @access public + * @param type + * @return type + */ function _compact_exploded_words($matches) { return preg_replace('/\s+/s', '', $matches[1]).$matches[2]; } // -------------------------------------------------------------------- - + /** - * Sanitize Naughty HTML - * - * Callback function for xss_clean() to remove naughty HTML elements - * - * @access private - * @param array - * @return string - */ + * Sanitize Naughty HTML + * + * Callback function for xss_clean() to remove naughty HTML elements + * + * @access private + * @param array + * @return string + */ function _sanitize_naughty_html($matches) { // encode opening brace $str = '<'.$matches[1].$matches[2].$matches[3]; - + // encode captured opening or closing brace to prevent recursive vectors $str .= str_replace(array('>', '<'), array('>', '<'), $matches[4]); - + return $str; } // -------------------------------------------------------------------- - + /** - * JS Link Removal - * - * Callback function for xss_clean() to sanitize links - * This limits the PCRE backtracks, making it more performance friendly - * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in - * PHP 5.2+ on link-heavy strings - * - * @access private - * @param array - * @return string - */ + * JS Link Removal + * + * Callback function for xss_clean() to sanitize links + * This limits the PCRE backtracks, making it more performance friendly + * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in + * PHP 5.2+ on link-heavy strings + * + * @access private + * @param array + * @return string + */ function _js_link_removal($match) { $attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1])); @@ -916,17 +924,17 @@ class CI_Input { } /** - * JS Image Removal - * - * Callback function for xss_clean() to sanitize image tags - * This limits the PCRE backtracks, making it more performance friendly - * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in - * PHP 5.2+ on image tag heavy strings - * - * @access private - * @param array - * @return string - */ + * JS Image Removal + * + * Callback function for xss_clean() to sanitize image tags + * This limits the PCRE backtracks, making it more performance friendly + * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in + * PHP 5.2+ on image tag heavy strings + * + * @access private + * @param array + * @return string + */ function _js_img_removal($match) { $attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1])); @@ -936,30 +944,30 @@ class CI_Input { // -------------------------------------------------------------------- /** - * Attribute Conversion - * - * Used as a callback for XSS Clean - * - * @access public - * @param array - * @return string - */ + * Attribute Conversion + * + * Used as a callback for XSS Clean + * + * @access public + * @param array + * @return string + */ function _convert_attribute($match) { - return str_replace(array('>', '<'), array('>', '<'), $match[0]); + return str_replace(array('>', '<', '\\'), array('>', '<', '\\\\'), $match[0]); } // -------------------------------------------------------------------- /** - * HTML Entity Decode Callback - * - * Used as a callback for XSS Clean - * - * @access public - * @param array - * @return string - */ + * HTML Entity Decode Callback + * + * Used as a callback for XSS Clean + * + * @access public + * @param array + * @return string + */ function _html_entity_decode_callback($match) { $CFG =& load_class('Config'); @@ -971,20 +979,20 @@ class CI_Input { // -------------------------------------------------------------------- /** - * HTML Entities Decode - * - * 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 - * - * @access private - * @param string - * @param string - * @return string - */ + * HTML Entities Decode + * + * 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 + * + * @access private + * @param string + * @param string + * @return string + */ /* ------------------------------------------------- /* Replacement for html_entity_decode() /* -------------------------------------------------*/ @@ -1025,16 +1033,16 @@ class CI_Input { } // -------------------------------------------------------------------- - + /** - * Filter Attributes - * - * Filters tag attributes for consistency and safety - * - * @access public - * @param string - * @return string - */ + * Filter Attributes + * + * Filters tag attributes for consistency and safety + * + * @access public + * @param string + * @return string + */ function _filter_attributes($str) { $out = ''; @@ -1043,8 +1051,8 @@ class CI_Input { { foreach ($matches[0] as $match) { - $out .= "{$match}"; - } + $out .= preg_replace("#/\*.*?\*/#s", '', $match); + } } return $out; diff --git a/libraries/Language.php b/libraries/Language.php index 621e217..b679c89 100644 --- a/libraries/Language.php +++ b/libraries/Language.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -33,77 +33,76 @@ class CI_Language { * Constructor * * @access public - */ + */ function CI_Language() { log_message('debug', "Language Class Initialized"); } - + // -------------------------------------------------------------------- - + /** * Load a language file * * @access public * @param mixed the name of the language file to be loaded. Can be an array * @param string the language (english, etc.) - * @return void + * @return mixed */ function load($langfile = '', $idiom = '', $return = FALSE) - { + { $langfile = str_replace(EXT, '', str_replace('_lang.', '', $langfile)).'_lang'.EXT; - + if (in_array($langfile, $this->is_loaded, TRUE)) { return; } - + if ($idiom == '') { $CI =& get_instance(); $deft_lang = $CI->config->item('language'); $idiom = ($deft_lang == '') ? 'english' : $deft_lang; } - + // Determine where the language file is and load it if (file_exists(APPPATH.'language/'.$idiom.'/'.$langfile)) { include(APPPATH.'language/'.$idiom.'/'.$langfile); } else - { + { if (file_exists(BASEPATH.'language/'.$idiom.'/'.$langfile)) { include(BASEPATH.'language/'.$idiom.'/'.$langfile); } else { - show_error('Unable to load the requested language file: language/'.$langfile); + show_error('Unable to load the requested language file: language/'.$idiom.'/'.$langfile); } } - if ( ! isset($lang)) { log_message('error', 'Language file contains no data: language/'.$idiom.'/'.$langfile); return; } - + if ($return == TRUE) { return $lang; } - + $this->is_loaded[] = $langfile; $this->language = array_merge($this->language, $lang); unset($lang); - + log_message('debug', 'Language file loaded: language/'.$idiom.'/'.$langfile); return TRUE; } - + // -------------------------------------------------------------------- - + /** * Fetch a single line of text from the language array * diff --git a/libraries/Loader.php b/libraries/Loader.php index b58cc7d..781c83c 100644 --- a/libraries/Loader.php +++ b/libraries/Loader.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -252,7 +252,7 @@ class CI_Loader { require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_utility'.EXT); $class = 'CI_DB_'.$CI->db->dbdriver.'_utility'; - $CI->dbutil =& new $class(); + $CI->dbutil =& instantiate_class(new $class()); $CI->load->_ci_assign_to_models(); } @@ -868,12 +868,9 @@ class CI_Loader { { include_once(APPPATH.'config/'.strtolower($class).EXT); } - else + elseif (file_exists(APPPATH.'config/'.ucfirst(strtolower($class)).EXT)) { - if (file_exists(APPPATH.'config/'.ucfirst(strtolower($class)).EXT)) - { - include_once(APPPATH.'config/'.ucfirst(strtolower($class)).EXT); - } + include_once(APPPATH.'config/'.ucfirst(strtolower($class)).EXT); } } diff --git a/libraries/Log.php b/libraries/Log.php index 326edaa..d8a07a9 100644 --- a/libraries/Log.php +++ b/libraries/Log.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/libraries/Model.php b/libraries/Model.php index c4cba56..f5e501b 100644 --- a/libraries/Model.php +++ b/libraries/Model.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/libraries/Output.php b/libraries/Output.php index b93963a..4423ac7 100644 --- a/libraries/Output.php +++ b/libraries/Output.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -116,7 +116,8 @@ class CI_Output { /** * Set HTTP Status Header - * + * moved to Common procedural functions in 1.7.2 + * * @access public * @param int the status code * @param string @@ -124,77 +125,7 @@ class CI_Output { */ function set_status_header($code = '200', $text = '') { - $stati = array( - '200' => 'OK', - '201' => 'Created', - '202' => 'Accepted', - '203' => 'Non-Authoritative Information', - '204' => 'No Content', - '205' => 'Reset Content', - '206' => 'Partial Content', - - '300' => 'Multiple Choices', - '301' => 'Moved Permanently', - '302' => 'Found', - '304' => 'Not Modified', - '305' => 'Use Proxy', - '307' => 'Temporary Redirect', - - '400' => 'Bad Request', - '401' => 'Unauthorized', - '403' => 'Forbidden', - '404' => 'Not Found', - '405' => 'Method Not Allowed', - '406' => 'Not Acceptable', - '407' => 'Proxy Authentication Required', - '408' => 'Request Timeout', - '409' => 'Conflict', - '410' => 'Gone', - '411' => 'Length Required', - '412' => 'Precondition Failed', - '413' => 'Request Entity Too Large', - '414' => 'Request-URI Too Long', - '415' => 'Unsupported Media Type', - '416' => 'Requested Range Not Satisfiable', - '417' => 'Expectation Failed', - - '500' => 'Internal Server Error', - '501' => 'Not Implemented', - '502' => 'Bad Gateway', - '503' => 'Service Unavailable', - '504' => 'Gateway Timeout', - '505' => 'HTTP Version Not Supported' - ); - - if ($code == '' OR ! is_numeric($code)) - { - show_error('Status codes must be numeric'); - } - - if (isset($stati[$code]) AND $text == '') - { - $text = $stati[$code]; - } - - if ($text == '') - { - show_error('No status text available. Please check your status code number or supply your own message text.'); - } - - $server_protocol = (isset($_SERVER['SERVER_PROTOCOL'])) ? $_SERVER['SERVER_PROTOCOL'] : FALSE; - - if (substr(php_sapi_name(), 0, 3) == 'cgi') - { - header("Status: {$code} {$text}", TRUE); - } - elseif ($server_protocol == 'HTTP/1.1' OR $server_protocol == 'HTTP/1.0') - { - header($server_protocol." {$code} {$text}", TRUE, $code); - } - else - { - header("HTTP/1.1 {$code} {$text}", TRUE, $code); - } + set_status_header($code, $text); } // -------------------------------------------------------------------- diff --git a/libraries/Pagination.php b/libraries/Pagination.php index 54ddd4c..d73c58e 100644 --- a/libraries/Pagination.php +++ b/libraries/Pagination.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -42,8 +42,8 @@ class CI_Pagination { var $first_tag_close = ' '; var $last_tag_open = ' '; var $last_tag_close = ''; - var $cur_tag_open = ' '; - var $cur_tag_close = ''; + var $cur_tag_open = ' '; + var $cur_tag_close = ''; var $next_tag_open = ' '; var $next_tag_close = ' '; var $prev_tag_open = ' '; @@ -63,14 +63,14 @@ class CI_Pagination { { if (count($params) > 0) { - $this->initialize($params); + $this->initialize($params); } - + log_message('debug', "Pagination Class Initialized"); } - + // -------------------------------------------------------------------- - + /** * Initialize Preferences * @@ -91,21 +91,21 @@ class CI_Pagination { } } } - + // -------------------------------------------------------------------- - + /** * Generate the pagination links * * @access public * @return string - */ + */ function create_links() { // If our item count or per-page total is zero there is no need to continue. if ($this->total_rows == 0 OR $this->per_page == 0) { - return ''; + return ''; } // Calculate the total number of pages @@ -117,15 +117,15 @@ class CI_Pagination { return ''; } - // Determine the current page number. + // 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) { $this->cur_page = $CI->input->get($this->query_string_segment); - + // Prep the current page - no funny business! $this->cur_page = (int) $this->cur_page; } @@ -135,31 +135,31 @@ class CI_Pagination { if ($CI->uri->segment($this->uri_segment) != 0) { $this->cur_page = $CI->uri->segment($this->uri_segment); - + // Prep the current page - no funny business! $this->cur_page = (int) $this->cur_page; } } $this->num_links = (int)$this->num_links; - + if ($this->num_links < 1) { show_error('Your number of links must be a positive number.'); } - + if ( ! is_numeric($this->cur_page)) { $this->cur_page = 0; } - + // Is the page number beyond the result range? // If so we show the last page 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); @@ -200,7 +200,7 @@ class CI_Pagination { for ($loop = $start -1; $loop <= $end; $loop++) { $i = ($loop * $this->per_page) - $this->per_page; - + if ($i >= 0) { if ($this->cur_page == $loop) @@ -234,8 +234,8 @@ class CI_Pagination { // Add the wrapper HTML if exists $output = $this->full_tag_open.$output.$this->full_tag_close; - - return $output; + + return $output; } } // END Pagination Class diff --git a/libraries/Parser.php b/libraries/Parser.php index 3d379b2..da32437 100644 --- a/libraries/Parser.php +++ b/libraries/Parser.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 diff --git a/libraries/Profiler.php b/libraries/Profiler.php index 5e9fa8b..ecd0e70 100644 --- a/libraries/Profiler.php +++ b/libraries/Profiler.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -103,11 +103,11 @@ class CI_Profiler { function _compile_queries() { $dbs = array(); - + // Let's determine which databases are currently connected to foreach (get_object_vars($this->CI) as $CI_object) { - if ( is_subclass_of(get_class($CI_object), 'CI_DB') ) + if (is_object($CI_object) && is_subclass_of(get_class($CI_object), 'CI_DB') ) { $dbs[] = $CI_object; } diff --git a/libraries/Router.php b/libraries/Router.php index 32de58d..50c7dd7 100644 --- a/libraries/Router.php +++ b/libraries/Router.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -97,18 +97,22 @@ class CI_Router { { show_error("Unable to determine what should be displayed. A default route has not been specified in the routing file."); } + + if (strpos($this->default_controller, '/') !== FALSE) + { + $x = explode('/', $this->default_controller); - // Turn the default route into an array. We explode it in the event that - // the controller is located in a subfolder - $segments = $this->_validate_request(explode('/', $this->default_controller)); + $this->set_class(end($x)); + $this->set_method('index'); + $this->_set_request($x); + } + else + { + $this->set_class($this->default_controller); + $this->set_method('index'); + $this->_set_request(array($this->default_controller, 'index')); + } - // Set the class and method - $this->set_class($segments[0]); - $this->set_method('index'); - - // Assign the segments to the URI class - $this->uri->rsegments = $segments; - // re-index the routed segments array so it starts with 1 rather than 0 $this->uri->_reindex_segments(); @@ -144,7 +148,7 @@ class CI_Router { * @return void */ function _set_request($segments = array()) - { + { $segments = $this->_validate_request($segments); if (count($segments) == 0) diff --git a/libraries/Session.php b/libraries/Session.php index 1191308..5e0ce48 100644 --- a/libraries/Session.php +++ b/libraries/Session.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -50,21 +50,21 @@ class CI_Session { * * The constructor runs the session routines automatically * whenever the class is instantiated. - */ + */ function CI_Session($params = array()) { log_message('debug', "Session Class Initialized"); // Set the super object to a local variable for use throughout the class $this->CI =& get_instance(); - - // Set all the session preferences, which can either be set + + // Set all the session preferences, which can either be set // manually via the $params array above or via the config file foreach (array('sess_encrypt_cookie', 'sess_use_database', 'sess_table_name', 'sess_expiration', 'sess_match_ip', 'sess_match_useragent', 'sess_cookie_name', 'cookie_path', 'cookie_domain', 'sess_time_to_update', 'time_reference', 'cookie_prefix', 'encryption_key') as $key) { $this->$key = (isset($params[$key])) ? $params[$key] : $this->CI->config->item($key); - } - + } + // Load the string helper so we can use the strip_slashes() function $this->CI->load->helper('string'); @@ -90,24 +90,24 @@ class CI_Session { { $this->sess_expiration = (60*60*24*365*2); } - + // Set the cookie name $this->sess_cookie_name = $this->cookie_prefix.$this->sess_cookie_name; - - // Run the Session routine. If a session doesn't exist we'll + + // Run the Session routine. If a session doesn't exist we'll // create a new one. If it does, we'll update it. if ( ! $this->sess_read()) { $this->sess_create(); } else - { + { $this->sess_update(); } - + // Delete 'old' flashdata (from last request) $this->_flashdata_sweep(); - + // Mark all new flashdata as old (data will be deleted before next request) $this->_flashdata_mark(); @@ -116,34 +116,34 @@ class CI_Session { log_message('debug', "Session routines successfully run"); } - + // -------------------------------------------------------------------- - + /** * Fetch the current session data if it exists * * @access public - * @return void + * @return bool */ function sess_read() - { + { // Fetch the cookie $session = $this->CI->input->cookie($this->sess_cookie_name); - + // No cookie? Goodbye cruel world!... if ($session === FALSE) { log_message('debug', 'A session cookie was not found.'); return FALSE; } - + // Decrypt the cookie data if ($this->sess_encrypt_cookie == TRUE) { $session = $this->CI->encrypt->decode($session); } else - { + { // encryption was not used, so we need to check the md5 hash $hash = substr($session, strlen($session)-32); // get last 32 chars $session = substr($session, 0, strlen($session)-32); @@ -156,17 +156,17 @@ class CI_Session { return FALSE; } } - + // Unserialize the session array $session = $this->_unserialize($session); - + // Is the session data we unserialized an array with the correct format? if ( ! is_array($session) OR ! isset($session['session_id']) OR ! isset($session['ip_address']) OR ! isset($session['user_agent']) OR ! isset($session['last_activity'])) { $this->sess_destroy(); return FALSE; } - + // Is the session current? if (($session['last_activity'] + $this->sess_expiration) < $this->now) { @@ -180,19 +180,19 @@ class CI_Session { $this->sess_destroy(); return FALSE; } - + // Does the User Agent Match? if ($this->sess_match_useragent == TRUE AND trim($session['user_agent']) != trim(substr($this->CI->input->user_agent(), 0, 50))) { $this->sess_destroy(); return FALSE; } - + // Is there a corresponding session in the DB? if ($this->sess_use_database === TRUE) { $this->CI->db->where('session_id', $session['session_id']); - + if ($this->sess_match_ip == TRUE) { $this->CI->db->where('ip_address', $session['ip_address']); @@ -202,7 +202,7 @@ class CI_Session { { $this->CI->db->where('user_agent', $session['user_agent']); } - + $query = $this->CI->db->get($this->sess_table_name); // No result? Kill it! @@ -225,18 +225,18 @@ class CI_Session { $session[$key] = $val; } } - } + } } - + // Session is valid! $this->userdata = $session; unset($session); - + return TRUE; } - + // -------------------------------------------------------------------- - + /** * Write the session data * @@ -255,7 +255,7 @@ class CI_Session { // set the custom userdata, the session data we will set in a second $custom_userdata = $this->userdata; $cookie_userdata = array(); - + // Before continuing, we need to determine if there is any custom data to deal with. // Let's determine this by removing the default indexes to see if there's anything left in the array // and set the session data while we're at it @@ -264,7 +264,7 @@ class CI_Session { unset($custom_userdata[$val]); $cookie_userdata[$val] = $this->userdata[$val]; } - + // Did we find any custom data? If not, we turn the empty array into a string // since there's no reason to serialize and store an empty array in the DB if (count($custom_userdata) === 0) @@ -272,23 +272,23 @@ class CI_Session { $custom_userdata = ''; } else - { + { // Serialize the custom data array so we can store it $custom_userdata = $this->_serialize($custom_userdata); } - + // Run the update query $this->CI->db->where('session_id', $this->userdata['session_id']); $this->CI->db->update($this->sess_table_name, array('last_activity' => $this->userdata['last_activity'], 'user_data' => $custom_userdata)); // Write the cookie. Notice that we manually pass the cookie data array to the - // _set_cookie() function. Normally that function will store $this->userdata, but + // _set_cookie() function. Normally that function will store $this->userdata, but // in this case that array contains custom data, which we do not want in the cookie. $this->_set_cookie($cookie_userdata); } - + // -------------------------------------------------------------------- - + /** * Create a new session * @@ -296,36 +296,36 @@ class CI_Session { * @return void */ function sess_create() - { + { $sessid = ''; while (strlen($sessid) < 32) { $sessid .= mt_rand(0, mt_getrandmax()); } - + // To make the session ID even more secure we'll combine it with the user's IP $sessid .= $this->CI->input->ip_address(); - + $this->userdata = array( 'session_id' => md5(uniqid($sessid, TRUE)), 'ip_address' => $this->CI->input->ip_address(), 'user_agent' => substr($this->CI->input->user_agent(), 0, 50), 'last_activity' => $this->now ); - - + + // Save the data to the DB if needed if ($this->sess_use_database === TRUE) { $this->CI->db->query($this->CI->db->insert_string($this->sess_table_name, $this->userdata)); } - + // Write the cookie $this->_set_cookie(); } - + // -------------------------------------------------------------------- - + /** * Update an existing session * @@ -339,8 +339,8 @@ class CI_Session { { return; } - - // Save the old session id so we know which record to + + // Save the old session id so we know which record to // update in the database if we need it $old_sessid = $this->userdata['session_id']; $new_sessid = ''; @@ -348,21 +348,21 @@ class CI_Session { { $new_sessid .= mt_rand(0, mt_getrandmax()); } - + // To make the session ID even more secure we'll combine it with the user's IP $new_sessid .= $this->CI->input->ip_address(); - + // Turn it into a hash $new_sessid = md5(uniqid($new_sessid, TRUE)); - + // Update the session data in the session data array $this->userdata['session_id'] = $new_sessid; $this->userdata['last_activity'] = $this->now; - + // _set_cookie() will handle this for us if we aren't using database sessions // by pushing all userdata to the cookie. $cookie_data = NULL; - + // Update the session ID and last_activity field in the DB if needed if ($this->sess_use_database === TRUE) { @@ -372,16 +372,16 @@ class CI_Session { { $cookie_data[$val] = $this->userdata[$val]; } - + $this->CI->db->query($this->CI->db->update_string($this->sess_table_name, array('last_activity' => $this->now, 'session_id' => $new_sessid), array('session_id' => $old_sessid))); } - + // Write the cookie $this->_set_cookie($cookie_data); } - + // -------------------------------------------------------------------- - + /** * Destroy the current session * @@ -389,14 +389,14 @@ class CI_Session { * @return void */ function sess_destroy() - { + { // Kill the session DB row if ($this->sess_use_database === TRUE AND isset($this->userdata['session_id'])) { $this->CI->db->where('session_id', $this->userdata['session_id']); $this->CI->db->delete($this->sess_table_name); } - + // Kill the cookie setcookie( $this->sess_cookie_name, @@ -407,36 +407,36 @@ class CI_Session { 0 ); } - + // -------------------------------------------------------------------- - + /** * Fetch a specific item from the session array * * @access public * @param string * @return string - */ + */ function userdata($item) { return ( ! isset($this->userdata[$item])) ? FALSE : $this->userdata[$item]; } // -------------------------------------------------------------------- - + /** * Fetch all session data * * @access public * @return mixed - */ + */ function all_userdata() { return ( ! isset($this->userdata)) ? FALSE : $this->userdata; } - + // -------------------------------------------------------------------- - + /** * Add or change data in the "userdata" array * @@ -444,14 +444,14 @@ class CI_Session { * @param mixed * @param string * @return void - */ + */ function set_userdata($newdata = array(), $newval = '') { if (is_string($newdata)) { $newdata = array($newdata => $newval); } - + if (count($newdata) > 0) { foreach ($newdata as $key => $val) @@ -462,22 +462,22 @@ class CI_Session { $this->sess_write(); } - + // -------------------------------------------------------------------- - + /** * Delete a session variable from the "userdata" array * * @access array * @return void - */ + */ function unset_userdata($newdata = array()) { if (is_string($newdata)) { $newdata = array($newdata => ''); } - + if (count($newdata) > 0) { foreach ($newdata as $key => $val) @@ -485,10 +485,10 @@ class CI_Session { unset($this->userdata[$key]); } } - + $this->sess_write(); } - + // ------------------------------------------------------------------------ /** @@ -506,7 +506,7 @@ class CI_Session { { $newdata = array($newdata => $newval); } - + if (count($newdata) > 0) { foreach ($newdata as $key => $val) @@ -515,8 +515,8 @@ class CI_Session { $this->set_userdata($flashdata_key, $val); } } - } - + } + // ------------------------------------------------------------------------ /** @@ -528,9 +528,9 @@ class CI_Session { */ function keep_flashdata($key) { - // 'old' flashdata gets removed. Here we mark all + // 'old' flashdata gets removed. Here we mark all // flashdata as 'new' to preserve it from _flashdata_sweep() - // Note the function will return FALSE if the $key + // Note the function will return FALSE if the $key // provided cannot be found $old_flashdata_key = $this->flashdata_key.':old:'.$key; $value = $this->userdata($old_flashdata_key); @@ -538,7 +538,7 @@ class CI_Session { $new_flashdata_key = $this->flashdata_key.':new:'.$key; $this->set_userdata($new_flashdata_key, $value); } - + // ------------------------------------------------------------------------ /** @@ -547,7 +547,7 @@ class CI_Session { * @access public * @param string * @return string - */ + */ function flashdata($key) { $flashdata_key = $this->flashdata_key.':old:'.$key; @@ -601,7 +601,7 @@ class CI_Session { } // -------------------------------------------------------------------- - + /** * Get the "now" time * @@ -619,12 +619,12 @@ class CI_Session { { $time = time(); } - + return $time; } // -------------------------------------------------------------------- - + /** * Write the session cookie * @@ -637,10 +637,10 @@ class CI_Session { { $cookie_data = $this->userdata; } - + // Serialize the userdata for the cookie $cookie_data = $this->_serialize($cookie_data); - + if ($this->sess_encrypt_cookie == TRUE) { $cookie_data = $this->CI->encrypt->encode($cookie_data); @@ -650,7 +650,7 @@ class CI_Session { // if encryption is not used, we provide an md5 hash to prevent userside tampering $cookie_data = $cookie_data.md5($cookie_data.$this->encryption_key); } - + // Set the cookie setcookie( $this->sess_cookie_name, @@ -663,7 +663,7 @@ class CI_Session { } // -------------------------------------------------------------------- - + /** * Serialize an array * @@ -673,7 +673,7 @@ class CI_Session { * @access private * @param array * @return string - */ + */ function _serialize($data) { if (is_array($data)) @@ -687,12 +687,12 @@ class CI_Session { { $data = str_replace('\\', '{{slash}}', $data); } - + return serialize($data); } // -------------------------------------------------------------------- - + /** * Unserialize * @@ -702,26 +702,26 @@ class CI_Session { * @access private * @param array * @return string - */ + */ function _unserialize($data) { $data = @unserialize(strip_slashes($data)); - + if (is_array($data)) { foreach ($data as $key => $val) { $data[$key] = str_replace('{{slash}}', '\\', $val); } - + return $data; } - + return str_replace('{{slash}}', '\\', $data); } // -------------------------------------------------------------------- - + /** * Garbage collection * @@ -737,12 +737,12 @@ class CI_Session { { return; } - + srand(time()); if ((rand() % 100) < $this->gc_probability) { $expire = $this->now - $this->sess_expiration; - + $this->CI->db->where("last_activity < {$expire}"); $this->CI->db->delete($this->sess_table_name); @@ -750,7 +750,7 @@ class CI_Session { } } - + } // END Session Class diff --git a/libraries/Sha1.php b/libraries/Sha1.php index 93982bf..6c39a5b 100644 --- a/libraries/Sha1.php +++ b/libraries/Sha1.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -80,7 +80,7 @@ class CI_SHA { $d = 271733878; $e = -1009589776; - for ($i = 0; $i < sizeof($x); $i += 16) + for ($i = 0; $i < count($x); $i += 16) { $olda = $a; $oldb = $b; diff --git a/libraries/Table.php b/libraries/Table.php index 1afc17c..86d5421 100644 --- a/libraries/Table.php +++ b/libraries/Table.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.3.1 diff --git a/libraries/Trackback.php b/libraries/Trackback.php index 844e503..ab8f46a 100644 --- a/libraries/Trackback.php +++ b/libraries/Trackback.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -267,7 +267,7 @@ class CI_Trackback { } @fclose($fp); - if ( ! eregi("0", $this->response)) + if (stristr($this->response, '0') === FALSE) { $message = 'An unknown error was encountered'; @@ -370,10 +370,7 @@ class CI_Trackback { } else { - if (ereg("/$", $url)) - { - $url = substr($url, 0, -1); - } + $url = rtrim($url, '/'); $tb_array = explode('/', $url); $tb_id = $tb_array[count($tb_array)-1]; diff --git a/libraries/Typography.php b/libraries/Typography.php index 0ee6a24..242ca3c 100644 --- a/libraries/Typography.php +++ b/libraries/Typography.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -30,11 +30,17 @@ class CI_Typography { var $block_elements = 'address|blockquote|div|dl|fieldset|form|h\d|hr|noscript|object|ol|p|pre|script|table|ul'; // Elements that should not have

    and
    tags within them. - var $skip_elements = 'p|pre|ol|ul|dl|object|table'; + var $skip_elements = 'p|pre|ol|ul|dl|object|table|h\d'; // Tags we want the parser to completely ignore when splitting the string. - var $inline_elements = 'a|abbr|acronym|b|bdo|br|button|cite|code|del|dfn|em|i|img|ins|input|label|map|kbd|samp|select|span|strong|sub|sup|textarea|var'; - + var $inline_elements = 'a|abbr|acronym|b|bdo|big|br|button|cite|code|del|dfn|em|i|img|ins|input|label|map|kbd|q|samp|select|small|span|strong|sub|sup|textarea|tt|var'; + + // array of block level elements that require inner content to be within another block level element + var $inner_block_required = array('blockquote'); + + // the last block element parsed + var $last_block_element = ''; + // whether or not to protect quotes within { curly braces } var $protect_braced_quotes = FALSE; @@ -59,11 +65,10 @@ class CI_Typography { * * @access public * @param string - * @param bool whether to strip javascript event handlers for security * @param bool whether to reduce more then two consecutive newlines to two * @return string */ - function auto_typography($str, $strip_js_event_handlers = TRUE, $reduce_linebreaks = FALSE) + function auto_typography($str, $reduce_linebreaks = FALSE) { if ($str == '') { @@ -81,39 +86,38 @@ class CI_Typography { if ($reduce_linebreaks === TRUE) { $str = preg_replace("/\n\n+/", "\n\n", $str); - } - - // Do we allow JavaScript event handlers? If not, we strip them from within all tags - if ($strip_js_event_handlers === TRUE) - { - $str = preg_replace("#<([^><]+?)([^a-z_\-]on\w*|xmlns)(\s*=\s*[^><]*)([><]*)#i", "<\\1\\4", $str); - } + } - // Convert quotes within tags to temporary markers. We don't want quotes converted - // within tags so we'll temporarily convert them to {@DQ} and {@SQ} - if (preg_match_all("#\<.+?>#si", $str, $matches)) + // HTML comment tags don't conform to patterns of normal tags, so pull them out separately, only if needed + $html_comments = array(); + if (strpos($str, '