upgrade to codeigniter 1.7.2 for f12
authorThierry Parmentelat <thierry.parmentelat@sophia.inria.fr>
Mon, 12 Apr 2010 18:00:20 +0000 (18:00 +0000)
committerThierry Parmentelat <thierry.parmentelat@sophia.inria.fr>
Mon, 12 Apr 2010 18:00:20 +0000 (18:00 +0000)
the <?= ?> notation being now unsupported, this still needs to be taken care of

109 files changed:
application/config/autoload.php
application/config/config.php
application/config/doctypes.php [new file with mode: 0644]
application/config/mimes.php
application/config/smileys.php
application/config/user_agents.php
application/errors/error_404.php
codeigniter/Base4.php
codeigniter/Base5.php
codeigniter/CodeIgniter.php
codeigniter/Common.php
codeigniter/Compat.php
database/DB.php
database/DB_active_rec.php
database/DB_cache.php
database/DB_driver.php
database/DB_forge.php
database/DB_result.php
database/DB_utility.php
database/drivers/mssql/mssql_driver.php
database/drivers/mssql/mssql_forge.php
database/drivers/mssql/mssql_result.php
database/drivers/mssql/mssql_utility.php
database/drivers/mysql/mysql_driver.php
database/drivers/mysql/mysql_forge.php
database/drivers/mysql/mysql_result.php
database/drivers/mysql/mysql_utility.php
database/drivers/mysqli/mysqli_driver.php
database/drivers/mysqli/mysqli_forge.php
database/drivers/mysqli/mysqli_result.php
database/drivers/mysqli/mysqli_utility.php
database/drivers/oci8/oci8_driver.php
database/drivers/oci8/oci8_forge.php
database/drivers/oci8/oci8_result.php
database/drivers/oci8/oci8_utility.php
database/drivers/odbc/odbc_driver.php
database/drivers/odbc/odbc_forge.php
database/drivers/odbc/odbc_result.php
database/drivers/odbc/odbc_utility.php
database/drivers/postgre/postgre_driver.php
database/drivers/postgre/postgre_forge.php
database/drivers/postgre/postgre_result.php
database/drivers/postgre/postgre_utility.php
database/drivers/sqlite/sqlite_driver.php
database/drivers/sqlite/sqlite_forge.php
database/drivers/sqlite/sqlite_result.php
database/drivers/sqlite/sqlite_utility.php
helpers/array_helper.php
helpers/compatibility_helper.php
helpers/cookie_helper.php
helpers/date_helper.php
helpers/directory_helper.php
helpers/download_helper.php
helpers/email_helper.php
helpers/file_helper.php
helpers/form_helper.php
helpers/html_helper.php
helpers/inflector_helper.php
helpers/language_helper.php
helpers/number_helper.php
helpers/path_helper.php
helpers/security_helper.php
helpers/smiley_helper.php
helpers/string_helper.php
helpers/text_helper.php
helpers/typography_helper.php
helpers/url_helper.php
helpers/xml_helper.php
index.html [new file with mode: 0644]
language/english/email_lang.php
language/english/imglib_lang.php
libraries/Benchmark.php
libraries/Calendar.php
libraries/Cart.php [new file with mode: 0644]
libraries/Config.php
libraries/Controller.php
libraries/Email.php
libraries/Encrypt.php
libraries/Exceptions.php
libraries/Form_validation.php
libraries/Ftp.php
libraries/Hooks.php
libraries/Image_lib.php
libraries/Input.php
libraries/Language.php
libraries/Loader.php
libraries/Log.php
libraries/Model.php
libraries/Output.php
libraries/Pagination.php
libraries/Parser.php
libraries/Profiler.php
libraries/Router.php
libraries/Session.php
libraries/Sha1.php
libraries/Table.php
libraries/Trackback.php
libraries/Typography.php
libraries/URI.php
libraries/Unit_test.php
libraries/Upload.php
libraries/User_agent.php
libraries/Validation.php
libraries/Xmlrpc.php
libraries/Xmlrpcs.php
libraries/Zip.php
plugins/captcha_pi.php
plugins/js_calendar_pi.php
scaffolding/Scaffolding.php

index fc08553..1745d5c 100644 (file)
@@ -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
index d770823..6059915 100644 (file)
@@ -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 (file)
index 0000000..9d510ab
--- /dev/null
@@ -0,0 +1,15 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+
+$_doctypes = array(
+                                       'xhtml11'               => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
+                                       'xhtml1-strict' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
+                                       'xhtml1-trans'  => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
+                                       'xhtml1-frame'  => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
+                                       'html5'                 => '<!DOCTYPE html>',
+                                       'html4-strict'  => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',
+                                       'html4-trans'   => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
+                                       'html4-frame'   => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">'
+                                       );
+
+/* End of file doctypes.php */
+/* Location: application/config/doctypes.php */
\ No newline at end of file
index 10acfad..438f610 100644 (file)
@@ -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',
index b1988cd..7f3aba5 100644 (file)
@@ -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 */
index f07f6b9..f15b007 100644 (file)
@@ -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",
index bfe9444..1c513a2 100644 (file)
@@ -1,4 +1,3 @@
-<?php header("HTTP/1.1 404 Not Found"); ?>
 <html>
 <head>
 <title>404 Page Not Found</title>
index a95c281..91a4350 100644 (file)
@@ -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
index aa90355..a2cca72 100644 (file)
@@ -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
index fa4bf77..dac137b 100644 (file)
@@ -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);
index 3c75f5e..eb9dce6 100644 (file)
@@ -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
 // ------------------------------------------------------------------------
 
 /**
- * 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
 *
index 6100956..958ab4c 100644 (file)
@@ -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
index ca0cfc2..0f734d7 100644 (file)
@@ -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)
        {
index 4cc54a7..0702199 100644 (file)
@@ -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)
                        {
index 70a2d95..8b0ad4f 100644 (file)
@@ -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
index fae8c28..014dfd4 100644 (file)
@@ -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);
index f708910..4050e30 100644 (file)
@@ -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;
        }
 
        // --------------------------------------------------------------------
index 4128141..4614e29 100644 (file)
@@ -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
index 195e4c4..33c68fa 100644 (file)
@@ -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');
                }
index a3adabc..97ac971 100644 (file)
@@ -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;                    
index 512fc47..632b4d9 100644 (file)
@@ -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
index e9679cb..a56a3a9 100644 (file)
@@ -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
index 38118ac..9fa257a 100644 (file)
@@ -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
index d10a5f0..fe18598 100644 (file)
@@ -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);
        }
index d8cb77e..d343b36 100644 (file)
@@ -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
index 673aeac..2e95507 100644 (file)
@@ -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
index 003b1dd..2c8b264 100644 (file)
@@ -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
index 07a07d3..488b074 100644 (file)
@@ -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;                    
index 99c2ebc..0992274 100644 (file)
@@ -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
index 5b1f793..00fc0db 100644 (file)
@@ -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
index c1d191d..7ebda4c 100644 (file)
@@ -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
index c4e1306..6145719 100644 (file)
@@ -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)
                {
index bbc11f3..c3e9cb9 100644 (file)
@@ -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
index 7d7cd1c..1d0b7db 100644 (file)
@@ -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
index cf6e9e6..c8049c2 100644 (file)
@@ -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
index 6404d54..dacbaab 100644 (file)
@@ -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)
                {
index 5305afb..99cb282 100644 (file)
@@ -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
index 9a59cfc..d6f1501 100644 (file)
@@ -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
index 67aee64..85707a0 100644 (file)
@@ -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
index b141978..9258da6 100644 (file)
@@ -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)
                {
index 72c2dd7..471dd80 100644 (file)
@@ -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
index 3206c13..8e45eb1 100644 (file)
@@ -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
index 06292f2..235954f 100644 (file)
@@ -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
index 968bb3f..0cb7997 100644 (file)
@@ -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)
                {
index 73630de..0688ba3 100644 (file)
@@ -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
index bed1698..c1c24c7 100644 (file)
@@ -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
index c067403..f66464e 100644 (file)
@@ -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
index 411d309..39d0c88 100644 (file)
@@ -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
index 3b37cea..c217f7f 100644 (file)
@@ -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
index d906882..7607ffb 100644 (file)
@@ -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);
        }
 }
 
index dbd7e0e..fae9e66 100644 (file)
@@ -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'];
                }
index be36590..a6fb784 100644 (file)
@@ -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;
+               }
        }
 }
 
index ce2dd48..a8f7b1a 100644 (file)
@@ -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
index af1fdb9..df602b1 100644 (file)
@@ -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
index 8078d96..0d7b5d5 100644 (file)
@@ -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'))
index c002c6f..c5e977a 100644 (file)
@@ -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 '<input type="hidden" name="'.$name.'" value="'.form_prep($value).'" />';
+                       $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 .= '<input type="hidden" name="'.$name.'" value="'.form_prep($value, $name).'" />'."\n";
+               }
+               else
                {
-                       $form .= "\n";
-                       $form .= '<input type="hidden" name="'.$name.'" value="'.form_prep($value).'" />';
+                       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 "<textarea "._parse_form_attributes($data, $defaults).$extra.">".$val."</textarea>";
+               
+               $name = (is_array($data)) ? $data['name'] : $data;
+               return "<textarea "._parse_form_attributes($data, $defaults).$extra.">".form_prep($val, $name)."</textarea>";
        }
 }
 
 // ------------------------------------------------------------------------
 
+/**
+ * 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 = '<select name="'.$name.'"'.$extra.$multiple.">\n";
-       
+
                foreach ($options as $key => $val)
                {
                        $key = (string) $key;
-                       $val = (string) $val;
 
-                       $sel = (in_array($key, $selected))?' selected="selected"':'';
+                       if (is_array($val))
+                       {
+                               $form .= '<optgroup label="'.$key.'">'."\n";
+
+                               foreach ($val as $optgroup_key => $optgroup_val)
+                               {
+                                       $sel = (in_array($optgroup_key, $selected)) ? ' selected="selected"' : '';
+
+                                       $form .= '<option value="'.$optgroup_key.'"'.$sel.'>'.(string) $optgroup_val."</option>\n";
+                               }
+
+                               $form .= '</optgroup>'."\n";
+                       }
+                       else
+                       {
+                               $sel = (in_array($key, $selected)) ? ' selected="selected"' : '';
 
-                       $form .= '<option value="'.$key.'"'.$sel.'>'.$val."</option>\n";
+                               $form .= '<option value="'.$key.'"'.$sel.'>'.(string) $val."</option>\n";
+                       }
                }
 
                $form .= '</select>';
@@ -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("&#39;", "&quot;"), $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 . '" ';
index 8cad736..427d1ce 100644 (file)
@@ -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 .= "<li>";
-               
+
                        if ( ! is_array($val))
                        {
                                $out .= $val;
@@ -149,19 +149,19 @@ if ( ! function_exists('_list'))
                                $out .= str_repeat(" ", $depth + 2);
                        }
 
-                       $out .= "</li>\n";              
+                       $out .= "</li>\n";
                }
 
                // Set the indentation for the closing tag
                $out .= str_repeat(" ", $depth);
-       
+
                // Write the closing list tag
                $out .= "</".$type.">\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("<br />", $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 = '<img';
-               
+
                foreach ($src as $k=>$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 .= '<meta '.$type.'="'.$name.'" content="'.$content.'" />'.$newline;
                }
 
@@ -362,7 +402,7 @@ if ( ! function_exists('meta'))
  * @access     public
  * @param      integer
  * @return     string
- */    
+ */
 if ( ! function_exists('nbs'))
 {
        function nbs($num = 1)
index 9393f11..e65968a 100644 (file)
@@ -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')
                {
index 2091fd4..e97a8c7 100644 (file)
@@ -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
index aeca8b2..a041a60 100644 (file)
@@ -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
index da5df98..502fae4 100644 (file)
@@ -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
index 0e2ba78..9cc70aa 100644 (file)
@@ -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
  *
  * @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);
        }
 }
 
index ce7eb8b..f085e53 100644 (file)
@@ -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
 // ------------------------------------------------------------------------
 
 /**
- * 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 <<<EOF
-<script type="text/javascript">
-       function insert_smiley(smiley)
+       function smiley_js($alias = '', $field_id = '')
        {
-               document.{$form_name}.{$form_field}.value += " " + smiley;
-       }
-</script>
+               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 .= <<<EOF
+                       
+                               var smiley_map = {$m};
+
+                               function insert_smiley(smiley, field_id) {
+                                       var el = document.getElementById(field_id), newStart;
+                               
+                                       if ( ! el && smiley_map[field_id]) {
+                                               el = document.getElementById(smiley_map[field_id]);
+                                       
+                                               if ( ! el)
+                                                       return false;
+                                       }
+                               
+                                       el.focus();
+                                       smiley = " " + smiley;
+
+                                       if ('selectionStart' in el) {
+                                               newStart = el.selectionStart + smiley.length;
+
+                                               el.value = el.value.substr(0, el.selectionStart) +
+                                                                               smiley +
+                                                                               el.value.substr(el.selectionEnd, el.value.length);
+                                               el.setSelectionRange(newStart, newStart);
+                                       }
+                                       else if (document.selection) {
+                                               document.selection.createRange().text = text;
+                                       }
+                               }
 EOF;
+               }
+               else
+               {
+                       if (is_array($alias))
+                       {
+                               foreach($alias as $name => $id)
+                               {
+                                       $r .= 'smiley_map["'.$name.'"] = "'.$id.'";'."\n";
+                               }
+                       }
+               }
+
+               return '<script type="text/javascript" charset="utf-8">'.$r.'</script>';
        }
 }
+
 // ------------------------------------------------------------------------
 
 /**
@@ -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[] = "<a href=\"javascript:void(0);\" onClick=\"insert_smiley('".$key."')\"><img src=\"".$image_url.$smileys[$key][0]."\" width=\"".$smileys[$key][1]."\" height=\"".$smileys[$key][2]."\" alt=\"".$smileys[$key][3]."\" style=\"border:0;\" /></a>";
-
+                       
+                       $link[] = "<a href=\"javascript:void(0);\" onClick=\"insert_smiley('".$key."', '".$alias."')\"><img src=\"".$image_url.$smileys[$key][0]."\" width=\"".$smileys[$key][1]."\" height=\"".$smileys[$key][2]."\" alt=\"".$smileys[$key][3]."\" style=\"border:0;\" /></a>";        
+       
                        $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 <<<EOF
+<script type="text/javascript">
+       function insert_smiley(smiley)
+       {
+               document.{$form_name}.{$form_field}.value += " " + smiley;
+       }
+</script>
+EOF;
+       }
+}
+
 
 /* End of file smiley_helper.php */
 /* Location: ./system/helpers/smiley_helper.php */
\ No newline at end of file
index 319002e..3f7f09a 100644 (file)
@@ -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
index 6e61f77..06910e4 100644 (file)
@@ -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);
        }
 }
        
index 9cbedbb..2706d53 100644 (file)
@@ -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);
        }
 }
 
index fd13dc2..546552a 100644 (file)
@@ -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;
index 90cce3d..2a4c808 100644 (file)
@@ -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 (file)
index 0000000..c942a79
--- /dev/null
@@ -0,0 +1,10 @@
+<html>
+<head>
+       <title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>
\ No newline at end of file
index 9324277..e3bd113 100644 (file)
@@ -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 */
index a587c0b..66505da 100644 (file)
@@ -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 */
index fec5071..695029e 100644 (file)
@@ -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
index ca4b9d5..68d4022 100644 (file)
@@ -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 (file)
index 0000000..2eb8b75
--- /dev/null
@@ -0,0 +1,550 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package            CodeIgniter
+ * @author             ExpressionEngine Dev Team
+ * @copyright  Copyright (c) 2006 - 2009, EllisLab, Inc.
+ * @license            http://codeigniter.com/user_guide/license.html
+ * @link               http://codeigniter.com
+ * @since              Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Shopping Cart Class
+ *
+ * @package            CodeIgniter
+ * @subpackage Libraries
+ * @category   Shopping Cart
+ * @author             ExpressionEngine Dev Team
+ * @link               http://codeigniter.com/user_guide/libraries/cart.html
+ */
+class CI_Cart {
+
+       // These are the regular expression rules that we use to validate the product ID and product name
+       var $product_id_rules   = '\.a-z0-9_-'; // alpha-numeric, dashes, underscores, or periods
+       var $product_name_rules = '\.\:\-_ a-z0-9'; // alpha-numeric, dashes, underscores, colons or periods
+       
+       // Private variables.  Do not change!
+       var $CI;
+       var $_cart_contents     = array();
+
+
+       /**
+        * Shopping Class Constructor
+        *
+        * The constructor loads the Session class, used to store the shopping cart contents.
+        */             
+       function CI_Cart($params = array())
+       {       
+               // Set the super object to a local variable for use later
+               $this->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
index 027f6bf..4ef2786 100644 (file)
@@ -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; 
                }
        }
        
index db156c8..5e93de3 100644 (file)
@@ -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
index 7bcb1d8..5858159 100644 (file)
@@ -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[] = "<pre>".$cmd.": ".$reply."</pre>";
 
@@ -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 .= "<pre>".$this->_header_str."\n".htmlspecialchars($this->_subject)."\n".htmlspecialchars($this->_finalbody).'</pre>';    
+               $msg .= "<pre>".$this->_header_str."\n".htmlspecialchars($this->_subject)."\n".htmlspecialchars($this->_finalbody).'</pre>';
                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)."<br />";
-               }       
+               }
                else
                {
                        $this->_debug_msg[] = str_replace('%s', $val, $line)."<br />";
-               }       
+               }
        }
-       
+  
        // --------------------------------------------------------------------
 
        /**
index 4edfaa7..95c758f 100644 (file)
@@ -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
index 541fd1a..9c655a1 100644 (file)
@@ -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 = '<p>'.implode('</p><p>', ( ! is_array($message)) ? array($message) : $message).'</p>';
 
                if (ob_get_level() > $this->ob_level + 1)
index 528d410..1497d85 100644 (file)
@@ -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);
 
index db65877..6fb1704 100644 (file)
@@ -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));
        }
 
 
index 76584a7..0b5d468 100644 (file)
@@ -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
  * @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;
        }
index c5ebc8f..169c6e4 100644 (file)
@@ -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
  * @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 = '<p>', $close = '</p>')
-       {       
+       {
                $str = '';
                foreach ($this->error_msg as $val)
                {
                        $str .= $open.$val.$close;
                }
-       
+
                return $str;
        }
 
index ee4bb1c..e7bf727 100644 (file)
@@ -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:
-                *
-                * <a href="http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D">Google</a>
-                *
-                * Note: Use rawurldecode() so it does not remove plus signs
-                *
-                */
+               * URL Decode
+               *
+               * Just in case stuff like this is submitted:
+               *
+               * <a href="http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D">Google</a>
+               *
+               * 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:
-                *
-                *      <?xml
-                *
-                * But it doesn't seem to pose a problem.
-                *
-                */
+               * Makes PHP tags safe
+               *
+               *  Note: XML tags are inadvertently replaced too:
+               *
+                     <?xml
+               *
+               * But it doesn't seem to pose a problem.
+               *
+               */
                if ($is_image === TRUE)
                {
                        // Images have a tendency to have the PHP short opening and closing tags every so often
                        // so we skip those and only do the long opening tags.
-                       $str = str_replace(array('<?php', '<?PHP'),  array('&lt;?php', '&lt;?PHP'), $str);
+                       $str = preg_replace('/<\?(php)/i', "&lt;?\\1", $str);
                }
                else
                {
-                       $str = str_replace(array('<?php', '<?PHP', '<?', '?'.'>'),  array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);
+                       $str = str_replace(array('<?', '?'.'>'),  array('&lt;?', '?&gt;'), $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("/<a/i", $str))
                        {
                                $str = preg_replace_callback("#<a\s+([^>]*?)(>|$)#si", array($this, '_js_link_removal'), $str);
                        }
-       
+
                        if (preg_match("/<img/i", $str))
                        {
                                $str = preg_replace_callback("#<img\s+([^>]*?)(\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: <blink>
-                * Becomes: &lt;blink&gt;
-                *
-                */
+               * 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: <blink>
+               * Becomes: &lt;blink&gt;
+               *
+               */
                $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&#40;'some code'&#41;
-                *
-                */
+               * 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&#40;'some code'&#41;
+               *
+               */
                $str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2&#40;\\3&#41;", $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 = '&lt;'.$matches[1].$matches[2].$matches[3];
-               
+
                // encode captured opening or closing brace to prevent recursive vectors
                $str .= str_replace(array('>', '<'), array('&gt;', '&lt;'), $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('&gt;', '&lt;'), $match[0]);
+               return str_replace(array('>', '<', '\\'), array('&gt;', '&lt;', '\\\\'), $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;
index 621e217..b679c89 100644 (file)
@@ -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
         *
index b58cc7d..781c83c 100644 (file)
@@ -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);
                        }
                }
                
index 326edaa..d8a07a9 100644 (file)
@@ -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
index c4cba56..f5e501b 100644 (file)
@@ -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
index b93963a..4423ac7 100644 (file)
@@ -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);
        }
        
        // --------------------------------------------------------------------
index 54ddd4c..d73c58e 100644 (file)
@@ -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    = '&nbsp;';
        var $last_tag_open              = '&nbsp;';
        var $last_tag_close             = '';
-       var $cur_tag_open               = '&nbsp;<b>';
-       var $cur_tag_close              = '</b>';
+       var $cur_tag_open               = '&nbsp;<strong>';
+       var $cur_tag_close              = '</strong>';
        var $next_tag_open              = '&nbsp;';
        var $next_tag_close             = '&nbsp;';
        var $prev_tag_open              = '&nbsp;';
@@ -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
index 3d379b2..da32437 100644 (file)
@@ -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
index 5e9fa8b..ecd0e70 100644 (file)
@@ -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;
                        }
index 32de58d..50c7dd7 100644 (file)
@@ -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)
index 1191308..5e0ce48 100644 (file)
@@ -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
 
index 93982bf..6c39a5b 100644 (file)
@@ -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;
index 1afc17c..86d5421 100644 (file)
@@ -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
index 844e503..ab8f46a 100644 (file)
@@ -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("<error>0</error>", $this->response))
+               if (stristr($this->response, '<error>0</error>') === 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];
index 0ee6a24..242ca3c 100644 (file)
@@ -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 <p> and <br /> 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, '<!--') !== FALSE)
                {
-                       for ($i = 0; $i < count($matches['0']); $i++)
+                       if (preg_match_all("#(<!\-\-.*?\-\->)#s", $str, $matches))
                        {
-                               $str = str_replace($matches['0'][$i],
-                                                                       str_replace(array("'",'"'), array('{@SQ}', '{@DQ}'), $matches['0'][$i]),
-                                                                       $str);
+                               for ($i = 0, $total = count($matches[0]); $i < $total; $i++)
+                               {
+                                       $html_comments[] = $matches[0][$i];
+                                       $str = str_replace($matches[0][$i], '{@HC'.$i.'}', $str);
+                               }
                        }
                }
+               
+               // match and yank <pre> tags if they exist.  It's cheaper to do this separately since most content will
+               // not contain <pre> tags, and it keeps the PCRE patterns below simpler and faster
+               if (strpos($str, '<pre') !== FALSE)
+               {
+                       $str = preg_replace_callback("#<pre.*?>.*?</pre>#si", array($this, '_protect_characters'), $str);
+               }
+               
+               // Convert quotes within tags to temporary markers.
+               $str = preg_replace_callback("#<.+?>#si", array($this, '_protect_characters'), $str);
 
+               // Do the same with braces if necessary
                if ($this->protect_braced_quotes === TRUE)
                {
-                       if (preg_match_all("#\{.+?}#si", $str, $matches))
-                       {
-                               for ($i = 0; $i < count($matches['0']); $i++)
-                               {
-                                       $str = str_replace($matches['0'][$i],
-                                                                               str_replace(array("'",'"'), array('{@SQ}', '{@DQ}'), $matches['0'][$i]),
-                                                                               $str);
-                               }
-                       }                       
+                       $str = preg_replace_callback("#\{.+?\}#si", array($this, '_protect_characters'), $str);         
                }
-                       
+                               
                // Convert "ignore" tags to temporary marker.  The parser splits out the string at every tag 
                // it encounters.  Certain inline tags, like image tags, links, span tags, etc. will be 
                // adversely affected if they are split out so we'll convert the opening bracket < temporarily to: {@TAG}
@@ -134,61 +138,91 @@ class CI_Typography {
                $str = '';
                $process = TRUE;
                $paragraph = FALSE;
+               $current_chunk = 0;
+               $total_chunks = count($chunks);
+               
                foreach ($chunks as $chunk)
-               {
+               { 
+                       $current_chunk++;
+                       
                        // Are we dealing with a tag? If so, we'll skip the processing for this cycle.
                        // Well also set the "process" flag which allows us to skip <pre> tags and a few other things.
-                       if (preg_match("#<(/*)(".$this->block_elements.").*?\>#", $chunk, $match))
+                       if (preg_match("#<(/*)(".$this->block_elements.").*?>#", $chunk, $match))
                        {
                                if (preg_match("#".$this->skip_elements."#", $match[2]))
                                {
                                        $process =  ($match[1] == '/') ? TRUE : FALSE;
                                }
                                
+                               if ($match[1] == '')
+                               {
+                                       $this->last_block_element = $match[2];
+                               }
+
                                $str .= $chunk;
                                continue;
                        }
-
+                       
                        if ($process == FALSE)
                        {
                                $str .= $chunk;
                                continue;
                        }
                        
+                       //  Force a newline to make sure end tags get processed by _format_newlines()
+                       if ($current_chunk == $total_chunks)
+                       {
+                               $chunk .= "\n";  
+                       }
+                       
                        //  Convert Newlines into <p> and <br /> tags
                        $str .= $this->_format_newlines($chunk);
                }
-
-               // is the whole of the content inside a block level element?
-               if ( ! preg_match("/^<(?:".$this->block_elements.")/i", $str, $match))
+               
+               // No opening block level tag?  Add it if needed.
+               if ( ! preg_match("/^\s*<(?:".$this->block_elements.")/i", $str))
                {
-                       $str = "<p>{$str}</p>";
+                       $str = preg_replace("/^(.*?)<(".$this->block_elements.")/i", '<p>$1</p><$2', $str);
                }
-
-               // Convert quotes, elipsis, and em-dashes
+               
+               // Convert quotes, elipsis, em-dashes, non-breaking spaces, and ampersands
                $str = $this->format_characters($str);
-       
+               
+               // restore HTML comments
+               for ($i = 0, $total = count($html_comments); $i < $total; $i++)
+               {
+                       // remove surrounding paragraph tags, but only if there's an opening paragraph tag
+                       // otherwise HTML comments at the ends of paragraphs will have the closing tag removed
+                       // if '<p>{@HC1}' then replace <p>{@HC1}</p> with the comment, else replace only {@HC1} with the comment
+                       $str = preg_replace('#(?(?=<p>\{@HC'.$i.'\})<p>\{@HC'.$i.'\}(\s*</p>)|\{@HC'.$i.'\})#s', $html_comments[$i], $str);
+               }
+                               
                // Final clean up
                $table = array(
                
                                                // If the user submitted their own paragraph tags within the text
                                                // we will retain them instead of using our tags.
-                                               '/(<p.*?>)<p>/'         => '$1', // <?php BBEdit syntax coloring bug fix
+                                               '/(<p[^>*?]>)<p>/'              => '$1', // <?php BBEdit syntax coloring bug fix
                                                
                                                // Reduce multiple instances of opening/closing paragraph tags to a single one
                                                '#(</p>)+#'                     => '</p>',
-                                               '/(<p><p>)+/'           => '<p>',
+                                               '/(<p>\W*<p>)+/'        => '<p>',
                                                
                                                // Clean up stray paragraph tags that appear before block level elements
                                                '#<p></p><('.$this->block_elements.')#' => '<$1',
-                       
+
+                                               // Clean up stray non-breaking spaces preceeding block elements
+                                               '#(&nbsp;\s*)+<('.$this->block_elements.')#'    => '  <$2',
+
                                                // Replace the temporary markers we added earlier
                                                '/\{@TAG\}/'            => '<',
                                                '/\{@DQ\}/'                     => '"',
-                                               '/\{@SQ\}/'                     => "'"
+                                               '/\{@SQ\}/'                     => "'",
+                                               '/\{@DD\}/'                     => '--',
+                                               '/\{@NBS\}/'            => '  '
 
                                                );
-       
+               
                // Do we need to reduce empty lines?
                if ($reduce_linebreaks === TRUE)
                {
@@ -200,13 +234,13 @@ class CI_Typography {
                        // otherwise most browsers won't treat them as true paragraphs
                        $table['#<p></p>#'] = '<p>&nbsp;</p>';
                }
-       
+               
                return preg_replace(array_keys($table), $table, $str);
 
        }
        
        // --------------------------------------------------------------------
-
+       
        /**
         * Format Characters
         *
@@ -224,26 +258,37 @@ class CI_Typography {
                
                if ( ! isset($table))
                {
-               $table = array(                                 
+                       $table = array(                                 
                                                        // nested smart quotes, opening and closing
                                                        // note that rules for grammar (English) allow only for two levels deep
                                                        // and that single quotes are _supposed_ to always be on the outside
                                                        // but we'll accommodate both
-                                                       '/(^|\W|\s)\'"/'                                => '$1&#8216;&#8220;',
-                                                       '/\'"(\s|\W|$)/'                                => '&#8217;&#8221;$1',
-                                                       '/(^|\W|\s)"\'/'                                => '$1&#8220;&#8216;',
-                                                       '/"\'(\s|\W|$)/'                                => '&#8221;&#8217;$1',
+                                                       // Note that in all cases, whitespace is the primary determining factor
+                                                       // on which direction to curl, with non-word characters like punctuation
+                                                       // being a secondary factor only after whitespace is addressed.
+                                                       '/\'"(\s|$)/'                                   => '&#8217;&#8221;$1',
+                                                       '/(^|\s|<p>)\'"/'                               => '$1&#8216;&#8220;',
+                                                       '/\'"(\W)/'                                             => '&#8217;&#8221;$1',
+                                                       '/(\W)\'"/'                                             => '$1&#8216;&#8220;',
+                                                       '/"\'(\s|$)/'                                   => '&#8221;&#8217;$1',
+                                                       '/(^|\s|<p>)"\'/'                               => '$1&#8220;&#8216;',
+                                                       '/"\'(\W)/'                                             => '&#8221;&#8217;$1',
+                                                       '/(\W)"\'/'                                             => '$1&#8220;&#8216;',
 
                                                        // single quote smart quotes
-                                                       '/\'(\s|\W|$)/'                                 => '&#8217;$1',
-                                                       '/(^|\W|\s)\'/'                                 => '$1&#8216;',
+                                                       '/\'(\s|$)/'                                    => '&#8217;$1',
+                                                       '/(^|\s|<p>)\'/'                                => '$1&#8216;',
+                                                       '/\'(\W)/'                                              => '&#8217;$1',
+                                                       '/(\W)\'/'                                              => '$1&#8216;',
 
                                                        // double quote smart quotes
-                                                       '/"(\s|\W|$)/'                                  => '&#8221;$1',
-                                                       '/(^|\W|\s)"/'                                  => '$1&#8220;',
+                                                       '/"(\s|$)/'                                             => '&#8221;$1',
+                                                       '/(^|\s|<p>)"/'                                 => '$1&#8220;',
+                                                       '/"(\W)/'                                               => '&#8221;$1',
+                                                       '/(\W)"/'                                               => '$1&#8220;',
 
                                                        // apostrophes
-                                                       "/(\w)'(\w)/"                   => '$1&#8217;$2',
+                                                       "/(\w)'(\w)/"                                   => '$1&#8217;$2',
 
                                                        // Em dash and ellipses dots
                                                        '/\s?\-\-\s?/'                                  => '&#8212;',
@@ -254,8 +299,8 @@ class CI_Typography {
 
                                                        // ampersands, if not a character entity
                                                        '/&(?!#?[a-zA-Z0-9]{2,};)/'             => '&amp;'
-                                       );                      
-               }       
+                                               );
+               }
 
                return preg_replace(array_keys($table), $table, $str);
        }
@@ -277,8 +322,8 @@ class CI_Typography {
                {
                        return $str;
                }
-
-               if (strpos($str, "\n") === FALSE)
+               
+               if (strpos($str, "\n") === FALSE  && ! in_array($this->last_block_element, $this->inner_block_required))
                {
                        return $str;
                }
@@ -304,6 +349,25 @@ class CI_Typography {
        
        // ------------------------------------------------------------------------
        
+       /**
+        * Protect Characters
+        *
+        * Protects special characters from being formatted later
+        * We don't want quotes converted within tags so we'll temporarily convert them to {@DQ} and {@SQ}
+        * and we don't want double dashes converted to emdash entities, so they are marked with {@DD}
+        * likewise double spaces are converted to {@NBS} to prevent entity conversion
+        *
+        * @access      public
+        * @param       array
+        * @return      string
+        */
+       function _protect_characters($match)
+       {
+               return str_replace(array("'",'"','--','  '), array('{@SQ}', '{@DQ}', '{@DD}', '{@NBS}'), $match[0]);
+       }
+
+       // --------------------------------------------------------------------
+       
        /**
         * Convert newlines to HTML line breaks except within PRE tags
         *
index 5dd888d..68b6780 100644 (file)
@@ -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,22 +41,22 @@ class CI_URI {
         * normally as other classes are.
         *
         * @access      public
-        */             
+        */
        function CI_URI()
        {
                $this->config =& load_class('Config');
                log_message('debug', "URI Class Initialized");
        }
-       
-       
+
+
        // --------------------------------------------------------------------
-       
+
        /**
         * Get the URI String
         *
         * @access      private
         * @return      string
-        */     
+        */
        function _fetch_uri_string()
        {
                if (strtoupper($this->config->item('uri_protocol')) == 'AUTO')
@@ -70,30 +70,30 @@ class CI_URI {
                                $this->uri_string = key($_GET);
                                return;
                        }
-               
+
                        // Is there a PATH_INFO variable?
-                       // Note: some servers seem to have trouble with getenv() so we'll test it two ways              
-                       $path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');                  
+                       // Note: some servers seem to have trouble with getenv() so we'll test it two ways
+                       $path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
                        if (trim($path, '/') != '' && $path != "/".SELF)
                        {
                                $this->uri_string = $path;
                                return;
                        }
-                                       
+
                        // No PATH_INFO?... What about QUERY_STRING?
-                       $path =  (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');        
+                       $path =  (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
                        if (trim($path, '/') != '')
                        {
                                $this->uri_string = $path;
                                return;
                        }
-                       
+
                        // No QUERY_STRING?... Maybe the ORIG_PATH_INFO variable exists?
-                       $path = (isset($_SERVER['ORIG_PATH_INFO'])) ? $_SERVER['ORIG_PATH_INFO'] : @getenv('ORIG_PATH_INFO');   
+                       $path = str_replace($_SERVER['SCRIPT_NAME'], '', (isset($_SERVER['ORIG_PATH_INFO'])) ? $_SERVER['ORIG_PATH_INFO'] : @getenv('ORIG_PATH_INFO'));
                        if (trim($path, '/') != '' && $path != "/".SELF)
                        {
                                // remove path and script information so we have good URI data
-                               $this->uri_string = str_replace($_SERVER['SCRIPT_NAME'], '', $path);
+                               $this->uri_string = $path;
                                return;
                        }
 
@@ -103,25 +103,25 @@ class CI_URI {
                else
                {
                        $uri = strtoupper($this->config->item('uri_protocol'));
-                       
+
                        if ($uri == 'REQUEST_URI')
                        {
                                $this->uri_string = $this->_parse_request_uri();
                                return;
                        }
-                       
+
                        $this->uri_string = (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri);
                }
-               
+
                // If the URI contains only a slash we'll kill it
                if ($this->uri_string == '/')
                {
                        $this->uri_string = '';
-               }               
+               }
        }
 
        // --------------------------------------------------------------------
-       
+
        /**
         * Parse the REQUEST_URI
         *
@@ -131,29 +131,29 @@ class CI_URI {
         *
         * @access      private
         * @return      string
-        */     
+        */
        function _parse_request_uri()
        {
                if ( ! isset($_SERVER['REQUEST_URI']) OR $_SERVER['REQUEST_URI'] == '')
                {
                        return '';
                }
-               
+
                $request_uri = preg_replace("|/(.*)|", "\\1", str_replace("\\", "/", $_SERVER['REQUEST_URI']));
 
                if ($request_uri == '' OR $request_uri == SELF)
                {
                        return '';
                }
-               
-               $fc_path = FCPATH;              
+
+               $fc_path = FCPATH.SELF;
                if (strpos($request_uri, '?') !== FALSE)
                {
                        $fc_path .= '?';
                }
-               
+
                $parsed_uri = explode("/", $request_uri);
-                               
+
                $i = 0;
                foreach(explode("/", $fc_path) as $segment)
                {
@@ -162,9 +162,9 @@ class CI_URI {
                                $i++;
                        }
                }
-               
+
                $parsed_uri = implode("/", array_slice($parsed_uri, $i));
-               
+
                if ($parsed_uri != '')
                {
                        $parsed_uri = '/'.$parsed_uri;
@@ -174,39 +174,41 @@ class CI_URI {
        }
 
        // --------------------------------------------------------------------
-       
+
        /**
         * Filter segments for malicious characters
         *
         * @access      private
         * @param       string
         * @return      string
-        */     
+        */
        function _filter_uri($str)
        {
                if ($str != '' && $this->config->item('permitted_uri_chars') != '' && $this->config->item('enable_query_strings') == FALSE)
                {
-                       if ( ! preg_match("|^[".preg_quote($this->config->item('permitted_uri_chars'))."]+$|i", $str))
+                       // preg_quote() in PHP 5.3 escapes -, so the str_replace() and addition of - to preg_quote() is to maintain backwards
+                       // compatibility as many are unaware of how characters in the permitted_uri_chars will be parsed as a regex pattern
+                       if ( ! preg_match("|^[".str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-'))."]+$|i", $str))
                        {
-                               exit('The URI you submitted has disallowed characters.');
+                               show_error('The URI you submitted has disallowed characters.', 400);
                        }
-               }       
-               
+               }
+
                // Convert programatic characters to entities
                $bad    = array('$',            '(',            ')',            '%28',          '%29');
                $good   = array('&#36;',        '&#40;',        '&#41;',        '&#40;',        '&#41;');
-               
+
                return str_replace($bad, $good, $str);
        }
 
        // --------------------------------------------------------------------
-       
+
        /**
         * Remove the suffix from the URL if needed
         *
         * @access      private
         * @return      void
-        */     
+        */
        function _remove_url_suffix()
        {
                if  ($this->config->item('url_suffix') != "")
@@ -214,31 +216,31 @@ class CI_URI {
                        $this->uri_string = preg_replace("|".preg_quote($this->config->item('url_suffix'))."$|", "", $this->uri_string);
                }
        }
-       
+
        // --------------------------------------------------------------------
-       
+
        /**
         * Explode the URI Segments. The individual segments will
-        * be stored in the $this->segments array.      
+        * be stored in the $this->segments array.
         *
         * @access      private
         * @return      void
-        */             
+        */
        function _explode_segments()
        {
                foreach(explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val)
                {
                        // Filter segments for security
                        $val = trim($this->_filter_uri($val));
-                       
+
                        if ($val != '')
                        {
                                $this->segments[] = $val;
                        }
                }
        }
-       
-       // -------------------------------------------------------------------- 
+
+       // --------------------------------------------------------------------
        /**
         * Re-index Segments
         *
@@ -249,17 +251,17 @@ class CI_URI {
         *
         * @access      private
         * @return      void
-        */     
+        */
        function _reindex_segments()
        {
                array_unshift($this->segments, NULL);
                array_unshift($this->rsegments, NULL);
                unset($this->segments[0]);
                unset($this->rsegments[0]);
-       }       
-       
+       }
+
        // --------------------------------------------------------------------
-       
+
        /**
         * Fetch a URI Segment
         *
@@ -276,7 +278,7 @@ class CI_URI {
        }
 
        // --------------------------------------------------------------------
-       
+
        /**
         * Fetch a URI "routed" Segment
         *
@@ -295,7 +297,7 @@ class CI_URI {
        }
 
        // --------------------------------------------------------------------
-       
+
        /**
         * Generate a key value pair from the URI string
         *
@@ -331,7 +333,7 @@ class CI_URI {
        }
 
        // --------------------------------------------------------------------
-       
+
        /**
         * Generate a key value pair from the URI string or Re-routed URI string
         *
@@ -353,29 +355,29 @@ class CI_URI {
                        $total_segments = 'total_rsegments';
                        $segment_array = 'rsegment_array';
                }
-               
+
                if ( ! is_numeric($n))
                {
                        return $default;
                }
-       
+
                if (isset($this->keyval[$n]))
                {
                        return $this->keyval[$n];
                }
-       
+
                if ($this->$total_segments() < $n)
                {
                        if (count($default) == 0)
                        {
                                return array();
                        }
-                       
+
                        $retval = array();
                        foreach ($default as $val)
                        {
                                $retval[$val] = FALSE;
-                       }               
+                       }
                        return $retval;
                }
 
@@ -395,7 +397,7 @@ class CI_URI {
                                $retval[$seg] = FALSE;
                                $lastval = $seg;
                        }
-               
+
                        $i++;
                }
 
@@ -424,21 +426,21 @@ class CI_URI {
         * @access      public
         * @param       array   an associative array of key/values
         * @return      array
-        */     
+        */
        function assoc_to_uri($array)
-       {       
+       {
                $temp = array();
                foreach ((array)$array as $key => $val)
                {
                        $temp[] = $key;
                        $temp[] = $val;
                }
-               
+
                return implode('/', $temp);
        }
 
        // --------------------------------------------------------------------
-       
+
        /**
         * Fetch a URI Segment and add a trailing slash
         *
@@ -453,7 +455,7 @@ class CI_URI {
        }
 
        // --------------------------------------------------------------------
-       
+
        /**
         * Fetch a URI Segment and add a trailing slash
         *
@@ -466,9 +468,9 @@ class CI_URI {
        {
                return $this->_slash_segment($n, $where, 'rsegment');
        }
-       
+
        // --------------------------------------------------------------------
-       
+
        /**
         * Fetch a URI Segment and add a trailing slash - helper function
         *
@@ -479,7 +481,7 @@ class CI_URI {
         * @return      string
         */
        function _slash_segment($n, $where = 'trailing', $which = 'segment')
-       {       
+       {
                if ($where == 'trailing')
                {
                        $trailing       = '/';
@@ -497,9 +499,9 @@ class CI_URI {
                }
                return $leading.$this->$which($n).$trailing;
        }
-       
+
        // --------------------------------------------------------------------
-       
+
        /**
         * Segment Array
         *
@@ -512,7 +514,7 @@ class CI_URI {
        }
 
        // --------------------------------------------------------------------
-       
+
        /**
         * Routed Segment Array
         *
@@ -523,9 +525,9 @@ class CI_URI {
        {
                return $this->rsegments;
        }
-       
+
        // --------------------------------------------------------------------
-       
+
        /**
         * Total number of segments
         *
@@ -538,7 +540,7 @@ class CI_URI {
        }
 
        // --------------------------------------------------------------------
-       
+
        /**
         * Total number of routed segments
         *
@@ -549,9 +551,9 @@ class CI_URI {
        {
                return count($this->rsegments);
        }
-       
+
        // --------------------------------------------------------------------
-       
+
        /**
         * Fetch the entire URI string
         *
@@ -563,9 +565,9 @@ class CI_URI {
                return $this->uri_string;
        }
 
-       
+
        // --------------------------------------------------------------------
-       
+
        /**
         * Fetch the entire Re-routed URI string
         *
index a5aa381..d1db629 100644 (file)
@@ -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
index 54124bc..618c49b 100644 (file)
@@ -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
@@ -556,11 +556,22 @@ class CI_Upload {
                        $this->set_error('upload_no_file_types');
                        return FALSE;
                }
-                               
+
+               $image_types = array('gif', 'jpg', 'jpeg', 'png', 'jpe');
+
                foreach ($this->allowed_types as $val)
                {
                        $mime = $this->mimes_types(strtolower($val));
-               
+
+                       // Images get some additional checks
+                       if (in_array($val, $image_types))
+                       {
+                               if (getimagesize($this->file_temp) === FALSE)
+                               {
+                                       return FALSE;
+                               }
+                       }
+
                        if (is_array($mime))
                        {
                                if (in_array($this->file_type, $mime, TRUE))
@@ -900,11 +911,11 @@ class CI_Upload {
                {
                        return $filename;
                }
-               
+
                $parts          = explode('.', $filename);
                $ext            = array_pop($parts);
                $filename       = array_shift($parts);
-                               
+
                foreach ($parts as $part)
                {
                        if ($this->mimes_types(strtolower($part)) === FALSE)
@@ -916,7 +927,14 @@ class CI_Upload {
                                $filename .= '.'.$part;
                        }
                }
-               
+
+               // file name override, since the exact name is provided, no need to
+               // run it through a $this->mimes check.
+               if ($this->file_name != '')
+               {
+                       $filename = $this->file_name;
+               }
+
                $filename .= '.'.$ext;
                
                return $filename;
index 78178d0..180b93d 100644 (file)
@@ -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
index 4baf78b..5e7759f 100644 (file)
@@ -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
index b077d3d..5460842 100644 (file)
@@ -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
@@ -38,7 +38,7 @@ class CI_Xmlrpc {
        var $xmlrpcBoolean      = 'boolean';
        var $xmlrpcDouble       = 'double';     
        var $xmlrpcString       = 'string';
-       var $xmlrpcDateTime     = 'datetime.iso8601';
+       var $xmlrpcDateTime     = 'dateTime.iso8601';
        var $xmlrpcBase64       = 'base64';
        var $xmlrpcArray        = 'array';
        var $xmlrpcStruct       = 'struct';
@@ -133,7 +133,7 @@ class CI_Xmlrpc {
 
        function initialize($config = array())
        {
-               if (sizeof($config) > 0)
+               if (count($config) > 0)
                {
                        foreach ($config as $key => $val)
                        {
@@ -231,7 +231,7 @@ class CI_Xmlrpc {
        {
                if (is_array($value) && isset($value['0']))
                {
-                       if ( ! isset($value['1']) OR ! isset($this->xmlrpcTypes[strtolower($value['1'])]))
+                       if ( ! isset($value['1']) OR (! isset($this->xmlrpcTypes[$value['1']])))
                        {
                                if (is_array($value[0]))
                                {
@@ -554,7 +554,7 @@ class XML_RPC_Response
                {
                        reset($xmlrpc_val->me);
                        list($a,$b) = each($xmlrpc_val->me);
-                       $size = sizeof($b);
+                       $size = count($b);
                        
                        $arr = array();
 
@@ -619,9 +619,9 @@ class XML_RPC_Message extends CI_Xmlrpc
                parent::CI_Xmlrpc();
                
                $this->method_name = $method;
-               if (is_array($pars) && sizeof($pars) > 0)
+               if (is_array($pars) && count($pars) > 0)
                {
-                       for($i=0; $i<sizeof($pars); $i++)
+                       for($i=0; $i<count($pars); $i++)
                        {
                                // $pars[$i] = XML_RPC_Values
                                $this->params[] = $pars[$i];
@@ -639,7 +639,7 @@ class XML_RPC_Message extends CI_Xmlrpc
                $this->payload .= '<methodName>' . $this->method_name . "</methodName>\r\n";
                $this->payload .= "<params>\r\n";
                
-               for($i=0; $i<sizeof($this->params); $i++)
+               for($i=0; $i<count($this->params); $i++)
                {
                        // $p = XML_RPC_Values
                        $p = $this->params[$i];
@@ -737,7 +737,7 @@ class XML_RPC_Message extends CI_Xmlrpc
                //  PARSE XML DATA
                //-------------------------------------         
 
-               if ( ! xml_parse($parser, $data, sizeof($data)))
+               if ( ! xml_parse($parser, $data, count($data)))
                {
                        $errstr = sprintf('XML error: %s at line %d',
                                        xml_error_string(xml_get_error_code($parser)),
@@ -1137,7 +1137,7 @@ class XML_RPC_Message extends CI_Xmlrpc
                {
                        $parameters = array();
                
-                       for ($i = 0; $i < sizeof($this->params); $i++)
+                       for ($i = 0; $i < count($this->params); $i++)
                        {
                                $a_param = $this->decode_message($this->params[$i]);
                                
@@ -1171,7 +1171,7 @@ class XML_RPC_Message extends CI_Xmlrpc
                        
                        $arr = array();
 
-                       for($i = 0; $i < sizeof($b); $i++)
+                       for($i = 0; $i < count($b); $i++)
                        {
                                $arr[] = $this->decode_message($param->me['array'][$i]);
                        }
@@ -1340,7 +1340,7 @@ class XML_RPC_Values extends CI_Xmlrpc
                        case 2:
                                // array
                                $rs .= "<array>\n<data>\n";
-                               for($i=0; $i < sizeof($val); $i++)
+                               for($i=0; $i < count($val); $i++)
                                {
                                        $rs .= $this->serializeval($val[$i]);
                                }
@@ -1351,13 +1351,13 @@ class XML_RPC_Values extends CI_Xmlrpc
                                switch ($typ)
                                {
                                        case $this->xmlrpcBase64:
-                                               $rs .= "<{$typ}>" . base64_encode($val) . "</{$typ}>\n";
+                                               $rs .= "<{$typ}>" . base64_encode((string)$val) . "</{$typ}>\n";
                                        break;
                                        case $this->xmlrpcBoolean:
-                                               $rs .= "<{$typ}>" . ($val ? '1' : '0') . "</{$typ}>\n";
+                                               $rs .= "<{$typ}>" . ((bool)$val ? '1' : '0') . "</{$typ}>\n";
                                        break;
                                        case $this->xmlrpcString:
-                                               $rs .= "<{$typ}>" . htmlspecialchars($val). "</{$typ}>\n";
+                                               $rs .= "<{$typ}>" . htmlspecialchars((string)$val). "</{$typ}>\n";
                                        break;
                                        default:
                                                $rs .= "<{$typ}>{$val}</{$typ}>\n";
index cdbdee9..c7daa60 100644 (file)
@@ -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
@@ -123,7 +123,7 @@ class CI_Xmlrpcs extends CI_Xmlrpc
                
                header("Content-Type: text/xml");
                header("Content-Length: ".strlen($payload));
-               echo $payload;
+               exit($payload);
        }
 
        //-------------------------------------
@@ -204,7 +204,7 @@ class CI_Xmlrpcs extends CI_Xmlrpc
                        $m = new XML_RPC_Message($parser_object->xh[$parser]['method']);
                        $plist='';
                        
-                       for($i=0; $i < sizeof($parser_object->xh[$parser]['params']); $i++)
+                       for($i=0; $i < count($parser_object->xh[$parser]['params']); $i++)
                        {
                                if ($this->debug === TRUE)
                                {
@@ -289,13 +289,13 @@ class CI_Xmlrpcs extends CI_Xmlrpc
                if (isset($this->methods[$methName]['signature']))
                {
                        $sig = $this->methods[$methName]['signature'];
-                       for($i=0; $i<sizeof($sig); $i++)
+                       for($i=0; $i<count($sig); $i++)
                        {
                                $current_sig = $sig[$i];
                
-                               if (sizeof($current_sig) == sizeof($m->params)+1)
+                               if (count($current_sig) == count($m->params)+1)
                                {
-                                       for($n=0; $n < sizeof($m->params); $n++)
+                                       for($n=0; $n < count($m->params); $n++)
                                        {
                                                $p = $m->params[$n];
                                                $pt = ($p->kindOf() == 'scalar') ? $p->scalarval() : $p->kindOf();
@@ -385,11 +385,11 @@ class CI_Xmlrpcs extends CI_Xmlrpc
                                $sigs = array();
                                $signature = $this->methods[$method_name]['signature'];
                                
-                               for($i=0; $i < sizeof($signature); $i++)
+                               for($i=0; $i < count($signature); $i++)
                                {
                                        $cursig = array();
                                        $inSig = $signature[$i];
-                                       for($j=0; $j<sizeof($inSig); $j++)
+                                       for($j=0; $j<count($inSig); $j++)
                                        {
                                                $cursig[]= new XML_RPC_Values($inSig[$j], 'string');
                                        }
@@ -451,7 +451,7 @@ class CI_Xmlrpcs extends CI_Xmlrpc
                        $m = new XML_RPC_Message($value[0]);
                        $plist='';
                        
-                       for($i=0; $i < sizeof($value[1]); $i++)
+                       for($i=0; $i < count($value[1]); $i++)
                        {
                                $m->addParam(new XML_RPC_Values($value[1][$i], 'string'));
                        }
@@ -510,7 +510,7 @@ class CI_Xmlrpcs extends CI_Xmlrpc
                        return $this->multicall_error('notarray');
                        
                list($a,$b)=each($params->me);
-               $numParams = sizeof($b);
+               $numParams = count($b);
 
                $msg = new XML_RPC_Message($scalar_value);
                for ($i = 0; $i < $numParams; $i++)
index 7318815..f81da85 100644 (file)
@@ -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
index 4a09dcb..36a74c4 100644 (file)
@@ -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
index 6dadd4a..19d0568 100644 (file)
@@ -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
index 1d52670..fb2ee5d 100644 (file)
@@ -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