summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordchill42 <dchill42@gmail.com>2012-10-10 14:16:39 +0200
committerdchill42 <dchill42@gmail.com>2012-10-10 14:16:39 +0200
commit2716398bd2f2ae36d7420c591fc759e0951ba0e2 (patch)
tree3845d6bacc5660559740a8eddd43210bbb14fefd
parenteeb6a480a4a25b7fe96e9ba0cf3aef273fd13c67 (diff)
parente8bc5f4450381b4f978f274f3e93604301115b64 (diff)
Merge branch 'develop' of github.com:/EllisLab/CodeIgniter into load_config_units
-rw-r--r--.gitignore3
-rw-r--r--.travis.yml5
-rw-r--r--application/config/autoload.php29
-rw-r--r--application/config/config.php21
-rw-r--r--application/config/constants.php16
-rw-r--r--application/config/database.php2
-rw-r--r--application/config/foreign_chars.php24
-rw-r--r--application/config/mimes.php4
-rw-r--r--application/views/errors/error_404.php8
-rw-r--r--application/views/errors/error_db.php8
-rw-r--r--application/views/errors/error_general.php8
-rw-r--r--application/views/welcome_message.php13
-rw-r--r--composer.json5
-rw-r--r--contributing.md92
-rw-r--r--readme.rst160
-rw-r--r--system/core/Common.php19
-rw-r--r--system/core/Config.php2
-rw-r--r--system/core/Input.php143
-rw-r--r--system/core/Loader.php6
-rw-r--r--system/core/Output.php4
-rw-r--r--system/database/DB_driver.php17
-rw-r--r--system/database/DB_query_builder.php19
-rw-r--r--system/database/drivers/cubrid/cubrid_driver.php26
-rw-r--r--system/database/drivers/ibase/ibase_driver.php20
-rw-r--r--system/database/drivers/mssql/mssql_driver.php20
-rw-r--r--system/database/drivers/mysql/mysql_driver.php42
-rw-r--r--system/database/drivers/mysqli/mysqli_driver.php54
-rw-r--r--system/database/drivers/oci8/oci8_driver.php20
-rw-r--r--system/database/drivers/odbc/odbc_driver.php18
-rw-r--r--system/database/drivers/pdo/pdo_driver.php4
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_4d_driver.php16
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php24
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php16
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php16
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php16
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_informix_driver.php16
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php24
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_oci_driver.php16
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php17
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php16
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php16
-rw-r--r--system/database/drivers/postgre/postgre_driver.php20
-rw-r--r--system/database/drivers/sqlite/sqlite_driver.php4
-rw-r--r--system/database/drivers/sqlite3/sqlite3_driver.php25
-rw-r--r--system/database/drivers/sqlsrv/sqlsrv_driver.php20
-rw-r--r--system/helpers/captcha_helper.php3
-rw-r--r--system/helpers/date_helper.php131
-rw-r--r--system/helpers/directory_helper.php2
-rw-r--r--system/helpers/text_helper.php3
-rw-r--r--system/helpers/url_helper.php2
-rw-r--r--system/language/english/date_lang.php28
-rw-r--r--system/language/english/form_validation_lang.php4
-rw-r--r--system/libraries/Driver.php4
-rw-r--r--system/libraries/Email.php36
-rw-r--r--system/libraries/Encrypt.php4
-rw-r--r--system/libraries/Image_lib.php7
-rw-r--r--system/libraries/Pagination.php19
-rwxr-xr-xsystem/libraries/Session/Session.php182
-rwxr-xr-xsystem/libraries/Session/drivers/Session_cookie.php149
-rwxr-xr-xsystem/libraries/Session/drivers/Session_native.php74
-rw-r--r--system/libraries/Unit_test.php5
-rwxr-xr-x[-rw-r--r--]system/libraries/Xmlrpc.php10
-rw-r--r--tests/Bootstrap.php1
-rw-r--r--tests/codeigniter/database/query_builder/escape_test.php4
-rw-r--r--tests/codeigniter/helpers/date_helper_test.php23
-rw-r--r--tests/codeigniter/helpers/directory_helper_test.php4
-rw-r--r--tests/codeigniter/libraries/Calendar_test.php204
-rw-r--r--tests/codeigniter/libraries/Session_test.php17
-rw-r--r--tests/codeigniter/libraries/Upload_test.php270
-rw-r--r--tests/mocks/core/input.php10
-rw-r--r--tests/mocks/core/lang.php15
-rw-r--r--tests/mocks/libraries/calendar.php25
-rw-r--r--tests/mocks/libraries/upload.php3
-rw-r--r--tests/mocks/uploads/ci_logo.gifbin0 -> 3270 bytes
-rw-r--r--tests/travis/mysql.phpunit.xml2
-rw-r--r--tests/travis/pdo/mysql.phpunit.xml2
-rw-r--r--tests/travis/pdo/pgsql.phpunit.xml2
-rw-r--r--tests/travis/pdo/sqlite.phpunit.xml2
-rw-r--r--tests/travis/pgsql.phpunit.xml2
-rw-r--r--tests/travis/sqlite.phpunit.xml2
-rw-r--r--user_guide_src/source/changelog.rst148
-rw-r--r--user_guide_src/source/database/configuration.rst7
-rw-r--r--user_guide_src/source/general/cli.rst2
-rw-r--r--user_guide_src/source/general/reserved_names.rst2
-rw-r--r--user_guide_src/source/helpers/captcha_helper.rst2
-rw-r--r--user_guide_src/source/helpers/date_helper.rst24
-rw-r--r--user_guide_src/source/helpers/url_helper.rst6
-rw-r--r--user_guide_src/source/images/codeigniter_1.7.1_library_reference.pngbin111744 -> 111747 bytes
-rw-r--r--user_guide_src/source/installation/upgrade_300.rst26
-rw-r--r--user_guide_src/source/libraries/email.rst7
-rw-r--r--user_guide_src/source/libraries/file_uploading.rst1
-rw-r--r--user_guide_src/source/libraries/form_validation.rst19
-rw-r--r--user_guide_src/source/libraries/image_lib.rst23
-rw-r--r--user_guide_src/source/libraries/loader.rst2
-rw-r--r--user_guide_src/source/libraries/migration.rst134
-rw-r--r--user_guide_src/source/libraries/output.rst3
-rw-r--r--user_guide_src/source/libraries/pagination.rst4
-rw-r--r--user_guide_src/source/libraries/trackback.rst2
-rw-r--r--user_guide_src/source/overview/cheatsheets.rst15
99 files changed, 1856 insertions, 896 deletions
diff --git a/.gitignore b/.gitignore
index 11fb6d67c..a035c2b27 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,4 +11,5 @@ application/logs/*
user_guide_src/build/*
user_guide_src/cilexer/build/*
user_guide_src/cilexer/dist/*
-user_guide_src/cilexer/pycilexer.egg-info/* \ No newline at end of file
+user_guide_src/cilexer/pycilexer.egg-info/*
+/vendor/ \ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 2496def0b..62acf05e5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,6 +3,11 @@ language: php
php:
- 5.3
- 5.4
+
+services:
+ - mysql
+ - postgresql
+ - sqlite
env:
- DB=mysql
diff --git a/application/config/autoload.php b/application/config/autoload.php
index b3e63cbf6..ff153fb48 100644
--- a/application/config/autoload.php
+++ b/application/config/autoload.php
@@ -46,10 +46,11 @@
|
| 1. Packages
| 2. Libraries
-| 3. Helper files
-| 4. Custom config files
-| 5. Language files
-| 6. Models
+| 3. Drivers
+| 4. Helper files
+| 5. Custom config files
+| 6. Language files
+| 7. Models
|
*/
@@ -75,7 +76,7 @@ $autoload['packages'] = array();
|
| Prototype:
|
-| $autoload['libraries'] = array('database', 'session', 'xmlrpc');
+| $autoload['libraries'] = array('database', 'email', 'xmlrpc');
*/
$autoload['libraries'] = array();
@@ -83,6 +84,22 @@ $autoload['libraries'] = array();
/*
| -------------------------------------------------------------------
+| Auto-load Drivers
+| -------------------------------------------------------------------
+| These classes are located in the system/libraries folder or in your
+| application/libraries folder within their own subdirectory. They
+| offer multiple interchangeable driver options.
+|
+| Prototype:
+|
+| $autoload['drivers'] = array('session', 'cache');
+*/
+
+$autoload['drivers'] = array();
+
+
+/*
+| -------------------------------------------------------------------
| Auto-load Helper Files
| -------------------------------------------------------------------
| Prototype:
@@ -139,4 +156,4 @@ $autoload['model'] = array();
/* End of file autoload.php */
-/* Location: ./application/config/autoload.php */ \ No newline at end of file
+/* Location: ./application/config/autoload.php */
diff --git a/application/config/config.php b/application/config/config.php
index 28fc406d1..ab1508e7b 100644
--- a/application/config/config.php
+++ b/application/config/config.php
@@ -265,6 +265,9 @@ $config['encryption_key'] = '';
| Session Variables
|--------------------------------------------------------------------------
|
+| '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_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.
@@ -278,6 +281,8 @@ $config['encryption_key'] = '';
| 'sess_time_to_update' = how many seconds between CI refreshing Session Information
|
*/
+$config['sess_driver'] = 'cookie';
+$config['sess_valid_drivers'] = array();
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 7200;
$config['sess_expire_on_close'] = FALSE;
@@ -401,15 +406,19 @@ $config['rewrite_short_tags'] = FALSE;
| Reverse Proxy IPs
|--------------------------------------------------------------------------
|
-| If your server is behind a reverse proxy, you must whitelist the proxy IP
-| addresses from which CodeIgniter should trust the HTTP_X_FORWARDED_FOR
-| header in order to properly identify the visitor's IP address.
-| Comma-delimited, e.g. '10.0.1.200,10.0.1.201'
+| If your server is behind a reverse proxy, you must whitelist the proxy
+| IP addresses from which CodeIgniter should trust headers such as
+| HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify
+| the visitor's IP address.
|
+| You can use both an array or a comma-separated list of proxy addresses,
+| as well as specifying whole subnets. Here are a few examples:
+|
+| Comma-separated: '10.0.1.200,192.168.5.0/24'
+| Array: array('10.0.1.200', '192.168.5.0/24')
*/
$config['proxy_ips'] = '';
-
/* End of file config.php */
-/* Location: ./application/config/config.php */
+/* Location: ./application/config/config.php */ \ No newline at end of file
diff --git a/application/config/constants.php b/application/config/constants.php
index d22d2963e..62a18e761 100644
--- a/application/config/constants.php
+++ b/application/config/constants.php
@@ -52,14 +52,14 @@ define('DIR_WRITE_MODE', 0777);
|
*/
-define('FOPEN_READ', 'rb');
-define('FOPEN_READ_WRITE', 'r+b');
-define('FOPEN_WRITE_CREATE_DESTRUCTIVE', 'wb'); // truncates existing file data, use with care
-define('FOPEN_READ_WRITE_CREATE_DESTRUCTIVE', 'w+b'); // truncates existing file data, use with care
-define('FOPEN_WRITE_CREATE', 'ab');
-define('FOPEN_READ_WRITE_CREATE', 'a+b');
-define('FOPEN_WRITE_CREATE_STRICT', 'xb');
-define('FOPEN_READ_WRITE_CREATE_STRICT', 'x+b');
+define('FOPEN_READ', 'rb');
+define('FOPEN_READ_WRITE', 'r+b');
+define('FOPEN_WRITE_CREATE_DESTRUCTIVE', 'wb'); // truncates existing file data, use with care
+define('FOPEN_READ_WRITE_CREATE_DESTRUCTIVE', 'w+b'); // truncates existing file data, use with care
+define('FOPEN_WRITE_CREATE', 'ab');
+define('FOPEN_READ_WRITE_CREATE', 'a+b');
+define('FOPEN_WRITE_CREATE_STRICT', 'xb');
+define('FOPEN_READ_WRITE_CREATE_STRICT', 'x+b');
/*
|--------------------------------------------------------------------------
diff --git a/application/config/database.php b/application/config/database.php
index bb0d87be0..4c5cad03f 100644
--- a/application/config/database.php
+++ b/application/config/database.php
@@ -63,6 +63,7 @@
| Sites using Latin-1 or UTF-8 database character set and collation are unaffected.
| ['swap_pre'] A default table prefix that should be swapped with the dbprefix
| ['autoinit'] Whether or not to automatically initialize the database.
+| ['compress'] Whether or not to use client compression (only MySQL and MySQLi)
| ['stricton'] TRUE/FALSE - forces 'Strict Mode' connections
| - good for ensuring strict SQL while developing
| ['failover'] array - A array with 0 or more data for connections if the main should fail.
@@ -93,6 +94,7 @@ $db['default'] = array(
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',
'autoinit' => TRUE,
+ 'compress' => TRUE,
'stricton' => FALSE,
'failover' => array()
);
diff --git a/application/config/foreign_chars.php b/application/config/foreign_chars.php
index 41de123da..6614caa31 100644
--- a/application/config/foreign_chars.php
+++ b/application/config/foreign_chars.php
@@ -40,20 +40,20 @@ $foreign_characters = array(
'/Ä/' => 'Ae',
'/Ü/' => 'Ue',
'/Ö/' => 'Oe',
- '/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ|Α|Ά/' => 'A',
- '/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª|α|ά/' => 'a',
+ '/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ|Α|Ά|Ả|Ạ|Ầ|Ẫ|Ẩ|Ậ|Ằ|Ắ|Ẵ|Ẳ|Ặ/' => 'A',
+ '/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª|α|ά|ả|ạ|ầ|ấ|ẫ|ẩ|ậ|ằ|ắ|ẵ|ẳ|ặ/' => 'a',
'/Ç|Ć|Ĉ|Ċ|Č/' => 'C',
'/ç|ć|ĉ|ċ|č/' => 'c',
'/Ð|Ď|Đ|Δ/' => 'Dj',
'/ð|ď|đ|δ/' => 'dj',
- '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Ε|Έ/' => 'E',
- '/è|é|ê|ë|ē|ĕ|ė|ę|ě|έ|ε/' => 'e',
+ '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Ε|Έ|Ẽ|Ẻ|Ẹ|Ề|Ế|Ễ|Ể|Ệ/' => 'E',
+ '/è|é|ê|ë|ē|ĕ|ė|ę|ě|έ|ε|ẽ|ẻ|ẹ|ề|ế|ễ|ể|ệ/' => 'e',
'/Ĝ|Ğ|Ġ|Ģ|Γ/' => 'G',
'/ĝ|ğ|ġ|ģ|γ/' => 'g',
'/Ĥ|Ħ/' => 'H',
'/ĥ|ħ/' => 'h',
- '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|Η|Ή|Ί|Ι|Ϊ/' => 'I',
- '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|η|ή|ί|ι|ϊ/' => 'i',
+ '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|Η|Ή|Ί|Ι|Ϊ|Ỉ|Ị/' => 'I',
+ '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|η|ή|ί|ι|ϊ|ỉ|ị/' => 'i',
'/Ĵ/' => 'J',
'/ĵ/' => 'j',
'/Ķ|Κ/' => 'K',
@@ -62,18 +62,18 @@ $foreign_characters = array(
'/ĺ|ļ|ľ|ŀ|ł|λ/' => 'l',
'/Ñ|Ń|Ņ|Ň|Ν/' => 'N',
'/ñ|ń|ņ|ň|ʼn|ν/' => 'n',
- '/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ|Ο|Ό|Ω|Ώ/' => 'O',
- '/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º|ο|ό|ω|ώ/' => 'o',
+ '/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ|Ο|Ό|Ω|Ώ|Ỏ|Ọ|Ồ|Ố|Ỗ|Ổ|Ộ|Ờ|Ớ|Ỡ|Ở|Ợ/' => 'O',
+ '/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º|ο|ό|ω|ώ|ỏ|ọ|ồ|ố|ỗ|ổ|ộ|ờ|ớ|ỡ|ở|ợ/' => 'o',
'/Ŕ|Ŗ|Ř|Ρ/' => 'R',
'/ŕ|ŗ|ř|ρ/' => 'r',
'/Ś|Ŝ|Ş|Ș|Š|Σ/' => 'S',
'/ś|ŝ|ş|ș|š|ſ|σ|ς/' => 's',
'/Ț|Ţ|Ť|Ŧ|τ/' => 'T',
'/ț|ţ|ť|ŧ/' => 't',
- '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ/' => 'U',
- '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|υ|ύ|ϋ/' => 'u',
- '/Ý|Ÿ|Ŷ|Υ|Ύ|Ϋ/' => 'Y',
- '/ý|ÿ|ŷ/' => 'y',
+ '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|Ũ|Ủ|Ụ|Ừ|Ứ|Ữ|Ử|Ự/' => 'U',
+ '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|υ|ύ|ϋ|ủ|ụ|ừ|ứ|ữ|ử|ự/' => 'u',
+ '/Ý|Ÿ|Ŷ|Υ|Ύ|Ϋ|Ỳ|Ỹ|Ỷ|Ỵ/' => 'Y',
+ '/ý|ÿ|ŷ|ỳ|ỹ|ỷ|ỵ/' => 'y',
'/Ŵ/' => 'W',
'/ŵ/' => 'w',
'/Ź|Ż|Ž|Ζ/' => 'Z',
diff --git a/application/config/mimes.php b/application/config/mimes.php
index 48771dc15..90ffe61ff 100644
--- a/application/config/mimes.php
+++ b/application/config/mimes.php
@@ -49,7 +49,7 @@ return array(
'sea' => 'application/octet-stream',
'dll' => 'application/octet-stream',
'oda' => 'application/oda',
- 'pdf' => array('application/pdf', 'application/x-download'),
+ 'pdf' => array('application/pdf', 'application/x-download', 'binary/octet-stream'),
'ai' => 'application/postscript',
'eps' => 'application/postscript',
'ps' => 'application/postscript',
@@ -124,6 +124,8 @@ return array(
'movie' => 'video/x-sgi-movie',
'doc' => array('application/msword', 'application/vnd.ms-office'),
'docx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword'),
+ 'dot' => array('application/msword', 'application/vnd.ms-office'),
+ 'dotx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword'),
'xlsx' => array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip', 'application/vnd.ms-excel', 'application/msword'),
'word' => array('application/msword', 'application/octet-stream'),
'xl' => 'application/excel',
diff --git a/application/views/errors/error_404.php b/application/views/errors/error_404.php
index c19bedfcd..fe48fd524 100644
--- a/application/views/errors/error_404.php
+++ b/application/views/errors/error_404.php
@@ -31,9 +31,9 @@
<title>404 Page Not Found</title>
<style type="text/css">
-::selection{ background-color: #E13300; color: white; }
-::moz-selection{ background-color: #E13300; color: white; }
-::webkit-selection{ background-color: #E13300; color: white; }
+::selection { background-color: #E13300; color: white; }
+::-moz-selection { background-color: #E13300; color: white; }
+::-webkit-selection { background-color: #E13300; color: white; }
body {
background-color: #fff;
@@ -73,6 +73,8 @@ code {
margin: 10px;
border: 1px solid #D0D0D0;
box-shadow: 0 0 8px #D0D0D0;
+ -moz-box-shadow: 0 0 8px #D0D0D0;
+ -webkit-box-shadow: 0 0 8px #D0D0D0;
}
p {
diff --git a/application/views/errors/error_db.php b/application/views/errors/error_db.php
index 3b244e094..76ca6df7a 100644
--- a/application/views/errors/error_db.php
+++ b/application/views/errors/error_db.php
@@ -31,9 +31,9 @@
<title>Database Error</title>
<style type="text/css">
-::selection{ background-color: #E13300; color: white; }
-::moz-selection{ background-color: #E13300; color: white; }
-::webkit-selection{ background-color: #E13300; color: white; }
+::selection { background-color: #E13300; color: white; }
+::-moz-selection { background-color: #E13300; color: white; }
+::-webkit-selection { background-color: #E13300; color: white; }
body {
background-color: #fff;
@@ -73,6 +73,8 @@ code {
margin: 10px;
border: 1px solid #D0D0D0;
box-shadow: 0 0 8px #D0D0D0;
+ -moz-box-shadow: 0 0 8px #D0D0D0;
+ -webkit-box-shadow: 0 0 8px #D0D0D0;
}
p {
diff --git a/application/views/errors/error_general.php b/application/views/errors/error_general.php
index c88afe168..e9baf1665 100644
--- a/application/views/errors/error_general.php
+++ b/application/views/errors/error_general.php
@@ -31,9 +31,9 @@
<title>Error</title>
<style type="text/css">
-::selection{ background-color: #E13300; color: white; }
-::moz-selection{ background-color: #E13300; color: white; }
-::webkit-selection{ background-color: #E13300; color: white; }
+::selection { background-color: #E13300; color: white; }
+::-moz-selection { background-color: #E13300; color: white; }
+::-webkit-selection { background-color: #E13300; color: white; }
body {
background-color: #fff;
@@ -73,6 +73,8 @@ code {
margin: 10px;
border: 1px solid #D0D0D0;
box-shadow: 0 0 8px #D0D0D0;
+ -moz-box-shadow: 0 0 8px #D0D0D0;
+ -webkit-box-shadow: 0 0 8px #D0D0D0;
}
p {
diff --git a/application/views/welcome_message.php b/application/views/welcome_message.php
index 65f62a922..d227f82d1 100644
--- a/application/views/welcome_message.php
+++ b/application/views/welcome_message.php
@@ -32,9 +32,9 @@
<style type="text/css">
- ::selection{ background-color: #E13300; color: white; }
- ::moz-selection{ background-color: #E13300; color: white; }
- ::webkit-selection{ background-color: #E13300; color: white; }
+ ::selection { background-color: #E13300; color: white; }
+ ::-moz-selection { background-color: #E13300; color: white; }
+ ::-webkit-selection { background-color: #E13300; color: white; }
body {
background-color: #fff;
@@ -70,11 +70,11 @@
padding: 12px 10px 12px 10px;
}
- #body{
+ #body {
margin: 0 15px 0 15px;
}
- p.footer{
+ p.footer {
text-align: right;
font-size: 11px;
border-top: 1px solid #D0D0D0;
@@ -83,9 +83,10 @@
margin: 20px 0 0 0;
}
- #container{
+ #container {
margin: 10px;
border: 1px solid #D0D0D0;
+ -moz-box-shadow: 0 0 8px #D0D0D0;
-webkit-box-shadow: 0 0 8px #D0D0D0;
}
</style>
diff --git a/composer.json b/composer.json
index fa6dc02e4..dc098acc3 100644
--- a/composer.json
+++ b/composer.json
@@ -1,5 +1,8 @@
{
"require": {
"mikey179/vfsStream": "*"
- }
+ },
+ "require-dev": {
+ "EHER/PHPUnit": "*"
+ }
} \ No newline at end of file
diff --git a/contributing.md b/contributing.md
new file mode 100644
index 000000000..f3f94fbc8
--- /dev/null
+++ b/contributing.md
@@ -0,0 +1,92 @@
+# Contributing to CodeIgniter
+
+
+CodeIgniter is a community driven project and accepts contributions of code and documentation from the community. These contributions are made in the form of Issues or [Pull Requests](http://help.github.com/send-pull-requests/) on the [EllisLab CodeIgniter repository](https://github.com/EllisLab/CodeIgniter>) on GitHub.
+
+Issues are a quick way to point out a bug. If you find a bug or documentation error in CodeIgniter then please check a few things first:
+
+1. There is not already an open Issue
+2. The issue has already been fixed (check the develop branch, or look for closed Issues)
+3. Is it something really obvious that you fix it yourself?
+
+Reporting issues is helpful but an even better approach is to send a Pull Request, which is done by "Forking" the main repository and committing to your own copy. This will require you to use the version control system called Git.
+
+## Guidelines
+
+Before we look into how, here are the guidelines. If your Pull Requests fail
+to pass these guidelines it will be declined and you will need to re-submit
+when you’ve made the changes. This might sound a bit tough, but it is required
+for us to maintain quality of the code-base.
+
+### PHP Style
+
+All code must meet the [Style Guide](http://codeigniter.com/user_guide/general/styleguide.html), which is
+essentially the [Allman indent style](http://en.wikipedia.org/wiki/Indent_style#Allman_style), underscores and readable operators. This makes certain that all code is the same format as the existing code and means it will be as readable as possible.
+
+### Documentation
+
+If you change anything that requires a change to documentation then you will need to add it. New classes, methods, parameters, changing default values, etc are all things that will require a change to documentation. The change-log must also be updated for every change. Also PHPDoc blocks must be maintained.
+
+### Compatibility
+
+CodeIgniter is compatible with PHP 5.2.4 so all code supplied must stick to
+this requirement. If PHP 5.3 or 5.4 functions or features are used then there
+must be a fallback for PHP 5.2.4.
+
+### Branching
+
+CodeIgniter uses the [Git-Flow](http://nvie.com/posts/a-successful-git-branching-model/) branching model which requires all pull requests to be sent to the "develop" branch. This is
+where the next planned version will be developed. The "master" branch will always contain the latest stable version and is kept clean so a "hotfix" (e.g: an emergency security patch) can be applied to master to create a new version, without worrying about other features holding it up. For this reason all commits need to be made to "develop" and any sent to "master" will be closed automatically. If you have multiple changes to submit, please place all changes into their own branch on your fork.
+
+One thing at a time: A pull request should only contain one change. That does not mean only one commit, but one change - however many commits it took. The reason for this is that if you change X and Y but send a pull request for both at the same time, we might really want X but disagree with Y, meaning we cannot merge the request. Using the Git-Flow branching model you can create new branches for both of these features and send two requests.
+
+### Signing
+
+You must sign your work, certifying that you either wrote the work or otherwise have the right to pass it on to an open source project. git makes this trivial as you merely have to use `--signoff` on your commits to your CodeIgniter fork.
+
+`git commit --signoff`
+
+or simply
+
+`git commit -s`
+
+This will sign your commits with the information setup in your git config, e.g.
+
+`Signed-off-by: John Q Public <john.public@example.com>`
+
+If you are using [Tower](http://www.git-tower.com/) there is a "Sign-Off" checkbox in the commit window. You could even alias git commit to use the `-s` flag so you don’t have to think about it.
+
+By signing your work in this manner, you certify to a "Developer's Certificate of Origin". The current version of this certificate is in the `DCO.txt` file in the root of this repository.
+
+
+## How-to Guide
+
+There are two ways to make changes, the easy way and the hard way. Either way you will need to [create a GitHub account](https://github.com/signup/free).
+
+Easy way GitHub allows in-line editing of files for making simple typo changes and quick-fixes. This is not the best way as you are unable to test the code works. If you do this you could be introducing syntax errors, etc, but for a Git-phobic user this is good for a quick-fix.
+
+Hard way The best way to contribute is to "clone" your fork of CodeIgniter to your development area. That sounds like some jargon, but "forking" on GitHub means "making a copy of that repo to your account" and "cloning" means "copying that code to your environment so you can work on it".
+
+1. Set up Git (Windows, Mac & Linux)
+2. Go to the CodeIgniter repo
+3. Fork it
+4. Clone your CodeIgniter repo: git@github.com:<your-name>/CodeIgniter.git
+5. Checkout the "develop" branch At this point you are ready to start making changes.
+6. Fix existing bugs on the Issue tracker after taking a look to see nobody else is working on them.
+7. Commit the files
+8. Push your develop branch to your fork
+9. Send a pull request [http://help.github.com/send-pull-requests/](http://help.github.com/send-pull-requests/)
+
+The Reactor Engineers will now be alerted about the change and at least one of the team will respond. If your change fails to meet the guidelines it will be bounced, or feedback will be provided to help you improve it.
+
+Once the Reactor Engineer handling your pull request is happy with it they will post it to the internal EllisLab discussion area to be double checked by the other Engineers and EllisLab developers. If nobody has a problem with the change then it will be merged into develop and will be part of the next release. Keeping your fork up-to-date
+
+Unlike systems like Subversion, Git can have multiple remotes. A remote is the name for a URL of a Git repository. By default your fork will have a remote named "origin" which points to your fork, but you can add another remote named "codeigniter" which points to `git://github.com/EllisLab/CodeIgniter.git`. This is a read-only remote but you can pull from this develop branch to update your own.
+
+If you are using command-line you can do the following:
+
+1. `git remote add codeigniter git://github.com/EllisLab/CodeIgniter.git`
+2. `git pull codeigniter develop`
+3. `git push origin develop`
+
+Now your fork is up to date. This should be done regularly, or before you send a pull request at least. \ No newline at end of file
diff --git a/readme.rst b/readme.rst
index b211ad7cd..8628645c6 100644
--- a/readme.rst
+++ b/readme.rst
@@ -38,166 +38,6 @@ Installation
Please see the `installation section <http://codeigniter.com/user_guide/installation/index.html>`_
of the CodeIgniter User Guide.
-************
-Contributing
-************
-
-CodeIgniter is a community driven project and accepts contributions of code
-and documentation from the community. These contributions are made in the form
-of Issues or `Pull Requests <http://help.github.com/send-pull-requests/>`_ on
-the `EllisLab CodeIgniter repository
-<https://github.com/EllisLab/CodeIgniter>`_ on GitHub.
-
-Issues are a quick way to point out a bug. If you find a bug or documentation
-error in CodeIgniter then please check a few things first:
-
-- There is not already an open Issue
-- The issue has already been fixed (check the develop branch, or look for
- closed Issues)
-- Is it something really obvious that you fix it yourself?
-
-Reporting issues is helpful but an even better approach is to send a Pull
-Request, which is done by "Forking" the main repository and committing to your
-own copy. This will require you to use the version control system called Git.
-
-**********
-Guidelines
-**********
-
-Before we look into how, here are the guidelines. If your Pull Requests fail
-to pass these guidelines it will be declined and you will need to re-submit
-when you’ve made the changes. This might sound a bit tough, but it is required
-for us to maintain quality of the code-base.
-
-PHP Style
-=========
-
-All code must meet the `Style Guide
-<http://codeigniter.com/user_guide/general/styleguide.html>`_, which is
-essentially the `Allman indent style
-<http://en.wikipedia.org/wiki/Indent_style#Allman_style>`_, underscores and
-readable operators. This makes certain that all code is the same format as the
-existing code and means it will be as readable as possible.
-
-Documentation
-=============
-
-If you change anything that requires a change to documentation then you will
-need to add it. New classes, methods, parameters, changing default values, etc
-are all things that will require a change to documentation. The change-log
-must also be updated for every change. Also PHPDoc blocks must be maintained.
-
-Compatibility
-=============
-
-CodeIgniter is compatible with PHP 5.2.4 so all code supplied must stick to
-this requirement. If PHP 5.3 or 5.4 functions or features are used then there
-must be a fallback for PHP 5.2.4.
-
-Branching
-=========
-
-CodeIgniter uses the `Git-Flow
-<http://nvie.com/posts/a-successful-git-branching-model/>`_ branching model
-which requires all pull requests to be sent to the "develop" branch. This is
-where the next planned version will be developed. The "master" branch will
-always contain the latest stable version and is kept clean so a "hotfix" (e.g:
-an emergency security patch) can be applied to master to create a new version,
-without worrying about other features holding it up. For this reason all
-commits need to be made to "develop" and any sent to "master" will be closed
-automatically. If you have multiple changes to submit, please place all
-changes into their own branch on your fork.
-
-One thing at a time: A pull request should only contain one change. That does
-not mean only one commit, but one change - however many commits it took. The
-reason for this is that if you change X and Y but send a pull request for both
-at the same time, we might really want X but disagree with Y, meaning we
-cannot merge the request. Using the Git-Flow branching model you can create
-new branches for both of these features and send two requests.
-
-Signing
-=======
-You must sign your work, certifying that you either wrote the work or
-otherwise have the right to pass it on to an open source project. git makes
-this trivial as you merely have to use `--signoff` on your commits to your
-CodeIgniter fork.
-
-::
-
- git commit --signoff
-
-or simply::
-
- git commit -s
-
-This will sign your commits with the information setup in your git config, e.g.
-
- Signed-off-by: John Q Public <john.public@example.com>
-
-If you are using Tower there is a "Sign-Off" checkbox in the commit window. You
-could even alias git commit to use the -s flag so you don’t have to think about
-it.
-
-By signing your work in this manner, you certify to a "Developer's Certificate
-or Origin". The current version of this certificate is in the `DCO.txt` file
-in the root of this repository.
-
-
-************
-How-to Guide
-************
-
-There are two ways to make changes, the easy way and the hard way. Either way
-you will need to `create a GitHub account <https://github.com/signup/free>`_.
-
-Easy way GitHub allows in-line editing of files for making simple typo changes
-and quick-fixes. This is not the best way as you are unable to test the code
-works. If you do this you could be introducing syntax errors, etc, but for a
-Git-phobic user this is good for a quick-fix.
-
-Hard way The best way to contribute is to "clone" your fork of CodeIgniter to
-your development area. That sounds like some jargon, but "forking" on GitHub
-means "making a copy of that repo to your account" and "cloning" means
-"copying that code to your environment so you can work on it".
-
-#. Set up Git (Windows, Mac & Linux)
-#. Go to the CodeIgniter repo
-#. Fork it
-#. Clone your CodeIgniter repo: git@github.com:<your-name>/CodeIgniter.git
-#. Checkout the "develop" branch At this point you are ready to start making
- changes.
-#. Fix existing bugs on the Issue tracker after taking a look to see nobody
- else is working on them.
-#. Commit the files
-#. Push your develop branch to your fork
-#. Send a pull request http://help.github.com/send-pull-requests/
-
-The Reactor Engineers will now be alerted about the change and at least one of
-the team will respond. If your change fails to meet the guidelines it will be
-bounced, or feedback will be provided to help you improve it.
-
-Once the Reactor Engineer handling your pull request is happy with it they
-will post it to the internal EllisLab discussion area to be double checked by
-the other Engineers and EllisLab developers. If nobody has a problem with the
-change then it will be merged into develop and will be part of the next
-release. Keeping your fork up-to-date
-
-Unlike systems like Subversion, Git can have multiple remotes. A remote is the
-name for a URL of a Git repository. By default your fork will have a remote
-named "origin" which points to your fork, but you can add another remote named
-"codeigniter" which points to git://github.com/EllisLab/CodeIgniter.git. This
-is a read-only remote but you can pull from this develop branch to update your
-own.
-
-If you are using command-line you can do the following:
-
-#. git remote add codeigniter git://github.com/EllisLab/CodeIgniter.git
-#. git pull codeigniter develop
-#. git push origin develop
-
-Now your fork is up to date. This should be done regularly, or before you send
-a pull request at least.
-
*******
License
*******
diff --git a/system/core/Common.php b/system/core/Common.php
index 57374b07d..981af4559 100644
--- a/system/core/Common.php
+++ b/system/core/Common.php
@@ -488,13 +488,9 @@ if ( ! function_exists('set_status_header'))
{
header('Status: '.$code.' '.$text, TRUE);
}
- elseif ($server_protocol === 'HTTP/1.0')
- {
- header('HTTP/1.0 '.$code.' '.$text, TRUE, $code);
- }
else
{
- header('HTTP/1.1 '.$code.' '.$text, TRUE, $code);
+ header(($server_protocol ? $server_protocol : 'HTTP/1.1').' '.$code.' '.$text, TRUE, $code);
}
}
}
@@ -524,18 +520,17 @@ if ( ! function_exists('_exception_handler'))
{
$_error =& load_class('Exceptions', 'core');
- // Should we display the error? We'll get the current error_reporting
+ // Should we ignore the error? We'll get the current error_reporting
// level and add its bits with the severity bits to find out.
- // And respect display_errors
- if (($severity & error_reporting()) === $severity && (bool) ini_get('display_errors') === TRUE)
+ if (($severity & error_reporting()) !== $severity)
{
- $_error->show_php_error($severity, $message, $filepath, $line);
+ return;
}
- // Should we log the error? No? We're done...
- if (config_item('log_threshold') === 0)
+ // Should we display the error?
+ if ((bool) ini_get('display_errors') === TRUE)
{
- return;
+ $_error->show_php_error($severity, $message, $filepath, $line);
}
$_error->log_exception($severity, $message, $filepath, $line);
diff --git a/system/core/Config.php b/system/core/Config.php
index 2f6a9e085..8e4f998ef 100644
--- a/system/core/Config.php
+++ b/system/core/Config.php
@@ -102,7 +102,7 @@ class CI_Config {
{
$file = ($file === '') ? 'config' : str_replace('.php', '', $file);
$found = $loaded = FALSE;
-
+
$check_locations = defined('ENVIRONMENT')
? array(ENVIRONMENT.'/'.$file, $file)
: array($file);
diff --git a/system/core/Input.php b/system/core/Input.php
index 968a42a9a..82482f2aa 100644
--- a/system/core/Input.php
+++ b/system/core/Input.php
@@ -328,62 +328,113 @@ class CI_Input {
return $this->ip_address;
}
- if (config_item('proxy_ips') != '' && $this->server('HTTP_X_FORWARDED_FOR') && $this->server('REMOTE_ADDR'))
+ $proxy_ips = config_item('proxy_ips');
+ if ( ! empty($proxy_ips) && ! is_array($proxy_ips))
{
- $has_ranges = strpos($proxies, '/') !== false;
- $proxies = preg_split('/[\s,]/', config_item('proxy_ips'), -1, PREG_SPLIT_NO_EMPTY);
- $proxies = is_array($proxies) ? $proxies : array($proxies);
-
- if ($has_ranges)
- {
- $long_ip = ip2long($_SERVER['REMOTE_ADDR']);
- $bit_32 = 1 << 32;
+ $proxy_ips = explode(',', str_replace(' ', '', $proxy_ips));
+ }
+
+ $this->ip_address = $this->server('REMOTE_ADDR');
- // Go through each of the IP Addresses to check for and
- // test against range notation
- foreach($proxies as $ip)
+ if ($proxy_ips)
+ {
+ foreach (array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_X_CLIENT_IP', 'HTTP_X_CLUSTER_CLIENT_IP') as $header)
+ {
+ if (($spoof = $this->server($header)) !== NULL)
{
- list($address, $mask_length) = explode('/', $ip);
+ // Some proxies typically list the whole chain of IP
+ // addresses through which the client has reached us.
+ // e.g. client_ip, proxy_ip1, proxy_ip2, etc.
+ if (strpos($spoof, ',') !== FALSE)
+ {
+ $spoof = explode(',', $spoof, 2);
+ $spoof = $spoof[0];
+ }
- // Generate the bitmask for a 32 bit IP Address
- $bitmask = $bit_32 - (1 << (32 - (int)$mask_length));
- if (($long_ip & $bitmask) == $address)
+ if ( ! $this->valid_ip($spoof))
+ {
+ $spoof = NULL;
+ }
+ else
{
- $this->ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
break;
}
}
-
- } else {
- $this->ip_address = in_array($_SERVER['REMOTE_ADDR'], $proxies) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
}
- }
- elseif ( ! $this->server('HTTP_CLIENT_IP') && $this->server('REMOTE_ADDR'))
- {
- $this->ip_address = $_SERVER['REMOTE_ADDR'];
- }
- elseif ($this->server('REMOTE_ADDR') && $this->server('HTTP_CLIENT_IP'))
- {
- $this->ip_address = $_SERVER['HTTP_CLIENT_IP'];
- }
- elseif ($this->server('HTTP_CLIENT_IP'))
- {
- $this->ip_address = $_SERVER['HTTP_CLIENT_IP'];
- }
- elseif ($this->server('HTTP_X_FORWARDED_FOR'))
- {
- $this->ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
- }
- if ($this->ip_address === FALSE)
- {
- return $this->ip_address = '0.0.0.0';
- }
+ if ($spoof)
+ {
+ for ($i = 0, $c = count($proxy_ips); $i < $c; $i++)
+ {
+ // Check if we have an IP address or a subnet
+ if (strpos($proxy_ips[$i], '/') === FALSE)
+ {
+ // An IP address (and not a subnet) is specified.
+ // We can compare right away.
+ if ($proxy_ips[$i] === $this->ip_address)
+ {
+ $this->ip_address = $spoof;
+ break;
+ }
+
+ continue;
+ }
- if (strpos($this->ip_address, ',') !== FALSE)
- {
- $x = explode(',', $this->ip_address);
- $this->ip_address = trim(end($x));
+ // We have a subnet ... now the heavy lifting begins
+ isset($separator) OR $separator = $this->valid_ip($this->ip_address, 'ipv6') ? ':' : '.';
+
+ // If the proxy entry doesn't match the IP protocol - skip it
+ if (strpos($proxy_ips[$i], $separator) === FALSE)
+ {
+ continue;
+ }
+
+ // Convert the REMOTE_ADDR IP address to binary, if needed
+ if ( ! isset($ip, $convert_func))
+ {
+ if ($separator === ':')
+ {
+ // Make sure we're have the "full" IPv6 format
+ $ip = str_replace('::', str_repeat(':', 9 - substr_count($this->ip_address, ':')), $this->ip_address);
+ $convert_func = is_php('5.3')
+ ? function ($value)
+ {
+ return str_pad(base_convert($value, 16, 2), 16, '0', STR_PAD_LEFT);
+ }
+ : create_function('$value', 'return str_pad(base_convert($value, 16, 2), 16, "0", STR_PAD_LEFT);');
+ }
+ else
+ {
+ $ip = $this->ip_address;
+ $convert_func = is_php('5.3')
+ ? function ($value)
+ {
+ return str_pad(decbin($value), 8, '0', STR_PAD_LEFT);
+ }
+ : create_function('$value', 'return str_pad(decbin($value), 8, "0", STR_PAD_LEFT);');
+ }
+
+ $ip = implode(array_map($convert_func, explode($separator, $ip)));
+ }
+
+ // Split the netmask length off the network address
+ list($netaddr, $masklen) = explode('/', $proxy_ips[$i], 2);
+
+ // Again, an IPv6 address is most likely in a compressed form
+ if ($separator === ':')
+ {
+ $netaddr = str_replace('::', str_repeat(':', 9 - substr_count($netaddr, ':')), $netaddr);
+ }
+
+ // Convert to a binary form and finally compare
+ $netaddr = implode(array_map($convert_func, explode($separator, $netaddr)));
+ if (strncmp($ip, $netaddr, $masklen) === 0)
+ {
+ $this->ip_address = $spoof;
+ break;
+ }
+ }
+ }
}
if ( ! $this->valid_ip($this->ip_address))
@@ -541,7 +592,7 @@ class CI_Input {
$_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']);
// CSRF Protection check
- if ($this->_enable_csrf === TRUE)
+ if ($this->_enable_csrf === TRUE && ! $this->is_cli_request())
{
$this->security->csrf_verify();
}
diff --git a/system/core/Loader.php b/system/core/Loader.php
index 242b19069..ed830e2dd 100644
--- a/system/core/Loader.php
+++ b/system/core/Loader.php
@@ -779,11 +779,11 @@ class CI_Loader {
$_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);
$_ci_file = ($_ci_ext === '') ? $_ci_view.'.php' : $_ci_view;
- foreach ($this->_ci_view_paths as $view_file => $cascade)
+ foreach ($this->_ci_view_paths as $_ci_view_file => $cascade)
{
- if (file_exists($view_file.$_ci_file))
+ if (file_exists($_ci_view_file.$_ci_file))
{
- $_ci_path = $view_file.$_ci_file;
+ $_ci_path = $_ci_view_file.$_ci_file;
$file_exists = TRUE;
break;
}
diff --git a/system/core/Output.php b/system/core/Output.php
index 9842f834d..052367ed6 100644
--- a/system/core/Output.php
+++ b/system/core/Output.php
@@ -552,13 +552,13 @@ class CI_Output {
fclose($fp);
// Strip out the embedded timestamp
- if ( ! preg_match('/\d+TS--->/', $cache, $match))
+ if ( ! preg_match('/^(\d+)TS--->/', $cache, $match))
{
return FALSE;
}
$last_modified = filemtime($cache_path);
- $expire = str_replace('TS--->', '', $match[0]);
+ $expire = $match[1];
// Has the file expired?
if ($_SERVER['REQUEST_TIME'] >= $expire && is_really_writable($cache_path))
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index d63a1d955..ea2a53eb2 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -51,6 +51,7 @@ abstract class CI_DB_driver {
public $char_set = 'utf8';
public $dbcollat = 'utf8_general_ci';
public $autoinit = TRUE; // Whether to automatically initialize the DB
+ public $compress = TRUE;
public $swap_pre = '';
public $port = '';
public $pconnect = FALSE;
@@ -78,6 +79,10 @@ abstract class CI_DB_driver {
protected $_protect_identifiers = TRUE;
protected $_reserved_identifiers = array('*'); // Identifiers that should NOT be escaped
+ // clause and character used for LIKE escape sequences
+ protected $_like_escape_str = " ESCAPE '%s' ";
+ protected $_like_escape_chr = '!';
+
/**
* The syntax to count rows is slightly different across different
* database engines, so this string appears in each driver and is
@@ -669,7 +674,7 @@ abstract class CI_DB_driver {
*/
public function is_write_type($sql)
{
- return (bool) preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD DATA|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s+/i', $sql);
+ return (bool) preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s+/i', $sql);
}
// --------------------------------------------------------------------
@@ -1343,7 +1348,7 @@ abstract class CI_DB_driver {
}
else
{
- $message = ( ! is_array($error)) ? array(str_replace('%s', $swap, $LANG->line($error))) : $error;
+ $message = is_array($error) ? $error : array(str_replace('%s', $swap, $LANG->line($error)));
}
// Find the most likely culprit of the error by going through
@@ -1352,7 +1357,13 @@ abstract class CI_DB_driver {
$trace = debug_backtrace();
foreach ($trace as $call)
{
- if (isset($call['file']) && strpos($call['file'], BASEPATH.'database') === FALSE)
+ // We'll need this on Windows, as APPPATH and BASEPATH will always use forward slashes
+ if (DIRECTORY_SEPARATOR !== '/')
+ {
+ $call['file'] = str_replace('\\', '/', $call['file']);
+ }
+
+ if (isset($call['file'], $call['class']) && strpos($call['file'], BASEPATH.'database') === FALSE && strpos($call['class'], 'Loader') !== FALSE)
{
// Found it - use a relative path for safety
$message[] = 'Filename: '.str_replace(array(APPPATH, BASEPATH), '', $call['file']);
diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php
index 479b7f24a..54510ec2e 100644
--- a/system/database/DB_query_builder.php
+++ b/system/database/DB_query_builder.php
@@ -1522,19 +1522,18 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
// --------------------------------------------------------------------
/**
- * From Tables
+ * FROM tables
*
- * This public function implicitly groups FROM tables so there is no confusion
- * about operator precedence in harmony with SQL standards
+ * Groups tables in FROM clauses if needed, so there is no confusion
+ * about operator precedence.
*
- * @param array
- * @return string
+ * Note: This is only used (and overriden) by MySQL and CUBRID.
+ *
+ * @return string
*/
- protected function _from_tables($tables)
+ protected function _from_tables()
{
- is_array($tables) OR $tables = array($tables);
-
- return (count($tables) === 1) ? $tables[0] : '('.implode(', ', $tables).')';
+ return implode(', ', $this->qb_from);
}
// --------------------------------------------------------------------
@@ -2058,7 +2057,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
// Write the "FROM" portion of the query
if (count($this->qb_from) > 0)
{
- $sql .= "\nFROM ".$this->_from_tables($this->qb_from);
+ $sql .= "\nFROM ".$this->_from_tables();
}
// Write the "JOIN" portion of the query
diff --git a/system/database/drivers/cubrid/cubrid_driver.php b/system/database/drivers/cubrid/cubrid_driver.php
index a3d0287f5..01d0ee39e 100644
--- a/system/database/drivers/cubrid/cubrid_driver.php
+++ b/system/database/drivers/cubrid/cubrid_driver.php
@@ -45,10 +45,6 @@ class CI_DB_cubrid_driver extends CI_DB {
// The character used for escaping - no need in CUBRID
protected $_escape_char = '`';
- // clause and character used for LIKE escape sequences - not used in CUBRID
- protected $_like_escape_str = '';
- protected $_like_escape_chr = '';
-
protected $_random_keyword = ' RAND()'; // database specific random keyword
// CUBRID-specific properties
@@ -72,6 +68,8 @@ class CI_DB_cubrid_driver extends CI_DB {
}
}
+ // --------------------------------------------------------------------
+
/**
* Non-persistent database connection
*
@@ -431,6 +429,26 @@ class CI_DB_cubrid_driver extends CI_DB {
// --------------------------------------------------------------------
/**
+ * FROM tables
+ *
+ * Groups tables in FROM clauses if needed, so there is no confusion
+ * about operator precedence.
+ *
+ * @return string
+ */
+ protected function _from_tables()
+ {
+ if ( ! empty($this->qb_join) && count($this->qb_from) > 1)
+ {
+ return '('.implode(', ', $this->qb_from).')';
+ }
+
+ return implode(', ', $this->qb_from);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* Close DB Connection
*
* @return void
diff --git a/system/database/drivers/ibase/ibase_driver.php b/system/database/drivers/ibase/ibase_driver.php
index c9027670d..ab1d1b88d 100644
--- a/system/database/drivers/ibase/ibase_driver.php
+++ b/system/database/drivers/ibase/ibase_driver.php
@@ -45,10 +45,6 @@ class CI_DB_ibase_driver extends CI_DB {
// The character used to escape with
protected $_escape_char = '"';
- // clause and character used for LIKE escape sequences
- protected $_like_escape_str = " ESCAPE '%s' ";
- protected $_like_escape_chr = '!';
-
protected $_random_keyword = ' Random()'; // database specific random keyword
// Keeps track of the resource for the current transaction
@@ -306,22 +302,6 @@ class CI_DB_ibase_driver extends CI_DB {
// --------------------------------------------------------------------
/**
- * From Tables
- *
- * This public function implicitly groups FROM tables so there is no confusion
- * about operator precedence in harmony with SQL standards
- *
- * @param array
- * @return string
- */
- protected function _from_tables($tables)
- {
- return is_array($tables) ? implode(', ', $tables) : $tables;
- }
-
- // --------------------------------------------------------------------
-
- /**
* Update statement
*
* Generates a platform-specific update string from the supplied data
diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php
index 1714704a8..a62ea94b3 100644
--- a/system/database/drivers/mssql/mssql_driver.php
+++ b/system/database/drivers/mssql/mssql_driver.php
@@ -45,10 +45,6 @@ class CI_DB_mssql_driver extends CI_DB {
// The character used for escaping
protected $_escape_char = '"';
- // clause and character used for LIKE escape sequences
- protected $_like_escape_str = " ESCAPE '%s' ";
- protected $_like_escape_chr = '!';
-
protected $_random_keyword = ' NEWID()';
// MSSQL-specific properties
@@ -366,22 +362,6 @@ class CI_DB_mssql_driver extends CI_DB {
// --------------------------------------------------------------------
/**
- * From Tables
- *
- * This function implicitly groups FROM tables so there is no confusion
- * about operator precedence in harmony with SQL standards
- *
- * @param array
- * @return string
- */
- protected function _from_tables($tables)
- {
- return is_array($tables) ? implode(', ', $tables) : $tables;
- }
-
- // --------------------------------------------------------------------
-
- /**
* Update statement
*
* Generates a platform-specific update string from the supplied data
diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php
index 29db90408..7262591ee 100644
--- a/system/database/drivers/mysql/mysql_driver.php
+++ b/system/database/drivers/mysql/mysql_driver.php
@@ -45,10 +45,6 @@ class CI_DB_mysql_driver extends CI_DB {
// The character used for escaping
protected $_escape_char = '`';
- // clause and character used for LIKE escape sequences - not used in MySQL
- protected $_like_escape_str = '';
- protected $_like_escape_chr = '\\';
-
protected $_random_keyword = ' RAND()'; // database specific random keyword
/**
@@ -83,7 +79,14 @@ class CI_DB_mysql_driver extends CI_DB {
*/
public function db_connect()
{
- return @mysql_connect($this->hostname, $this->username, $this->password, TRUE);
+ if ($this->compress === TRUE)
+ {
+ return @mysql_connect($this->hostname, $this->username, $this->password, TRUE, MYSQL_CLIENT_COMPRESS);
+ }
+ else
+ {
+ return @mysql_connect($this->hostname, $this->username, $this->password, TRUE);
+ }
}
// --------------------------------------------------------------------
@@ -95,7 +98,14 @@ class CI_DB_mysql_driver extends CI_DB {
*/
public function db_pconnect()
{
- return @mysql_pconnect($this->hostname, $this->username, $this->password);
+ if ($this->compress === TRUE)
+ {
+ return @mysql_pconnect($this->hostname, $this->username, $this->password, MYSQL_CLIENT_COMPRESS);
+ }
+ else
+ {
+ return @mysql_pconnect($this->hostname, $this->username, $this->password);
+ }
}
// --------------------------------------------------------------------
@@ -455,6 +465,26 @@ class CI_DB_mysql_driver extends CI_DB {
// --------------------------------------------------------------------
/**
+ * FROM tables
+ *
+ * Groups tables in FROM clauses if needed, so there is no confusion
+ * about operator precedence.
+ *
+ * @return string
+ */
+ protected function _from_tables()
+ {
+ if ( ! empty($this->qb_join) && count($this->qb_from) > 1)
+ {
+ return '('.implode(', ', $this->qb_from).')';
+ }
+
+ return implode(', ', $this->qb_from);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* Close DB Connection
*
* @return void
diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php
index be61aab20..b5a1e26ed 100644
--- a/system/database/drivers/mysqli/mysqli_driver.php
+++ b/system/database/drivers/mysqli/mysqli_driver.php
@@ -45,10 +45,6 @@ class CI_DB_mysqli_driver extends CI_DB {
// The character used for escaping
protected $_escape_char = '`';
- // clause and character used for LIKE escape sequences - not used in MySQL
- protected $_like_escape_str = '';
- protected $_like_escape_chr = '\\';
-
protected $_random_keyword = ' RAND()'; // database specific random keyword
/**
@@ -65,6 +61,17 @@ class CI_DB_mysqli_driver extends CI_DB {
*/
public function db_connect()
{
+ // Use MySQL client compression?
+ if ($this->compress === TRUE)
+ {
+ $port = empty($this->port) ? NULL : $this->port;
+
+ $mysqli = new mysqli();
+ @$mysqli->real_connect($this->hostname, $this->username, $this->password, $this->database, $port, NULL, MYSQLI_CLIENT_COMPRESS);
+
+ return $mysqli;
+ }
+
return empty($this->port)
? @new mysqli($this->hostname, $this->username, $this->password, $this->database)
: @new mysqli($this->hostname, $this->username, $this->password, $this->database, $this->port);
@@ -85,6 +92,17 @@ class CI_DB_mysqli_driver extends CI_DB {
return $this->db_connect();
}
+ // Use MySQL client compression?
+ if ($this->compress === TRUE)
+ {
+ $port = empty($this->port) ? NULL : $this->port;
+
+ $mysqli = mysqli_init();
+ $mysqli->real_connect('p:'.$this->hostname, $this->username, $this->password, $this->database, $port, NULL, MYSQLI_CLIENT_COMPRESS);
+
+ return $mysqli;
+ }
+
return empty($this->port)
? @new mysqli('p:'.$this->hostname, $this->username, $this->password, $this->database)
: @new mysqli('p:'.$this->hostname, $this->username, $this->password, $this->database, $this->port);
@@ -400,6 +418,14 @@ class CI_DB_mysqli_driver extends CI_DB {
*/
public function error()
{
+ if ( ! empty($this->conn_id->connect_errno))
+ {
+ return array(
+ 'code' => $this->conn_id->connect_errno,
+ 'message' => is_php('5.2.9') ? $this->conn_id->connect_error : mysqli_connect_error()
+ );
+ }
+
return array('code' => $this->conn_id->errno, 'message' => $this->conn_id->error);
}
@@ -449,6 +475,26 @@ class CI_DB_mysqli_driver extends CI_DB {
// --------------------------------------------------------------------
/**
+ * FROM tables
+ *
+ * Groups tables in FROM clauses if needed, so there is no confusion
+ * about operator precedence.
+ *
+ * @return string
+ */
+ protected function _from_tables()
+ {
+ if ( ! empty($this->qb_join) && count($this->qb_from) > 1)
+ {
+ return '('.implode(', ', $this->qb_from).')';
+ }
+
+ return implode(', ', $this->qb_from);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* Close DB Connection
*
* @return void
diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php
index 691247fee..72cbce5c1 100644
--- a/system/database/drivers/oci8/oci8_driver.php
+++ b/system/database/drivers/oci8/oci8_driver.php
@@ -54,10 +54,6 @@ class CI_DB_oci8_driver extends CI_DB {
// The character used for excaping
protected $_escape_char = '"';
- // clause and character used for LIKE escape sequences
- protected $_like_escape_str = " ESCAPE '%s' ";
- protected $_like_escape_chr = '!';
-
/**
* The syntax to count rows is slightly different across different
* database engines, so this string appears in each driver and is
@@ -547,22 +543,6 @@ class CI_DB_oci8_driver extends CI_DB {
// --------------------------------------------------------------------
/**
- * From Tables
- *
- * This function implicitly groups FROM tables so there is no confusion
- * about operator precedence in harmony with SQL standards
- *
- * @param array
- * @return string
- */
- protected function _from_tables($tables)
- {
- return is_array($tables) ? implode(', ', $tables) : $tables;
- }
-
- // --------------------------------------------------------------------
-
- /**
* Insert_batch statement
*
* Generates a platform-specific insert string from the supplied data
diff --git a/system/database/drivers/odbc/odbc_driver.php b/system/database/drivers/odbc/odbc_driver.php
index 8f0a474b0..c1f6ccfe2 100644
--- a/system/database/drivers/odbc/odbc_driver.php
+++ b/system/database/drivers/odbc/odbc_driver.php
@@ -45,9 +45,7 @@ class CI_DB_odbc_driver extends CI_DB {
// the character used to excape - not necessary for ODBC
protected $_escape_char = '';
- // clause and character used for LIKE escape sequences
protected $_like_escape_str = " {escape '%s'} ";
- protected $_like_escape_chr = '!';
protected $_random_keyword;
@@ -291,22 +289,6 @@ class CI_DB_odbc_driver extends CI_DB {
// --------------------------------------------------------------------
/**
- * From Tables
- *
- * This function implicitly groups FROM tables so there is no confusion
- * about operator precedence in harmony with SQL standards
- *
- * @param array
- * @return string
- */
- protected function _from_tables($tables)
- {
- return is_array($tables) ? implode(', ', $tables) : $tables;
- }
-
- // --------------------------------------------------------------------
-
- /**
* Truncate statement
*
* Generates a platform-specific truncate string from the supplied data
diff --git a/system/database/drivers/pdo/pdo_driver.php b/system/database/drivers/pdo/pdo_driver.php
index 705b16560..0ffe3bc13 100644
--- a/system/database/drivers/pdo/pdo_driver.php
+++ b/system/database/drivers/pdo/pdo_driver.php
@@ -45,10 +45,6 @@ class CI_DB_pdo_driver extends CI_DB {
// The character used to escaping
protected $_escape_char = '"';
- // clause and character used for LIKE escape sequences
- protected $_like_escape_str = " ESCAPE '%s' ";
- protected $_like_escape_chr = '!';
-
protected $_random_keyword;
public $trans_enabled = FALSE;
diff --git a/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php b/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php
index e287f5c63..efc0500a5 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php
@@ -130,22 +130,6 @@ class CI_DB_pdo_4d_driver extends CI_DB_pdo_driver {
// --------------------------------------------------------------------
/**
- * From Tables
- *
- * This function implicitly groups FROM tables so there is no confusion
- * about operator precedence in harmony with SQL standards
- *
- * @param array
- * @return string
- */
- protected function _from_tables($tables)
- {
- return is_array($tables) ? implode(', ', $tables) : $tables;
- }
-
- // --------------------------------------------------------------------
-
- /**
* Update statement
*
* Generates a platform-specific update string from the supplied data
diff --git a/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php b/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php
index 05eeacfe6..cb18a5c10 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php
@@ -44,10 +44,6 @@ class CI_DB_pdo_cubrid_driver extends CI_DB_pdo_driver {
protected $_escape_char = '`';
- // clause and character used for LIKE escape sequences - not used in CUBRID
- protected $_like_escape_str = '';
- protected $_like_escape_chr = '\\';
-
protected $_random_keyword = ' RAND()';
/**
@@ -183,6 +179,26 @@ class CI_DB_pdo_cubrid_driver extends CI_DB_pdo_driver {
return 'TRUNCATE '.$table;
}
+ // --------------------------------------------------------------------
+
+ /**
+ * FROM tables
+ *
+ * Groups tables in FROM clauses if needed, so there is no confusion
+ * about operator precedence.
+ *
+ * @return string
+ */
+ protected function _from_tables()
+ {
+ if ( ! empty($this->qb_join) && count($this->qb_from) > 1)
+ {
+ return '('.implode(', ', $this->qb_from).')';
+ }
+
+ return implode(', ', $this->qb_from);
+ }
+
}
/* End of file pdo_cubrid_driver.php */
diff --git a/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php b/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php
index 7060c9eb9..2346e683e 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php
@@ -153,22 +153,6 @@ class CI_DB_pdo_dblib_driver extends CI_DB_pdo_driver {
// --------------------------------------------------------------------
/**
- * From Tables
- *
- * This function implicitly groups FROM tables so there is no confusion
- * about operator precedence in harmony with SQL standards
- *
- * @param array
- * @return string
- */
- protected function _from_tables($tables)
- {
- return is_array($tables) ? implode(', ', $tables) : $tables;
- }
-
- // --------------------------------------------------------------------
-
- /**
* Update statement
*
* Generates a platform-specific update string from the supplied data
diff --git a/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php b/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php
index c074a9a78..6fba764a9 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php
@@ -139,22 +139,6 @@ class CI_DB_pdo_firebird_driver extends CI_DB_pdo_driver {
// --------------------------------------------------------------------
/**
- * From Tables
- *
- * This function implicitly groups FROM tables so there is no confusion
- * about operator precedence in harmony with SQL standards
- *
- * @param array
- * @return string
- */
- protected function _from_tables($tables)
- {
- return is_array($tables) ? implode(', ', $tables) : $tables;
- }
-
- // --------------------------------------------------------------------
-
- /**
* Update statement
*
* Generates a platform-specific update string from the supplied data
diff --git a/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php b/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php
index 832c03c96..399182e12 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php
@@ -165,22 +165,6 @@ class CI_DB_pdo_ibm_driver extends CI_DB_pdo_driver {
// --------------------------------------------------------------------
/**
- * From Tables
- *
- * This function implicitly groups FROM tables so there is no confusion
- * about operator precedence in harmony with SQL standards
- *
- * @param array
- * @return string
- */
- protected function _from_tables($tables)
- {
- return is_array($tables) ? implode(', ', $tables) : $tables;
- }
-
- // --------------------------------------------------------------------
-
- /**
* Update statement
*
* Generates a platform-specific update string from the supplied data
diff --git a/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php b/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php
index a3efc63dc..028121540 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php
@@ -159,22 +159,6 @@ class CI_DB_pdo_informix_driver extends CI_DB_pdo_driver {
// --------------------------------------------------------------------
/**
- * From Tables
- *
- * This function implicitly groups FROM tables so there is no confusion
- * about operator precedence in harmony with SQL standards
- *
- * @param array
- * @return string
- */
- protected function _from_tables($tables)
- {
- return is_array($tables) ? implode(', ', $tables) : $tables;
- }
-
- // --------------------------------------------------------------------
-
- /**
* Update statement
*
* Generates a platform-specific update string from the supplied data
diff --git a/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php b/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php
index 78afe246c..42446889a 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php
@@ -44,10 +44,6 @@ class CI_DB_pdo_mysql_driver extends CI_DB_pdo_driver {
protected $_escape_char = '`';
- // clause and character used for LIKE escape sequences - not used in MySQL
- protected $_like_escape_str = '';
- protected $_like_escape_chr = '\\';
-
protected $_random_keyword = ' RAND()';
/**
@@ -211,6 +207,26 @@ class CI_DB_pdo_mysql_driver extends CI_DB_pdo_driver {
return 'TRUNCATE '.$table;
}
+ // --------------------------------------------------------------------
+
+ /**
+ * FROM tables
+ *
+ * Groups tables in FROM clauses if needed, so there is no confusion
+ * about operator precedence.
+ *
+ * @return string
+ */
+ protected function _from_tables()
+ {
+ if ( ! empty($this->qb_join) && count($this->qb_from) > 1)
+ {
+ return '('.implode(', ', $this->qb_from).')';
+ }
+
+ return implode(', ', $this->qb_from);
+ }
+
}
/* End of file pdo_mysql_driver.php */
diff --git a/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php b/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php
index 56ec1bce1..d584d1f5b 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php
@@ -146,22 +146,6 @@ class CI_DB_pdo_oci_driver extends CI_DB_pdo_driver {
// --------------------------------------------------------------------
/**
- * From Tables
- *
- * This function implicitly groups FROM tables so there is no confusion
- * about operator precedence in harmony with SQL standards
- *
- * @param array
- * @return string
- */
- protected function _from_tables($tables)
- {
- return is_array($tables) ? implode(', ', $tables) : $tables;
- }
-
- // --------------------------------------------------------------------
-
- /**
* Insert_batch statement
*
* @param string the table name
diff --git a/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php b/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php
index 392754ff7..e7ab3fd50 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php
@@ -46,7 +46,6 @@ class CI_DB_pdo_odbc_driver extends CI_DB_pdo_driver {
protected $_escape_char = '';
// clause and character used for LIKE escape sequences
- protected $_like_escape_chr = '!';
protected $_like_escape_str = " {escape '%s'} ";
protected $_random_keyword = ' RAND()';
@@ -157,22 +156,6 @@ class CI_DB_pdo_odbc_driver extends CI_DB_pdo_driver {
// --------------------------------------------------------------------
/**
- * From Tables
- *
- * This function implicitly groups FROM tables so there is no confusion
- * about operator precedence in harmony with SQL standards
- *
- * @param array
- * @return string
- */
- protected function _from_tables($tables)
- {
- return is_array($tables) ? implode(', ', $tables) : $tables;
- }
-
- // --------------------------------------------------------------------
-
- /**
* Update statement
*
* Generates a platform-specific update string from the supplied data
diff --git a/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php b/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php
index 9a476f143..2a687812a 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php
@@ -142,22 +142,6 @@ class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver {
// --------------------------------------------------------------------
/**
- * From Tables
- *
- * This function implicitly groups FROM tables so there is no confusion
- * about operator precedence in harmony with SQL standards
- *
- * @param array
- * @return string
- */
- protected function _from_tables($tables)
- {
- return is_array($tables) ? implode(', ', $tables) : $tables;
- }
-
- // --------------------------------------------------------------------
-
- /**
* Update statement
*
* Generates a platform-specific update string from the supplied data
diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php
index f125b8f50..ee7c1d15a 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php
@@ -182,22 +182,6 @@ class CI_DB_pdo_sqlsrv_driver extends CI_DB_pdo_driver {
// --------------------------------------------------------------------
/**
- * From Tables
- *
- * This function implicitly groups FROM tables so there is no confusion
- * about operator precedence in harmony with SQL standards
- *
- * @param array
- * @return string
- */
- protected function _from_tables($tables)
- {
- return is_array($tables) ? implode(', ', $tables) : $tables;
- }
-
- // --------------------------------------------------------------------
-
- /**
* Update statement
*
* Generates a platform-specific update string from the supplied data
diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php
index 8c11c477b..2a91a8959 100644
--- a/system/database/drivers/postgre/postgre_driver.php
+++ b/system/database/drivers/postgre/postgre_driver.php
@@ -44,10 +44,6 @@ class CI_DB_postgre_driver extends CI_DB {
protected $_escape_char = '"';
- // clause and character used for LIKE escape sequences
- protected $_like_escape_str = " ESCAPE '%s' ";
- protected $_like_escape_chr = '!';
-
protected $_random_keyword = ' RANDOM()'; // database specific random keyword
/**
@@ -461,22 +457,6 @@ class CI_DB_postgre_driver extends CI_DB {
// --------------------------------------------------------------------
/**
- * From Tables
- *
- * This function implicitly groups FROM tables so there is no confusion
- * about operator precedence in harmony with SQL standards
- *
- * @param array
- * @return string
- */
- protected function _from_tables($tables)
- {
- return is_array($tables) ? implode(', ', $tables) : $tables;
- }
-
- // --------------------------------------------------------------------
-
- /**
* Update statement
*
* Generates a platform-specific update string from the supplied data
diff --git a/system/database/drivers/sqlite/sqlite_driver.php b/system/database/drivers/sqlite/sqlite_driver.php
index 19824dbbf..2744a63cf 100644
--- a/system/database/drivers/sqlite/sqlite_driver.php
+++ b/system/database/drivers/sqlite/sqlite_driver.php
@@ -45,10 +45,6 @@ class CI_DB_sqlite_driver extends CI_DB {
// The character used to escape with - not needed for SQLite
protected $_escape_char = '"';
- // clause and character used for LIKE escape sequences
- protected $_like_escape_str = " ESCAPE '%s' ";
- protected $_like_escape_chr = '!';
-
protected $_random_keyword = ' Random()'; // database specific random keyword
/**
diff --git a/system/database/drivers/sqlite3/sqlite3_driver.php b/system/database/drivers/sqlite3/sqlite3_driver.php
index cc35d319f..d03be15f5 100644
--- a/system/database/drivers/sqlite3/sqlite3_driver.php
+++ b/system/database/drivers/sqlite3/sqlite3_driver.php
@@ -46,10 +46,6 @@ class CI_DB_sqlite3_driver extends CI_DB {
// The character used for escaping
protected $_escape_char = '"';
- // clause and character used for LIKE escape sequences
- protected $_like_escape_str = ' ESCAPE \'%s\' ';
- protected $_like_escape_chr = '!';
-
protected $_random_keyword = ' RANDOM()';
/**
@@ -288,25 +284,16 @@ class CI_DB_sqlite3_driver extends CI_DB {
// --------------------------------------------------------------------
/**
- * The error message string
+ * Error
*
- * @return string
- */
- protected function _error_message()
- {
- return $this->conn_id->lastErrorMsg();
- }
-
- // --------------------------------------------------------------------
-
- /**
- * The error message number
+ * Returns an array containing code and message of the last
+ * database error that has occured.
*
- * @return int
+ * @return array
*/
- protected function _error_number()
+ public function error()
{
- return $this->conn_id->lastErrorCode();
+ return array('code' => $this->conn_id->lastErrorCode(), 'message' => $this->conn_id->lastErrorMsg());
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/sqlsrv/sqlsrv_driver.php b/system/database/drivers/sqlsrv/sqlsrv_driver.php
index bda450e88..a6739d192 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_driver.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_driver.php
@@ -45,10 +45,6 @@ class CI_DB_sqlsrv_driver extends CI_DB {
// The character used for escaping
protected $_escape_char = '"';
- // clause and character used for LIKE escape sequences
- protected $_like_escape_str = " ESCAPE '%s' ";
- protected $_like_escape_chr = '!';
-
protected $_random_keyword = ' NEWID()';
// SQLSRV-specific properties
@@ -362,22 +358,6 @@ class CI_DB_sqlsrv_driver extends CI_DB {
// --------------------------------------------------------------------
/**
- * From Tables
- *
- * This function implicitly groups FROM tables so there is no confusion
- * about operator precedence in harmony with SQL standards
- *
- * @param array
- * @return string
- */
- protected function _from_tables($tables)
- {
- return is_array($tables) ? implode(', ', $tables) : $tables;
- }
-
- // --------------------------------------------------------------------
-
- /**
* Update statement
*
* Generates a platform-specific update string from the supplied data
diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php
index a4383c9d3..3aac14db8 100644
--- a/system/helpers/captcha_helper.php
+++ b/system/helpers/captcha_helper.php
@@ -80,8 +80,7 @@ if ( ! function_exists('create_captcha'))
$current_dir = @opendir($img_path);
while ($filename = @readdir($current_dir))
{
- if ($filename !== '.' && $filename !== '..' && $filename !== 'index.html'
- && (str_replace('.jpg', '', $filename) + $expiration) < $now)
+ if (substr($filename, -4) === '.jpg' && (str_replace('.jpg', '', $filename) + $expiration) < $now)
{
@unlink($img_path.$filename);
}
diff --git a/system/helpers/date_helper.php b/system/helpers/date_helper.php
index a792f09a2..955d74542 100644
--- a/system/helpers/date_helper.php
+++ b/system/helpers/date_helper.php
@@ -657,5 +657,136 @@ if ( ! function_exists('timezones'))
}
}
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('date_range'))
+{
+ /**
+ * Date range
+ *
+ * Returns a list of dates within a specified period.
+ *
+ * @param int unix_start UNIX timestamp of period start date
+ * @param int unix_end|days UNIX timestamp of period end date
+ * or interval in days.
+ * @param mixed is_unix Specifies wether the second parameter
+ * is a UNIX timestamp or a day interval
+ * - TRUE or 'unix' for a timestamp
+ * - FALSE or 'days' for an interval
+ * @param string date_format Output date format, same as in date()
+ * @return array
+ */
+ function date_range($unix_start = '', $mixed = '', $is_unix = TRUE, $format = 'Y-m-d')
+ {
+ if ($unix_start == '' OR $mixed == '' OR $format == '')
+ {
+ return FALSE;
+ }
+
+ $is_unix = ! ( ! $is_unix OR $is_unix === 'days');
+
+ // Validate input and try strtotime() on invalid timestamps/intervals, just in case
+ if ( ( ! preg_match('/^[0-9]+$/', $unix_start) && ($unix_start = @strtotime($unix_time)) === FALSE)
+ OR ( ! preg_match('/^[0-9]+$/', $mixed) && ($is_unix === FALSE OR ($mixed = @strtotime($mixed)) === FALSE))
+ OR ($is_unix === TRUE && $mixed < $unix_start))
+ {
+ return FALSE;
+ }
+
+ if ($is_unix && ($unix_start == $mixed OR date($format, $unix_start) === date($format, $mixed)))
+ {
+ return array($start_date);
+ }
+
+ $range = array();
+
+ /* NOTE: Even though the DateTime object has many useful features, it appears that
+ * it doesn't always handle properly timezones, when timestamps are passed
+ * directly to its constructor. Neither of the following gave proper results:
+ *
+ * new DateTime('<timestamp>')
+ * new DateTime('<timestamp>', '<timezone>')
+ *
+ * --- available in PHP 5.3:
+ *
+ * DateTime::createFromFormat('<format>', '<timestamp>')
+ * DateTime::createFromFormat('<format>', '<timestamp>', '<timezone')
+ *
+ * ... so we'll have to set the timestamp after the object is instantiated.
+ * Furthermore, in PHP 5.3 we can use DateTime::setTimestamp() to do that and
+ * given that we have UNIX timestamps - we should use it.
+ */
+ $from = new DateTime();
+
+ if (is_php('5.3'))
+ {
+ $from->setTimestamp($unix_start);
+ if ($is_unix)
+ {
+ $arg = new DateTime();
+ $arg->setTimestamp($mixed);
+ }
+ else
+ {
+ $arg = (int) $mixed;
+ }
+
+ $period = new DatePeriod($from, new DateInterval('P1D'), $arg);
+ foreach ($period as $date)
+ {
+ $range[] = $date->format($format);
+ }
+
+ /* If a period end date was passed to the DatePeriod constructor, it might not
+ * be in our results. Not sure if this is a bug or it's just possible because
+ * the end date might actually be less than 24 hours away from the previously
+ * generated DateTime object, but either way - we have to append it manually.
+ */
+ if ( ! is_int($arg) && $range[count($range) - 1] !== $arg->format($format))
+ {
+ $range[] = $arg->format($format);
+ }
+
+ return $range;
+ }
+
+ $from->setDate(date('Y', $unix_start), date('n', $unix_start), date('j', $unix_start));
+ $from->setTime(date('G', $unix_start), date('i', $unix_start), date('s', $unix_start));
+ if ($is_unix)
+ {
+ $arg = new DateTime();
+ $arg->setDate(date('Y', $mixed), date('n', $mixed), date('j', $mixed));
+ $arg->setTime(date('G', $mixed), date('i', $mixed), date('s', $mixed));
+ }
+ else
+ {
+ $arg = (int) $mixed;
+ }
+ $range[] = $from->format($format);
+
+ if (is_int($arg)) // Day intervals
+ {
+ do
+ {
+ $from->modify('+1 day');
+ $range[] = $from->format($format);
+ }
+ while (--$arg > 0);
+ }
+ else // end date UNIX timestamp
+ {
+ for ($from->modify('+1 day'), $end_check = $arg->format('Ymd'); $from->format('Ymd') < $end_check; $from->modify('+1 day'))
+ {
+ $range[] = $from->format($format);
+ }
+
+ // Our loop only appended dates prior to our end date
+ $range[] = $arg->format($format);
+ }
+
+ return $range;
+ }
+}
+
/* End of file date_helper.php */
/* Location: ./system/helpers/date_helper.php */ \ No newline at end of file
diff --git a/system/helpers/directory_helper.php b/system/helpers/directory_helper.php
index e7d3b5e8a..7d6b6770e 100644
--- a/system/helpers/directory_helper.php
+++ b/system/helpers/directory_helper.php
@@ -62,7 +62,7 @@ if ( ! function_exists('directory_map'))
while (FALSE !== ($file = readdir($fp)))
{
// Remove '.', '..', and hidden files [optional]
- if ( ! trim($file, '.') OR ($hidden === FALSE && $file[0] === '.'))
+ if ($file === '.' OR $file === '..' OR ($hidden === FALSE && $file[0] === '.'))
{
continue;
}
diff --git a/system/helpers/text_helper.php b/system/helpers/text_helper.php
index 8a1f01b51..b592f3cc0 100644
--- a/system/helpers/text_helper.php
+++ b/system/helpers/text_helper.php
@@ -89,7 +89,8 @@ if ( ! function_exists('character_limiter'))
return $str;
}
- $str = preg_replace('/\s+/', ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));
+ // a bit complicated, but faster than preg_replace with \s+
+ $str = preg_replace('/ {2,}/', ' ', str_replace(array("\r", "\n", "\t", "\x0B", "\x0C"), ' ', $str));
if (strlen($str) <= $n)
{
diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php
index 57208c948..b1f5eccf1 100644
--- a/system/helpers/url_helper.php
+++ b/system/helpers/url_helper.php
@@ -534,7 +534,7 @@ if ( ! function_exists('redirect'))
}
// IIS environment likely? Use 'refresh' for better compatibility
- if (DIRECTORY_SEPARATOR !== '/' && $method === 'auto')
+ if ($method === 'auto' && isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== FALSE)
{
$method = 'refresh';
}
diff --git a/system/language/english/date_lang.php b/system/language/english/date_lang.php
index 229d33d2e..6683e4c69 100644
--- a/system/language/english/date_lang.php
+++ b/system/language/english/date_lang.php
@@ -25,20 +25,20 @@
* @filesource
*/
-$lang['date_year'] = "Year";
-$lang['date_years'] = "Years";
-$lang['date_month'] = "Month";
-$lang['date_months'] = "Months";
-$lang['date_week'] = "Week";
-$lang['date_weeks'] = "Weeks";
-$lang['date_day'] = "Day";
-$lang['date_days'] = "Days";
-$lang['date_hour'] = "Hour";
-$lang['date_hours'] = "Hours";
-$lang['date_minute'] = "Minute";
-$lang['date_minutes'] = "Minutes";
-$lang['date_second'] = "Second";
-$lang['date_seconds'] = "Seconds";
+$lang['date_year'] = 'Year';
+$lang['date_years'] = 'Years';
+$lang['date_month'] = 'Month';
+$lang['date_months'] = 'Months';
+$lang['date_week'] = 'Week';
+$lang['date_weeks'] = 'Weeks';
+$lang['date_day'] = 'Day';
+$lang['date_days'] = 'Days';
+$lang['date_hour'] = 'Hour';
+$lang['date_hours'] = 'Hours';
+$lang['date_minute'] = 'Minute';
+$lang['date_minutes'] = 'Minutes';
+$lang['date_second'] = 'Second';
+$lang['date_seconds'] = 'Seconds';
$lang['UM12'] = '(UTC -12:00) Baker/Howland Island';
$lang['UM11'] = '(UTC -11:00) Niue';
diff --git a/system/language/english/form_validation_lang.php b/system/language/english/form_validation_lang.php
index 021776161..cf1b3b503 100644
--- a/system/language/english/form_validation_lang.php
+++ b/system/language/english/form_validation_lang.php
@@ -43,8 +43,8 @@ $lang['integer'] = 'The %s field must contain an integer.';
$lang['regex_match'] = 'The %s field is not in the correct format.';
$lang['matches'] = 'The %s field does not match the %s field.';
$lang['is_unique'] = 'The %s field must contain a unique value.';
-$lang['is_natural'] = 'The %s field must contain only positive numbers.';
-$lang['is_natural_no_zero'] = 'The %s field must contain a number greater than zero.';
+$lang['is_natural'] = 'The %s field must only contain digits.';
+$lang['is_natural_no_zero'] = 'The %s field must only contain digits and must be greater than zero.';
$lang['decimal'] = 'The %s field must contain a decimal number.';
$lang['less_than'] = 'The %s field must contain a number less than %s.';
$lang['less_than_equal_to'] = 'The %s field must contain a number less than or equal to %s.';
diff --git a/system/libraries/Driver.php b/system/libraries/Driver.php
index 1d084c8e4..769d892dc 100644
--- a/system/libraries/Driver.php
+++ b/system/libraries/Driver.php
@@ -63,7 +63,7 @@ class CI_Driver_Library {
* @return object Child class
*/
public function __get($child)
- {
+ {
// Try to load the driver
return $this->load_driver($child);
}
@@ -284,4 +284,4 @@ class CI_Driver {
}
/* End of file Driver.php */
-/* Location: ./system/libraries/Driver.php */
+/* Location: ./system/libraries/Driver.php */ \ No newline at end of file
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index 8fd7a79e7..1b457aee4 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -188,7 +188,7 @@ class CI_Email {
* @param string
* @return object
*/
- public function from($from, $name = '')
+ public function from($from, $name = '', $return_path = '')
{
if (preg_match('/\<(.*)\>/', $from, $match))
{
@@ -198,6 +198,10 @@ class CI_Email {
if ($this->validate)
{
$this->validate_email($this->_str_to_array($from));
+ if ($return_path)
+ {
+ $this->validate_email($this->_str_to_array($return_path));
+ }
}
// prepare the display name
@@ -216,7 +220,12 @@ class CI_Email {
}
$this->set_header('From', $name.' <'.$from.'>');
- $this->set_header('Return-Path', '<'.$from.'>');
+
+ if( ! $return_path)
+ {
+ $return_path = $from;
+ }
+ $this->set_header('Return-Path', '<'.$return_path.'>');
return $this;
}
@@ -971,7 +980,6 @@ class CI_Email {
$this->_finalbody = $body.$this->_prep_quoted_printable($this->_body).$this->newline.$this->newline;
-
if ($this->_get_protocol() === 'mail')
{
$this->_header_str .= $hdr;
@@ -1091,17 +1099,17 @@ class CI_Email {
* Refer to RFC 2045 http://www.ietf.org/rfc/rfc2045.txt
*
* @param string
- * @param int
* @return string
*/
- protected function _prep_quoted_printable($str, $charlim = '')
+ protected function _prep_quoted_printable($str)
{
- // Set the character limit
- // Don't allow over 76, as that will make servers and MUAs barf
- // all over quoted-printable data
- if ($charlim === '' OR $charlim > 76)
+ // RFC 2045 specifies CRLF as "\r\n".
+ // However, many developers choose to override that and violate
+ // the RFC rules due to (apparently) a bug in MS Exchange,
+ // which only works with "\n".
+ if ($this->crlf === "\r\n" && is_php('5.3'))
{
- $charlim = 76;
+ return quoted_printable_encode($str);
}
// Reduce multiple spaces & remove nulls
@@ -1146,7 +1154,7 @@ class CI_Email {
// If we're at the character limit, add the line to the output,
// reset our temp variable, and keep on chuggin'
- if ((strlen($temp) + strlen($char)) >= $charlim)
+ if ((strlen($temp) + strlen($char)) >= 76)
{
$output .= $temp.$escape.$this->crlf;
$temp = '';
@@ -1228,7 +1236,7 @@ class CI_Email {
// wrap each line with the shebang, charset, and transfer encoding
// the preceding space on successive lines is required for header "folding"
- return trim(preg_replace('/^(.*)$/m', ' =?'.$this->charset.'?Q?$1?=', $output.$temp));
+ return trim(preg_replace('/^(.*?)(\r*)$/m', ' =?'.$this->charset.'?Q?$1?=$2', $output.$temp));
}
// --------------------------------------------------------------------
@@ -1399,7 +1407,7 @@ class CI_Email {
{
// most documentation of sendmail using the "-f" flag lacks a space after it, however
// we've encountered servers that seem to require it to be in place.
- return mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, '-f '.$this->clean_email($this->_headers['From']));
+ return mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, '-f '.$this->clean_email($this->_headers['Return-Path']));
}
}
@@ -1412,7 +1420,7 @@ class CI_Email {
*/
protected function _send_with_sendmail()
{
- $fp = @popen($this->mailpath.' -oi -f '.$this->clean_email($this->_headers['From']).' -t', 'w');
+ $fp = @popen($this->mailpath.' -oi -f '.$this->clean_email($this->_headers['From']).' -t'.' -r '.$this->clean_email($this->_headers['Return-Path']), 'w');
if ($fp === FALSE OR $fp === NULL)
{
diff --git a/system/libraries/Encrypt.php b/system/libraries/Encrypt.php
index 8ffd93aea..679609251 100644
--- a/system/libraries/Encrypt.php
+++ b/system/libraries/Encrypt.php
@@ -484,7 +484,7 @@ class CI_Encrypt {
*/
public function set_hash($type = 'sha1')
{
- $this->_hash_type = ($type !== 'sha1' && $type !== 'md5') ? 'sha1' : $type;
+ $this->_hash_type = in_array($type, hash_algos()) ? $type : 'sha1';
}
// --------------------------------------------------------------------
@@ -497,7 +497,7 @@ class CI_Encrypt {
*/
public function hash($str)
{
- return ($this->_hash_type === 'sha1') ? sha1($str) : md5($str);
+ return hash($this->_hash_type, $str);
}
}
diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php
index 899b995d4..ef4187847 100644
--- a/system/libraries/Image_lib.php
+++ b/system/libraries/Image_lib.php
@@ -1320,6 +1320,13 @@ class CI_Image_lib {
imagestring($src_img, $this->wm_font_size, $x_shad, $y_shad, $this->wm_text, $drp_color);
imagestring($src_img, $this->wm_font_size, $x_axis, $y_axis, $this->wm_text, $txt_color);
}
+
+ // We can preserve transparency for PNG images
+ if ($this->image_type === 3)
+ {
+ imagealphablending($src_img, FALSE);
+ imagesavealpha($src_img, TRUE);
+ }
}
// Output the final image
diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php
index 5573f6407..e1e729bb0 100644
--- a/system/libraries/Pagination.php
+++ b/system/libraries/Pagination.php
@@ -52,20 +52,20 @@ class CI_Pagination {
protected $full_tag_open = '';
protected $full_tag_close = '';
protected $first_tag_open = '';
- protected $first_tag_close = '&nbsp;';
- protected $last_tag_open = '&nbsp;';
+ protected $first_tag_close = '';
+ protected $last_tag_open = '';
protected $last_tag_close = '';
protected $first_url = ''; // Alternative URL for the First Page.
- protected $cur_tag_open = '&nbsp;<strong>';
+ protected $cur_tag_open = '<strong>';
protected $cur_tag_close = '</strong>';
- protected $next_tag_open = '&nbsp;';
- protected $next_tag_close = '&nbsp;';
- protected $prev_tag_open = '&nbsp;';
+ protected $next_tag_open = '';
+ protected $next_tag_close = '';
+ protected $prev_tag_open = '';
protected $prev_tag_close = '';
- protected $num_tag_open = '&nbsp;';
+ protected $num_tag_open = '';
protected $num_tag_close = '';
protected $page_query_string = FALSE;
- protected $query_string_segment = 'per_page';
+ protected $query_string_segment = 'per_page';
protected $display_pages = TRUE;
protected $_attributes = '';
protected $_link_types = array();
@@ -215,7 +215,8 @@ class CI_Pagination {
// string. If post, add a trailing slash to the base URL if needed
if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE)
{
- $this->base_url = rtrim($this->base_url).'&amp;'.$this->query_string_segment.'=';
+ $segment = (strpos($this->base_url, '?')) ? '&amp;' : '?';
+ $this->base_url = rtrim($this->base_url).$segment.$this->query_string_segment.'=';
}
else
{
diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php
index 1f24456a4..978506062 100755
--- a/system/libraries/Session/Session.php
+++ b/system/libraries/Session/Session.php
@@ -2,20 +2,31 @@
/**
* CodeIgniter
*
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
+ *
+ * NOTICE OF LICENSE
+ *
+ * Licensed under the Open Software License version 3.0
+ *
+ * This source file is subject to the Open Software License (OSL 3.0) that is
+ * bundled with this package in the files license.txt / license.rst. It is
+ * also available through the world wide web at this URL:
+ * http://opensource.org/licenses/OSL-3.0
+ * If you did not receive a copy of the license and are unable to obtain it
+ * through the world wide web, please send an email to
+ * licensing@ellislab.com so we can send you a copy immediately.
*
* @package CodeIgniter
- * @author ExpressionEngine Dev Team
- * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc.
- * @license http://codeigniter.com/user_guide/license.html
+ * @author EllisLab Dev Team
+ * @copyright Copyright (c) 2006 - 2012 EllisLab, Inc.
+ * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 2.0
* @filesource
*/
-
/**
- * CI_Session Class
+ * CodeIgniter Session Class
*
* The user interface defined by EllisLabs, now with puggable drivers to manage different storage mechanisms.
* By default, the cookie session driver will load, but the 'sess_driver' config/param item (see above) can be
@@ -35,12 +46,13 @@
* @package CodeIgniter
* @subpackage Libraries
* @category Sessions
- * @author ExpressionEngine Dev Team
+ * @author EllisLab Dev Team
* @link http://codeigniter.com/user_guide/libraries/sessions.html
*/
class CI_Session extends CI_Driver_Library {
+
public $params = array();
- protected $current = null;
+ protected $current = NULL;
protected $userdata = array();
const FLASHDATA_KEY = 'flash';
@@ -57,22 +69,30 @@ class CI_Session extends CI_Driver_Library {
* routines in its constructor, and manages flashdata aging.
*
* @param array Configuration parameters
+ * @return void
*/
public function __construct(array $params = array())
{
+ $CI =& get_instance();
+
+ // No sessions under CLI
+ if ($CI->input->is_cli_request())
+ {
+ return;
+ }
+
log_message('debug', 'CI_Session Class Initialized');
// Get valid drivers list
- $CI =& get_instance();
$this->valid_drivers = array(
'Session_native',
'Session_cookie'
);
$key = 'sess_valid_drivers';
- $drivers = (isset($params[$key])) ? $params[$key] : $CI->config->item($key);
+ $drivers = isset($params[$key]) ? $params[$key] : $CI->config->item($key);
if ($drivers)
{
- if ( ! is_array($drivers)) $drivers = array($drivers);
+ is_array($drivers) OR $drivers = array($drivers);
// Add driver names to valid list
foreach ($drivers as $driver)
@@ -86,8 +106,12 @@ class CI_Session extends CI_Driver_Library {
// Get driver to load
$key = 'sess_driver';
- $driver = (isset($params[$key])) ? $params[$key] : $CI->config->item($key);
- if ( ! $driver) $driver = 'cookie';
+ $driver = isset($params[$key]) ? $params[$key] : $CI->config->item($key);
+ if ( ! $driver)
+ {
+ $driver = 'cookie';
+ }
+
if ( ! in_array('session_'.strtolower($driver), array_map('strtolower', $this->valid_drivers)))
{
$this->valid_drivers[] = 'Session_'.$driver;
@@ -111,6 +135,8 @@ class CI_Session extends CI_Driver_Library {
log_message('debug', 'CI_Session routines successfully run');
}
+ // ------------------------------------------------------------------------
+
/**
* Loads session storage driver
*
@@ -125,6 +151,8 @@ class CI_Session extends CI_Driver_Library {
return $this->current;
}
+ // ------------------------------------------------------------------------
+
/**
* Select default session storage driver
*
@@ -142,7 +170,8 @@ class CI_Session extends CI_Driver_Library {
if (isset($this->$child))
{
// See if driver is already current
- if ($this->$child !== $this->current) {
+ if ($this->$child !== $this->current)
+ {
// Make driver current and sync userdata
$this->current = $this->$child;
$this->userdata =& $this->current->get_userdata();
@@ -156,6 +185,8 @@ class CI_Session extends CI_Driver_Library {
}
}
+ // ------------------------------------------------------------------------
+
/**
* Destroy the current session
*
@@ -167,19 +198,23 @@ class CI_Session extends CI_Driver_Library {
$this->current->sess_destroy();
}
+ // ------------------------------------------------------------------------
+
/**
* Regenerate the current session
*
- * @param boolean Destroy session data flag (default: false)
+ * @param bool Destroy session data flag (default: false)
* @return void
*/
- public function sess_regenerate($destroy = false)
+ public function sess_regenerate($destroy = FALSE)
{
// Call regenerate on driver and resync userdata
$this->current->sess_regenerate($destroy);
$this->userdata =& $this->current->get_userdata();
}
+ // ------------------------------------------------------------------------
+
/**
* Fetch a specific item from the session array
*
@@ -188,10 +223,11 @@ class CI_Session extends CI_Driver_Library {
*/
public function userdata($item)
{
- // Return value or NULL if not found
- return ( ! isset($this->userdata[$item])) ? NULL : $this->userdata[$item];
+ return isset($this->userdata[$item]) ? $this->userdata[$item] : NULL;
}
+ // ------------------------------------------------------------------------
+
/**
* Fetch all session data
*
@@ -199,10 +235,11 @@ class CI_Session extends CI_Driver_Library {
*/
public function all_userdata()
{
- // Return entire array
- return ( ! isset($this->userdata)) ? NULL : $this->userdata;
+ return isset($this->userdata) ? $this->userdata : NULL;
}
+ // ------------------------------------------------------------------------
+
/**
* Fetch all flashdata
*
@@ -225,6 +262,8 @@ class CI_Session extends CI_Driver_Library {
return $out;
}
+ // ------------------------------------------------------------------------
+
/**
* Add or change data in the "userdata" array
*
@@ -253,6 +292,8 @@ class CI_Session extends CI_Driver_Library {
$this->current->sess_save();
}
+ // ------------------------------------------------------------------------
+
/**
* Delete a session variable from the "userdata" array
*
@@ -270,7 +311,7 @@ class CI_Session extends CI_Driver_Library {
// Unset each item name
if (count($newdata) > 0)
{
- foreach ($newdata as $key => $val)
+ foreach (array_keys($newdata) as $key)
{
unset($this->userdata[$key]);
}
@@ -280,18 +321,21 @@ class CI_Session extends CI_Driver_Library {
$this->current->sess_save();
}
+ // ------------------------------------------------------------------------
+
/**
* Determine if an item exists
*
* @param string Item name
- * @return boolean
+ * @return bool
*/
public function has_userdata($item)
{
- // Check for item name
return isset($this->userdata[$item]);
}
+ // ------------------------------------------------------------------------
+
/**
* Add or change flashdata, only available until the next request
*
@@ -318,6 +362,8 @@ class CI_Session extends CI_Driver_Library {
}
}
+ // ------------------------------------------------------------------------
+
/**
* Keeps existing flashdata available to next request.
*
@@ -335,6 +381,8 @@ class CI_Session extends CI_Driver_Library {
$this->set_userdata($new_flashdata_key, $value);
}
+ // ------------------------------------------------------------------------
+
/**
* Fetch a specific flashdata item from the session array
*
@@ -348,13 +396,14 @@ class CI_Session extends CI_Driver_Library {
return $this->userdata($flashdata_key);
}
+ // ------------------------------------------------------------------------
+
/**
- * Add or change tempdata, only available
- * until expiration
+ * Add or change tempdata, only available until expiration
*
* @param mixed Item name or array of items
* @param string Item value or empty string
- * @param int Item lifetime in seconds or 0 for default
+ * @param int Item lifetime in seconds or 0 for default
* @return void
*/
public function set_tempdata($newdata = array(), $newval = '', $expire = 0)
@@ -390,6 +439,8 @@ class CI_Session extends CI_Driver_Library {
$this->set_userdata(self::EXPIRATION_KEY, $expirations);
}
+ // ------------------------------------------------------------------------
+
/**
* Delete a temporary session variable from the "userdata" array
*
@@ -400,7 +451,7 @@ class CI_Session extends CI_Driver_Library {
{
// Get expirations list
$expirations = $this->userdata(self::EXPIRATION_KEY);
- if ( ! $expirations || ! count($expirations))
+ if (empty($expirations))
{
// Nothing to do
return;
@@ -415,7 +466,7 @@ class CI_Session extends CI_Driver_Library {
// Prepend each item name and unset
if (count($newdata) > 0)
{
- foreach ($newdata as $key => $val)
+ foreach (array_keys($newdata) as $key)
{
$tempdata_key = self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key;
unset($expirations[$tempdata_key]);
@@ -427,6 +478,8 @@ class CI_Session extends CI_Driver_Library {
$this->set_userdata(self::EXPIRATION_KEY, $expirations);
}
+ // ------------------------------------------------------------------------
+
/**
* Fetch a specific tempdata item from the session array
*
@@ -440,17 +493,17 @@ class CI_Session extends CI_Driver_Library {
return $this->userdata($tempdata_key);
}
+ // ------------------------------------------------------------------------
+
/**
* Identifies flashdata as 'old' for removal
* when _flashdata_sweep() runs.
*
- * @access protected
* @return void
*/
protected function _flashdata_mark()
{
- $userdata = $this->all_userdata();
- foreach ($userdata as $name => $value)
+ foreach ($this->all_userdata() as $name => $value)
{
$parts = explode(self::FLASHDATA_NEW, $name);
if (is_array($parts) && count($parts) === 2)
@@ -462,16 +515,17 @@ class CI_Session extends CI_Driver_Library {
}
}
+ // ------------------------------------------------------------------------
+
/**
* Removes all flashdata marked as 'old'
*
- * @access protected
* @return void
*/
protected function _flashdata_sweep()
{
$userdata = $this->all_userdata();
- foreach ($userdata as $key => $value)
+ foreach (array_keys($userdata) as $key)
{
if (strpos($key, self::FLASHDATA_OLD))
{
@@ -480,17 +534,18 @@ class CI_Session extends CI_Driver_Library {
}
}
+ // ------------------------------------------------------------------------
+
/**
* Removes all expired tempdata
*
- * @access protected
* @return void
*/
protected function _tempdata_sweep()
{
// Get expirations list
$expirations = $this->userdata(self::EXPIRATION_KEY);
- if ( ! $expirations || ! count($expirations))
+ if (empty($expirations))
{
// Nothing to do
return;
@@ -499,7 +554,7 @@ class CI_Session extends CI_Driver_Library {
// Unset expired elements
$now = time();
$userdata = $this->all_userdata();
- foreach ($userdata as $key => $value)
+ foreach (array_keys($userdata) as $key)
{
if (strpos($key, self::FLASHDATA_EXP) && $expirations[$key] < $now)
{
@@ -511,9 +566,10 @@ class CI_Session extends CI_Driver_Library {
// Update expiration list
$this->set_userdata(self::EXPIRATION_KEY, $expirations);
}
+
}
-// END CI_Session Class
+// ------------------------------------------------------------------------
/**
* CI_Session_driver Class
@@ -535,9 +591,27 @@ class CI_Session extends CI_Driver_Library {
* @package CodeIgniter
* @subpackage Libraries
* @category Sessions
- * @author ExpressionEngine Dev Team
+ * @author EllisLab Dev Team
*/
abstract class CI_Session_driver extends CI_Driver {
+
+ protected $CI;
+
+ /**
+ * Constructor
+ *
+ * Gets the CI singleton, so that individual drivers
+ * don't have to do it separately.
+ *
+ * @return void
+ */
+ public function __construct()
+ {
+ $this->CI =& get_instance();
+ }
+
+ // ------------------------------------------------------------------------
+
/**
* Decorate
*
@@ -555,6 +629,8 @@ abstract class CI_Session_driver extends CI_Driver {
$this->initialize();
}
+ // ------------------------------------------------------------------------
+
/**
* __call magic method
*
@@ -571,6 +647,8 @@ abstract class CI_Session_driver extends CI_Driver {
return parent::__call($method, $args);
}
+ // ------------------------------------------------------------------------
+
/**
* Initialize driver
*
@@ -581,50 +659,56 @@ abstract class CI_Session_driver extends CI_Driver {
// Overload this method to implement initialization
}
+ // ------------------------------------------------------------------------
+
/**
* Save the session data
*
- * Data in the array has changed - perform any storage synchronization necessary
- * The child class MUST implement this abstract method!
+ * Data in the array has changed - perform any storage synchronization
+ * necessary. The child class MUST implement this abstract method!
*
* @return void
*/
abstract public function sess_save();
+ // ------------------------------------------------------------------------
+
/**
* Destroy the current session
*
- * Clean up storage for this session - it has been terminated
+ * Clean up storage for this session - it has been terminated.
* The child class MUST implement this abstract method!
*
* @return void
*/
abstract public function sess_destroy();
+ // ------------------------------------------------------------------------
+
/**
* Regenerate the current session
*
- * Regenerate the session id
+ * Regenerate the session ID.
* The child class MUST implement this abstract method!
*
- * @param boolean Destroy session data flag (default: false)
+ * @param bool Destroy session data flag (default: false)
* @return void
*/
- abstract public function sess_regenerate($destroy = false);
+ abstract public function sess_regenerate($destroy = FALSE);
+
+ // ------------------------------------------------------------------------
/**
* Get a reference to user data array
*
- * Give array access to the main CI_Session object
+ * Give array access to the main CI_Session object.
* The child class MUST implement this abstract method!
*
* @return array Reference to userdata
*/
abstract public function &get_userdata();
-}
-// END CI_Session_driver Class
+}
/* End of file Session.php */
-/* Location: ./system/libraries/Session/Session.php */
-?>
+/* Location: ./system/libraries/Session/Session.php */ \ No newline at end of file
diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php
index 69e5fde14..fb62c7ec4 100755
--- a/system/libraries/Session/drivers/Session_cookie.php
+++ b/system/libraries/Session/drivers/Session_cookie.php
@@ -37,6 +37,7 @@
* @link http://codeigniter.com/user_guide/libraries/sessions.html
*/
class CI_Session_cookie extends CI_Session_driver {
+
/**
* Whether to encrypt the session cookie
*
@@ -157,13 +158,6 @@ class CI_Session_cookie extends CI_Session_driver {
public $userdata = array();
/**
- * Reference to CodeIgniter instance
- *
- * @var object
- */
- public $CI;
-
- /**
* Current time
*
* @var int
@@ -192,14 +186,10 @@ class CI_Session_cookie extends CI_Session_driver {
/**
* Initialize session driver object
*
- * @access protected
* @return void
*/
protected function initialize()
{
- // Set the super object to a local variable for use throughout the class
- $this->CI =& get_instance();
-
// Set all the session preferences, which can either be set
// manually via the $params array or via the config file
$prefs = array(
@@ -220,16 +210,17 @@ class CI_Session_cookie extends CI_Session_driver {
'cookie_prefix',
'encryption_key'
);
+
foreach ($prefs as $key)
{
- $this->$key = isset($this->_parent->params[$key]) ? $this->_parent->params[$key] :
- $this->CI->config->item($key);
+ $this->$key = isset($this->_parent->params[$key])
+ ? $this->_parent->params[$key]
+ : $this->CI->config->item($key);
}
if ($this->encryption_key === '')
{
- show_error('In order to use the Cookie Session driver you are required to set an encryption key '.
- 'in your config file.');
+ show_error('In order to use the Cookie Session driver you are required to set an encryption key in your config file.');
}
// Load the string helper so we can use the strip_slashes() function
@@ -280,6 +271,8 @@ class CI_Session_cookie extends CI_Session_driver {
$this->_sess_gc();
}
+ // ------------------------------------------------------------------------
+
/**
* Write the session data
*
@@ -298,6 +291,8 @@ class CI_Session_cookie extends CI_Session_driver {
$this->_set_cookie();
}
+ // ------------------------------------------------------------------------
+
/**
* Destroy the current session
*
@@ -309,6 +304,7 @@ class CI_Session_cookie extends CI_Session_driver {
if ($this->sess_use_database === TRUE && isset($this->userdata['session_id']))
{
$this->CI->db->delete($this->sess_table_name, array('session_id' => $this->userdata['session_id']));
+ $this->data_dirty = FALSE;
}
// Kill the cookie
@@ -319,15 +315,17 @@ class CI_Session_cookie extends CI_Session_driver {
$this->userdata = array();
}
+ // ------------------------------------------------------------------------
+
/**
* Regenerate the current session
*
* Regenerate the session id
*
- * @param boolean Destroy session data flag (default: false)
+ * @param bool Destroy session data flag (default: false)
* @return void
*/
- public function sess_regenerate($destroy = false)
+ public function sess_regenerate($destroy = FALSE)
{
// Check destroy flag
if ($destroy)
@@ -339,25 +337,27 @@ class CI_Session_cookie extends CI_Session_driver {
else
{
// Just force an update to recreate the id
- $this->_sess_update(true);
+ $this->_sess_update(TRUE);
}
}
+ // ------------------------------------------------------------------------
+
/**
* Get a reference to user data array
*
- * @return array - Reference to userdata
+ * @return array Reference to userdata
*/
public function &get_userdata()
{
- // Return reference to array
return $this->userdata;
}
+ // ------------------------------------------------------------------------
+
/**
* Fetch the current session data if it exists
*
- * @access protected
* @return bool
*/
protected function _sess_read()
@@ -388,8 +388,7 @@ class CI_Session_cookie extends CI_Session_driver {
// Does the md5 hash match? This is to prevent manipulation of session data in userspace
if ($hash !== md5($session.$this->encryption_key))
{
- log_message('error', 'The session cookie data did not match what was expected. '.
- 'This could be a possible hacking attempt.');
+ log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.');
$this->sess_destroy();
return FALSE;
}
@@ -399,8 +398,7 @@ class CI_Session_cookie extends CI_Session_driver {
$session = $this->_unserialize($session);
// Is the session data we unserialized an array with the correct format?
- if ( ! is_array($session) || ! isset($session['session_id'], $session['ip_address'], $session['user_agent'],
- $session['last_activity']))
+ if ( ! is_array($session) OR ! isset($session['session_id'], $session['ip_address'], $session['user_agent'], $session['last_activity']))
{
$this->sess_destroy();
return FALSE;
@@ -422,7 +420,7 @@ class CI_Session_cookie extends CI_Session_driver {
// Does the User Agent Match?
if ($this->sess_match_useragent === TRUE &&
- trim($session['user_agent']) !== trim(substr($this->CI->input->user_agent(), 0, 120)))
+ trim($session['user_agent']) !== trim(substr($this->CI->input->user_agent(), 0, 120)))
{
$this->sess_destroy();
return FALSE;
@@ -443,8 +441,19 @@ class CI_Session_cookie extends CI_Session_driver {
$this->CI->db->where('user_agent', $session['user_agent']);
}
+ // Is caching in effect? Turn it off
+ $db_cache = $this->CI->db->cache_on;
+ $this->CI->db->cache_off();
+
$query = $this->CI->db->limit(1)->get($this->sess_table_name);
+ // Was caching in effect?
+ if ($db_cache)
+ {
+ // Turn it back on
+ $this->CI->db->cache_on();
+ }
+
// No result? Kill it!
if ($query->num_rows() === 0)
{
@@ -470,10 +479,11 @@ class CI_Session_cookie extends CI_Session_driver {
return TRUE;
}
+ // ------------------------------------------------------------------------
+
/**
* Create a new session
*
- * @access protected
* @return void
*/
protected function _sess_create()
@@ -497,11 +507,12 @@ class CI_Session_cookie extends CI_Session_driver {
$this->_set_cookie();
}
+ // ------------------------------------------------------------------------
+
/**
* Update an existing session
*
- * @access protected
- * @param boolean Force update flag (default: false)
+ * @param bool Force update flag (default: false)
* @return void
*/
protected function _sess_update($force = FALSE)
@@ -539,6 +550,8 @@ class CI_Session_cookie extends CI_Session_driver {
$this->_set_cookie();
}
+ // ------------------------------------------------------------------------
+
/**
* Update database with current data
*
@@ -547,6 +560,8 @@ class CI_Session_cookie extends CI_Session_driver {
* so it's guaranteed to update even when a fatal error
* occurs. The first call makes the update and clears the
* dirty flag so it won't happen twice.
+ *
+ * @return void
*/
public function _update_db()
{
@@ -583,6 +598,8 @@ class CI_Session_cookie extends CI_Session_driver {
}
}
+ // ------------------------------------------------------------------------
+
/**
* Generate a new session id
*
@@ -604,15 +621,16 @@ class CI_Session_cookie extends CI_Session_driver {
return md5(uniqid($new_sessid, TRUE));
}
+ // ------------------------------------------------------------------------
+
/**
* Get the "now" time
*
- * @access protected
* @return int Time
*/
protected function _get_time()
{
- if ($this->time_reference === 'local' || $this->time_reference === date_default_timezone_get())
+ if ($this->time_reference === 'local' OR $this->time_reference === date_default_timezone_get())
{
return time();
}
@@ -623,36 +641,27 @@ class CI_Session_cookie extends CI_Session_driver {
return mktime($hour, $minute, $second, $month, $day, $year);
}
+ // ------------------------------------------------------------------------
+
/**
* Write the session cookie
*
- * @access protected
* @return void
*/
protected function _set_cookie()
{
// Get userdata (only defaults if database)
- if ($this->sess_use_database === TRUE)
- {
- $cookie_data = array_intersect_key($this->userdata, $this->defaults);
- }
- else
- {
- $cookie_data = $this->userdata;
- }
+ $cookie_data = ($this->sess_use_database === TRUE)
+ ? array_intersect_key($this->userdata, $this->defaults)
+ : $this->userdata;
// Serialize the userdata for the cookie
$cookie_data = $this->_serialize($cookie_data);
- if ($this->sess_encrypt_cookie === TRUE)
- {
- $cookie_data = $this->CI->encrypt->encode($cookie_data);
- }
- else
- {
+ $cookie_data = ($this->sess_encrypt_cookie === TRUE)
+ ? $this->CI->encrypt->encode($cookie_data)
// if encryption is not used, we provide an md5 hash to prevent userside tampering
- $cookie_data = $cookie_data.md5($cookie_data.$this->encryption_key);
- }
+ : $cookie_data.md5($cookie_data.$this->encryption_key);
$expire = ($this->sess_expire_on_close === TRUE) ? 0 : $this->sess_expiration + time();
@@ -661,35 +670,35 @@ class CI_Session_cookie extends CI_Session_driver {
$this->cookie_secure, $this->cookie_httponly);
}
+ // ------------------------------------------------------------------------
+
/**
* Set a cookie with the system
*
* This abstraction of the setcookie call allows overriding for unit testing
*
- * @access protected
- * @param string Cookie name
- * @param string Cookie value
- * @param int Expiration time
- * @param string Cookie path
- * @param string Cookie domain
- * @param bool Secure connection flag
- * @param bool HTTP protocol only flag
- * @return void
- */
- protected function _setcookie($name, $value = '', $expire = 0, $path = '', $domain = '', $secure = false,
- $httponly = false)
+ * @param string Cookie name
+ * @param string Cookie value
+ * @param int Expiration time
+ * @param string Cookie path
+ * @param string Cookie domain
+ * @param bool Secure connection flag
+ * @param bool HTTP protocol only flag
+ * @return void
+ */
+ protected function _setcookie($name, $value = '', $expire = 0, $path = '', $domain = '', $secure = FALSE, $httponly = FALSE)
{
- // Set the cookie
setcookie($name, $value, $expire, $path, $domain, $secure, $httponly);
}
+ // ------------------------------------------------------------------------
+
/**
* Serialize an array
*
* This function first converts any slashes found in the array to a temporary
* marker, so when it gets unserialized the slashes will be preserved
*
- * @access protected
* @param mixed Data to serialize
* @return string Serialized data
*/
@@ -703,15 +712,17 @@ class CI_Session_cookie extends CI_Session_driver {
{
$data = str_replace('\\', '{{slash}}', $data);
}
+
return serialize($data);
}
+ // ------------------------------------------------------------------------
+
/**
* Escape slashes
*
* This function converts any slashes found into a temporary marker
*
- * @access protected
* @param string Value
* @param string Key
* @return void
@@ -724,13 +735,14 @@ class CI_Session_cookie extends CI_Session_driver {
}
}
+ // ------------------------------------------------------------------------
+
/**
* Unserialize
*
* This function unserializes a data string, then converts any
* temporary slash markers back to actual slashes
*
- * @access protected
* @param mixed Data to unserialize
* @return mixed Unserialized data
*/
@@ -747,12 +759,13 @@ class CI_Session_cookie extends CI_Session_driver {
return is_string($data) ? str_replace('{{slash}}', '\\', $data) : $data;
}
+ // ------------------------------------------------------------------------
+
/**
* Unescape slashes
*
* This function converts any slash markers back into actual slashes
*
- * @access protected
* @param string Value
* @param string Key
* @return void
@@ -765,13 +778,14 @@ class CI_Session_cookie extends CI_Session_driver {
}
}
+ // ------------------------------------------------------------------------
+
/**
* Garbage collection
*
* This deletes expired session rows from database
* if the probability percentage is met
*
- * @access protected
* @return void
*/
protected function _sess_gc()
@@ -793,7 +807,8 @@ class CI_Session_cookie extends CI_Session_driver {
log_message('debug', 'Session garbage collection performed.');
}
}
+
}
/* End of file Session_cookie.php */
-/* Location: ./system/libraries/Session/drivers/Session_cookie.php */
+/* Location: ./system/libraries/Session/drivers/Session_cookie.php */ \ No newline at end of file
diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php
index 8ba8e749a..8d5e51546 100755
--- a/system/libraries/Session/drivers/Session_native.php
+++ b/system/libraries/Session/drivers/Session_native.php
@@ -2,18 +2,29 @@
/**
* CodeIgniter
*
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
+ *
+ * NOTICE OF LICENSE
+ *
+ * Licensed under the Open Software License version 3.0
+ *
+ * This source file is subject to the Open Software License (OSL 3.0) that is
+ * bundled with this package in the files license.txt / license.rst. It is
+ * also available through the world wide web at this URL:
+ * http://opensource.org/licenses/OSL-3.0
+ * If you did not receive a copy of the license and are unable to obtain it
+ * through the world wide web, please send an email to
+ * licensing@ellislab.com so we can send you a copy immediately.
*
* @package CodeIgniter
- * @author ExpressionEngine Dev Team
- * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc.
- * @license http://codeigniter.com/user_guide/license.html
+ * @author EllisLab Dev Team
+ * @copyright Copyright (c) 2008 - 2012, 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 2.0
+ * @since Version 1.0
* @filesource
*/
-
/**
* Native PHP session management driver
*
@@ -22,20 +33,19 @@
* @package CodeIgniter
* @subpackage Libraries
* @category Sessions
- * @author ExpressionEngine Dev Team
+ * @author EllisLab Dev Team
*/
class CI_Session_native extends CI_Session_driver {
+
/**
* Initialize session driver object
*
- * @access protected
* @return void
*/
protected function initialize()
{
// Get config parameters
$config = array();
- $CI =& get_instance();
$prefs = array(
'sess_cookie_name',
'sess_expire_on_close',
@@ -47,10 +57,12 @@ class CI_Session_native extends CI_Session_driver {
'cookie_path',
'cookie_domain'
);
+
foreach ($prefs as $key)
{
- $config[$key] = isset($this->_parent->params[$key]) ? $this->_parent->params[$key] :
- $CI->config->item($key);
+ $config[$key] = isset($this->_parent->params[$key])
+ ? $this->_parent->params[$key]
+ : $this->CI->config->item($key);
}
// Set session name, if specified
@@ -75,11 +87,13 @@ class CI_Session_native extends CI_Session_driver {
// Default to 2 years if expiration is "0"
$expire = ($config['sess_expiration'] == 0) ? (60*60*24*365*2) : $config['sess_expiration'];
}
+
if ($config['cookie_path'])
{
// Use specified path
$path = $config['cookie_path'];
}
+
if ($config['cookie_domain'])
{
// Use specified domain
@@ -98,14 +112,14 @@ class CI_Session_native extends CI_Session_driver {
// Expired - destroy
$destroy = TRUE;
}
- else if ($config['sess_match_ip'] == TRUE && isset($_SESSION['ip_address']) &&
- $_SESSION['ip_address'] != $CI->input->ip_address())
+ elseif ($config['sess_match_ip'] === TRUE && isset($_SESSION['ip_address'])
+ && $_SESSION['ip_address'] !== $this->CI->input->ip_address())
{
// IP doesn't match - destroy
$destroy = TRUE;
}
- else if ($config['sess_match_useragent'] == TRUE && isset($_SESSION['user_agent']) &&
- $_SESSION['user_agent'] != trim(substr($CI->input->user_agent(), 0, 50)))
+ 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
$destroy = TRUE;
@@ -120,8 +134,8 @@ class CI_Session_native extends CI_Session_driver {
}
// Check for update time
- if ($config['sess_time_to_update'] && isset($_SESSION['last_activity']) &&
- ($_SESSION['last_activity'] + $config['sess_time_to_update']) < $now)
+ if ($config['sess_time_to_update'] && isset($_SESSION['last_activity'])
+ && ($_SESSION['last_activity'] + $config['sess_time_to_update']) < $now)
{
// Regenerate ID, but don't destroy session
$this->sess_regenerate(FALSE);
@@ -131,25 +145,27 @@ class CI_Session_native extends CI_Session_driver {
$_SESSION['last_activity'] = $now;
// Set matching values as required
- if ($config['sess_match_ip'] == TRUE && !isset($_SESSION['ip_address']))
+ if ($config['sess_match_ip'] === TRUE && ! isset($_SESSION['ip_address']))
{
// Store user IP address
- $_SESSION['ip_address'] = $CI->input->ip_address();
+ $_SESSION['ip_address'] = $this->CI->input->ip_address();
}
- if ($config['sess_match_useragent'] == TRUE && !isset($_SESSION['user_agent']))
+
+ if ($config['sess_match_useragent'] === TRUE && ! isset($_SESSION['user_agent']))
{
// Store user agent string
- $_SESSION['user_agent'] = trim(substr($CI->input->user_agent(), 0, 50));
+ $_SESSION['user_agent'] = trim(substr($this->CI->input->user_agent(), 0, 50));
}
// Make session ID available
$_SESSION['session_id'] = session_id();
}
+ // ------------------------------------------------------------------------
+
/**
* Save the session data
*
- * @access public
* @return void
*/
public function sess_save()
@@ -157,10 +173,11 @@ class CI_Session_native extends CI_Session_driver {
// Nothing to do - changes to $_SESSION are automatically saved
}
+ // ------------------------------------------------------------------------
+
/**
* Destroy the current session
*
- * @access public
* @return void
*/
public function sess_destroy()
@@ -178,13 +195,14 @@ class CI_Session_native extends CI_Session_driver {
session_destroy();
}
+ // ------------------------------------------------------------------------
+
/**
* Regenerate the current session
*
* Regenerate the session id
*
- * @access public
- * @param boolean Destroy session data flag (default: FALSE)
+ * @param bool Destroy session data flag (default: FALSE)
* @return void
*/
public function sess_regenerate($destroy = FALSE)
@@ -194,10 +212,11 @@ class CI_Session_native extends CI_Session_driver {
$_SESSION['session_id'] = session_id();
}
+ // ------------------------------------------------------------------------
+
/**
* Get a reference to user data array
*
- * @access public
* @return array Reference to userdata
*/
public function &get_userdata()
@@ -205,7 +224,8 @@ class CI_Session_native extends CI_Session_driver {
// Just return reference to $_SESSION
return $_SESSION;
}
+
}
/* End of file Session_native.php */
-/* Location: ./system/libraries/Session/drivers/Session_native.php */
+/* Location: ./system/libraries/Session/drivers/Session_native.php */ \ No newline at end of file
diff --git a/system/libraries/Unit_test.php b/system/libraries/Unit_test.php
index 70ad8dc41..c2c01758e 100644
--- a/system/libraries/Unit_test.php
+++ b/system/libraries/Unit_test.php
@@ -240,6 +240,11 @@ class CI_Unit_test {
{
foreach ($val as $k => $v)
{
+ if ( ! in_array($k, $this->_test_items_visible))
+ {
+ continue;
+ }
+
if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$v))))
{
$v = $line;
diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php
index cbb91c40a..dc5d27f8c 100644..100755
--- a/system/libraries/Xmlrpc.php
+++ b/system/libraries/Xmlrpc.php
@@ -1317,15 +1317,15 @@ class XML_RPC_Values extends CI_Xmlrpc
{
$type = $type === '' ? 'string' : $type;
- if ($this->xmlrpcTypes[$type] === 1)
+ if ($this->xmlrpcTypes[$type] == 1)
{
$this->addScalar($val,$type);
}
- elseif ($this->xmlrpcTypes[$type] === 2)
+ elseif ($this->xmlrpcTypes[$type] == 2)
{
$this->addArray($val);
}
- elseif ($this->xmlrpcTypes[$type] === 3)
+ elseif ($this->xmlrpcTypes[$type] == 3)
{
$this->addStruct($val);
}
@@ -1351,7 +1351,7 @@ class XML_RPC_Values extends CI_Xmlrpc
return 0;
}
- if ($typeof !== 1)
+ if ($typeof != 1)
{
echo '<strong>XML_RPC_Values</strong>: not a scalar type (${typeof})<br />';
return 0;
@@ -1359,7 +1359,7 @@ class XML_RPC_Values extends CI_Xmlrpc
if ($type === $this->xmlrpcBoolean)
{
- $val = (int) (strcasecmp($val,'true') === 0 OR $val === 1 OR ($val === TRUE && strcasecmp($val, 'false')));
+ $val = (int) (strcasecmp($val, 'true') === 0 OR $val === 1 OR ($val === TRUE && strcasecmp($val, 'false')));
}
if ($this->mytype === 2)
diff --git a/tests/Bootstrap.php b/tests/Bootstrap.php
index 5216038c6..1c666d503 100644
--- a/tests/Bootstrap.php
+++ b/tests/Bootstrap.php
@@ -11,6 +11,7 @@ defined('PROJECT_BASE') OR define('PROJECT_BASE', realpath($dir.'/../').'/');
defined('BASEPATH') OR define('BASEPATH', PROJECT_BASE.'system/');
defined('APPPATH') OR define('APPPATH', PROJECT_BASE.'application/');
defined('VIEWPATH') OR define('VIEWPATH', PROJECT_BASE.'');
+isset($_SERVER['REMOTE_ADDR']) OR $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
// Get vfsStream either via PEAR or composer
foreach (explode(PATH_SEPARATOR, get_include_path()) as $path)
diff --git a/tests/codeigniter/database/query_builder/escape_test.php b/tests/codeigniter/database/query_builder/escape_test.php
index c6380ddf1..27e678f22 100644
--- a/tests/codeigniter/database/query_builder/escape_test.php
+++ b/tests/codeigniter/database/query_builder/escape_test.php
@@ -27,7 +27,7 @@ class Escape_test extends CI_TestCase {
if (strpos(DB_DRIVER, 'mysql') !== FALSE)
{
- $sql = "SELECT `value` FROM `misc` WHERE `key` LIKE '$string%' ESCAPE '';";
+ $sql = "SELECT `value` FROM `misc` WHERE `key` LIKE '$string%' ESCAPE '!';";
}
else
{
@@ -52,7 +52,7 @@ class Escape_test extends CI_TestCase {
if (strpos(DB_DRIVER, 'mysql') !== FALSE)
{
- $sql = "SELECT `value` FROM `misc` WHERE `key` LIKE '$string%' ESCAPE '';";
+ $sql = "SELECT `value` FROM `misc` WHERE `key` LIKE '$string%' ESCAPE '!';";
}
else
{
diff --git a/tests/codeigniter/helpers/date_helper_test.php b/tests/codeigniter/helpers/date_helper_test.php
index 1b79b9480..9feade71c 100644
--- a/tests/codeigniter/helpers/date_helper_test.php
+++ b/tests/codeigniter/helpers/date_helper_test.php
@@ -290,6 +290,29 @@ class Date_helper_test extends CI_TestCase {
$this->assertEquals(0, timezones('non_existant'));
}
+ // ------------------------------------------------------------------------
+
+ public function test_date_range()
+ {
+ $dates = array(
+ '29-01-2012', '30-01-2012', '31-01-2012',
+ '01-02-2012', '02-02-2012', '03-02-2012',
+ '04-02-2012', '05-02-2012', '06-02-2012',
+ '07-02-2012', '08-02-2012', '09-02-2012',
+ '10-02-2012', '11-02-2012', '12-02-2012',
+ '13-02-2012', '14-02-2012', '15-02-2012',
+ '16-02-2012', '17-02-2012', '18-02-2012',
+ '19-02-2012', '20-02-2012', '21-02-2012',
+ '22-02-2012', '23-02-2012', '24-02-2012',
+ '25-02-2012', '26-02-2012', '27-02-2012',
+ '28-02-2012', '29-02-2012', '01-03-2012'
+ );
+
+ $this->assertEquals($dates, date_range(mktime(12, 0, 0, 1, 29, 2012), mktime(12, 0, 0, 3, 1, 2012), TRUE, 'd-m-Y'));
+ array_pop($dates);
+ $this->assertEquals($dates, date_range(mktime(12, 0, 0, 1, 29, 2012), 31, FALSE, 'd-m-Y'));
+ }
+
}
/* End of file date_helper_test.php */ \ No newline at end of file
diff --git a/tests/codeigniter/helpers/directory_helper_test.php b/tests/codeigniter/helpers/directory_helper_test.php
index 176ff1d78..c39ccd8d0 100644
--- a/tests/codeigniter/helpers/directory_helper_test.php
+++ b/tests/codeigniter/helpers/directory_helper_test.php
@@ -19,6 +19,7 @@ class Directory_helper_test extends CI_TestCase {
'benchmark.html' => '',
'database' => array('active_record.html' => '', 'binds.html' => ''),
'email.html' => '',
+ '0' => '',
'.hiddenfile.txt' => ''
)
);
@@ -30,7 +31,8 @@ class Directory_helper_test extends CI_TestCase {
'libraries' => array(
'benchmark.html',
'database' => array('active_record.html', 'binds.html'),
- 'email.html'
+ 'email.html',
+ '0'
)
);
diff --git a/tests/codeigniter/libraries/Calendar_test.php b/tests/codeigniter/libraries/Calendar_test.php
new file mode 100644
index 000000000..95668d70d
--- /dev/null
+++ b/tests/codeigniter/libraries/Calendar_test.php
@@ -0,0 +1,204 @@
+<?php
+
+class Calendar_test extends CI_TestCase {
+
+ function __construct()
+ {
+ $obj = new stdClass;
+ $obj->calendar = new Mock_Libraries_Calendar();
+
+ $this->calendar = $obj->calendar;
+ }
+
+ function test_initialize()
+ {
+ $this->calendar->initialize(array(
+ 'month_type' => 'short',
+ 'start_day' => 'monday'
+ ));
+ $this->assertEquals('short', $this->calendar->month_type);
+ $this->assertEquals('monday', $this->calendar->start_day);
+ }
+
+ /**
+ * @covers Mock_Libraries_Calendar::parse_template
+ */
+ function test_generate()
+ {
+ $no_events = '<table border="0" cellpadding="4" cellspacing="0">
+
+<tr>
+<th colspan="7">September&nbsp;2011</th>
+
+</tr>
+
+<tr>
+<td>Su</td><td>Mo</td><td>Tu</td><td>We</td><td>Th</td><td>Fr</td><td>Sa</td>
+</tr>
+
+<tr>
+<td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>1</td><td>2</td><td>3</td>
+</tr>
+
+<tr>
+<td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td>
+</tr>
+
+<tr>
+<td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td>
+</tr>
+
+<tr>
+<td>18</td><td>19</td><td>20</td><td>21</td><td>22</td><td>23</td><td>24</td>
+</tr>
+
+<tr>
+<td>25</td><td>26</td><td>27</td><td>28</td><td>29</td><td>30</td><td>&nbsp;</td>
+</tr>
+
+</table>';
+
+ $this->assertEquals($no_events, $this->calendar->generate(2011, 9));
+
+ $data = array(
+ 3 => 'http://example.com/news/article/2006/03/',
+ 7 => 'http://example.com/news/article/2006/07/',
+ 13 => 'http://example.com/news/article/2006/13/',
+ 26 => 'http://example.com/news/article/2006/26/'
+ );
+
+ $events = '<table border="0" cellpadding="4" cellspacing="0">
+
+<tr>
+<th colspan="7">September&nbsp;2011</th>
+
+</tr>
+
+<tr>
+<td>Su</td><td>Mo</td><td>Tu</td><td>We</td><td>Th</td><td>Fr</td><td>Sa</td>
+</tr>
+
+<tr>
+<td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>1</td><td>2</td><td><a href="http://example.com/news/article/2006/03/">3</a></td>
+</tr>
+
+<tr>
+<td>4</td><td>5</td><td>6</td><td><a href="http://example.com/news/article/2006/07/">7</a></td><td>8</td><td>9</td><td>10</td>
+</tr>
+
+<tr>
+<td>11</td><td>12</td><td><a href="http://example.com/news/article/2006/13/">13</a></td><td>14</td><td>15</td><td>16</td><td>17</td>
+</tr>
+
+<tr>
+<td>18</td><td>19</td><td>20</td><td>21</td><td>22</td><td>23</td><td>24</td>
+</tr>
+
+<tr>
+<td>25</td><td><a href="http://example.com/news/article/2006/26/">26</a></td><td>27</td><td>28</td><td>29</td><td>30</td><td>&nbsp;</td>
+</tr>
+
+</table>';
+
+ $this->assertEquals($events, $this->calendar->generate(2011, 9, $data));
+ }
+
+ function test_get_month_name()
+ {
+ $this->calendar->month_type = NULL;
+ $this->assertEquals('January', $this->calendar->get_month_name('01'));
+
+ $this->calendar->month_type = 'short';
+ $this->assertEquals('Jan', $this->calendar->get_month_name('01'));
+ }
+
+ function test_get_day_names()
+ {
+ $this->assertEquals(array(
+ 'Sunday',
+ 'Monday',
+ 'Tuesday',
+ 'Wednesday',
+ 'Thursday',
+ 'Friday',
+ 'Saturday'
+ ), $this->calendar->get_day_names('long'));
+
+ $this->assertEquals(array(
+ 'Sun',
+ 'Mon',
+ 'Tue',
+ 'Wed',
+ 'Thu',
+ 'Fri',
+ 'Sat'
+ ), $this->calendar->get_day_names('short'));
+
+ $this->calendar->day_type = NULL;
+
+ $this->assertEquals(array(
+ 'Su',
+ 'Mo',
+ 'Tu',
+ 'We',
+ 'Th',
+ 'Fr',
+ 'Sa'
+ ), $this->calendar->get_day_names());
+ }
+
+ function test_adjust_date()
+ {
+ $this->assertEquals(array('month' => 8, 'year' => 2012), $this->calendar->adjust_date(8, 2012));
+ $this->assertEquals(array('month' => 1, 'year' => 2013), $this->calendar->adjust_date(13, 2012));
+ }
+
+ function test_get_total_days()
+ {
+ $this->assertEquals(0, $this->calendar->get_total_days(13, 2012));
+
+ $this->assertEquals(31, $this->calendar->get_total_days(1, 2012));
+ $this->assertEquals(28, $this->calendar->get_total_days(2, 2011));
+ $this->assertEquals(29, $this->calendar->get_total_days(2, 2012));
+ $this->assertEquals(31, $this->calendar->get_total_days(3, 2012));
+ $this->assertEquals(30, $this->calendar->get_total_days(4, 2012));
+ $this->assertEquals(31, $this->calendar->get_total_days(5, 2012));
+ $this->assertEquals(30, $this->calendar->get_total_days(6, 2012));
+ $this->assertEquals(31, $this->calendar->get_total_days(7, 2012));
+ $this->assertEquals(31, $this->calendar->get_total_days(8, 2012));
+ $this->assertEquals(30, $this->calendar->get_total_days(9, 2012));
+ $this->assertEquals(31, $this->calendar->get_total_days(10, 2012));
+ $this->assertEquals(30, $this->calendar->get_total_days(11, 2012));
+ $this->assertEquals(31, $this->calendar->get_total_days(12, 2012));
+ }
+
+ function test_default_template()
+ {
+ $array = array(
+ 'table_open' => '<table border="0" cellpadding="4" cellspacing="0">',
+ 'heading_row_start' => '<tr>',
+ 'heading_previous_cell' => '<th><a href="{previous_url}">&lt;&lt;</a></th>',
+ 'heading_title_cell' => '<th colspan="{colspan}">{heading}</th>',
+ 'heading_next_cell' => '<th><a href="{next_url}">&gt;&gt;</a></th>',
+ 'heading_row_end' => '</tr>',
+ 'week_row_start' => '<tr>',
+ 'week_day_cell' => '<td>{week_day}</td>',
+ 'week_row_end' => '</tr>',
+ 'cal_row_start' => '<tr>',
+ 'cal_cell_start' => '<td>',
+ 'cal_cell_start_today' => '<td>',
+ 'cal_cell_content' => '<a href="{content}">{day}</a>',
+ 'cal_cell_content_today' => '<a href="{content}"><strong>{day}</strong></a>',
+ 'cal_cell_no_content' => '{day}',
+ 'cal_cell_no_content_today' => '<strong>{day}</strong>',
+ 'cal_cell_blank' => '&nbsp;',
+ 'cal_cell_end' => '</td>',
+ 'cal_cell_end_today' => '</td>',
+ 'cal_row_end' => '</tr>',
+ 'table_close' => '</table>'
+ );
+
+ $this->assertEquals($array, $this->calendar->default_template());
+ }
+
+} \ No newline at end of file
diff --git a/tests/codeigniter/libraries/Session_test.php b/tests/codeigniter/libraries/Session_test.php
index 135f71806..60d3a5b30 100644
--- a/tests/codeigniter/libraries/Session_test.php
+++ b/tests/codeigniter/libraries/Session_test.php
@@ -30,15 +30,11 @@ class Session_test extends CI_TestCase {
// Establish necessary support classes
$obj = new stdClass;
- $classes = array(
- 'config' => 'cfg',
- 'load' => 'load',
- 'input' => 'in'
- );
- foreach ($classes as $name => $abbr) {
- $class = $this->ci_core_class($abbr);
- $obj->$name = new $class;
- }
+ $cfg = $this->ci_core_class('cfg');
+ $obj->config = new $cfg();
+ $ldr = $this->ci_core_class('load');
+ $obj->load = new $ldr();
+ $obj->input = new Mock_Core_Input(NULL, NULL);
$this->ci_instance($obj);
// Attach session instance locally
@@ -401,5 +397,4 @@ class Session_test extends CI_TestCase {
$this->session->native->sess_destroy();
$this->assertNull($this->session->native->userdata($key));
}
-}
-
+} \ No newline at end of file
diff --git a/tests/codeigniter/libraries/Upload_test.php b/tests/codeigniter/libraries/Upload_test.php
new file mode 100644
index 000000000..d79a3ffc9
--- /dev/null
+++ b/tests/codeigniter/libraries/Upload_test.php
@@ -0,0 +1,270 @@
+<?php
+
+class Upload_test extends CI_TestCase {
+
+ function set_up()
+ {
+ $obj = new stdClass;
+ $obj->upload = new Mock_Libraries_Upload();
+ $obj->security = new Mock_Core_Security();
+ $obj->lang = new Mock_Core_Lang();
+
+ $this->ci_instance($obj);
+ $this->upload = $obj->upload;
+
+ vfsStreamWrapper::register();
+ vfsStreamWrapper::setRoot(new vfsStreamDirectory('testDir'));
+
+ $this->_test_dir = vfsStreamWrapper::getRoot();
+ }
+
+ function test_do_upload()
+ {
+ $this->markTestIncomplete('We can\'t really test this at the moment because of the call to `is_uploaded_file` in do_upload which isn\'t supported by vfsStream');
+ }
+
+ function test_data()
+ {
+ $data = array(
+ 'file_name' => 'hello.txt',
+ 'file_type' => 'text/plain',
+ 'file_path' => '/tmp/',
+ 'full_path' => '/tmp/hello.txt',
+ 'raw_name' => 'hello',
+ 'orig_name' => 'hello.txt',
+ 'client_name' => '',
+ 'file_ext' => '.txt',
+ 'file_size' => 100,
+ 'is_image' => FALSE,
+ 'image_width' => '',
+ 'image_height' => '',
+ 'image_type' => '',
+ 'image_size_str' => ''
+ );
+
+ $this->upload->set_upload_path('/tmp/');
+
+ foreach ($data as $k => $v)
+ {
+ $this->upload->{$k} = $v;
+ }
+
+ $this->assertEquals('hello.txt', $this->upload->data('file_name'));
+ $this->assertEquals($data, $this->upload->data());
+ }
+
+ function test_set_upload_path()
+ {
+ $this->upload->set_upload_path('/tmp/');
+ $this->assertEquals('/tmp/', $this->upload->upload_path);
+
+ $this->upload->set_upload_path('/tmp');
+ $this->assertEquals('/tmp/', $this->upload->upload_path);
+ }
+
+ function test_set_filename()
+ {
+ $file1 = vfsStream::newFile('hello-world.txt')->withContent('Hello world.')->at($this->_test_dir);
+ $this->upload->file_ext = '.txt';
+
+ $this->assertEquals('helloworld.txt', $this->upload->set_filename(vfsStream::url('testDir').'/', 'helloworld.txt'));
+ $this->assertEquals('hello-world1.txt', $this->upload->set_filename(vfsStream::url('testDir').'/', 'hello-world.txt'));
+ }
+
+ function test_set_max_filesize()
+ {
+ $this->upload->set_max_filesize(100);
+ $this->assertEquals(100, $this->upload->max_size);
+ }
+
+ function test_set_max_filename()
+ {
+ $this->upload->set_max_filename(100);
+ $this->assertEquals(100, $this->upload->max_filename);
+ }
+
+ function test_set_max_width()
+ {
+ $this->upload->set_max_width(100);
+ $this->assertEquals(100, $this->upload->max_width);
+ }
+
+ function test_set_max_height()
+ {
+ $this->upload->set_max_height(100);
+ $this->assertEquals(100, $this->upload->max_height);
+ }
+
+ function test_set_allowed_types()
+ {
+ $this->upload->set_allowed_types('*');
+ $this->assertEquals('*', $this->upload->allowed_types);
+
+ $this->upload->set_allowed_types('foo|bar');
+ $this->assertEquals(array('foo', 'bar'), $this->upload->allowed_types);
+ }
+
+ function test_set_image_properties()
+ {
+ $this->upload->file_type = 'image/gif';
+ $this->upload->file_temp = 'tests/mocks/uploads/ci_logo.gif';
+
+ $props = array(
+ 'image_width' => 170,
+ 'image_height' => 73,
+ 'image_type' => 'gif',
+ 'image_size_str' => 'width="170" height="73"'
+ );
+
+ $this->upload->set_image_properties($this->upload->file_temp);
+
+ $this->assertEquals($props['image_width'], $this->upload->image_width);
+ $this->assertEquals($props['image_height'], $this->upload->image_height);
+ $this->assertEquals($props['image_type'], $this->upload->image_type);
+ $this->assertEquals($props['image_size_str'], $this->upload->image_size_str);
+ }
+
+ function test_set_xss_clean()
+ {
+ $this->upload->set_xss_clean(TRUE);
+ $this->assertTrue($this->upload->xss_clean);
+
+ $this->upload->set_xss_clean(FALSE);
+ $this->assertFalse($this->upload->xss_clean);
+ }
+
+ function test_is_image()
+ {
+ $this->upload->file_type = 'image/x-png';
+ $this->assertTrue($this->upload->is_image());
+
+ $this->upload->file_type = 'text/plain';
+ $this->assertFalse($this->upload->is_image());
+ }
+
+ function test_is_allowed_filetype()
+ {
+ $this->upload->allowed_types = array('html', 'gif');
+
+ $this->upload->file_ext = '.txt';
+ $this->upload->file_type = 'text/plain';
+ $this->assertFalse($this->upload->is_allowed_filetype(FALSE));
+ $this->assertFalse($this->upload->is_allowed_filetype(TRUE));
+
+ $this->upload->file_ext = '.html';
+ $this->upload->file_type = 'text/html';
+ $this->assertTrue($this->upload->is_allowed_filetype(FALSE));
+ $this->assertTrue($this->upload->is_allowed_filetype(TRUE));
+
+ $this->upload->file_temp = 'tests/mocks/uploads/ci_logo.gif';
+ $this->upload->file_ext = '.gif';
+ $this->upload->file_type = 'image/gif';
+ $this->assertTrue($this->upload->is_allowed_filetype());
+ }
+
+ function test_is_allowed_filesize()
+ {
+ $this->upload->max_size = 100;
+ $this->upload->file_size = 99;
+
+ $this->assertTrue($this->upload->is_allowed_filesize());
+
+ $this->upload->file_size = 101;
+ $this->assertFalse($this->upload->is_allowed_filesize());
+ }
+
+ function test_is_allowed_dimensions()
+ {
+ $this->upload->file_type = 'text/plain';
+ $this->assertTrue($this->upload->is_allowed_dimensions());
+
+ $this->upload->file_type = 'image/gif';
+ $this->upload->file_temp = 'tests/mocks/uploads/ci_logo.gif';
+
+ $this->upload->max_width = 10;
+ $this->assertFalse($this->upload->is_allowed_dimensions());
+
+ $this->upload->max_width = 170;
+ $this->upload->max_height = 10;
+ $this->assertFalse($this->upload->is_allowed_dimensions());
+
+ $this->upload->max_height = 73;
+ $this->assertTrue($this->upload->is_allowed_dimensions());
+ }
+
+ function test_validate_upload_path()
+ {
+ $this->upload->upload_path = '';
+ $this->assertFalse($this->upload->validate_upload_path());
+
+ $this->upload->upload_path = vfsStream::url('testDir');
+ $this->assertTrue($this->upload->validate_upload_path());
+ }
+
+ function test_get_extension()
+ {
+ $this->assertEquals('.txt', $this->upload->get_extension('hello.txt'));
+ $this->assertEquals('.htaccess', $this->upload->get_extension('.htaccess'));
+ $this->assertEquals('', $this->upload->get_extension('hello'));
+ }
+
+ function test_clean_file_name()
+ {
+ $this->assertEquals('hello.txt', $this->upload->clean_file_name('hello.txt'));
+ $this->assertEquals('hello.txt', $this->upload->clean_file_name('%253chell>o.txt'));
+ }
+
+ function test_limit_filename_length()
+ {
+ $this->assertEquals('hello.txt', $this->upload->limit_filename_length('hello.txt', 10));
+ $this->assertEquals('hello.txt', $this->upload->limit_filename_length('hello-world.txt', 9));
+ }
+
+ function test_do_xss_clean()
+ {
+ $file1 = vfsStream::newFile('file1.txt')->withContent('The billy goat was waiting for them.')->at($this->_test_dir);
+ $file2 = vfsStream::newFile('file2.txt')->at($this->_test_dir);
+ $file3 = vfsStream::newFile('file3.txt')->withContent('<script type="text/javascript">alert("Boo! said the billy goat")</script>')->at($this->_test_dir);
+
+ $this->upload->file_temp = vfsStream::url('file1.txt');
+ $this->assertTrue($this->upload->do_xss_clean());
+
+ $this->upload->file_temp = vfsStream::url('file2.txt');
+ $this->assertFalse($this->upload->do_xss_clean());
+
+ $this->upload->file_temp = vfsStream::url('file3.txt');
+ $this->assertFalse($this->upload->do_xss_clean());
+
+ $this->upload->file_temp = 'tests/mocks/uploads/ci_logo.gif';
+ $this->assertTrue($this->upload->do_xss_clean());
+ }
+
+ function test_set_error()
+ {
+ $errors = array(
+ 'An error!'
+ );
+
+ $another = 'Another error!';
+
+ $this->upload->set_error($errors);
+ $this->assertEquals($errors, $this->upload->error_msg);
+
+ $errors[] = $another;
+ $this->upload->set_error($another);
+ $this->assertEquals($errors, $this->upload->error_msg);
+ }
+
+ function test_display_errors()
+ {
+ $this->upload->error_msg[] = 'Error test';
+ $this->assertEquals('<p>Error test</p>', $this->upload->display_errors());
+ }
+
+ function test_mimes_types()
+ {
+ $this->assertEquals('text/plain', $this->upload->mimes_types('txt'));
+ $this->assertFalse($this->upload->mimes_types('foobar'));
+ }
+
+} \ No newline at end of file
diff --git a/tests/mocks/core/input.php b/tests/mocks/core/input.php
index 2a4aa4997..0d1873849 100644
--- a/tests/mocks/core/input.php
+++ b/tests/mocks/core/input.php
@@ -28,4 +28,14 @@ class Mock_Core_Input extends CI_Input {
return parent::_fetch_from_array($array, $index, $xss_clean);
}
+ /**
+ * Lie about being a CLI request
+ *
+ * We take advantage of this in libraries/Session_test
+ */
+ public function is_cli_request()
+ {
+ return FALSE;
+ }
+
} \ No newline at end of file
diff --git a/tests/mocks/core/lang.php b/tests/mocks/core/lang.php
new file mode 100644
index 000000000..1b99aedb3
--- /dev/null
+++ b/tests/mocks/core/lang.php
@@ -0,0 +1,15 @@
+<?php
+
+class Mock_Core_Lang extends CI_Lang {
+
+ function line($line = '')
+ {
+ return FALSE;
+ }
+
+ function load($langfile, $idiom = '', $return = false, $add_suffix = true, $alt_path = '')
+ {
+ return;
+ }
+
+} \ No newline at end of file
diff --git a/tests/mocks/libraries/calendar.php b/tests/mocks/libraries/calendar.php
new file mode 100644
index 000000000..8fee5365e
--- /dev/null
+++ b/tests/mocks/libraries/calendar.php
@@ -0,0 +1,25 @@
+<?php
+
+class Mock_Libraries_Calendar extends CI_Calendar {
+
+ public function __construct($config = array())
+ {
+ $this->CI = new stdClass;
+ $this->CI->lang = new Mock_Core_Lang();
+
+ if ( ! in_array('calendar_lang.php', $this->CI->lang->is_loaded, TRUE))
+ {
+ $this->CI->lang->load('calendar');
+ }
+
+ $this->local_time = time();
+
+ if (count($config) > 0)
+ {
+ $this->initialize($config);
+ }
+
+ log_message('debug', 'Calendar Class Initialized');
+ }
+
+} \ No newline at end of file
diff --git a/tests/mocks/libraries/upload.php b/tests/mocks/libraries/upload.php
new file mode 100644
index 000000000..988723e45
--- /dev/null
+++ b/tests/mocks/libraries/upload.php
@@ -0,0 +1,3 @@
+<?php
+
+class Mock_Libraries_Upload extends CI_Upload {} \ No newline at end of file
diff --git a/tests/mocks/uploads/ci_logo.gif b/tests/mocks/uploads/ci_logo.gif
new file mode 100644
index 000000000..073ec14b4
--- /dev/null
+++ b/tests/mocks/uploads/ci_logo.gif
Binary files differ
diff --git a/tests/travis/mysql.phpunit.xml b/tests/travis/mysql.phpunit.xml
index 38c8eba48..06d4a011b 100644
--- a/tests/travis/mysql.phpunit.xml
+++ b/tests/travis/mysql.phpunit.xml
@@ -18,7 +18,7 @@
</testsuite>
</testsuites>
<filter>
- <whitelist addUncoveredFilesFromWhitelist="true">
+ <whitelist addUncoveredFilesFromWhitelist="false">
<directory suffix=".php">../../system</directory>
</whitelist>
</filter>
diff --git a/tests/travis/pdo/mysql.phpunit.xml b/tests/travis/pdo/mysql.phpunit.xml
index c3113a66f..7121edc45 100644
--- a/tests/travis/pdo/mysql.phpunit.xml
+++ b/tests/travis/pdo/mysql.phpunit.xml
@@ -18,7 +18,7 @@
</testsuite>
</testsuites>
<filter>
- <whitelist addUncoveredFilesFromWhitelist="true">
+ <whitelist addUncoveredFilesFromWhitelist="false">
<directory suffix=".php">../../../system</directory>
</whitelist>
</filter>
diff --git a/tests/travis/pdo/pgsql.phpunit.xml b/tests/travis/pdo/pgsql.phpunit.xml
index 232025523..df3ff986e 100644
--- a/tests/travis/pdo/pgsql.phpunit.xml
+++ b/tests/travis/pdo/pgsql.phpunit.xml
@@ -18,7 +18,7 @@
</testsuite>
</testsuites>
<filter>
- <whitelist addUncoveredFilesFromWhitelist="true">
+ <whitelist addUncoveredFilesFromWhitelist="false">
<directory suffix=".php">../../../system</directory>
</whitelist>
</filter>
diff --git a/tests/travis/pdo/sqlite.phpunit.xml b/tests/travis/pdo/sqlite.phpunit.xml
index 3d1256721..7d867f6d1 100644
--- a/tests/travis/pdo/sqlite.phpunit.xml
+++ b/tests/travis/pdo/sqlite.phpunit.xml
@@ -18,7 +18,7 @@
</testsuite>
</testsuites>
<filter>
- <whitelist addUncoveredFilesFromWhitelist="true">
+ <whitelist addUncoveredFilesFromWhitelist="false">
<directory suffix=".php">../../../system</directory>
</whitelist>
</filter>
diff --git a/tests/travis/pgsql.phpunit.xml b/tests/travis/pgsql.phpunit.xml
index 51e433d76..bfddbf6b5 100644
--- a/tests/travis/pgsql.phpunit.xml
+++ b/tests/travis/pgsql.phpunit.xml
@@ -18,7 +18,7 @@
</testsuite>
</testsuites>
<filter>
- <whitelist addUncoveredFilesFromWhitelist="true">
+ <whitelist addUncoveredFilesFromWhitelist="false">
<directory suffix=".php">../../system</directory>
</whitelist>
</filter>
diff --git a/tests/travis/sqlite.phpunit.xml b/tests/travis/sqlite.phpunit.xml
index 701165734..75c946aee 100644
--- a/tests/travis/sqlite.phpunit.xml
+++ b/tests/travis/sqlite.phpunit.xml
@@ -18,7 +18,7 @@
</testsuite>
</testsuites>
<filter>
- <whitelist addUncoveredFilesFromWhitelist="true">
+ <whitelist addUncoveredFilesFromWhitelist="false">
<directory suffix=".php">../../system</directory>
</whitelist>
</filter>
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index 77c018a11..ba2036dd8 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -39,7 +39,7 @@ Release Date: Not Released
- Updated support for zip files in mimes.php.
- Updated support for csv files in mimes.php.
- Added some more doctypes.
- - Added Romanian and Greek characters in foreign_characters.php.
+ - Added Romanian, Greek and Vietnamese characters in *foreign_characters.php*.
- Changed logger to only chmod when file is first created.
- Removed previously deprecated SHA1 Library.
- Removed previously deprecated use of ``$autoload['core']`` in application/config/autoload.php.
@@ -51,7 +51,8 @@ Release Date: Not Released
- Changed detection of ``$view_folder`` so that if it's not found in the current path, it will now also be searched for under the application folder.
- Path constants BASEPATH, APPPATH and VIEWPATH are now (internally) defined as absolute paths.
- Updated email validation methods to use ``filter_var()`` instead of PCRE.
- - Changed environment defaults to report all errors in 'development' and only fatal ones in 'testing' and 'production' but only display them in 'development'.
+ - Changed environment defaults to report all errors in *development* and only fatal ones in *testing*, *production* but only display them in *development*.
+ - Updated *ip_address* database field lengths from 16 to 45 for supporting IPv6 address on :doc:`Trackback Library <libraries/trackback>` and :doc:`Captcha Helper <helpers/captcha_helper>`.
- Helpers
@@ -59,13 +60,15 @@ Release Date: Not Released
- ``now()`` now works with all timezone strings supported by PHP.
- Added an optional third parameter to ``timespan()`` that constrains the number of time units displayed.
- Added an optional parameter to ``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://bg2.php.net/manual/en/class.datetime.php#datetime.constants.types>`_.
+ - 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 ``date_range()`` that generates a list of dates between a specified period.
- ``create_captcha()`` accepts additional colors parameter, allowing for color customization.
- :doc:`URL Helper <helpers/url_helper>` changes include:
- ``url_title()`` will now trim extra dashes from beginning and end.
- ``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 ``anchor_popup()`` function.
- Added support (auto-detection) for HTTP/1.1 response code 303 in ``redirect()``.
+ - "auto" method in ``redirect()`` now chooses the "refresh" method only on IIS servers, instead of all servers on Windows.
- Added XHTML Basic 1.1 doctype to :doc:`HTML Helper <helpers/html_helper>`.
- Changed ``humanize()`` to include a second param for the separator.
- Refactored ``plural()`` and ``singular()`` to avoid double pluralization and support more words.
@@ -73,7 +76,7 @@ Release Date: Not Released
- Added a work-around in ``force_download()`` for a bug Android <= 2.1, where the filename extension needs to be in uppercase.
- ``form_dropdown()`` will now also take an array for unity with other form helpers.
- ``do_hash()`` now uses PHP's native ``hash()`` function (supporting more algorithms) and is deprecated.
- - Removed previously deprecated helper function ``js_insert_smiley()`` from smiley helper.
+ - Removed previously deprecated helper function ``js_insert_smiley()`` from :doc:`Smiley Helper <helpers/smiley_helper>`.
- :doc:`File Helper <helpers/file_helper>` changes include:
- ``set_realpath()`` can now also handle file paths as opposed to just directories.
- Added an optional paramater to ``delete_files()`` to enable it to skip deleting files such as .htaccess and index.html.
@@ -142,25 +145,39 @@ Release Date: Not Released
- Added PDO support for ``list_fields()`` in :doc:`Database Results <database/results>`.
- Added capability for packages to hold database.php config files
- Added subdrivers support (currently only used by PDO).
+ - Added client compression support for MySQL and MySQLi.
+ - Removed :doc:`Loader Class <libraries/loader>` from Database error tracing to better find the likely culprit.
- Libraries
- - CI_Session now respects php.ini's session.gc_probability and session.gc_divisor
- - Added max_filename_increment config setting for Upload library.
- - CI_Loader::_ci_autoloader() is now a protected method.
+ - :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 session drivers can be added anywhere in package paths and loaded with Session library.
+ - Session 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
+ - 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.
+ - :doc:`File Uploading Library <libraries/file_uploading>` changes include:
+ - Added *max_filename_increment* config setting.
+ - Added an "index" parameter to the ``data()`` method.
- :doc:`Cart library <libraries/cart>` changes include:
- It now auto-increments quantity's instead of just resetting it, this is the default behaviour of large e-commerce sites.
- Product Name strictness can be disabled via the Cart Library by switching "$product_name_safe".
- Added function remove() to remove a cart item, updating with quantity of 0 seemed like a hack but has remained to retain compatibility.
- :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
- - Removed SHA1 function in the :doc:`Encryption Library <libraries/encryption>`.
- - Added $config['csrf_regeneration'] to the CSRF protection in the :doc:`Security library <libraries/security>`, which makes token regeneration optional.
- - Added $config['csrf_exclude_uris'] to the CSRF protection in the :doc:`Security library <libraries/security>`, which allows you list URIs which will not have the CSRF validation functions run.
+ - 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.
@@ -171,9 +188,7 @@ Release Date: Not Released
- Native PHP functions used as rules can now accept an additional parameter, other than the data itself.
- Updated 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).
- - Changed the :doc:`Session Library <libraries/sessions>` to select only one row when using database sessions.
- - Added all_flashdata() method to session class. Returns an associative array of only flashdata.
- - Allowed for setting table class defaults in a config file.
+ - Added support for setting :doc:`Table <libraries/table>` class defaults in a config file.
- Added a Wincache driver to the :doc:`Caching Library <libraries/caching>`.
- Added a Redis driver to the :doc:`Caching Library <libraries/caching>`.
- :doc:`Email library <libraries/email>` changes include:
@@ -182,34 +197,50 @@ Release Date: Not Released
- 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 an "index" parameter to the data() method in the :doc:`Upload Library <libraries/file_uploading>`.
+ - 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()`` function on PHP 5.3+ if CRLF is set to "\r\n".
- :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>`.
+ - :doc:`Encryption Library <libraries/encryption>` changes include:
+ - Added support for hashing algorithms other than SHA1 and MD5.
+ - Removed previously deprecated ``sha1()`` method.
- Core
- Changed private methods in the :doc:`URI Library <libraries/uri>` to protected so MY_URI can override them.
- - Removed CI_CORE boolean constant from CodeIgniter.php (no longer Reactor and Core versions).
- - Added method get_vars() to the :doc:`Loader Library <libraries/loader>` to retrieve all variables loaded with $this->load->vars().
- - is_loaded() function from system/core/Commons.php now returns a reference.
- - $config['rewrite_short_tags'] now has no effect when using PHP 5.4 as *<?=* will always be available.
- - Added method() to the :doc:`Input Library <libraries/input>` to retrieve $_SERVER['REQUEST_METHOD'].
- - Modified valid_ip() to use PHP's filter_var() in the :doc:`Input Library <libraries/input>`.
- - 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 get_content_type() method to the :doc:`Output Library <libraries/output>`.
- - Added get_mimes() function to system/core/Commons.php to return the config/mimes.php array.
- - Added a second argument to set_content_type() in the :doc:`Output Library <libraries/output>` that allows setting the document charset as well.
- - $config['time_reference'] now supports all timezone strings supported by PHP.
- - Added support for HTTP code 303 ("See Other") in set_status_header().
- - Changed :doc:`Config Library <libraries/config>` method site_url() to accept an array as well.
- - Added method ``strip_image_tags()`` to the :doc:`Security Library <libraries/security>`.
- - Changed ``_exception_handler()`` to respect php.ini 'display_errors' setting.
- - Added support for IPv4 range masks (e.g. 192.168.1.1/24) to specify ranges of IP addresses for use with the proxy_ips setting.
+ - Removed ``CI_CORE`` boolean constant from *CodeIgniter.php* (no longer Reactor and Core versions).
+ - :doc:`Loader Library <libraries/loader>` changes include:
+ - Added method ``get_vars()`` to the Loader to retrieve all variables loaded with ``$this->load->vars()``.
+ - ``CI_Loader::_ci_autoloader()`` is now a protected method.
+ - Added autoloading of drivers with ``$autoload['drivers']``.
+ - ``CI_Loader::library()`` will now load drivers as well, for backward compatibility of converted libraries (like Session).
+ - ``$config['rewrite_short_tags']`` now has no effect when using PHP 5.4 as *<?=* will always be available.
+ - :doc:`Input Library <libraries/input>` changes include:
+ - Added ``method()`` to retrieve ``$_SERVER['REQUEST_METHOD']``.
+ - Modified ``valid_ip()`` to use PHP's ``filter_var()``.
+ - Added support for arrays and network addresses (e.g. 192.168.1.1/24) for use with the *proxy_ips* setting.
+ - :doc:`Common functions <general/common_functions>` changes include:
+ - Added ``get_mimes()`` function to return the *config/mimes.php* array.
+ - Added support for HTTP code 303 ("See Other") in ``set_status_header()``.
+ - Removed redundant conditional to determine HTTP server protocol in ``set_status_header()``.
+ - Changed ``_exception_handler()`` to respect php.ini *display_errors* setting.
+ - 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>`.
+ - :doc:`Output Library <libraries/output>` changes include:
+ - Added method ``get_content_type()``.
+ - Added a second argument to method ``set_content_type()`` that allows setting the document charset as well.
+ - ``$config['time_reference']`` now supports all timezone strings supported by PHP.
+ - Changed :doc:`Config Library <libraries/config>` method ``site_url()`` to accept an array as well.
+ - :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.
Bug fixes for 3.0
------------------
@@ -244,23 +275,20 @@ Bug fixes for 3.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.
- Fixed a bug (#153) - E_NOTICE being generated by getimagesize() in the :doc:`File Uploading Library <libraries/file_uploading>`.
- Fixed a bug (#611) - SQLSRV's error handling methods used to issue warnings when there's no actual error.
-- Fixed a bug (#1036) - is_write_type() method in the :doc:`Database Library <database/index>` didn't return TRUE for RENAME queries.
+- Fixed a bug (#1036) - ``is_write_type()`` method in the :doc:`Database Library <database/index>` didn't return TRUE for RENAME queries.
- Fixed a bug in PDO's _version() method where it used to return the client version as opposed to the server one.
- Fixed a bug in PDO's insert_id() method where it could've failed if it's used with Postgre versions prior to 8.1.
- Fixed a bug in CUBRID's affected_rows() method where a connection resource was passed to cubrid_affected_rows() instead of a result.
- Fixed a bug (#638) - db_set_charset() ignored its arguments and always used the configured charset instead.
- Fixed a bug (#413) - Oracle's error handling methods used to only return connection-related errors.
-- Fixed a bug (#804) - Profiler library was trying to handle objects as strings in some cases, resulting in warnings being issued by htmlspecialchars().
- Fixed a bug (#1101) - MySQL/MySQLi result method field_data() was implemented as if it was handling a DESCRIBE result instead of the actual result set.
- Fixed a bug in Oracle's :doc:`Database Forge Class <database/forge>` method _create_table() where it failed with AUTO_INCREMENT as it's not supported.
- Fixed a bug (#1080) - When using the SMTP protocol, the :doc:`Email Library <libraries/email>` send() method was returning TRUE even if the connection/authentication against the server failed.
-- Fixed a bug (#499) - a CSRF cookie was created even with CSRF protection being disabled.
- Fixed a bug (#306) - ODBC's insert_id() method was calling non-existent function odbc_insert_id(), which resulted in a fatal error.
- Fixed a bug in Oracle's DB_result class where the cursor id passed to it was always NULL.
- Fixed a bug (#64) - Regular expression in DB_query_builder.php failed to handle queries containing SQL bracket delimiters in the join condition.
- Fixed a bug in the :doc:`Session Library <libraries/sessions>` where a PHP E_NOTICE error was triggered by _unserialize() due to results from databases such as MSSQL and Oracle being space-padded on the right.
- Fixed a bug (#501) - set_rules() to check if the request method is not 'POST' before aborting, instead of depending on count($_POST) in the :doc:`Form Validation Library <libraries/form_validation>`.
-- Fixed a bug (#940) - csrf_verify() used to set the CSRF cookie while processing a POST request with no actual POST data, which resulted in validating a request that should be considered invalid.
- Fixed a bug (#136) - PostgreSQL, MySQL and MySQLi's escape_str() method didn't properly escape LIKE wild characters.
- Fixed a bug in the library loader where some PHP versions wouldn't execute the class constructor.
- Fixed a bug (#88) - An unexisting property was used for configuration of the Memcache cache driver.
@@ -279,7 +307,6 @@ Bug fixes for 3.0
- Fixed a bug (#1265) - Database connections were always closed, regardless of the 'pconnect' option value.
- Fixed a bug (#128) - :doc:`Language Library <libraries/language>` did not correctly keep track of loaded language files.
- Fixed a bug (#1242) - Added Windows path compatibility to function read_dir of ZIP library.
-- Fixed a bug (#1314) - sess_destroy() did not destroy userdata.
- Fixed a bug (#1349) - get_extension() in the :doc:`File Uploading Library <libraries/file_uploading>` returned the original filename when it didn't have an actual extension.
- Fixed a bug (#1273) - E_NOTICE being generated by :doc:`Query Builder <database/query_builder>`'s set_update_batch() method.
- Fixed a bug (#44, #110) - :doc:`Upload library <libraries/file_uploading>`'s clean_file_name() method didn't clear '!' and '#' characters.
@@ -293,14 +320,13 @@ Bug fixes for 3.0
- Fixed a bug (#666) - :doc:`Output library <libraries/output>`'s set_content_type() method didn't set the document charset.
- 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 _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 (#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 ``_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.
-- Fixed a bug (#7) - :doc:`Query Builder <database/query_builder>`'s join() method only escaped one set of conditions.
+- Fixed a bug (#7) - :doc:`Query Builder <database/query_builder>`'s ``join()`` method only escaped one set of conditions.
- Fixed a bug (#1321) - Core Exceptions class couldn't find the errors/ folder in some cases.
-- Fixed a bug in the File-based :doc:`Cache Library <libraries/caching>` driver's get_metadata() method where a non-existent array key was accessed for the TTL value.
- Fixed a bug (#1202) - :doc:`Encryption Library <libraries/encryption>` encode_from_legacy() didn't set back the encrypt mode on failure.
- Fixed a bug (#145) - compile_binds() failed when the bind marker was present in a literal string within the query.
- Fixed a bug in protect_identifiers() where if passed along with the field names, operators got escaped as well.
@@ -322,6 +348,36 @@ Bug fixes for 3.0
- Fixed a bug (#1613) - :doc:`Form Helper <helpers/form_helper>` functions ``form_multiselect()``, ``form_dropdown()`` didn't properly handle empty array option groups.
- Fixed a bug (#1605) - :doc:`Pagination Library <libraries/pagination>` produced incorrect *previous* and *next* link values.
- Fixed a bug in SQLSRV's ``affected_rows()`` method where an erroneous function name was used.
+- Fixed a bug (#1000) - Change syntax of ``$view_file`` to ``$_ci_view_file`` to prevent being overwritten by application.
+- Fixed a bug (#1757) - :doc:`Directory Helper <helpers/directory_helper>` function ``directory_map()`` was skipping files and directories named *0*.
+- Fixed a bug (#1789) - :doc:`Database Library <database/index>` method ``escape_str()`` escaped quote characters in LIKE conditions twice under MySQL.
+- Fixed a bug (#395) - :doc:`Unit Testing Library <libraries/unit_testing>` method ``result()`` didn't properly check array result columns when called from ``report()``.
+- Fixed a bug (#1692) - :doc:`Database Library <database/index>` method ``display_error()`` didn't properly trace the possible error source on Windows systems.
+- Fixed a bug (#1745) - ``is_write_type()`` method in the :doc:`Database Library <database/index>` didn't return TRUE for LOAD queries.
+- Fixed a bug (#1765) - :doc:`Database Library <database/index>` didn't properly detect connection errors for MySQLi.
+- Fixed a bug (#1257) - :doc:`Query Builder <database/query_builder>` used to (unnecessarily) group FROM clause contents, which breaks certain queries and is invalid for some databases.
+- Fixed a bug (#1709) - :doc:`Email <libraries/email>` headers were broken when using long email subjects and \r\n as CRLF.
+
+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
+-------------------
+
+- Fixed a bug (#1543) - File-based :doc:`Caching <libraries/caching>` method ``get_metadata()`` used a non-existent array key to look for the TTL value.
+- Fixed a bug (#1314) - :doc:`Session Library <libraries/session>` method ``sess_destroy()`` didn't destroy the userdata array.
+- Fixed a bug (#804) - Profiler library was trying to handle objects as strings in some cases, resulting in *E_WARNING* messages being issued by ``htmlspecialchars()``.
+- Fixed a bug (#1699) - :doc:`Migration Library <libraries/migration>` ignored the ``$config['migration_path']`` setting.
+- Fixed a bug (#227) - :doc:`Input Library <libraries/input>` allowed unconditional spoofing of HTTP clients' IP addresses through the *HTTP_CLIENT_IP* header.
+- Fixed a bug (#907) - :doc:`Input Library <libraries/input>` ignored *HTTP_X_CLUSTER_CLIENT_IP* and *HTTP_X_CLIENT_IP* headers when checking for proxies.
+- Fixed a bug (#940) - ``csrf_verify()`` used to set the CSRF cookie while processing a POST request with no actual POST data, which resulted in validating a request that should be considered invalid.
+- Fixed a bug (#499) - :doc:`Security Library <libraries/security>` where a CSRF cookie was created even if ``$config['csrf_protection']`` is set tot FALSE.
+- Fixed a bug (#1715) - :doc:`Input Library <libraries/input>` triggered ``csrf_verify()`` on CLI requests.
Version 2.1.2
=============
diff --git a/user_guide_src/source/database/configuration.rst b/user_guide_src/source/database/configuration.rst
index c17de600a..636b5b5b2 100644
--- a/user_guide_src/source/database/configuration.rst
+++ b/user_guide_src/source/database/configuration.rst
@@ -28,6 +28,7 @@ prototype::
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',
'autoinit' => TRUE,
+ 'compress' => TRUE,
'stricton' => FALSE,
'failover' => array()
);
@@ -69,6 +70,7 @@ These failovers can be specified by setting the failover for a connection like t
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',
'autoinit' => TRUE,
+ 'compress' => TRUE,
'stricton' => FALSE
),
array(
@@ -86,6 +88,7 @@ These failovers can be specified by setting the failover for a connection like t
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',
'autoinit' => TRUE,
+ 'compress' => TRUE,
'stricton' => FALSE
)
);
@@ -115,6 +118,7 @@ example, to set up a "test" environment you would do this::
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',
'autoinit' => TRUE,
+ 'compress' => TRUE,
'stricton' => FALSE,
'failover' => array()
);
@@ -174,11 +178,12 @@ Explanation of Values:
customizable by the end user.
**autoinit** Whether or not to automatically connect to the database when the library loads. If set to false,
the connection will take place prior to executing the first query.
+**compress** Whether or not to use client compression for MySQL or MySQLi.
**stricton** TRUE/FALSE (boolean) - Whether to force "Strict Mode" connections, good for ensuring strict SQL
while developing an application.
**port** The database port number. To use this value you have to add a line to the database config array.
::
-
+
$db['default']['port'] = 5432;
====================== ==================================================================================================
diff --git a/user_guide_src/source/general/cli.rst b/user_guide_src/source/general/cli.rst
index 7dc1ca319..649d5d548 100644
--- a/user_guide_src/source/general/cli.rst
+++ b/user_guide_src/source/general/cli.rst
@@ -52,7 +52,7 @@ Now normally you would visit the your site using a URL similar to this::
example.com/index.php/tools/message/to
-Instead, we are going to open Terminal in Mac/Lunix or go to Run > "cmd"
+Instead, we are going to open Terminal in Mac/Linux or go to Run > "cmd"
in Windows and navigate to our CodeIgniter project.
.. code-block:: bash
diff --git a/user_guide_src/source/general/reserved_names.rst b/user_guide_src/source/general/reserved_names.rst
index 5ce7fc2ff..3354375c5 100644
--- a/user_guide_src/source/general/reserved_names.rst
+++ b/user_guide_src/source/general/reserved_names.rst
@@ -45,11 +45,11 @@ Constants
---------
- ENVIRONMENT
-- EXT
- FCPATH
- SELF
- BASEPATH
- APPPATH
+- VIEWPATH
- CI_VERSION
- FILE_READ_MODE
- FILE_WRITE_MODE
diff --git a/user_guide_src/source/helpers/captcha_helper.rst b/user_guide_src/source/helpers/captcha_helper.rst
index 48095a11d..90244739b 100644
--- a/user_guide_src/source/helpers/captcha_helper.rst
+++ b/user_guide_src/source/helpers/captcha_helper.rst
@@ -102,7 +102,7 @@ Here is a table prototype
CREATE TABLE captcha (  
captcha_id bigint(13) unsigned NOT NULL auto_increment,  
captcha_time int(10) unsigned NOT NULL,  
- ip_address varchar(16) default '0' NOT NULL,  
+ ip_address varchar(45) NOT NULL,  
word varchar(20) NOT NULL,  
PRIMARY KEY `captcha_id` (`captcha_id`),  
KEY `word` (`word`)
diff --git a/user_guide_src/source/helpers/date_helper.rst b/user_guide_src/source/helpers/date_helper.rst
index e332a913f..9de925ba7 100644
--- a/user_guide_src/source/helpers/date_helper.rst
+++ b/user_guide_src/source/helpers/date_helper.rst
@@ -306,6 +306,30 @@ Example
If the second parameter is empty, the current year will be used.
+date_range()
+============
+
+Returns a list of dates within a specified period.
+
+.. php:method:: date_range($unix_start = '', $mixed = '', $is_unix = TRUE, $format = 'Y-m-d')
+
+ :param integer $unix_start: UNIX timestamp of the range start date
+ :param integer $mixed: UNIX timestamp of the range end date or interval in days
+ :param boolean $is_unix: set to FALSE if $mixed is not a timestamp
+ :param string $format: output date format, same as in date()
+ :returns: array
+
+Example
+
+::
+
+ $range = date_range('2012-01-01', '2012-01-15');
+ echo "First 15 days of 2012:";
+ foreach ($range as $date)
+ {
+ echo $date."\n";
+ }
+
timezones()
===========
diff --git a/user_guide_src/source/helpers/url_helper.rst b/user_guide_src/source/helpers/url_helper.rst
index 305454048..1987dfb72 100644
--- a/user_guide_src/source/helpers/url_helper.rst
+++ b/user_guide_src/source/helpers/url_helper.rst
@@ -303,7 +303,7 @@ link. The function will build the URL based on your config file values.
The optional second parameter allows you to force a particular redirection
method. The available methods are "location" or "refresh", with location
-being faster but less reliable on Windows servers. The default is "auto",
+being faster but less reliable on IIS servers. The default is "auto",
which will attempt to intelligently choose the method based on the server
environment.
@@ -325,3 +325,7 @@ engine purposes. The default Response Code is 302. The third parameter is
.. note:: For very fine grained control over headers, you should use the
`Output Library </libraries/output>` set_header() function.
+
+.. note:: To IIS users: if you hide the `Server` HTTP header, the "auto"
+ method won't detect IIS, in that case it is advised you explicitly
+ use the "refresh" method.
diff --git a/user_guide_src/source/images/codeigniter_1.7.1_library_reference.png b/user_guide_src/source/images/codeigniter_1.7.1_library_reference.png
index 554ae2eed..7f054f95f 100644
--- a/user_guide_src/source/images/codeigniter_1.7.1_library_reference.png
+++ b/user_guide_src/source/images/codeigniter_1.7.1_library_reference.png
Binary files differ
diff --git a/user_guide_src/source/installation/upgrade_300.rst b/user_guide_src/source/installation/upgrade_300.rst
index 64a237069..31a5c0761 100644
--- a/user_guide_src/source/installation/upgrade_300.rst
+++ b/user_guide_src/source/installation/upgrade_300.rst
@@ -31,8 +31,24 @@ Step 3: 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: Add new session driver items to your config/config.php
+**************************************************************
+
+With the change from a single Session Library to the new Session Driver, two new config items have been added:
+
+ - ``$config['sess_driver']`` selects which driver to initially load. Options are:
+ - 'cookie' (the default) for classic CodeIgniter cookie-based sessions
+ - 'native' for native PHP Session support
+ - the name of a custom driver you have provided (see :doc:`Session Driver <../libraries/sessions>` for more info)
+ - ``$config['sess_valid_drivers']`` provides an array of additional custom drivers to make available for loading
+
+As the new Session Driver library loads the classic Cookie driver by default and always makes 'cookie' and 'native'
+available as valid drivers, neither of these configuration items are required. However, it is recommended that you
+add them for clarity and ease of configuration in the future.
+
***************************************
-Step 4: Update your config/database.php
+Step 5: 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
@@ -43,20 +59,20 @@ need to rename the `$active_record` variable to `$query_builder`.
$query_builder = TRUE;
*******************************
-Step 5: Move your errors folder
+Step 6: Move your errors folder
*******************************
In version 3.0.0, the errors folder has been moved from _application/errors* to _application/views/errors*.
****************************************************************************
-Step 6: Check the calls to Array Helper's element() and elements() functions
+Step 7: Check the calls to Array Helper's element() and elements() functions
****************************************************************************
The default return value of these functions, when the required elements
don't exist, has been changed from FALSE to NULL.
***************************************************************
-Step 7: Remove usage of (previously) deprecated functionalities
+Step 8: Remove usage of (previously) deprecated functionalities
***************************************************************
In addition to the ``$autoload['core']`` configuration setting, there's a number of other functionalities
@@ -151,4 +167,4 @@ emails. To override this behaviour, pass FALSE as the first parameter in the ``s
if ($this->email->send(FALSE))
{
// Parameters won't be cleared
- } \ No newline at end of file
+ }
diff --git a/user_guide_src/source/libraries/email.rst b/user_guide_src/source/libraries/email.rst
index 4403079b6..e7ed9f74c 100644
--- a/user_guide_src/source/libraries/email.rst
+++ b/user_guide_src/source/libraries/email.rst
@@ -117,6 +117,13 @@ Sets the email address and name of the person sending the email::
$this->email->from('you@example.com', 'Your Name');
+You can also set a Return-Path, to help redirect undelivered mail::
+
+ $this->email->from('you@example.com', 'Your Name', 'returned_emails@example.com');
+
+.. note:: Return-Path can't be used if you've configured
+ 'smtp' as your protocol.
+
$this->email->reply_to()
-------------------------
diff --git a/user_guide_src/source/libraries/file_uploading.rst b/user_guide_src/source/libraries/file_uploading.rst
index 65cd5c722..1698dcbb9 100644
--- a/user_guide_src/source/libraries/file_uploading.rst
+++ b/user_guide_src/source/libraries/file_uploading.rst
@@ -197,6 +197,7 @@ Preference Default Value Options Descripti
Separate multiple types with a pipe.
**file_name** None Desired file name If set CodeIgniter will rename the uploaded file to this name. The
extension provided in the file name must also be an allowed file type.
+ If no extension is provided in the original file_name will be used.
**overwrite** FALSE TRUE/FALSE (boolean) If set to true, if a file with the same name as the one you are
uploading exists, it will be overwritten. If set to false, a number will
be appended to the filename if another with the same name exists.
diff --git a/user_guide_src/source/libraries/form_validation.rst b/user_guide_src/source/libraries/form_validation.rst
index 3bcad7ba6..22272dc9b 100644
--- a/user_guide_src/source/libraries/form_validation.rst
+++ b/user_guide_src/source/libraries/form_validation.rst
@@ -399,7 +399,7 @@ The validation system supports callbacks to your own validation
functions. This permits you to extend the validation class to meet your
needs. For example, if you need to run a database query to see if the
user is choosing a unique username, you can create a callback function
-that does that. Let's create a example of this.
+that does that. Let's create an example of this.
In your controller, change the "username" rule to this::
@@ -488,6 +488,17 @@ the name of the function::
$this->form_validation->set_message('username_check')
+If you are using an error message that can accept two $s in your error string,
+such as:
+::
+
+ $this->form_validation->set_message('min_length', 'The $s field must contain at least $s characters.');
+
+Then you can also use %1$s and %2$s:
+::
+
+ $this->form_validation->set_message('min_length', 'This field must contain at least %2$s characters.');
+
You can also override any error message found in the language file. For
example, to change the message for the "required" rule you will do this::
@@ -861,8 +872,9 @@ Rule Parameter Description
========================= ========== ============================================================================================= =======================
**required** No Returns FALSE if the form element is empty.
**matches** Yes Returns FALSE if the form element does not match the one in the parameter. matches[form_item]
-**is_unique** Yes Returns FALSE if the form element is not unique to the is_unique[table.field]
- table and field name in the parameter. is_unique[table.field]
+**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.
**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]
@@ -884,7 +896,6 @@ Rule Parameter Description
0, 1, 2, 3, etc.
**is_natural_no_zero** No Returns FALSE if the form element contains anything other than a natural
number, but not zero: 1, 2, 3, etc.
-**is_unique** Yes Returns FALSE if the form element is not unique in a database table. is_unique[table.field]
**valid_email** No Returns FALSE if the form element does not contain a valid email address.
**valid_emails** No Returns FALSE if any value provided in a comma separated list is not a valid email.
**valid_ip** No Returns FALSE if the supplied IP is not valid.
diff --git a/user_guide_src/source/libraries/image_lib.rst b/user_guide_src/source/libraries/image_lib.rst
index ed6575c62..dcdccbd92 100644
--- a/user_guide_src/source/libraries/image_lib.rst
+++ b/user_guide_src/source/libraries/image_lib.rst
@@ -91,9 +91,9 @@ error upon failure, like this::
echo $this->image_lib->display_errors();
}
-Note: You can optionally specify the HTML formatting to be applied to
-the errors, by submitting the opening/closing tags in the function, like
-this::
+.. note:: You can optionally specify the HTML formatting to be applied to
+ the errors, by submitting the opening/closing tags in the function,
+ like this::
$this->image_lib->display_errors('<p>', '</p>');
@@ -225,8 +225,7 @@ pixels) specifying where to crop, like this::
$config['y_axis'] = '40';
All preferences listed in the table above are available for this
-function except these: rotation_angle, width, height, create_thumb,
-new_image.
+function except these: rotation_angle, create_thumb, new_image.
Here's an example showing how you might crop an image::
@@ -243,11 +242,11 @@ Here's an example showing how you might crop an image::
echo $this->image_lib->display_errors();
}
-Note: Without a visual interface it is difficult to crop images, so this
-function is not very useful unless you intend to build such an
-interface. That's exactly what we did using for the photo gallery module
-in ExpressionEngine, the CMS we develop. We added a JavaScript UI that
-lets the cropping area be selected.
+.. note:: Without a visual interface it is difficult to crop images, so this
+ function is not very useful unless you intend to build such an
+ interface. That's exactly what we did using for the photo gallery module
+ in ExpressionEngine, the CMS we develop. We added a JavaScript UI that
+ lets the cropping area be selected.
$this->image_lib->rotate()
===========================
@@ -338,8 +337,8 @@ The above example will use a 16 pixel True Type font to create the text
bottom/center of the image, 20 pixels from the bottom of the image.
.. note:: In order for the image class to be allowed to do any
- processing, the image file must have "write" file permissions. For
- example, 777.
+ processing, the image file must have "write" file permissions
+ For example, 777.
Watermarking Preferences
========================
diff --git a/user_guide_src/source/libraries/loader.rst b/user_guide_src/source/libraries/loader.rst
index 33c1bafec..615aba1c2 100644
--- a/user_guide_src/source/libraries/loader.rst
+++ b/user_guide_src/source/libraries/loader.rst
@@ -344,6 +344,6 @@ calling add_package_path().
$this->load->remove_package_path(APPPATH.'my_app');
// Again without the second parameter:
- $this->load->add_package_path(APPPATH.'my_app', TRUE);
+ $this->load->add_package_path(APPPATH.'my_app');
$this->load->view('my_app_index'); // Loads
$this->load->view('welcome_message'); // Loads
diff --git a/user_guide_src/source/libraries/migration.rst b/user_guide_src/source/libraries/migration.rst
index 5192f1f29..cb7d96a6d 100644
--- a/user_guide_src/source/libraries/migration.rst
+++ b/user_guide_src/source/libraries/migration.rst
@@ -2,4 +2,136 @@
Migrations Class
################
-Coming soon. \ No newline at end of file
+Migrations are a convenient way for you to alter your database in a
+structured and organized manner. You could edit fragments of SQL by hand
+but you would then be responsible for telling other developers that they
+need to go and run them. You would also have to keep track of which changes
+need to be run against the production machines next time you deploy.
+
+The database table **migration** tracks which migrations have already been
+run so all you have to do is update your application files and
+call **$this->migrate->current()** to work out which migrations should be run.
+The current version is found in **config/migration.php**.
+
+******************
+Create a Migration
+******************
+
+.. note:: Each Migration is run in numerical order forward or backwards
+ depending on the method taken. Use a prefix of 3 numbers followed by an
+ underscore for the filename of your migration.
+
+This will be the first migration for a new site which has a blog. All
+migrations go in the folder **application/migrations/** and have names such
+as: **001_add_blog.php**.::
+
+ defined('BASEPATH') OR exit('No direct script access allowed');
+
+ class Migration_Add_blog extends CI_Migration {
+
+ public function up()
+ {
+ $this->dbforge->add_field(array(
+ 'blog_id' => array(
+ 'type' => 'INT',
+ 'constraint' => 5,
+ 'unsigned' => TRUE,
+ 'auto_increment' => TRUE
+ ),
+ 'blog_title' => array(
+ 'type' => 'VARCHAR',
+ 'constraint' => '100',
+ ),
+ 'blog_description' => array(
+ 'type' => 'TEXT',
+ 'null' => TRUE,
+ ),
+ ));
+
+ $this->dbforge->create_table('blog');
+ }
+
+ public function down()
+ {
+ $this->dbforge->drop_table('blog');
+ }
+
+Then in **application/config/migration.php** set **$config['migration_version'] = 1;**.
+
+*************
+Usage Example
+*************
+
+In this example some simple code is placed in **application/controllers/migrate.php**
+to update the schema.::
+
+ $this->load->library('migration');
+
+ if ( ! $this->migration->current())
+ {
+ show_error($this->migration->error_string());
+ }
+
+******************
+Function Reference
+******************
+
+There are five available methods for the Migration class:
+
+- $this->migration->current();
+- $this->migration->error_string();
+- $this->migration->find_migrations();
+- $this->migration->latest();
+- $this->migration->version();
+
+$this->migration->current()
+============================
+
+The current migration is whatever is set for **$config['migration_version']** in
+**application/config/migration.php**.
+
+$this->migration->error_string()
+=================================
+
+This returns a string of errors while performing a migration.
+
+$this->migration->find_migrations()
+====================================
+
+An array of migration filenames are returned that are found in the **migration_path**
+property.
+
+$this->migration->latest()
+===========================
+
+This works much the same way as current() but instead of looking for
+the **$config['migration_version']** the Migration class will use the very
+newest migration found in the filesystem.
+
+$this->migration->version()
+============================
+
+Version can be used to roll back changes or step forwards programmatically to
+specific versions. It works just like current but ignores **$config['migration_version']**.::
+
+ $this->load->library('migration');
+
+ $this->migration->version(5);
+
+*********************
+Migration Preferences
+*********************
+
+The following is a table of all the config options for migrations.
+
+========================== ====================== ============= =============================================
+Preference Default Options Description
+========================== ====================== ============= =============================================
+**migration_enabled** FALSE TRUE / FALSE Enable or disable migrations.
+**migration_path** APPPATH.'migrations/' None The path to your migrations folder.
+**migration_version** 0 None The current version your database should use.
+**migration_table** migrations None The table name for storing the shema
+ version number.
+**migration_auto_latest** FALSE TRUE / FALSE Enable or disable automatically
+ running migrations.
+========================== ====================== ============= =============================================
diff --git a/user_guide_src/source/libraries/output.rst b/user_guide_src/source/libraries/output.rst
index 0472d14cf..3289a241f 100644
--- a/user_guide_src/source/libraries/output.rst
+++ b/user_guide_src/source/libraries/output.rst
@@ -105,6 +105,9 @@ Permits you to manually set a server status header. Example::
`See here <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html>`_ for
a full list of headers.
+.. note:: This method is an alias for :doc:`Common function <../general/common_funtions.rst>`
+ ``set_status_header()``.
+
$this->output->enable_profiler();
==================================
diff --git a/user_guide_src/source/libraries/pagination.rst b/user_guide_src/source/libraries/pagination.rst
index 7d750bd23..d9d3f5092 100644
--- a/user_guide_src/source/libraries/pagination.rst
+++ b/user_guide_src/source/libraries/pagination.rst
@@ -80,8 +80,8 @@ The number of "digit" links you would like before and after the selected
page number. For example, the number 2 will place two digits on either
side, as in the example links at the very top of this page.
-$config['use_page_number'] = TRUE;
-==================================
+$config['use_page_numbers'] = TRUE;
+===================================
By default, the URI segment will use the starting index for the items
you are paginating. If you prefer to show the the actual page number,
diff --git a/user_guide_src/source/libraries/trackback.rst b/user_guide_src/source/libraries/trackback.rst
index 07b2b2177..f9e0df882 100644
--- a/user_guide_src/source/libraries/trackback.rst
+++ b/user_guide_src/source/libraries/trackback.rst
@@ -114,7 +114,7 @@ store them. Here is a basic prototype for such a table::
excerpt text NOT NULL,
blog_name varchar(100) NOT NULL,
tb_date int(10) NOT NULL,
- ip_address varchar(16) NOT NULL,
+ ip_address varchar(45) NOT NULL,
PRIMARY KEY `tb_id` (`tb_id`),
KEY `entry_id` (`entry_id`)
);
diff --git a/user_guide_src/source/overview/cheatsheets.rst b/user_guide_src/source/overview/cheatsheets.rst
index 2e277aa9a..80c3112c4 100644
--- a/user_guide_src/source/overview/cheatsheets.rst
+++ b/user_guide_src/source/overview/cheatsheets.rst
@@ -5,12 +5,19 @@ CodeIgniter Cheatsheets
Library Reference
=================
-`|CodeIgniter Library
-Reference| <../images/codeigniter_1.7.1_library_reference.pdf>`_
+|CodeIgniter Library Reference|
+
+- :download:`Download PDF <../images/codeigniter_1.7.1_library_reference.pdf>`
+
Helpers Reference
=================
-`|image1| <../images/codeigniter_1.7.1_helper_reference.pdf>`_
+|CodeIgniter Helper Reference|
+
+- :download:`Download PDF <../images/codeigniter_1.7.1_helper_reference.pdf>`
+
.. |CodeIgniter Library Reference| image:: ../images/codeigniter_1.7.1_library_reference.png
-.. |image1| image:: ../images/codeigniter_1.7.1_helper_reference.png
+ :target: ../_downloads/codeigniter_1.7.1_library_reference.pdf
+.. |CodeIgniter Helper Reference| image:: ../images/codeigniter_1.7.1_helper_reference.png
+ :target: ../_downloads/codeigniter_1.7.1_helper_reference.pdf