diff options
-rw-r--r-- | application/config/config.php | 2 | ||||
-rw-r--r-- | system/core/Common.php | 16 | ||||
-rw-r--r-- | system/core/Loader.php | 40 | ||||
-rw-r--r-- | system/core/Router.php | 2 | ||||
-rw-r--r-- | system/database/DB_forge.php | 2 | ||||
-rw-r--r-- | system/database/DB_query_builder.php | 17 | ||||
-rw-r--r-- | system/helpers/file_helper.php | 2 | ||||
-rw-r--r-- | system/helpers/path_helper.php | 2 | ||||
-rw-r--r-- | system/helpers/text_helper.php | 2 | ||||
-rw-r--r-- | system/libraries/Encrypt.php | 2 | ||||
-rw-r--r-- | system/libraries/Ftp.php | 2 | ||||
-rw-r--r-- | system/libraries/Javascript/Jquery.php | 2 | ||||
-rw-r--r-- | system/libraries/Session/Session.php | 2 | ||||
-rw-r--r-- | system/libraries/Upload.php | 16 | ||||
-rw-r--r-- | tests/codeigniter/core/Loader_test.php | 4 | ||||
-rw-r--r-- | user_guide_src/source/changelog.rst | 5 | ||||
-rw-r--r-- | user_guide_src/source/database/results.rst | 131 |
17 files changed, 176 insertions, 73 deletions
diff --git a/application/config/config.php b/application/config/config.php index f4ba70a4e..a4d883fab 100644 --- a/application/config/config.php +++ b/application/config/config.php @@ -480,6 +480,8 @@ $config['time_reference'] = 'local'; | can rewrite the tags on-the-fly, enabling you to utilize that syntax | in your view files. Options are TRUE or FALSE (boolean) | +| Note: You need to have eval() enabled for this to work. +| */ $config['rewrite_short_tags'] = FALSE; diff --git a/system/core/Common.php b/system/core/Common.php index b850fd39a..ce324a1cc 100644 --- a/system/core/Common.php +++ b/system/core/Common.php @@ -833,19 +833,9 @@ if ( ! function_exists('function_usable')) { if ( ! isset($_suhosin_func_blacklist)) { - if (extension_loaded('suhosin')) - { - $_suhosin_func_blacklist = explode(',', trim(ini_get('suhosin.executor.func.blacklist'))); - - if ( ! in_array('eval', $_suhosin_func_blacklist, TRUE) && ini_get('suhosin.executor.disable_eval')) - { - $_suhosin_func_blacklist[] = 'eval'; - } - } - else - { - $_suhosin_func_blacklist = array(); - } + $_suhosin_func_blacklist = extension_loaded('suhosin') + ? explode(',', trim(ini_get('suhosin.executor.func.blacklist'))) + : array(); } return ! in_array($function_name, $_suhosin_func_blacklist, TRUE); diff --git a/system/core/Loader.php b/system/core/Loader.php index 9205ad1b6..1f48c0782 100644 --- a/system/core/Loader.php +++ b/system/core/Loader.php @@ -272,7 +272,7 @@ class CI_Loader { $CI =& get_instance(); if (isset($CI->$name)) { - show_error('The model name you are loading is the name of a resource that is already being used: '.$name); + throw new RuntimeException('The model name you are loading is the name of a resource that is already being used: '.$name); } if ($db_conn !== FALSE && ! class_exists('CI_DB', FALSE)) @@ -291,23 +291,37 @@ class CI_Loader { } $model = ucfirst(strtolower($model)); - - foreach ($this->_ci_model_paths as $mod_path) + if ( ! class_exists($model)) { - if ( ! file_exists($mod_path.'models/'.$path.$model.'.php')) + foreach ($this->_ci_model_paths as $mod_path) { - continue; - } + if ( ! file_exists($mod_path.'models/'.$path.$model.'.php')) + { + continue; + } - require_once($mod_path.'models/'.$path.$model.'.php'); + require_once($mod_path.'models/'.$path.$model.'.php'); + if ( ! class_exists($model, FALSE)) + { + throw new RuntimeException($mod_path."models/".$path.$model.".php exists, but doesn't declare class ".$model); + } - $this->_ci_models[] = $name; - $CI->$name = new $model(); - return $this; + break; + } + + if ( ! class_exists($model, FALSE)) + { + throw new RuntimeException('Unable to locate the model you have specified: '.$model); + } + } + elseif ( ! is_subclass_of($model, 'CI_Model')) + { + throw new RuntimeException("Class ".$model." already exists and doesn't extend CI_Model"); } - // couldn't find the model - show_error('Unable to locate the model you have specified: '.$model); + $this->_ci_models[] = $name; + $CI->$name = new $model(); + return $this; } // -------------------------------------------------------------------- @@ -905,7 +919,7 @@ class CI_Loader { // If the PHP installation does not support short tags we'll // do a little string replacement, changing the short tags // to standard PHP echo statements. - if ( ! is_php('5.4') && ! ini_get('short_open_tag') && config_item('rewrite_short_tags') === TRUE && function_usable('eval')) + if ( ! is_php('5.4') && ! ini_get('short_open_tag') && config_item('rewrite_short_tags') === TRUE) { echo eval('?>'.preg_replace('/;*\s*\?>/', '; ?>', str_replace('<?=', '<?php echo ', file_get_contents($_ci_path)))); } diff --git a/system/core/Router.php b/system/core/Router.php index af87a305a..ab5246a1f 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -494,7 +494,7 @@ class CI_Router { * Set directory name * * @param string $dir Directory name - * @param bool $appent Whether we're appending rather than setting the full value + * @param bool $append Whether we're appending rather than setting the full value * @return void */ public function set_directory($dir, $append = FALSE) diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php index 865498fb5..dde285598 100644 --- a/system/database/DB_forge.php +++ b/system/database/DB_forge.php @@ -143,7 +143,7 @@ abstract class CI_DB_forge { protected $_unsigned = TRUE; /** - * NULL value representatin in CREATE/ALTER TABLE statements + * NULL value representation in CREATE/ALTER TABLE statements * * @var string */ diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php index fc2d5901e..0bb91bae9 100644 --- a/system/database/DB_query_builder.php +++ b/system/database/DB_query_builder.php @@ -1276,8 +1276,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { foreach ($key as $k => $v) { - $this->qb_set[$this->protect_identifiers($k, FALSE, $escape)] = ($escape) - ? $this->escape($v) : $v; + $this->qb_set[$this->protect_identifiers($k, FALSE, $escape)] = $this->escape($v); } return $this; @@ -1291,7 +1290,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { * Compiles a SELECT query string and returns the sql. * * @param string the table name to select from (optional) - * @param bool TRUE: resets QB values; FALSE: leave QB vaules alone + * @param bool TRUE: resets QB values; FALSE: leave QB values alone * @return string */ public function get_compiled_select($table = '', $reset = TRUE) @@ -1516,15 +1515,9 @@ abstract class CI_DB_query_builder extends CI_DB_driver { ksort($row); // puts $row in the same order as our keys - if ($escape !== FALSE) + foreach ($row as $k => $v) { - $clean = array(); - foreach ($row as $value) - { - $clean[] = $this->escape($value); - } - - $row = $clean; + $row[$k] = $this->escape($v); } $this->qb_set[] = '('.implode(',', $row).')'; @@ -1945,7 +1938,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { $index_set = TRUE; } - $clean[$this->protect_identifiers($k2, FALSE, $escape)] = ($escape === FALSE) ? $v2 : $this->escape($v2); + $clean[$this->protect_identifiers($k2, FALSE, $escape)] = $this->escape($v2); } if ($index_set === FALSE) diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php index 8b15e60a5..cd1c641ec 100644 --- a/system/helpers/file_helper.php +++ b/system/helpers/file_helper.php @@ -54,7 +54,7 @@ if ( ! function_exists('read_file')) /** * Read File * - * Opens the file specfied in the path and returns it as a string. + * Opens the file specified in the path and returns it as a string. * * @todo Remove in version 3.1+. * @deprecated 3.0.0 It is now just an alias for PHP's native file_get_contents(). diff --git a/system/helpers/path_helper.php b/system/helpers/path_helper.php index c23ec6435..c96d0b8b3 100644 --- a/system/helpers/path_helper.php +++ b/system/helpers/path_helper.php @@ -61,7 +61,7 @@ if ( ! function_exists('set_realpath')) function set_realpath($path, $check_existance = FALSE) { // Security check to make sure the path is NOT a URL. No remote file inclusion! - if (preg_match('#^(http:\/\/|https:\/\/|www\.|ftp|[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})#i', $path)) + if (preg_match('#^(http:\/\/|https:\/\/|www\.|ftp)#i', $path) OR filter_var($path, FILTER_VALIDATE_IP) === $path ) { show_error('The path you submitted must be a local server path, not a URL'); } diff --git a/system/helpers/text_helper.php b/system/helpers/text_helper.php index f2290c895..fb47036f2 100644 --- a/system/helpers/text_helper.php +++ b/system/helpers/text_helper.php @@ -254,7 +254,7 @@ if ( ! function_exists('word_censor')) * word you've submitted. * * @param string the text string - * @param string the array of censoered words + * @param string the array of censored words * @param string the optional replacement value * @return string */ diff --git a/system/libraries/Encrypt.php b/system/libraries/Encrypt.php index 5faf1f206..a46d4f462 100644 --- a/system/libraries/Encrypt.php +++ b/system/libraries/Encrypt.php @@ -65,7 +65,7 @@ class CI_Encrypt { protected $_hash_type = 'sha1'; /** - * Flag for the existance of mcrypt + * Flag for the existence of mcrypt * * @var bool */ diff --git a/system/libraries/Ftp.php b/system/libraries/Ftp.php index b53207577..2d345c294 100644 --- a/system/libraries/Ftp.php +++ b/system/libraries/Ftp.php @@ -466,7 +466,7 @@ class CI_FTP { /** * Delete a folder and recursively delete everything (including sub-folders) - * containted within it. + * contained within it. * * @param string $filepath * @return bool diff --git a/system/libraries/Javascript/Jquery.php b/system/libraries/Javascript/Jquery.php index 25acceef7..11f2d2361 100644 --- a/system/libraries/Javascript/Jquery.php +++ b/system/libraries/Javascript/Jquery.php @@ -84,7 +84,7 @@ class CI_Jquery extends CI_Javascript { public $jquery_table_sorter_active = FALSE; /** - * JQuery table sorder pager active + * JQuery table sorter pager active * * @var bool */ diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 0549fef66..05a470d86 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -795,7 +795,7 @@ class CI_Session { /** * Set flashdata * - * Legacy CI_Session compatibiliy method + * Legacy CI_Session compatibility method * * @param mixed $data Session data key or an associative array * @param mixed $value Value to store diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php index 51232f8a7..20ddfc145 100644 --- a/system/libraries/Upload.php +++ b/system/libraries/Upload.php @@ -695,6 +695,22 @@ class CI_Upload { // -------------------------------------------------------------------- /** + * Set Maximum File Size + * + * An internal alias to set_max_filesize() to help with configuration + * as initialize() will look for a set_<property_name>() method ... + * + * @param int $n + * @return CI_Upload + */ + protected function set_max_size($n) + { + return $this->set_max_filesize($n); + } + + // -------------------------------------------------------------------- + + /** * Set Maximum File Name Length * * @param int $n diff --git a/tests/codeigniter/core/Loader_test.php b/tests/codeigniter/core/Loader_test.php index cfaf6c74b..889ab92e4 100644 --- a/tests/codeigniter/core/Loader_test.php +++ b/tests/codeigniter/core/Loader_test.php @@ -229,7 +229,7 @@ class Loader_test extends CI_TestCase { $this->ci_obj->$obj = new stdClass(); $this->setExpectedException( 'RuntimeException', - 'CI Error: The model name you are loading is the name of a resource that is already being used: '.$obj + 'The model name you are loading is the name of a resource that is already being used: '.$obj ); $this->load->model('not_real', $obj); } @@ -240,7 +240,7 @@ class Loader_test extends CI_TestCase { { $this->setExpectedException( 'RuntimeException', - 'CI Error: Unable to locate the model you have specified: Ci_test_nonexistent_model.php' + 'Unable to locate the model you have specified: Ci_test_nonexistent_model.php' ); $this->load->model('ci_test_nonexistent_model.php'); diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst index 22243cf04..ee52d2e49 100644 --- a/user_guide_src/source/changelog.rst +++ b/user_guide_src/source/changelog.rst @@ -34,6 +34,7 @@ Release Date: Not Released - Core - Added support for defining a list of specific query parameters in ``$config['cache_query_string']`` for the :doc:`Output Library <libraries/output>`. + - Added class existence and inheritance checks to ``CI_Loader::model()`` in order to ease debugging in case of name collisions. Bug fixes for 3.0.1 ------------------- @@ -67,8 +68,10 @@ Bug fixes for 3.0.1 - Fixed a bug (#3704) - :doc:`Database <database/index>` method ``stored_procedure()`` in the 'oci8' driver didn't properly bind parameters. - Fixed a bug (#3778) - :doc:`Download Helper <helpers/download_helper>` function :php:func:`force_download()` incorrectly sent a *Pragma* response header. - Fixed a bug (#3752) - ``$routing['directory']`` overrides were not properly handled and always resulted in a 404 "Not Found" error. -- Fixed an internal bug in :doc:`Query Builder <database/query_builder>` escaping logic where if field name escaping is force-disabled, methods ``where()`` and ``having()`` will also treat values as fields. +- Fixed an internal bug (#3989) - :doc:`Query Builder <database/query_builder>` escaping logic where if field name escaping is force-disabled, would also treat values as fields in methods ``where()``, ``having()``, ``set()``, ``set_insert_batch()``, ``set_update_batch()``. - Fixed a bug (#3279) - :doc:`Query Builder <database/query_builder>` methods ``update()`` and ``get_compiled_update()`` did double escaping on the table name if it was provided via ``from()``. +- Fixed a bug (#3991) - ``$config['rewrite_short_tags']`` never worked due to ``function_exists('eval')`` always returning FALSE. +- Fixed a bug where the :doc:`File Uploadin Library <libraries/file_uploading>` library will not properly configure its maximum file size unless the input value is of type integer. Version 3.0.0 ============= diff --git a/user_guide_src/source/database/results.rst b/user_guide_src/source/database/results.rst index ac44566d3..e72d9fa77 100644 --- a/user_guide_src/source/database/results.rst +++ b/user_guide_src/source/database/results.rst @@ -19,7 +19,7 @@ This method returns the query result as an array of **objects**, or loop, like this:: $query = $this->db->query("YOUR QUERY"); - + foreach ($query->result() as $row) { echo $row->title; @@ -33,18 +33,15 @@ If you run queries that might **not** produce a result, you are encouraged to test the result first:: $query = $this->db->query("YOUR QUERY"); - - if ($query->num_rows() > 0) + + foreach ($query->result() as $row) { - foreach ($query->result() as $row) - { - echo $row->title; - echo $row->name; - echo $row->body; - } + echo $row->title; + echo $row->name; + echo $row->body; } -You can also pass a string to result() which represents a class to +You can also pass a string to ``result()`` which represents a class to instantiate for each result object (note: this class must be loaded) :: @@ -64,7 +61,7 @@ array when no result is produced. Typically you'll use this in a foreach loop, like this:: $query = $this->db->query("YOUR QUERY"); - + foreach ($query->result_array() as $row) { echo $row['title']; @@ -83,11 +80,11 @@ one row, it returns only the first row. The result is returned as an **object**. Here's a usage example:: $query = $this->db->query("YOUR QUERY"); - - if ($query->num_rows() > 0) + + $row = $query->row(); + + if (isset($row)) { - $row = $query->row(); - echo $row->title; echo $row->name; echo $row->body; @@ -113,11 +110,11 @@ Identical to the above ``row()`` method, except it returns an array. Example:: $query = $this->db->query("YOUR QUERY"); - - if ($query->num_rows() > 0) + + $row = $query->row_array(); + + if (isset($row)) { - $row = $query->row_array(); - echo $row['title']; echo $row['name']; echo $row['body']; @@ -157,7 +154,7 @@ it returns the current row and moves the internal data pointer ahead. :: $query = $this->db->query("YOUR QUERY"); - + while ($row = $query->unbuffered_row()) { echo $row->title; @@ -173,6 +170,94 @@ the returned value's type:: $query->unbuffered_row('array'); // associative array ********************* +Custom Result Objects +********************* + +You can have the results returned as an instance of a custom class instead +of a ``stdClass`` or array, as the ``result()`` and ``result_array()`` +methods allow. This requires that the class is already loaded into memory. +The object will have all values returned from the database set as properties. +If these have been declared and are non-public then you should provide a +``__set()`` method to allow them to be set. + +Example:: + + class User { + + public $id; + public $email; + public $username; + + protected $last_login; + + public function last_login($format) + { + return $this->last_login->format($format); + } + + public function __set($name, $value) + { + if ($name === 'last_login') + { + $this->last_login = DateTime::createFromFormat('U', $value); + } + } + + public function __get($name) + { + if (isset($this->$name)) + { + return $this->$name; + } + } + } + +In addition to the two methods listed below, the following methods also can +take a class name to return the results as: ``first_row()``, ``last_row()``, +``next_row()``, and ``previous_row()``. + +**custom_result_object()** + +Returns the entire result set as an array of instances of the class requested. +The only parameter is the name of the class to instantiate. + +Example:: + + $query = $this->db->query("YOUR QUERY"); + + $rows = $query->custom_result_object('User'); + + foreach ($rows as $row) + { + echo $row->id; + echo $row->email; + echo $row->last_login('Y-m-d'); + } + +**custom_row_object()** + +Returns a single row from your query results. The first parameter is the row +number of the results. The second parameter is the class name to instantiate. + +Example:: + + $query = $this->db->query("YOUR QUERY"); + + $row = $query->custom_row_object(0, 'User'); + + if (isset($row)) + { + echo $row->email; // access attributes + echo $row->last_login('Y-m-d'); // access class methods + } + +You can also use the ``row()`` method in exactly the same way. + +Example:: + + $row = $query->custom_row_object(0, 'User'); + +********************* Result Helper Methods ********************* @@ -182,7 +267,7 @@ The number of rows returned by the query. Note: In this example, $query is the variable that the query result object is assigned to:: $query = $this->db->query('SELECT * FROM my_table'); - + echo $query->num_rows(); .. note:: Not all database drivers have a native way of getting the total @@ -196,7 +281,7 @@ The number of FIELDS (columns) returned by the query. Make sure to call the method using your query result object:: $query = $this->db->query('SELECT * FROM my_table'); - + echo $query->num_fields(); **free_result()** @@ -210,7 +295,7 @@ result has been generated in order to cut down on memory consumption. Example:: $query = $this->db->query('SELECT title FROM my_table'); - + foreach ($query->result() as $row) { echo $row->title; |