summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--application/config/config.php2
-rw-r--r--application/config/constants.php5
-rw-r--r--application/config/doctypes.php12
-rw-r--r--application/config/foreign_chars.php56
-rw-r--r--application/config/mimes.php3
-rw-r--r--application/config/routes.php14
-rw-r--r--application/config/smileys.php4
-rw-r--r--application/config/user_agents.php5
-rw-r--r--application/controllers/Welcome.php (renamed from application/controllers/welcome.php)2
-rw-r--r--application/views/welcome_message.php2
-rw-r--r--composer.json2
-rwxr-xr-xindex.php20
-rw-r--r--readme.rst2
-rw-r--r--system/core/CodeIgniter.php22
-rw-r--r--system/core/Common.php152
-rw-r--r--system/core/Config.php10
-rw-r--r--system/core/Exceptions.php2
-rw-r--r--system/core/Input.php53
-rw-r--r--system/core/Loader.php130
-rw-r--r--system/core/Log.php3
-rw-r--r--system/core/Output.php39
-rw-r--r--system/core/Router.php60
-rw-r--r--system/core/Security.php53
-rw-r--r--system/database/DB.php8
-rw-r--r--system/database/DB_driver.php16
-rw-r--r--system/database/DB_query_builder.php7
-rw-r--r--system/database/drivers/mysqli/mysqli_driver.php27
-rw-r--r--system/database/drivers/oci8/oci8_driver.php10
-rw-r--r--system/database/drivers/oci8/oci8_result.php2
-rw-r--r--system/database/drivers/pdo/pdo_driver.php4
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_4d_forge.php2
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php15
-rw-r--r--system/database/drivers/postgre/postgre_driver.php23
-rw-r--r--system/helpers/captcha_helper.php68
-rw-r--r--system/helpers/date_helper.php4
-rw-r--r--system/helpers/file_helper.php2
-rw-r--r--system/helpers/form_helper.php192
-rw-r--r--system/helpers/html_helper.php2
-rw-r--r--system/helpers/url_helper.php30
-rw-r--r--system/libraries/Cache/Cache.php3
-rw-r--r--system/libraries/Cache/drivers/Cache_apc.php2
-rw-r--r--system/libraries/Cache/drivers/Cache_memcached.php30
-rw-r--r--system/libraries/Cache/drivers/Cache_redis.php2
-rw-r--r--system/libraries/Cache/drivers/Cache_wincache.php2
-rw-r--r--system/libraries/Email.php29
-rw-r--r--system/libraries/Form_validation.php4
-rw-r--r--system/libraries/Javascript.php6
-rw-r--r--system/libraries/Javascript/Jquery.php7
-rw-r--r--system/libraries/Pagination.php3
-rw-r--r--system/libraries/Parser.php4
-rw-r--r--system/libraries/Profiler.php31
-rw-r--r--system/libraries/Session/Session.php39
-rw-r--r--system/libraries/Session/drivers/Session_cookie.php9
-rw-r--r--system/libraries/Session/drivers/Session_native.php6
-rw-r--r--system/libraries/Upload.php18
-rw-r--r--system/libraries/User_agent.php19
-rw-r--r--system/libraries/Xmlrpc.php2
-rw-r--r--system/libraries/Zip.php38
-rw-r--r--tests/codeigniter/core/Benchmark_test.php2
-rw-r--r--tests/codeigniter/core/Config_test.php10
-rw-r--r--tests/codeigniter/core/Input_test.php12
-rw-r--r--tests/codeigniter/core/Loader_test.php32
-rw-r--r--tests/codeigniter/core/Security_test.php2
-rw-r--r--tests/codeigniter/helpers/directory_helper_test.php19
-rw-r--r--tests/mocks/core/common.php2
-rw-r--r--tests/mocks/database/db.php2
-rw-r--r--user_guide_src/source/changelog.rst575
-rw-r--r--user_guide_src/source/general/cli.rst2
-rw-r--r--user_guide_src/source/general/common_functions.rst7
-rw-r--r--user_guide_src/source/general/controllers.rst10
-rw-r--r--user_guide_src/source/general/creating_libraries.rst7
-rw-r--r--user_guide_src/source/general/libraries.rst2
-rw-r--r--user_guide_src/source/general/models.rst9
-rw-r--r--user_guide_src/source/general/routing.rst14
-rw-r--r--user_guide_src/source/general/styleguide.rst31
-rw-r--r--user_guide_src/source/general/urls.rst18
-rw-r--r--user_guide_src/source/general/views.rst2
-rw-r--r--user_guide_src/source/helpers/captcha_helper.rst11
-rw-r--r--user_guide_src/source/helpers/date_helper.rst10
-rw-r--r--user_guide_src/source/helpers/form_helper.rst48
-rw-r--r--user_guide_src/source/helpers/smiley_helper.rst10
-rw-r--r--user_guide_src/source/helpers/url_helper.rst6
-rw-r--r--user_guide_src/source/installation/downloads.rst91
-rw-r--r--user_guide_src/source/installation/upgrade_214.rst14
-rw-r--r--user_guide_src/source/installation/upgrade_300.rst132
-rw-r--r--user_guide_src/source/installation/upgrading.rst3
-rw-r--r--user_guide_src/source/libraries/config.rst2
-rw-r--r--user_guide_src/source/libraries/file_uploading.rst2
-rw-r--r--user_guide_src/source/libraries/form_validation.rst3
-rw-r--r--user_guide_src/source/libraries/input.rst16
-rw-r--r--user_guide_src/source/libraries/loader.rst33
-rw-r--r--user_guide_src/source/libraries/migration.rst2
-rw-r--r--user_guide_src/source/libraries/xmlrpc.rst4
-rw-r--r--user_guide_src/source/tutorial/news_section.rst6
-rw-r--r--user_guide_src/source/tutorial/static_pages.rst2
95 files changed, 1458 insertions, 1014 deletions
diff --git a/application/config/config.php b/application/config/config.php
index 0608348c6..8d08a7401 100644
--- a/application/config/config.php
+++ b/application/config/config.php
@@ -282,7 +282,7 @@ $config['encryption_key'] = '';
| 'sess_driver' = the driver to load: cookie (Classic), native (PHP sessions),
| or your custom driver name
| 'sess_valid_drivers' = additional valid drivers which may be loaded
-| 'sess_cookie_name' = the name you want for the cookie
+| 'sess_cookie_name' = the name you want for the cookie, must contain only [0-9a-z_-] characters
| 'sess_expiration' = the number of SECONDS you want the session to last.
| by default sessions last 7200 seconds (two hours). Set to zero for no expiration.
| 'sess_expire_on_close' = Whether to cause the session to expire automatically
diff --git a/application/config/constants.php b/application/config/constants.php
index dc84712cd..e71097b6c 100644
--- a/application/config/constants.php
+++ b/application/config/constants.php
@@ -81,11 +81,11 @@ define('SHOW_DEBUG_BACKTRACE', TRUE);
| Used to indicate the conditions under which the script is exit()ing.
| While there is no universal standard for error codes, there are some
| broad conventions. Three such conventions are mentioned below, for
-| those who wish to make use of them. The CodeIgniter defaults were
+| those who wish to make use of them. The CodeIgniter defaults were
| chosen for the least overlap with these conventions, while still
| leaving room for others to be defined in future versions and user
| applications.
-|
+|
| The three main conventions used for determining exit status codes
| are as follows:
|
@@ -108,7 +108,6 @@ define('EXIT_USER_INPUT', 7); // invalid user input
define('EXIT_DATABASE', 8); // database error
define('EXIT__AUTO_MIN', 9); // lowest automatically-assigned error code
define('EXIT__AUTO_MAX', 125); // highest automatically-assigned error code
-
/* End of file constants.php */
/* Location: ./application/config/constants.php */ \ No newline at end of file
diff --git a/application/config/doctypes.php b/application/config/doctypes.php
index fe5420263..b1a8959c2 100644
--- a/application/config/doctypes.php
+++ b/application/config/doctypes.php
@@ -26,19 +26,19 @@
*/
$_doctypes = array(
- 'xhtml11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
+ '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">',
'xhtml-basic11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">',
- 'html5' => '<!DOCTYPE html>',
+ '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">',
- 'mathml1' => '<!DOCTYPE math SYSTEM "http://www.w3.org/Math/DTD/mathml1/mathml.dtd">',
- 'mathml2' => '<!DOCTYPE math PUBLIC "-//W3C//DTD MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/mathml2.dtd">',
- 'svg10' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">',
- 'svg11' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">',
+ 'mathml1' => '<!DOCTYPE math SYSTEM "http://www.w3.org/Math/DTD/mathml1/mathml.dtd">',
+ 'mathml2' => '<!DOCTYPE math PUBLIC "-//W3C//DTD MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/mathml2.dtd">',
+ 'svg10' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">',
+ 'svg11' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">',
'svg11-basic' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">',
'svg11-tiny' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">',
'xhtml-math-svg-xh' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">',
diff --git a/application/config/foreign_chars.php b/application/config/foreign_chars.php
index b2374ae1a..ab98224f7 100644
--- a/application/config/foreign_chars.php
+++ b/application/config/foreign_chars.php
@@ -50,16 +50,16 @@ $foreign_characters = array(
'/д/' => 'd',
'/Ð|Ď|Đ|Δ/' => 'Dj',
'/ð|ď|đ|δ/' => 'dj',
- '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Ε|Έ|Ẽ|Ẻ|Ẹ|Ề|Ế|Ễ|Ể|Ệ|Е|Ё|Э/' => 'E',
- '/è|é|ê|ë|ē|ĕ|ė|ę|ě|έ|ε|ẽ|ẻ|ẹ|ề|ế|ễ|ể|ệ|е|ё|э/' => 'e',
+ '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Ε|Έ|Ẽ|Ẻ|Ẹ|Ề|Ế|Ễ|Ể|Ệ|Е|Э/' => 'E',
+ '/è|é|ê|ë|ē|ĕ|ė|ę|ě|έ|ε|ẽ|ẻ|ẹ|ề|ế|ễ|ể|ệ|е|э/' => 'e',
'/Ф/' => 'F',
'/ф/' => 'f',
- '/Ĝ|Ğ|Ġ|Ģ|Γ|Г/' => 'G',
- '/ĝ|ğ|ġ|ģ|γ|г/' => 'g',
+ '/Ĝ|Ğ|Ġ|Ģ|Γ|Г|Ґ/' => 'G',
+ '/ĝ|ğ|ġ|ģ|γ|г|ґ/' => 'g',
'/Ĥ|Ħ/' => 'H',
'/ĥ|ħ/' => 'h',
- '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|Η|Ή|Ί|Ι|Ϊ|Ỉ|Ị|И|Й/' => 'I',
- '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|η|ή|ί|ι|ϊ|ỉ|ị|и|й/' => 'i',
+ '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|Η|Ή|Ί|Ι|Ϊ|Ỉ|Ị|И|Ы/' => 'I',
+ '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|η|ή|ί|ι|ϊ|ỉ|ị|и|ы|ї/' => 'i',
'/Ĵ/' => 'J',
'/ĵ/' => 'j',
'/Ķ|Κ|К/' => 'K',
@@ -82,8 +82,8 @@ $foreign_characters = array(
'/ț|ţ|ť|ŧ|т/' => 't',
'/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|Ũ|Ủ|Ụ|Ừ|Ứ|Ữ|Ử|Ự|У/' => 'U',
'/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|υ|ύ|ϋ|ủ|ụ|ừ|ứ|ữ|ử|ự|у/' => 'u',
- '/Ý|Ÿ|Ŷ|Υ|Ύ|Ϋ|Ỳ|Ỹ|Ỷ|Ỵ/' => 'Y',
- '/ý|ÿ|ŷ|ỳ|ỹ|ỷ|ỵ/' => 'y',
+ '/Ý|Ÿ|Ŷ|Υ|Ύ|Ϋ|Ỳ|Ỹ|Ỷ|Ỵ|Й/' => 'Y',
+ '/ý|ÿ|ŷ|ỳ|ỹ|ỷ|ỵ|й/' => 'y',
'/В/' => 'V',
'/в/' => 'v',
'/Ŵ/' => 'W',
@@ -91,7 +91,7 @@ $foreign_characters = array(
'/Ź|Ż|Ž|Ζ|З/' => 'Z',
'/ź|ż|ž|ζ|з/' => 'z',
'/Æ|Ǽ/' => 'AE',
- '/ß/'=> 'ss',
+ '/ß/' => 'ss',
'/IJ/' => 'IJ',
'/ij/' => 'ij',
'/Œ/' => 'OE',
@@ -101,22 +101,28 @@ $foreign_characters = array(
'/β/' => 'v',
'/μ/' => 'm',
'/ψ/' => 'ps',
- '/Ж/'=>'Zh',
- '/ж/'=>'zh',
- '/Х/'=>'Kh',
- '/х/'=>'kh',
- '/Ц/'=>'Tc',
- '/ц/'=>'tc',
- '/Ч/'=>'Ch',
- '/ч/'=>'ch',
- '/Ш/'=>'Sh',
- '/ш/'=>'sh',
- '/Щ/'=>'Shch',
- '/щ/'=>'shch',
- '/Ю/'=>'Iu',
- '/ю/'=>'iu',
- '/Я/'=>'Ia',
- '/я/'=>'ia'
+ '/Ё/' => 'Yo',
+ '/ё/' => 'yo',
+ '/Є/' => 'Ye',
+ '/є/' => 'ye',
+ '/Ї/' => 'Yi',
+ '/Ж/' => 'Zh',
+ '/ж/' => 'zh',
+ '/Х/' => 'Kh',
+ '/х/' => 'kh',
+ '/Ц/' => 'Ts',
+ '/ц/' => 'ts',
+ '/Ч/' => 'Ch',
+ '/ч/' => 'ch',
+ '/Ш/' => 'Sh',
+ '/ш/' => 'sh',
+ '/Щ/' => 'Shch',
+ '/щ/' => 'shch',
+ '/Ъ|ъ|Ь|ь/' => '',
+ '/Ю/' => 'Yu',
+ '/ю/' => 'yu',
+ '/Я/' => 'Ya',
+ '/я/' => 'ya'
);
/* End of file foreign_chars.php */
diff --git a/application/config/mimes.php b/application/config/mimes.php
index 32d10f6c1..27d4b2514 100644
--- a/application/config/mimes.php
+++ b/application/config/mimes.php
@@ -78,6 +78,7 @@ return array(
'sit' => 'application/x-stuffit',
'tar' => 'application/x-tar',
'tgz' => array('application/x-tar', 'application/x-gzip-compressed'),
+ 'z' => 'application/x-compress',
'xhtml' => 'application/xhtml+xml',
'xht' => 'application/xhtml+xml',
'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed', 'application/s-compressed', 'multipart/x-zip'),
@@ -96,7 +97,7 @@ return array(
'ra' => 'audio/x-realaudio',
'rv' => 'video/vnd.rn-realvideo',
'wav' => array('audio/x-wav', 'audio/wave', 'audio/wav'),
- 'bmp' => array('image/bmp', 'image/x-windows-bmp'),
+ 'bmp' => array('image/bmp', 'image/x-bmp', 'image/x-bitmap', 'image/x-xbitmap', 'image/x-win-bitmap', 'image/x-windows-bmp', 'image/ms-bmp', 'image/x-ms-bmp', 'application/bmp', 'application/x-bmp', 'application/x-win-bitmap'),
'gif' => 'image/gif',
'jpeg' => array('image/jpeg', 'image/pjpeg'),
'jpg' => array('image/jpeg', 'image/pjpeg'),
diff --git a/application/config/routes.php b/application/config/routes.php
index a5047a14e..3078c3c76 100644
--- a/application/config/routes.php
+++ b/application/config/routes.php
@@ -49,7 +49,7 @@
| RESERVED ROUTES
| -------------------------------------------------------------------------
|
-| There are two reserved routes:
+| There are three reserved routes:
|
| $route['default_controller'] = 'welcome';
|
@@ -62,10 +62,20 @@
| This route will tell the Router which controller/method to use if those
| provided in the URL cannot be matched to a valid route.
|
+| $route['translate_uri_dashes'] = FALSE;
+|
+| This is not exactly a route, but allows you to automatically route
+| controller and method names that contain dashes. '-' isn't a valid
+| class or method name character, so it requires translation.
+| When you set this option to TRUE, it will replace ALL dashes in the
+| controller and method URI segments.
+|
+| Examples: my-controller/index -> my_controller/index
+| my-controller/my-method -> my_controller/my_method
*/
-
$route['default_controller'] = 'welcome';
$route['404_override'] = '';
+$route['translate_uri_dashes'] = FALSE;
/* End of file routes.php */
/* Location: ./application/config/routes.php */ \ No newline at end of file
diff --git a/application/config/smileys.php b/application/config/smileys.php
index 4b253098b..3c49c469e 100644
--- a/application/config/smileys.php
+++ b/application/config/smileys.php
@@ -30,7 +30,7 @@
| SMILEYS
| -------------------------------------------------------------------
| This file contains an array of smileys for use with the emoticon helper.
-| Individual images can be used to replace multiple simileys. For example:
+| Individual images can be used to replace multiple smileys. For example:
| :-) and :) use the same image replacement.
|
| Please see user guide for more info:
@@ -84,7 +84,7 @@ $smileys = array(
':vampire:' => array('vampire.gif', '19', '19', 'vampire'),
':snake:' => array('snake.gif', '19', '19', 'snake'),
':exclaim:' => array('exclaim.gif', '19', '19', 'excaim'),
- ':question:' => array('question.gif', '19', '19', 'question') // no comma after last item
+ ':question:' => array('question.gif', '19', '19', 'question')
);
diff --git a/application/config/user_agents.php b/application/config/user_agents.php
index 0aae987a2..899e96a94 100644
--- a/application/config/user_agents.php
+++ b/application/config/user_agents.php
@@ -50,6 +50,7 @@ $platforms = array(
'win98' => 'Windows 98',
'windows 95' => 'Windows 95',
'win95' => 'Windows 95',
+ 'windows phone' => 'Windows Phone',
'windows' => 'Unknown Windows OS',
'android' => 'Android',
'blackberry' => 'BlackBerry',
@@ -80,6 +81,7 @@ $platforms = array(
// The order of this array should NOT be changed. Many browsers return
// multiple browser types so we want to identify the sub-type first.
$browsers = array(
+ 'OPR' => 'Opera',
'Flock' => 'Flock',
'Chrome' => 'Chrome',
'Opera' => 'Opera',
@@ -149,6 +151,7 @@ $mobiles = array(
'mot-' => 'Motorola',
'playstation portable' => 'PlayStation Portable',
'playstation 3' => 'PlayStation 3',
+ 'playstation vita' => 'PlayStation Vita',
'hiptop' => 'Danger Hiptop',
'nec-' => 'NEC',
'panasonic' => 'Panasonic',
@@ -181,7 +184,7 @@ $mobiles = array(
'operamini' => 'Opera Mini',
'opera mini' => 'Opera Mini',
'opera mobi' => 'Opera Mobile',
- 'fennec' => 'Firefox Mobile',
+ 'fennec' => 'Firefox Mobile',
// Other
'digital paths' => 'Digital Paths',
diff --git a/application/controllers/welcome.php b/application/controllers/Welcome.php
index 2f0e358bc..31ceea948 100644
--- a/application/controllers/welcome.php
+++ b/application/controllers/Welcome.php
@@ -50,4 +50,4 @@ class Welcome extends CI_Controller {
}
/* End of file welcome.php */
-/* Location: ./application/controllers/welcome.php */ \ No newline at end of file
+/* Location: ./application/controllers/Welcome.php */ \ No newline at end of file
diff --git a/application/views/welcome_message.php b/application/views/welcome_message.php
index 3cc8b80aa..2466a83fc 100644
--- a/application/views/welcome_message.php
+++ b/application/views/welcome_message.php
@@ -104,7 +104,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
<code>application/views/welcome_message.php</code>
<p>The corresponding controller for this page is found at:</p>
- <code>application/controllers/welcome.php</code>
+ <code>application/controllers/Welcome.php</code>
<p>If you are exploring CodeIgniter for the very first time, you should start by reading the <a href="user_guide/">User Guide</a>.</p>
</div>
diff --git a/composer.json b/composer.json
index 29715763f..0f98fe7a0 100644
--- a/composer.json
+++ b/composer.json
@@ -5,6 +5,6 @@
"php": ">=5.2.4"
},
"require-dev": {
- "mikey179/vfsStream": "*"
+ "mikey179/vfsStream": "1.1.*"
}
} \ No newline at end of file
diff --git a/index.php b/index.php
index cfb003eb8..72c97c410 100755
--- a/index.php
+++ b/index.php
@@ -61,7 +61,7 @@ switch (ENVIRONMENT)
case 'testing':
case 'production':
- error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED ^ E_STRICT);
+ error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT);
ini_set('display_errors', 0);
break;
@@ -77,7 +77,7 @@ switch (ENVIRONMENT)
*---------------------------------------------------------------
*
* This variable must contain the name of your "system" folder.
- * Include the path if the folder is not in the same directory
+ * Include the path if the folder is not in the same directory
* as this file.
*/
$system_path = 'system';
@@ -220,28 +220,28 @@ switch (ENVIRONMENT)
$application_folder = $_temp;
}
- define('APPPATH', $application_folder.'/');
+ define('APPPATH', $application_folder.DIRECTORY_SEPARATOR);
}
else
{
- if ( ! is_dir(BASEPATH.$application_folder.'/'))
+ if ( ! is_dir(BASEPATH.$application_folder.DIRECTORY_SEPARATOR))
{
header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);
echo 'Your application folder path does not appear to be set correctly. Please open the following file and correct this: '.SELF;
exit(3); // EXIT_* constants not yet defined; 3 is EXIT_CONFIG.
}
- define('APPPATH', BASEPATH.$application_folder.'/');
+ define('APPPATH', BASEPATH.$application_folder.DIRECTORY_SEPARATOR);
}
// The path to the "views" folder
if ( ! is_dir($view_folder))
{
- if ( ! empty($view_folder) && is_dir(APPPATH.$view_folder.'/'))
+ if ( ! empty($view_folder) && is_dir(APPPATH.$view_folder.DIRECTORY_SEPARATOR))
{
$view_folder = APPPATH.$view_folder;
}
- elseif ( ! is_dir(APPPATH.'views/'))
+ elseif ( ! is_dir(APPPATH.'views'.DIRECTORY_SEPARATOR))
{
header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);
echo 'Your view folder path does not appear to be set correctly. Please open the following file and correct this: '.SELF;
@@ -255,11 +255,11 @@ switch (ENVIRONMENT)
if (($_temp = realpath($view_folder)) !== FALSE)
{
- $view_folder = $_temp.'/';
+ $view_folder = $_temp.DIRECTORY_SEPARATOR;
}
else
{
- $view_folder = rtrim($view_folder, '/').'/';
+ $view_folder = rtrim($view_folder, '/\\').DIRECTORY_SEPARATOR;
}
define('VIEWPATH', $view_folder);
@@ -274,4 +274,4 @@ switch (ENVIRONMENT)
require_once BASEPATH.'core/CodeIgniter.php';
/* End of file index.php */
-/* Location: ./index.php */
+/* Location: ./index.php */ \ No newline at end of file
diff --git a/readme.rst b/readme.rst
index d76816237..5857558c2 100644
--- a/readme.rst
+++ b/readme.rst
@@ -14,7 +14,7 @@ for a given task.
Release Information
*******************
-This repo contains in development code for future releases. To download the
+This repo contains in-development code for future releases. To download the
latest stable release please visit the `CodeIgniter Downloads
<http://codeigniter.com/downloads/>`_ page.
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php
index 3fe5c0648..c12116236 100644
--- a/system/core/CodeIgniter.php
+++ b/system/core/CodeIgniter.php
@@ -73,11 +73,10 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* ------------------------------------------------------
*/
set_error_handler('_exception_handler');
+ register_shutdown_function('_shutdown_handler');
- if ( ! is_php('5.4'))
- {
- @ini_set('magic_quotes_runtime', 0); // Kill magic quotes
- }
+ // Kill magic quotes
+ is_php('5.4') OR @ini_set('magic_quotes_runtime', 0);
/*
* ------------------------------------------------------
@@ -88,7 +87,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* The subclass prefix allows CI to know if a core class is
* being extended via a library in the local application
* "libraries" folder. Since CI allows config items to be
- * overriden via data set in the main index. php file,
+ * overriden via data set in the main index.php file,
* before proceeding we need to know if a subclass_prefix
* override exists. If so, we will set this value now,
* before any classes are loaded
@@ -165,7 +164,6 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* ------------------------------------------------------
*/
$RTR =& load_class('Router', 'core');
- $RTR->_set_routing();
// Set any routing overrides that may exist in the main index file
if (isset($routing))
@@ -241,12 +239,13 @@ defined('BASEPATH') OR exit('No direct script access allowed');
// Load the local application controller
// Note: The Router class automatically validates the controller path using the router->_validate_request().
// If this include fails it means that the default controller in the Routes.php file is not resolving to something valid.
- if ( ! file_exists(APPPATH.'controllers/'.$RTR->directory.$RTR->class.'.php'))
+ $class = ucfirst($RTR->class);
+ if ( ! file_exists(APPPATH.'controllers/'.$RTR->directory.$class.'.php'))
{
show_error('Unable to load your default controller. Please make sure the controller specified in your Routes.php file is valid.');
}
- include(APPPATH.'controllers/'.$RTR->directory.$RTR->class.'.php');
+ include(APPPATH.'controllers/'.$RTR->directory.$class.'.php');
// Set a mark point for benchmarking
$BM->mark('loading_time:_base_classes_end');
@@ -258,9 +257,8 @@ defined('BASEPATH') OR exit('No direct script access allowed');
*
* None of the methods in the app controller or the
* loader class can be called via the URI, nor can
- * controller functions that begin with an underscore.
+ * controller methods that begin with an underscore.
*/
- $class = $RTR->class;
$method = $RTR->method;
if ( ! class_exists($class, FALSE) OR $method[0] === '_' OR method_exists('CI_Controller', $method))
@@ -272,6 +270,8 @@ defined('BASEPATH') OR exit('No direct script access allowed');
$method = 'index';
}
+ $class = ucfirst($class);
+
if ( ! class_exists($class, FALSE))
{
if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
@@ -310,6 +310,8 @@ defined('BASEPATH') OR exit('No direct script access allowed');
$method = 'index';
}
+ $class = ucfirst($class);
+
if ( ! class_exists($class, FALSE))
{
if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
diff --git a/system/core/Common.php b/system/core/Common.php
index d88b0867b..56008efe8 100644
--- a/system/core/Common.php
+++ b/system/core/Common.php
@@ -82,7 +82,7 @@ if ( ! function_exists('is_really_writable'))
function is_really_writable($file)
{
// If we're on a Unix server with safe_mode off we call is_writable
- if (DIRECTORY_SEPARATOR === '/' && (bool) @ini_get('safe_mode') === FALSE)
+ if (DIRECTORY_SEPARATOR === '/' && (is_php('5.4') OR (bool) @ini_get('safe_mode') === FALSE))
{
return is_writable($file);
}
@@ -224,56 +224,51 @@ if ( ! function_exists('get_config'))
* @param array
* @return array
*/
- function &get_config($replace = array())
+ function &get_config(Array $replace = array())
{
static $_config;
- if (isset($_config))
+ if (empty($_config))
{
- return $_config[0];
- }
+ $file_path = APPPATH.'config/config.php';
+ $found = FALSE;
+ if (file_exists($file_path))
+ {
+ $found = TRUE;
+ require($file_path);
+ }
- $file_path = APPPATH.'config/config.php';
- $found = FALSE;
- if (file_exists($file_path))
- {
- $found = TRUE;
- require($file_path);
- }
+ // Is the config file in the environment folder?
+ if (file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php'))
+ {
+ require($file_path);
+ }
+ elseif ( ! $found)
+ {
+ set_status_header(503);
+ echo 'The configuration file does not exist.';
+ exit(EXIT_CONFIG);
+ }
- // Is the config file in the environment folder?
- if (file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php'))
- {
- require($file_path);
- }
- elseif ( ! $found)
- {
- set_status_header(503);
- echo 'The configuration file does not exist.';
- exit(EXIT_CONFIG);
- }
+ // Does the $config array exist in the file?
+ if ( ! isset($config) OR ! is_array($config))
+ {
+ set_status_header(503);
+ echo 'Your config file does not appear to be formatted correctly.';
+ exit(EXIT_CONFIG);
+ }
- // Does the $config array exist in the file?
- if ( ! isset($config) OR ! is_array($config))
- {
- set_status_header(503);
- echo 'Your config file does not appear to be formatted correctly.';
- exit(EXIT_CONFIG);
+ // references cannot be directly assigned to static variables, so we use an array
+ $_config[0] =& $config;
}
- // Are any values being dynamically replaced?
- if (count($replace) > 0)
+ // Are any values being dynamically added or replaced?
+ foreach ($replace as $key => $val)
{
- foreach ($replace as $key => $val)
- {
- if (isset($config[$key]))
- {
- $config[$key] = $val;
- }
- }
+ $_config[0][$key] = $val;
}
- return $_config[0] =& $config;
+ return $_config[0];
}
}
@@ -289,20 +284,15 @@ if ( ! function_exists('config_item'))
*/
function config_item($item)
{
- static $_config_item = array();
+ static $_config;
- if ( ! isset($_config_item[$item]))
+ if (empty($_config))
{
- $config =& get_config();
-
- if ( ! isset($config[$item]))
- {
- return FALSE;
- }
- $_config_item[$item] = $config[$item];
+ // references cannot be directly assigned to static variables, so we use an array
+ $_config[0] =& get_config();
}
- return $_config_item[$item];
+ return isset($_config[0][$item]) ? $_config[0][$item] : FALSE;
}
}
@@ -439,29 +429,19 @@ if ( ! function_exists('log_message'))
*
* @param string the error level: 'error', 'debug' or 'info'
* @param string the error message
- * @param bool whether the error is a native PHP error
* @return void
*/
- function log_message($level, $message, $php_error = FALSE)
+ function log_message($level, $message)
{
- static $_log, $_log_threshold;
-
- if ($_log_threshold === NULL)
- {
- $_log_threshold = config_item('log_threshold');
- }
-
- if ($_log_threshold === 0)
- {
- return;
- }
+ static $_log;
if ($_log === NULL)
{
- $_log =& load_class('Log', 'core');
+ // references cannot be directly assigned to static variables, so we use an array
+ $_log[0] =& load_class('Log', 'core');
}
- $_log->write_log($level, $message, $php_error);
+ $_log[0]->write_log($level, $message);
}
}
@@ -543,7 +523,7 @@ if ( ! function_exists('set_status_header'))
$server_protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : FALSE;
- if (strpos(php_sapi_name(), 'cgi') === 0)
+ if (strpos(PHP_SAPI, 'cgi') === 0)
{
header('Status: '.$code.' '.$text, TRUE);
}
@@ -561,23 +541,23 @@ if ( ! function_exists('_exception_handler'))
/**
* Exception Handler
*
- * This is the custom exception handler that is declaired at the top
- * of Codeigniter.php. The main reason we use this is to permit
+ * This is the custom exception handler that is declared at the top
+ * of CodeIgniter.php. The main reason we use this is to permit
* PHP errors to be logged in our own log files since the user may
* not have access to server logs. Since this function
* effectively intercepts PHP errors, however, we also need
* to display errors based on the current error_reporting level.
* We do that with the use of a PHP error template.
*
- * @param int
- * @param string
- * @param string
- * @param int
+ * @param int $severity
+ * @param string $message
+ * @param string $filepath
+ * @param int $line
* @return void
*/
function _exception_handler($severity, $message, $filepath, $line)
{
- $is_error = ((E_ERROR | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity;
+ $is_error = (((E_ERROR | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity);
// When an error occurred, set the status header to '500 Internal Server Error'
// to indicate to the client something went wrong.
@@ -617,6 +597,34 @@ if ( ! function_exists('_exception_handler'))
}
}
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('_shutdown_handler'))
+{
+ /**
+ * Shutdown Handler
+ *
+ * This is the shutdown handler that is declared at the top
+ * of CodeIgniter.php. The main reason we use this is to simulate
+ * a complete custom exception handler.
+ *
+ * E_STRICT is purposivly neglected because such events may have
+ * been caught. Duplication or none? None is preferred for now.
+ *
+ * @link http://insomanic.me.uk/post/229851073/php-trick-catching-fatal-errors-e-error-with-a
+ * @return void
+ */
+ function _shutdown_handler()
+ {
+ $last_error = function_exists('error_get_last') ? error_get_last() : NULL;
+ if (isset($last_error) &&
+ ($last_error['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING)))
+ {
+ _exception_handler($last_error['type'], $last_error['message'], $last_error['file'], $last_error['line']);
+ }
+ }
+}
+
// --------------------------------------------------------------------
if ( ! function_exists('remove_invisible_characters'))
diff --git a/system/core/Config.php b/system/core/Config.php
index 7e64444bc..109ee6424 100644
--- a/system/core/Config.php
+++ b/system/core/Config.php
@@ -184,16 +184,16 @@ class CI_Config {
*
* @param string $item Config item name
* @param string $index Index name
- * @return string|bool The configuration item or FALSE on failure
+ * @return string|null The configuration item or NULL if the item doesn't exist
*/
public function item($item, $index = '')
{
if ($index == '')
{
- return isset($this->config[$item]) ? $this->config[$item] : FALSE;
+ return isset($this->config[$item]) ? $this->config[$item] : NULL;
}
- return isset($this->config[$index], $this->config[$index][$item]) ? $this->config[$index][$item] : FALSE;
+ return isset($this->config[$index], $this->config[$index][$item]) ? $this->config[$index][$item] : NULL;
}
// --------------------------------------------------------------------
@@ -202,13 +202,13 @@ class CI_Config {
* Fetch a config file item with slash appended (if not empty)
*
* @param string $item Config item name
- * @return string|bool The configuration item or FALSE on failure
+ * @return string|null The configuration item or NULL if the item doesn't exist
*/
public function slash_item($item)
{
if ( ! isset($this->config[$item]))
{
- return FALSE;
+ return NULL;
}
elseif (trim($this->config[$item]) === '')
{
diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php
index 9c68d06a5..d7e5ed4d9 100644
--- a/system/core/Exceptions.php
+++ b/system/core/Exceptions.php
@@ -91,7 +91,7 @@ class CI_Exceptions {
public function log_exception($severity, $message, $filepath, $line)
{
$severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity;
- log_message('error', 'Severity: '.$severity.' --> '.$message. ' '.$filepath.' '.$line, TRUE);
+ log_message('error', 'Severity: '.$severity.' --> '.$message. ' '.$filepath.' '.$line);
}
// --------------------------------------------------------------------
diff --git a/system/core/Input.php b/system/core/Input.php
index 0ef81128e..8c32e459e 100644
--- a/system/core/Input.php
+++ b/system/core/Input.php
@@ -47,7 +47,7 @@ class CI_Input {
public $ip_address = FALSE;
/**
- * User agent strin
+ * User agent string
*
* @var string
*/
@@ -261,7 +261,7 @@ class CI_Input {
* @param bool $xss_clean Whether to apply XSS filtering
* @return mixed
*/
- public function get_post($index = '', $xss_clean = FALSE)
+ public function post_get($index = '', $xss_clean = FALSE)
{
return isset($_POST[$index])
? $this->post($index, $xss_clean)
@@ -271,6 +271,22 @@ class CI_Input {
// --------------------------------------------------------------------
/**
+ * Fetch an item from GET data with fallback to POST
+ *
+ * @param string $index Index for item to be fetched from $_GET or $_POST
+ * @param bool $xss_clean Whether to apply XSS filtering
+ * @return mixed
+ */
+ public function get_post($index = '', $xss_clean = FALSE)
+ {
+ return isset($_GET[$index])
+ ? $this->get($index, $xss_clean)
+ : $this->post($index, $xss_clean);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* Fetch an item from the COOKIE array
*
* @param string $index Index for item to be fetched from $_COOKIE
@@ -677,7 +693,14 @@ class CI_Input {
foreach ($_COOKIE as $key => $val)
{
- $_COOKIE[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
+ if (($cookie_key = $this->_clean_input_keys($key)) !== FALSE)
+ {
+ $_COOKIE[$cookie_key] = $this->_clean_input_data($val);
+ }
+ else
+ {
+ unset($_COOKIE[$key]);
+ }
}
}
@@ -690,7 +713,7 @@ class CI_Input {
$this->security->csrf_verify();
}
- log_message('debug', 'Global POST and COOKIE data sanitized');
+ log_message('debug', 'Global POST, GET and COOKIE data sanitized');
}
// --------------------------------------------------------------------
@@ -760,15 +783,25 @@ class CI_Input {
* only named with alpha-numeric text and a few other items.
*
* @param string $str Input string
- * @return string
+ * @param string $fatal Whether to terminate script exection
+ * or to return FALSE if an invalid
+ * key is encountered
+ * @return string|bool
*/
- protected function _clean_input_keys($str)
+ protected function _clean_input_keys($str, $fatal = TRUE)
{
if ( ! preg_match('/^[a-z0-9:_\/|-]+$/i', $str))
{
- set_status_header(503);
- echo 'Disallowed Key Characters.';
- exit(EXIT_USER_INPUT);
+ if ($fatal === TRUE)
+ {
+ return FALSE;
+ }
+ else
+ {
+ set_status_header(503);
+ echo 'Disallowed Key Characters.';
+ exit(EXIT_USER_INPUT);
+ }
}
// Clean UTF-8 if supported
@@ -872,7 +905,7 @@ class CI_Input {
*/
public function is_cli_request()
{
- return (php_sapi_name() === 'cli' OR defined('STDIN'));
+ return (PHP_SAPI === 'cli' OR defined('STDIN'));
}
// --------------------------------------------------------------------
diff --git a/system/core/Loader.php b/system/core/Loader.php
index 70a6b6fa6..70c1e4154 100644
--- a/system/core/Loader.php
+++ b/system/core/Loader.php
@@ -76,13 +76,6 @@ class CI_Loader {
protected $_ci_helper_paths = array(APPPATH, BASEPATH);
/**
- * List of loaded base classes
- *
- * @var array
- */
- protected $_base_classes = array(); // Set by the controller class
-
- /**
* List of cached variables
*
* @var array
@@ -120,6 +113,8 @@ class CI_Loader {
'user_agent' => 'agent'
);
+ // --------------------------------------------------------------------
+
/**
* Class constructor
*
@@ -129,7 +124,8 @@ class CI_Loader {
*/
public function __construct()
{
- $this->_ci_ob_level = ob_get_level();
+ $this->_ci_ob_level = ob_get_level();
+ $this->_ci_classes =& is_loaded();
log_message('debug', 'Loader Class Initialized');
}
@@ -147,7 +143,6 @@ class CI_Loader {
*/
public function initialize()
{
- $this->_base_classes =& is_loaded();
$this->_ci_autoloader();
}
@@ -165,7 +160,7 @@ class CI_Loader {
*/
public function is_loaded($class)
{
- return isset($this->_ci_classes[$class]) ? $this->_ci_classes[$class] : FALSE;
+ return array_search(ucfirst($class), $this->_ci_classes, TRUE);
}
// --------------------------------------------------------------------
@@ -183,7 +178,11 @@ class CI_Loader {
*/
public function library($library = '', $params = NULL, $object_name = NULL)
{
- if (is_array($library))
+ if (empty($library))
+ {
+ return;
+ }
+ elseif (is_array($library))
{
foreach ($library as $class)
{
@@ -193,11 +192,6 @@ class CI_Loader {
return;
}
- if ($library === '' OR isset($this->_base_classes[$library]))
- {
- return;
- }
-
if ($params !== NULL && ! is_array($params))
{
$params = NULL;
@@ -228,7 +222,7 @@ class CI_Loader {
{
foreach ($model as $key => $value)
{
- $this->model(is_int($key) ? $value : $key, $value);
+ is_int($key) ? $this->model($value, '', $db_conn) : $this->model($key, $value, $db_conn);
}
return;
}
@@ -261,33 +255,32 @@ class CI_Loader {
show_error('The model name you are loading is the name of a resource that is already being used: '.$name);
}
- $model = strtolower($model);
-
- foreach ($this->_ci_model_paths as $mod_path)
+ if ($db_conn !== FALSE && ! class_exists('CI_DB', FALSE))
{
- if ( ! file_exists($mod_path.'models/'.$path.$model.'.php'))
+ if ($db_conn === TRUE)
{
- continue;
+ $db_conn = '';
}
- if ($db_conn !== FALSE && ! class_exists('CI_DB', FALSE))
- {
- if ($db_conn === TRUE)
- {
- $db_conn = '';
- }
+ $CI->load->database($db_conn, FALSE, TRUE);
+ }
- $CI->load->database($db_conn, FALSE, TRUE);
- }
+ if ( ! class_exists('CI_Model', FALSE))
+ {
+ load_class('Model', 'core');
+ }
- if ( ! class_exists('CI_Model', FALSE))
+ $model = ucfirst(strtolower($model));
+
+ foreach ($this->_ci_model_paths as $mod_path)
+ {
+ if ( ! file_exists($mod_path.'models/'.$path.$model.'.php'))
{
- load_class('Model', 'core');
+ continue;
}
require_once($mod_path.'models/'.$path.$model.'.php');
- $model = ucfirst($model);
$CI->$name = new $model();
$this->_ci_models[] = $name;
return;
@@ -422,7 +415,7 @@ class CI_Loader {
* to be extracted for use in the view
* @param bool $return Whether to return the view output
* or leave it to the Output class
- * @return void
+ * @return void|string
*/
public function view($view, $vars = array(), $return = FALSE)
{
@@ -478,6 +471,20 @@ class CI_Loader {
// --------------------------------------------------------------------
/**
+ * Clear Cached Variables
+ *
+ * Clears the cached variables.
+ *
+ * @return void
+ */
+ public function clear_vars()
+ {
+ $this->_ci_cached_vars = array();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* Get Variable
*
* Check if a variable is set and retrieve it.
@@ -1118,30 +1125,35 @@ class CI_Loader {
// Set the variable name we will assign the class to
// Was a custom class name supplied? If so we'll use it
- $class = strtolower($class);
-
- if ($object_name === NULL)
+ if (empty($object_name))
{
- $classvar = isset($this->_ci_varmap[$class]) ? $this->_ci_varmap[$class] : $class;
+ $object_name = strtolower($class);
+ if (isset($this->_ci_varmap[$object_name]))
+ {
+ $object_name = $this->_ci_varmap[$object_name];
+ }
}
- else
+
+ // Don't overwrite existing properties
+ $CI =& get_instance();
+ if (isset($CI->$object_name))
{
- $classvar = $object_name;
+ if ($CI->$object_name instanceof $name)
+ {
+ log_message('debug', $class." has already been instantiated as '".$object_name."'. Second attempt aborted.");
+ return;
+ }
+
+ show_error("Resource '".$object_name."' already exists and is not a ".$class." instance.");
}
// Save the class name and object name
- $this->_ci_classes[$class] = $classvar;
+ $this->_ci_classes[$object_name] = $class;
// Instantiate the class
- $CI =& get_instance();
- if ($config !== NULL)
- {
- $CI->$classvar = new $name($config);
- }
- else
- {
- $CI->$classvar = new $name();
- }
+ $CI->$object_name = isset($config)
+ ? new $name($config)
+ : new $name();
}
// --------------------------------------------------------------------
@@ -1198,6 +1210,15 @@ class CI_Loader {
}
}
+ // Autoload drivers
+ if (isset($autoload['drivers']))
+ {
+ foreach ($autoload['drivers'] as $item)
+ {
+ $this->driver($item);
+ }
+ }
+
// Load libraries
if (isset($autoload['libraries']) && count($autoload['libraries']) > 0)
{
@@ -1215,15 +1236,6 @@ class CI_Loader {
}
}
- // Autoload drivers
- if (isset($autoload['drivers']))
- {
- foreach ($autoload['drivers'] as $item)
- {
- $this->driver($item);
- }
- }
-
// Autoload models
if (isset($autoload['model']))
{
diff --git a/system/core/Log.php b/system/core/Log.php
index e4d72b544..b2327b8f0 100644
--- a/system/core/Log.php
+++ b/system/core/Log.php
@@ -140,10 +140,9 @@ class CI_Log {
*
* @param string the error level: 'error', 'debug' or 'info'
* @param string the error message
- * @param bool whether the error is a native PHP error
* @return bool
*/
- public function write_log($level, $msg, $php_error = FALSE)
+ public function write_log($level, $msg)
{
if ($this->_enabled === FALSE)
{
diff --git a/system/core/Output.php b/system/core/Output.php
index 06d7a866b..04209d920 100644
--- a/system/core/Output.php
+++ b/system/core/Output.php
@@ -841,13 +841,42 @@ class CI_Output {
$output = substr_replace($output, '', 0, $pos);
// Remove closing tag and save it for later
- $pos = strpos($output, '</');
- $closing_tag = substr($output, $pos, strlen($output));
+ $pos = strrpos($output, '</');
+ $closing_tag = substr($output, $pos);
$output = substr_replace($output, '', $pos);
}
// Remove CSS comments
- $output = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!i', '', $output);
+ $output = preg_replace('@/\*([^/][^*]*\*)*/(?!.+?["\'])@i', '', $output);
+
+ // Remove Javascript inline comments
+ if ($has_tags === TRUE && strpos(strtolower($open_tag), 'script') !== FALSE)
+ {
+ $lines = preg_split('/\r?\n|\n?\r/', $output);
+ foreach ($lines as &$line)
+ {
+ $in_string = $in_dstring = FALSE;
+ for ($i = 0, $len = strlen($line); $i < $len; $i++)
+ {
+ if ( ! $in_string && ! $in_dstring && substr($line, $i, 2) === '//')
+ {
+ $line = substr($line, 0, $i);
+ break;
+ }
+
+ if ($line[$i] === "'" && ! $in_dstring)
+ {
+ $in_string = ! $in_string;
+ }
+ elseif ($line[$i] === '"' && ! $in_string)
+ {
+ $in_dstring = ! $in_dstring;
+ }
+ }
+ }
+
+ $output = implode("\n", $lines);
+ }
// Remove spaces around curly brackets, colons,
// semi-colons, parenthesis, commas
@@ -899,11 +928,11 @@ class CI_Output {
}
}
- if ($value === "'")
+ if ($value === "'" && ! $in_dstring)
{
$in_string = ! $in_string;
}
- elseif ($value === '"')
+ elseif ($value === '"' && ! $in_string)
{
$in_dstring = ! $in_dstring;
}
diff --git a/system/core/Router.php b/system/core/Router.php
index c86ab9c20..0f7278ae6 100644
--- a/system/core/Router.php
+++ b/system/core/Router.php
@@ -82,6 +82,18 @@ class CI_Router {
public $default_controller;
/**
+ * Translate URI dashes
+ *
+ * Determines whether dashes in controller & method segments
+ * should be automatically replaced by underscores.
+ *
+ * @var bool
+ */
+ public $translate_uri_dashes = FALSE;
+
+ // --------------------------------------------------------------------
+
+ /**
* Class constructor
*
* Runs the route mapping function.
@@ -92,6 +104,7 @@ class CI_Router {
{
$this->config =& load_class('Config', 'core');
$this->uri =& load_class('URI', 'core');
+ $this->_set_routing();
log_message('debug', 'Router Class Initialized');
}
@@ -105,7 +118,7 @@ class CI_Router {
*
* @return void
*/
- public function _set_routing()
+ protected function _set_routing()
{
// Are query strings enabled in the config file? Normally CI doesn't utilize query strings
// since URI segments are more search-engine friendly, but they can optionally be used.
@@ -143,12 +156,14 @@ class CI_Router {
include(APPPATH.'config/'.ENVIRONMENT.'/routes.php');
}
- $this->routes = (empty($route) OR ! is_array($route)) ? array() : $route;
- unset($route);
-
- // Set the default controller so we can display it in the event
- // the URI doesn't correlated to a valid controller.
- $this->default_controller = empty($this->routes['default_controller']) ? FALSE : $this->routes['default_controller'];
+ // Validate & get reserved routes
+ if (isset($route) && is_array($route))
+ {
+ isset($route['default_controller']) && $this->default_controller = $route['default_controller'];
+ isset($route['translate_uri_dashes']) && $this->translate_uri_dashes = $route['translate_uri_dashes'];
+ unset($route['default_controller'], $route['translate_uri_dashes']);
+ $this->routes = $route;
+ }
// Were there any query string segments? If so, we'll validate them and bail out since we're done.
if (count($segments) > 0)
@@ -191,8 +206,6 @@ class CI_Router {
$method = 'index';
}
- $this->set_class($class);
- $this->set_method($method);
$this->_set_request(array($class, $method));
// re-index the routed segments array so it starts with 1 rather than 0
@@ -221,8 +234,16 @@ class CI_Router {
return $this->_set_default_controller();
}
- $this->set_class($segments[0]);
+ if ($this->translate_uri_dashes === TRUE)
+ {
+ $segments[0] = str_replace('-', '_', $segments[0]);
+ if (isset($segments[1]))
+ {
+ $segments[1] = str_replace('-', '_', $segments[1]);
+ }
+ }
+ $this->set_class($segments[0]);
isset($segments[1]) OR $segments[1] = 'index';
$this->set_method($segments[1]);
@@ -249,13 +270,11 @@ class CI_Router {
return $segments;
}
- $temp = str_replace('-', '_', $segments[0]);
+ $test = ucfirst($this->translate_uri_dashes === TRUE ? str_replace('-', '_', $segments[0]) : $segments[0]);
// Does the requested controller exist in the root folder?
- if (file_exists(APPPATH.'controllers/'.$temp.'.php'))
+ if (file_exists(APPPATH.'controllers/'.$test.'.php'))
{
- $segments[0] = $temp;
- empty($segments[1]) OR $segments[1] = str_replace('-', '_', $segments[1]);
return $segments;
}
@@ -266,11 +285,10 @@ class CI_Router {
$this->set_directory(array_shift($segments));
if (count($segments) > 0)
{
- $segments[0] = str_replace('-', '_', $segments[0]);
- empty($segments[1]) OR $segments[1] = str_replace('-', '_', $segments[1]);
+ $test = ucfirst($this->translate_uri_dashes === TRUE ? str_replace('-', '_', $segments[0]) : $segments[0]);
- // Does the requested controller exist in the sub-folder?
- if ( ! file_exists(APPPATH.'controllers/'.$this->directory.$segments[0].'.php'))
+ // Does the requested controller exist in the sub-directory?
+ if ( ! file_exists(APPPATH.'controllers/'.$this->directory.$test.'.php'))
{
if ( ! empty($this->routes['404_override']))
{
@@ -287,7 +305,7 @@ class CI_Router {
{
// Is the method being specified in the route?
$segments = explode('/', $this->default_controller);
- if ( ! file_exists(APPPATH.'controllers/'.$this->directory.$segments[0].'.php'))
+ if ( ! file_exists(APPPATH.'controllers/'.$this->directory.ucfirst($segments[0]).'.php'))
{
$this->directory = '';
}
@@ -333,10 +351,10 @@ class CI_Router {
return $this->_set_request(explode('/', $this->routes[$uri]));
}
- // Loop through the route array looking for wild-cards
+ // Loop through the route array looking for wildcards
foreach ($this->routes as $key => $val)
{
- // Convert wild-cards to RegEx
+ // Convert wildcards to RegEx
$key = str_replace(array(':any', ':num'), array('[^/]+', '[0-9]+'), $key);
// Does the RegEx match?
diff --git a/system/core/Security.php b/system/core/Security.php
index 196d61144..9423f825c 100644
--- a/system/core/Security.php
+++ b/system/core/Security.php
@@ -38,6 +38,30 @@ defined('BASEPATH') OR exit('No direct script access allowed');
class CI_Security {
/**
+ * List of sanitize filename strings
+ *
+ * @var array
+ */
+ public $filename_bad_chars = array(
+ '../', '<!--', '-->', '<', '>',
+ "'", '"', '&', '$', '#',
+ '{', '}', '[', ']', '=',
+ ';', '?', '%20', '%22',
+ '%3c', // <
+ '%253c', // <
+ '%3e', // >
+ '%0e', // >
+ '%28', // (
+ '%29', // )
+ '%2528', // (
+ '%26', // &
+ '%24', // $
+ '%3f', // ?
+ '%3b', // ;
+ '%3d' // =
+ );
+
+ /**
* XSS Hash
*
* Random Hash for protecting URLs.
@@ -529,9 +553,9 @@ class CI_Security {
{
$matches = $matches1 = 0;
+ $str = preg_replace('~(&#x0*[0-9a-f]{2,5});?~iS', '$1;', $str, -1, $matches);
+ $str = preg_replace('~(&#\d{2,4});?~S', '$1;', $str, -1, $matches1);
$str = html_entity_decode($str, ENT_COMPAT, $charset);
- $str = preg_replace('~&#x(0*[0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str, -1, $matches);
- $str = preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str, -1, $matches1);
}
while ($matches OR $matches1);
@@ -549,24 +573,7 @@ class CI_Security {
*/
public function sanitize_filename($str, $relative_path = FALSE)
{
- $bad = array(
- '../', '<!--', '-->', '<', '>',
- "'", '"', '&', '$', '#',
- '{', '}', '[', ']', '=',
- ';', '?', '%20', '%22',
- '%3c', // <
- '%253c', // <
- '%3e', // >
- '%0e', // >
- '%28', // (
- '%29', // )
- '%2528', // (
- '%26', // &
- '%24', // $
- '%3f', // ?
- '%3b', // ;
- '%3d' // =
- );
+ $bad = $this->filename_bad_chars;
if ( ! $relative_path)
{
@@ -596,7 +603,7 @@ class CI_Security {
*/
public function strip_image_tags($str)
{
- return preg_replace(array('#<img\s+.*?src\s*=\s*["\'](.+?)["\'].*?\>#', '#<img\s+.*?src\s*=\s*(.+?).*?\>#'), '\\1', $str);
+ return preg_replace(array('#<img[\s/]+.*?src\s*=\s*["\'](.+?)["\'].*?\>#', '#<img[\s/]+.*?src\s*=\s*(.+?).*?\>#'), '\\1', $str);
}
// ----------------------------------------------------------------
@@ -877,7 +884,7 @@ class CI_Security {
{
if ($this->_csrf_hash === '')
{
- // If the cookie exists we will use it's value.
+ // If the cookie exists we will use its value.
// We don't necessarily want to regenerate it with
// each page load since a page could contain embedded
// sub-pages causing this feature to fail
@@ -887,7 +894,7 @@ class CI_Security {
return $this->_csrf_hash = $_COOKIE[$this->_csrf_cookie_name];
}
- $this->_csrf_hash = md5(uniqid(rand(), TRUE));
+ $this->_csrf_hash = md5(uniqid(mt_rand(), TRUE));
$this->csrf_set_cookie();
}
diff --git a/system/database/DB.php b/system/database/DB.php
index 83d973304..8742800c8 100644
--- a/system/database/DB.php
+++ b/system/database/DB.php
@@ -76,9 +76,13 @@ function &DB($params = '', $query_builder_override = NULL)
$active_group = $params;
}
- if ( ! isset($active_group) OR ! isset($db[$active_group]))
+ if ( ! isset($active_group))
{
- show_error('You have specified an invalid database connection group.');
+ show_error('You have not specified a database connection group via $active_group in your config/database.php file.');
+ }
+ elseif ( ! isset($db[$active_group]))
+ {
+ show_error('You have specified an invalid database connection group ('.$active_group.') in your config/database.php file.');
}
$params = $db[$active_group];
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index 593d78ba4..9aa6c5de5 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -561,7 +561,6 @@ abstract class CI_DB_driver {
if ($sql === '')
{
log_message('error', 'Invalid query: '.$sql);
-
return ($this->db_debug) ? $this->display_error('db_invalid_query') : FALSE;
}
elseif ( ! is_bool($return_object))
@@ -625,7 +624,14 @@ abstract class CI_DB_driver {
// if transactions are enabled. If we don't call this here
// the error message will trigger an exit, causing the
// transactions to remain in limbo.
- $this->_trans_depth > 0 && $this->trans_complete();
+ if ($this->_trans_depth !== 0)
+ {
+ do
+ {
+ $this->trans_complete();
+ }
+ while ($this->_trans_depth !== 0);
+ }
// Display errors
return $this->display_error(array('Error Number: '.$error['code'], $error['message'], $sql));
@@ -1136,7 +1142,7 @@ abstract class CI_DB_driver {
else
{
/* We have no other choice but to just get the first element's key.
- * Due to array_shift() accepting it's argument by reference, if
+ * Due to array_shift() accepting its argument by reference, if
* E_STRICT is on, this would trigger a warning. So we'll have to
* assign it first.
*/
@@ -1376,7 +1382,9 @@ abstract class CI_DB_driver {
$fields[$this->protect_identifiers($key)] = $this->escape($val);
}
- return $this->_update($this->protect_identifiers($table, TRUE, NULL, FALSE), $fields);
+ $sql = $this->_update($this->protect_identifiers($table, TRUE, NULL, FALSE), $fields);
+ $this->_reset_write();
+ return $sql;
}
// --------------------------------------------------------------------
diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php
index 292621b66..a36501eb6 100644
--- a/system/database/DB_query_builder.php
+++ b/system/database/DB_query_builder.php
@@ -385,7 +385,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$alias = $this->_create_alias_from_table(trim($select));
}
- $sql = $this->protect_identifiers($type.'('.trim($select).')').' AS '.$this->escape_identifiers(trim($alias));
+ $sql = $type.'('.$this->protect_identifiers(trim($select)).') AS '.$this->escape_identifiers(trim($alias));
$this->qb_select[] = $sql;
$this->qb_no_escape[] = NULL;
@@ -1138,7 +1138,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* ORDER BY
*
* @param string $orderby
- * @param string $direction ASC or DESC
+ * @param string $direction ASC, DESC or RANDOM
* @param bool $escape
* @return CI_DB_query_builder
*/
@@ -1152,7 +1152,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
// Do we have a seed value?
$orderby = ctype_digit((string) $orderby)
- ? $orderby = sprintf($this->_random_keyword[1], $orderby)
+ ? sprintf($this->_random_keyword[1], $orderby)
: $this->_random_keyword[0];
}
elseif (empty($orderby))
@@ -1846,6 +1846,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
{
$this->query($this->_update_batch($this->protect_identifiers($table, TRUE, NULL, FALSE), array_slice($this->qb_set, $i, 100), $this->protect_identifiers($index)));
$affected_rows += $this->affected_rows();
+ $this->qb_where = array();
}
$this->_reset_write();
diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php
index ef2cb8a8d..0f3c6fc62 100644
--- a/system/database/drivers/mysqli/mysqli_driver.php
+++ b/system/database/drivers/mysqli/mysqli_driver.php
@@ -241,9 +241,10 @@ class CI_DB_mysqli_driver extends CI_DB {
// even if the queries produce a successful result.
$this->_trans_failure = ($test_mode === TRUE);
- $this->simple_query('SET AUTOCOMMIT=0');
- $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK
- return TRUE;
+ $this->conn_id->autocommit(FALSE);
+ return is_php('5.5')
+ ? $this->conn_id->begin_transaction()
+ : $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK
}
// --------------------------------------------------------------------
@@ -261,9 +262,13 @@ class CI_DB_mysqli_driver extends CI_DB {
return TRUE;
}
- $this->simple_query('COMMIT');
- $this->simple_query('SET AUTOCOMMIT=1');
- return TRUE;
+ if ($this->conn_id->commit())
+ {
+ $this->conn_id->autocommit(TRUE);
+ return TRUE;
+ }
+
+ return FALSE;
}
// --------------------------------------------------------------------
@@ -281,9 +286,13 @@ class CI_DB_mysqli_driver extends CI_DB {
return TRUE;
}
- $this->simple_query('ROLLBACK');
- $this->simple_query('SET AUTOCOMMIT=1');
- return TRUE;
+ if ($this->conn_id->rollback())
+ {
+ $this->conn_id->autocommit(TRUE);
+ return TRUE;
+ }
+
+ return FALSE;
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php
index 0ec8b53b8..020a3a4ba 100644
--- a/system/database/drivers/oci8/oci8_driver.php
+++ b/system/database/drivers/oci8/oci8_driver.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -327,12 +327,8 @@ class CI_DB_oci8_driver extends CI_DB {
{
if ($package === '' OR $procedure === '' OR ! is_array($params))
{
- if ($this->db_debug)
- {
- log_message('error', 'Invalid query: '.$package.'.'.$procedure);
- return $this->display_error('db_invalid_query');
- }
- return FALSE;
+ log_message('error', 'Invalid query: '.$package.'.'.$procedure);
+ return ($this->db_debug) ? $this->display_error('db_invalid_query') : FALSE;
}
// build the query string
diff --git a/system/database/drivers/oci8/oci8_result.php b/system/database/drivers/oci8/oci8_result.php
index fd1d28787..ce09b62bc 100644
--- a/system/database/drivers/oci8/oci8_result.php
+++ b/system/database/drivers/oci8/oci8_result.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
diff --git a/system/database/drivers/pdo/pdo_driver.php b/system/database/drivers/pdo/pdo_driver.php
index fa89661b1..184a8df33 100644
--- a/system/database/drivers/pdo/pdo_driver.php
+++ b/system/database/drivers/pdo/pdo_driver.php
@@ -69,7 +69,7 @@ class CI_DB_pdo_driver extends CI_DB {
{
parent::__construct($params);
- if (preg_match('/([^;]+):/', $this->dsn, $match) && count($match) === 2)
+ if (preg_match('/([^:]+):/', $this->dsn, $match) && count($match) === 2)
{
// If there is a minimum valid dsn string pattern found, we're done
// This is for general PDO users, who tend to have a full DSN string.
@@ -77,7 +77,7 @@ class CI_DB_pdo_driver extends CI_DB {
return;
}
// Legacy support for DSN specified in the hostname field
- elseif (preg_match('/([^;]+):/', $this->hostname, $match) && count($match) === 2)
+ elseif (preg_match('/([^:]+):/', $this->hostname, $match) && count($match) === 2)
{
$this->dsn = $this->hostname;
$this->hostname = NULL;
diff --git a/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php b/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php
index a39045eb7..c49549961 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php
@@ -103,7 +103,7 @@ class CI_DB_pdo_4d_forge extends CI_DB_4d_forge {
{
if (in_array($alter_type, array('ADD', 'DROP'), TRUE))
{
- return parent::_alter_table($alter_table, $table, $field);
+ return parent::_alter_table($alter_type, $table, $field);
}
// No method of modifying columns is supported
diff --git a/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php b/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php
index fdeefc9c5..fda3f238b 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php
@@ -130,6 +130,19 @@ class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver {
// --------------------------------------------------------------------
/**
+ * Determines if a query is a "write" type.
+ *
+ * @param string An SQL query string
+ * @return bool
+ */
+ public function is_write_type($sql)
+ {
+ return (bool) preg_match('/^\s*"?(SET|INSERT(?![^\)]+\)\s+RETURNING)|UPDATE(?!.*\sRETURNING)|DELETE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s+/i', str_replace(array("\r\n", "\r", "\n"), ' ', $sql));
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* "Smart" Escape String
*
* Escapes data based on type
@@ -153,7 +166,7 @@ class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver {
* ORDER BY
*
* @param string $orderby
- * @param string $direction ASC or DESC
+ * @param string $direction ASC, DESC or RANDOM
* @param bool $escape
* @return object
*/
diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php
index d35e351fc..b72fb873a 100644
--- a/system/database/drivers/postgre/postgre_driver.php
+++ b/system/database/drivers/postgre/postgre_driver.php
@@ -311,6 +311,19 @@ class CI_DB_postgre_driver extends CI_DB {
// --------------------------------------------------------------------
/**
+ * Determines if a query is a "write" type.
+ *
+ * @param string An SQL query string
+ * @return bool
+ */
+ public function is_write_type($sql)
+ {
+ return (bool) preg_match('/^\s*"?(SET|INSERT(?![^\)]+\)\s+RETURNING)|UPDATE(?!.*\sRETURNING)|DELETE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s+/i', str_replace(array("\r\n", "\r", "\n"), ' ', $sql));
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* Platform-dependant string escape
*
* @param string
@@ -318,7 +331,7 @@ class CI_DB_postgre_driver extends CI_DB {
*/
protected function _escape_str($str)
{
- return pg_escape_string($str);
+ return pg_escape_string($this->conn_id, $str);
}
// --------------------------------------------------------------------
@@ -333,7 +346,11 @@ class CI_DB_postgre_driver extends CI_DB {
*/
public function escape($str)
{
- if (is_bool($str))
+ if (is_php('5.4.4') && (is_string($str) OR (is_object($str) && method_exists($str, '__toString'))))
+ {
+ return pg_escape_literal($this->conn_id, $str);
+ }
+ elseif (is_bool($str))
{
return ($str) ? 'TRUE' : 'FALSE';
}
@@ -499,7 +516,7 @@ class CI_DB_postgre_driver extends CI_DB {
* ORDER BY
*
* @param string $orderby
- * @param string $direction ASC or DESC
+ * @param string $direction ASC, DESC or RANDOM
* @param bool $escape
* @return object
*/
diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php
index f3b9c6cc4..ea46f97b3 100644
--- a/system/helpers/captcha_helper.php
+++ b/system/helpers/captcha_helper.php
@@ -43,15 +43,31 @@ if ( ! function_exists('create_captcha'))
/**
* Create CAPTCHA
*
- * @param array array of data for the CAPTCHA
- * @param string path to create the image in
- * @param string URL to the CAPTCHA image folder
- * @param string server path to font
+ * @param array $data data for the CAPTCHA
+ * @param string $img_path path to create the image in
+ * @param string $img_url URL to the CAPTCHA image folder
+ * @param string $font_path server path to font
* @return string
*/
function create_captcha($data = '', $img_path = '', $img_url = '', $font_path = '')
{
- $defaults = array('word' => '', 'img_path' => '', 'img_url' => '', 'img_width' => '150', 'img_height' => '30', 'font_path' => '', 'expiration' => 7200, 'word_length' => 8, 'pool' => '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
+ $defaults = array(
+ 'word' => '',
+ 'img_path' => '',
+ 'img_url' => '',
+ 'img_width' => '150',
+ 'img_height' => '30',
+ 'font_path' => '',
+ 'expiration' => 7200,
+ 'word_length' => 8,
+ 'pool' => '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
+ 'colors' => array(
+ 'background' => array(255,255,255),
+ 'border' => array(153,102,102),
+ 'text' => array(204,153,153),
+ 'grid' => array(255,182,182)
+ )
+ );
foreach ($defaults as $key => $val)
{
@@ -110,9 +126,9 @@ if ( ! function_exists('create_captcha'))
// Determine angle and position
// -----------------------------------
$length = strlen($word);
- $angle = ($length >= 6) ? rand(-($length-6), ($length-6)) : 0;
- $x_axis = rand(6, (360/$length)-16);
- $y_axis = ($angle >= 0) ? rand($img_height, $img_width) : rand(6, $img_height);
+ $angle = ($length >= 6) ? mt_rand(-($length-6), ($length-6)) : 0;
+ $x_axis = mt_rand(6, (360/$length)-16);
+ $y_axis = ($angle >= 0) ? mt_rand($img_height, $img_width) : mt_rand(6, $img_height);
// Create image
// PHP.net recommends imagecreatetruecolor(), but it isn't always available
@@ -122,15 +138,19 @@ if ( ! function_exists('create_captcha'))
// -----------------------------------
// Assign colors
- // -----------------------------------
- $bg_color = imagecolorallocate($im, 255, 255, 255);
- $border_color = imagecolorallocate($im, 153, 102, 102);
- $text_color = imagecolorallocate($im, 204, 153, 153);
- $grid_color = imagecolorallocate($im, 255, 182, 182);
- $shadow_color = imagecolorallocate($im, 255, 240, 240);
+ // ----------------------------------
+
+ is_array($colors) OR $colors = $defaults['colors'];
+
+ foreach (array_keys($defaults['colors']) as $key)
+ {
+ // Check for a possible missing value
+ is_array($colors[$key]) OR $colors[$key] = $defaults['colors'][$key];
+ $colors[$key] = imagecolorallocate($im, $colors[$key][0], $colors[$key][1], $colors[$key][2]);
+ }
- // Create the rectangle
- ImageFilledRectangle($im, 0, 0, $img_width, $img_height, $bg_color);
+ // Create the rectangle
+ ImageFilledRectangle($im, 0, 0, $img_width, $img_height, $colors['background']);
// -----------------------------------
// Create the spiral pattern
@@ -151,7 +171,7 @@ if ( ! function_exists('create_captcha'))
$rad1 = $radius * (($i + 1) / $points);
$x1 = ($rad1 * cos($theta)) + $x_axis;
$y1 = ($rad1 * sin($theta)) + $y_axis;
- imageline($im, $x, $y, $x1, $y1, $grid_color);
+ imageline($im, $x, $y, $x1, $y1, $colors['grid']);
$theta -= $thetac;
}
@@ -163,13 +183,13 @@ if ( ! function_exists('create_captcha'))
if ($use_font === FALSE)
{
$font_size = 5;
- $x = rand(0, $img_width / ($length / 3));
+ $x = mt_rand(0, $img_width / ($length / 3));
$y = 0;
}
else
{
$font_size = 16;
- $x = rand(0, $img_width / ($length / 1.5));
+ $x = mt_rand(0, $img_width / ($length / 1.5));
$y = $font_size + 2;
}
@@ -177,20 +197,20 @@ if ( ! function_exists('create_captcha'))
{
if ($use_font === FALSE)
{
- $y = rand(0 , $img_height / 2);
- imagestring($im, $font_size, $x, $y, $word[$i], $text_color);
+ $y = mt_rand(0 , $img_height / 2);
+ imagestring($im, $font_size, $x, $y, $word[$i], $colors['text']);
$x += ($font_size * 2);
}
else
{
- $y = rand($img_height / 2, $img_height - 3);
- imagettftext($im, $font_size, $angle, $x, $y, $text_color, $font_path, $word[$i]);
+ $y = mt_rand($img_height / 2, $img_height - 3);
+ imagettftext($im, $font_size, $angle, $x, $y, $colors['text'], $font_path, $word[$i]);
$x += $font_size;
}
}
// Create the border
- imagerectangle($im, 0, 0, $img_width - 1, $img_height - 1, $border_color);
+ imagerectangle($im, 0, 0, $img_width - 1, $img_height - 1, $colors['border']);
// -----------------------------------
// Generate the image
diff --git a/system/helpers/date_helper.php b/system/helpers/date_helper.php
index 41a7ab635..c3a8d3c9e 100644
--- a/system/helpers/date_helper.php
+++ b/system/helpers/date_helper.php
@@ -677,7 +677,7 @@ if ( ! function_exists('date_range'))
$is_unix = ! ( ! $is_unix OR $is_unix === 'days');
// Validate input and try strtotime() on invalid timestamps/intervals, just in case
- if ( ( ! ctype_digit((string) $unix_start) && ($unix_start = @strtotime($unix_time)) === FALSE)
+ if ( ( ! ctype_digit((string) $unix_start) && ($unix_start = @strtotime($unix_start)) === FALSE)
OR ( ! ctype_digit((string) $mixed) && ($is_unix === FALSE OR ($mixed = @strtotime($mixed)) === FALSE))
OR ($is_unix === TRUE && $mixed < $unix_start))
{
@@ -686,7 +686,7 @@ if ( ! function_exists('date_range'))
if ($is_unix && ($unix_start == $mixed OR date($format, $unix_start) === date($format, $mixed)))
{
- return array($start_date);
+ return array(date($format, $unix_start));
}
$range = array();
diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php
index 1b8efff27..4b45a62d0 100644
--- a/system/helpers/file_helper.php
+++ b/system/helpers/file_helper.php
@@ -275,7 +275,7 @@ if ( ! function_exists('get_file_info'))
switch ($key)
{
case 'name':
- $fileinfo['name'] = substr(strrchr($file, DIRECTORY_SEPARATOR), 1);
+ $fileinfo['name'] = basename($file);
break;
case 'server_path':
$fileinfo['server_path'] = $file;
diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php
index 2002d4269..85f1f4e01 100644
--- a/system/helpers/form_helper.php
+++ b/system/helpers/form_helper.php
@@ -50,15 +50,10 @@ if ( ! function_exists('form_open'))
* @param array a key/value pair hidden data
* @return string
*/
- function form_open($action = '', $attributes = '', $hidden = array())
+ function form_open($action = '', $attributes = array(), $hidden = array())
{
$CI =& get_instance();
- if ($attributes === '')
- {
- $attributes = 'method="post"';
- }
-
// If an action is not a full URL then turn it into one
if ($action && strpos($action, '://') === FALSE)
{
@@ -70,10 +65,22 @@ if ( ! function_exists('form_open'))
$action = $CI->config->site_url($CI->uri->uri_string());
}
- $form = '<form action="'.$action.'"'._attributes_to_string($attributes, TRUE).">\n";
+ $attributes = _attributes_to_string($attributes);
+
+ if (stripos($attributes, 'method=') === FALSE)
+ {
+ $attributes .= ' method="post"';
+ }
+
+ if (stripos($attributes, 'accept-charset=') === FALSE)
+ {
+ $attributes .= ' accept-charset="'.strtolower(config_item('charset')).'"';
+ }
+
+ $form = '<form action="'.$action.'"'.$attributes.">\n";
// Add CSRF field if enabled, but leave it out for GET requests and requests to external websites
- if ($CI->config->item('csrf_protection') === TRUE && ! (strpos($action, $CI->config->base_url()) === FALSE OR strpos($form, 'method="get"')))
+ if ($CI->config->item('csrf_protection') === TRUE && ! (strpos($action, $CI->config->base_url()) === FALSE OR stripos($form, 'method="get"')))
{
$hidden[$CI->security->get_csrf_token_name()] = $CI->security->get_csrf_hash();
}
@@ -321,11 +328,8 @@ if ( ! function_exists('form_dropdown'))
{
$selected = array($_POST[$name]);
}
-
- if ($extra != '')
- {
- $extra = ' '.$extra;
- }
+
+ $extra = _attributes_to_string($extra);
$multiple = (count($selected) > 1 && strpos($extra, 'multiple') === FALSE) ? ' multiple="multiple"' : '';
@@ -542,12 +546,12 @@ if ( ! function_exists('form_fieldset'))
* use form_fieldset_close()
*
* @param string The legend text
- * @param string Additional attributes
+ * @param array Additional attributes
* @return string
*/
function form_fieldset($legend_text = '', $attributes = array())
{
- $fieldset = '<fieldset'._attributes_to_string($attributes, FALSE).">\n";
+ $fieldset = '<fieldset'._attributes_to_string($attributes).">\n";
if ($legend_text !== '')
{
return $fieldset.'<legend>'.$legend_text."</legend>\n";
@@ -668,37 +672,22 @@ if ( ! function_exists('set_select'))
*/
function set_select($field = '', $value = '', $default = FALSE)
{
- $OBJ =& _get_validation_object();
+ $CI =& get_instance();
- if ($OBJ === FALSE)
+ if (isset($CI->form_validation) && is_object($CI->form_validation) && $CI->form_validation->has_rule($field))
+ {
+ return $CI->form_validation->set_select($field, $value, $default);
+ }
+ elseif (($input = $CI->input->post($field, FALSE)) === NULL)
+ {
+ return ($default === TRUE) ? ' selected="selected"' : '';
+ }
+ elseif (is_array($input) && in_array($value, $input, TRUE))
{
- if ( ! isset($_POST[$field]))
- {
- if (count($_POST) === 0 && $default === TRUE)
- {
- return ' selected="selected"';
- }
- return '';
- }
-
- $field = $_POST[$field];
-
- if (is_array($field))
- {
- if ( ! in_array($value, $field))
- {
- return '';
- }
- }
- elseif (($field == '' OR $value == '') OR $field !== $value)
- {
- return '';
- }
-
return ' selected="selected"';
}
- return $OBJ->set_select($field, $value, $default);
+ return ($input === $value) ? ' selected="selected"' : '';
}
}
@@ -719,37 +708,22 @@ if ( ! function_exists('set_checkbox'))
*/
function set_checkbox($field = '', $value = '', $default = FALSE)
{
- $OBJ =& _get_validation_object();
+ $CI =& get_instance();
- if ($OBJ === FALSE)
+ if (isset($CI->form_validation) && is_object($CI->form_validation) && $CI->form_validation->has_rule($field))
+ {
+ return $CI->form_validation->set_checkbox($field, $value, $default);
+ }
+ elseif (($input = $CI->input->post($field, FALSE)) === NULL)
+ {
+ return ($default === TRUE) ? ' checked="checked"' : '';
+ }
+ elseif (is_array($input) && in_array($value, $input, TRUE))
{
- if ( ! isset($_POST[$field]))
- {
- if (count($_POST) === 0 && $default === TRUE)
- {
- return ' checked="checked"';
- }
- return '';
- }
-
- $field = $_POST[$field];
-
- if (is_array($field))
- {
- if ( ! in_array($value, $field))
- {
- return '';
- }
- }
- elseif (($field == '' OR $value == '') OR $field !== $value)
- {
- return '';
- }
-
return ' checked="checked"';
}
- return $OBJ->set_checkbox($field, $value, $default);
+ return ($input === $value) ? ' checked="checked"' : '';
}
}
@@ -763,47 +737,25 @@ if ( ! function_exists('set_radio'))
* Let's you set the selected value of a radio field via info in the POST array.
* If Form Validation is active it retrieves the info from the validation class
*
- * @param string
- * @param string
- * @param bool
+ * @param string $field
+ * @param string $value
+ * @param bool $default
* @return string
*/
function set_radio($field = '', $value = '', $default = FALSE)
{
- $OBJ =& _get_validation_object();
+ $CI =& get_instance();
- if ($OBJ === FALSE)
+ if (isset($CI->form_validation) && is_object($CI->form_validation) && $CI->form_validation->has_rule($field))
{
- if ( ! isset($_POST[$field]))
- {
- if (count($_POST) === 0 && $default === TRUE)
- {
- return ' checked="checked"';
- }
- return '';
- }
-
- $field = $_POST[$field];
-
- if (is_array($field))
- {
- if ( ! in_array($value, $field))
- {
- return '';
- }
- }
- else
- {
- if (($field == '' OR $value == '') OR $field !== $value)
- {
- return '';
- }
- }
-
- return ' checked="checked"';
+ return $CI->form_validation->set_radio($field, $value, $default);
+ }
+ elseif (($input = $CI->input->post($field, FALSE)) === NULL)
+ {
+ return ($default === TRUE) ? ' checked="checked"' : '';
}
- return $OBJ->set_radio($field, $value, $default);
+ return ($input === $value) ? ' checked="checked"' : '';
}
}
@@ -920,45 +872,24 @@ if ( ! function_exists('_attributes_to_string'))
* Helper function used by some of the form helpers
*
* @param mixed
- * @param bool
* @return string
*/
- function _attributes_to_string($attributes, $formtag = FALSE)
+ function _attributes_to_string($attributes)
{
- if (is_string($attributes) && strlen($attributes) > 0)
+ if (empty($attributes))
{
- if ($formtag === TRUE && strpos($attributes, 'method=') === FALSE)
- {
- $attributes .= ' method="post"';
- }
-
- if ($formtag === TRUE && strpos($attributes, 'accept-charset=') === FALSE)
- {
- $attributes .= ' accept-charset="'.strtolower(config_item('charset')).'"';
- }
-
- return ' '.$attributes;
+ return '';
}
- if (is_object($attributes) && count($attributes) > 0)
+ if (is_object($attributes))
{
$attributes = (array) $attributes;
}
- if (is_array($attributes) && ($formtag === TRUE OR count($attributes) > 0))
+ if (is_array($attributes))
{
$atts = '';
- if ( ! isset($attributes['method']) && $formtag === TRUE)
- {
- $atts .= ' method="post"';
- }
-
- if ( ! isset($attributes['accept-charset']) && $formtag === TRUE)
- {
- $atts .= ' accept-charset="'.strtolower(config_item('charset')).'"';
- }
-
foreach ($attributes as $key => $val)
{
$atts .= ' '.$key.'="'.$val.'"';
@@ -966,6 +897,13 @@ if ( ! function_exists('_attributes_to_string'))
return $atts;
}
+
+ if (is_string($attributes))
+ {
+ return ' '.$attributes;
+ }
+
+ return FALSE;
}
}
@@ -988,7 +926,7 @@ if ( ! function_exists('_get_validation_object'))
// We set this as a variable since we're returning by reference.
$return = FALSE;
- if (FALSE !== ($object = $CI->load->is_loaded('form_validation')))
+ if (FALSE !== ($object = $CI->load->is_loaded('Form_validation')))
{
if ( ! isset($CI->$object) OR ! is_object($CI->$object))
{
diff --git a/system/helpers/html_helper.php b/system/helpers/html_helper.php
index 80a27876f..ece39584b 100644
--- a/system/helpers/html_helper.php
+++ b/system/helpers/html_helper.php
@@ -109,7 +109,7 @@ if ( ! function_exists('_list'))
* @param int
* @return string
*/
- function _list($type = 'ul', $list, $attributes = '', $depth = 0)
+ function _list($type = 'ul', $list = array(), $attributes = '', $depth = 0)
{
// If an array wasn't submitted there's nothing to do...
if ( ! is_array($list))
diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php
index d0fab3fe0..fbb4a1b24 100644
--- a/system/helpers/url_helper.php
+++ b/system/helpers/url_helper.php
@@ -46,13 +46,20 @@ if ( ! function_exists('site_url'))
* Create a local URL based on your basepath. Segments can be passed via the
* first parameter either as a string or an array.
*
- * @param string
+ * @param string $uri
+ * @param string $protocol
* @return string
*/
- function site_url($uri = '')
+ function site_url($uri = '', $protocol = NULL)
{
- $CI =& get_instance();
- return $CI->config->site_url($uri);
+ $uri = get_instance()->config->site_url($uri);
+
+ if (isset($protocol))
+ {
+ return $protocol.substr($uri, strpos($uri, '://'));
+ }
+
+ return $uri;
}
}
@@ -67,13 +74,20 @@ if ( ! function_exists('base_url'))
* Segments can be passed in as a string or an array, same as site_url
* or a URL to a file can be passed in, e.g. to an image file.
*
- * @param string
+ * @param string $uri
+ * @param string $protocol
* @return string
*/
- function base_url($uri = '')
+ function base_url($uri = '', $protocol = NULL)
{
- $CI =& get_instance();
- return $CI->config->base_url($uri);
+ $uri = get_instance()->config->base_url($uri);
+
+ if (isset($protocol))
+ {
+ return $protocol.substr($uri, strpos($uri, '://'));
+ }
+
+ return $uri;
}
}
diff --git a/system/libraries/Cache/Cache.php b/system/libraries/Cache/Cache.php
index e1089f755..537897eaf 100644
--- a/system/libraries/Cache/Cache.php
+++ b/system/libraries/Cache/Cache.php
@@ -106,7 +106,7 @@ class CI_Cache extends CI_Driver_Library {
isset($config['key_prefix']) && $this->key_prefix = $config['key_prefix'];
- if (isset($config['backup']) && in_array('cache_'.$config['backup'], $this->valid_drivers))
+ if (isset($config['backup']) && in_array($config['backup'], $this->valid_drivers))
{
$this->_backup_driver = $config['backup'];
}
@@ -123,6 +123,7 @@ class CI_Cache extends CI_Driver_Library {
else
{
// Backup is supported. Set it to primary.
+ log_message('debug', 'Cache adapter "'.$this->_adapter.'" is unavailable. Falling back to "'.$this->_backup_driver.'" backup adapter.');
$this->_adapter = $this->_backup_driver;
}
}
diff --git a/system/libraries/Cache/drivers/Cache_apc.php b/system/libraries/Cache/drivers/Cache_apc.php
index 127a220a7..a84e7d2d3 100644
--- a/system/libraries/Cache/drivers/Cache_apc.php
+++ b/system/libraries/Cache/drivers/Cache_apc.php
@@ -150,7 +150,7 @@ class CI_Cache_apc extends CI_Driver {
{
if ( ! extension_loaded('apc') OR ! (bool) @ini_get('apc.enabled'))
{
- log_message('error', 'The APC PHP extension must be loaded to use APC Cache.');
+ log_message('debug', 'The APC PHP extension must be loaded to use APC Cache.');
return FALSE;
}
diff --git a/system/libraries/Cache/drivers/Cache_memcached.php b/system/libraries/Cache/drivers/Cache_memcached.php
index 246a7a264..d2a3a489d 100644
--- a/system/libraries/Cache/drivers/Cache_memcached.php
+++ b/system/libraries/Cache/drivers/Cache_memcached.php
@@ -51,9 +51,9 @@ class CI_Cache_memcached extends CI_Driver {
*/
protected $_memcache_conf = array(
'default' => array(
- 'default_host' => '127.0.0.1',
- 'default_port' => 11211,
- 'default_weight' => 1
+ 'host' => '127.0.0.1',
+ 'port' => 11211,
+ 'weight' => 1
)
);
@@ -173,7 +173,8 @@ class CI_Cache_memcached extends CI_Driver {
{
if (is_array($CI->config->config['memcached']))
{
- $this->_memcache_conf = NULL;
+ $defaults = $this->_memcache_conf['default'];
+ $this->_memcache_conf = array();
foreach ($CI->config->config['memcached'] as $name => $conf)
{
@@ -196,22 +197,11 @@ class CI_Cache_memcached extends CI_Driver {
return FALSE;
}
- foreach ($this->_memcache_conf as $name => $cache_server)
+ foreach ($this->_memcache_conf as $cache_server)
{
- if ( ! array_key_exists('hostname', $cache_server))
- {
- $cache_server['hostname'] = $this->_memcache_conf['default']['default_host'];
- }
-
- if ( ! array_key_exists('port', $cache_server))
- {
- $cache_server['port'] = $this->_memcache_conf['default']['default_port'];
- }
-
- if ( ! array_key_exists('weight', $cache_server))
- {
- $cache_server['weight'] = $this->_memcache_conf['default']['default_weight'];
- }
+ isset($cache_server['hostname']) OR $cache_server['hostname'] = $defaults['host'];
+ isset($cache_server['port']) OR $cache_server['port'] = $defaults['host'];
+ isset($cache_server['weight']) OR $cache_server['weight'] = $defaults['weight'];
if (get_class($this->_memcached) === 'Memcache')
{
@@ -250,7 +240,7 @@ class CI_Cache_memcached extends CI_Driver {
{
if ( ! extension_loaded('memcached') && ! extension_loaded('memcache'))
{
- log_message('error', 'The Memcached Extension must be loaded to use Memcached Cache.');
+ log_message('debug', 'The Memcached Extension must be loaded to use Memcached Cache.');
return FALSE;
}
diff --git a/system/libraries/Cache/drivers/Cache_redis.php b/system/libraries/Cache/drivers/Cache_redis.php
index 484f284f1..40823fcb4 100644
--- a/system/libraries/Cache/drivers/Cache_redis.php
+++ b/system/libraries/Cache/drivers/Cache_redis.php
@@ -168,7 +168,7 @@ class CI_Cache_redis extends CI_Driver
}
else
{
- log_message('error', 'The Redis extension must be loaded to use Redis cache.');
+ log_message('debug', 'The Redis extension must be loaded to use Redis cache.');
return FALSE;
}
}
diff --git a/system/libraries/Cache/drivers/Cache_wincache.php b/system/libraries/Cache/drivers/Cache_wincache.php
index d749978f5..80d3ac13d 100644
--- a/system/libraries/Cache/drivers/Cache_wincache.php
+++ b/system/libraries/Cache/drivers/Cache_wincache.php
@@ -150,7 +150,7 @@ class CI_Cache_wincache extends CI_Driver {
{
if ( ! extension_loaded('wincache'))
{
- log_message('error', 'The Wincache PHP extension must be loaded to use Wincache Cache.');
+ log_message('debug', 'The Wincache PHP extension must be loaded to use Wincache Cache.');
return FALSE;
}
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index 11ee29041..efdbfd7c1 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -399,9 +399,9 @@ class CI_Email {
else
{
$this->_smtp_auth = ! ($this->smtp_user === '' && $this->smtp_pass === '');
- $this->_safe_mode = (bool) @ini_get('safe_mode');
}
+ $this->_safe_mode = ( ! is_php('5.4') && (bool) @ini_get('safe_mode'));
$this->charset = strtoupper($this->charset);
log_message('debug', 'Email Class Initialized');
@@ -451,7 +451,6 @@ class CI_Email {
$this->clear();
$this->_smtp_auth = ! ($this->smtp_user === '' && $this->smtp_pass === '');
- $this->_safe_mode = (bool) @ini_get('safe_mode');
return $this;
}
@@ -1265,7 +1264,7 @@ class CI_Email {
}
else
{
- $this->_finalbody = $hdr . $this->newline . $this->newline . $this->_body;
+ $this->_finalbody = $hdr.$this->newline.$this->newline.$this->_body;
}
return;
@@ -1275,11 +1274,11 @@ class CI_Email {
if ($this->send_multipart === FALSE)
{
$hdr .= 'Content-Type: text/html; charset='.$this->charset.$this->newline
- .'Content-Transfer-Encoding: quoted-printable'.$this->newline.$this->newline;
+ .'Content-Transfer-Encoding: quoted-printable';
}
else
{
- $hdr .= 'Content-Type: multipart/alternative; boundary="'.$this->_alt_boundary.'"'.$this->newline.$this->newline;
+ $hdr .= 'Content-Type: multipart/alternative; boundary="'.$this->_alt_boundary.'"';
$body .= $this->_get_mime_message().$this->newline.$this->newline
.'--'.$this->_alt_boundary.$this->newline
@@ -1300,7 +1299,7 @@ class CI_Email {
}
else
{
- $this->_finalbody = $hdr.$this->_finalbody;
+ $this->_finalbody = $hdr.$this->newline.$this->newline.$this->_finalbody;
}
if ($this->send_multipart !== FALSE)
@@ -1312,25 +1311,25 @@ class CI_Email {
case 'plain-attach' :
- $hdr .= 'Content-Type: multipart/'.$this->multipart.'; boundary="'.$this->_atc_boundary.'"'.$this->newline.$this->newline;
+ $hdr .= 'Content-Type: multipart/'.$this->multipart.'; boundary="'.$this->_atc_boundary.'"';
if ($this->_get_protocol() === 'mail')
{
$this->_header_str .= $hdr;
}
- $body .= $this->_get_mime_message().$this->newline.$this->newline
+ $body .= $this->_get_mime_message().$this->newline
+ .$this->newline
.'--'.$this->_atc_boundary.$this->newline
-
.'Content-Type: text/plain; charset='.$this->charset.$this->newline
- .'Content-Transfer-Encoding: '.$this->_get_encoding().$this->newline.$this->newline
-
+ .'Content-Transfer-Encoding: '.$this->_get_encoding().$this->newline
+ .$this->newline
.$this->_body.$this->newline.$this->newline;
break;
case 'html-attach' :
- $hdr .= 'Content-Type: multipart/'.$this->multipart.'; boundary="'.$this->_atc_boundary.'"'.$this->newline.$this->newline;
+ $hdr .= 'Content-Type: multipart/'.$this->multipart.'; boundary="'.$this->_atc_boundary.'"';
if ($this->_get_protocol() === 'mail')
{
@@ -1400,7 +1399,9 @@ class CI_Email {
}
$body .= implode($this->newline, $attachment).$this->newline.'--'.$this->_atc_boundary.'--';
- $this->_finalbody = ($this->_get_protocol() === 'mail') ? $body : $hdr.$body;
+ $this->_finalbody = ($this->_get_protocol() === 'mail')
+ ? $body
+ : $hdr.$this->newline.$this->newline.$body;
return TRUE;
}
@@ -2140,7 +2141,7 @@ class CI_Email {
if (in_array('headers', $include, TRUE))
{
- $raw_data = $this->_header_str."\n";
+ $raw_data = htmlspecialchars($this->_header_str)."\n";
}
if (in_array('subject', $include, TRUE))
diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php
index 40ba01202..8b9bfa897 100644
--- a/system/libraries/Form_validation.php
+++ b/system/libraries/Form_validation.php
@@ -583,7 +583,7 @@ class CI_Form_validation {
// If the field is blank, but NOT required, no further tests are necessary
$callback = FALSE;
- if ( ! in_array('required', $rules) && $postdata === NULL)
+ if ( ! in_array('required', $rules) && ($postdata === NULL OR $postdata === ''))
{
// Before we bail out, does the rule contain a callback?
if (preg_match('/(callback_\w+(\[.*?\])?)/', implode(' ', $rules), $match))
@@ -598,7 +598,7 @@ class CI_Form_validation {
}
// Isset Test. Typically this rule will only apply to checkboxes.
- if ($postdata === NULL && $callback === FALSE)
+ if (($postdata === NULL OR $postdata === '') && $callback === FALSE)
{
if (in_array('isset', $rules, TRUE) OR in_array('required', $rules))
{
diff --git a/system/libraries/Javascript.php b/system/libraries/Javascript.php
index 773a58384..26a16850c 100644
--- a/system/libraries/Javascript.php
+++ b/system/libraries/Javascript.php
@@ -172,7 +172,7 @@ class CI_Javascript {
*/
public function focus($element = 'this', $js = '')
{
- return $this->js->__add_event($focus, $js);
+ return $this->js->_focus($element, $js);
}
// --------------------------------------------------------------------
@@ -187,9 +187,9 @@ class CI_Javascript {
* @param string - Javascript code for mouse out
* @return string
*/
- public function hover($element = 'this', $over, $out)
+ public function hover($element = 'this', $over = '', $out = '')
{
- return $this->js->__hover($element, $over, $out);
+ return $this->js->_hover($element, $over, $out);
}
// --------------------------------------------------------------------
diff --git a/system/libraries/Javascript/Jquery.php b/system/libraries/Javascript/Jquery.php
index b6e0434b2..ab78e8b2e 100644
--- a/system/libraries/Javascript/Jquery.php
+++ b/system/libraries/Javascript/Jquery.php
@@ -225,7 +225,7 @@ class CI_Jquery extends CI_Javascript {
* @param string - Javascript code for mouse out
* @return string
*/
- protected function _hover($element = 'this', $over, $out)
+ protected function _hover($element = 'this', $over = '', $out = '')
{
$event = "\n\t$(".$this->_prep_element($element).").hover(\n\t\tfunction()\n\t\t{\n\t\t\t{$over}\n\t\t}, \n\t\tfunction()\n\t\t{\n\t\t\t{$out}\n\t\t});\n";
@@ -715,7 +715,7 @@ class CI_Jquery extends CI_Javascript {
* @return string
*/
- protected function _updater($container = 'this', $controller, $options = '')
+ protected function _updater($container = 'this', $controller = '', $options = '')
{
$container = $this->_prep_element($container);
$controller = (strpos('://', $controller) === FALSE) ? $controller : $this->CI->config->site_url($controller);
@@ -923,7 +923,6 @@ class CI_Jquery extends CI_Javascript {
if (is_array($js))
{
$js = implode("\n\t\t", $js);
-
}
$event = "\n\t$(".$this->_prep_element($element).').'.$event."(function(){\n\t\t{$js}\n\t});\n";
@@ -937,7 +936,7 @@ class CI_Jquery extends CI_Javascript {
* Compile
*
* As events are specified, they are stored in an array
- * This funciton compiles them all for output on a page
+ * This function compiles them all for output on a page
*
* @param string $view_var
* @param bool $script_tags
diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php
index 10fb29dbd..c6ffd03d4 100644
--- a/system/libraries/Pagination.php
+++ b/system/libraries/Pagination.php
@@ -354,7 +354,8 @@ class CI_Pagination {
public 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)
+ // Note: DO NOT change the operator to === here!
+ if ($this->total_rows == 0 OR $this->per_page == 0)
{
return '';
}
diff --git a/system/libraries/Parser.php b/system/libraries/Parser.php
index 1c26bd2b2..c1f1ad73b 100644
--- a/system/libraries/Parser.php
+++ b/system/libraries/Parser.php
@@ -38,14 +38,14 @@ defined('BASEPATH') OR exit('No direct script access allowed');
class CI_Parser {
/**
- * Left delimeter character for psuedo vars
+ * Left delimiter character for pseudo vars
*
* @var string
*/
public $l_delim = '{';
/**
- * Right delimeter character for psuedo vars
+ * Right delimiter character for pseudo vars
*
* @var string
*/
diff --git a/system/libraries/Profiler.php b/system/libraries/Profiler.php
index 3c7ce5406..50ba1673f 100644
--- a/system/libraries/Profiler.php
+++ b/system/libraries/Profiler.php
@@ -264,7 +264,7 @@ class CI_Profiler {
foreach ($db->queries as $key => $val)
{
$time = number_format($db->query_times[$key], 4);
- $val = highlight_code($val, ENT_QUOTES);
+ $val = highlight_code($val);
foreach ($highlight as $bold)
{
@@ -307,10 +307,7 @@ class CI_Profiler {
foreach ($_GET as $key => $val)
{
- if ( ! is_numeric($key))
- {
- $key = "'".$key."'";
- }
+ is_int($key) OR $key = "'".$key."'";
$output .= '<tr><td style="width:50%;color:#000;background-color:#ddd;padding:5px;">&#36;_GET['
.$key.']&nbsp;&nbsp; </td><td style="width:50%;padding:5px;color:#cd6e00;font-weight:normal;background-color:#ddd;">'
@@ -338,7 +335,7 @@ class CI_Profiler {
."\n"
.'<legend style="color:#009900;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_post_data')."&nbsp;&nbsp;</legend>\n";
- if (count($_POST) === 0)
+ if (count($_POST) === 0 && count($_FILES) === 0)
{
$output .= '<div style="color:#009900;font-weight:normal;padding:4px 0 4px 0;">'.$this->CI->lang->line('profiler_no_post').'</div>';
}
@@ -348,10 +345,7 @@ class CI_Profiler {
foreach ($_POST as $key => $val)
{
- if ( ! is_numeric($key))
- {
- $key = "'".$key."'";
- }
+ is_int($key) OR $key = "'".$key."'";
$output .= '<tr><td style="width:50%;padding:5px;color:#000;background-color:#ddd;">&#36;_POST['
.$key.']&nbsp;&nbsp; </td><td style="width:50%;padding:5px;color:#009900;font-weight:normal;background-color:#ddd;">';
@@ -368,6 +362,21 @@ class CI_Profiler {
$output .= "</td></tr>\n";
}
+ foreach ($_FILES as $key => $val)
+ {
+ is_int($key) OR $key = "'".$key."'";
+
+ $output .= '<tr><td style="width:50%;padding:5px;color:#000;background-color:#ddd;">&#36;_FILES['
+ .$key.']&nbsp;&nbsp; </td><td style="width:50%;padding:5px;color:#009900;font-weight:normal;background-color:#ddd;">';
+
+ if (is_array($val) OR is_object($val))
+ {
+ $output .= '<pre>'.htmlspecialchars(stripslashes(print_r($val, TRUE))).'</pre>';
+ }
+
+ $output .= "</td></tr>\n";
+ }
+
$output .= "</table>\n";
}
@@ -447,7 +456,7 @@ class CI_Profiler {
.'&nbsp;&nbsp;(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_httpheaders_table\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show')."</span>)</legend>\n\n\n"
.'<table style="width:100%;display:none;" id="ci_profiler_httpheaders_table">'."\n";
- foreach (array('HTTP_ACCEPT', 'HTTP_USER_AGENT', 'HTTP_CONNECTION', 'SERVER_PORT', 'SERVER_NAME', 'REMOTE_ADDR', 'SERVER_SOFTWARE', 'HTTP_ACCEPT_LANGUAGE', 'SCRIPT_NAME', 'REQUEST_METHOD',' HTTP_HOST', 'REMOTE_HOST', 'CONTENT_TYPE', 'SERVER_PROTOCOL', 'QUERY_STRING', 'HTTP_ACCEPT_ENCODING', 'HTTP_X_FORWARDED_FOR') as $header)
+ foreach (array('HTTP_ACCEPT', 'HTTP_USER_AGENT', 'HTTP_CONNECTION', 'SERVER_PORT', 'SERVER_NAME', 'REMOTE_ADDR', 'SERVER_SOFTWARE', 'HTTP_ACCEPT_LANGUAGE', 'SCRIPT_NAME', 'REQUEST_METHOD',' HTTP_HOST', 'REMOTE_HOST', 'CONTENT_TYPE', 'SERVER_PROTOCOL', 'QUERY_STRING', 'HTTP_ACCEPT_ENCODING', 'HTTP_X_FORWARDED_FOR', 'HTTP_DNT') as $header)
{
$val = isset($_SERVER[$header]) ? $_SERVER[$header] : '';
$output .= '<tr><td style="vertical-align:top;width:50%;padding:5px;color:#900;background-color:#ddd;">'
diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php
index c7f6f828c..659a0269e 100644
--- a/system/libraries/Session/Session.php
+++ b/system/libraries/Session/Session.php
@@ -60,11 +60,18 @@ class CI_Session extends CI_Driver_Library {
public $params = array();
/**
+ * Valid drivers list
+ *
+ * @var array
+ */
+ public $valid_drivers = array('native', 'cookie');
+
+ /**
* Current driver in use
*
* @var string
*/
- protected $current = NULL;
+ public $current = NULL;
/**
* User data
@@ -105,36 +112,26 @@ class CI_Session extends CI_Driver_Library {
log_message('debug', 'CI_Session Class Initialized');
- // Get valid drivers list
- $this->valid_drivers = array(
- 'native',
- 'cookie'
- );
- $key = 'sess_valid_drivers';
- $drivers = isset($params[$key]) ? $params[$key] : $CI->config->item($key);
- if ($drivers)
+ // Add possible extra entries to our valid drivers list
+ $drivers = isset($params['sess_valid_drivers']) ? $params['sess_valid_drivers'] : $CI->config->item('sess_valid_drivers');
+ if ( ! empty($drivers))
{
- // Add driver names to valid list
- foreach ((array) $drivers as $driver)
- {
- if ( ! in_array(strtolower($driver), array_map('strtolower', $this->valid_drivers)))
- {
- $this->valid_drivers[] = $driver;
- }
- }
+ $drivers = array_map('strtolower', (array) $drivers);
+ $this->valid_drivers = array_merge($this->valid_drivers, array_diff($drivers, $this->valid_drivers));
}
// Get driver to load
- $key = 'sess_driver';
- $driver = isset($params[$key]) ? $params[$key] : $CI->config->item($key);
+ $driver = isset($params['sess_driver']) ? $params['sess_driver'] : $CI->config->item('sess_driver');
if ( ! $driver)
{
+ log_message('debug', "Session: No driver name is configured, defaulting to 'cookie'.");
$driver = 'cookie';
}
- if ( ! in_array(strtolower($driver), array_map('strtolower', $this->valid_drivers)))
+ if ( ! in_array($driver, $this->valid_drivers))
{
- $this->valid_drivers[] = $driver;
+ log_message('error', 'Session: Configured driver name is not valid, aborting.');
+ return;
}
// Save a copy of parameters in case drivers need access
diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php
index 7174d63c8..d3d22d03a 100644
--- a/system/libraries/Session/drivers/Session_cookie.php
+++ b/system/libraries/Session/drivers/Session_cookie.php
@@ -402,6 +402,7 @@ class CI_Session_cookie extends CI_Session_driver {
// Is the session data we unserialized an array with the correct format?
if ( ! is_array($session) OR ! isset($session['session_id'], $session['ip_address'], $session['user_agent'], $session['last_activity']))
{
+ log_message('debug', 'Session: Wrong cookie data format');
$this->sess_destroy();
return FALSE;
}
@@ -409,6 +410,7 @@ class CI_Session_cookie extends CI_Session_driver {
// Is the session current?
if (($session['last_activity'] + $this->sess_expiration) < $this->now OR $session['last_activity'] > $this->now)
{
+ log_message('debug', 'Session: Expired');
$this->sess_destroy();
return FALSE;
}
@@ -416,6 +418,7 @@ class CI_Session_cookie extends CI_Session_driver {
// Does the IP match?
if ($this->sess_match_ip === TRUE && $session['ip_address'] !== $this->CI->input->ip_address())
{
+ log_message('debug', 'Session: IP address mismatch');
$this->sess_destroy();
return FALSE;
}
@@ -424,6 +427,7 @@ class CI_Session_cookie extends CI_Session_driver {
if ($this->sess_match_useragent === TRUE &&
trim($session['user_agent']) !== trim(substr($this->CI->input->user_agent(), 0, 120)))
{
+ log_message('debug', 'Session: User Agent string mismatch');
$this->sess_destroy();
return FALSE;
}
@@ -459,6 +463,7 @@ class CI_Session_cookie extends CI_Session_driver {
// No result? Kill it!
if (empty($query) OR $query->num_rows() === 0)
{
+ log_message('debug', 'Session: No match found in our database');
$this->sess_destroy();
return FALSE;
}
@@ -498,6 +503,8 @@ class CI_Session_cookie extends CI_Session_driver {
'last_activity' => $this->now,
);
+ log_message('debug', 'Session: Creating new session ('.$this->userdata['session_id'].')');
+
// Check for database
if ($this->sess_use_database === TRUE)
{
@@ -536,6 +543,8 @@ class CI_Session_cookie extends CI_Session_driver {
{
// Get new id
$this->userdata['session_id'] = $this->_make_sess_id();
+
+ log_message('debug', 'Session: Regenerate ID');
}
// Check for database
diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php
index fb5ce1906..c237ad059 100644
--- a/system/libraries/Session/drivers/Session_native.php
+++ b/system/libraries/Session/drivers/Session_native.php
@@ -117,18 +117,21 @@ class CI_Session_native extends CI_Session_driver {
if (isset($_SESSION['last_activity']) && (($_SESSION['last_activity'] + $expire) < $now OR $_SESSION['last_activity'] > $now))
{
// Expired - destroy
+ log_message('debug', 'Session: Expired');
$destroy = TRUE;
}
elseif ($config['sess_match_ip'] === TRUE && isset($_SESSION['ip_address'])
&& $_SESSION['ip_address'] !== $this->CI->input->ip_address())
{
// IP doesn't match - destroy
+ log_message('debug', 'Session: IP address mismatch');
$destroy = TRUE;
}
elseif ($config['sess_match_useragent'] === TRUE && isset($_SESSION['user_agent'])
&& $_SESSION['user_agent'] !== trim(substr($this->CI->input->user_agent(), 0, 50)))
{
// Agent doesn't match - destroy
+ log_message('debug', 'Session: User Agent string mismatch');
$destroy = TRUE;
}
@@ -145,9 +148,10 @@ class CI_Session_native extends CI_Session_driver {
&& ($_SESSION['last_activity'] + $config['sess_time_to_update']) < $now)
{
// Changing the session ID amidst a series of AJAX calls causes problems
- if( ! $this->CI->input->is_ajax_request())
+ if ( ! $this->CI->input->is_ajax_request())
{
// Regenerate ID, but don't destroy session
+ log_message('debug', 'Session: Regenerate ID');
$this->sess_regenerate(FALSE);
}
}
diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php
index 5861df584..060973847 100644
--- a/system/libraries/Upload.php
+++ b/system/libraries/Upload.php
@@ -463,7 +463,7 @@ class CI_Upload {
}
// Are the image dimensions within the allowed size?
- // Note: This can fail if the server has an open_basdir restriction.
+ // Note: This can fail if the server has an open_basedir restriction.
if ( ! $this->is_allowed_dimensions())
{
$this->set_error('upload_invalid_dimensions');
@@ -1090,18 +1090,14 @@ class CI_Upload {
$CI =& get_instance();
$CI->lang->load('upload');
- if (is_array($msg))
+ 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);
- }
+ $msg = array($msg);
}
- else
+
+ foreach ($msg as $val)
{
- $msg = ($CI->lang->line($msg) === FALSE) ? $msg : $CI->lang->line($msg);
+ $msg = ($CI->lang->line($val) === FALSE) ? $val : $CI->lang->line($val);
$this->error_msg[] = $msg;
log_message('error', $msg);
}
@@ -1249,7 +1245,7 @@ class CI_Upload {
}
}
- if ( (bool) @ini_get('safe_mode') === FALSE && function_usable('shell_exec'))
+ if ((bool) @ini_get('safe_mode') === FALSE && function_usable('shell_exec'))
{
$mime = @shell_exec($cmd);
if (strlen($mime) > 0)
diff --git a/system/libraries/User_agent.php b/system/libraries/User_agent.php
index 2f6f81909..50ac9be98 100644
--- a/system/libraries/User_agent.php
+++ b/system/libraries/User_agent.php
@@ -471,13 +471,24 @@ class CI_User_agent {
*/
public function is_referral()
{
- if (empty($_SERVER['HTTP_REFERER']))
+ static $result;
+
+ if ( ! isset($result))
{
- return FALSE;
+ if (empty($_SERVER['HTTP_REFERER']))
+ {
+ $result = FALSE;
+ }
+ else
+ {
+ $referer_host = @parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST);
+ $own_host = parse_url(config_item('base_url'), PHP_URL_HOST);
+
+ $result = ($referer_host && $referer_host !== $own_host);
+ }
}
- $referer = parse_url($_SERVER['HTTP_REFERER']);
- return ! (empty($referer['host']) && strpos(config_item('base_url'), $referer['host']) !== FALSE);
+ return $result;
}
// --------------------------------------------------------------------
diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php
index 9e60791ae..16c5b0ed8 100644
--- a/system/libraries/Xmlrpc.php
+++ b/system/libraries/Xmlrpc.php
@@ -446,7 +446,7 @@ class CI_Xmlrpc {
{
while (list($k) = each($value[0]))
{
- $value[0][$k] = $this->values_parsing($value[0][$k], TRUE);
+ $value[0][$k] = $this->values_parsing($value[0][$k]);
}
}
diff --git a/system/libraries/Zip.php b/system/libraries/Zip.php
index 6608f050e..2ce457844 100644
--- a/system/libraries/Zip.php
+++ b/system/libraries/Zip.php
@@ -103,12 +103,12 @@ class CI_Zip {
*
* Lets you add a virtual directory into which you can place files.
*
- * @param mixed the directory name. Can be string or array
+ * @param mixed $directory the directory name. Can be string or array
* @return void
*/
public function add_dir($directory)
{
- foreach ( (array) $directory as $dir)
+ foreach ((array) $directory as $dir)
{
if ( ! preg_match('|.+/$|', $dir))
{
@@ -127,7 +127,7 @@ class CI_Zip {
*
* If this is a newly created file/dir, we will set the time to 'now'
*
- * @param string path to file
+ * @param string $dir path to file
* @return array filemtime/filemdate
*/
protected function _get_mod_time($dir)
@@ -146,9 +146,9 @@ class CI_Zip {
/**
* Add Directory
*
- * @param string the directory name
- * @param int
- * @param int
+ * @param string $dir the directory name
+ * @param int $file_mtime
+ * @param int $file_mdate
* @return void
*/
protected function _add_dir($dir, $file_mtime, $file_mdate)
@@ -199,8 +199,8 @@ class CI_Zip {
* in the filename it will be placed within a directory. Make
* sure you use add_dir() first to create the folder.
*
- * @param mixed
- * @param string
+ * @param mixed $filepath A single filepath or an array of file => data pairs
+ * @param string $data Single file contents
* @return void
*/
public function add_data($filepath, $data = NULL)
@@ -225,10 +225,10 @@ class CI_Zip {
/**
* Add Data to Zip
*
- * @param string the file name/path
- * @param string the data to be encoded
- * @param int
- * @param int
+ * @param string $filepath the file name/path
+ * @param string $data the data to be encoded
+ * @param int $file_mtime
+ * @param int $file_mdate
* @return void
*/
protected function _add_data($filepath, $data, $file_mtime, $file_mdate)
@@ -278,8 +278,8 @@ class CI_Zip {
/**
* Read the contents of a file and add it to the zip
*
- * @param string
- * @param bool
+ * @param string $path
+ * @param bool $preserve_filepath
* @return bool
*/
public function read_file($path, $preserve_filepath = FALSE)
@@ -313,9 +313,9 @@ class CI_Zip {
* sub-folders) and creates a zip based on it. Whatever directory structure
* is in the original file path will be recreated in the zip file.
*
- * @param string path to source
- * @param bool
- * @param bool
+ * @param string $path path to source directory
+ * @param bool $preserve_filepath
+ * @param string $root_path
* @return bool
*/
public function read_dir($path, $preserve_filepath = TRUE, $root_path = NULL)
@@ -389,7 +389,7 @@ class CI_Zip {
*
* Lets you write a file
*
- * @param string the file name
+ * @param string $filepath the file name
* @return bool
*/
public function archive($filepath)
@@ -412,7 +412,7 @@ class CI_Zip {
/**
* Download
*
- * @param string the file name
+ * @param string $filename the file name
* @return void
*/
public function download($filename = 'backup.zip')
diff --git a/tests/codeigniter/core/Benchmark_test.php b/tests/codeigniter/core/Benchmark_test.php
index a239ba51d..aff736a40 100644
--- a/tests/codeigniter/core/Benchmark_test.php
+++ b/tests/codeigniter/core/Benchmark_test.php
@@ -30,7 +30,7 @@ class Benchmark_test extends CI_TestCase {
sleep(1);
$this->benchmark->mark('code_end');
- $this->assertEquals('1.0', $this->benchmark->elapsed_time('code_start', 'code_end', 1));
+ $this->assertEquals('1', $this->benchmark->elapsed_time('code_start', 'code_end', 0));
}
// --------------------------------------------------------------------
diff --git a/tests/codeigniter/core/Config_test.php b/tests/codeigniter/core/Config_test.php
index e3be8a3fc..ba9a2c070 100644
--- a/tests/codeigniter/core/Config_test.php
+++ b/tests/codeigniter/core/Config_test.php
@@ -24,18 +24,18 @@ class Config_test extends CI_TestCase {
$this->assertEquals($this->cfg['base_url'], $this->config->item('base_url'));
// Bad Config value
- $this->assertFalse($this->config->item('no_good_item'));
+ $this->assertNull($this->config->item('no_good_item'));
// Index
- $this->assertFalse($this->config->item('no_good_item', 'bad_index'));
- $this->assertFalse($this->config->item('no_good_item', 'default'));
+ $this->assertNull($this->config->item('no_good_item', 'bad_index'));
+ $this->assertNull($this->config->item('no_good_item', 'default'));
}
// --------------------------------------------------------------------
public function test_set_item()
{
- $this->assertFalse($this->config->item('not_yet_set'));
+ $this->assertNull($this->config->item('not_yet_set'));
$this->config->set_item('not_yet_set', 'is set');
$this->assertEquals('is set', $this->config->item('not_yet_set'));
@@ -46,7 +46,7 @@ class Config_test extends CI_TestCase {
public function test_slash_item()
{
// Bad Config value
- $this->assertFalse($this->config->slash_item('no_good_item'));
+ $this->assertNull($this->config->slash_item('no_good_item'));
$this->assertEquals($this->cfg['base_url'], $this->config->slash_item('base_url'));
$this->assertEquals($this->cfg['subclass_prefix'].'/', $this->config->slash_item('subclass_prefix'));
diff --git a/tests/codeigniter/core/Input_test.php b/tests/codeigniter/core/Input_test.php
index 5cf25fefa..0a98e556c 100644
--- a/tests/codeigniter/core/Input_test.php
+++ b/tests/codeigniter/core/Input_test.php
@@ -82,11 +82,21 @@ class Input_test extends CI_TestCase {
// --------------------------------------------------------------------
- public function test_get_post()
+ public function test_post_get()
{
$_SERVER['REQUEST_METHOD'] = 'POST';
$_POST['foo'] = 'bar';
+ $this->assertEquals('bar', $this->input->post_get('foo'));
+ }
+
+ // --------------------------------------------------------------------
+
+ public function test_get_post()
+ {
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $_GET['foo'] = 'bar';
+
$this->assertEquals('bar', $this->input->get_post('foo'));
}
diff --git a/tests/codeigniter/core/Loader_test.php b/tests/codeigniter/core/Loader_test.php
index ac2656e75..9ad3ca6b9 100644
--- a/tests/codeigniter/core/Loader_test.php
+++ b/tests/codeigniter/core/Loader_test.php
@@ -28,7 +28,7 @@ class Loader_test extends CI_TestCase {
$this->ci_vfs_create(ucfirst($lib), '<?php class '.$class.' { }', $this->ci_base_root, 'libraries');
// Test is_loaded fail
- $this->assertFalse($this->load->is_loaded($lib));
+ $this->assertFalse($this->load->is_loaded(ucfirst($lib)));
// Test loading as an array.
$this->assertNull($this->load->library(array($lib)));
@@ -123,7 +123,7 @@ class Loader_test extends CI_TestCase {
$this->assertEquals($cfg, $this->ci_obj->$obj->config);
// Test is_loaded
- $this->assertEquals($obj, $this->load->is_loaded($lib));
+ $this->assertEquals($obj, $this->load->is_loaded(ucfirst($lib)));
}
// --------------------------------------------------------------------
@@ -181,16 +181,16 @@ class Loader_test extends CI_TestCase {
$this->ci_set_core_class('model', 'CI_Model');
// Create model in VFS
- $model = 'unit_test_model';
- $class = ucfirst($model);
- $content = '<?php class '.$class.' extends CI_Model {} ';
+ $model = 'Unit_test_model';
+ $content = '<?php class '.$model.' extends CI_Model {} ';
$this->ci_vfs_create($model, $content, $this->ci_app_root, 'models');
// Load model
$this->assertNull($this->load->model($model));
// Was the model class instantiated.
- $this->assertTrue(class_exists($class));
+ $this->assertTrue(class_exists($model));
+ $this->assertObjectHasAttribute($model, $this->ci_obj);
// Test no model given
$this->assertNull($this->load->model(''));
@@ -204,11 +204,10 @@ class Loader_test extends CI_TestCase {
$this->ci_core_class('model');
// Create modelin VFS
- $model = 'test_sub_model';
+ $model = 'Test_sub_model';
$base = 'CI_Model';
- $class = ucfirst($model);
$subdir = 'cars';
- $this->ci_vfs_create($model, '<?php class '.$class.' extends '.$base.' { }', $this->ci_app_root,
+ $this->ci_vfs_create($model, '<?php class '.$model.' extends '.$base.' { }', $this->ci_app_root,
array('models', $subdir));
// Load model
@@ -216,10 +215,10 @@ class Loader_test extends CI_TestCase {
$this->assertNull($this->load->model($subdir.'/'.$model, $name));
// Was the model class instantiated?
- $this->assertTrue(class_exists($class));
+ $this->assertTrue(class_exists($model));
$this->assertObjectHasAttribute($name, $this->ci_obj);
$this->assertAttributeInstanceOf($base, $name, $this->ci_obj);
- $this->assertAttributeInstanceOf($class, $name, $this->ci_obj);
+ $this->assertAttributeInstanceOf($model, $name, $this->ci_obj);
// Test name conflict
$obj = 'conflict';
@@ -237,7 +236,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'
+ 'CI Error: Unable to locate the model you have specified: Ci_test_nonexistent_model.php'
);
$this->load->model('ci_test_nonexistent_model.php');
@@ -481,9 +480,8 @@ class Loader_test extends CI_TestCase {
// Create model in VFS package path
$dir = 'testdir';
$path = APPPATH.$dir.'/';
- $model = 'automod';
- $mod_class = ucfirst($model);
- $this->ci_vfs_create($model, '<?php class '.$mod_class.' { }', $this->ci_app_root, array($dir, 'models'));
+ $model = 'Automod';
+ $this->ci_vfs_create($model, '<?php class '.$model.' { }', $this->ci_app_root, array($dir, 'models'));
// Create autoloader config
$cfg = array(
@@ -513,8 +511,8 @@ class Loader_test extends CI_TestCase {
$this->assertAttributeInstanceOf($drv_class, $drv, $this->ci_obj);
// Verify model
- $this->assertTrue(class_exists($mod_class), $mod_class.' does not exist');
- $this->assertAttributeInstanceOf($mod_class, $model, $this->ci_obj);
+ $this->assertTrue(class_exists($model), $model.' does not exist');
+ $this->assertAttributeInstanceOf($model, $model, $this->ci_obj);
// Verify config calls
$this->assertEquals($cfg['config'], $this->ci_obj->config->loaded);
diff --git a/tests/codeigniter/core/Security_test.php b/tests/codeigniter/core/Security_test.php
index 3f6e3b07a..433ad313f 100644
--- a/tests/codeigniter/core/Security_test.php
+++ b/tests/codeigniter/core/Security_test.php
@@ -5,7 +5,7 @@ class Security_test extends CI_TestCase {
public function set_up()
{
// Set cookie for security test
- $_COOKIE['ci_csrf_cookie'] = md5(uniqid(rand(), TRUE));
+ $_COOKIE['ci_csrf_cookie'] = md5(uniqid(mt_rand(), TRUE));
// Set config for Security class
$this->ci_set_config('csrf_protection', TRUE);
diff --git a/tests/codeigniter/helpers/directory_helper_test.php b/tests/codeigniter/helpers/directory_helper_test.php
index 41370e6e7..de72dee78 100644
--- a/tests/codeigniter/helpers/directory_helper_test.php
+++ b/tests/codeigniter/helpers/directory_helper_test.php
@@ -14,6 +14,8 @@ class Directory_helper_test extends CI_TestCase {
public function test_directory_map()
{
+ $ds = DIRECTORY_SEPARATOR;
+
$structure = array(
'libraries' => array(
'benchmark.html' => '',
@@ -26,11 +28,18 @@ class Directory_helper_test extends CI_TestCase {
vfsStream::create($structure, $this->_test_dir);
+ // is_dir(), opendir(), etc. seem to fail on Windows + vfsStream when there are trailing backslashes in directory names
+ if ( ! is_dir(vfsStream::url('testDir').DIRECTORY_SEPARATOR))
+ {
+ $this->markTestSkipped();
+ return;
+ }
+
// test default recursive behavior
$expected = array(
- 'libraries/' => array(
+ 'libraries'.$ds => array(
'benchmark.html',
- 'database/' => array('active_record.html', 'binds.html'),
+ 'database'.$ds => array('active_record.html', 'binds.html'),
'email.html',
'0'
)
@@ -39,12 +48,12 @@ class Directory_helper_test extends CI_TestCase {
$this->assertEquals($expected, directory_map(vfsStream::url('testDir')));
// test detection of hidden files
- $expected['libraries/'][] = '.hiddenfile.txt';
+ $expected['libraries'.$ds][] = '.hiddenfile.txt';
- $this->assertEquals($expected, directory_map(vfsStream::url('testDir'), FALSE, TRUE));
+ $this->assertEquals($expected, directory_map(vfsStream::url('testDir'), 0, TRUE));
// test recursion depth behavior
- $this->assertEquals(array('libraries/'), directory_map(vfsStream::url('testDir'), 1));
+ $this->assertEquals(array('libraries'.$ds), directory_map(vfsStream::url('testDir'), 1));
}
}
diff --git a/tests/mocks/core/common.php b/tests/mocks/core/common.php
index 0ccfe1ea4..e5dc29c86 100644
--- a/tests/mocks/core/common.php
+++ b/tests/mocks/core/common.php
@@ -178,7 +178,7 @@ if ( ! function_exists('is_loaded'))
if ( ! function_exists('log_message'))
{
- function log_message($level, $message, $php_error = FALSE)
+ function log_message($level, $message)
{
return TRUE;
}
diff --git a/tests/mocks/database/db.php b/tests/mocks/database/db.php
index 7e0030e15..968476dea 100644
--- a/tests/mocks/database/db.php
+++ b/tests/mocks/database/db.php
@@ -106,6 +106,7 @@ class Mock_Database_DB {
$subdriver = self::$subdriver;
$case->ci_vfs_create(array(
'DB_driver.php' => '',
+ 'DB_result.php' => '',
'DB_forge.php' => '',
'DB_query_builder.php' => ''
), '', $case->ci_base_root, 'database');
@@ -113,6 +114,7 @@ class Mock_Database_DB {
{
$case->ci_vfs_create(array(
$driver.'_driver.php' => '',
+ $driver.'_result.php' => '',
$driver.'_forge.php' => ''
), '', $case->ci_base_root, 'database/drivers/'.$driver);
}
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index f5e2da738..8f5dfe540 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -19,6 +19,7 @@ Release Date: Not Released
- General Changes
- PHP 5.1.6 is no longer supported. CodeIgniter now requires PHP 5.2.4.
+ - Changed filenaming convention (class file names now must be Ucfirst and everything else in lowercase).
- ``$_SERVER['CI_ENV']`` can now be set to control the ``ENVIRONMENT`` constant.
- Added an optional backtrace to php-error template.
- Added Android to the list of user agents.
@@ -60,52 +61,78 @@ Release Date: Not Released
- Helpers
- :doc:`Date Helper <helpers/date_helper>` changes include:
- - :php:func:`now()` now works with all timezone strings supported by PHP.
- - Added an optional third parameter to :php:func:`timespan()` that constrains the number of time units displayed.
- - Added an optional parameter to :php:func:`timezone_menu()` that allows more attributes to be added to the generated select tag.
- - Deprecated ``standard_date()``, which now just uses the native ``date()`` with `DateTime constants <http://www.php.net/manual/en/class.datetime.php#datetime.constants.types>`_.
- - Added function :php:func:`date_range()` that generates a list of dates between a specified period.
+
+ - :php:func:`now()` now works with all timezone strings supported by PHP.
+ - Added an optional third parameter to :php:func:`timespan()` that constrains the number of time units displayed.
+ - Added an optional parameter to :php:func:`timezone_menu()` that allows more attributes to be added to the generated select tag.
+ - Deprecated ``standard_date()``, which now just uses the native ``date()`` with `DateTime constants <http://www.php.net/manual/en/class.datetime.php#datetime.constants.types>`_.
+ - Added function :php:func:`date_range()` that generates a list of dates between a specified period.
+
- :doc:`URL Helper <helpers/url_helper>` changes include:
- - Deprecated *separator* options **dash** and **underscore** for function :php:func:`url_title()` (they are only aliases for '-' and '_' respectively).
- - :php:func:`url_title()` will now trim extra dashes from beginning and end.
- - :php:func:`anchor_popup()` will now fill the *href* attribute with the URL and its JS code will return FALSE instead.
- - Added JS window name support to the :php:func:`anchor_popup()` function.
- - Added support (auto-detection) for HTTP/1.1 response code 303 in :php:func:`redirect()`.
- - Changed :php:func:`redirect()` to only choose the **refresh** method only on IIS servers, instead of all servers on Windows (when **auto** is used).
- - Changed :php:func:`anchor()`, :php:func:`anchor_popup()`, and :php:func:`redirect()` to support protocol-relative URLs (e.g. *//ellislab.com/codeigniter*).
+
+ - Deprecated *separator* options **dash** and **underscore** for function :php:func:`url_title()` (they are only aliases for '-' and '_' respectively).
+ - :php:func:`url_title()` will now trim extra dashes from beginning and end.
+ - :php:func:`anchor_popup()` will now fill the *href* attribute with the URL and its JS code will return FALSE instead.
+ - Added JS window name support to the :php:func:`anchor_popup()` function.
+ - Added support (auto-detection) for HTTP/1.1 response code 303 in :php:func:`redirect()`.
+ - Changed :php:func:`redirect()` to choose the **refresh** method only on IIS servers, instead of all servers on Windows (when **auto** is used).
+ - Changed :php:func:`anchor()`, :php:func:`anchor_popup()`, and :php:func:`redirect()` to support protocol-relative URLs (e.g. *//ellislab.com/codeigniter*).
+ - Added an optional second parameter to both :php:func:`base_url()` and :php:func:`site_url()` that allows enforcing of a protocol different than the one in the *base_url* configuration setting.
+
- :doc:`HTML Helper <helpers/html_helper>` changes include:
- - Added more doctypes.
- - Changed application and environment config files to be loaded in a cascade-like manner.
- - The doctypes array is now cached and loaded only once.
+
+ - Added more doctypes.
+ - Changed application and environment config files to be loaded in a cascade-like manner.
+ - The doctypes array is now cached and loaded only once.
+
- :doc:`Inflector Helper <helpers/inflector_helper>` changes include:
- - Changed :php:func:`humanize()` to allow passing an input separator as its second parameter.
- - Refactored :php:func:`plural()` and :php:func:`singular()` to avoid double pluralization and support more words.
+
+ - Changed :php:func:`humanize()` to allow passing an input separator as its second parameter.
+ - Refactored :php:func:`plural()` and :php:func:`singular()` to avoid double pluralization and support more words.
+
- :doc:`Download Helper <helpers/download_helper>` changes include:
- - Added an optional third parameter to :php:func:`force_download()` that enables/disables sending the actual file MIME type in the Content-Type header (disabled by default).
- - Added a work-around in :php:func:`force_download()` for a bug Android <= 2.1, where the filename extension needs to be in uppercase.
- - Added support for reading from an existing file path by passing NULL as the second parameter to :php:func:`force_download()` (useful for large files and/or safely transmitting binary data).
+
+ - Added an optional third parameter to :php:func:`force_download()` that enables/disables sending the actual file MIME type in the Content-Type header (disabled by default).
+ - Added a work-around in :php:func:`force_download()` for a bug Android <= 2.1, where the filename extension needs to be in uppercase.
+ - Added support for reading from an existing file path by passing NULL as the second parameter to :php:func:`force_download()` (useful for large files and/or safely transmitting binary data).
+
- :doc:`Form Helper <helpers/form_helper>` changes include:
- - :php:func:`form_dropdown()` will now also take an array for unity with other form helpers.
- - :php:func:`form_prep()`'s second argument now only accepts a boolean value, which determines whether the value is escaped for a <textarea> or a regular <input> element.
+
+ - :php:func:`form_dropdown()` will now also take an array for unity with other form helpers.
+ - :php:func:`form_prep()`'s second argument now only accepts a boolean value, which determines whether the value is escaped for a <textarea> or a regular <input> element.
+
- :doc:`Security Helper <helpers/security_helper>` changes include:
- - :php:func:`do_hash()` now uses PHP's native ``hash()`` function (supporting more algorithms) and is deprecated.
- - :php:func:`strip_image_tags()` is now an alias for the same method in the :doc:`Security Library <libraries/security>`.
+
+ - :php:func:`do_hash()` now uses PHP's native ``hash()`` function (supporting more algorithms) and is deprecated.
+ - :php:func:`strip_image_tags()` is now an alias for the same method in the :doc:`Security Library <libraries/security>`.
+
- :doc:`Smiley Helper <helpers/smiley_helper>` changes include:
- - Removed previously deprecated function ``js_insert_smiley()``.
- - Changed application and environment config files to be loaded in a cascade-like manner.
- - The smileys array is now cached and loaded only once.
+
+ - Removed previously deprecated function ``js_insert_smiley()``.
+ - Changed application and environment config files to be loaded in a cascade-like manner.
+ - The smileys array is now cached and loaded only once.
+
- :doc:`File Helper <helpers/file_helper>` changes include:
- - :php:func:`set_realpath()` can now also handle file paths as opposed to just directories.
- - Added an optional paramater to :php:func:`delete_files()` to enable it to skip deleting files such as *.htaccess* and *index.html*.
- - Deprecated function ``read_file()`` - it's just an alias for PHP's native ``file_get_contents()``.
+
+ - :php:func:`set_realpath()` can now also handle file paths as opposed to just directories.
+ - Added an optional paramater to :php:func:`delete_files()` to enable it to skip deleting files such as *.htaccess* and *index.html*.
+ - Deprecated function ``read_file()`` - it's just an alias for PHP's native ``file_get_contents()``.
+
- :doc:`String Helper <helpers/string_helper>` changes include:
- - Deprecated function ``repeater()`` - it's just an alias for PHP's native ``str_repeat()``.
- - Deprecated function ``trim_slashes()`` - it's just an alias for PHP's native ``trim()`` (with a slash as its second argument).
- - Deprecated randomization type options **unique** and **encrypt** for funcion :php:func:`random_string()` (they are only aliases for **md5** and **sha1** respectively).
+
+ - Deprecated function ``repeater()`` - it's just an alias for PHP's native ``str_repeat()``.
+ - Deprecated function ``trim_slashes()`` - it's just an alias for PHP's native ``trim()`` (with a slash as its second argument).
+ - Deprecated randomization type options **unique** and **encrypt** for funcion :php:func:`random_string()` (they are only aliases for **md5** and **sha1** respectively).
+
+ - :doc:`CAPTCHA Helper <helpers/captcha_helper>` changes include:
+
+ - Added *word_length* and *pool* options to allow customization of the generated word.
+ - Added *colors* configuration to allow customization for the *background*, *border*, *text* and *grid* colors.
+
- :doc:`Directory Helper <helpers/directory_helper>` :php:func:`directory_map()` will now append ``DIRECTORY_SEPARATOR`` to directory names in the returned array.
+ - :doc:`Array Helper <helpers/array_helper>` :php:func:`element()` and :php:func:`elements()` now return NULL instead of FALSE when the required elements don't exist.
- :doc:`Language Helper <helpers/language_helper>` :php:func:`lang()` now accepts an optional list of additional HTML attributes.
- Deprecated the :doc:`Email Helper <helpers/email_helper>` as its ``valid_email()``, ``send_email()`` functions are now only aliases for PHP native functions ``filter_var()`` and ``mail()`` respectively.
- - :doc:`CAPTCHA Helper <helpers/captcha_helper>` :php:func:`create_captcha` added word_length and pool options for setting length of randomly generated captcha word, and what characters to select from.
- Database
@@ -128,217 +155,295 @@ Release Date: Not Released
- Added support for SQLite3 database driver.
- Added Interbase/Firebird database support via the *ibase* driver.
- Added ODBC support for ``create_database()``, ``drop_database()`` and ``drop_table()`` in :doc:`Database Forge <database/forge>`.
+
- :doc:`Query Builder <database/query_builder>` changes include:
- - Renamed the Active Record class to Query Builder to remove confusion with the Active Record design pattern.
- - Added the ability to insert objects with ``insert_batch()``.
- - Added new methods that return the SQL string of queries without executing them: ``get_compiled_select()``, ``get_compiled_insert()``, ``get_compiled_update()``, ``get_compiled_delete()``.
- - Added an optional parameter that allows to disable escaping (useful for custom fields) for methods ``join()``, ``order_by()``, ``where_in()``, ``or_where_in()``, ``where_not_in()``, ``or_where_not_in()``, ``insert()``, ``insert_batch()``.
- - Added support for ``join()`` with multiple conditions.
- - Added support for *USING* in ``join()``.
- - Added seed values support for random ordering with ``order_by(seed, 'RANDOM')``.
- - Changed ``limit()`` to ignore NULL values instead of always casting to integer.
- - Changed ``offset()`` to ignore empty values instead of always casting to integer.
- - Methods ``insert_batch()`` and ``update_batch()`` now return an integer representing the number of rows affected by them.
+
+ - Renamed the Active Record class to Query Builder to remove confusion with the Active Record design pattern.
+ - Added the ability to insert objects with ``insert_batch()``.
+ - Added new methods that return the SQL string of queries without executing them: ``get_compiled_select()``, ``get_compiled_insert()``, ``get_compiled_update()``, ``get_compiled_delete()``.
+ - Added an optional parameter that allows to disable escaping (useful for custom fields) for methods ``join()``, ``order_by()``, ``where_in()``, ``or_where_in()``, ``where_not_in()``, ``or_where_not_in()``, ``insert()``, ``insert_batch()``.
+ - Added support for ``join()`` with multiple conditions.
+ - Added support for *USING* in ``join()``.
+ - Added seed values support for random ordering with ``order_by(seed, 'RANDOM')``.
+ - Changed ``limit()`` to ignore NULL values instead of always casting to integer.
+ - Changed ``offset()`` to ignore empty values instead of always casting to integer.
+ - Methods ``insert_batch()`` and ``update_batch()`` now return an integer representing the number of rows affected by them.
+
- :doc:`Database Results <database/results>` changes include:
- - Added a constructor to the ``DB_result`` class and moved all driver-specific properties and logic out of the base ``DB_driver`` class to allow better abstraction.
- - Added method ``unbuffered_row()`` for fetching a row without prefetching the whole result (consume less memory).
- - Renamed former method ``_data_seek()`` to ``data_seek()`` and made it public.
+
+ - Added a constructor to the ``DB_result`` class and moved all driver-specific properties and logic out of the base ``DB_driver`` class to allow better abstraction.
+ - Added method ``unbuffered_row()`` for fetching a row without prefetching the whole result (consume less memory).
+ - Renamed former method ``_data_seek()`` to ``data_seek()`` and made it public.
+
- Improved support for the MySQLi driver, including:
- - OOP style of the PHP extension is now used, instead of the procedural aliases.
- - Server version checking is now done via ``mysqli::$server_info`` instead of running an SQL query.
- - Added persistent connections support for PHP >= 5.3.
- - Added support for ``backup()`` in :doc:`Database Utilities <database/utilities>`.
+
+ - OOP style of the PHP extension is now used, instead of the procedural aliases.
+ - Server version checking is now done via ``mysqli::$server_info`` instead of running an SQL query.
+ - Added persistent connections support for PHP >= 5.3.
+ - Added support for ``backup()`` in :doc:`Database Utilities <database/utilities>`.
+ - Changed methods ``trans_begin()``, ``trans_commit()`` and ``trans_rollback()`` to use the PHP API instead of sending queries.
+
- Improved support of the PDO driver, including:
- - Added support for ``create_database()``, ``drop_database()`` and ``drop_table()`` in :doc:`Database Forge <database/forge>`.
- - Added support for ``list_fields()`` in :doc:`Database Results <database/results>`.
- - Subdrivers are now isolated from each other instead of being in one large class.
+
+ - Added support for ``create_database()``, ``drop_database()`` and ``drop_table()`` in :doc:`Database Forge <database/forge>`.
+ - Added support for ``list_fields()`` in :doc:`Database Results <database/results>`.
+ - Subdrivers are now isolated from each other instead of being in one large class.
+
- Improved support of the PostgreSQL driver, including:
- - ``pg_version()`` is now used to get the database version number, when possible.
- - Added ``db_set_charset()`` support.
- - Added support for ``optimize_table()`` in :doc:`Database Utilities <database/utilities>` (rebuilds table indexes).
- - Added boolean data type support in ``escape()``.
- - Added ``update_batch()`` support.
- - Removed ``limit()`` and ``order_by()`` support for *UPDATE* and *DELETE* queries as PostgreSQL does not support those features.
- - Added a work-around for dead persistent connections to be re-created after a database restart.
- - Changed ``db_connect()`` to include the (new) **schema** value into Postgre's **search_path** session variable.
+
+ - ``pg_version()`` is now used to get the database version number, when possible.
+ - Added ``db_set_charset()`` support.
+ - Added support for ``optimize_table()`` in :doc:`Database Utilities <database/utilities>` (rebuilds table indexes).
+ - Added boolean data type support in ``escape()``.
+ - Added ``update_batch()`` support.
+ - Removed ``limit()`` and ``order_by()`` support for *UPDATE* and *DELETE* queries as PostgreSQL does not support those features.
+ - Added a work-around for dead persistent connections to be re-created after a database restart.
+ - Changed ``db_connect()`` to include the (new) **schema** value into Postgre's **search_path** session variable.
+ - ``pg_escape_literal()`` is now used for escaping strings, if available.
+
- Improved support of the CUBRID driver, including:
- - Added DSN string support.
- - Added persistent connections support.
- - Improved ``list_databases()`` in :doc:`Database Utility <database/utilities>` (until now only the currently used database was returned).
+
+ - Added DSN string support.
+ - Added persistent connections support.
+ - Improved ``list_databases()`` in :doc:`Database Utility <database/utilities>` (until now only the currently used database was returned).
+
- Improved support of the MSSQL and SQLSRV drivers, including:
- - Added random ordering support.
- - Added support for ``optimize_table()`` in :doc:`Database Utility <database/utilities>`.
- - Added escaping with *QUOTE_IDENTIFIER* setting detection.
- - Added port handling support for UNIX-based systems (MSSQL driver).
- - Added *OFFSET* support for SQL Server 2005 and above.
- - Added ``db_set_charset()`` support (MSSQL driver).
+
+ - Added random ordering support.
+ - Added support for ``optimize_table()`` in :doc:`Database Utility <database/utilities>`.
+ - Added escaping with *QUOTE_IDENTIFIER* setting detection.
+ - Added port handling support for UNIX-based systems (MSSQL driver).
+ - Added *OFFSET* support for SQL Server 2005 and above.
+ - Added ``db_set_charset()`` support (MSSQL driver).
+
- Improved support of the Oracle (OCI8) driver, including:
- - Added DSN string support (Easy Connect and TNS).
- - Added support for ``drop_table()`` in :doc:`Database Forge <database/forge>`.
- - Added support for ``list_databases()`` in :doc:`Database Utilities <database/utilities>`.
- - Generally improved for speed and cleaned up all of its components.
- - ``num_rows()`` is now only called explicitly by the developer and no longer re-executes statements.
+
+ - Added DSN string support (Easy Connect and TNS).
+ - Added support for ``drop_table()`` in :doc:`Database Forge <database/forge>`.
+ - Added support for ``list_databases()`` in :doc:`Database Utilities <database/utilities>`.
+ - Generally improved for speed and cleaned up all of its components.
+ - ``num_rows()`` is now only called explicitly by the developer and no longer re-executes statements.
+
- Improved support of the SQLite driver, including:
- - Added support for ``replace()`` in :doc:`Query Builder <database/query_builder>`.
- - Added support for ``drop_table()`` in :doc:`Database Forge <database/forge>`.
+
+ - Added support for ``replace()`` in :doc:`Query Builder <database/query_builder>`.
+ - Added support for ``drop_table()`` in :doc:`Database Forge <database/forge>`.
+
- :doc:`Database Forge <database/forge>` changes include:
- - Added an optional second parameter to ``drop_table()`` that allows adding the **IF EXISTS** condition, which is no longer the default.
- - Added support for passing a custom database object to the loader.
- - Deprecated ``add_column()``'s third method. *AFTER* clause should now be added to the field definition array instead.
- - Added support for usage of the *FIRST* clause in ``add_column()`` for MySQL and CUBRID.
- - Overall improved support for all of the drivers.
+
+ - Added an optional second parameter to ``drop_table()`` that allows adding the **IF EXISTS** condition, which is no longer the default.
+ - Added support for passing a custom database object to the loader.
+ - Deprecated ``add_column()``'s third method. *AFTER* clause should now be added to the field definition array instead.
+ - Added support for usage of the *FIRST* clause in ``add_column()`` for MySQL and CUBRID.
+ - Overall improved support for all of the drivers.
+
- :doc:`Database Utility <database/utilities>` changes include:
- - Added support for passing a custom database object to the loader.
- - Modified the class to no longer extend :doc:`Database Forge <database/forge>`, which has been a deprecated behavior for awhile.
- - Overall improved support for all of the drivers.
- - Added *foreign_key_checks* option to MySQL/MySQLi backup, allowing statement to disable/re-enable foreign key checks to be inserted into the backup output.
+
+ - Added support for passing a custom database object to the loader.
+ - Modified the class to no longer extend :doc:`Database Forge <database/forge>`, which has been a deprecated behavior for awhile.
+ - Overall improved support for all of the drivers.
+ - Added *foreign_key_checks* option to MySQL/MySQLi backup, allowing statement to disable/re-enable foreign key checks to be inserted into the backup output.
- Libraries
- :doc:`Session Library <libraries/sessions>` changes include:
- - Library changed to :doc:`Driver <general/drivers>` with classic Cookie driver as default.
- - Added Native PHP Session driver to work with ``$_SESSION``.
- - Custom drivers can be added anywhere in package paths and be loaded with the library.
- - Drivers interchangeable on the fly.
- - New **tempdata** feature allows setting user data items with an expiration time.
- - Added default ``$config['sess_driver']`` and ``$config['sess_valid_drivers']`` items to *config.php* file.
- - Cookie driver now respects php.ini's *session.gc_probability* and *session.gc_divisor* settings.
- - Cookie driver now uses HMAC authentication instead of the simple md5 checksum.
- - The Cookie driver now also checks authentication on encrypted session data.
- - Changed the Cookie driver to select only one row when using database sessions.
- - Cookie driver now only writes to database at end of request when using database.
- - Cookie driver now uses PHP functions for faster array manipulation when using database.
- - Added ``all_flashdata()`` method to session class. Returns an associative array of only flashdata.
- - Added ``has_userdata()`` method to verify existence of userdata item.
- - Added ``tempdata()``, ``set_tempdata()``, and ``unset_tempdata()`` methods for manipulating tempdata.
- - ``keep_flashdata()`` now accepts an array of keys.
+
+ - Library changed to :doc:`Driver <general/drivers>` with classic Cookie driver as default.
+ - Added Native PHP Session driver to work with ``$_SESSION``.
+ - Custom drivers can be added anywhere in package paths and be loaded with the library.
+ - Drivers interchangeable on the fly.
+ - New **tempdata** feature allows setting user data items with an expiration time.
+ - Added default ``$config['sess_driver']`` and ``$config['sess_valid_drivers']`` items to *config.php* file.
+ - Cookie driver now respects php.ini's *session.gc_probability* and *session.gc_divisor* settings.
+ - Cookie driver now uses HMAC authentication instead of the simple md5 checksum.
+ - The Cookie driver now also checks authentication on encrypted session data.
+ - Changed the Cookie driver to select only one row when using database sessions.
+ - Cookie driver now only writes to database at end of request when using database.
+ - Cookie driver now uses PHP functions for faster array manipulation when using database.
+ - Added ``all_flashdata()`` method to session class. Returns an associative array of only flashdata.
+ - Added ``has_userdata()`` method to verify existence of userdata item.
+ - Added ``tempdata()``, ``set_tempdata()``, and ``unset_tempdata()`` methods for manipulating tempdata.
+ - ``keep_flashdata()`` now accepts an array of keys.
+ - Added *debug* level log messages for key events in the session validation process.
+
- :doc:`File Uploading Library <libraries/file_uploading>` changes include:
- - Added **max_filename_increment** config setting.
- - Added an **index** parameter to the ``data()`` method.
- - Added the **min_width** and **min_height** options for images.
- - Removed method ``clean_file_name()`` and its usage in favor of :doc:`Security Library <libraries/security>`'s ``sanitize_filename()``.
- - Added **file_ext_tolower** config setting.
+
+ - Added **max_filename_increment** config setting.
+ - Added an **index** parameter to the ``data()`` method.
+ - Added the **min_width** and **min_height** options for images.
+ - Removed method ``clean_file_name()`` and its usage in favor of :doc:`Security Library <libraries/security>`'s ``sanitize_filename()``.
+ - Added **file_ext_tolower** config setting.
+
- :doc:`Cart library <libraries/cart>` changes include:
- - ``insert()`` now auto-increments quantity for an item when inserted twice instead of resetting it, this is the default behaviour of large e-commerce sites.
- - *Product Name* strictness can be disabled by switching the ``$product_name_safe`` property to FALSE.
- - Added method ``remove()`` to remove a cart item, updating with quantity of 0 seemed like a hack but has remained to retain compatibility.
- - Added method ``get_item()`` to enable retrieving data for a single cart item.
- - Added unicode support for product names.
+
+ - ``insert()`` now auto-increments quantity for an item when inserted twice instead of resetting it, this is the default behaviour of large e-commerce sites.
+ - *Product Name* strictness can be disabled by switching the ``$product_name_safe`` property to FALSE.
+ - Added method ``remove()`` to remove a cart item, updating with quantity of 0 seemed like a hack but has remained to retain compatibility.
+ - Added method ``get_item()`` to enable retrieving data for a single cart item.
+ - Added unicode support for product names.
+
- :doc:`Image Manipulation library <libraries/image_lib>` changes include:
- - The ``initialize()`` method now only sets existing class properties.
- - Added support for 3-length hex color values for *wm_font_color* and *wm_shadow_color* properties, as well as validation for them.
- - Class properties *wm_font_color*, *wm_shadow_color* and *wm_use_drop_shadow* are now protected, to avoid breaking the ``text_watermark()`` method if they are set manually after initialization.
- - If property *maintain_ratio* is set to TRUE, ``image_reproportion()`` now doesn't need both width and height to be specified.
- - Property *maintain_ratio* is now taken into account when resizing images using ImageMagick library.
- - Added support for maintaining transparency for PNG images in method ``text_watermark()``.
+
+ - The ``initialize()`` method now only sets existing class properties.
+ - Added support for 3-length hex color values for *wm_font_color* and *wm_shadow_color* properties, as well as validation for them.
+ - Class properties *wm_font_color*, *wm_shadow_color* and *wm_use_drop_shadow* are now protected, to avoid breaking the ``text_watermark()`` method if they are set manually after initialization.
+ - If property *maintain_ratio* is set to TRUE, ``image_reproportion()`` now doesn't need both width and height to be specified.
+ - Property *maintain_ratio* is now taken into account when resizing images using ImageMagick library.
+ - Added support for maintaining transparency for PNG images in method ``text_watermark()``.
+
- :doc:`Form Validation library <libraries/form_validation>` changes include:
- - Added method ``error_array()`` to return all error messages as an array.
- - Added method ``set_data()`` to set an alternative data array to be validated instead of the default ``$_POST``.
- - Added method ``reset_validation()`` which resets internal validation variables in case of multiple validation routines.
- - Added support for setting error delimiters in the config file via ``$config['error_prefix']`` and ``$config['error_suffix']``.
- - Internal method ``_execute()`` now considers input data to be invalid if a specified rule is not found.
- - Removed method ``is_numeric()`` as it exists as a native PHP function and ``_execute()`` will find and use that (the **is_numeric** rule itself is deprecated since 1.6.1).
- - Native PHP functions used as rules can now accept an additional parameter, other than the data itself.
- - Updated method ``set_rules()`` to accept an array of rules as well as a string.
- - Fields that have empty rules set no longer run through validation (and therefore are not considered erroneous).
- - Added rule **differs** to check if the value of a field differs from the value of another field.
- - Added rule **valid_url**.
- - Added support for named parameters in error messages.
- - :doc:`Language <libraries/language>` line keys must now be prefixed with **form_validation_**.
- - Added rule **alpha_numeric_spaces**.
- - Added support for setting :doc:`Table <libraries/table>` class defaults in a config file.
+
+ - Added method ``error_array()`` to return all error messages as an array.
+ - Added method ``set_data()`` to set an alternative data array to be validated instead of the default ``$_POST``.
+ - Added method ``reset_validation()`` which resets internal validation variables in case of multiple validation routines.
+ - Added support for setting error delimiters in the config file via ``$config['error_prefix']`` and ``$config['error_suffix']``.
+ - Internal method ``_execute()`` now considers input data to be invalid if a specified rule is not found.
+ - Removed method ``is_numeric()`` as it exists as a native PHP function and ``_execute()`` will find and use that (the **is_numeric** rule itself is deprecated since 1.6.1).
+ - Native PHP functions used as rules can now accept an additional parameter, other than the data itself.
+ - Updated method ``set_rules()`` to accept an array of rules as well as a string.
+ - Fields that have empty rules set no longer run through validation (and therefore are not considered erroneous).
+ - Added rule **differs** to check if the value of a field differs from the value of another field.
+ - Added rule **valid_url**.
+ - Added support for named parameters in error messages.
+ - :doc:`Language <libraries/language>` line keys must now be prefixed with **form_validation_**.
+ - Added rule **alpha_numeric_spaces**.
+
- :doc:`Caching Library <libraries/caching>` changes include:
- - Added Wincache driver.
- - Added Redis driver.
- - Added a *key_prefix* option for cache IDs.
+
+ - Added Wincache driver.
+ - Added Redis driver.
+ - Added a *key_prefix* option for cache IDs.
+ - Updated driver ``is_supported()`` methods to log at the "debug" level.
+
- :doc:`Email library <libraries/email>` changes include:
- - Added custom filename to ``Email::attach()`` as ``$this->email->attach($filename, $disposition, $newname)``.
- - Added possibility to send attachment as buffer string in ``Email::attach()`` as ``$this->email->attach($buffer, $disposition, $newname, $mime)``.
- - Added dsn (delivery status notification) option.
- - Renamed method _set_header() to set_header() and made it public to enable adding custom headers in the :doc:`Email Library <libraries/email>`.
- - Successfully sent emails will automatically clear the parameters.
- - Added a *return_path* parameter to the ``from()`` method.
- - Removed the second parameter (character limit) from internal method ``_prep_quoted_printable()`` as it is never used.
- - Internal method ``_prep_quoted_printable()`` will now utilize the native ``quoted_printable_encode()``, ``imap_8bit()`` functions (if available) when CRLF is set to "\r\n".
- - Default charset now relies on the global ``$config['charset']`` setting.
- - Removed unused protected method ``_get_ip()`` (:doc:`Input Library <libraries/input>`'s ``ip_address()`` should be used anyway).
- - Internal method ``_prep_q_encoding()`` now utilizes PHP's *mbstring* and *iconv* extensions (when available) and no longer has a second (``$from``) argument.
- - Added an optional parameter to ``print_debugger()`` to allow specifying which parts of the message should be printed ('headers', 'subject', 'body').
- - Added SMTP keepalive option to avoid opening the connection for each ``Email::send()``. Accessible as ``$smtp_keepalive``.
- - Public method ``set_header()`` now filters the input by removing all "\\r" and "\\n" characters.
+
+ - Added custom filename to ``Email::attach()`` as ``$this->email->attach($filename, $disposition, $newname)``.
+ - Added possibility to send attachment as buffer string in ``Email::attach()`` as ``$this->email->attach($buffer, $disposition, $newname, $mime)``.
+ - Added dsn (delivery status notification) option.
+ - Renamed method _set_header() to set_header() and made it public to enable adding custom headers in the :doc:`Email Library <libraries/email>`.
+ - Successfully sent emails will automatically clear the parameters.
+ - Added a *return_path* parameter to the ``from()`` method.
+ - Removed the second parameter (character limit) from internal method ``_prep_quoted_printable()`` as it is never used.
+ - Internal method ``_prep_quoted_printable()`` will now utilize the native ``quoted_printable_encode()``, ``imap_8bit()`` functions (if available) when CRLF is set to "\r\n".
+ - Default charset now relies on the global ``$config['charset']`` setting.
+ - Removed unused protected method ``_get_ip()`` (:doc:`Input Library <libraries/input>`'s ``ip_address()`` should be used anyway).
+ - Internal method ``_prep_q_encoding()`` now utilizes PHP's *mbstring* and *iconv* extensions (when available) and no longer has a second (``$from``) argument.
+ - Added an optional parameter to ``print_debugger()`` to allow specifying which parts of the message should be printed ('headers', 'subject', 'body').
+ - Added SMTP keepalive option to avoid opening the connection for each ``Email::send()``. Accessible as ``$smtp_keepalive``.
+ - Public method ``set_header()`` now filters the input by removing all "\\r" and "\\n" characters.
+
- :doc:`Pagination Library <libraries/pagination>` changes include:
- - Added support for the anchor "rel" attribute.
- - Added support for setting custom attributes.
- - Deprecated usage of the "anchor_class" setting (use the new "attributes" setting instead).
- - Added $config['reuse_query_string'] to allow automatic repopulation of query string arguments, combined with normal URI segments.
- - Removed the default ``&nbsp;`` from a number of the configuration variables.
- - Added the ability to use a proxy with the :doc:`XML-RPC Library <libraries/xmlrpc>`.
+
+ - Added support for the anchor "rel" attribute.
+ - Added support for setting custom attributes.
+ - Deprecated usage of the "anchor_class" setting (use the new "attributes" setting instead).
+ - Added $config['reuse_query_string'] to allow automatic repopulation of query string arguments, combined with normal URI segments.
+ - Removed the default ``&nbsp;`` from a number of the configuration variables.
+ - Added the ability to use a proxy with the :doc:`XML-RPC Library <libraries/xmlrpc>`.
+
- :doc:`Encryption Library <libraries/encryption>` changes include:
- - Added support for hashing algorithms other than SHA1 and MD5.
- - Removed previously deprecated ``sha1()`` method.
+
+ - Added support for hashing algorithms other than SHA1 and MD5.
+ - Removed previously deprecated ``sha1()`` method.
+
- :doc:`Profiler Library <general/profiling>` changes include:
- - Database object names are now being displayed.
- - The sum of all queries running times in seconds is now being displayed.
+
+ - Database object names are now being displayed.
+ - The sum of all queries running times in seconds is now being displayed.
+ - Added support for displaying the HTTP DNT ("Do Not Track") header.
+ - Added support for displaying $_FILES.
+
- :doc:`Migration Library <libraries/migration>` changes include:
- - Added support for timestamp-based migrations (enabled by default).
- - Added ``$config['migration_type']`` to allow switching between *sequential* and *timestamp* migrations.
+
+ - Added support for timestamp-based migrations (enabled by default).
+ - Added ``$config['migration_type']`` to allow switching between *sequential* and *timestamp* migrations.
+
- :doc:`User Agent Library <libraries/user_agent>` will now check if robots are pretending to be mobile clients (helps with e.g. Google indexing mobile website versions).
+ - Added support for setting :doc:`Table <libraries/table>` class defaults in a config file.
- Core
- :doc:`URI Library <libraries/uri>` changes include:
- - Changed private methods to protected so that MY_URI can override them.
- - Renamed internal method ``_parse_cli_args()`` to ``_parse_argv()``.
- - Renamed internal method ``_detect_uri()`` to ``_parse_request_uri()``.
- - Changed ``_parse_request_uri()`` to accept absolute URIs for compatibility with HTTP/1.1 as per `RFC2616 <http://www.ietf.org/rfc/rfc2616.txt>`.
- - Added protected method ``_parse_query_string()`` to URI paths in the the **QUERY_STRING** value, like ``_parse_request_uri()`` does.
- - Changed ``_fetch_uri_string()`` to try the **PATH_INFO** variable first when auto-detecting.
- - Removed ``CI_CORE`` boolean constant from *CodeIgniter.php* (no longer Reactor and Core versions).
+
+ - Changed private methods to protected so that MY_URI can override them.
+ - Renamed internal method ``_parse_cli_args()`` to ``_parse_argv()``.
+ - Renamed internal method ``_detect_uri()`` to ``_parse_request_uri()``.
+ - Changed ``_parse_request_uri()`` to accept absolute URIs for compatibility with HTTP/1.1 as per `RFC2616 <http://www.ietf.org/rfc/rfc2616.txt>`.
+ - Added protected method ``_parse_query_string()`` to URI paths in the the **QUERY_STRING** value, like ``_parse_request_uri()`` does.
+ - Changed ``_fetch_uri_string()`` to try the **PATH_INFO** variable first when auto-detecting.
+
- :doc:`Loader Library <libraries/loader>` changes include:
- - Added method ``get_vars()`` to the Loader to retrieve all variables loaded with ``$this->load->vars()``.
- - ``_ci_autoloader()`` is now a protected method.
- - Added autoloading of drivers with ``$autoload['drivers']``.
- - ``$config['rewrite_short_tags']`` now has no effect when using PHP 5.4 as ``<?=`` will always be available.
- - Changed method ``config()`` to return whatever ``CI_Config::load()`` returns instead of always being void.
- - Added support for model aliasing on autoload.
+
+ - Added method ``get_vars()`` to the Loader to retrieve all variables loaded with ``$this->load->vars()``.
+ - ``_ci_autoloader()`` is now a protected method.
+ - Added autoloading of drivers with ``$autoload['drivers']``.
+ - ``$config['rewrite_short_tags']`` now has no effect when using PHP 5.4 as ``<?=`` will always be available.
+ - Changed method ``config()`` to return whatever ``CI_Config::load()`` returns instead of always being void.
+ - Added support for model aliasing on autoload.
+ - Changed method ``is_loaded()`` to ask for the (case sensitive) library name instead of its instance name.
+ - Removed ``$_base_classes`` property and unified all class data in ``$_ci_classes`` instead.
+ - Added method ``clear_vars()`` to allow clearing the cached variables for views.
+
- :doc:`Input Library <libraries/input>` changes include:
- - Added ``method()`` to retrieve ``$_SERVER['REQUEST_METHOD']``.
- - Added support for arrays and network addresses (e.g. 192.168.1.1/24) for use with the *proxy_ips* setting.
- - Added method ``input_stream()`` to aid in using **php://input** stream data such as one passed via PUT, DELETE and PATCH requests.
- - Changed method ``valid_ip()`` to use PHP's native ``filter_var()`` function.
- - Changed internal method ``_sanitize_globals()`` to skip enforcing reversal of *register_globals* in PHP 5.4+, where this functionality no longer exists.
- - Changed methods ``get()``, ``post()``, ``get_post()``, ``cookie()``, ``server()``, ``user_agent()`` to return NULL instead of FALSE when no value is found.
- - Changed method ``_fetch_from_array()`` to parse array notation in field name.
+
+ - Added ``method()`` to retrieve ``$_SERVER['REQUEST_METHOD']``.
+ - Added support for arrays and network addresses (e.g. 192.168.1.1/24) for use with the *proxy_ips* setting.
+ - Added method ``input_stream()`` to aid in using **php://input** stream data such as one passed via PUT, DELETE and PATCH requests.
+ - Changed method ``valid_ip()`` to use PHP's native ``filter_var()`` function.
+ - Changed internal method ``_sanitize_globals()`` to skip enforcing reversal of *register_globals* in PHP 5.4+, where this functionality no longer exists.
+ - Changed methods ``get()``, ``post()``, ``get_post()``, ``cookie()``, ``server()``, ``user_agent()`` to return NULL instead of FALSE when no value is found.
+ - Added method ``post_get()`` and changed ``get_post()`` to search in GET data first. Both methods' names now properly match their GET/POST data search priorities.
+ - Changed method ``_fetch_from_array()`` to parse array notation in field name.
+ - Added an option for ``_clean_input_keys()`` to return FALSE instead of terminating the whole script.
+
- :doc:`Common functions <general/common_functions>` changes include:
- - Added function :php:func:`get_mimes()` to return the *application/config/mimes.php* array.
- - Added support for HTTP code 303 ("See Other") in :php:func:`set_status_header()`.
- - Removed redundant conditional to determine HTTP server protocol in :php:func:`set_status_header()`.
- - Changed ``_exception_handler()`` to respect php.ini *display_errors* setting.
- - Added function :php:func:`is_https()` to check if a secure connection is used.
- - Added function :php:func:`function_usable()` to check if a function exists and is not disabled by `Suhosin <http://www.hardened-php.net/suhosin/>`.
- - Added support for HTTP-Only cookies with new config option *cookie_httponly* (default FALSE).
- - Renamed method ``_call_hook()`` to ``call_hook()`` in the :doc:`Hooks Library <general/hooks>`.
+
+ - Added function :php:func:`get_mimes()` to return the *application/config/mimes.php* array.
+ - Added support for HTTP code 303 ("See Other") in :php:func:`set_status_header()`.
+ - Removed redundant conditional to determine HTTP server protocol in :php:func:`set_status_header()`.
+ - Changed ``_exception_handler()`` to respect php.ini *display_errors* setting.
+ - Added function :php:func:`is_https()` to check if a secure connection is used.
+ - Added function :php:func:`function_usable()` to check if a function exists and is not disabled by `Suhosin <http://www.hardened-php.net/suhosin/>`.
+ - Removed the third (`$php_error`) from function :php:func:`log_message()`.
+
- :doc:`Output Library <libraries/output>` changes include:
- - Added a second argument to method ``set_content_type()`` that allows setting the document charset as well.
- - Added methods ``get_content_type()`` and ``get_header()``.
- - Added method ``delete_cache()``.
- - ``$config['time_reference']`` now supports all timezone strings supported by PHP.
+
+ - Added a second argument to method ``set_content_type()`` that allows setting the document charset as well.
+ - Added methods ``get_content_type()`` and ``get_header()``.
+ - Added method ``delete_cache()``.
+
- :doc:`Config Library <libraries/config>` changes include:
- - Changed ``site_url()`` method to accept an array as well.
- - Removed internal method ``_assign_to_config()`` and moved it's implementation in *CodeIgniter.php* instead.
+
+ - Changed ``site_url()`` method to accept an array as well.
+ - Removed internal method ``_assign_to_config()`` and moved its implementation to *CodeIgniter.php* instead.
+ - ``item()`` now returns NULL instead of FALSE when the required config item doesn't exist.
+
- :doc:`Security Library <libraries/security>` changes include:
- - Added method ``strip_image_tags()``.
- - Added ``$config['csrf_regeneration']``, which makes token regeneration optional.
- - Added ``$config['csrf_exclude_uris']``, which allows you list URIs which will not have the CSRF validation methods run.
+
+ - Added method ``strip_image_tags()``.
+ - Added ``$config['csrf_regeneration']``, which makes token regeneration optional.
+ - Added ``$config['csrf_exclude_uris']``, which allows you list URIs which will not have the CSRF validation methods run.
+ - Modified method ``sanitize_filename()`` to read a public ``$filename_bad_chars`` property for getting the invalid characters list.
+
- :doc:`URI Routing <general/routing>` changes include:
- - Added possibility to route requests using callbacks.
- - Added possibility to use dashes in the controller and method URI segments (translated to underscores).
- - Deprecated methods ``fetch_directory()``, ``fetch_class()`` and ``fetch_method()`` in favor of their respective public properties.
+
+ - Added possibility to route requests using callbacks.
+ - Added a new reserved route (*translate_uri_dashes*) to allow usage of dashes in the controller and method URI segments.
+ - Deprecated methods ``fetch_directory()``, ``fetch_class()`` and ``fetch_method()`` in favor of their respective public properties.
+
- :doc:`Language Library <libraries/language>` changes include:
- - Changed method ``load()`` to filter the language name with ``ctype_digit()``.
- - Added an optional second parameter to method ``line()`` to disable error login for line keys that were not found.
- - Language files are now loaded in a cascading style with the one in **system/** always loaded and overriden afterwards, if another one is found.
+
+ - Changed method ``load()`` to filter the language name with ``ctype_digit()``.
+ - Added an optional second parameter to method ``line()`` to disable error login for line keys that were not found.
+ - Language files are now loaded in a cascading style with the one in **system/** always loaded and overriden afterwards, if another one is found.
+
+ - Removed ``CI_CORE`` boolean constant from *CodeIgniter.php* (no longer Reactor and Core versions).
- Log Library will now try to create the **log_path** directory if it doesn't exist.
+ - Added support for HTTP-Only cookies with new config option *cookie_httponly* (default FALSE).
+ - Renamed method ``_call_hook()`` to ``call_hook()`` in the :doc:`Hooks Library <general/hooks>`.
+ - ``$config['time_reference']`` now supports all timezone strings supported by PHP.
+ - Fatal PHP errors are now also passed to ``_exception_handler()``, so they can be logged.
+
Bug fixes for 3.0
------------------
@@ -366,7 +471,7 @@ Bug fixes for 3.0
- Fixed a possible bug in ``CI_Input::is_ajax_request()`` where some clients might not send the X-Requested-With HTTP header value exactly as 'XmlHttpRequest'.
- Fixed a bug (#1039) - MySQL's _backup() method failed due to a table name not being escaped.
- Fixed a bug (#1070) - CI_DB_driver::initialize() didn't set a character set if a database is not selected.
-- Fixed a bug (#177) - CI_Form_validation::set_value() didn't set the default value if POST data is NULL.
+- Fixed a bug (#177) - ``CI_Form_validation::set_value()`` didn't set the default value if POST data is NULL.
- Fixed a bug (#68, #414) - Oracle's escape_str() didn't properly escape LIKE wild characters.
- Fixed a bug (#81) - ODBC's list_fields() and field_data() methods skipped the first column due to odbc_field_*() functions' index starting at 1 instead of 0.
- Fixed a bug (#129) - ODBC's num_rows() returned -1 in some cases, due to not all subdrivers supporting the odbc_num_rows() function.
@@ -393,7 +498,7 @@ Bug fixes for 3.0
- Fixed a bug (#23, #1238) - delete_all() in the `Database Caching Library <database/caching>` used to delete .htaccess and index.html files, which is a potential security risk.
- Fixed a bug in :doc:`Trackback Library <libraries/trackback>` method validate_url() where it didn't actually do anything, due to input not being passed by reference.
- Fixed a bug (#11, #183, #863) - CI_Form_validation::_execute() silently continued to the next rule, if a rule method/function is not found.
-- Fixed a bug (#122) Where routed uri string was being reported incorrectly in sub-directories.
+- Fixed a bug (#122) - routed URI string was being reported incorrectly in sub-directories.
- Fixed a bug (#1242) - read_dir() in the :doc:`Zip Library <libraries/zip>` wasn't compatible with Windows.
- Fixed a bug (#306) - ODBC driver didn't have an _insert_batch() method, which resulted in fatal error being triggered when insert_batch() is used with it.
- Fixed a bug in MSSQL and SQLSrv's _truncate() where the TABLE keyword was missing.
@@ -418,7 +523,7 @@ Bug fixes for 3.0
- Fixed a bug (#784, #861) - :doc:`Database Forge <database/forge>` method ``create_table()`` used to accept constraints for MSSQL/SQLSRV integer-type columns.
- Fixed a bug (#706) - SQLSRV/MSSSQL didn't escape field names.
- Fixed a bug (#1452) - ``protect_identifiers()`` didn't properly detect identifiers with spaces in their names.
-- Fixed a bug where ``protect_identifiers()`` ignored it's extra arguments when the value passed to it is an array.
+- Fixed a bug where ``protect_identifiers()`` ignored its extra arguments when the value passed to it is an array.
- Fixed a bug where ``_has_operator()`` didn't detect BETWEEN.
- Fixed a bug in :doc:`Query Builder <database/query_builder>`'s ``join()`` method where it failed with identifiers containing dashes.
- Fixed a bug (#1264) - :doc:`Database Forge <database/forge>` and :doc:`Database Utilities <database/utilities>` didn't update/reset the databases and tables list cache when a table or a database is created, dropped or renamed.
@@ -458,7 +563,7 @@ Bug fixes for 3.0
- Fixed a bug where the :doc:`Session Library <libraries/sessions>` accepted cookies with *last_activity* values being in the future.
- Fixed a bug (#1897) - :doc:`Email Library <libraries/email>` triggered PHP E_WARNING errors when *mail* protocol used and ``to()`` is never called.
- Fixed a bug (#1409) - :doc:`Email Library <libraries/email>` didn't properly handle multibyte characters when applying Q-encoding to headers.
-- Fixed a bug where :doc:`Email Library <libraries/email>` didn't honor it's *wordwrap* setting while handling alternative messages.
+- Fixed a bug where :doc:`Email Library <libraries/email>` didn't honor its *wordwrap* setting while handling alternative messages.
- Fixed a bug (#1476, #1909) - :doc:`Pagination Library <libraries/pagination>` didn't take into account actual routing when determining the current page.
- Fixed a bug (#1766) - :doc:`Query Builder <database/query_builder>` didn't always take into account the *dbprefix* setting.
- Fixed a bug (#779) - :doc:`URI Class <libraries/uri>` didn't always trim slashes from the *uri_string* as shown in the documentation.
@@ -494,14 +599,45 @@ Bug fixes for 3.0
- Fixed a bug (#2239) - :doc:`Email Library <libraries/email>` improperly handled the Subject when used with ``bcc_batch_mode`` resulting in E_WARNING messages and an empty Subject.
- Fixed a bug (#2234) - :doc:`Query Builder <database/query_builder>` didn't reset JOIN cache for write-type queries.
- Fixed a bug (#2298) - :doc:`Database Results <database/results>` method ``next_row()`` kept returning the last row, allowing for infinite loops.
-- Fixed a bug (#2236) - :doc:`Form Helper <helpers/form_helper>` function ``set_value()`` didn't parse array notation for keys if the rule was not present in the :doc:`Form Validation Library <libraries/form_validation>`.
+- Fixed a bug (#2236, #2639) - :doc:`Form Helper <helpers/form_helper>` functions :func:`set_value()`, :func:`set_select()`, :func:`set_radio()`, :func:`set_checkbox()` didn't parse array notation for keys if the rule was not present in the :doc:`Form Validation Library <libraries/form_validation>`.
- Fixed a bug (#2353) - :doc:`Query Builder <database/query_builder>` erroneously prefixed literal strings with **dbprefix**.
- Fixed a bug (#78) - :doc:`Cart Library <libraries/cart>` didn't allow non-English letters in product names.
- Fixed a bug (#77) - :doc:`Database Class <database/index>` didn't properly handle the transaction "test mode" flag.
- Fixed a bug (#2380) - :doc:`URI Routing <general/routing>` method ``fetch_method()`` returned 'index' if the requested method name matches its controller name.
- Fixed a bug (#2388) - :doc:`Email Library <libraries/email>` used to ignore attachment errors, resulting in broken emails being sent.
- Fixed a bug (#2498) - :doc:`Form Validation Library <libraries/form_validation>` rule **valid_base64** only checked characters instead of actual validity.
-- Fixed a bug (#2515) - The script now halts when a fatal error occurs, instead of continuing.
+- Fixed a bug (#2425) - OCI8 :doc:`database <database>` driver's method ``stored_procedure()`` didn't log an error unless **db_debug** was set to TRUE.
+- Fixed a bug (#2490) - :doc:`Database Class <database/queries>` method ``query()`` returning boolean instead of a result object when the PostgreSQL-specific *RETURNING* clause is used.
+- Fixed a bug (#249) - :doc:`Cache Library <libraries/caching>` didn't properly handle Memcache(d) configurations with missing options.
+- Fixed a bug (#180) - :php:func:`config_item()` didn't take into account run-time configuration changes.
+- Fixed a bug (#2551) - :doc:`Loader Library <libraries/loader>` method ``library()`` didn't properly check if a class that is being loaded already exists.
+- Fixed a bug (#2560) - :doc:`Form Helper <helpers/form_helper>` function :php:func:`form_open()` set the 'method="post"' attribute only if the passed attributes equaled an empty string.
+- Fixed a bug (#2585) - :doc:`Query Builder <database/query_builder>` methods ``min()``, ``max()``, ``avg()``, ``sum()`` didn't escape field names.
+- Fixed an edge case (#2583) in the :doc:`Email Library <libraries/email>` where `Suhosin <http://www.hardened-php.net/suhosin/>` blocked messages sent via ``mail()`` due to trailing newspaces in headers.
+- Fixed a bug (#2590) - :php:func:`log_message()` didn't actually cache the ``CI_Log`` class instance.
+- Fixed a bug (#2609) - :php:func:`get_config()` optional argument was only effective on first function call. Also, it can now add items, in addition to updating existing items.
+- Fixed a bug in the 'postgre' :doc:`database <database/index>` driver where the connection ID wasn't passed to ``pg_escape_string()``.
+- Fixed a bug (#33) - Script execution was terminated when an invalid cookie key was encountered.
+- Fixed a bug (#2681) - ``CI_Security::entity_decode()`` used the `PREG_REPLACE_EVAL` flag, which is deprecated since PHP 5.5.
+- Fixed a bug (#2691) - nested transactions could end in a deadlock when an error is encountered with *db_debug* set to TRUE.
+- Fixed a bug (#2515) - ``_exception_handler()`` used to send the 200 "OK" HTTP status code and didn't stop script exection even on fatal errors.
+
+Version 2.1.4
+=============
+
+Release Date: July 8, 2013
+
+- General Changes
+
+ - Improved security in ``xss_clean()``.
+
+Bug fixes for 2.1.4
+-------------------
+
+- Fixed a bug (#1936) - :doc:`Migration Library <libraries/migration>` method ``latest()`` had a typo when retrieving language values.
+- Fixed a bug (#2021) - :doc:`Migration Library <libraries/migration>` configuration file was mistakenly using Windows style line feeds.
+- Fixed a bug (#1273) - ``E_NOTICE`` being generated by :doc:`Query Builder <database/query_builder>`'s ``set_update_batch()`` method.
+- Fixed a bug (#2337) - :doc:`Email Library <libraries/email>` method ``print_debugger()`` didn't apply ``htmlspecialchars()`` to headers.
Version 2.1.3
=============
@@ -509,6 +645,7 @@ Version 2.1.3
Release Date: October 8, 2012
- Core
+
- :doc:`Common function <general/common_functions>` ``is_loaded()`` now returns a reference.
Bug fixes for 2.1.3
@@ -532,6 +669,7 @@ Version 2.1.2
Release Date: June 29, 2012
- General Changes
+
- Improved security in ``xss_clean()``.
Version 2.1.1
@@ -540,14 +678,17 @@ Version 2.1.1
Release Date: June 12, 2012
- General Changes
+
- Fixed support for docx, xlsx files in mimes.php.
- Libraries
+
- Further improved MIME type detection in the :doc:`File Uploading Library <libraries/file_uploading>`.
- Added support for IPv6 to the :doc:`Input Library <libraries/input>`.
- Added support for the IP format parameter to the :doc:`Form Validation Library <libraries/form_validation>`.
- Helpers
+
- ``url_title()`` performance and output improved. You can now use any string as the word delimiter, but 'dash' and 'underscore' are still supported.
Bug fixes for 2.1.1
@@ -559,7 +700,7 @@ Bug fixes for 2.1.1
- Fixed a bug (#538) - Windows paths were ignored when using the :doc:`Image Manipulation Library <libraries/image_lib>` to create a new file.
- Fixed a bug - When database caching was enabled, $this->db->query() checked the cache before binding variables which resulted in cached queries never being found.
- Fixed a bug - CSRF cookie value was allowed to be any (non-empty) string before being written to the output, making code injection a risk.
-- Fixed a bug (#726) - PDO put a 'dbname' argument in it's connection string regardless of the database platform in use, which made it impossible to use SQLite.
+- Fixed a bug (#726) - PDO put a 'dbname' argument in its connection string regardless of the database platform in use, which made it impossible to use SQLite.
- Fixed a bug - ``CI_DB_pdo_driver::num_rows()`` was not returning properly value with SELECT queries, cause it was relying on ``PDOStatement::rowCount()``.
- Fixed a bug (#1059) - ``CI_Image_lib::clear()`` was not correctly clearing all necessary object properties, namely width and height.
@@ -603,7 +744,7 @@ Release Date: November 14, 2011
- Libraries
- - Changed $this->cart->insert() in the :doc:`Cart
+ - Changed ``$this->cart->insert()`` in the :doc:`Cart
Library <libraries/cart>` to return the Row ID if a single
item was inserted successfully.
- Added support to set an optional parameter in your callback rules
@@ -613,8 +754,7 @@ Release Date: November 14, 2011
incremental updates to your database schema.
- Driver children can be located in any package path.
- Added max_filename_increment config setting for Upload library.
- - Added is_unique to the :doc:`Form Validation
- library <libraries/form_validation>`.
+ - Added ``is_unique`` to the :doc:`Form Validation library <libraries/form_validation>`.
- Added $config['use_page_numbers'] to the :doc:`Pagination library <libraries/pagination>`, which enables real page numbers in the URI.
- Added TLS and SSL Encryption for SMTP.
@@ -637,7 +777,6 @@ Bug fixes for 2.1.0
but the requested method did not.
- Fixed a bug (Reactor #89) where MySQL export would fail if the table
had hyphens or other non alphanumeric/underscore characters.
-- Fixed a bug (#200) where MySQL queries would be malformed after calling $this->db->count_all() then $this->db->get()
- Fixed a bug (#105) that stopped query errors from being logged unless database debugging was enabled
- Fixed a bug (#160) - Removed unneeded array copy in the file cache
driver.
@@ -658,7 +797,7 @@ Bug fixes for 2.1.0
- Fixed a bug (#537) - Support for all wav type in browser.
- Fixed a bug (#576) - Using ini_get() function to detect if apc is enabled or not.
- Fixed invalid date time format in :doc:`Date helper <helpers/date_helper>` and :doc:`XMLRPC library <libraries/xmlrpc>`.
-- Fixed a bug (#200) - MySQL queries would be malformed after calling count_all() then db->get().
+- Fixed a bug (#200) - MySQL queries would be malformed after calling db->count_all() then db->get().
Version 2.0.3
=============
diff --git a/user_guide_src/source/general/cli.rst b/user_guide_src/source/general/cli.rst
index 998d2a907..4145d5ccc 100644
--- a/user_guide_src/source/general/cli.rst
+++ b/user_guide_src/source/general/cli.rst
@@ -33,7 +33,7 @@ Let's try it: Hello World!
==========================
Let's create a simple controller so you can see it in action. Using your
-text editor, create a file called tools.php, and put the following code
+text editor, create a file called Tools.php, and put the following code
in it::
<?php
diff --git a/user_guide_src/source/general/common_functions.rst b/user_guide_src/source/general/common_functions.rst
index a133fdc6d..e085ef808 100644
--- a/user_guide_src/source/general/common_functions.rst
+++ b/user_guide_src/source/general/common_functions.rst
@@ -68,10 +68,6 @@ accessing configuration information, however ``config_item()`` can be used
to retrieve single keys. See :doc:`Config Library <../libraries/config>`
documentation for more information.
-.. important:: This function only returns values set in your configuration
- files. It does not take into account config values that are
- dynamically set at runtime.
-
show_error()
============
@@ -100,11 +96,10 @@ please see the :doc:`Error Handling <errors>` documentation.
log_message()
=============
-.. php:function:: log_message($level, $message, $php_error = FALSE)
+.. php:function:: log_message($level, $message)
:param string $level: Log level: 'error', 'debug' or 'info'
:param string $message: Message to log
- :param bool $php_error: Whether we're logging a native PHP error message
:returns: void
This function is an alias for ``CI_Log::write_log()``. For more info,
diff --git a/user_guide_src/source/general/controllers.rst b/user_guide_src/source/general/controllers.rst
index 04f23276d..d8ef824fb 100644
--- a/user_guide_src/source/general/controllers.rst
+++ b/user_guide_src/source/general/controllers.rst
@@ -18,7 +18,7 @@ Consider this URI::
example.com/index.php/blog/
In the above example, CodeIgniter would attempt to find a controller
-named blog.php and load it.
+named Blog.php and load it.
**When a controller's name matches the first segment of a URI, it will
be loaded.**
@@ -27,7 +27,7 @@ Let's try it: Hello World!
==========================
Let's create a simple controller so you can see it in action. Using your
-text editor, create a file called blog.php, and put the following code
+text editor, create a file called Blog.php, and put the following code
in it::
<?php
@@ -41,6 +41,8 @@ in it::
Then save the file to your *application/controllers/* directory.
+.. important:: The file must be called 'Blog.php', with a capital 'B'.
+
Now visit the your site using a URL similar to this::
example.com/index.php/blog/
@@ -136,7 +138,7 @@ present, as will be the case when only your site root URL is requested.
To specify a default controller, open your **application/config/routes.php**
file and set this variable::
- $route['default_controller'] = 'blog';
+ $route['default_controller'] = 'Blog';
Where Blog is the name of the controller class you want used. If you now
load your main index.php file without specifying any URI segments you'll
@@ -272,7 +274,7 @@ and place your controller classes within them.
specify the folder. For example, let's say you have a controller located
here::
- application/controllers/products/shoes.php
+ application/controllers/products/Shoes.php
To call the above controller your URI will look something like this::
diff --git a/user_guide_src/source/general/creating_libraries.rst b/user_guide_src/source/general/creating_libraries.rst
index 4fc8ed72f..4beb600da 100644
--- a/user_guide_src/source/general/creating_libraries.rst
+++ b/user_guide_src/source/general/creating_libraries.rst
@@ -42,8 +42,7 @@ Naming Conventions
The Class File
==============
-Classes should have this basic prototype (Note: We are using the name
-Someclass purely as an example)::
+Classes should have this basic prototype::
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
@@ -56,6 +55,8 @@ Someclass purely as an example)::
/* End of file Someclass.php */
+.. note:: We are using the name Someclass purely as an example.
+
Using Your Class
================
@@ -81,7 +82,7 @@ constructor::
$params = array('type' => 'large', 'color' => 'red');
- $this->load->library('Someclass', $params);
+ $this->load->library('someclass', $params);
If you use this feature you must set up your class constructor to expect
data::
diff --git a/user_guide_src/source/general/libraries.rst b/user_guide_src/source/general/libraries.rst
index 6e1c8b6dd..9bbda51bb 100644
--- a/user_guide_src/source/general/libraries.rst
+++ b/user_guide_src/source/general/libraries.rst
@@ -29,4 +29,4 @@ Creating Your Own Libraries
===========================
Please read the section of the user guide that discusses how to
-:doc:`create your own libraries <creating_libraries>`.
+:doc:`create your own libraries <creating_libraries>`. \ No newline at end of file
diff --git a/user_guide_src/source/general/models.rst b/user_guide_src/source/general/models.rst
index a028a9569..c4fd12476 100644
--- a/user_guide_src/source/general/models.rst
+++ b/user_guide_src/source/general/models.rst
@@ -84,8 +84,7 @@ Where **Model_name** is the name of your class. Class names **must** have
the first letter capitalized with the rest of the name lowercase. Make
sure your class extends the base Model class.
-The file name will be a lower case version of your class name. For
-example, if your class is this::
+The file name must match the class name. For example, if this is your class::
class User_model extends CI_Model {
@@ -98,7 +97,7 @@ example, if your class is this::
Your file will be this::
- application/models/user_model.php
+ application/models/User_model.php
Loading a Model
===============
@@ -111,7 +110,7 @@ the following method::
If your model is located in a sub-directory, include the relative path
from your models directory. For example, if you have a model located at
-*application/models/blog/queries.php* you'll load it using::
+*application/models/blog/Queries.php* you'll load it using::
$this->load->model('blog/queries');
@@ -181,4 +180,4 @@ database. The following options for connecting are available to you:
$config['pconnect'] = FALSE;
$config['db_debug'] = TRUE;
- $this->load->model('Model_name', '', $config); \ No newline at end of file
+ $this->load->model('model_name', '', $config); \ No newline at end of file
diff --git a/user_guide_src/source/general/routing.rst b/user_guide_src/source/general/routing.rst
index 123257fc8..5520f59fe 100644
--- a/user_guide_src/source/general/routing.rst
+++ b/user_guide_src/source/general/routing.rst
@@ -145,7 +145,7 @@ routing rules to process the back-references. Example::
Reserved Routes
===============
-There are two reserved routes::
+There are three reserved routes::
$route['default_controller'] = 'welcome';
@@ -165,5 +165,17 @@ error page. It won't affect to the ``show_404()`` function, which will
continue loading the default *error_404.php* file at
*application/views/errors/error_404.php*.
+
+::
+
+ $route['translate_uri_dashes'] = FALSE;
+
+As evident by the boolean value, this is not exactly a route. This
+option enables you to automatically replace dashes ('-') with
+underscores in the controller and method URI segments, thus saving you
+additional route entries if you need to do that.
+This is required, because the dash isn't a valid class or method name
+character and would cause a fatal error if you try to use it.
+
.. important:: The reserved routes must come before any wildcard or
regular expression routes. \ No newline at end of file
diff --git a/user_guide_src/source/general/styleguide.rst b/user_guide_src/source/general/styleguide.rst
index 144b362f5..5613eabec 100644
--- a/user_guide_src/source/general/styleguide.rst
+++ b/user_guide_src/source/general/styleguide.rst
@@ -71,13 +71,42 @@ identify a file as being complete and not truncated.
echo "Here's my code!";
- /* End of file myfile.php */
+ /* End of file Myfile.php */
/* Location: ./system/modules/mymodule/myfile.php */
.. note:: There should be no empty line or newline character(s) following
the closing comments. If you happen to see one when
submitting a pull request, please check your IDE settings and fix it.
+File Naming
+===========
+
+Class files must be named in a Ucfirst-like manner, while any other file name
+(configurations, views, generic scripts, etc.) should be in all lowercase.
+
+**INCORRECT**::
+
+ somelibrary.php
+ someLibrary.php
+ SOMELIBRARY.php
+ Some_Library.php
+
+ Application_config.php
+ Application_Config.php
+ applicationConfig.php
+
+**CORRECT**::
+
+ Somelibrary.php
+ Some_library.php
+
+ applicationconfig.php
+ application_config.php
+
+Furthermore, class file names should match the name of the class itself.
+For example, if you have a class named `Myclass`, then its filename must
+be **Myclass.php**.
+
Class and Method Naming
=======================
diff --git a/user_guide_src/source/general/urls.rst b/user_guide_src/source/general/urls.rst
index d678e4a0a..ca44e2f4c 100644
--- a/user_guide_src/source/general/urls.rst
+++ b/user_guide_src/source/general/urls.rst
@@ -32,24 +32,6 @@ The :doc:`URI Library <../libraries/uri>` and the :doc:`URL Helper
with your URI data. In addition, your URLs can be remapped using the
:doc:`URI Routing <routing>` feature for more flexibility.
-Friendly URLs
-=============
-
-As you might guess, since there's a straight relationship between
-URI segments and the controller/method pair that's being called,
-those two determining segments must represent a valid class and
-method name.
-You may however also use dashes in the class/method-representing
-segments, and they will automatically be translated to underscores
-in order to be valid routed segments.
-
-For example::
-
- example.com/my-settings/change-password/
-
-The above example will route to the ``My_settings`` controller and
-its method ``change_password()``.
-
Removing the index.php file
===========================
diff --git a/user_guide_src/source/general/views.rst b/user_guide_src/source/general/views.rst
index 4b1ab3c34..2fc0cb2ca 100644
--- a/user_guide_src/source/general/views.rst
+++ b/user_guide_src/source/general/views.rst
@@ -45,7 +45,7 @@ Where name is the name of your view file.
.. note:: The .php file extension does not need to be specified
unless you use something other than .php.
-Now, open the controller file you made earlier called blog.php, and
+Now, open the controller file you made earlier called Blog.php, and
replace the echo statement with the view loading method::
<?php
diff --git a/user_guide_src/source/helpers/captcha_helper.rst b/user_guide_src/source/helpers/captcha_helper.rst
index ca24e011f..3c56addf3 100644
--- a/user_guide_src/source/helpers/captcha_helper.rst
+++ b/user_guide_src/source/helpers/captcha_helper.rst
@@ -64,7 +64,15 @@ Once loaded you can generate a captcha like this::
'img_height' => 30,
'expiration' => 7200,
'word_length' => 8,
- 'pool' => '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ 'pool' => '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
+
+ // White background and border, black text and red grid
+ 'colors' => array(
+ 'background' => array(255, 255, 255),
+ 'border' => array(255, 255, 255),
+ 'text' => array(0, 0, 0),
+ 'grid' => array(255, 40, 40)
+ )
);
$cap = create_captcha($vals);
@@ -82,6 +90,7 @@ Once loaded you can generate a captcha like this::
in the captcha folder before it will be deleted. The default is two
hours.
- **word_length** defaults to 8, **pool** defaults to '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
+- If any of the **colors** values is missing, it will be replaced by the default.
Adding a Database
-----------------
diff --git a/user_guide_src/source/helpers/date_helper.rst b/user_guide_src/source/helpers/date_helper.rst
index 3a3454edc..5dfee8b48 100644
--- a/user_guide_src/source/helpers/date_helper.rst
+++ b/user_guide_src/source/helpers/date_helper.rst
@@ -414,9 +414,9 @@ Note some of the location lists have been abridged for clarity and formatting.
=========== =====================================================================
Time Zone Location
=========== =====================================================================
-UM2 (UTC - 12:00) Baker/Howland Island
-UM1 (UTC - 11:00) Samoa Time Zone, Niue
-UM0 (UTC - 10:00) Hawaii-Aleutian Standard Time, Cook Islands
+UM12 (UTC - 12:00) Baker/Howland Island
+UM11 (UTC - 11:00) Samoa Time Zone, Niue
+UM10 (UTC - 10:00) Hawaii-Aleutian Standard Time, Cook Islands
UM95 (UTC - 09:30) Marquesas Islands
UM9 (UTC - 09:00) Alaska Standard Time, Gambier Islands
UM8 (UTC - 08:00) Pacific Standard Time, Clipperton Island
@@ -428,7 +428,7 @@ UM4 (UTC - 04:00) Atlantic Standard Time, Eastern Caribbean
UM35 (UTC - 03:30) Newfoundland Standard Time
UM3 (UTC - 03:00) Argentina, Brazil, French Guiana, Uruguay
UM2 (UTC - 02:00) South Georgia/South Sandwich Islands
-UM (UTC -1:00) Azores, Cape Verde Islands
+UM1 (UTC -1:00) Azores, Cape Verde Islands
UTC (UTC) Greenwich Mean Time, Western European Time
UP1 (UTC +1:00) Central European Time, West Africa Time
UP2 (UTC +2:00) Central Africa Time, Eastern European Time
@@ -452,6 +452,6 @@ UP11 (UTC +11:00) Magadan Time, Solomon Islands, Vanuatu
UP115 (UTC +11:30) Norfolk Island
UP12 (UTC +12:00) Fiji, Gilbert Islands, Kamchatka, New Zealand
UP1275 (UTC +12:45) Chatham Islands Standard Time
-UP1 (UTC +13:00) Phoenix Islands Time, Tonga
+UP13 (UTC +13:00) Phoenix Islands Time, Tonga
UP14 (UTC +14:00) Line Islands
=========== ===================================================================== \ No newline at end of file
diff --git a/user_guide_src/source/helpers/form_helper.rst b/user_guide_src/source/helpers/form_helper.rst
index b2a9b6f0f..f49027baa 100644
--- a/user_guide_src/source/helpers/form_helper.rst
+++ b/user_guide_src/source/helpers/form_helper.rst
@@ -22,7 +22,7 @@ form_open()
.. php:function:: form_open($action = '', $attributes = '', $hidden = array())
:param string $action: Form action/target URI string
- :param string $attributes: HTML attributes
+ :param array $attributes: HTML attributes
:param array $hidden: An array of hidden fields' definitions
:returns: string
@@ -41,7 +41,7 @@ Here's a simple example::
The above example would create a form that points to your base URL plus the
"email/send" URI segments, like this::
- <form method="post" accept-charset="utf-8" action="http://example.com/index.php/email/send" />
+ <form method="post" accept-charset="utf-8" action="http://example.com/index.php/email/send">
Adding Attributes
^^^^^^^^^^^^^^^^^
@@ -52,9 +52,13 @@ parameter, like this::
$attributes = array('class' => 'email', 'id' => 'myform');
echo form_open('email/send', $attributes);
-The above example would create a form similar to this::
+Alternatively, you can specify the second parameter as a string::
+
+ echo form_open('email/send', 'class="email" id="myform"');
+
+The above examples would create a form similar to this::
- <form method="post" accept-charset="utf-8" action="http://example.com/index.php/email/send" class="email" id="myform" />
+ <form method="post" accept-charset="utf-8" action="http://example.com/index.php/email/send" class="email" id="myform">
Adding Hidden Input Fields
^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -65,6 +69,8 @@ third parameter, like this::
$hidden = array('username' => 'Joe', 'member_id' => '234');
echo form_open('email/send', '', $hidden);
+You can skip the second parameter by passing any falsy value to it.
+
The above example would create a form similar to this::
<form method="post" accept-charset="utf-8" action="http://example.com/index.php/email/send">
@@ -77,7 +83,7 @@ form_open_multipart()
.. php:function:: form_open_multipart($action = '', $attributes = array(), $hidden = array())
:param string $action: Form action/target URI string
- :param string $attributes: HTML attributes
+ :param array $attributes: HTML attributes
:param array $hidden: An array of hidden fields' definitions
:returns: string
@@ -258,10 +264,10 @@ multiple select for you.
Example::
$options = array(
- 'small' => 'Small Shirt',
- 'med' => 'Medium Shirt',
- 'large' => 'Large Shirt',
- 'xlarge' => 'Extra Large Shirt',
+ 'small' => 'Small Shirt',
+ 'med' => 'Medium Shirt',
+ 'large' => 'Large Shirt',
+ 'xlarge' => 'Extra Large Shirt',
);
$shirts_on_sale = array('small', 'large');
@@ -407,16 +413,14 @@ The third parameter contains a boolean TRUE/FALSE to determine whether
the box should be checked or not.
Similar to the other form functions in this helper, you can also pass an
-array of attributes to the function
-
-::
+array of attributes to the function::
$data = array(
- 'name' => 'newsletter',
- 'id'      => 'newsletter',
- 'value'   => 'accept',
- 'checked' => TRUE,
- 'style'   => 'margin:10px'
+ 'name' => 'newsletter',
+ 'id' => 'newsletter',
+ 'value' => 'accept',
+ 'checked' => TRUE,
+ 'style' => 'margin:10px'
);
echo form_checkbox($data);
@@ -523,11 +527,11 @@ Or you can pass an associative array containing any data you wish your
form to contain::
$data = array(
- 'name' => 'button',
- 'id' => 'button',
- 'value' => 'true',
- 'type' => 'reset',
- 'content' => 'Reset'
+ 'name' => 'button',
+ 'id' => 'button',
+ 'value' => 'true',
+ 'type' => 'reset',
+ 'content' => 'Reset'
);
echo form_button($data);
diff --git a/user_guide_src/source/helpers/smiley_helper.rst b/user_guide_src/source/helpers/smiley_helper.rst
index 7069b465e..cfd52ffbc 100644
--- a/user_guide_src/source/helpers/smiley_helper.rst
+++ b/user_guide_src/source/helpers/smiley_helper.rst
@@ -17,7 +17,7 @@ This helper is loaded using the following code::
Overview
========
-The Smiley helper has a renderer that takes plain text simileys, like
+The Smiley helper has a renderer that takes plain text smileys, like
:-) and turns them into a image representation, like |smile!|
It also lets you display a set of smiley images that when clicked will
@@ -43,8 +43,8 @@ View as described.
The Controller
--------------
-In your `application/controllers/` folder, create a file called
-smileys.php and place the code below in it.
+In your **application/controllers/** directory, create a file called
+Smileys.php and place the code below in it.
.. important:: Change the URL in the :php:func:`get_clickable_smileys()`
function below so that it points to your smiley folder.
@@ -70,7 +70,7 @@ the :doc:`Table Class <../libraries/table>`::
}
-In your `application/views/` folder, create a file called `smiley_view.php`
+In your **application/views/** folder, create a file called **smiley_view.php**
and place this code in it::
<html>
@@ -156,7 +156,7 @@ string, the second must contain the URL to your smiley folder
Example::
- $str = 'Here are some simileys: :-) ;-)';
+ $str = 'Here are some smileys: :-) ;-)';
$str = parse_smileys($str, "http://example.com/images/smileys/");
echo $str;
diff --git a/user_guide_src/source/helpers/url_helper.rst b/user_guide_src/source/helpers/url_helper.rst
index 8b5361f94..7a49f188d 100644
--- a/user_guide_src/source/helpers/url_helper.rst
+++ b/user_guide_src/source/helpers/url_helper.rst
@@ -18,9 +18,10 @@ The following functions are available:
site_url()
==========
-.. php:function:: site_url($uri = '')
+.. php:function:: site_url($uri = '', $protocol = NULL)
:param string $uri: URI string
+ :param string $protocol: Protocol, e.g. 'http' or 'https'
:returns: string
Returns your site URL, as specified in your config file. The index.php
@@ -51,9 +52,10 @@ please see the :doc:`Config Library <../libraries/config>` documentation.
base_url()
===========
-.. php:function:: base_url($uri = '')
+.. php:function:: base_url($uri = '', $protocol = NULL)
:param string $uri: URI string
+ :param string $protocol: Protocol, e.g. 'http' or 'https'
:returns: string
Returns your site base URL, as specified in your config file. Example::
diff --git a/user_guide_src/source/installation/downloads.rst b/user_guide_src/source/installation/downloads.rst
index 45a8f80a7..93c5cc21b 100644
--- a/user_guide_src/source/installation/downloads.rst
+++ b/user_guide_src/source/installation/downloads.rst
@@ -2,62 +2,38 @@
Downloading CodeIgniter
#######################
-- `CodeIgniter V 3.0.0 (Current
- version) <http://codeigniter.com/downloads/>`_
-- `CodeIgniter V
- 2.1.2 <http://codeigniter.com/download_files/reactor/CodeIgniter_2.1.2.zip>`_
-- `CodeIgniter V
- 2.1.1 <http://codeigniter.com/download_files/reactor/CodeIgniter_2.1.1.zip>`_
-- `CodeIgniter V
- 2.1.0 <http://codeigniter.com/download_files/reactor/CodeIgniter_2.1.0.zip>`_
-- `CodeIgniter V
- 2.0.3 <http://codeigniter.com/download_files/reactor/CodeIgniter_2.0.3.zip>`_
-- `CodeIgniter V
- 2.0.2 <http://codeigniter.com/download_files/reactor/CodeIgniter_2.0.2.zip>`_
-- `CodeIgniter V
- 2.0.1 <http://codeigniter.com/download_files/reactor/CodeIgniter_2.0.1.zip>`_
-- `CodeIgniter V
- 2.0.0 <http://codeigniter.com/download_files/reactor/CodeIgniter_2.0.0.zip>`_
-- `CodeIgniter V
- 1.7.3 <http://codeigniter.com/download_files/CodeIgniter_1.7.3.zip>`_
-- `CodeIgniter V
- 1.7.2 <http://codeigniter.com/download_files/CodeIgniter_1.7.2.zip>`_
-- `CodeIgniter V
- 1.7.1 <http://codeigniter.com/download_files/CodeIgniter_1.7.1.zip>`_
-- `CodeIgniter V
- 1.7.0 <http://codeigniter.com/download_files/CodeIgniter_1.7.0.zip>`_
-- `CodeIgniter V
- 1.6.3 <http://codeigniter.com/download_files/CodeIgniter_1.6.3.zip>`_
-- `CodeIgniter V
- 1.6.2 <http://codeigniter.com/download_files/CodeIgniter_1.6.2.zip>`_
-- `CodeIgniter V
- 1.6.1 <http://codeigniter.com/download_files/CodeIgniter_1.6.1.zip>`_
-- `CodeIgniter V
- 1.6.0 <http://codeigniter.com/download_files/CodeIgniter_1.6.0.zip>`_
-- `CodeIgniter V
- 1.5.4 <http://codeigniter.com/download_files/CodeIgniter_1.5.4.zip>`_
-- `CodeIgniter V
- 1.5.3 <http://codeigniter.com/download_files/CodeIgniter_1.5.3.zip>`_
-- `CodeIgniter V
- 1.5.2 <http://codeigniter.com/download_files/CodeIgniter_1.5.2.zip>`_
-- `CodeIgniter V
- 1.5.1 <http://codeigniter.com/download_files/CodeIgniter_1.5.1.zip>`_
-- `CodeIgniter V
- 1.4.1 <http://codeigniter.com/download_files/CodeIgniter_1.4.1.zip>`_
-- `CodeIgniter V
- 1.3.3 <http://codeigniter.com/download_files/CodeIgniter_1.3.3.zip>`_
-- `CodeIgniter V
- 1.3.2 <http://codeigniter.com/download_files/CodeIgniter_1.3.2.zip>`_
-- `CodeIgniter V
- 1.3.1 <http://codeigniter.com/download_files/CodeIgniter_1.3.1.zip>`_
-- `CodeIgniter V
- 1.3 <http://codeigniter.com/download_files/CodeIgniter_1.3.zip>`_
-- `CodeIgniter V
- 1.2 <http://codeigniter.com/download_files/CodeIgniter_1.2.zip>`_
-- `CodeIgniter V
- 1.1 <http://codeigniter.com/download_files/CodeIgniter_1.1b.zip>`_
-- `CodeIgniter V
- 1.0 <http://codeigniter.com/download_files/CodeIgniter_1.0b.zip>`_
+- `CodeIgniter v3.0.0 (Current version) <http://ellislab.com/codeigniter/download>`_
+- `CodeIgniter v2.1.4 <http://ellislab.com/asset/ci_download_files/CodeIgniter_2.1.4.zip>`_ (MD5 Checksum: e74a296c1d412a855c025b9cd468a513)
+- `CodeIgniter v2.1.3 <http://ellislab.com/asset/ci_download_files/CodeIgniter_2.1.3.zip>`_ (MD5 Checksum: 781d06be06eaa36f10759ef82c8594d5)
+- `CodeIgniter v2.1.2 <http://ellislab.com/asset/ci_download_files/CodeIgniter_2.1.2.zip>`_ (MD5 Checksum: c7a2980dff2774c97bd38bfbf450d8d5)
+- `CodeIgniter v2.1.1 <http://ellislab.com/asset/ci_download_files/CodeIgniter_2.1.1.zip>`_ (MD5 Checksum: c4aa5f188f4ff16f919607b46a16c76c)
+- `CodeIgniter v2.1.0 <http://ellislab.com/asset/ci_download_files/CodeIgniter_2.1.0.zip>`_ (MD5 Checksum: 8cb676b0f831114935d7dd1ae2e0d490)
+- `CodeIgniter v2.0.3 <http://ellislab.com/asset/ci_download_files/CodeIgniter_2.0.3.zip>`_ (MD5 Checksum: 910475d50daf088bdd949c3d35b444d9)
+- `CodeIgniter v2.0.2 <http://ellislab.com/asset/ci_download_files/CodeIgniter_2.0.2.zip>`_ (MD5 Checksum: e75bab8cf27d2fb2483c5bb61b85a524)
+- `CodeIgniter v2.0.1 <http://ellislab.com/asset/ci_download_files/CodeIgniter_2.0.1.zip>`_ (MD5 Checksum: 675aa95896bfb16467436c0484f15f1f)
+- `CodeIgniter v2.0.0 <http://ellislab.com/asset/ci_download_files/CodeIgniter_2.0.0.zip>`_ (MD5 Checksum: bd657863de45dbb397f3b3dbc4f13abb)
+- `CodeIgniter v1.7.3 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.7.3.zip>`_ (MD5 Checksum: 16f50e7df4f44c1defe18355131049e9)
+- `CodeIgniter v1.7.2 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.7.2.zip>`_ (MD5 Checksum: ff2f4d1b3ab921f91e006f38b3ae6540)
+- `CodeIgniter v1.7.1 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.7.1.zip>`_ (MD5 Checksum: deca9709cf21b26dc0e4ec040b37e866)
+- `CodeIgniter v1.7.0 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.7.0.zip>`_ (MD5 Checksum: 28037f2071f940d8756864460d949045)
+- `CodeIgniter v1.6.3 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.6.3.zip>`_ (MD5 Checksum: 5ffab52b39b235ed6bd08ee5dd64d2f6)
+- `CodeIgniter v1.6.2 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.6.2.zip>`_ (MD5 Checksum: 0922830f96dfd40874b39ad018a49206)
+- `CodeIgniter v1.6.1 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.6.1.zip>`_ (MD5 Checksum: cc3f0b566e3654d351fa067aeee9bced)
+- `CodeIgniter v1.6.0 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.6.0.zip>`_ (MD5 Checksum: 89efabb8c1d57bb51071e6a20bb5590d)
+- `CodeIgniter v1.5.4 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.5.4.zip>`_ (MD5 Checksum: 0d6cc66b01d5ddecde483b3d5f51e4f8)
+- `CodeIgniter v1.5.3 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.5.3.zip>`_ (MD5 Checksum: f44dd21d34a2842bd052879ca5de6630)
+- `CodeIgniter v1.5.2 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.5.2.zip>`_ (MD5 Checksum: 78e7106b271f75af48e626f6e923c1aa)
+- `CodeIgniter v1.5.1 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.5.1.zip>`_ (MD5 Checksum: 9dfd0dbed4f283a42a817e1e88f97481)
+- `CodeIgniter v1.5.0 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.5.0.zip>`_ (MD5 Checksum: 116b805eae4b7e78ddd43a8aee733632)
+- `CodeIgniter v1.4.1 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.4.1.zip>`_ (MD5 Checksum: 470005a83772e9d2e99dec2b4058e584)
+- `CodeIgniter v1.4.0 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.4.0.zip>`_ (MD5 Checksum: 43ca6ff3447d6b5681f98a328b386338)
+- `CodeIgniter v1.3.3 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.3.3.zip>`_ (MD5 Checksum: 55692ba4b55b53b58e4514e310288981)
+- `CodeIgniter v1.3.2 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.3.2.zip>`_ (MD5 Checksum: 7dace6e1d6245b569943e8df952c7637)
+- `CodeIgniter v1.3.1 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.3.1.zip>`_ (MD5 Checksum: f6c6f00830c60d7f98b948269ee81069)
+- `CodeIgniter v1.3 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.3.zip>`_ (MD5 Checksum: 03b2f796df6af808ecff3a18b6000477)
+- `CodeIgniter v1.2 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.2.zip>`_ (MD5 Checksum: f9289814fabe102bc35beb791d0c0f62)
+- `CodeIgniter v1.1 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.1b.zip>`_ (MD5 Checksum: bf4cabb6a3ea3122a974270b8044befb)
+- `CodeIgniter v1.0 <http://ellislab.com/asset/ci_download_files/CodeIgniter_1.0b.zip>`_ (MD5 Checksum: 427ca4255e2bdaacee976de1aa143ea0)
******
@@ -71,5 +47,4 @@ Please note that while every effort is made to keep this code base
functional, we cannot guarantee the functionality of code taken from
the develop branch.
-Beginning with version 2.0.3, stable tags are also available via GitHub,
-simply select the version from the Tags dropdown. \ No newline at end of file
+Beginning with version 2.0.3, stable versions are also available via `GitHub Releases <https://github.com/EllisLab/CodeIgniter/releases>`_. \ No newline at end of file
diff --git a/user_guide_src/source/installation/upgrade_214.rst b/user_guide_src/source/installation/upgrade_214.rst
new file mode 100644
index 000000000..ba57e5976
--- /dev/null
+++ b/user_guide_src/source/installation/upgrade_214.rst
@@ -0,0 +1,14 @@
+#############################
+Upgrading from 2.1.3 to 2.1.4
+#############################
+
+Before performing an update you should take your site offline by
+replacing the index.php file with a static one.
+
+Step 1: Update your CodeIgniter files
+=====================================
+
+Replace all files and directories in your "system" folder.
+
+.. note:: If you have any custom developed files in these folders please
+ make copies of them first. \ No newline at end of file
diff --git a/user_guide_src/source/installation/upgrade_300.rst b/user_guide_src/source/installation/upgrade_300.rst
index 926af312d..e8fdd0b15 100644
--- a/user_guide_src/source/installation/upgrade_300.rst
+++ b/user_guide_src/source/installation/upgrade_300.rst
@@ -1,5 +1,5 @@
#############################
-Upgrading from 2.1.3 to 3.0.0
+Upgrading from 2.1.4 to 3.0.0
#############################
.. note:: These upgrade notes are for a version that is yet to be released.
@@ -17,22 +17,63 @@ they will need to be made fresh in this new one.
.. note:: If you have any custom developed files in these folders please
make copies of them first.
+**************************************
+Step 2: Update your classes file names
+**************************************
+
+Starting with CodeIgniter 3.0, all class filenames (libraries, drivers, controllers
+and models) must be named in a Ucfirst-like manner or in other words - they must
+start with a capital letter.
+
+For example, if you have the following library file:
+
+ application/libraries/mylibrary.php
+
+... then you'll have to rename it to:
+
+ application/libraries/Mylibrary.php
+
+The same goes for driver libraries and extensions and/or overrides of CodeIgniter's
+own libraries and core classes.
+
+ application/libraries/MY_email.php
+ application/core/MY_log.php
+
+The above files should respectively be renamed to the following:
+
+ application/libraries/MY_Email.php
+ application/core/MY_Log.php
+
+Controllers:
+
+ application/controllers/welcome.php -> application/controllers/Welcome.php
+
+Models:
+
+ application/models/misc_model.php -> application/models/Misc_model.php
+
+Please note that this DOES NOT affect directories, configuration files, views,
+helpers, hooks and anything else - it is only applied to classes.
+
+You must now follow just one simple rule - class names in Ucfirst and everything else
+in lowercase.
+
********************************
-Step 2: Replace config/mimes.php
+Step 3: Replace config/mimes.php
********************************
This config file has been updated to contain more user mime-types, please copy
it to _application/config/mimes.php*.
**************************************************************
-Step 3: Remove $autoload['core'] from your config/autoload.php
+Step 4: Remove $autoload['core'] from your config/autoload.php
**************************************************************
Use of the ``$autoload['core']`` config array has been deprecated as of CodeIgniter 1.4.1 and is now removed.
Move any entries that you might have listed there to ``$autoload['libraries']`` instead.
***************************************************
-Step 4: Move your Log class overrides or extensions
+Step 5: Move your Log class overrides or extensions
***************************************************
The Log Class is considered as a "core" class and is now located in the
@@ -40,10 +81,10 @@ The Log Class is considered as a "core" class and is now located in the
or extensions to work, you need to move them to **application/core/**::
application/libraries/Log.php -> application/core/Log.php
- application/libraries/MY_Log.php -> application/core/MY_log.php
+ application/libraries/MY_Log.php -> application/core/MY_Log.php
*********************************************************
-Step 5: Convert your Session usage from library to driver
+Step 6: Convert your Session usage from library to driver
*********************************************************
When you load (or autoload) the Session library, you must now load it as a driver instead of a library. This means
@@ -67,7 +108,7 @@ standard for Drivers. Also beware that some functions which are not part of the
the drivers, so your extension may have to be broken down into separate library and driver class extensions.
***************************************
-Step 6: Update your config/database.php
+Step 7: Update your config/database.php
***************************************
Due to 3.0.0's renaming of Active Record to Query Builder, inside your `config/database.php`, you will
@@ -78,14 +119,14 @@ need to rename the `$active_record` variable to `$query_builder`
// $active_record = TRUE;
$query_builder = TRUE;
-*******************************
-Step 7: Move your errors folder
-*******************************
+*******************************************
+Step 8: Move your error templates directory
+*******************************************
In version 3.0.0, the errors folder has been moved from _application/errors* to _application/views/errors*.
*******************************************************
-Step 8: Update your config/routes.php containing (:any)
+Step 9: Update your config/routes.php containing (:any)
*******************************************************
Historically, CodeIgniter has always provided the **:any** wildcard in routing,
@@ -104,47 +145,62 @@ regular expression::
(.+) // matches ANYTHING
(:any) // matches any character, except for '/'
-*****************************************
-Step 9: Update your libraries' file names
-*****************************************
+*************************************************************************
+Step 10: Many functions now return NULL instead of FALSE on missing items
+*************************************************************************
-CodeIgniter 3.0 only allows library file names to be named in a *ucfirst* manner
-(meaning that the first letter of the class name must be a capital). For example,
-if you have the following library file:
+Many methods and functions now return NULL instead of FALSE when the required items don't exist:
- application/libraries/mylibrary.php
+ - :doc:`Config Class <../libraries/config>`
-... then you'll have to rename it to:
+ - config->item()
+ - config->slash_item()
- application/libraries/Mylibrary.php
+ - :doc:`Input Class <../libraries/input>`
-The same goes for driver libraries and extensions and/or overrides of CodeIgniter's
-own libraries and core classes.
+ - input->get()
+ - input->post()
+ - input->get_post()
+ - input->cookie()
+ - input->server()
+ - input->input_stream()
+ - input->get_request_header()
- application/libraries/MY_email.php
- application/core/MY_log.php
+ - :doc:`Session Class <../libraries/sessions>`
-The above files should respectively be renamed to the following:
+ - session->userdata()
+ - session->flashdata()
- application/libraries/MY_Email.php
- application/core/MY_Log.php
+ - :doc:`URI Class <../libraries/uri>`
+
+ - uri->segment()
+ - uri->rsegment()
+
+ - :doc:`Array Helper <../helpers/array_helper>`
+
+ - element()
+ - elements()
+
+********************************************************
+Step 11: Update usage of Input Class's get_post() method
+********************************************************
-*****************************************************************************
-Step 10: Check the calls to Array Helper's element() and elements() functions
-*****************************************************************************
+Previously, the :doc:`Input Class <../libraries/input>` method ``get_post()``
+was searching first in POST data, then in GET data. This method has been
+modified so that it searches in GET then in POST, as its name suggests.
-The default return value of these functions, when the required elements
-don't exist, has been changed from FALSE to NULL.
+A method has been added, ``post_get()``, which searches in POST then in GET, as
+``get_post()`` was doing before.
***********************************************************************
-Step 11: Check the calls to Directory Helper's directory_map() function
+Step 12: Update usage of Directory Helper's directory_map() function
***********************************************************************
In the resulting array, directories now end with a trailing directory
separator (i.e. a slash, usually).
*************************************************************
-Step 12: Update usage of Database Forge's drop_table() method
+Step 13: Update usage of Database Forge's drop_table() method
*************************************************************
Up until now, ``drop_table()`` added an IF EXISTS clause by default or it didn't work
@@ -162,11 +218,11 @@ If your application relies on IF EXISTS, you'll have to change its usage.
// Produces DROP TABLE IF EXISTS `table_name`
$this->dbforge->drop_table('table_name', TRUE);
-.. note:: The given example users MySQL-specific syntax, but it should work across
+.. note:: The given example uses MySQL-specific syntax, but it should work across
all drivers with the exception of ODBC.
***********************************************************
-Step 13: Change usage of Email library with multiple emails
+Step 14: Change usage of Email library with multiple emails
***********************************************************
The :doc:`Email Library <../libraries/email>` will automatically clear the
@@ -181,7 +237,7 @@ pass FALSE as the first parameter in the ``send()`` method:
}
***************************************************
-Step 14: Update your Form_validation language lines
+Step 15: Update your Form_validation language lines
***************************************************
Two improvements have been made to the :doc:`Form Validation Library
@@ -212,7 +268,7 @@ files and error messages format:
later.
****************************************************************
-Step 15: Remove usage of (previously) deprecated functionalities
+Step 16: Remove usage of (previously) deprecated functionalities
****************************************************************
In addition to the ``$autoload['core']`` configuration setting, there's a
diff --git a/user_guide_src/source/installation/upgrading.rst b/user_guide_src/source/installation/upgrading.rst
index 4f276207c..6d2e788dd 100644
--- a/user_guide_src/source/installation/upgrading.rst
+++ b/user_guide_src/source/installation/upgrading.rst
@@ -5,7 +5,8 @@ Upgrading From a Previous Version
Please read the upgrade notes corresponding to the version you are
upgrading from.
-- :doc:`Upgrading from 2.1.3 to 3.0.0 <upgrade_300>`
+- :doc:`Upgrading from 2.1.4 to 3.0.0 <upgrade_300>`
+- :doc:`Upgrading from 2.1.3 to 2.1.4 <upgrade_214>`
- :doc:`Upgrading from 2.1.2 to 2.1.3 <upgrade_213>`
- :doc:`Upgrading from 2.1.1 to 2.1.2 <upgrade_212>`
- :doc:`Upgrading from 2.1.0 to 2.1.1 <upgrade_211>`
diff --git a/user_guide_src/source/libraries/config.rst b/user_guide_src/source/libraries/config.rst
index 08d9c2905..654dc4ded 100644
--- a/user_guide_src/source/libraries/config.rst
+++ b/user_guide_src/source/libraries/config.rst
@@ -90,7 +90,7 @@ example, to fetch your language choice you'll do this::
$lang = $this->config->item('language');
-The function returns FALSE (boolean) if the item you are trying to fetch
+The function returns NULL if the item you are trying to fetch
does not exist.
If you are using the second parameter of the $this->config->load
diff --git a/user_guide_src/source/libraries/file_uploading.rst b/user_guide_src/source/libraries/file_uploading.rst
index a92d3af34..a295d7427 100644
--- a/user_guide_src/source/libraries/file_uploading.rst
+++ b/user_guide_src/source/libraries/file_uploading.rst
@@ -83,7 +83,7 @@ place this code and save it to your **application/views/** directory::
The Controller
==============
-Using a text editor, create a controller called upload.php. In it, place
+Using a text editor, create a controller called Upload.php. In it, place
this code and save it to your **application/controllers/** directory::
<?php
diff --git a/user_guide_src/source/libraries/form_validation.rst b/user_guide_src/source/libraries/form_validation.rst
index 8b35fdc75..8534175bb 100644
--- a/user_guide_src/source/libraries/form_validation.rst
+++ b/user_guide_src/source/libraries/form_validation.rst
@@ -431,7 +431,7 @@ Here's how your controller should now look::
}
}
- protected function username_check($str)
+ public function username_check($str)
{
if ($str == 'test')
{
@@ -866,6 +866,7 @@ Rule Parameter Description
**is_unique** Yes Returns FALSE if the form element is not unique to the table and field name in the is_unique[table.field]
parameter. Note: This rule requires :doc:`Query Builder <../database/query_builder>` to be
enabled in order to work.
+**min_length** Yes Returns FALSE if the form element is shorter then the parameter value. min_length[3]
**max_length** Yes Returns FALSE if the form element is longer then the parameter value. max_length[12]
**exact_length** Yes Returns FALSE if the form element is not exactly the parameter value. exact_length[8]
**greater_than** Yes Returns FALSE if the form element is less than or equal to the parameter value or not greater_than[8]
diff --git a/user_guide_src/source/libraries/input.rst b/user_guide_src/source/libraries/input.rst
index 177f5cb64..fb245d7cd 100644
--- a/user_guide_src/source/libraries/input.rst
+++ b/user_guide_src/source/libraries/input.rst
@@ -98,7 +98,7 @@ The method returns NULL if there are no items in the POST.
$this->input->get()
===================
-This method is identical to the post method, only it fetches get data
+This method is identical to the POST method, only it fetches GET data
::
$this->input->get('some_data', TRUE);
@@ -116,18 +116,26 @@ The method returns NULL if there are no items in the GET.
$this->input->get(); // returns all GET items without XSS filtering
+$this->input->post_get()
+========================
+
+This method will search through both the POST and GET streams for
+data, looking first in POST, and then in GET::
+
+ $this->input->post_get('some_data', TRUE);
+
$this->input->get_post()
========================
-This method will search through both the post and get streams for
-data, looking first in post, and then in get::
+This method will search through both the POST and GET streams for
+data, looking first in GET, and then in POST::
$this->input->get_post('some_data', TRUE);
$this->input->cookie()
======================
-This method is identical to the post method, only it fetches cookie data
+This method is identical to the POST method, only it fetches cookie data
::
$this->input->cookie('some_cookie');
diff --git a/user_guide_src/source/libraries/loader.rst b/user_guide_src/source/libraries/loader.rst
index b048f4881..91db5afbd 100644
--- a/user_guide_src/source/libraries/loader.rst
+++ b/user_guide_src/source/libraries/loader.rst
@@ -192,7 +192,7 @@ $this->load->model('model_name');
If your model is located in a subdirectory, include the relative path
from your models directory. For example, if you have a model located at
-application/models/blog/queries.php you'll load it using::
+application/models/blog/Queries.php you'll load it using::
$this->load->model('blog/queries');
@@ -234,6 +234,11 @@ $this->load->get_vars()
This method retrieves all variables available to your views.
+$this->load->clear_vars()
+=========================
+
+Clears cached view variables.
+
$this->load->helper('file_name')
================================
@@ -261,6 +266,32 @@ $this->load->config('file_name')
This method is an alias of the :doc:`config file loading
method <config>`: ``$this->config->load()``
+$this->load->is_loaded('library_name')
+======================================
+
+The ``is_loaded()`` method allows you to check if a class has already
+been loaded or not.
+
+.. note:: The word "class" here refers to libraries and drivers.
+
+If the requested class has been loaded, the method returns its assigned
+name in the CI Super-object and FALSE if it's not::
+
+ $this->load->library('form_validation');
+ $this->load->is_loaded('Form_validation'); // returns 'form_validation'
+
+ $this->load->is_loaded('Nonexistent_library'); // returns FALSE
+
+.. important:: If you have more than one instance of a class (assigned to
+ different properties), then the first one will be returned.
+
+::
+
+ $this->load->library('form_validation', $config, 'fv');
+ $this->load->library('form_validation');
+
+ $this->load->is_loaded('Form_validation'); // returns 'fv'
+
Application "Packages"
======================
diff --git a/user_guide_src/source/libraries/migration.rst b/user_guide_src/source/libraries/migration.rst
index b734f5c34..9dc3c08da 100644
--- a/user_guide_src/source/libraries/migration.rst
+++ b/user_guide_src/source/libraries/migration.rst
@@ -86,7 +86,7 @@ Then in **application/config/migration.php** set **$config['migration_version']
Usage Example
*************
-In this example some simple code is placed in **application/controllers/migrate.php**
+In this example some simple code is placed in **application/controllers/Migrate.php**
to update the schema.::
<?php
diff --git a/user_guide_src/source/libraries/xmlrpc.rst b/user_guide_src/source/libraries/xmlrpc.rst
index a43c48837..d2d695ee3 100644
--- a/user_guide_src/source/libraries/xmlrpc.rst
+++ b/user_guide_src/source/libraries/xmlrpc.rst
@@ -296,7 +296,7 @@ Client to send a request to the Server and receive a response.
The Client
----------
-Using a text editor, create a controller called xmlrpc_client.php. In
+Using a text editor, create a controller called Xmlrpc_client.php. In
it, place this code and save it to your application/controllers/
folder::
@@ -337,7 +337,7 @@ folder::
The Server
----------
-Using a text editor, create a controller called xmlrpc_server.php. In
+Using a text editor, create a controller called Xmlrpc_server.php. In
it, place this code and save it to your application/controllers/
folder::
diff --git a/user_guide_src/source/tutorial/news_section.rst b/user_guide_src/source/tutorial/news_section.rst
index d7754e9f3..ad9ed41d3 100644
--- a/user_guide_src/source/tutorial/news_section.rst
+++ b/user_guide_src/source/tutorial/news_section.rst
@@ -16,7 +16,7 @@ are the place where you retrieve, insert, and update information in your
database or other data stores. They represent your data.
Open up the application/models directory and create a new file called
-news_model.php and add the following code. Make sure you've configured
+News_model.php and add the following code. Make sure you've configured
your database properly as described
`here <../database/configuration.html>`_.
@@ -85,7 +85,7 @@ Now that the queries are written, the model should be tied to the views
that are going to display the news items to the user. This could be done
in our pages controller created earlier, but for the sake of clarity, a
new "news" controller is defined. Create the new controller at
-application/controllers/news.php.
+application/controllers/News.php.
::
@@ -127,7 +127,7 @@ the views.
public function index()
{
- data['news'] = $this->news_model->get_news();
+ $data['news'] = $this->news_model->get_news();
$data['title'] = 'News archive';
$this->load->view('templates/header', $data);
diff --git a/user_guide_src/source/tutorial/static_pages.rst b/user_guide_src/source/tutorial/static_pages.rst
index 97c74601d..330a50ecf 100644
--- a/user_guide_src/source/tutorial/static_pages.rst
+++ b/user_guide_src/source/tutorial/static_pages.rst
@@ -20,7 +20,7 @@ match:
As URL schemes become more complex, this may change. But for now, this
is all we will need to know.
-Create a file at application/controllers/pages.php with the following
+Create a file at application/controllers/Pages.php with the following
code.
::