diff options
299 files changed, 12697 insertions, 7198 deletions
diff --git a/.travis.yml b/.travis.yml index ab0aa5616..1d3562980 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,9 @@ language: php php: - 5.3 - 5.4 + - 5.5 + - 5.6 + - hhvm env: - DB=mysql @@ -21,6 +24,15 @@ before_script: script: phpunit --coverage-text --configuration tests/travis/$DB.phpunit.xml +matrix: + allow_failures: + - php: hhvm + exclude: + - php: hhvm + env: DB=mysqli + env: DB=pgsql + env: DB=pdo/pgsql + branches: only: - develop diff --git a/application/config/autoload.php b/application/config/autoload.php index 5a20c943a..f3ae942a2 100644 --- a/application/config/autoload.php +++ b/application/config/autoload.php @@ -1,4 +1,4 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php /** * CodeIgniter * @@ -18,12 +18,13 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) * @link http://codeigniter.com * @since Version 1.0 * @filesource */ +defined('BASEPATH') OR exit('No direct script access allowed'); /* | ------------------------------------------------------------------- @@ -77,6 +78,11 @@ $autoload['packages'] = array(); | Prototype: | | $autoload['libraries'] = array('database', 'email', 'xmlrpc'); +| +| You can also supply an alternative library name to be assigned +| in the controller: +| +| $autoload['libraries'] = array('user_agent' => 'ua'); */ $autoload['libraries'] = array(); diff --git a/application/config/config.php b/application/config/config.php index 0608348c6..ae89715c0 100644 --- a/application/config/config.php +++ b/application/config/config.php @@ -1,4 +1,4 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php /** * CodeIgniter * @@ -18,12 +18,13 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) * @link http://codeigniter.com * @since Version 1.0 * @filesource */ +defined('BASEPATH') OR exit('No direct script access allowed'); /* |-------------------------------------------------------------------------- @@ -141,15 +142,18 @@ $config['subclass_prefix'] = 'MY_'; | Allowed URL Characters |-------------------------------------------------------------------------- | -| This lets you specify with a regular expression which characters are permitted -| within your URLs. When someone tries to submit a URL with disallowed -| characters they will get a warning message. +| This lets you specify which characters are permitted within your URLs. +| When someone tries to submit a URL with disallowed characters they will +| get a warning message. | | As a security measure you are STRONGLY encouraged to restrict URLs to | as few characters as possible. By default only these are allowed: a-z 0-9~%.:_- | | Leave blank to allow all characters -- but only if you are insane. | +| The configured value is actually a regular expression character group +| and it will be executed as: ! preg_match('/^[<permitted_uri_chars>]+$/i +| | DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!! | */ @@ -282,7 +286,7 @@ $config['encryption_key'] = ''; | 'sess_driver' = the driver to load: cookie (Classic), native (PHP sessions), | or your custom driver name | 'sess_valid_drivers' = additional valid drivers which may be loaded -| 'sess_cookie_name' = the name you want for the cookie +| 'sess_cookie_name' = the name you want for the cookie, must contain only [0-9a-z_-] characters | 'sess_expiration' = the number of SECONDS you want the session to last. | by default sessions last 7200 seconds (two hours). Set to zero for no expiration. | 'sess_expire_on_close' = Whether to cause the session to expire automatically @@ -327,6 +331,20 @@ $config['cookie_httponly'] = FALSE; /* |-------------------------------------------------------------------------- +| Standardize newlines +|-------------------------------------------------------------------------- +| +| Determines whether to standardize newline characters in input data, +| meaning to replace \r\n, \r, \n occurences with the PHP_EOL value. +| +| This is particularly useful for portability between UNIX-based OSes, +| (usually \n) and Windows (\r\n). +| +*/ +$config['standardize_newlines'] = TRUE; + +/* +|-------------------------------------------------------------------------- | Global XSS Filtering |-------------------------------------------------------------------------- | @@ -367,6 +385,9 @@ $config['csrf_exclude_uris'] = array(); | Even if it does, however, not all browsers support compression | so enable only if you are reasonably sure your visitors can handle it. | +| Only used if zlib.output_compression is turned off in your php.ini. +| Please do not use it together with httpd-level output compression. +| | VERY IMPORTANT: If you are getting a blank page when compression is enabled it | means you are prematurely outputting something to your browser. It could | even be a line of whitespace at the end of one of your scripts. For diff --git a/application/config/constants.php b/application/config/constants.php index dc84712cd..239fd46fb 100644 --- a/application/config/constants.php +++ b/application/config/constants.php @@ -1,4 +1,4 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php /** * CodeIgniter * @@ -18,12 +18,13 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) * @link http://codeigniter.com * @since Version 1.0 * @filesource */ +defined('BASEPATH') OR exit('No direct script access allowed'); /* |-------------------------------------------------------------------------- @@ -81,11 +82,11 @@ define('SHOW_DEBUG_BACKTRACE', TRUE); | Used to indicate the conditions under which the script is exit()ing. | While there is no universal standard for error codes, there are some | broad conventions. Three such conventions are mentioned below, for -| those who wish to make use of them. The CodeIgniter defaults were +| those who wish to make use of them. The CodeIgniter defaults were | chosen for the least overlap with these conventions, while still | leaving room for others to be defined in future versions and user | applications. -| +| | The three main conventions used for determining exit status codes | are as follows: | @@ -108,7 +109,6 @@ define('EXIT_USER_INPUT', 7); // invalid user input define('EXIT_DATABASE', 8); // database error define('EXIT__AUTO_MIN', 9); // lowest automatically-assigned error code define('EXIT__AUTO_MAX', 125); // highest automatically-assigned error code - /* End of file constants.php */ /* Location: ./application/config/constants.php */
\ No newline at end of file diff --git a/application/config/database.php b/application/config/database.php index f0b839757..c8297796b 100644 --- a/application/config/database.php +++ b/application/config/database.php @@ -1,4 +1,4 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php /** * CodeIgniter * @@ -18,12 +18,14 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) * @link http://codeigniter.com * @since Version 1.0 * @filesource */ +defined('BASEPATH') OR exit('No direct script access allowed'); + /* | ------------------------------------------------------------------- | DATABASE CONNECTIVITY SETTINGS @@ -68,6 +70,13 @@ | ['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. +| ['save_queries'] TRUE/FALSE - Whether to "save" all executed queries. +| NOTE: Disabling this will also effectively disable both +| $this->db->last_query() and profiling of DB queries. +| When you run a query, with this setting set to TRUE (default), +| CodeIgniter will store the SQL statement for debugging purposes. +| However, this may cause high memory usage, especially if you run +| a lot of SQL queries ... disable this to avoid that problem. | | The $active_group variable lets you choose which connection group to | make active. By default there is only one group (the 'default' group). @@ -98,7 +107,8 @@ $db['default'] = array( 'encrypt' => FALSE, 'compress' => FALSE, 'stricton' => FALSE, - 'failover' => array() + 'failover' => array(), + 'save_queries' => TRUE ); /* End of file database.php */ diff --git a/application/config/doctypes.php b/application/config/doctypes.php index b1a8959c2..4468456b3 100644 --- a/application/config/doctypes.php +++ b/application/config/doctypes.php @@ -1,4 +1,4 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php /** * CodeIgniter * @@ -18,12 +18,13 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) * @link http://codeigniter.com * @since Version 1.0 * @filesource */ +defined('BASEPATH') OR exit('No direct script access allowed'); $_doctypes = array( 'xhtml11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">', diff --git a/application/config/foreign_chars.php b/application/config/foreign_chars.php index ab98224f7..e151364ad 100644 --- a/application/config/foreign_chars.php +++ b/application/config/foreign_chars.php @@ -1,4 +1,4 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php /** * CodeIgniter * @@ -18,12 +18,13 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) * @link http://codeigniter.com * @since Version 1.0 * @filesource */ +defined('BASEPATH') OR exit('No direct script access allowed'); /* | ------------------------------------------------------------------- diff --git a/application/config/hooks.php b/application/config/hooks.php index c7532f538..2693c34f7 100644 --- a/application/config/hooks.php +++ b/application/config/hooks.php @@ -1,4 +1,4 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php /** * CodeIgniter * @@ -18,12 +18,13 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) * @link http://codeigniter.com * @since Version 1.0 * @filesource */ +defined('BASEPATH') OR exit('No direct script access allowed'); /* | ------------------------------------------------------------------------- diff --git a/application/config/memcached.php b/application/config/memcached.php index 714e81f6b..373536d44 100644 --- a/application/config/memcached.php +++ b/application/config/memcached.php @@ -1,4 +1,4 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php /** * CodeIgniter * @@ -18,12 +18,13 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) * @link http://codeigniter.com * @since Version 2.0 * @filesource */ +defined('BASEPATH') OR exit('No direct script access allowed'); /* | ------------------------------------------------------------------------- diff --git a/application/config/migration.php b/application/config/migration.php index b348fb317..3b84787d3 100644 --- a/application/config/migration.php +++ b/application/config/migration.php @@ -1,4 +1,4 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php /** * CodeIgniter * @@ -18,12 +18,13 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) * @link http://codeigniter.com * @since Version 1.0 * @filesource */ +defined('BASEPATH') OR exit('No direct script access allowed'); /* |-------------------------------------------------------------------------- @@ -105,7 +106,7 @@ $config['migration_version'] = 0; | Also, writing permission is required within the migrations path. | */ -$config['migration_path'] = APPPATH . 'migrations/'; +$config['migration_path'] = APPPATH.'migrations/'; /* End of file migration.php */ /* Location: ./application/config/migration.php */
\ No newline at end of file diff --git a/application/config/mimes.php b/application/config/mimes.php index 32d10f6c1..8123557f4 100644 --- a/application/config/mimes.php +++ b/application/config/mimes.php @@ -1,4 +1,4 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php /** * CodeIgniter * @@ -18,12 +18,13 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) * @link http://codeigniter.com * @since Version 1.0 * @filesource */ +defined('BASEPATH') OR exit('No direct script access allowed'); /* | ------------------------------------------------------------------- @@ -78,6 +79,7 @@ return array( 'sit' => 'application/x-stuffit', 'tar' => 'application/x-tar', 'tgz' => array('application/x-tar', 'application/x-gzip-compressed'), + 'z' => 'application/x-compress', 'xhtml' => 'application/xhtml+xml', 'xht' => 'application/xhtml+xml', 'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed', 'application/s-compressed', 'multipart/x-zip'), @@ -96,7 +98,7 @@ return array( 'ra' => 'audio/x-realaudio', 'rv' => 'video/vnd.rn-realvideo', 'wav' => array('audio/x-wav', 'audio/wave', 'audio/wav'), - 'bmp' => array('image/bmp', 'image/x-windows-bmp'), + 'bmp' => array('image/bmp', 'image/x-bmp', 'image/x-bitmap', 'image/x-xbitmap', 'image/x-win-bitmap', 'image/x-windows-bmp', 'image/ms-bmp', 'image/x-ms-bmp', 'application/bmp', 'application/x-bmp', 'application/x-win-bitmap'), 'gif' => 'image/gif', 'jpeg' => array('image/jpeg', 'image/pjpeg'), 'jpg' => array('image/jpeg', 'image/pjpeg'), diff --git a/application/config/profiler.php b/application/config/profiler.php index fb9d8eed4..f99e109db 100644 --- a/application/config/profiler.php +++ b/application/config/profiler.php @@ -1,4 +1,4 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php /** * CodeIgniter * @@ -18,12 +18,13 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) * @link http://codeigniter.com * @since Version 1.0 * @filesource */ +defined('BASEPATH') OR exit('No direct script access allowed'); /* | ------------------------------------------------------------------------- diff --git a/application/config/routes.php b/application/config/routes.php index 3078c3c76..572f87e35 100644 --- a/application/config/routes.php +++ b/application/config/routes.php @@ -1,4 +1,4 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php /** * CodeIgniter * @@ -18,12 +18,13 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) * @link http://codeigniter.com * @since Version 1.0 * @filesource */ +defined('BASEPATH') OR exit('No direct script access allowed'); /* | ------------------------------------------------------------------------- diff --git a/application/config/smileys.php b/application/config/smileys.php index 3c49c469e..0537fe339 100644 --- a/application/config/smileys.php +++ b/application/config/smileys.php @@ -1,4 +1,4 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php /** * CodeIgniter * @@ -18,12 +18,13 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) * @link http://codeigniter.com * @since Version 1.0 * @filesource */ +defined('BASEPATH') OR exit('No direct script access allowed'); /* | ------------------------------------------------------------------- @@ -83,7 +84,7 @@ $smileys = array( ':coolcheese:' => array('shade_cheese.gif', '19', '19', 'cool cheese'), ':vampire:' => array('vampire.gif', '19', '19', 'vampire'), ':snake:' => array('snake.gif', '19', '19', 'snake'), - ':exclaim:' => array('exclaim.gif', '19', '19', 'excaim'), + ':exclaim:' => array('exclaim.gif', '19', '19', 'exclaim'), ':question:' => array('question.gif', '19', '19', 'question') ); diff --git a/application/config/user_agents.php b/application/config/user_agents.php index 5887a15be..69b91fff5 100644 --- a/application/config/user_agents.php +++ b/application/config/user_agents.php @@ -1,4 +1,4 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php /** * CodeIgniter * @@ -18,12 +18,13 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) * @link http://codeigniter.com * @since Version 1.0 * @filesource */ +defined('BASEPATH') OR exit('No direct script access allowed'); /* | ------------------------------------------------------------------- @@ -36,6 +37,7 @@ */ $platforms = array( + 'windows nt 6.3' => 'Windows 8.1', 'windows nt 6.2' => 'Windows 8', 'windows nt 6.1' => 'Windows 7', 'windows nt 6.0' => 'Windows Vista', @@ -81,11 +83,15 @@ $platforms = array( // The order of this array should NOT be changed. Many browsers return // multiple browser types so we want to identify the sub-type first. $browsers = array( + 'OPR' => 'Opera', 'Flock' => 'Flock', 'Chrome' => 'Chrome', + // Opera 10+ always reports Opera/9.80 and appends Version/<real version> to the user agent string + 'Opera.*?Version' => 'Opera', 'Opera' => 'Opera', 'MSIE' => 'Internet Explorer', 'Internet Explorer' => 'Internet Explorer', + 'Trident.* rv' => 'Internet Explorer', 'Shiira' => 'Shiira', 'Firefox' => 'Firefox', 'Chimera' => 'Chimera', @@ -103,7 +109,8 @@ $browsers = array( 'hotjava' => 'HotJava', 'amaya' => 'Amaya', 'IBrowse' => 'IBrowse', - 'Maxthon' => 'Maxthon' + 'Maxthon' => 'Maxthon', + 'Ubuntu' => 'Ubuntu Web Browser' ); $mobiles = array( diff --git a/application/controllers/Welcome.php b/application/controllers/Welcome.php index 31ceea948..a0e7879e6 100644 --- a/application/controllers/Welcome.php +++ b/application/controllers/Welcome.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/application/language/index.html b/application/language/index.html new file mode 100644 index 000000000..c942a79ce --- /dev/null +++ b/application/language/index.html @@ -0,0 +1,10 @@ +<html> +<head> + <title>403 Forbidden</title> +</head> +<body> + +<p>Directory access is forbidden.</p> + +</body> +</html>
\ No newline at end of file diff --git a/application/views/errors/cli/error_404.php b/application/views/errors/cli/error_404.php new file mode 100644 index 000000000..d9f4aa64d --- /dev/null +++ b/application/views/errors/cli/error_404.php @@ -0,0 +1,33 @@ +<?php +/** + * CodeIgniter + * + * An open source application development framework for PHP 5.2.4 or newer + * + * NOTICE OF LICENSE + * + * Licensed under the Academic Free License version 3.0 + * + * This source file is subject to the Academic Free License (AFL 3.0) that is + * bundled with this package in the files license_afl.txt / license_afl.rst. + * It is also available through the world wide web at this URL: + * http://opensource.org/licenses/AFL-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 EllisLab Dev Team + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) + * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) + * @link http://codeigniter.com + * @since Version 3.0 + * @filesource + */ +defined('BASEPATH') OR exit('No direct script access allowed'); + +echo "\nERROR: ", + $heading, + "\n\n", + $message, + "\n\n";
\ No newline at end of file diff --git a/application/views/errors/cli/error_db.php b/application/views/errors/cli/error_db.php new file mode 100644 index 000000000..e6d6afd73 --- /dev/null +++ b/application/views/errors/cli/error_db.php @@ -0,0 +1,33 @@ +<?php +/** + * CodeIgniter + * + * An open source application development framework for PHP 5.2.4 or newer + * + * NOTICE OF LICENSE + * + * Licensed under the Academic Free License version 3.0 + * + * This source file is subject to the Academic Free License (AFL 3.0) that is + * bundled with this package in the files license_afl.txt / license_afl.rst. + * It is also available through the world wide web at this URL: + * http://opensource.org/licenses/AFL-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 EllisLab Dev Team + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) + * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) + * @link http://codeigniter.com + * @since Version 3.0 + * @filesource + */ +defined('BASEPATH') OR exit('No direct script access allowed'); + +echo "\nDatabase error: ", + $heading, + "\n\n", + $message, + "\n\n";
\ No newline at end of file diff --git a/application/views/errors/cli/error_general.php b/application/views/errors/cli/error_general.php new file mode 100644 index 000000000..b8a3c6b30 --- /dev/null +++ b/application/views/errors/cli/error_general.php @@ -0,0 +1,33 @@ +<?php +/** + * CodeIgniter + * + * An open source application development framework for PHP 5.2.4 or newer + * + * NOTICE OF LICENSE + * + * Licensed under the Academic Free License version 3.0 + * + * This source file is subject to the Academic Free License (AFL 3.0) that is + * bundled with this package in the files license_afl.txt / license_afl.rst. + * It is also available through the world wide web at this URL: + * http://opensource.org/licenses/AFL-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 EllisLab Dev Team + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) + * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) + * @link http://codeigniter.com + * @since Version 1.0 + * @filesource + */ +defined('BASEPATH') OR exit('No direct script access allowed'); + +echo "\nERROR: ", + $heading, + "\n\n", + $message, + "\n\n";
\ No newline at end of file diff --git a/application/views/errors/cli/error_php.php b/application/views/errors/cli/error_php.php new file mode 100644 index 000000000..faaddb1cc --- /dev/null +++ b/application/views/errors/cli/error_php.php @@ -0,0 +1,50 @@ +<?php +/** + * CodeIgniter + * + * An open source application development framework for PHP 5.2.4 or newer + * + * NOTICE OF LICENSE + * + * Licensed under the Academic Free License version 3.0 + * + * This source file is subject to the Academic Free License (AFL 3.0) that is + * bundled with this package in the files license_afl.txt / license_afl.rst. + * It is also available through the world wide web at this URL: + * http://opensource.org/licenses/AFL-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 EllisLab Dev Team + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) + * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) + * @link http://codeigniter.com + * @since Version 3.0 + * @filesource + */ +defined('BASEPATH') OR exit('No direct script access allowed'); +?> + +A PHP Error was encountered + +Severity: <?php echo $severity;?> +Message: <?php echo $message;?> +Filename: <?php echo $filepath;?> +Line Number: <?php echo $line;?> + +<?php if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === TRUE): ?> + +Backtrace: + <?php foreach (debug_backtrace() as $error): ?> + <?php if (isset($error['file']) && strpos($error['file'], realpath(BASEPATH)) !== 0): ?> + + File: <?php echo $error['file'];?> + Line: <?php echo $error['line'];?> + Function: <?php echo $error['function'];?> + + <?php endif ?> + + <?php endforeach ?> +<?php endif ?>
\ No newline at end of file diff --git a/application/views/errors/cli/index.html b/application/views/errors/cli/index.html new file mode 100644 index 000000000..c942a79ce --- /dev/null +++ b/application/views/errors/cli/index.html @@ -0,0 +1,10 @@ +<html> +<head> + <title>403 Forbidden</title> +</head> +<body> + +<p>Directory access is forbidden.</p> + +</body> +</html>
\ No newline at end of file diff --git a/application/views/errors/error_404.php b/application/views/errors/html/error_404.php index 21ff6db37..76ad84742 100644 --- a/application/views/errors/error_404.php +++ b/application/views/errors/html/error_404.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -74,8 +74,6 @@ 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/html/error_db.php index a251e1ca9..edf73a6cc 100644 --- a/application/views/errors/error_db.php +++ b/application/views/errors/html/error_db.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -74,8 +74,6 @@ 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/html/error_general.php index b9d54384f..250ef6223 100644 --- a/application/views/errors/error_general.php +++ b/application/views/errors/html/error_general.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -74,8 +74,6 @@ 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_php.php b/application/views/errors/html/error_php.php index c4e6b2934..8f7860bd6 100644 --- a/application/views/errors/error_php.php +++ b/application/views/errors/html/error_php.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -38,11 +38,10 @@ defined('BASEPATH') OR exit('No direct script access allowed'); <?php if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === TRUE): ?> - <p>Backtrace: </p> - <?php foreach(debug_backtrace() as $error): ?> + <p>Backtrace:</p> + <?php foreach (debug_backtrace() as $error): ?> - <?php if(isset($error['file']) && - strpos($error['file'], realpath(BASEPATH)) !== 0): ?> + <?php if (isset($error['file']) && strpos($error['file'], realpath(BASEPATH)) !== 0): ?> <p style="margin-left:10px"> File: <?php echo $error['file'] ?><br /> diff --git a/application/views/errors/html/index.html b/application/views/errors/html/index.html new file mode 100644 index 000000000..c942a79ce --- /dev/null +++ b/application/views/errors/html/index.html @@ -0,0 +1,10 @@ +<html> +<head> + <title>403 Forbidden</title> +</head> +<body> + +<p>Directory access is forbidden.</p> + +</body> +</html>
\ No newline at end of file diff --git a/application/views/welcome_message.php b/application/views/welcome_message.php index 2466a83fc..b149650c8 100644 --- a/application/views/welcome_message.php +++ b/application/views/welcome_message.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -87,8 +87,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); #container { margin: 10px; border: 1px solid #D0D0D0; - -moz-box-shadow: 0 0 8px #D0D0D0; - -webkit-box-shadow: 0 0 8px #D0D0D0; + box-shadow: 0 0 8px #D0D0D0; } </style> </head> @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -220,28 +220,28 @@ switch (ENVIRONMENT) $application_folder = $_temp; } - define('APPPATH', $application_folder.'/'); + define('APPPATH', $application_folder.DIRECTORY_SEPARATOR); } else { - if ( ! is_dir(BASEPATH.$application_folder.'/')) + if ( ! is_dir(BASEPATH.$application_folder.DIRECTORY_SEPARATOR)) { header('HTTP/1.1 503 Service Unavailable.', TRUE, 503); echo 'Your application folder path does not appear to be set correctly. Please open the following file and correct this: '.SELF; exit(3); // EXIT_* constants not yet defined; 3 is EXIT_CONFIG. } - define('APPPATH', BASEPATH.$application_folder.'/'); + define('APPPATH', BASEPATH.$application_folder.DIRECTORY_SEPARATOR); } // The path to the "views" folder if ( ! is_dir($view_folder)) { - if ( ! empty($view_folder) && is_dir(APPPATH.$view_folder.'/')) + if ( ! empty($view_folder) && is_dir(APPPATH.$view_folder.DIRECTORY_SEPARATOR)) { $view_folder = APPPATH.$view_folder; } - elseif ( ! is_dir(APPPATH.'views/')) + elseif ( ! is_dir(APPPATH.'views'.DIRECTORY_SEPARATOR)) { header('HTTP/1.1 503 Service Unavailable.', TRUE, 503); echo 'Your view folder path does not appear to be set correctly. Please open the following file and correct this: '.SELF; @@ -255,11 +255,11 @@ switch (ENVIRONMENT) if (($_temp = realpath($view_folder)) !== FALSE) { - $view_folder = $_temp.'/'; + $view_folder = $_temp.DIRECTORY_SEPARATOR; } else { - $view_folder = rtrim($view_folder, '/').'/'; + $view_folder = rtrim($view_folder, '/\\').DIRECTORY_SEPARATOR; } define('VIEWPATH', $view_folder); diff --git a/readme.rst b/readme.rst index d76816237..aa07d6e12 100644 --- a/readme.rst +++ b/readme.rst @@ -14,7 +14,7 @@ for a given task. Release Information ******************* -This repo contains in development code for future releases. To download the +This repo contains in-development code for future releases. To download the latest stable release please visit the `CodeIgniter Downloads <http://codeigniter.com/downloads/>`_ page. @@ -35,7 +35,7 @@ Server Requirements Installation ************ -Please see the `installation section <http://codeigniter.com/user_guide/installation/index.html>`_ +Please see the `installation section <http://ellislab.com/codeigniter/user-guide/installation/index.html>`_ of the CodeIgniter User Guide. ******* @@ -43,15 +43,15 @@ License ******* Please see the `license -agreement <http://codeigniter.com/user_guide/license.html>`_ +agreement <http://ellislab.com/codeigniter/user-guide/license.html>`_ ********* Resources ********* -- `User Guide <http://codeigniter.com/user_guide/>`_ -- `Community Forums <http://codeigniter.com/forums/>`_ -- `Community Wiki <http://codeigniter.com/wiki/>`_ +- `User Guide <http://ellislab.com/codeigniter/user_guide/>`_ +- `Community Forums <http://ellislab.com/forums/>`_ +- `Community Wiki <https://github.com/EllisLab/CodeIgniter/wiki/>`_ - `Community IRC <http://ellislab.com/codeigniter/irc>`_ *************** diff --git a/system/core/Benchmark.php b/system/core/Benchmark.php index f9be18a42..36326f521 100644 --- a/system/core/Benchmark.php +++ b/system/core/Benchmark.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php index c962fda20..270988a1b 100644 --- a/system/core/CodeIgniter.php +++ b/system/core/CodeIgniter.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -48,24 +48,22 @@ defined('BASEPATH') OR exit('No direct script access allowed'); /* * ------------------------------------------------------ - * Load the global functions + * Load the framework constants * ------------------------------------------------------ */ - require_once(BASEPATH.'core/Common.php'); + if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/constants.php')) + { + require_once(APPPATH.'config/'.ENVIRONMENT.'/constants.php'); + } + + require_once(APPPATH.'config/constants.php'); /* * ------------------------------------------------------ - * Load the framework constants + * Load the global functions * ------------------------------------------------------ */ - if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/constants.php')) - { - require(APPPATH.'config/'.ENVIRONMENT.'/constants.php'); - } - else - { - require(APPPATH.'config/constants.php'); - } + require_once(BASEPATH.'core/Common.php'); /* * ------------------------------------------------------ @@ -73,11 +71,10 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * ------------------------------------------------------ */ set_error_handler('_exception_handler'); + register_shutdown_function('_shutdown_handler'); - if ( ! is_php('5.4')) - { - @ini_set('magic_quotes_runtime', 0); // Kill magic quotes - } + // Kill magic quotes + is_php('5.4') OR @ini_set('magic_quotes_runtime', 0); /* * ------------------------------------------------------ @@ -127,6 +124,11 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * ------------------------------------------------------ * Instantiate the config class * ------------------------------------------------------ + * + * Note: It is important that Config is loaded first as + * most other classes depend on it either directly or by + * depending on another class that uses it. + * */ $CFG =& load_class('Config', 'core'); @@ -141,15 +143,59 @@ defined('BASEPATH') OR exit('No direct script access allowed'); /* * ------------------------------------------------------ - * Instantiate the UTF-8 class + * Important charset-related stuff * ------------------------------------------------------ * - * Note: Order here is rather important as the UTF-8 - * class needs to be used very early on, but it cannot - * properly determine if UTF-8 can be supported until - * after the Config class is instantiated. + * Configure mbstring and/or iconv if they are enabled + * and set MB_ENABLED and ICONV_ENABLED constants, so + * that we don't repeatedly do extension_loaded() or + * function_exists() calls. + * + * Note: UTF-8 class depends on this. It used to be done + * in it's constructor, but it's _not_ class-specific. * */ + $charset = strtoupper(config_item('charset')); + + if (extension_loaded('mbstring')) + { + define('MB_ENABLED', TRUE); + mb_internal_encoding($charset); + // This is required for mb_convert_encoding() to strip invalid characters. + // That's utilized by CI_Utf8, but it's also done for consistency with iconv. + mb_substitute_character('none'); + } + else + { + define('MB_ENABLED', FALSE); + } + + // There's an ICONV_IMPL constant, but the PHP manual says that using + // iconv's predefined constants is "strongly discouraged". + if (extension_loaded('iconv')) + { + define('ICONV_ENABLED', TRUE); + iconv_set_encoding('internal_encoding', $charset); + } + else + { + define('ICONV_ENABLED', FALSE); + } + +/* + * ------------------------------------------------------ + * Load compatibility features + * ------------------------------------------------------ + */ + + require_once(BASEPATH.'core/compat/mbstring.php'; + require_once(BASEPATH.'core/compat/password.php'; + +/* + * ------------------------------------------------------ + * Instantiate the UTF-8 class + * ------------------------------------------------------ + */ $UNI =& load_class('Utf8', 'core'); /* @@ -166,12 +212,6 @@ defined('BASEPATH') OR exit('No direct script access allowed'); */ $RTR =& load_class('Router', 'core'); - // Set any routing overrides that may exist in the main index file - if (isset($routing)) - { - $RTR->_set_overrides($routing); - } - /* * ------------------------------------------------------ * Instantiate the output class @@ -218,7 +258,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * */ // Load the base controller class - require BASEPATH.'core/Controller.php'; + require_once BASEPATH.'core/Controller.php'; /** * Reference to the CI_Controller method. @@ -234,96 +274,117 @@ defined('BASEPATH') OR exit('No direct script access allowed'); if (file_exists(APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php')) { - require APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php'; - } - - // Load the local application controller - // Note: The Router class automatically validates the controller path using the router->_validate_request(). - // If this include fails it means that the default controller in the Routes.php file is not resolving to something valid. - $class = ucfirst($RTR->class); - if ( ! file_exists(APPPATH.'controllers/'.$RTR->directory.$class.'.php')) - { - show_error('Unable to load your default controller. Please make sure the controller specified in your Routes.php file is valid.'); + require_once APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php'; } - include(APPPATH.'controllers/'.$RTR->directory.$class.'.php'); - // Set a mark point for benchmarking $BM->mark('loading_time:_base_classes_end'); /* * ------------------------------------------------------ - * Security check + * Sanity checks * ------------------------------------------------------ * - * None of the methods in the app controller or the - * loader class can be called via the URI, nor can + * The Router class has already validated the request, + * leaving us with 3 options here: + * + * 1) an empty class name, if we reached the default + * controller, but it didn't exist; + * 2) a query string which doesn't go through a + * file_exists() check + * 3) a regular request for a non-existing page + * + * We handle all of these as a 404 error. + * + * Furthermore, none of the methods in the app controller + * or the loader class can be called via the URI, nor can * controller methods that begin with an underscore. */ - $method = $RTR->method; - - if ( ! class_exists($class, FALSE) OR $method[0] === '_' OR method_exists('CI_Controller', $method)) - { - if ( ! empty($RTR->routes['404_override'])) - { - if (sscanf($RTR->routes['404_override'], '%[^/]/%s', $class, $method) !== 2) - { - $method = 'index'; - } - - $class = ucfirst($class); - if ( ! class_exists($class, FALSE)) - { - if ( ! file_exists(APPPATH.'controllers/'.$class.'.php')) - { - show_404($class.'/'.$method); - } - - include_once(APPPATH.'controllers/'.$class.'.php'); - } - } - else - { - show_404($class.'/'.$method); - } - } + $e404 = FALSE; + $class = ucfirst($RTR->class); + $method = $RTR->method; - if (method_exists($class, '_remap')) + if (empty($class) OR ! file_exists(APPPATH.'controllers/'.$RTR->directory.$class.'.php')) { - $params = array($method, array_slice($URI->rsegments, 2)); - $method = '_remap'; + $e404 = TRUE; } else { + require_once(APPPATH.'controllers/'.$RTR->directory.$class.'.php'); + + if ( ! class_exists($class, FALSE) OR $method[0] === '_' OR method_exists('CI_Controller', $method)) + { + $e404 = TRUE; + } + elseif (method_exists($class, '_remap')) + { + $params = array($method, array_slice($URI->rsegments, 2)); + $method = '_remap'; + } // WARNING: It appears that there are issues with is_callable() even in PHP 5.2! // Furthermore, there are bug reports and feature/change requests related to it // that make it unreliable to use in this context. Please, DO NOT change this // work-around until a better alternative is available. - if ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($class)), TRUE)) + elseif ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($class)), TRUE)) { - if (empty($RTR->routes['404_override'])) - { - show_404($class.'/'.$method); - } - elseif (sscanf($RTR->routes['404_override'], '%[^/]/%s', $class, $method) !== 2) + $e404 = TRUE; + } + } + + if ($e404) + { + if ( ! empty($RTR->routes['404_override'])) + { + if (sscanf($RTR->routes['404_override'], '%[^/]/%s', $error_class, $error_method) !== 2) { - $method = 'index'; + $error_method = 'index'; } - $class = ucfirst($class); + $error_class = ucfirst($error_class); - if ( ! class_exists($class, FALSE)) + if ( ! class_exists($error_class, FALSE)) { - if ( ! file_exists(APPPATH.'controllers/'.$class.'.php')) + if (file_exists(APPPATH.'controllers/'.$RTR->directory.$error_class.'.php')) { - show_404($class.'/'.$method); + require_once(APPPATH.'controllers/'.$RTR->directory.$error_class.'.php'); + $e404 = ! class_exists($error_class, FALSE); } - - include_once(APPPATH.'controllers/'.$class.'.php'); + // Were we in a directory? If so, check for a global override + elseif ( ! empty($RTR->directory) && file_exists(APPPATH.'controllers/'.$error_class.'.php')) + { + require_once(APPPATH.'controllers/'.$error_class.'.php'); + if (($e404 = ! class_exists($error_class, FALSE)) === FALSE) + { + $RTR->directory = ''; + } + } + } + else + { + $e404 = FALSE; } } + // Did we reset the $e404 flag? If so, set the rsegments, starting from index 1 + if ( ! $e404) + { + $class = $error_class; + $method = $error_method; + + $URI->rsegments = array( + 1 => $class, + 2 => $method + ); + } + else + { + show_404($RTR->directory.$class.'/'.$method); + } + } + + if ($method !== '_remap') + { $params = array_slice($URI->rsegments, 2); } diff --git a/system/core/Common.php b/system/core/Common.php index 7f296b133..16a916a01 100644 --- a/system/core/Common.php +++ b/system/core/Common.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -76,13 +76,14 @@ if ( ! function_exists('is_really_writable')) * the file, based on the read-only attribute. is_writable() is also unreliable * on Unix servers if safe_mode is on. * + * @link https://bugs.php.net/bug.php?id=54709 * @param string * @return void */ function is_really_writable($file) { // If we're on a Unix server with safe_mode off we call is_writable - if (DIRECTORY_SEPARATOR === '/' && (bool) @ini_get('safe_mode') === FALSE) + if (DIRECTORY_SEPARATOR === '/' && (is_php('5.4') OR (bool) @ini_get('safe_mode') === FALSE)) { return is_writable($file); } @@ -355,6 +356,24 @@ if ( ! function_exists('is_https')) // ------------------------------------------------------------------------ +if ( ! function_exists('is_cli')) +{ + + /** + * Is CLI? + * + * Test to see if a request was made from the command line. + * + * @return bool + */ + function is_cli() + { + return (PHP_SAPI === 'cli' OR defined('STDIN')); + } +} + +// ------------------------------------------------------------------------ + if ( ! function_exists('show_error')) { /** @@ -429,10 +448,9 @@ if ( ! function_exists('log_message')) * * @param string the error level: 'error', 'debug' or 'info' * @param string the error message - * @param bool whether the error is a native PHP error * @return void */ - function log_message($level, $message, $php_error = FALSE) + function log_message($level, $message) { static $_log; @@ -442,7 +460,7 @@ if ( ! function_exists('log_message')) $_log[0] =& load_class('Log', 'core'); } - $_log[0]->write_log($level, $message, $php_error); + $_log[0]->write_log($level, $message); } } @@ -550,14 +568,27 @@ if ( ! function_exists('_exception_handler')) * to display errors based on the current error_reporting level. * We do that with the use of a PHP error template. * - * @param int - * @param string - * @param string - * @param int + * @param int $severity + * @param string $message + * @param string $filepath + * @param int $line * @return void */ function _exception_handler($severity, $message, $filepath, $line) { + $is_error = (((E_ERROR | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity); + + // When an error occurred, set the status header to '500 Internal Server Error' + // to indicate to the client something went wrong. + // This can't be done within the $_error->show_php_error method because + // it is only called when the display_errors flag is set (which isn't usually + // the case in a production environment) or when errors are ignored because + // they are above the error_reporting threshold. + if ($is_error) + { + set_status_header(500); + } + $_error =& load_class('Exceptions', 'core'); // Should we ignore the error? We'll get the current error_reporting @@ -567,13 +598,49 @@ if ( ! function_exists('_exception_handler')) return; } + $_error->log_exception($severity, $message, $filepath, $line); + // Should we display the error? if ((bool) ini_get('display_errors') === TRUE) { $_error->show_php_error($severity, $message, $filepath, $line); } - $_error->log_exception($severity, $message, $filepath, $line); + // If the error is fatal, the execution of the script should be stopped because + // errors can't be recovered from. Halting the script conforms with PHP's + // default error handling. See http://www.php.net/manual/en/errorfunc.constants.php + if ($is_error) + { + exit(EXIT_ERROR); + } + } +} + +// ------------------------------------------------------------------------ + +if ( ! function_exists('_shutdown_handler')) +{ + /** + * Shutdown Handler + * + * This is the shutdown handler that is declared at the top + * of CodeIgniter.php. The main reason we use this is to simulate + * a complete custom exception handler. + * + * E_STRICT is purposivly neglected because such events may have + * been caught. Duplication or none? None is preferred for now. + * + * @link http://insomanic.me.uk/post/229851073/php-trick-catching-fatal-errors-e-error-with-a + * @return void + */ + function _shutdown_handler() + { + $last_error = error_get_last(); + if (isset($last_error) && + ($last_error['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING))) + { + _exception_handler($last_error['type'], $last_error['message'], $last_error['file'], $last_error['line']); + } } } @@ -689,6 +756,11 @@ if ( ! function_exists('function_usable')) * *suhosin.executor.disable_eval*. These settings will just * terminate script execution if a disabled function is executed. * + * The above described behavior turned out to be a bug in Suhosin, + * but even though a fix was commited for 0.9.34 on 2012-02-12, + * that version is yet to be released. This function will therefore + * be just temporary, but would probably be kept for a few years. + * * @link http://www.hardened-php.net/suhosin/ * @param string $function_name Function to check for * @return bool TRUE if the function exists and is safe to call, diff --git a/system/core/Config.php b/system/core/Config.php index 109ee6424..f630d1709 100644 --- a/system/core/Config.php +++ b/system/core/Config.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -228,13 +228,21 @@ class CI_Config { * @uses CI_Config::_uri_string() * * @param string|string[] $uri URI string or an array of segments + * @param string $protocol * @return string */ - public function site_url($uri = '') + public function site_url($uri = '', $protocol = NULL) { + $base_url = $this->slash_item('base_url'); + + if (isset($protocol)) + { + $base_url = $protocol.substr($base_url, strpos($base_url, '://')); + } + if (empty($uri)) { - return $this->slash_item('base_url').$this->item('index_page'); + return $base_url.$this->item('index_page'); } $uri = $this->_uri_string($uri); @@ -255,14 +263,14 @@ class CI_Config { } } - return $this->slash_item('base_url').$this->slash_item('index_page').$uri; + return $base_url.$this->slash_item('index_page').$uri; } elseif (strpos($uri, '?') === FALSE) { $uri = '?'.$uri; } - return $this->slash_item('base_url').$this->item('index_page').$uri; + return $base_url.$this->item('index_page').$uri; } // ------------------------------------------------------------- @@ -275,11 +283,19 @@ class CI_Config { * @uses CI_Config::_uri_string() * * @param string|string[] $uri URI string or an array of segments + * @param string $protocol * @return string */ - public function base_url($uri = '') + public function base_url($uri = '', $protocol = NULL) { - return $this->slash_item('base_url').ltrim($this->_uri_string($uri), '/'); + $base_url = $this->slash_item('base_url'); + + if (isset($protocol)) + { + $base_url = $protocol.substr($base_url, strpos($base_url, '://')); + } + + return $base_url.ltrim($this->_uri_string($uri), '/'); } // ------------------------------------------------------------- @@ -316,6 +332,7 @@ class CI_Config { /** * System URL * + * @deprecated 3.0.0 Encourages insecure practices * @return string */ public function system_url() diff --git a/system/core/Controller.php b/system/core/Controller.php index 3fcadcadf..8db222a98 100644 --- a/system/core/Controller.php +++ b/system/core/Controller.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php index 9c68d06a5..54a5bc48b 100644 --- a/system/core/Exceptions.php +++ b/system/core/Exceptions.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -91,7 +91,7 @@ class CI_Exceptions { public function log_exception($severity, $message, $filepath, $line) { $severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity; - log_message('error', 'Severity: '.$severity.' --> '.$message. ' '.$filepath.' '.$line, TRUE); + log_message('error', 'Severity: '.$severity.' --> '.$message.' '.$filepath.' '.$line); } // -------------------------------------------------------------------- @@ -107,13 +107,21 @@ class CI_Exceptions { */ public function show_404($page = '', $log_error = TRUE) { - $heading = '404 Page Not Found'; - $message = 'The page you requested was not found.'; + if (is_cli()) + { + $heading = 'Not Found'; + $message = 'The controller/method pair you requested was not found.'; + } + else + { + $heading = '404 Page Not Found'; + $message = 'The page you requested was not found.'; + } // By default we log this, but allow a dev to skip it if ($log_error) { - log_message('error', '404 Page Not Found --> '.$page); + log_message('error', $heading.': '.$page); } echo $this->show_error($heading, $message, 'error_404', 404); @@ -137,16 +145,24 @@ class CI_Exceptions { */ public function show_error($heading, $message, $template = 'error_general', $status_code = 500) { - set_status_header($status_code); - - $message = '<p>'.implode('</p><p>', is_array($message) ? $message : array($message)).'</p>'; + if (is_cli()) + { + $message = "\t".(is_array($message) ? implode("\n\t", $message) : $message); + $template = 'cli'.DIRECTORY_SEPARATOR.$template; + } + else + { + set_status_header($status_code); + $message = '<p>'.(is_array($message) ? implode('</p><p>', $message) : $message).'</p>'; + $template = 'html'.DIRECTORY_SEPARATOR.$template; + } if (ob_get_level() > $this->ob_level + 1) { ob_end_flush(); } ob_start(); - include(VIEWPATH.'errors/'.$template.'.php'); + include(VIEWPATH.'errors'.DIRECTORY_SEPARATOR.$template.'.php'); $buffer = ob_get_contents(); ob_end_clean(); return $buffer; @@ -166,13 +182,22 @@ class CI_Exceptions { public function show_php_error($severity, $message, $filepath, $line) { $severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity; - $filepath = str_replace('\\', '/', $filepath); - // For safety reasons we do not show the full file path - if (FALSE !== strpos($filepath, '/')) + // For safety reasons we don't show the full file path in non-CLI requests + if ( ! is_cli()) + { + $filepath = str_replace('\\', '/', $filepath); + if (FALSE !== strpos($filepath, '/')) + { + $x = explode('/', $filepath); + $filepath = $x[count($x)-2].'/'.end($x); + } + + $template = 'html'.DIRECTORY_SEPARATOR.'error_php'; + } + else { - $x = explode('/', $filepath); - $filepath = $x[count($x)-2].'/'.end($x); + $template = 'cli'.DIRECTORY_SEPARATOR.'error_php'; } if (ob_get_level() > $this->ob_level + 1) @@ -180,7 +205,7 @@ class CI_Exceptions { ob_end_flush(); } ob_start(); - include(VIEWPATH.'errors/error_php.php'); + include(VIEWPATH.'errors'.DIRECTORY_SEPARATOR.$template.'.php'); $buffer = ob_get_contents(); ob_end_clean(); echo $buffer; diff --git a/system/core/Hooks.php b/system/core/Hooks.php index b3b111991..f6eff4b3f 100644 --- a/system/core/Hooks.php +++ b/system/core/Hooks.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -54,6 +54,13 @@ class CI_Hooks { public $hooks = array(); /** + * Array with class objects to use hooks methods + * + * @var array + */ + protected $_objects = array(); + + /** * In progress flag * * Determines whether hook is in progress, used to prevent infinte loops @@ -184,7 +191,7 @@ class CI_Hooks { $function = empty($data['function']) ? FALSE : $data['function']; $params = isset($data['params']) ? $data['params'] : ''; - if ($class === FALSE && $function === FALSE) + if (empty($function)) { return FALSE; } @@ -195,19 +202,39 @@ class CI_Hooks { // Call the requested class and/or function if ($class !== FALSE) { - if ( ! class_exists($class, FALSE)) + // The object is stored? + if (isset($this->_objects[$class])) { - require($filepath); + if (method_exists($this->_objects[$class], $function)) + { + $this->_objects[$class]->$function($params); + } + else + { + return $this->_in_progress = FALSE; + } } + else + { + class_exists($class, FALSE) OR require_once($filepath); + + if ( ! class_exists($class, FALSE) OR ! method_exists($class, $function)) + { + return $this->_in_progress = FALSE; + } - $HOOK = new $class(); - $HOOK->$function($params); + // Store the object and execute the method + $this->_objects[$class] = new $class(); + $this->_objects[$class]->$function($params); + } } else { + function_exists($function) OR require_once($filepath); + if ( ! function_exists($function)) { - require($filepath); + return $this->_in_progress = FALSE; } $function($params); diff --git a/system/core/Input.php b/system/core/Input.php index 24e21ea08..fdb308b5a 100644 --- a/system/core/Input.php +++ b/system/core/Input.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -63,7 +63,7 @@ class CI_Input { protected $_allow_get_array = TRUE; /** - * Standartize new lines flag + * Standardize new lines flag * * If set to TRUE, then newlines are standardized. * @@ -121,9 +121,10 @@ class CI_Input { { log_message('debug', 'Input Class Initialized'); - $this->_allow_get_array = (config_item('allow_get_array') === TRUE); - $this->_enable_xss = (config_item('global_xss_filtering') === TRUE); - $this->_enable_csrf = (config_item('csrf_protection') === TRUE); + $this->_allow_get_array = (config_item('allow_get_array') === TRUE); + $this->_enable_xss = (config_item('global_xss_filtering') === TRUE); + $this->_enable_csrf = (config_item('csrf_protection') === TRUE); + $this->_sandardize_newlines = (bool) config_item('standardize_newlines'); global $SEC; $this->security =& $SEC; @@ -151,8 +152,22 @@ class CI_Input { * @param bool $xss_clean Whether to apply XSS filtering * @return mixed */ - protected function _fetch_from_array(&$array, $index = '', $xss_clean = FALSE) + protected function _fetch_from_array(&$array, $index = NULL, $xss_clean = NULL) { + // If $index is NULL, it means that the whole $array is requested + if ($index === NULL) + { + $output = array(); + foreach (array_keys($array) as $key) + { + $output[$key] = $this->_fetch_from_array($array, $key, $xss_clean); + } + + return $output; + } + + is_bool($xss_clean) OR $xss_clean = $this->_enable_xss; + if (isset($array[$index])) { $value = $array[$index]; @@ -197,26 +212,8 @@ class CI_Input { * @param bool $xss_clean Whether to apply XSS filtering * @return mixed */ - public function get($index = NULL, $xss_clean = FALSE) + public function get($index = NULL, $xss_clean = NULL) { - // Check if a field has been provided - if ($index === NULL) - { - if (empty($_GET)) - { - return array(); - } - - $get = array(); - - // loop through the full _GET array - foreach (array_keys($_GET) as $key) - { - $get[$key] = $this->_fetch_from_array($_GET, $key, $xss_clean); - } - return $get; - } - return $this->_fetch_from_array($_GET, $index, $xss_clean); } @@ -229,26 +226,8 @@ class CI_Input { * @param bool $xss_clean Whether to apply XSS filtering * @return mixed */ - public function post($index = NULL, $xss_clean = FALSE) + public function post($index = NULL, $xss_clean = NULL) { - // Check if a field has been provided - if ($index === NULL) - { - if (empty($_POST)) - { - return array(); - } - - $post = array(); - - // Loop through the full _POST array and return it - foreach (array_keys($_POST) as $key) - { - $post[$key] = $this->_fetch_from_array($_POST, $key, $xss_clean); - } - return $post; - } - return $this->_fetch_from_array($_POST, $index, $xss_clean); } @@ -261,7 +240,7 @@ class CI_Input { * @param bool $xss_clean Whether to apply XSS filtering * @return mixed */ - public function post_get($index = '', $xss_clean = FALSE) + public function post_get($index, $xss_clean = NULL) { return isset($_POST[$index]) ? $this->post($index, $xss_clean) @@ -277,7 +256,7 @@ class CI_Input { * @param bool $xss_clean Whether to apply XSS filtering * @return mixed */ - public function get_post($index = '', $xss_clean = FALSE) + public function get_post($index, $xss_clean = NULL) { return isset($_GET[$index]) ? $this->get($index, $xss_clean) @@ -293,7 +272,7 @@ class CI_Input { * @param bool $xss_clean Whether to apply XSS filtering * @return mixed */ - public function cookie($index = '', $xss_clean = FALSE) + public function cookie($index = NULL, $xss_clean = NULL) { return $this->_fetch_from_array($_COOKIE, $index, $xss_clean); } @@ -307,7 +286,7 @@ class CI_Input { * @param bool $xss_clean Whether to apply XSS filtering * @return mixed */ - public function server($index = '', $xss_clean = FALSE) + public function server($index, $xss_clean = NULL) { return $this->_fetch_from_array($_SERVER, $index, $xss_clean); } @@ -323,21 +302,14 @@ class CI_Input { * @param bool $xss_clean Whether to apply XSS filtering * @return mixed */ - public function input_stream($index = '', $xss_clean = FALSE) + public function input_stream($index = NULL, $xss_clean = NULL) { // The input stream can only be read once, so we'll need to check // if we have already done that first. - if (is_array($this->_input_stream)) - { - return $this->_fetch_from_array($this->_input_stream, $index, $xss_clean); - } - - // Parse the input stream in our cache var - parse_str(file_get_contents('php://input'), $this->_input_stream); if ( ! is_array($this->_input_stream)) { - $this->_input_stream = array(); - return NULL; + parse_str(file_get_contents('php://input'), $this->_input_stream); + is_array($this->_input_stream) OR $this->_input_stream = array(); } return $this->_fetch_from_array($this->_input_stream, $index, $xss_clean); @@ -361,7 +333,7 @@ class CI_Input { * @param bool $httponly Whether to only makes the cookie accessible via HTTP (no javascript) * @return void */ - public function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE) + public function set_cookie($name, $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE) { if (is_array($name)) { @@ -687,13 +659,22 @@ class CI_Input { // but that when present will trip our 'Disallowed Key Characters' alarm // http://www.ietf.org/rfc/rfc2109.txt // note that the key names below are single quoted strings, and are not PHP variables - unset($_COOKIE['$Version']); - unset($_COOKIE['$Path']); - unset($_COOKIE['$Domain']); + unset( + $_COOKIE['$Version'], + $_COOKIE['$Path'], + $_COOKIE['$Domain'] + ); foreach ($_COOKIE as $key => $val) { - $_COOKIE[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); + if (($cookie_key = $this->_clean_input_keys($key)) !== FALSE) + { + $_COOKIE[$cookie_key] = $this->_clean_input_data($val); + } + else + { + unset($_COOKIE[$key]); + } } } @@ -701,12 +682,12 @@ class CI_Input { $_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']); // CSRF Protection check - if ($this->_enable_csrf === TRUE && ! $this->is_cli_request()) + if ($this->_enable_csrf === TRUE && ! is_cli()) { $this->security->csrf_verify(); } - log_message('debug', 'Global POST and COOKIE data sanitized'); + log_message('debug', 'Global POST, GET and COOKIE data sanitized'); } // -------------------------------------------------------------------- @@ -749,13 +730,7 @@ class CI_Input { } // Remove control characters - $str = remove_invisible_characters($str); - - // Should we filter the input data? - if ($this->_enable_xss === TRUE) - { - $str = $this->security->xss_clean($str); - } + $str = remove_invisible_characters($str, FALSE); // Standardize newlines if needed if ($this->_standardize_newlines === TRUE) @@ -776,15 +751,25 @@ class CI_Input { * only named with alpha-numeric text and a few other items. * * @param string $str Input string - * @return string + * @param string $fatal Whether to terminate script exection + * or to return FALSE if an invalid + * key is encountered + * @return string|bool */ - protected function _clean_input_keys($str) + protected function _clean_input_keys($str, $fatal = TRUE) { if ( ! preg_match('/^[a-z0-9:_\/|-]+$/i', $str)) { - set_status_header(503); - echo 'Disallowed Key Characters.'; - exit(EXIT_USER_INPUT); + if ($fatal === TRUE) + { + return FALSE; + } + else + { + set_status_header(503); + echo 'Disallowed Key Characters.'; + exit(EXIT_USER_INPUT); + } } // Clean UTF-8 if supported @@ -884,11 +869,12 @@ class CI_Input { * * Test to see if a request was made from the command line. * - * @return bool + * @deprecated 3.0.0 Use is_cli() instead + * @return bool */ public function is_cli_request() { - return (PHP_SAPI === 'cli' OR defined('STDIN')); + return is_cli(); } // -------------------------------------------------------------------- diff --git a/system/core/Lang.php b/system/core/Lang.php index 3236709f2..94342133a 100644 --- a/system/core/Lang.php +++ b/system/core/Lang.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -166,7 +166,7 @@ class CI_Lang { * @param bool $log_errors Whether to log an error message if the line is not found * @return string Translation */ - public function line($line = '', $log_errors = TRUE) + public function line($line, $log_errors = TRUE) { $value = ($line === '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line]; diff --git a/system/core/Loader.php b/system/core/Loader.php index 1709c2db1..2d40ab5b8 100644 --- a/system/core/Loader.php +++ b/system/core/Loader.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -174,22 +174,29 @@ class CI_Loader { * @param string $library Library name * @param array $params Optional parameters to pass to the library class constructor * @param string $object_name An optional object name to assign to - * @return void + * @return object */ - public function library($library = '', $params = NULL, $object_name = NULL) + public function library($library, $params = NULL, $object_name = NULL) { if (empty($library)) { - return; + return $this; } elseif (is_array($library)) { - foreach ($library as $class) + foreach ($library as $key => $value) { - $this->library($class, $params); + if (is_int($key)) + { + $this->library($value, $params); + } + else + { + $this->library($key, $params, $value); + } } - return; + return $this; } if ($params !== NULL && ! is_array($params)) @@ -198,6 +205,7 @@ class CI_Loader { } $this->_ci_load_class($library, $params, $object_name); + return $this; } // -------------------------------------------------------------------- @@ -210,21 +218,22 @@ class CI_Loader { * @param string $model Model name * @param string $name An optional object name to assign to * @param bool $db_conn An optional database connection configuration to initialize - * @return void + * @return object */ public function model($model, $name = '', $db_conn = FALSE) { if (empty($model)) { - return; + return $this; } elseif (is_array($model)) { foreach ($model as $key => $value) { - $this->model(is_int($key) ? $value : $key, $value); + is_int($key) ? $this->model($value, '', $db_conn) : $this->model($key, $value, $db_conn); } - return; + + return $this; } $path = ''; @@ -246,7 +255,7 @@ class CI_Loader { if (in_array($name, $this->_ci_models, TRUE)) { - return; + return $this; } $CI =& get_instance(); @@ -283,7 +292,7 @@ class CI_Loader { $CI->$name = new $model(); $this->_ci_models[] = $name; - return; + return $this; } // couldn't find the model @@ -300,8 +309,8 @@ class CI_Loader { * @param bool $query_builder Whether to enable Query Builder * (overrides the configuration setting) * - * @return void|object|bool Database object if $return is set to TRUE, - * FALSE on failure, void in any other case + * @return object|bool Database object if $return is set to TRUE, + * FALSE on failure, CI_Loader instance in any other case */ public function database($params = '', $return = FALSE, $query_builder = NULL) { @@ -327,6 +336,7 @@ class CI_Loader { // Load the DB class $CI->db =& DB($params, $query_builder); + return $this; } // -------------------------------------------------------------------- @@ -335,8 +345,8 @@ class CI_Loader { * Load the Database Utilities Class * * @param object $db Database object - * @param bool $return Whether to return the DB Forge class object or not - * @return void|object + * @param bool $return Whether to return the DB Utilities class object or not + * @return object */ public function dbutil($db = NULL, $return = FALSE) { @@ -358,6 +368,7 @@ class CI_Loader { } $CI->dbutil = new $class($db); + return $this; } // -------------------------------------------------------------------- @@ -367,7 +378,7 @@ class CI_Loader { * * @param object $db Database object * @param bool $return Whether to return the DB Forge class object or not - * @return void|object + * @return object */ public function dbforge($db = NULL, $return = FALSE) { @@ -401,6 +412,7 @@ class CI_Loader { } $CI->dbforge = new $class($db); + return $this; } // -------------------------------------------------------------------- @@ -415,7 +427,7 @@ class CI_Loader { * to be extracted for use in the view * @param bool $return Whether to return the view output * or leave it to the Output class - * @return void + * @return object|string */ public function view($view, $vars = array(), $return = FALSE) { @@ -429,7 +441,7 @@ class CI_Loader { * * @param string $path File path * @param bool $return Whether to return the file output - * @return void|string + * @return object|string */ public function file($path, $return = FALSE) { @@ -448,9 +460,9 @@ class CI_Loader { * An associative array or object containing values * to be set, or a value's name if string * @param string $val Value to set, only used if $vars is a string - * @return void + * @return object */ - public function vars($vars = array(), $val = '') + public function vars($vars, $val = '') { if (is_string($vars)) { @@ -466,6 +478,23 @@ class CI_Loader { $this->_ci_cached_vars[$key] = $val; } } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Clear Cached Variables + * + * Clears the cached variables. + * + * @return object + */ + public function clear_vars() + { + $this->_ci_cached_vars = array(); + return $this; } // -------------------------------------------------------------------- @@ -503,7 +532,7 @@ class CI_Loader { * Helper Loader * * @param string|string[] $helpers Helper name(s) - * @return void + * @return object */ public function helper($helpers = array()) { @@ -560,6 +589,8 @@ class CI_Loader { show_error('Unable to load the requested file: helpers/'.$helper.'.php'); } } + + return $this; } // -------------------------------------------------------------------- @@ -572,11 +603,11 @@ class CI_Loader { * * @uses CI_Loader::helper() * @param string|string[] $helpers Helper name(s) - * @return void + * @return object */ public function helpers($helpers = array()) { - $this->helper($helpers); + return $this->helper($helpers); } // -------------------------------------------------------------------- @@ -588,18 +619,19 @@ class CI_Loader { * * @param string|string[] $files List of language file names to load * @param string Language name - * @return void + * @return object */ - public function language($files = array(), $lang = '') + public function language($files, $lang = '') { $CI =& get_instance(); - is_array($files) OR $files = array($files); foreach ($files as $langfile) { $CI->lang->load($langfile, $lang); } + + return $this; } // -------------------------------------------------------------------- @@ -615,10 +647,9 @@ class CI_Loader { * @param bool $fail_gracefully Whether to just return FALSE or display an error message * @return bool TRUE if the file was loaded correctly or FALSE on failure */ - public function config($file = '', $use_sections = FALSE, $fail_gracefully = FALSE) + public function config($file, $use_sections = FALSE, $fail_gracefully = FALSE) { - $CI =& get_instance(); - return $CI->config->load($file, $use_sections, $fail_gracefully); + return get_instance()->config->load($file, $use_sections, $fail_gracefully); } // -------------------------------------------------------------------- @@ -632,10 +663,10 @@ class CI_Loader { * @param array $params Optional parameters to pass to the driver * @param string $object_name An optional object name to assign to * - * @return void|object|bool Object or FALSE on failure if $library is a string - * and $object_name is set. void otherwise. + * @return object|bool Object or FALSE on failure if $library is a string + * and $object_name is set. CI_Loader instance otherwise. */ - public function driver($library = '', $params = NULL, $object_name = NULL) + public function driver($library, $params = NULL, $object_name = NULL) { if (is_array($library)) { @@ -643,10 +674,10 @@ class CI_Loader { { $this->driver($driver); } - return; - } - if ($library === '') + return $this; + } + elseif (empty($library)) { return FALSE; } @@ -682,7 +713,7 @@ class CI_Loader { * * @param string $path Path to add * @param bool $view_cascade (default: TRUE) - * @return void + * @return object */ public function add_package_path($path, $view_cascade = TRUE) { @@ -697,6 +728,8 @@ class CI_Loader { // Add config file path $config =& $this->_ci_get_component('config'); $config->_config_paths[] = $path; + + return $this; } // -------------------------------------------------------------------- @@ -724,7 +757,7 @@ class CI_Loader { * added path will be removed removed. * * @param string $path Path to remove - * @return void + * @return object */ public function remove_package_path($path = '') { @@ -766,6 +799,8 @@ class CI_Loader { $this->_ci_model_paths = array_unique(array_merge($this->_ci_model_paths, array(APPPATH))); $this->_ci_view_paths = array_merge($this->_ci_view_paths, array(APPPATH.'views/' => TRUE)); $config->_config_paths = array_unique(array_merge($config->_config_paths, array(APPPATH))); + + return $this; } // -------------------------------------------------------------------- @@ -781,7 +816,7 @@ class CI_Loader { * @used-by CI_Loader::view() * @used-by CI_Loader::file() * @param array $_ci_data Data to load - * @return void + * @return object */ protected function _ci_load($_ci_data) { @@ -905,6 +940,8 @@ class CI_Loader { $_ci_CI->output->append_output(ob_get_contents()); @ob_end_clean(); } + + return $this; } // -------------------------------------------------------------------- diff --git a/system/core/Log.php b/system/core/Log.php index e4d72b544..707964ccc 100644 --- a/system/core/Log.php +++ b/system/core/Log.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -140,10 +140,9 @@ class CI_Log { * * @param string the error level: 'error', 'debug' or 'info' * @param string the error message - * @param bool whether the error is a native PHP error * @return bool */ - public function write_log($level, $msg, $php_error = FALSE) + public function write_log($level, $msg) { if ($this->_enabled === FALSE) { @@ -176,10 +175,18 @@ class CI_Log { return FALSE; } - $message .= $level.' '.($level === 'INFO' ? ' -' : '-').' '.date($this->_date_fmt).' --> '.$msg."\n"; + $message .= $level.' - '.date($this->_date_fmt).' --> '.$msg."\n"; flock($fp, LOCK_EX); - fwrite($fp, $message); + + for ($written = 0, $length = strlen($message); $written < $length; $written += $result) + { + if (($result = fwrite($fp, substr($message, $written))) === FALSE) + { + break; + } + } + flock($fp, LOCK_UN); fclose($fp); @@ -188,7 +195,7 @@ class CI_Log { @chmod($filepath, FILE_WRITE_MODE); } - return TRUE; + return is_int($result); } } diff --git a/system/core/Model.php b/system/core/Model.php index 1eb6f909b..9485ec2c9 100644 --- a/system/core/Model.php +++ b/system/core/Model.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -59,8 +59,7 @@ class CI_Model { */ public function __get($key) { - $CI =& get_instance(); - return $CI->$key; + return get_instance()->$key; } } diff --git a/system/core/Output.php b/system/core/Output.php index 06d7a866b..ef56a97bf 100644 --- a/system/core/Output.php +++ b/system/core/Output.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -58,21 +58,21 @@ class CI_Output { * * @var array */ - public $headers = array(); + public $headers = array(); /** * List of mime types * * @var array */ - public $mimes = array(); + public $mimes = array(); /** * Mime-type for the current page * * @var string */ - protected $mime_type = 'text/html'; + protected $mime_type = 'text/html'; /** * Enable Profiler flag @@ -82,11 +82,18 @@ class CI_Output { public $enable_profiler = FALSE; /** - * zLib output compression flag + * php.ini zlib.output_compression flag * * @var bool */ - protected $_zlib_oc = FALSE; + protected $_zlib_oc = FALSE; + + /** + * CI output compression flag + * + * @var bool + */ + protected $_compress_output = FALSE; /** * List of profiler sections @@ -102,7 +109,7 @@ class CI_Output { * * @var bool */ - public $parse_exec_vars = TRUE; + public $parse_exec_vars = TRUE; /** * Class constructor @@ -114,6 +121,11 @@ class CI_Output { public function __construct() { $this->_zlib_oc = (bool) @ini_get('zlib.output_compression'); + $this->_compress_output = ( + $this->_zlib_oc === FALSE + && config_item('compress_output') === TRUE + && extension_loaded('zlib') + ); // Get mime types for later $this->mimes =& get_mimes(); @@ -436,15 +448,14 @@ class CI_Output { if ($this->parse_exec_vars === TRUE) { $memory = round(memory_get_usage() / 1024 / 1024, 2).'MB'; - $output = str_replace(array('{elapsed_time}', '{memory_usage}'), array($elapsed, $memory), $output); } // -------------------------------------------------------------------- // Is compression requested? - if ($CFG->item('compress_output') === TRUE && $this->_zlib_oc === FALSE - && extension_loaded('zlib') + if (isset($CI) // This means that we're not serving a cache file, if we were, it would already be compressed + && $this->_compress_output === TRUE && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE) { ob_start('ob_gzhandler'); @@ -468,6 +479,21 @@ class CI_Output { // simply echo out the data and exit. if ( ! isset($CI)) { + if ($this->_compress_output === TRUE) + { + if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE) + { + header('Content-Encoding: gzip'); + header('Content-Length: '.strlen($output)); + } + else + { + // User agent doesn't support gzip compression, + // so we'll have to decompress our cache + $output = gzinflate(substr($output, 10, -8)); + } + } + echo $output; log_message('debug', 'Final output sent to browser'); log_message('debug', 'Total execution time: '.$elapsed); @@ -530,9 +556,9 @@ class CI_Output { return; } - $uri = $CI->config->item('base_url'). - $CI->config->item('index_page'). - $CI->uri->uri_string(); + $uri = $CI->config->item('base_url') + .$CI->config->item('index_page') + .$CI->uri->uri_string(); $cache_path .= md5($uri); @@ -542,17 +568,39 @@ class CI_Output { return; } - $expire = time() + ($this->cache_expiration * 60); - - // Put together our serialized info. - $cache_info = serialize(array( - 'expire' => $expire, - 'headers' => $this->headers - )); - if (flock($fp, LOCK_EX)) { - fwrite($fp, $cache_info.'ENDCI--->'.$output); + // If output compression is enabled, compress the cache + // itself, so that we don't have to do that each time + // we're serving it + if ($this->_compress_output === TRUE) + { + $output = gzencode($output); + + if ($this->get_header('content-type') === NULL) + { + $this->set_content_type($this->mime_type); + } + } + + $expire = time() + ($this->cache_expiration * 60); + + // Put together our serialized info. + $cache_info = serialize(array( + 'expire' => $expire, + 'headers' => $this->headers + )); + + $output = $cache_info.'ENDCI--->'.$output; + + for ($written = 0, $length = strlen($output); $written < $length; $written += $result) + { + if (($result = fwrite($fp, substr($output, $written))) === FALSE) + { + break; + } + } + flock($fp, LOCK_UN); } else @@ -560,13 +608,22 @@ class CI_Output { log_message('error', 'Unable to secure a file lock for file at: '.$cache_path); return; } + fclose($fp); - @chmod($cache_path, FILE_WRITE_MODE); - log_message('debug', 'Cache file written: '.$cache_path); + if (is_int($result)) + { + @chmod($cache_path, FILE_WRITE_MODE); + log_message('debug', 'Cache file written: '.$cache_path); - // Send HTTP cache-control headers to browser to match file cache settings. - $this->set_cache_header($_SERVER['REQUEST_TIME'], $expire); + // Send HTTP cache-control headers to browser to match file cache settings. + $this->set_cache_header($_SERVER['REQUEST_TIME'], $expire); + } + else + { + @unlink($cache_path); + log_message('error', 'Unable to write the complete cache content at: '.$cache_path); + } } // -------------------------------------------------------------------- @@ -701,7 +758,7 @@ class CI_Output { else { header('Pragma: public'); - header('Cache-Control: max-age=' . $max_age . ', public'); + header('Cache-Control: max-age='.$max_age.', public'); header('Expires: '.gmdate('D, d M Y H:i:s', $expiration).' GMT'); header('Last-modified: '.gmdate('D, d M Y H:i:s', $last_modified).' GMT'); } @@ -740,13 +797,13 @@ class CI_Output { preg_match_all('{<style.+</style>}msU', $output, $style_clean); foreach ($style_clean[0] as $s) { - $output = str_replace($s, $this->_minify_script_style($s, TRUE), $output); + $output = str_replace($s, $this->_minify_js_css($s, 'css', TRUE), $output); } // Minify the javascript in <script> tags. foreach ($javascript_clean[0] as $s) { - $javascript_mini[] = $this->_minify_script_style($s, TRUE); + $javascript_mini[] = $this->_minify_js_css($s, 'js', TRUE); } // Replace multiple spaces with a single space. @@ -792,13 +849,14 @@ class CI_Output { break; case 'text/css': + + return $this->_minify_js_css($output, 'css'); + case 'text/javascript': case 'application/javascript': case 'application/x-javascript': - $output = $this->_minify_script_style($output); - - break; + return $this->_minify_js_css($output, 'js'); default: break; } @@ -809,134 +867,100 @@ class CI_Output { // -------------------------------------------------------------------- /** - * Minify Style and Script - * - * Reduce excessive size of CSS/JavaScript content. To remove spaces this - * script walks the string as an array and determines if the pointer is inside - * a string created by single quotes or double quotes. spaces inside those - * strings are not stripped. Opening and closing tags are severed from - * the string initially and saved without stripping whitespace to preserve - * the tags and any associated properties if tags are present + * Minify JavaScript and CSS code * - * Minification logic/workflow is similar to methods used by Douglas Crockford - * in JSMIN. http://www.crockford.com/javascript/jsmin.html + * Strips comments and excessive whitespace characters * - * KNOWN ISSUE: ending a line with a closing parenthesis ')' and no semicolon - * where there should be one will break the Javascript. New lines after a - * closing parenthesis are not recognized by the script. For best results - * be sure to terminate lines with a semicolon when appropriate. - * - * @param string $output Output to minify - * @param bool $has_tags Specify if the output has style or script tags - * @return string Minified output + * @param string $output + * @param string $type 'js' or 'css' + * @param bool $tags Whether $output contains the 'script' or 'style' tag + * @return string */ - protected function _minify_script_style($output, $has_tags = FALSE) + protected function _minify_js_css($output, $type, $tags = FALSE) { - // We only need this if there are tags in the file - if ($has_tags === TRUE) + if ($tags === TRUE) { - // Remove opening tag and save for later - $pos = strpos($output, '>') + 1; - $open_tag = substr($output, 0, $pos); - $output = substr_replace($output, '', 0, $pos); + $tags = array('close' => strrchr($output, '<')); - // Remove closing tag and save it for later - $pos = strpos($output, '</'); - $closing_tag = substr($output, $pos, strlen($output)); - $output = substr_replace($output, '', $pos); - } + $open_length = strpos($output, '>') + 1; + $tags['open'] = substr($output, 0, $open_length); - // Remove CSS comments - $output = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!i', '', $output); + $output = substr($output, $open_length, -strlen($tags['close'])); - // Remove spaces around curly brackets, colons, - // semi-colons, parenthesis, commas - $chunks = preg_split('/([\'|"]).+(?![^\\\]\\1)\\1/iU', $output, -1, PREG_SPLIT_OFFSET_CAPTURE); - for ($i = count($chunks) - 1; $i >= 0; $i--) - { - $output = substr_replace( - $output, - preg_replace('/\s*(:|;|,|}|{|\(|\))\s*/i', '$1', $chunks[$i][0]), - $chunks[$i][1], - strlen($chunks[$i][0]) - ); + // Strip spaces from the tags + $tags = preg_replace('#\s{2,}#', ' ', $tags); } - // Replace tabs with spaces - // Replace carriage returns & multiple new lines with single new line - // and trim any leading or trailing whitespace - $output = trim(preg_replace(array('/\t+/', '/\r/', '/\n+/'), array(' ', "\n", "\n"), $output)); + $output = trim($output); - // Remove spaces when safe to do so. - $in_string = $in_dstring = $prev = FALSE; - $array_output = str_split($output); - foreach ($array_output as $key => $value) + if ($type === 'js') { - if ($in_string === FALSE && $in_dstring === FALSE) + // Catch all string literals and comment blocks + if (preg_match_all('#((?:((?<!\\\)\'|")|(/\*)|(//)).*(?(2)(?<!\\\)\2|(?(3)\*/|\n)))#msuUS', $output, $match, PREG_OFFSET_CAPTURE)) { - if ($value === ' ') + $js_literals = $js_code = array(); + for ($match = $match[0], $c = count($match), $i = $pos = $offset = 0; $i < $c; $i++) { - // Get the next element in the array for comparisons - $next = $array_output[$key + 1]; - - // Strip spaces preceded/followed by a non-ASCII character - // or not preceded/followed by an alphanumeric - // or not preceded/followed \ $ and _ - if ((preg_match('/^[\x20-\x7f]*$/D', $next) OR preg_match('/^[\x20-\x7f]*$/D', $prev)) - && ( ! ctype_alnum($next) OR ! ctype_alnum($prev)) - && ! in_array($next, array('\\', '_', '$'), TRUE) - && ! in_array($prev, array('\\', '_', '$'), TRUE) - ) + $js_code[$pos++] = trim(substr($output, $offset, $match[$i][1] - $offset)); + $offset = $match[$i][1] + strlen($match[$i][0]); + + // Save only if we haven't matched a comment block + if ($match[$i][0][0] !== '/') { - unset($array_output[$key]); + $js_literals[$pos++] = array_shift($match[$i]); } } - else - { - // Save this value as previous for the next iteration - // if it is not a blank space - $prev = $value; - } - } + $js_code[$pos] = substr($output, $offset); - if ($value === "'") - { - $in_string = ! $in_string; + // $match might be quite large, so free it up together with other vars that we no longer need + unset($match, $offset, $pos); } - elseif ($value === '"') + else { - $in_dstring = ! $in_dstring; + $js_code = array($output); + $js_literals = array(); } + + $varname = 'js_code'; + } + else + { + $varname = 'output'; } - // Put the string back together after spaces have been stripped - $output = implode($array_output); + // Standartize new lines + $$varname = str_replace(array("\r\n", "\r"), "\n", $$varname); - // Remove new line characters unless previous or next character is - // printable or Non-ASCII - preg_match_all('/[\n]/', $output, $lf, PREG_OFFSET_CAPTURE); - $removed_lf = 0; - foreach ($lf as $feed_position) + if ($type === 'js') { - foreach ($feed_position as $position) - { - $position = $position[1] - $removed_lf; - $next = $output[$position + 1]; - $prev = $output[$position - 1]; - if ( ! ctype_print($next) && ! ctype_print($prev) - && ! preg_match('/^[\x20-\x7f]*$/D', $next) - && ! preg_match('/^[\x20-\x7f]*$/D', $prev) - ) - { - $output = substr_replace($output, '', $position, 1); - $removed_lf++; - } - } + $patterns = array( + '#\s*([!\#%&()*+,\-./:;<=>?@\[\]^`{|}~])\s*#' => '$1', // Remove spaces following and preceeding JS-wise non-special & non-word characters + '#\s{2,}#' => ' ' // Reduce the remaining multiple whitespace characters to a single space + ); + } + else + { + $patterns = array( + '#/\*.*(?=\*/)\*/#s' => '', // Remove /* block comments */ + '#\n?//[^\n]*#' => '', // Remove // line comments + '#\s*([^\w.\#%])\s*#U' => '$1', // Remove spaces following and preceeding non-word characters, excluding dots, hashes and the percent sign + '#\s{2,}#' => ' ' // Reduce the remaining multiple space characters to a single space + ); + } + + $$varname = preg_replace(array_keys($patterns), array_values($patterns), $$varname); + + // Glue back JS quoted strings + if ($type === 'js') + { + $js_code += $js_literals; + ksort($js_code); + $output = implode($js_code); + unset($js_code, $js_literals, $varname, $patterns); } - // Put the opening and closing tags back if applicable - return isset($open_tag) - ? $open_tag.$output.$closing_tag + return is_array($tags) + ? $tags['open'].$output.$tags['close'] : $output; } diff --git a/system/core/Router.php b/system/core/Router.php index 0f7278ae6..05263b153 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -91,6 +91,15 @@ class CI_Router { */ public $translate_uri_dashes = FALSE; + /** + * Enable query strings flag + * + * Determines wether to use GET parameters or segment URIs + * + * @var bool + */ + public $enable_query_strings = FALSE; + // -------------------------------------------------------------------- /** @@ -102,9 +111,34 @@ class CI_Router { */ public function __construct() { + global $routing; + $this->config =& load_class('Config', 'core'); $this->uri =& load_class('URI', 'core'); + + $this->enable_query_strings = ( ! is_cli() && $this->config->item('enable_query_strings') === TRUE); $this->_set_routing(); + + // Set any routing overrides that may exist in the main index file + if (isset($routing) && is_array($routing)) + { + if (isset($routing['directory'])) + { + $this->set_directory($routing['directory']); + } + + if ( ! empty($routing['controller'])) + { + $this->set_class($routing['controller']); + } + + if (isset($routing['function'])) + { + $routing['function'] = empty($routing['function']) ? 'index' : $routing['function']; + $this->set_method($routing['function']); + } + } + log_message('debug', 'Router Class Initialized'); } @@ -123,26 +157,39 @@ class CI_Router { // Are query strings enabled in the config file? Normally CI doesn't utilize query strings // since URI segments are more search-engine friendly, but they can optionally be used. // If this feature is enabled, we will gather the directory/class/method a little differently - $segments = array(); - if ($this->config->item('enable_query_strings') === TRUE - && ! empty($_GET[$this->config->item('controller_trigger')]) - && is_string($_GET[$this->config->item('controller_trigger')]) - ) + if ($this->enable_query_strings) { - if (isset($_GET[$this->config->item('directory_trigger')]) && is_string($_GET[$this->config->item('directory_trigger')])) + $_d = $this->config->item('directory_trigger'); + $_d = isset($_GET[$_d]) ? trim($_GET[$_d], " \t\n\r\0\x0B/") : ''; + if ($_d !== '') { - $this->set_directory(trim($this->uri->_filter_uri($_GET[$this->config->item('directory_trigger')]))); - $segments[] = $this->directory; + $this->set_directory($this->uri->filter_uri($_d)); } - $this->set_class(trim($this->uri->_filter_uri($_GET[$this->config->item('controller_trigger')]))); - $segments[] = $this->class; + $_c = $this->config->item('controller_trigger'); + if ( ! empty($_GET[$_c])) + { + $this->set_class(trim($this->uri->filter_uri(trim($_GET[$_c])))); + + $_f = $this->config->item('function_trigger'); + if ( ! empty($_GET[$_f])) + { + $this->set_method(trim($this->uri->filter_uri($_GET[$_f]))); + } - if ( ! empty($_GET[$this->config->item('function_trigger')]) && is_string($_GET[$this->config->item('function_trigger')])) + $this->uri->rsegments = array( + 1 => $this->class, + 2 => $this->method + ); + } + else { - $this->set_method(trim($this->uri->_filter_uri($_GET[$this->config->item('function_trigger')]))); - $segments[] = $this->method; + $this->_set_default_controller(); } + + // Routing rules don't apply to query strings and we don't need to detect + // directories, so we're done here + return; } // Load the routes.php file. @@ -165,53 +212,15 @@ class CI_Router { $this->routes = $route; } - // Were there any query string segments? If so, we'll validate them and bail out since we're done. - if (count($segments) > 0) + // Is there anything to parse? + if ($this->uri->uri_string !== '') { - return $this->_validate_request($segments); + $this->_parse_routes(); } - - // Fetch the complete URI string - $this->uri->_fetch_uri_string(); - - // Is there a URI string? If not, the default controller specified in the "routes" file will be shown. - if ($this->uri->uri_string == '') + else { - return $this->_set_default_controller(); + $this->_set_default_controller(); } - - $this->uri->_remove_url_suffix(); // Remove the URL suffix - $this->uri->_explode_segments(); // Compile the segments into an array - $this->_parse_routes(); // Parse any custom routing that may exist - $this->uri->_reindex_segments(); // Re-index the segment array so that it starts with 1 rather than 0 - } - - // -------------------------------------------------------------------- - - /** - * Set default controller - * - * @return void - */ - protected function _set_default_controller() - { - if (empty($this->default_controller)) - { - show_error('Unable to determine what should be displayed. A default route has not been specified in the routing file.'); - } - - // Is the method being specified? - if (sscanf($this->default_controller, '%[^/]/%s', $class, $method) !== 2) - { - $method = 'index'; - } - - $this->_set_request(array($class, $method)); - - // re-index the routed segments array so it starts with 1 rather than 0 - $this->uri->_reindex_segments(); - - log_message('debug', 'No URI present. Default controller set.'); } // -------------------------------------------------------------------- @@ -222,16 +231,19 @@ class CI_Router { * Takes an array of URI segments as input and sets the class/method * to be called. * + * @used-by CI_Router::_parse_routes() * @param array $segments URI segments * @return void */ protected function _set_request($segments = array()) { $segments = $this->_validate_request($segments); - - if (count($segments) === 0) + // If we don't have any segments left - try the default controller; + // WARNING: Directories get shifted out of the segments array! + if (empty($segments)) { - return $this->_set_default_controller(); + $this->_set_default_controller(); + return; } if ($this->translate_uri_dashes === TRUE) @@ -244,90 +256,86 @@ class CI_Router { } $this->set_class($segments[0]); - isset($segments[1]) OR $segments[1] = 'index'; - $this->set_method($segments[1]); + if (isset($segments[1])) + { + $this->set_method($segments[1]); + } - // Update our "routed" segment array to contain the segments. - // Note: If there is no custom routing, this array will be - // identical to $this->uri->segments + array_unshift($segments, NULL); + unset($segments[0]); $this->uri->rsegments = $segments; } // -------------------------------------------------------------------- /** - * Validate request - * - * Attempts validate the URI request and determine the controller path. + * Set default controller * - * @param array $segments URI segments - * @return array URI segments + * @return void */ - protected function _validate_request($segments) + protected function _set_default_controller() { - if (count($segments) === 0) + if (empty($this->default_controller)) { - return $segments; + show_error('Unable to determine what should be displayed. A default route has not been specified in the routing file.'); } - $test = ucfirst($this->translate_uri_dashes === TRUE ? str_replace('-', '_', $segments[0]) : $segments[0]); - - // Does the requested controller exist in the root folder? - if (file_exists(APPPATH.'controllers/'.$test.'.php')) + // Is the method being specified? + if (sscanf($this->default_controller, '%[^/]/%s', $class, $method) !== 2) { - return $segments; + $method = 'index'; } - // Is the controller in a sub-folder? - if (is_dir(APPPATH.'controllers/'.$segments[0])) + if ( ! file_exists(APPPATH.'controllers/'.$this->directory.ucfirst($class).'.php')) { - // Set the directory and remove it from the segment array - $this->set_directory(array_shift($segments)); - if (count($segments) > 0) - { - $test = ucfirst($this->translate_uri_dashes === TRUE ? str_replace('-', '_', $segments[0]) : $segments[0]); + // This will trigger 404 later + return; + } - // Does the requested controller exist in the sub-directory? - if ( ! file_exists(APPPATH.'controllers/'.$this->directory.$test.'.php')) - { - if ( ! empty($this->routes['404_override'])) - { - $this->directory = ''; - return explode('/', $this->routes['404_override'], 2); - } - else - { - show_404($this->directory.$segments[0]); - } - } - } - else - { - // Is the method being specified in the route? - $segments = explode('/', $this->default_controller); - if ( ! file_exists(APPPATH.'controllers/'.$this->directory.ucfirst($segments[0]).'.php')) - { - $this->directory = ''; - } - } + $this->set_class($class); + $this->set_method($method); - return $segments; - } + // Assign routed segments, index starting from 1 + $this->uri->rsegments = array( + 1 => $class, + 2 => $method + ); - // If we've gotten this far it means that the URI does not correlate to a valid - // controller class. We will now see if there is an override - if ( ! empty($this->routes['404_override'])) + log_message('debug', 'No URI present. Default controller set.'); + } + + // -------------------------------------------------------------------- + + /** + * Validate request + * + * Attempts validate the URI request and determine the controller path. + * + * @used-by CI_Router::_set_request() + * @param array $segments URI segments + * @return mixed URI segments + */ + protected function _validate_request($segments) + { + $c = count($segments); + // Loop through our segments and return as soon as a controller + // is found or when such a directory doesn't exist + while ($c-- > 0) { - if (sscanf($this->routes['404_override'], '%[^/]/%s', $class, $method) !== 2) + $test = $this->directory + .ucfirst($this->translate_uri_dashes === TRUE ? str_replace('-', '_', $segments[0]) : $segments[0]); + + if ( ! file_exists(APPPATH.'controllers/'.$test.'.php') && is_dir(APPPATH.'controllers/'.$this->directory.$segments[0])) { - $method = 'index'; + $this->set_directory(array_shift($segments), TRUE); + continue; } - return array($class, $method); + return $segments; } - // Nothing else to do at this point but show a 404 - show_404($segments[0]); + // This means that all segments were actually directories + return $segments; } // -------------------------------------------------------------------- @@ -345,15 +353,42 @@ class CI_Router { // Turn the segment array into a URI string $uri = implode('/', $this->uri->segments); + // Get HTTP verb + $http_verb = isset($_SERVER['REQUEST_METHOD']) ? strtolower($_SERVER['REQUEST_METHOD']) : 'cli'; + // Is there a literal match? If so we're done - if (isset($this->routes[$uri]) && is_string($this->routes[$uri])) + if (isset($this->routes[$uri])) { - return $this->_set_request(explode('/', $this->routes[$uri])); + // Check default routes format + if (is_string($this->routes[$uri])) + { + $this->_set_request(explode('/', $this->routes[$uri])); + return; + } + // Is there a matching http verb? + elseif (is_array($this->routes[$uri]) && isset($this->routes[$uri][$http_verb])) + { + $this->_set_request(explode('/', $this->routes[$uri][$http_verb])); + return; + } } // Loop through the route array looking for wildcards foreach ($this->routes as $key => $val) { + // Check if route format is using http verb + if (is_array($val)) + { + if (isset($val[$http_verb])) + { + $val = $val[$http_verb]; + } + else + { + continue; + } + } + // Convert wildcards to RegEx $key = str_replace(array(':any', ':num'), array('[^/]+', '[0-9]+'), $key); @@ -404,13 +439,14 @@ class CI_Router { $val = preg_replace('#^'.$key.'$#', $val, $uri); } - return $this->_set_request(explode('/', $val)); + $this->_set_request(explode('/', $val)); + return; } } // If we got this far it means we didn't encounter a // matching route so we'll set the site default route - $this->_set_request($this->uri->segments); + $this->_set_request(array_values($this->uri->segments)); } // -------------------------------------------------------------------- @@ -471,11 +507,19 @@ class CI_Router { * Set directory name * * @param string $dir Directory name + * @param bool $appent Whether we're appending rather then setting the full value * @return void */ - public function set_directory($dir) + public function set_directory($dir, $append = FALSE) { - $this->directory = str_replace(array('/', '.'), '', $dir).'/'; + if ($append !== TRUE OR empty($this->directory)) + { + $this->directory = str_replace('.', '', trim($dir, '/')).'/'; + } + else + { + $this->directory .= str_replace('.', '', trim($dir, '/')).'/'; + } } // -------------------------------------------------------------------- @@ -494,38 +538,6 @@ class CI_Router { return $this->directory; } - // -------------------------------------------------------------------- - - /** - * Set controller overrides - * - * @param array $routing Route overrides - * @return void - */ - public function _set_overrides($routing) - { - if ( ! is_array($routing)) - { - return; - } - - if (isset($routing['directory'])) - { - $this->set_directory($routing['directory']); - } - - if ( ! empty($routing['controller'])) - { - $this->set_class($routing['controller']); - } - - if (isset($routing['function'])) - { - $routing['function'] = empty($routing['function']) ? 'index' : $routing['function']; - $this->set_method($routing['function']); - } - } - } /* End of file Router.php */ diff --git a/system/core/Security.php b/system/core/Security.php index 70cf3e013..faa52d746 100644 --- a/system/core/Security.php +++ b/system/core/Security.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -62,6 +62,19 @@ class CI_Security { ); /** + * HTML5 entities + * + * @var array + */ + public $html5_entities = array( + ':' => ':', + '(' => '(', + ')' => ')', + '&newline;' => "\n", + '&tab;' => "\t" + ); + + /** * XSS Hash * * Random Hash for protecting URLs. @@ -117,7 +130,6 @@ class CI_Security { 'document.write' => '[removed]', '.parentNode' => '[removed]', '.innerHTML' => '[removed]', - 'window.location' => '[removed]', '-moz-binding' => '[removed]', '<!--' => '<!--', '-->' => '-->', @@ -132,9 +144,13 @@ class CI_Security { */ protected $_never_allowed_regex = array( 'javascript\s*:', + '(document|(document\.)?window)\.(location|on\w*)', 'expression\s*(\(|&\#40;)', // CSS and IE 'vbscript\s*:', // IE, surprise! - 'Redirect\s+302', + 'wscript\s*:', // IE + 'jscript\s*:', // IE + 'vbs\s*:', // IE + 'Redirect\s+30\d', "([\"'])?data\s*:[^\\1]*?base64[^\\1]*?,[^\\1]*?\\1?" ); @@ -343,7 +359,11 @@ class CI_Security { * * Note: Use rawurldecode() so it does not remove plus signs */ - $str = rawurldecode($str); + do + { + $str = rawurldecode($str); + } + while (preg_match('/%[0-9a-f]{2,}/i', $str)); /* * Convert character entities to ASCII @@ -402,8 +422,9 @@ class CI_Security { * These words are compacted back to their correct state. */ $words = array( - 'javascript', 'expression', 'vbscript', 'script', 'base64', - 'applet', 'alert', 'document', 'write', 'cookie', 'window' + 'javascript', 'expression', 'vbscript', 'jscript', 'wscript', + 'vbs', 'script', 'base64', 'applet', 'alert', 'document', + 'write', 'cookie', 'window', 'confirm', 'prompt' ); foreach ($words as $word) @@ -420,6 +441,12 @@ class CI_Security { * We used to do some version comparisons and use of stripos for PHP5, * but it is dog slow compared to these simplified non-capturing * preg_match(), especially if the pattern exists in the string + * + * Note: It was reported that not only space characters, but all in + * the following pattern can be parsed as separators between a tag name + * and its attributes: [\d\s"\'`;,\/\=\(\x00\x0B\x09\x0C] + * ... however, remove_invisible_characters() above already strips the + * hex-encoded ones, so we'll skip them below. */ do { @@ -427,12 +454,12 @@ class CI_Security { if (preg_match('/<a/i', $str)) { - $str = preg_replace_callback('#<a\s+([^>]*?)(?:>|$)#si', array($this, '_js_link_removal'), $str); + $str = preg_replace_callback('#<a[\s\d"\'`;/=,\(\\\\]+([^>]*?)(?:>|$)#si', array($this, '_js_link_removal'), $str); } if (preg_match('/<img/i', $str)) { - $str = preg_replace_callback('#<img\s+([^>]*?)(?:\s?/?>|$)#si', array($this, '_js_img_removal'), $str); + $str = preg_replace_callback('#<img[\s\d"\'`;/=,\(\\\\]+([^>]*?)(?:\s?/?>|$)#si', array($this, '_js_img_removal'), $str); } if (preg_match('/script|xss/i', $str)) @@ -456,7 +483,7 @@ class CI_Security { * So this: <blink> * Becomes: <blink> */ - $naughty = 'alert|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|isindex|layer|link|meta|object|plaintext|style|script|textarea|title|video|xml|xss'; + $naughty = 'alert|prompt|confirm|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|button|select|isindex|layer|link|meta|keygen|object|plaintext|style|script|textarea|title|math|video|svg|xml|xss'; $str = preg_replace_callback('#<(/*\s*)('.$naughty.')([^><]*)([><]*)#is', array($this, '_sanitize_naughty_html'), $str); /* @@ -471,7 +498,7 @@ class CI_Security { * For example: eval('some code') * Becomes: eval('some code') */ - $str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', + $str = preg_replace('#(alert|prompt|confirm|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', '\\1\\2(\\3)', $str); @@ -551,13 +578,13 @@ class CI_Security { do { - $matches = $matches1 = 0; + $m1 = $m2 = 0; + $str = preg_replace('/(�*[0-9a-f]{2,5})(?![0-9a-f;])/iS', '$1;', $str, -1, $m1); + $str = preg_replace('/(&#\d{2,4})(?![0-9;])/S', '$1;', $str, -1, $m2); $str = html_entity_decode($str, ENT_COMPAT, $charset); - $str = preg_replace('~&#x(0*[0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str, -1, $matches); - $str = preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str, -1, $matches1); } - while ($matches OR $matches1); + while ($m1 OR $m2); return $str; } @@ -603,7 +630,7 @@ class CI_Security { */ public function strip_image_tags($str) { - return preg_replace(array('#<img\s+.*?src\s*=\s*["\'](.+?)["\'].*?\>#', '#<img\s+.*?src\s*=\s*(.+?).*?\>#'), '\\1', $str); + return preg_replace(array('#<img[\s/]+.*?src\s*=\s*["\'](.+?)["\'].*?\>#', '#<img[\s/]+.*?src\s*=\s*(.+?).*?\>#'), '\\1', $str); } // ---------------------------------------------------------------- @@ -648,8 +675,7 @@ class CI_Security { */ protected function _remove_evil_attributes($str, $is_image) { - // All javascript event handlers (e.g. onload, onclick, onmouseover), style, and xmlns - $evil_attributes = array('on\w*', 'style', 'xmlns', 'formaction'); + $evil_attributes = array('on\w*', 'style', 'xmlns', 'formaction', 'form', 'xlink:href'); if ($is_image === TRUE) { @@ -665,7 +691,7 @@ class CI_Security { $attribs = array(); // find occurrences of illegal attribute strings with quotes (042 and 047 are octal quotes) - preg_match_all('/('.implode('|', $evil_attributes).')\s*=\s*(\042|\047)([^\\2]*?)(\\2)/is', $str, $matches, PREG_SET_ORDER); + preg_match_all('/(?<!\w)('.implode('|', $evil_attributes).')\s*=\s*(\042|\047)([^\\2]*?)(\\2)/is', $str, $matches, PREG_SET_ORDER); foreach ($matches as $attr) { @@ -673,7 +699,7 @@ class CI_Security { } // find occurrences of illegal attribute strings without quotes - preg_match_all('/('.implode('|', $evil_attributes).')\s*=\s*([^\s>]*)/is', $str, $matches, PREG_SET_ORDER); + preg_match_all('/(?<!\w)('.implode('|', $evil_attributes).')\s*=\s*([^\s>]*)/is', $str, $matches, PREG_SET_ORDER); foreach ($matches as $attr) { @@ -727,7 +753,7 @@ class CI_Security { protected function _js_link_removal($match) { return str_replace($match[1], - preg_replace('#href=.*?(?:alert\(|alert&\#40;|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|<script|<xss|data\s*:)#si', + preg_replace('#href=.*?(?:(?:alert|prompt|confirm)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|<script|<xss|data\s*:)#si', '', $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1])) ), @@ -752,7 +778,7 @@ class CI_Security { protected function _js_img_removal($match) { return str_replace($match[1], - preg_replace('#src=.*?(?:alert\(|alert&\#40;|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si', + preg_replace('#src=.*?(?:(?:alert|prompt|confirm)(?:\(|&\#40;)|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si', '', $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1])) ), @@ -810,7 +836,14 @@ class CI_Security { */ protected function _decode_entity($match) { - return $this->entity_decode($match[0], strtoupper(config_item('charset'))); + // entity_decode() won't convert dangerous HTML5 entities + // (it could, but ENT_HTML5 is only available since PHP 5.4), + // so we'll do that here + return str_ireplace( + array_keys($this->html5_entities), + array_values($this->html5_entities), + $this->entity_decode($match[0], strtoupper(config_item('charset'))) + ); } // -------------------------------------------------------------------- @@ -837,14 +870,15 @@ class CI_Security { * Add a semicolon if missing. We do this to enable * the conversion of entities to ASCII later. */ - $str = preg_replace('#(&\#?[0-9a-z]{2,})([\x00-\x20])*;?#i', '\\1;\\2', $str); + $str = preg_replace('/(&#\d{2,4})(?![0-9;])/', '$1;', $str); + $str = preg_replace('/(&[a-z]{2,})(?![a-z;])/i', '$1;', $str); /* * Validate UTF16 two byte encoding (x00) * * Just as above, adds a semicolon if missing. */ - $str = preg_replace('#(&\#x?)([0-9A-F]+);?#i', '\\1\\2;', $str); + $str = preg_replace('/(�*[0-9a-f]{2,5})(?![0-9a-f;])/i', '$1;', $str); /* * Un-Protect GET variables in URLs @@ -884,7 +918,7 @@ class CI_Security { { if ($this->_csrf_hash === '') { - // If the cookie exists we will use it's value. + // If the cookie exists we will use its value. // We don't necessarily want to regenerate it with // each page load since a page could contain embedded // sub-pages causing this feature to fail @@ -894,7 +928,7 @@ class CI_Security { return $this->_csrf_hash = $_COOKIE[$this->_csrf_cookie_name]; } - $this->_csrf_hash = md5(uniqid(rand(), TRUE)); + $this->_csrf_hash = md5(uniqid(mt_rand(), TRUE)); $this->csrf_set_cookie(); } diff --git a/system/core/URI.php b/system/core/URI.php index bc086d223..15d6263be 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -44,21 +44,21 @@ class CI_URI { * * @var array */ - public $keyval = array(); + public $keyval = array(); /** * Current URI string * * @var string */ - public $uri_string; + public $uri_string = ''; /** * List of URI segments * * @var array */ - public $segments = array(); + public $segments = array(); /** * Re-indexed list of URI segments @@ -67,90 +67,67 @@ class CI_URI { * * @var array */ - public $rsegments = array(); + public $rsegments = array(); /** - * Class constructor + * Permitted URI chars * - * Simply globalizes the $RTR object. The front - * loads the Router class early on so it's not available - * normally as other classes are. + * PCRE character group allowed in URI segments * - * @return void + * @var string */ - public function __construct() - { - $this->config =& load_class('Config', 'core'); - log_message('debug', 'URI Class Initialized'); - } - - // -------------------------------------------------------------------- + protected $_permitted_uri_chars; /** - * Fetch URI String + * Class constructor * - * @used-by CI_Router * @return void */ - public function _fetch_uri_string() + public function __construct() { - $protocol = strtoupper($this->config->item('uri_protocol')); + $this->config =& load_class('Config', 'core'); - if ($protocol === 'AUTO') + // If query strings are enabled, we don't need to parse any segments. + // However, they don't make sense under CLI. + if (is_cli() OR $this->config->item('enable_query_strings') !== TRUE) { - // Is the request coming from the command line? - if ($this->_is_cli_request()) + $this->_permitted_uri_chars = $this->config->item('permitted_uri_chars'); + + // If it's a CLI request, ignore the configuration + if (is_cli() OR ($protocol = strtoupper($this->config->item('uri_protocol'))) === 'CLI') { $this->_set_uri_string($this->_parse_argv()); - return; } - - // Is there a PATH_INFO variable? This should be the easiest solution. - if (isset($_SERVER['PATH_INFO'])) + elseif ($protocol === 'AUTO') { - $this->_set_uri_string($_SERVER['PATH_INFO']); - return; + // Is there a PATH_INFO variable? This should be the easiest solution. + if (isset($_SERVER['PATH_INFO'])) + { + $this->_set_uri_string($_SERVER['PATH_INFO']); + } + // No PATH_INFO? Let's try REQUST_URI or QUERY_STRING then + elseif (($uri = $this->_parse_request_uri()) !== '' OR ($uri = $this->_parse_query_string()) !== '') + { + $this->_set_uri_string($uri); + } + // As a last ditch effor, let's try using the $_GET array + elseif (is_array($_GET) && count($_GET) === 1 && trim(key($_GET), '/') !== '') + { + $this->_set_uri_string(key($_GET)); + } } - - // Let's try REQUEST_URI then, this will work in most situations - if (($uri = $this->_parse_request_uri()) !== '') + elseif (method_exists($this, ($method = '_parse_'.strtolower($protocol)))) { - $this->_set_uri_string($uri); - return; + $this->_set_uri_string($this->$method()); } - - // No REQUEST_URI either?... What about QUERY_STRING? - if (($uri = $this->_parse_query_string()) !== '') + else { + $uri = isset($_SERVER[$protocol]) ? $_SERVER[$protocol] : @getenv($protocol); $this->_set_uri_string($uri); - return; - } - - // As a last ditch effort let's try using the $_GET array - if (is_array($_GET) && count($_GET) === 1 && trim(key($_GET), '/') !== '') - { - $this->_set_uri_string(key($_GET)); - return; } - - // We've exhausted all our options... - $this->uri_string = ''; - return; } - if ($protocol === 'CLI') - { - $this->_set_uri_string($this->_parse_argv()); - return; - } - elseif (method_exists($this, ($method = '_parse_'.strtolower($protocol)))) - { - $this->_set_uri_string($this->$method()); - return; - } - - $uri = isset($_SERVER[$protocol]) ? $_SERVER[$protocol] : @getenv($protocol); - $this->_set_uri_string($uri); + log_message('debug', 'URI Class Initialized'); } // -------------------------------------------------------------------- @@ -165,6 +142,35 @@ class CI_URI { { // Filter out control characters and trim slashes $this->uri_string = trim(remove_invisible_characters($str, FALSE), '/'); + + if ($this->uri_string !== '') + { + // Remove the URL suffix, if present + if (($suffix = (string) $this->config->item('url_suffix')) !== '') + { + $slen = strlen($suffix); + + if (substr($this->uri_string, -$slen) === $suffix) + { + $this->uri_string = substr($this->uri_string, 0, -$slen); + } + } + + $this->segments[0] = NULL; + // Populate the segments array + foreach (explode('/', preg_replace('|/*(.+?)/*$|', '\\1', $this->uri_string)) as $val) + { + // Filter segments for security + $val = trim($this->filter_uri($val)); + + if ($val !== '') + { + $this->segments[] = $val; + } + } + + unset($this->segments[0]); + } } // -------------------------------------------------------------------- @@ -225,36 +231,10 @@ class CI_URI { // -------------------------------------------------------------------- /** - * Remove relative directory (../) and multi slashes (///) - * - * Do some final cleaning of the URI and return it, currently only used in self::_parse_request_uri() - * - * @param string $url - * @return string - */ - protected function _remove_relative_directory($uri) - { - $uris = array(); - $tok = strtok($uri, '/'); - while ($tok !== FALSE) - { - if (( ! empty($tok) OR $tok === '0') && $tok !== '..') - { - $uris[] = $tok; - } - $tok = strtok('/'); - } - return implode('/', $uris); - } - - // -------------------------------------------------------------------- - - /** * Parse QUERY_STRING * * Will parse QUERY_STRING and automatically detect the URI from it. * - * @used-by CI_URI::_fetch_uri_string() * @return string */ protected function _parse_query_string() @@ -280,23 +260,6 @@ class CI_URI { // -------------------------------------------------------------------- /** - * Is CLI Request? - * - * Duplicate of method from the Input class to test to see if - * a request was made from the command line. - * - * @see CI_Input::is_cli_request() - * @used-by CI_URI::_fetch_uri_string() - * @return bool - */ - protected function _is_cli_request() - { - return (PHP_SAPI === 'cli') OR defined('STDIN'); - } - - // -------------------------------------------------------------------- - - /** * Parse CLI arguments * * Take each command line argument and assume it is a URI segment. @@ -312,104 +275,52 @@ class CI_URI { // -------------------------------------------------------------------- /** - * Filter URI + * Remove relative directory (../) and multi slashes (///) * - * Filters segments for malicious characters. + * Do some final cleaning of the URI and return it, currently only used in self::_parse_request_uri() * - * @used-by CI_Router - * @param string $str + * @param string $url * @return string */ - public function _filter_uri($str) + protected function _remove_relative_directory($uri) { - if ($str !== '' && $this->config->item('permitted_uri_chars') != '' && $this->config->item('enable_query_strings') === FALSE) + $uris = array(); + $tok = strtok($uri, '/'); + while ($tok !== FALSE) { - // preg_quote() in PHP 5.3 escapes -, so the str_replace() and addition of - to preg_quote() is to maintain backwards - // compatibility as many are unaware of how characters in the permitted_uri_chars will be parsed as a regex pattern - if ( ! preg_match('|^['.str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-')).']+$|i', $str)) + if (( ! empty($tok) OR $tok === '0') && $tok !== '..') { - show_error('The URI you submitted has disallowed characters.', 400); + $uris[] = $tok; } + $tok = strtok('/'); } - // Convert programatic characters to entities and return - return str_replace( - array('$', '(', ')', '%28', '%29'), // Bad - array('$', '(', ')', '(', ')'), // Good - $str); - } - - // -------------------------------------------------------------------- - - /** - * Remove URL suffix - * - * Removes the suffix from the URL if needed. - * - * @used-by CI_Router - * @return void - */ - public function _remove_url_suffix() - { - $suffix = (string) $this->config->item('url_suffix'); - - if ($suffix === '') - { - return; - } - - $slen = strlen($suffix); - - if (substr($this->uri_string, -$slen) === $suffix) - { - $this->uri_string = substr($this->uri_string, 0, -$slen); - } + return implode('/', $uris); } // -------------------------------------------------------------------- /** - * Explode URI segments + * Filter URI * - * The individual segments will be stored in the $this->segments array. + * Filters segments for malicious characters. * - * @see CI_URI::$segments - * @used-by CI_Router - * @return void + * @param string $str + * @return string */ - public function _explode_segments() + public function filter_uri($str) { - foreach (explode('/', preg_replace('|/*(.+?)/*$|', '\\1', $this->uri_string)) as $val) + if ( ! empty($str) && ! empty($this->_permitted_uri_chars) && ! preg_match('/^['.$this->_permitted_uri_chars.']+$/i'.(UTF8_ENABLED ? 'u' : ''), $str)) { - // Filter segments for security - $val = trim($this->_filter_uri($val)); - - if ($val !== '') - { - $this->segments[] = $val; - } + show_error('The URI you submitted has disallowed characters.', 400); } - } - // -------------------------------------------------------------------- - - /** - * Re-index Segments - * - * Re-indexes the CI_URI::$segment array so that it starts at 1 rather - * than 0. Doing so makes it simpler to use methods like - * CI_URI::segment(n) since there is a 1:1 relationship between the - * segment array and the actual segments. - * - * @used-by CI_Router - * @return void - */ - public function _reindex_segments() - { - array_unshift($this->segments, NULL); - array_unshift($this->rsegments, NULL); - unset($this->segments[0]); - unset($this->rsegments[0]); + // Convert programatic characters to entities and return + return str_replace( + array('$', '(', ')', '%28', '%29'), // Bad + array('$', '(', ')', '(', ')'), // Good + $str + ); } // -------------------------------------------------------------------- @@ -720,12 +631,7 @@ class CI_URI { { global $RTR; - if (($dir = $RTR->directory) === '/') - { - $dir = ''; - } - - return $dir.implode('/', $this->rsegment_array()); + return ltrim($RTR->directory, '/').implode('/', $this->rsegments); } } diff --git a/system/core/Utf8.php b/system/core/Utf8.php index a78616d40..6ca1a02ca 100644 --- a/system/core/Utf8.php +++ b/system/core/Utf8.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 @@ -48,28 +48,10 @@ class CI_Utf8 { */ public function __construct() { - log_message('debug', 'Utf8 Class Initialized'); - - $charset = strtoupper(config_item('charset')); - - // set internal encoding for multibyte string functions if necessary - // and set a flag so we don't have to repeatedly use extension_loaded() - // or function_exists() - if (extension_loaded('mbstring')) - { - define('MB_ENABLED', TRUE); - mb_internal_encoding($charset); - } - else - { - define('MB_ENABLED', FALSE); - } - if ( - @preg_match('/./u', 'é') === 1 // PCRE must support UTF-8 - && function_exists('iconv') // iconv must be installed - && MB_ENABLED === TRUE // mbstring must be enabled - && $charset === 'UTF-8' // Application charset must be UTF-8 + defined('PREG_BAD_UTF8_ERROR') // PCRE must support UTF-8 + && (ICONV_ENABLED === TRUE OR MB_ENABLED === TRUE) // iconv or mbstring must be installed + && strnatcasecmp(config_item('charset'), 'UTF-8') === 0 // Application charset must be UTF-8 ) { define('UTF8_ENABLED', TRUE); @@ -80,6 +62,8 @@ class CI_Utf8 { define('UTF8_ENABLED', FALSE); log_message('debug', 'UTF-8 Support Disabled'); } + + log_message('debug', 'Utf8 Class Initialized'); } // -------------------------------------------------------------------- @@ -98,7 +82,14 @@ class CI_Utf8 { { if ($this->_is_ascii($str) === FALSE) { - $str = @iconv('UTF-8', 'UTF-8//IGNORE', $str); + if (ICONV_ENABLED) + { + $str = @iconv('UTF-8', 'UTF-8//IGNORE', $str); + } + elseif (MB_ENABLED) + { + $str = mb_convert_encoding($str, 'UTF-8', 'UTF-8'); + } } return $str; @@ -134,7 +125,7 @@ class CI_Utf8 { */ public function convert_to_utf8($str, $encoding) { - if (function_exists('iconv')) + if (ICONV_ENABLED) { return @iconv($encoding, 'UTF-8', $str); } diff --git a/system/core/compat/mbstring.php b/system/core/compat/mbstring.php new file mode 100644 index 000000000..91ea8017c --- /dev/null +++ b/system/core/compat/mbstring.php @@ -0,0 +1,141 @@ +<?php +/** + * CodeIgniter + * + * 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 EllisLab Dev Team + * @copyright Copyright (c) 2008 - 2014, 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 3.0 + * @filesource + */ +defined('BASEPATH') OR exit('No direct script access allowed'); + +/** + * PHP ext/mbstring compatibility package + * + * @package CodeIgniter + * @subpackage CodeIgniter + * @category Compatibility + * @author Andrey Andreev + * @link http://codeigniter.com/user_guide/ + * @link http://php.net/mbstring + */ + +// ------------------------------------------------------------------------ + +if (MB_ENABLED === TRUE) +{ + return; +} + +// ------------------------------------------------------------------------ + +if ( ! function_exists('mb_strlen')) +{ + /** + * mb_strlen() + * + * WARNING: This function WILL fall-back to strlen() + * if iconv is not available! + * + * @link http://php.net/mb_strlen + * @param string $str + * @param string $encoding + * @return string + */ + function mb_strlen($str, $encoding = NULL) + { + if (ICONV_ENABLED === TRUE) + { + return iconv_strlen($str, isset($charset) ? $charset : config_item('charset')); + } + + log_message('debug', 'Compatibility (mbstring): iconv_strlen() is not available, falling back to strlen().'); + return strlen($str); + } +} + +// ------------------------------------------------------------------------ + +if ( ! function_exists('mb_strpos')) +{ + /** + * mb_strpos() + * + * WARNING: This function WILL fall-back to strpos() + * if iconv is not available! + * + * @link http://php.net/mb_strpos() + * @param string $haystack + * @param string $needle + * @param int $offset + * @param string $encoding + * @return mixed + */ + function mb_strpos($haystack, $needle, $offset = 0, $encoding = NULL) + { + if (ICONV_ENABLED === TRUE) + { + return iconv_strpos($haystack, $needle, $offset, isset($encoding) ? $encoding : config_item('charset')); + } + + log_message('debug', 'Compatibility (mbstring): iconv_strpos() is not available, falling back to strpos().'); + return strpos($haystack, $needle, $offset); + } +} + +// ------------------------------------------------------------------------ + +if ( ! function_exists('mb_substr')) +{ + /** + * mb_substr() + * + * WARNING: This function WILL fall-back to substr() + * if iconv is not available. + * + * @link http://php.net/mb_substr + * @param string $str + * @param int $start + * @param int $length + * @param string $encoding + * @return string + */ + function mb_substr($str, $start, $length = NULL, $encoding = NULL) + { + if (ICONV_ENABLED === TRUE) + { + isset($encoding) OR $encoding = config_item('charset'); + return iconv_substr( + $str, + $start, + isset($length) ? $length : iconv_strlen($str, $encoding), // NULL doesn't work + $encoding + ); + } + + log_message('debug', 'Compatibility (mbstring): iconv_substr() is not available, falling back to substr().'); + return isset($length) + ? substr($str, $start, $length) + : substr($str, $start); + } +} + +/* End of file mbstring.php */ +/* Location: ./system/core/compat/mbstring.php */
\ No newline at end of file diff --git a/system/core/compat/password.php b/system/core/compat/password.php new file mode 100644 index 000000000..92fdedb99 --- /dev/null +++ b/system/core/compat/password.php @@ -0,0 +1,216 @@ +<?php +/** + * CodeIgniter + * + * 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 EllisLab Dev Team + * @copyright Copyright (c) 2008 - 2014, 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 3.0 + * @filesource + */ +defined('BASEPATH') OR exit('No direct script access allowed'); + +/** + * PHP ext/standard/password compatibility package + * + * @package CodeIgniter + * @subpackage CodeIgniter + * @category Compatibility + * @author Andrey Andreev + * @link http://codeigniter.com/user_guide/ + * @link http://php.net/password + */ + +// ------------------------------------------------------------------------ + +if (is_php('5.5') OR ! is_php('5.3.7') OR ! defined('CRYPT_BLOWFISH') OR CRYPT_BLOWFISH !== 1) +{ + return; +} + +// ------------------------------------------------------------------------ + +defined('PASSWORD_BCRYPT') OR define('PASSWORD_BCRYPT', 1); +defined('PASSWORD_DEFAULT') OR define('PASSWORD_DEFAULT', PASSWORD_BCRYPT); + +// ------------------------------------------------------------------------ + +if ( ! function_exists('password_get_info')) +{ + /** + * password_get_info() + * + * @link http://php.net/password_get_info + * @param string $hash + * @return array + */ + function password_get_info($hash) + { + return (strlen($hash) < 60 OR sscanf($hash, '$2y$%d', $hash) !== 1) + ? array('algo' => 0, 'algoName' => 'unknown', 'options' => array()) + : array('algo' => 1, 'algoName' => 'bcrypt', 'options' => array('cost' => $hash)); + } +} + +// ------------------------------------------------------------------------ + +if ( ! function_exists('password_hash')) +{ + /** + * password_hash() + * + * @link http://php.net/password_hash + * @param string $password + * @param int $algo + * @param array $options + * @return mixed + */ + function password_hash($password, $algo, array $options = array()) + { + if ($algo !== 1) + { + trigger_error('password_hash(): Unknown hashing algorithm: '.(int) $algo, E_USER_WARNING); + return NULL; + } + + if (isset($options['cost']) && ($options['cost'] < 4 OR $options['cost'] > 31)) + { + trigger_error('password_hash(): Invalid bcrypt cost parameter specified: '.(int) $options['cost'], E_USER_WARNING); + return NULL; + } + + if (isset($options['salt']) && strlen($options['salt']) < 22) + { + trigger_error('password_hash(): Provided salt is too short: '.strlen($options['salt']).' expecting 22', E_USER_WARNING); + return NULL; + } + elseif ( ! isset($options['salt'])) + { + if (defined('MCRYPT_DEV_URANDOM')) + { + $options['salt'] = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM); + } + elseif (function_exists('openssl_random_pseudo_bytes')) + { + $options['salt'] = openssl_random_pseudo_bytes(16); + } + elseif (DIRECTORY_SEPARATOR === '/' && (is_readable($dev = '/dev/arandom') OR is_readable($dev = '/dev/urandom'))) + { + if (($fp = fopen($dev, 'rb')) === FALSE) + { + log_message('error', 'compat/password: Unable to open '.$dev.' for reading.'); + return FALSE; + } + + $options['salt'] = ''; + for ($read = 0; $read < 16; $read = strlen($options['salt'])) + { + if (($read = fread($fp, 16 - $read)) === FALSE) + { + log_message('error', 'compat/password: Error while reading from '.$dev.'.'); + return FALSE; + } + $options['salt'] .= $read; + } + + fclose($fp); + } + else + { + log_message('error', 'compat/password: No CSPRNG available.'); + return FALSE; + } + + $options['salt'] = str_replace('+', '.', rtrim(base64_encode($options['salt']), '=')); + } + elseif ( ! preg_match('#^[a-zA-Z0-9./]+$#D', $options['salt'])) + { + $options['salt'] = str_replace('+', '.', rtrim(base64_encode($options['salt']), '=')); + } + + isset($options['cost']) OR $options['cost'] = 10; + return crypt($password, sprintf('$2y$%02d$%s', $options['cost'], $options['salt'])); + } +} + +// ------------------------------------------------------------------------ + +if ( ! function_exists('password_needs_rehash')) +{ + /** + * password_needs_rehash() + * + * @link http://php.net/password_needs_rehash + * @param string $hash + * @param int $algo + * @param array $options + * @return bool + */ + function password_needs_rehash($hash, $algo, array $options = array()) + { + $info = password_get_info($hash); + + if ($algo !== $info['algo']) + { + return TRUE; + } + elseif ($algo === 1) + { + $options['cost'] = isset($options['cost']) ? (int) $options['cost'] : 10; + return ($info['options']['cost'] !== $options['cost']); + } + + // Odd at first glance, but according to a comment in PHP's own unit tests, + // because it is an unknown algorithm - it's valid and therefore doesn't + // need rehashing. + return FALSE; + } +} + +// ------------------------------------------------------------------------ + +if ( ! function_exists('password_verify')) +{ + /** + * password_verify() + * + * @link http://php.net/password_verify + * @param string $password + * @param string $hash + * @return bool + */ + function password_verify($password, $hash) + { + if (strlen($hash) !== 60 OR strlen($password = crypt($password, $hash)) !== 60) + { + return FALSE; + } + + $compare = 0; + for ($i = 0; $i < 60; $i++) + { + $compare |= (ord($password[$i]) ^ ord($hash[$i])); + } + + return ($compare === 0); + } +} + +/* End of file password.php */ +/* Location: ./system/core/compat/password.php */
\ No newline at end of file diff --git a/system/database/DB.php b/system/database/DB.php index 8742800c8..7e6cd7466 100644 --- a/system/database/DB.php +++ b/system/database/DB.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -206,11 +206,6 @@ function &DB($params = '', $query_builder_override = NULL) $DB->initialize(); } - if ( ! empty($params['stricton'])) - { - $DB->query('SET SESSION sql_mode="STRICT_ALL_TABLES"'); - } - return $DB; } diff --git a/system/database/DB_cache.php b/system/database/DB_cache.php index 921e68655..0ef0ae52f 100644 --- a/system/database/DB_cache.php +++ b/system/database/DB_cache.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php index 53decf014..aeeb2d0f3 100644 --- a/system/database/DB_driver.php +++ b/system/database/DB_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -624,7 +624,14 @@ abstract class CI_DB_driver { // if transactions are enabled. If we don't call this here // the error message will trigger an exit, causing the // transactions to remain in limbo. - $this->_trans_depth > 0 && $this->trans_complete(); + if ($this->_trans_depth !== 0) + { + do + { + $this->trans_complete(); + } + while ($this->_trans_depth !== 0); + } // Display errors return $this->display_error(array('Error Number: '.$error['code'], $error['message'], $sql)); @@ -917,7 +924,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|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); } // -------------------------------------------------------------------- @@ -1135,7 +1142,7 @@ abstract class CI_DB_driver { else { /* We have no other choice but to just get the first element's key. - * Due to array_shift() accepting it's argument by reference, if + * Due to array_shift() accepting its argument by reference, if * E_STRICT is on, this would trigger a warning. So we'll have to * assign it first. */ @@ -1414,7 +1421,7 @@ abstract class CI_DB_driver { */ protected function _has_operator($str) { - return (bool) preg_match('/(<|>|!|=|\sIS NULL|\sIS NOT NULL|\sBETWEEN|\sLIKE|\sIN\s*\(|\s)/i', trim($str)); + return (bool) preg_match('/(<|>|!|=|\sIS NULL|\sIS NOT NULL|\sEXISTS|\sBETWEEN|\sLIKE|\sIN\s*\(|\s)/i', trim($str)); } // -------------------------------------------------------------------- @@ -1440,6 +1447,8 @@ abstract class CI_DB_driver { '\s*>\s*', // > '\s+IS NULL', // IS NULL '\s+IS NOT NULL', // IS NOT NULL + '\s+EXISTS\s*\([^\)]+\)', // EXISTS(sql) + '\s+NOT EXISTS\s*\([^\)]+\)', // NOT EXISTS(sql) '\s+BETWEEN\s+\S+\s+AND\s+\S+', // BETWEEN value AND value '\s+IN\s*\([^\)]+\)', // IN(list) '\s+NOT IN\s*\([^\)]+\)', // NOT IN (list) @@ -1476,7 +1485,7 @@ abstract class CI_DB_driver { } return (func_num_args() > 1) - ? call_user_func_array($function, array_splice(func_get_args(), 1)) + ? call_user_func_array($function, array_slice(func_get_args(), 1)) : call_user_func($function); } diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php index d52029ecd..4eeb74a9c 100644 --- a/system/database/DB_forge.php +++ b/system/database/DB_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -314,9 +314,10 @@ abstract class CI_DB_forge { * * @param string $table Table name * @param bool $if_not_exists Whether to add IF NOT EXISTS condition + * @param array $attributes Associative array of table attributes * @return bool */ - public function create_table($table = '', $if_not_exists = FALSE) + public function create_table($table = '', $if_not_exists = FALSE, array $attributes = array()) { if ($table === '') { @@ -332,7 +333,7 @@ abstract class CI_DB_forge { show_error('Field information is required.'); } - $sql = $this->_create_table($table, $if_not_exists); + $sql = $this->_create_table($table, $if_not_exists, $attributes); if (is_bool($sql)) { @@ -368,9 +369,10 @@ abstract class CI_DB_forge { * * @param string $table Table name * @param bool $if_not_exists Whether to add 'IF NOT EXISTS' condition + * @param array $attributes Associative array of table attributes * @return mixed */ - protected function _create_table($table, $if_not_exists) + protected function _create_table($table, $if_not_exists, $attributes) { if ($if_not_exists === TRUE && $this->_create_table_if === FALSE) { @@ -406,10 +408,11 @@ abstract class CI_DB_forge { } // _create_table will usually have the following format: "%s %s (%s\n)" - $sql = sprintf($this->_create_table.';', + $sql = sprintf($this->_create_table.'%s;', $sql, $this->db->escape_identifiers($table), - $columns + $columns, + $this->_create_table_attr($attributes) ); return $sql; @@ -418,6 +421,29 @@ abstract class CI_DB_forge { // -------------------------------------------------------------------- /** + * CREATE TABLE attributes + * + * @param array $attributes Associative array of table attributes + * @return string + */ + protected function _create_table_attr($attributes) + { + $sql = ''; + + foreach (array_keys($attributes) as $key) + { + if (is_string($key)) + { + $sql .= ' '.strtoupper($key).' '.$attributes[$key]; + } + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** * Drop Table * * @param string $table_name Table name @@ -740,6 +766,18 @@ abstract class CI_DB_forge { '_literal' => FALSE ); + if ($create_table === FALSE) + { + if (isset($attributes['AFTER'])) + { + $field['after'] = $attributes['AFTER']; + } + elseif (isset($attributes['FIRST'])) + { + $field['first'] = (bool) $attributes['FIRST']; + } + } + $this->_attr_default($attributes, $field); if (isset($attributes['NULL'])) @@ -748,11 +786,15 @@ abstract class CI_DB_forge { { $field['null'] = empty($this->_null) ? '' : ' '.$this->_null; } - elseif ($create_table === TRUE) + else { $field['null'] = ' NOT NULL'; } } + elseif ($create_table === TRUE) + { + $field['null'] = ' NOT NULL'; + } $this->_attr_auto_increment($attributes, $field); $this->_attr_unique($attributes, $field); @@ -968,7 +1010,6 @@ abstract class CI_DB_forge { */ protected function _process_indexes($table) { - $table = $this->db->escape_identifiers($table); $sqls = array(); for ($i = 0, $c = count($this->keys); $i < $c; $i++) @@ -992,7 +1033,7 @@ abstract class CI_DB_forge { is_array($this->keys[$i]) OR $this->keys[$i] = array($this->keys[$i]); - $sqls[] = 'CREATE INDEX '.$this->db->escape_identifiers(implode('_', $this->keys[$i])) + $sqls[] = 'CREATE INDEX '.$this->db->escape_identifiers($table.'_'.implode('_', $this->keys[$i])) .' ON '.$this->db->escape_identifiers($table) .' ('.implode(', ', $this->db->escape_identifiers($this->keys[$i])).');'; } diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php index a36501eb6..085c615e5 100644 --- a/system/database/DB_query_builder.php +++ b/system/database/DB_query_builder.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -263,7 +263,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { $select = explode(',', $select); } - // If the escape value was not set will will base it on the global setting + // If the escape value was not set, we will base it on the global setting is_bool($escape) OR $escape = $this->_protect_identifiers; foreach ($select as $val) @@ -1338,7 +1338,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver { * returned by an Query Builder query. * * @param string - * @return string + * @return int */ public function count_all_results($table = '') { @@ -2291,7 +2291,12 @@ abstract class CI_DB_query_builder extends CI_DB_driver { { for ($i = 0, $c = count($this->$qb_key); $i < $c; $i++) { - if ($this->{$qb_key}[$i]['escape'] === FALSE) + // Is this condition already compiled? + if (is_string($this->{$qb_key}[$i])) + { + continue; + } + elseif ($this->{$qb_key}[$i]['escape'] === FALSE) { $this->{$qb_key}[$i] = $this->{$qb_key}[$i]['condition']; continue; @@ -2361,6 +2366,12 @@ abstract class CI_DB_query_builder extends CI_DB_driver { { for ($i = 0, $c = count($this->qb_groupby); $i < $c; $i++) { + // Is it already compiled? + if (is_string($this->qb_groupby[$i])) + { + continue; + } + $this->qb_groupby[$i] = ($this->qb_groupby[$i]['escape'] === FALSE OR $this->_is_literal($this->qb_groupby[$i]['field'])) ? $this->qb_groupby[$i]['field'] : $this->protect_identifiers($this->qb_groupby[$i]['field']); @@ -2545,17 +2556,34 @@ abstract class CI_DB_query_builder extends CI_DB_driver { { return; } + elseif (in_array('select', $this->qb_cache_exists, TRUE)) + { + $qb_no_escape = $this->qb_cache_no_escape; + } - foreach ($this->qb_cache_exists as $val) + foreach (array_unique($this->qb_cache_exists) as $val) // select, from, etc. { $qb_variable = 'qb_'.$val; $qb_cache_var = 'qb_cache_'.$val; + $qb_new = $this->$qb_cache_var; - if (count($this->$qb_cache_var) === 0) + for ($i = 0, $c = count($this->$qb_variable); $i < $c; $i++) { - continue; + if ( ! in_array($this->{$qb_variable}[$i], $qb_new, TRUE)) + { + $qb_new[] = $this->{$qb_variable}[$i]; + if ($val === 'select') + { + $qb_no_escape[] = $this->qb_no_escape[$i]; + } + } + } + + $this->$qb_variable = $qb_new; + if ($val === 'select') + { + $this->qb_no_escape = $qb_no_escape; } - $this->$qb_variable = array_merge($this->$qb_variable, array_diff($this->$qb_cache_var, $this->$qb_variable)); } // If we are "protecting identifiers" we need to examine the "from" @@ -2564,8 +2592,6 @@ abstract class CI_DB_query_builder extends CI_DB_driver { { $this->_track_aliases($this->qb_from); } - - $this->qb_no_escape = array_merge($this->qb_no_escape, array_diff($this->qb_cache_no_escape, $this->qb_no_escape)); } // -------------------------------------------------------------------- diff --git a/system/database/DB_result.php b/system/database/DB_result.php index 41a851777..6aa4e92b6 100644 --- a/system/database/DB_result.php +++ b/system/database/DB_result.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/DB_utility.php b/system/database/DB_utility.php index 9f953d4ac..11c5e116b 100644 --- a/system/database/DB_utility.php +++ b/system/database/DB_utility.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -282,8 +282,7 @@ abstract class CI_DB_utility { extract($params); // Load the xml helper - $CI =& get_instance(); - $CI->load->helper('xml'); + get_instance()->load->helper('xml'); // Generate the result $xml = '<'.$root.'>'.$newline; diff --git a/system/database/drivers/cubrid/cubrid_driver.php b/system/database/drivers/cubrid/cubrid_driver.php index 51bbbdb47..0db51735c 100644 --- a/system/database/drivers/cubrid/cubrid_driver.php +++ b/system/database/drivers/cubrid/cubrid_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.1 diff --git a/system/database/drivers/cubrid/cubrid_forge.php b/system/database/drivers/cubrid/cubrid_forge.php index 554f31ec7..807dd6d02 100644 --- a/system/database/drivers/cubrid/cubrid_forge.php +++ b/system/database/drivers/cubrid/cubrid_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.1 diff --git a/system/database/drivers/cubrid/cubrid_result.php b/system/database/drivers/cubrid/cubrid_result.php index 67d5beda5..76a479a18 100644 --- a/system/database/drivers/cubrid/cubrid_result.php +++ b/system/database/drivers/cubrid/cubrid_result.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.1 diff --git a/system/database/drivers/cubrid/cubrid_utility.php b/system/database/drivers/cubrid/cubrid_utility.php index 472b7b042..54e6b4a01 100644 --- a/system/database/drivers/cubrid/cubrid_utility.php +++ b/system/database/drivers/cubrid/cubrid_utility.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.1 diff --git a/system/database/drivers/ibase/ibase_driver.php b/system/database/drivers/ibase/ibase_driver.php index 745011056..4cff5f448 100644 --- a/system/database/drivers/ibase/ibase_driver.php +++ b/system/database/drivers/ibase/ibase_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 3.0 diff --git a/system/database/drivers/ibase/ibase_forge.php b/system/database/drivers/ibase/ibase_forge.php index e3f714688..19ac86c37 100644 --- a/system/database/drivers/ibase/ibase_forge.php +++ b/system/database/drivers/ibase/ibase_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 3.0 diff --git a/system/database/drivers/ibase/ibase_result.php b/system/database/drivers/ibase/ibase_result.php index 1ab1e2ada..1f89db65d 100644 --- a/system/database/drivers/ibase/ibase_result.php +++ b/system/database/drivers/ibase/ibase_result.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/ibase/ibase_utility.php b/system/database/drivers/ibase/ibase_utility.php index 4f9b1d19e..a17b19ea8 100644 --- a/system/database/drivers/ibase/ibase_utility.php +++ b/system/database/drivers/ibase/ibase_utility.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 3.0 diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php index 0836fa802..655aa7148 100644 --- a/system/database/drivers/mssql/mssql_driver.php +++ b/system/database/drivers/mssql/mssql_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -311,7 +311,7 @@ class CI_DB_mssql_driver extends CI_DB { .' FROM '.$this->escape_identifiers('sysobjects') .' WHERE '.$this->escape_identifiers('type')." = 'U'"; - if ($prefix_limit !== FALSE AND $this->dbprefix !== '') + if ($prefix_limit !== FALSE && $this->dbprefix !== '') { $sql .= ' AND '.$this->escape_identifiers('name')." LIKE '".$this->escape_like_str($this->dbprefix)."%' " .sprintf($this->_like_escape_str, $this->_like_escape_chr); diff --git a/system/database/drivers/mssql/mssql_forge.php b/system/database/drivers/mssql/mssql_forge.php index c03db5773..eeb01ba68 100644 --- a/system/database/drivers/mssql/mssql_forge.php +++ b/system/database/drivers/mssql/mssql_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/mssql/mssql_result.php b/system/database/drivers/mssql/mssql_result.php index b6e5f2b17..cce93740f 100644 --- a/system/database/drivers/mssql/mssql_result.php +++ b/system/database/drivers/mssql/mssql_result.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/mssql/mssql_utility.php b/system/database/drivers/mssql/mssql_utility.php index 5007e88b8..97212bd6c 100644 --- a/system/database/drivers/mssql/mssql_utility.php +++ b/system/database/drivers/mssql/mssql_utility.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php index b94642b35..499d42691 100644 --- a/system/database/drivers/mysql/mysql_driver.php +++ b/system/database/drivers/mysql/mysql_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -66,6 +66,15 @@ class CI_DB_mysql_driver extends CI_DB { */ public $delete_hack = TRUE; + /** + * Strict ON flag + * + * Whether we're running in strict SQL mode. + * + * @var bool + */ + public $stricton = FALSE; + // -------------------------------------------------------------------- /** @@ -126,6 +135,11 @@ class CI_DB_mysql_driver extends CI_DB { : FALSE; } + if ($this->stricton && is_resource($this->conn_id)) + { + $this->simple_query('SET SESSION sql_mode="STRICT_ALL_TABLES"'); + } + return $this->conn_id; } diff --git a/system/database/drivers/mysql/mysql_forge.php b/system/database/drivers/mysql/mysql_forge.php index e251c0ea6..cc886e8ac 100644 --- a/system/database/drivers/mysql/mysql_forge.php +++ b/system/database/drivers/mysql/mysql_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -82,16 +82,34 @@ class CI_DB_mysql_forge extends CI_DB_forge { // -------------------------------------------------------------------- /** - * Class constructor + * CREATE TABLE attributes * - * @param object &$db Database object - * @return void + * @param array $attributes Associative array of table attributes + * @return string */ - public function __construct(&$db) + protected function _create_table_attr($attributes) { - parent::__construct($db); + $sql = ''; + + foreach (array_keys($attributes) as $key) + { + if (is_string($key)) + { + $sql .= ' '.strtoupper($key).' = '.$attributes[$key]; + } + } - $this->_create_table .= ' DEFAULT CHARSET '.$this->db->char_set.' COLLATE '.$this->db->dbcollat; + if ( ! empty($this->db->char_set) && ! strpos($sql, 'CHARACTER SET') && ! strpos($sql, 'CHARSET')) + { + $sql .= ' DEFAULT CHARACTER SET = '.$this->db->char_set; + } + + if ( ! empty($this->db->dbcollat) && ! strpos($sql, 'COLLATE')) + { + $sql .= ' COLLATE = '.$this->db->dbcollat; + } + + return $sql; } // -------------------------------------------------------------------- diff --git a/system/database/drivers/mysql/mysql_result.php b/system/database/drivers/mysql/mysql_result.php index a2affcb58..c232b5c90 100644 --- a/system/database/drivers/mysql/mysql_result.php +++ b/system/database/drivers/mysql/mysql_result.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/mysql/mysql_utility.php b/system/database/drivers/mysql/mysql_utility.php index ea8702708..91de8710e 100644 --- a/system/database/drivers/mysql/mysql_utility.php +++ b/system/database/drivers/mysql/mysql_utility.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php index ef2cb8a8d..083b0c621 100644 --- a/system/database/drivers/mysqli/mysqli_driver.php +++ b/system/database/drivers/mysqli/mysqli_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -66,6 +66,15 @@ class CI_DB_mysqli_driver extends CI_DB { */ public $delete_hack = TRUE; + /** + * Strict ON flag + * + * Whether we're running in strict SQL mode. + * + * @var bool + */ + public $stricton = FALSE; + // -------------------------------------------------------------------- /** @@ -93,6 +102,11 @@ class CI_DB_mysqli_driver extends CI_DB { $client_flags = ($this->compress === TRUE) ? MYSQLI_CLIENT_COMPRESS : 0; $mysqli = mysqli_init(); + if ($this->stricton) + { + $mysqli->options(MYSQLI_INIT_COMMAND, 'SET SESSION sql_mode="STRICT_ALL_TABLES"'); + } + return @$mysqli->real_connect($hostname, $this->username, $this->password, $this->database, $port, NULL, $client_flags) ? $mysqli : FALSE; } @@ -241,9 +255,10 @@ class CI_DB_mysqli_driver extends CI_DB { // even if the queries produce a successful result. $this->_trans_failure = ($test_mode === TRUE); - $this->simple_query('SET AUTOCOMMIT=0'); - $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK - return TRUE; + $this->conn_id->autocommit(FALSE); + return is_php('5.5') + ? $this->conn_id->begin_transaction() + : $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK } // -------------------------------------------------------------------- @@ -261,9 +276,13 @@ class CI_DB_mysqli_driver extends CI_DB { return TRUE; } - $this->simple_query('COMMIT'); - $this->simple_query('SET AUTOCOMMIT=1'); - return TRUE; + if ($this->conn_id->commit()) + { + $this->conn_id->autocommit(TRUE); + return TRUE; + } + + return FALSE; } // -------------------------------------------------------------------- @@ -281,9 +300,13 @@ class CI_DB_mysqli_driver extends CI_DB { return TRUE; } - $this->simple_query('ROLLBACK'); - $this->simple_query('SET AUTOCOMMIT=1'); - return TRUE; + if ($this->conn_id->rollback()) + { + $this->conn_id->autocommit(TRUE); + return TRUE; + } + + return FALSE; } // -------------------------------------------------------------------- diff --git a/system/database/drivers/mysqli/mysqli_forge.php b/system/database/drivers/mysqli/mysqli_forge.php index d1e5e20ff..3a19405d2 100644 --- a/system/database/drivers/mysqli/mysqli_forge.php +++ b/system/database/drivers/mysqli/mysqli_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -82,16 +82,34 @@ class CI_DB_mysqli_forge extends CI_DB_forge { // -------------------------------------------------------------------- /** - * Class constructor + * CREATE TABLE attributes * - * @param object &$db Database object - * @return void + * @param array $attributes Associative array of table attributes + * @return string */ - public function __construct(&$db) + protected function _create_table_attr($attributes) { - parent::__construct($db); + $sql = ''; + + foreach (array_keys($attributes) as $key) + { + if (is_string($key)) + { + $sql .= ' '.strtoupper($key).' = '.$attributes[$key]; + } + } - $this->_create_table .= ' DEFAULT CHARSET '.$this->db->char_set.' COLLATE '.$this->db->dbcollat; + if ( ! empty($this->db->char_set) && ! strpos($sql, 'CHARACTER SET') && ! strpos($sql, 'CHARSET')) + { + $sql .= ' DEFAULT CHARACTER SET = '.$this->db->char_set; + } + + if ( ! empty($this->db->dbcollat) && ! strpos($sql, 'COLLATE')) + { + $sql .= ' COLLATE = '.$this->db->dbcollat; + } + + return $sql; } // -------------------------------------------------------------------- diff --git a/system/database/drivers/mysqli/mysqli_result.php b/system/database/drivers/mysqli/mysqli_result.php index 3fe05f9c5..7f5792ae5 100644 --- a/system/database/drivers/mysqli/mysqli_result.php +++ b/system/database/drivers/mysqli/mysqli_result.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/mysqli/mysqli_utility.php b/system/database/drivers/mysqli/mysqli_utility.php index ef113e5e2..1c9475761 100644 --- a/system/database/drivers/mysqli/mysqli_utility.php +++ b/system/database/drivers/mysqli/mysqli_utility.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php index 020a3a4ba..f309a8272 100644 --- a/system/database/drivers/oci8/oci8_driver.php +++ b/system/database/drivers/oci8/oci8_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -344,7 +344,7 @@ class CI_DB_oci8_driver extends CI_DB { $have_cursor = TRUE; } } - $sql = trim($sql, ',') . '); END;'; + $sql = trim($sql, ',').'); END;'; $this->stmt_id = FALSE; $this->_set_stmt_id($sql); diff --git a/system/database/drivers/oci8/oci8_forge.php b/system/database/drivers/oci8/oci8_forge.php index 341f9dd3b..d63846f55 100644 --- a/system/database/drivers/oci8/oci8_forge.php +++ b/system/database/drivers/oci8/oci8_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/oci8/oci8_result.php b/system/database/drivers/oci8/oci8_result.php index ce09b62bc..177646273 100644 --- a/system/database/drivers/oci8/oci8_result.php +++ b/system/database/drivers/oci8/oci8_result.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/oci8/oci8_utility.php b/system/database/drivers/oci8/oci8_utility.php index 70b8bdb86..856125b17 100644 --- a/system/database/drivers/oci8/oci8_utility.php +++ b/system/database/drivers/oci8/oci8_utility.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/odbc/odbc_driver.php b/system/database/drivers/odbc/odbc_driver.php index 45e91cbc5..662a1063a 100644 --- a/system/database/drivers/odbc/odbc_driver.php +++ b/system/database/drivers/odbc/odbc_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -222,7 +222,7 @@ class CI_DB_odbc_driver extends CI_DB { */ public function affected_rows() { - return @odbc_num_rows($this->conn_id); + return @odbc_num_rows($this->result_id); } // -------------------------------------------------------------------- diff --git a/system/database/drivers/odbc/odbc_forge.php b/system/database/drivers/odbc/odbc_forge.php index 2a477a5b6..dbf9949c9 100644 --- a/system/database/drivers/odbc/odbc_forge.php +++ b/system/database/drivers/odbc/odbc_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/odbc/odbc_result.php b/system/database/drivers/odbc/odbc_result.php index 474143e41..5b2df3943 100644 --- a/system/database/drivers/odbc/odbc_result.php +++ b/system/database/drivers/odbc/odbc_result.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/odbc/odbc_utility.php b/system/database/drivers/odbc/odbc_utility.php index a012c4ef9..00b6186db 100644 --- a/system/database/drivers/odbc/odbc_utility.php +++ b/system/database/drivers/odbc/odbc_utility.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/pdo/pdo_driver.php b/system/database/drivers/pdo/pdo_driver.php index 184a8df33..49612b972 100644 --- a/system/database/drivers/pdo/pdo_driver.php +++ b/system/database/drivers/pdo/pdo_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.1.0 @@ -92,7 +92,7 @@ class CI_DB_pdo_driver extends CI_DB { { $this->subdriver = '4d'; } - elseif ( ! in_array($this->subdriver, array('4d', 'cubrid', 'dblib', 'firebird', 'ibm', 'informix', 'mysql', 'oci', 'odbc', 'sqlite', 'sqlsrv'), TRUE)) + elseif ( ! in_array($this->subdriver, array('4d', 'cubrid', 'dblib', 'firebird', 'ibm', 'informix', 'mysql', 'oci', 'odbc', 'pgsql', 'sqlite', 'sqlsrv'), TRUE)) { log_message('error', 'PDO: Invalid or non-existent subdriver'); @@ -117,7 +117,6 @@ class CI_DB_pdo_driver extends CI_DB { { $this->options[PDO::ATTR_PERSISTENT] = $persistent; - // Connecting... try { return @new PDO($this->dsn, $this->username, $this->password, $this->options); diff --git a/system/database/drivers/pdo/pdo_forge.php b/system/database/drivers/pdo/pdo_forge.php index ccd39ca97..4bc854692 100644 --- a/system/database/drivers/pdo/pdo_forge.php +++ b/system/database/drivers/pdo/pdo_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.1.0 diff --git a/system/database/drivers/pdo/pdo_result.php b/system/database/drivers/pdo/pdo_result.php index 761348eb2..904bdd5b3 100644 --- a/system/database/drivers/pdo/pdo_result.php +++ b/system/database/drivers/pdo/pdo_result.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/pdo/pdo_utility.php b/system/database/drivers/pdo/pdo_utility.php index bd78cd8b4..f3c8e2dc4 100644 --- a/system/database/drivers/pdo/pdo_utility.php +++ b/system/database/drivers/pdo/pdo_utility.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.1.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php b/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php index e94c0bfff..590a33275 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_4d_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 3.0.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php b/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php index c49549961..97255ed78 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_4d_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.1.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php b/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php index 1dbd385e5..d2d1fd57e 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 3.0.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php b/system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php index 1ee17035d..ed93d24ca 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_cubrid_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.1.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php b/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php index 95203e236..379fc0794 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 3.0.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php b/system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php index 516b6f2c5..271c00dbf 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_dblib_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.1.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php b/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php index abb3d4511..cbee19e8c 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 3.0.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php b/system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php index a43397378..d754c2782 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_firebird_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.1.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php b/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php index 5670da75f..030fae036 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_ibm_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 3.0.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php b/system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php index ed7f4cc97..fc3579fe2 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_ibm_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.1.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php b/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php index c126b5b52..f28cce1d9 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_informix_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 3.0.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_informix_forge.php b/system/database/drivers/pdo/subdrivers/pdo_informix_forge.php index fca8c22a7..a2d0bdda8 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_informix_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_informix_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.1.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php b/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php index ff486fc5a..70c405c78 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 3.0.0 @@ -55,6 +55,15 @@ class CI_DB_pdo_mysql_driver extends CI_DB_pdo_driver { */ public $compress = FALSE; + /** + * Strict ON flag + * + * Whether we're running in strict SQL mode. + * + * @var bool + */ + public $stricton = FALSE; + // -------------------------------------------------------------------- /** @@ -114,6 +123,18 @@ class CI_DB_pdo_mysql_driver extends CI_DB_pdo_driver { .(empty($this->dbcollat) ? '' : ' COLLATE '.$this->dbcollat); } + if ($this->stricton) + { + if (empty($this->options[PDO::MYSQL_ATTR_INIT_COMMAND])) + { + $this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET SESSION sql_mode="STRICT_ALL_TABLES"'; + } + else + { + $this->options[PDO::MYSQL_ATTR_INIT_COMMAND] .= ', @@session.sql_mode = "STRICT_ALL_TABLES"'; + } + } + if ($this->compress === TRUE) { $this->options[PDO::MYSQL_ATTR_COMPRESS] = TRUE; diff --git a/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php b/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php index 74689d91e..d2e1e2828 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_mysql_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.1.0 @@ -96,16 +96,34 @@ class CI_DB_pdo_mysql_forge extends CI_DB_pdo_forge { // -------------------------------------------------------------------- /** - * Class constructor + * CREATE TABLE attributes * - * @param object &$db Database object - * @return void + * @param array $attributes Associative array of table attributes + * @return string */ - public function __construct(&$db) + protected function _create_table_attr($attributes) { - parent::__construct($db); + $sql = ''; + + foreach (array_keys($attributes) as $key) + { + if (is_string($key)) + { + $sql .= ' '.strtoupper($key).' = '.$attributes[$key]; + } + } - $this->_create_table .= ' DEFAULT CHARSET '.$this->db->char_set.' COLLATE '.$this->db->dbcollat; + if ( ! empty($this->db->char_set) && ! strpos($sql, 'CHARACTER SET') && ! strpos($sql, 'CHARSET')) + { + $sql .= ' DEFAULT CHARACTER SET = '.$this->db->char_set; + } + + if ( ! empty($this->db->dbcollat) && ! strpos($sql, 'COLLATE')) + { + $sql .= ' COLLATE = '.$this->db->dbcollat; + } + + return $sql; } // -------------------------------------------------------------------- diff --git a/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php b/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php index 4b3053c3c..6fef078c5 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_oci_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 3.0.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php b/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php index 4ace1bc4e..dbbff5b2d 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_oci_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.1.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php b/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php index 773180ee2..c95fe18d8 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 3.0.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_odbc_forge.php b/system/database/drivers/pdo/subdrivers/pdo_odbc_forge.php index 3d00c8831..e7feacd0c 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_odbc_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_odbc_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.1.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php b/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php index 83daee9f6..0e25bc5b4 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 3.0.0 @@ -84,6 +84,12 @@ class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver { empty($this->port) OR $this->dsn .= ';port='.$this->port; empty($this->database) OR $this->dsn .= ';dbname='.$this->database; + + if ( ! empty($this->username)) + { + $this->dsn .= ';username='.$this->username; + empty($this->password) OR $this->dsn .= ';password='.$this->password; + } } } @@ -137,7 +143,7 @@ class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver { */ public function is_write_type($sql) { - return (bool) preg_match('/^\s*"?(SET|INSERT(?![^\)]+\)\s+RETURNING)|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s+/i', $sql); + return (bool) preg_match('/^\s*"?(SET|INSERT(?![^\)]+\)\s+RETURNING)|UPDATE(?!.*\sRETURNING)|DELETE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s/i', str_replace(array("\r\n", "\r", "\n"), ' ', $sql)); } // -------------------------------------------------------------------- diff --git a/system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php b/system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php index 630cd527d..cdaa20265 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_pgsql_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.1.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php b/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php index 6cad6797c..a91f00bc9 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 3.0.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php b/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php index b451d056a..b43e3238d 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_sqlite_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.1.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php index 722e22636..ba004d5d8 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php +++ b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 3.0.0 diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php index dbaff7762..3a903c723 100644 --- a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php +++ b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.1.0 diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php index f24db46b4..7d17f799e 100644 --- a/system/database/drivers/postgre/postgre_driver.php +++ b/system/database/drivers/postgre/postgre_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -318,7 +318,7 @@ class CI_DB_postgre_driver extends CI_DB { */ public function is_write_type($sql) { - return (bool) preg_match('/^\s*"?(SET|INSERT(?![^\)]+\)\s+RETURNING)|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s+/i', $sql); + return (bool) preg_match('/^\s*"?(SET|INSERT(?![^\)]+\)\s+RETURNING)|UPDATE(?!.*\sRETURNING)|DELETE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s/i', str_replace(array("\r\n", "\r", "\n"), ' ', $sql)); } // -------------------------------------------------------------------- @@ -331,7 +331,7 @@ class CI_DB_postgre_driver extends CI_DB { */ protected function _escape_str($str) { - return pg_escape_string($str); + return pg_escape_string($this->conn_id, $str); } // -------------------------------------------------------------------- @@ -346,7 +346,11 @@ class CI_DB_postgre_driver extends CI_DB { */ public function escape($str) { - if (is_bool($str)) + if (is_php('5.4.4') && (is_string($str) OR (is_object($str) && method_exists($str, '__toString')))) + { + return pg_escape_literal($this->conn_id, $str); + } + elseif (is_bool($str)) { return ($str) ? 'TRUE' : 'FALSE'; } diff --git a/system/database/drivers/postgre/postgre_forge.php b/system/database/drivers/postgre/postgre_forge.php index 97b82776d..8bfb66c43 100644 --- a/system/database/drivers/postgre/postgre_forge.php +++ b/system/database/drivers/postgre/postgre_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/postgre/postgre_result.php b/system/database/drivers/postgre/postgre_result.php index 592078171..ec484e940 100644 --- a/system/database/drivers/postgre/postgre_result.php +++ b/system/database/drivers/postgre/postgre_result.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/postgre/postgre_utility.php b/system/database/drivers/postgre/postgre_utility.php index a082e33b8..fe7e3b682 100644 --- a/system/database/drivers/postgre/postgre_utility.php +++ b/system/database/drivers/postgre/postgre_utility.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/sqlite/sqlite_driver.php b/system/database/drivers/sqlite/sqlite_driver.php index 6a3397f6f..9928aedb7 100644 --- a/system/database/drivers/sqlite/sqlite_driver.php +++ b/system/database/drivers/sqlite/sqlite_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/sqlite/sqlite_forge.php b/system/database/drivers/sqlite/sqlite_forge.php index 1823227db..f80b5e71b 100644 --- a/system/database/drivers/sqlite/sqlite_forge.php +++ b/system/database/drivers/sqlite/sqlite_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/sqlite/sqlite_result.php b/system/database/drivers/sqlite/sqlite_result.php index b73105486..8279c315d 100644 --- a/system/database/drivers/sqlite/sqlite_result.php +++ b/system/database/drivers/sqlite/sqlite_result.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/sqlite/sqlite_utility.php b/system/database/drivers/sqlite/sqlite_utility.php index 8825cd5b6..7ad040e9a 100644 --- a/system/database/drivers/sqlite/sqlite_utility.php +++ b/system/database/drivers/sqlite/sqlite_utility.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/sqlite3/sqlite3_driver.php b/system/database/drivers/sqlite3/sqlite3_driver.php index 4d131c31a..30c38ec47 100644 --- a/system/database/drivers/sqlite3/sqlite3_driver.php +++ b/system/database/drivers/sqlite3/sqlite3_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/sqlite3/sqlite3_forge.php b/system/database/drivers/sqlite3/sqlite3_forge.php index 6aa42cf4b..0eed05908 100644 --- a/system/database/drivers/sqlite3/sqlite3_forge.php +++ b/system/database/drivers/sqlite3/sqlite3_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/sqlite3/sqlite3_result.php b/system/database/drivers/sqlite3/sqlite3_result.php index 87ad64d7a..fb2fc4e89 100644 --- a/system/database/drivers/sqlite3/sqlite3_result.php +++ b/system/database/drivers/sqlite3/sqlite3_result.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/sqlite3/sqlite3_utility.php b/system/database/drivers/sqlite3/sqlite3_utility.php index 565d7d954..49dcf3d12 100644 --- a/system/database/drivers/sqlite3/sqlite3_utility.php +++ b/system/database/drivers/sqlite3/sqlite3_utility.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/database/drivers/sqlsrv/sqlsrv_driver.php b/system/database/drivers/sqlsrv/sqlsrv_driver.php index 09e6b8c9a..a723b78bc 100644 --- a/system/database/drivers/sqlsrv/sqlsrv_driver.php +++ b/system/database/drivers/sqlsrv/sqlsrv_driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.3 @@ -48,6 +48,18 @@ class CI_DB_sqlsrv_driver extends CI_DB { */ public $dbdriver = 'sqlsrv'; + /** + * Scrollable flag + * + * Determines what cursor type to use when executing queries. + * + * FALSE or SQLSRV_CURSOR_FORWARD would increase performance, + * but would disable num_rows() (and possibly insert_id()) + * + * @var mixed + */ + public $scrollable; + // -------------------------------------------------------------------- /** @@ -70,6 +82,27 @@ class CI_DB_sqlsrv_driver extends CI_DB { // -------------------------------------------------------------------- /** + * Class constructor + * + * @param array $params + * @return void + */ + public function __construct($params) + { + parent::__construct($params); + + // This is only supported as of SQLSRV 3.0 + if ($this->scrollable === NULL) + { + $this->scrollable = defined('SQLSRV_CURSOR_CLIENT_BUFFERED') + ? SQLSRV_CURSOR_CLIENT_BUFFERED + : FALSE; + } + } + + // -------------------------------------------------------------------- + + /** * Database connection * * @param bool $pooling @@ -154,9 +187,9 @@ class CI_DB_sqlsrv_driver extends CI_DB { */ protected function _execute($sql) { - return ($this->is_write_type($sql) && stripos($sql, 'INSERT') === FALSE) + return ($this->scrollable === FALSE OR $this->is_write_type($sql)) ? sqlsrv_query($this->conn_id, $sql) - : sqlsrv_query($this->conn_id, $sql, NULL, array('Scrollable' => SQLSRV_CURSOR_STATIC)); + : sqlsrv_query($this->conn_id, $sql, NULL, array('Scrollable' => $this->scrollable)); } // -------------------------------------------------------------------- diff --git a/system/database/drivers/sqlsrv/sqlsrv_forge.php b/system/database/drivers/sqlsrv/sqlsrv_forge.php index cced5b98f..79386843f 100644 --- a/system/database/drivers/sqlsrv/sqlsrv_forge.php +++ b/system/database/drivers/sqlsrv/sqlsrv_forge.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.3 diff --git a/system/database/drivers/sqlsrv/sqlsrv_result.php b/system/database/drivers/sqlsrv/sqlsrv_result.php index 3c8148f1b..71c429e51 100644 --- a/system/database/drivers/sqlsrv/sqlsrv_result.php +++ b/system/database/drivers/sqlsrv/sqlsrv_result.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -39,15 +39,45 @@ defined('BASEPATH') OR exit('No direct script access allowed'); class CI_DB_sqlsrv_result extends CI_DB_result { /** + * Scrollable flag + * + * @var mixed + */ + public $scrollable; + + // -------------------------------------------------------------------- + + /** + * Constructor + * + * @param object $driver_object + * @return void + */ + public function __construct(&$driver_object) + { + parent::__construct($driver_object); + + $this->scrollable = $driver_object->scrollable; + } + + // -------------------------------------------------------------------- + + /** * Number of rows in the result set * * @return int */ public function num_rows() { + // sqlsrv_num_rows() doesn't work with the FORWARD and DYNAMIC cursors (FALSE is the same as FORWARD) + if ( ! in_array($this->scrollable, array(FALSE, SQLSRV_CURSOR_FORWARD, SQLSRV_CURSOR_DYNAMIC), TRUE)) + { + return parent::num_rows(); + } + return is_int($this->num_rows) ? $this->num_rows - : $this->num_rows = @sqlsrv_num_rows($this->result_id); + : $this->num_rows = sqlsrv_num_rows($this->result_id); } // -------------------------------------------------------------------- diff --git a/system/database/drivers/sqlsrv/sqlsrv_utility.php b/system/database/drivers/sqlsrv/sqlsrv_utility.php index d75e6a6da..b6a1fe449 100644 --- a/system/database/drivers/sqlsrv/sqlsrv_utility.php +++ b/system/database/drivers/sqlsrv/sqlsrv_utility.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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.3 diff --git a/system/helpers/array_helper.php b/system/helpers/array_helper.php index 7b62da68f..1cdbcdfcf 100644 --- a/system/helpers/array_helper.php +++ b/system/helpers/array_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php index 29911dc17..13926774e 100644 --- a/system/helpers/captcha_helper.php +++ b/system/helpers/captcha_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -82,7 +82,7 @@ if ( ! function_exists('create_captcha')) } if ($img_path === '' OR $img_url === '' - OR ! @is_dir($img_path) OR ! is_writeable($img_path) + OR ! @is_dir($img_path) OR ! is_really_writable($img_path) OR ! extension_loaded('gd')) { return FALSE; @@ -126,9 +126,9 @@ if ( ! function_exists('create_captcha')) // Determine angle and position // ----------------------------------- $length = strlen($word); - $angle = ($length >= 6) ? rand(-($length-6), ($length-6)) : 0; - $x_axis = rand(6, (360/$length)-16); - $y_axis = ($angle >= 0) ? rand($img_height, $img_width) : rand(6, $img_height); + $angle = ($length >= 6) ? mt_rand(-($length-6), ($length-6)) : 0; + $x_axis = mt_rand(6, (360/$length)-16); + $y_axis = ($angle >= 0) ? mt_rand($img_height, $img_width) : mt_rand(6, $img_height); // Create image // PHP.net recommends imagecreatetruecolor(), but it isn't always available @@ -183,13 +183,13 @@ if ( ! function_exists('create_captcha')) if ($use_font === FALSE) { $font_size = 5; - $x = rand(0, $img_width / ($length / 3)); + $x = mt_rand(0, $img_width / ($length / 3)); $y = 0; } else { $font_size = 16; - $x = rand(0, $img_width / ($length / 1.5)); + $x = mt_rand(0, $img_width / ($length / 1.5)); $y = $font_size + 2; } @@ -197,13 +197,13 @@ if ( ! function_exists('create_captcha')) { if ($use_font === FALSE) { - $y = rand(0 , $img_height / 2); + $y = mt_rand(0 , $img_height / 2); imagestring($im, $font_size, $x, $y, $word[$i], $colors['text']); $x += ($font_size * 2); } else { - $y = rand($img_height / 2, $img_height - 3); + $y = mt_rand($img_height / 2, $img_height - 3); imagettftext($im, $font_size, $angle, $x, $y, $colors['text'], $font_path, $word[$i]); $x += $font_size; } @@ -215,12 +215,12 @@ if ( ! function_exists('create_captcha')) // ----------------------------------- // Generate the image // ----------------------------------- - $img_name = $now.'.jpg'; - ImageJPEG($im, $img_path.$img_name); - $img = '<img src="'.$img_url.$img_name.'" style="width: '.$img_width.'; height: '.$img_height .'; border: 0;" alt=" " />'; + $img_filename = $now.'.jpg'; + ImageJPEG($im, $img_path.$img_filename); + $img = '<img src="'.$img_url.$img_filename.'" style="width: '.$img_width.'; height: '.$img_height .'; border: 0;" alt=" " />'; ImageDestroy($im); - return array('word' => $word, 'time' => $now, 'image' => $img); + return array('word' => $word, 'time' => $now, 'image' => $img, 'filename' => $img_filename); } } diff --git a/system/helpers/cookie_helper.php b/system/helpers/cookie_helper.php index e5cf6b1d6..a08bec398 100644 --- a/system/helpers/cookie_helper.php +++ b/system/helpers/cookie_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -56,11 +56,10 @@ if ( ! function_exists('set_cookie')) * @param bool true makes the cookie accessible via http(s) only (no javascript) * @return void */ - function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE) + function set_cookie($name, $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE) { // Set the config file options - $CI =& get_instance(); - $CI->input->set_cookie($name, $value, $expire, $domain, $path, $prefix, $secure, $httponly); + get_instance()->input->set_cookie($name, $value, $expire, $domain, $path, $prefix, $secure, $httponly); } } @@ -75,11 +74,11 @@ if ( ! function_exists('get_cookie')) * @param bool * @return mixed */ - function get_cookie($index = '', $xss_clean = FALSE) + function get_cookie($index, $xss_clean = NULL) { - $CI =& get_instance(); + is_bool($xss_clean) OR $xss_clean = (config_item('global_xss_filtering') === TRUE); $prefix = isset($_COOKIE[$index]) ? '' : config_item('cookie_prefix'); - return $CI->input->cookie($prefix.$index, $xss_clean); + return get_instance()->input->cookie($prefix.$index, $xss_clean); } } @@ -96,7 +95,7 @@ if ( ! function_exists('delete_cookie')) * @param string the cookie prefix * @return void */ - function delete_cookie($name = '', $domain = '', $path = '/', $prefix = '') + function delete_cookie($name, $domain = '', $path = '/', $prefix = '') { set_cookie($name, '', '', $domain, $path, $prefix); } diff --git a/system/helpers/date_helper.php b/system/helpers/date_helper.php index c3a8d3c9e..56e5c46aa 100644 --- a/system/helpers/date_helper.php +++ b/system/helpers/date_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/helpers/directory_helper.php b/system/helpers/directory_helper.php index 81ffd1579..84ad35894 100644 --- a/system/helpers/directory_helper.php +++ b/system/helpers/directory_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -69,7 +69,7 @@ if ( ! function_exists('directory_map')) continue; } - @is_dir($source_dir.$file) AND $file .= DIRECTORY_SEPARATOR; + @is_dir($source_dir.$file) && $file .= DIRECTORY_SEPARATOR; if (($directory_depth < 1 OR $new_depth > 0) && @is_dir($source_dir.$file)) { diff --git a/system/helpers/download_helper.php b/system/helpers/download_helper.php index 4fe6a0e88..ffe5ff997 100644 --- a/system/helpers/download_helper.php +++ b/system/helpers/download_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -120,7 +120,7 @@ if ( ! function_exists('force_download')) // Clean output buffer if (ob_get_level() !== 0 && @ob_end_clean() === FALSE) { - ob_clean(); + @ob_clean(); } // Generate the server headers diff --git a/system/helpers/email_helper.php b/system/helpers/email_helper.php index d2e6f5491..e93f35705 100644 --- a/system/helpers/email_helper.php +++ b/system/helpers/email_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php index 4b45a62d0..575b87479 100644 --- a/system/helpers/file_helper.php +++ b/system/helpers/file_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -79,11 +79,19 @@ if ( ! function_exists('write_file')) } flock($fp, LOCK_EX); - fwrite($fp, $data); + + for ($written = 0, $length = strlen($data); $written < $length; $written += $result) + { + if (($result = fwrite($fp, substr($data, $written))) === FALSE) + { + break; + } + } + flock($fp, LOCK_UN); fclose($fp); - return TRUE; + return is_int($result); } } @@ -290,8 +298,7 @@ if ( ! function_exists('get_file_info')) $fileinfo['readable'] = is_readable($file); break; case 'writable': - // There are known problems using is_weritable on IIS. It may not be reliable - consider fileperms() - $fileinfo['writable'] = is_writable($file); + $fileinfo['writable'] = is_really_writable($file); break; case 'executable': $fileinfo['executable'] = is_executable($file); diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php index 146c0f588..40852faf8 100644 --- a/system/helpers/form_helper.php +++ b/system/helpers/form_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -316,7 +316,7 @@ if ( ! function_exists('form_dropdown')) { isset($name['options']) OR $name['options'] = array(); isset($name['selected']) OR $name['selected'] = array(); - isset($name['extra']) OR $name['extra'] = array(); + isset($name['extra']) OR $name['extra'] = ''; return form_dropdown($name['name'], $name['options'], $name['selected'], $name['extra']); } @@ -329,10 +329,7 @@ if ( ! function_exists('form_dropdown')) $selected = array($_POST[$name]); } - if ($extra != '') - { - $extra = ' '.$extra; - } + $extra = _attributes_to_string($extra); $multiple = (count($selected) > 1 && strpos($extra, 'multiple') === FALSE) ? ' multiple="multiple"' : ''; @@ -675,37 +672,33 @@ if ( ! function_exists('set_select')) */ function set_select($field = '', $value = '', $default = FALSE) { - $OBJ =& _get_validation_object(); + $CI =& get_instance(); - if ($OBJ === FALSE) + if (isset($CI->form_validation) && is_object($CI->form_validation) && $CI->form_validation->has_rule($field)) { - if ( ! isset($_POST[$field])) - { - if (count($_POST) === 0 && $default === TRUE) - { - return ' selected="selected"'; - } - return ''; - } - - $field = $_POST[$field]; + return $CI->form_validation->set_select($field, $value, $default); + } + elseif (($input = $CI->input->post($field, FALSE)) === NULL) + { + return ($default === TRUE) ? ' selected="selected"' : ''; + } - if (is_array($field)) + $value = (string) $value; + if (is_array($input)) + { + // Note: in_array('', array(0)) returns TRUE, do not use it + foreach ($input as &$v) { - if ( ! in_array($value, $field)) + if ($value === $v) { - return ''; + return ' selected="selected"'; } } - elseif (($field == '' OR $value == '') OR $field !== $value) - { - return ''; - } - return ' selected="selected"'; + return ''; } - return $OBJ->set_select($field, $value, $default); + return ($input === $value) ? ' selected="selected"' : ''; } } @@ -726,37 +719,33 @@ if ( ! function_exists('set_checkbox')) */ function set_checkbox($field = '', $value = '', $default = FALSE) { - $OBJ =& _get_validation_object(); + $CI =& get_instance(); - if ($OBJ === FALSE) + if (isset($CI->form_validation) && is_object($CI->form_validation) && $CI->form_validation->has_rule($field)) { - if ( ! isset($_POST[$field])) - { - if (count($_POST) === 0 && $default === TRUE) - { - return ' checked="checked"'; - } - return ''; - } - - $field = $_POST[$field]; + return $CI->form_validation->set_checkbox($field, $value, $default); + } + elseif (($input = $CI->input->post($field, FALSE)) === NULL) + { + return ($default === TRUE) ? ' checked="checked"' : ''; + } - if (is_array($field)) + $value = (string) $value; + if (is_array($input)) + { + // Note: in_array('', array(0)) returns TRUE, do not use it + foreach ($input as &$v) { - if ( ! in_array($value, $field)) + if ($value === $v) { - return ''; + return ' checked="checked"'; } } - elseif (($field == '' OR $value == '') OR $field !== $value) - { - return ''; - } - return ' checked="checked"'; + return ''; } - return $OBJ->set_checkbox($field, $value, $default); + return ($input === $value) ? ' checked="checked"' : ''; } } @@ -770,47 +759,25 @@ if ( ! function_exists('set_radio')) * Let's you set the selected value of a radio field via info in the POST array. * If Form Validation is active it retrieves the info from the validation class * - * @param string - * @param string - * @param bool + * @param string $field + * @param string $value + * @param bool $default * @return string */ function set_radio($field = '', $value = '', $default = FALSE) { - $OBJ =& _get_validation_object(); + $CI =& get_instance(); - if ($OBJ === FALSE) + if (isset($CI->form_validation) && is_object($CI->form_validation) && $CI->form_validation->has_rule($field)) { - if ( ! isset($_POST[$field])) - { - if (count($_POST) === 0 && $default === TRUE) - { - return ' checked="checked"'; - } - return ''; - } - - $field = $_POST[$field]; - - if (is_array($field)) - { - if ( ! in_array($value, $field)) - { - return ''; - } - } - else - { - if (($field == '' OR $value == '') OR $field !== $value) - { - return ''; - } - } - - return ' checked="checked"'; + return $CI->form_validation->set_radio($field, $value, $default); + } + elseif (($input = $CI->input->post($field, FALSE)) === NULL) + { + return ($default === TRUE) ? ' checked="checked"' : ''; } - return $OBJ->set_radio($field, $value, $default); + return ($input === (string) $value) ? ' checked="checked"' : ''; } } diff --git a/system/helpers/html_helper.php b/system/helpers/html_helper.php index ece39584b..604d1144a 100644 --- a/system/helpers/html_helper.php +++ b/system/helpers/html_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -199,15 +199,13 @@ if ( ! function_exists('img')) { if ($k === 'src' && strpos($v, '://') === FALSE) { - $CI =& get_instance(); - if ($index_page === TRUE) { - $img .= ' src="'.$CI->config->site_url($v).'"'; + $img .= ' src="'.get_instance()->config->site_url($v).'"'; } else { - $img .= ' src="'.$CI->config->slash_item('base_url').$v.'"'; + $img .= ' src="'.get_instance()->config->slash_item('base_url').$v.'"'; } } else diff --git a/system/helpers/inflector_helper.php b/system/helpers/inflector_helper.php index a133cdddb..210d0fdfd 100644 --- a/system/helpers/inflector_helper.php +++ b/system/helpers/inflector_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/helpers/language_helper.php b/system/helpers/language_helper.php index 4d571a71c..baea849b1 100644 --- a/system/helpers/language_helper.php +++ b/system/helpers/language_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -52,8 +52,7 @@ if ( ! function_exists('lang')) */ function lang($line, $for = '', $attributes = array()) { - $CI =& get_instance(); - $line = $CI->lang->line($line); + $line = get_instance()->lang->line($line); if ($for !== '') { diff --git a/system/helpers/number_helper.php b/system/helpers/number_helper.php index 5ebdc946f..7d3bb2797 100644 --- a/system/helpers/number_helper.php +++ b/system/helpers/number_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/helpers/path_helper.php b/system/helpers/path_helper.php index 3f4f7e9fb..ae1f0bf33 100644 --- a/system/helpers/path_helper.php +++ b/system/helpers/path_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/helpers/security_helper.php b/system/helpers/security_helper.php index 4bb94a201..848cf4623 100644 --- a/system/helpers/security_helper.php +++ b/system/helpers/security_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -49,8 +49,7 @@ if ( ! function_exists('xss_clean')) */ function xss_clean($str, $is_image = FALSE) { - $CI =& get_instance(); - return $CI->security->xss_clean($str, $is_image); + return get_instance()->security->xss_clean($str, $is_image); } } @@ -66,8 +65,7 @@ if ( ! function_exists('sanitize_filename')) */ function sanitize_filename($filename) { - $CI =& get_instance(); - return $CI->security->sanitize_filename($filename); + return get_instance()->security->sanitize_filename($filename); } } @@ -107,8 +105,7 @@ if ( ! function_exists('strip_image_tags')) */ function strip_image_tags($str) { - $CI =& get_instance(); - return $CI->security->strip_image_tags($str); + return get_instance()->security->strip_image_tags($str); } } diff --git a/system/helpers/smiley_helper.php b/system/helpers/smiley_helper.php index d9a693493..57debffa9 100644 --- a/system/helpers/smiley_helper.php +++ b/system/helpers/smiley_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/helpers/string_helper.php b/system/helpers/string_helper.php index 12f818fda..a1daa1efe 100644 --- a/system/helpers/string_helper.php +++ b/system/helpers/string_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -188,7 +188,7 @@ if ( ! function_exists('random_string')) * * Useful for generating passwords or hashes. * - * @param string type of random string. basic, alpha, alunum, numeric, nozero, unique, md5, encrypt and sha1 + * @param string type of random string. basic, alpha, alnum, numeric, nozero, unique, md5, encrypt and sha1 * @param int number of characters * @return string */ diff --git a/system/helpers/text_helper.php b/system/helpers/text_helper.php index bfbdc2f00..45e8ae760 100644 --- a/system/helpers/text_helper.php +++ b/system/helpers/text_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -127,7 +127,7 @@ if ( ! function_exists('ascii_to_entities')) function ascii_to_entities($str) { $out = ''; - for ($i = 0, $s = strlen($str), $count = 1, $temp = array(); $i < $s; $i++) + for ($i = 0, $s = strlen($str) - 1, $count = 1, $temp = array(); $i <= $s; $i++) { $ordinal = ord($str[$i]); @@ -164,6 +164,11 @@ if ( ! function_exists('ascii_to_entities')) $count = 1; $temp = array(); } + // If this is the last iteration, just output whatever we have + elseif ($i === $s) + { + $out .= '&#'.implode(';', $temp).';'; + } } } @@ -329,25 +334,17 @@ if ( ! function_exists('highlight_phrase')) * * Highlights a phrase within a text string * - * @param string the text string - * @param string the phrase you'd like to highlight - * @param string the openging tag to precede the phrase with - * @param string the closing tag to end the phrase with + * @param string $str the text string + * @param string $phrase the phrase you'd like to highlight + * @param string $tag_open the openging tag to precede the phrase with + * @param string $tag_close the closing tag to end the phrase with * @return string */ - function highlight_phrase($str, $phrase, $tag_open = '<strong>', $tag_close = '</strong>') + function highlight_phrase($str, $phrase, $tag_open = '<mark>', $tag_close = '</mark>') { - if ($str === '') - { - return ''; - } - - if ($phrase !== '') - { - return preg_replace('/('.preg_quote($phrase, '/').')/i', $tag_open.'\\1'.$tag_close, $str); - } - - return $str; + return ($str !== '' && $phrase !== '') + ? preg_replace('/('.preg_quote($phrase, '/').')/i', $tag_open.'\\1'.$tag_close, $str) + : $str; } } diff --git a/system/helpers/typography_helper.php b/system/helpers/typography_helper.php index e4a8d3bc0..cd3827c8b 100644 --- a/system/helpers/typography_helper.php +++ b/system/helpers/typography_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php index fbb4a1b24..a9790e5c4 100644 --- a/system/helpers/url_helper.php +++ b/system/helpers/url_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -52,14 +52,7 @@ if ( ! function_exists('site_url')) */ function site_url($uri = '', $protocol = NULL) { - $uri = get_instance()->config->site_url($uri); - - if (isset($protocol)) - { - return $protocol.substr($uri, strpos($uri, '://')); - } - - return $uri; + return get_instance()->config->site_url($uri, $protocol); } } @@ -80,14 +73,7 @@ if ( ! function_exists('base_url')) */ function base_url($uri = '', $protocol = NULL) { - $uri = get_instance()->config->base_url($uri); - - if (isset($protocol)) - { - return $protocol.substr($uri, strpos($uri, '://')); - } - - return $uri; + return get_instance()->config->base_url($uri, $protocol); } } @@ -123,8 +109,7 @@ if ( ! function_exists('uri_string')) */ function uri_string() { - $CI =& get_instance(); - return $CI->uri->uri_string(); + return get_instance()->uri->uri_string(); } } @@ -141,8 +126,7 @@ if ( ! function_exists('index_page')) */ function index_page() { - $CI =& get_instance(); - return $CI->config->item('index_page'); + return get_instance()->config->item('index_page'); } } @@ -548,11 +532,16 @@ if ( ! function_exists('redirect')) } elseif ($method !== 'refresh' && (empty($code) OR ! is_numeric($code))) { - // Reference: http://en.wikipedia.org/wiki/Post/Redirect/Get - $code = (isset($_SERVER['REQUEST_METHOD'], $_SERVER['SERVER_PROTOCOL']) - && $_SERVER['REQUEST_METHOD'] === 'POST' - && $_SERVER['SERVER_PROTOCOL'] === 'HTTP/1.1') - ? 303 : 302; + if (isset($_SERVER['SERVER_PROTOCOL'], $_SERVER['REQUEST_METHOD']) && $_SERVER['SERVER_PROTOCOL'] === 'HTTP/1.1') + { + $code = ($_SERVER['REQUEST_METHOD'] !== 'GET') + ? 303 // reference: http://en.wikipedia.org/wiki/Post/Redirect/Get + : 307; + } + else + { + $code = 302; + } } switch ($method) diff --git a/system/helpers/xml_helper.php b/system/helpers/xml_helper.php index 84069a689..4c38b6988 100644 --- a/system/helpers/xml_helper.php +++ b/system/helpers/xml_helper.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/language/english/calendar_lang.php b/system/language/english/calendar_lang.php index 4c2aa8c86..0fc949476 100644 --- a/system/language/english/calendar_lang.php +++ b/system/language/english/calendar_lang.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/language/english/date_lang.php b/system/language/english/date_lang.php index 3f9f7a0d3..f0822d4bb 100644 --- a/system/language/english/date_lang.php +++ b/system/language/english/date_lang.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/language/english/db_lang.php b/system/language/english/db_lang.php index 62de80337..4e2b808a7 100644 --- a/system/language/english/db_lang.php +++ b/system/language/english/db_lang.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/language/english/email_lang.php b/system/language/english/email_lang.php index 1eec470e0..bcd0cee70 100644 --- a/system/language/english/email_lang.php +++ b/system/language/english/email_lang.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/language/english/form_validation_lang.php b/system/language/english/form_validation_lang.php index 7c0277c25..9156ebef0 100644 --- a/system/language/english/form_validation_lang.php +++ b/system/language/english/form_validation_lang.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/language/english/ftp_lang.php b/system/language/english/ftp_lang.php index ae4086ff3..8453653a8 100644 --- a/system/language/english/ftp_lang.php +++ b/system/language/english/ftp_lang.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -26,18 +26,18 @@ */ defined('BASEPATH') OR exit('No direct script access allowed'); -$lang['ftp_no_connection'] = 'Unable to locate a valid connection ID. Please make sure you are connected before peforming any file routines.'; +$lang['ftp_no_connection'] = 'Unable to locate a valid connection ID. Please make sure you are connected before performing any file routines.'; $lang['ftp_unable_to_connect'] = 'Unable to connect to your FTP server using the supplied hostname.'; $lang['ftp_unable_to_login'] = 'Unable to login to your FTP server. Please check your username and password.'; -$lang['ftp_unable_to_makdir'] = 'Unable to create the directory you have specified.'; +$lang['ftp_unable_to_mkdir'] = 'Unable to create the directory you have specified.'; $lang['ftp_unable_to_changedir'] = 'Unable to change directories.'; -$lang['ftp_unable_to_chmod'] = 'Unable to set file permissions. Please check your path. Note: This feature is only available in PHP 5 or higher.'; +$lang['ftp_unable_to_chmod'] = 'Unable to set file permissions. Please check your path.'; $lang['ftp_unable_to_upload'] = 'Unable to upload the specified file. Please check your path.'; $lang['ftp_unable_to_download'] = 'Unable to download the specified file. Please check your path.'; -$lang['ftp_no_source_file'] = 'Unable to locate the source file. Please check your path.'; +$lang['ftp_no_source_file'] = 'Unable to locate the source file. Please check your path.'; $lang['ftp_unable_to_rename'] = 'Unable to rename the file.'; $lang['ftp_unable_to_delete'] = 'Unable to delete the file.'; -$lang['ftp_unable_to_move'] = 'Unable to move the file. Please make sure the destination directory exists.'; +$lang['ftp_unable_to_move'] = 'Unable to move the file. Please make sure the destination directory exists.'; /* End of file ftp_lang.php */ /* Location: ./system/language/english/ftp_lang.php */
\ No newline at end of file diff --git a/system/language/english/imglib_lang.php b/system/language/english/imglib_lang.php index a27d31651..c1c95bea6 100644 --- a/system/language/english/imglib_lang.php +++ b/system/language/english/imglib_lang.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/language/english/migration_lang.php b/system/language/english/migration_lang.php index 54f9e769b..8e8b606c0 100644 --- a/system/language/english/migration_lang.php +++ b/system/language/english/migration_lang.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 3.0 diff --git a/system/language/english/number_lang.php b/system/language/english/number_lang.php index 2f37358d7..eb78931b1 100644 --- a/system/language/english/number_lang.php +++ b/system/language/english/number_lang.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/language/english/profiler_lang.php b/system/language/english/profiler_lang.php index 0ed5f4cb0..af3b0c808 100644 --- a/system/language/english/profiler_lang.php +++ b/system/language/english/profiler_lang.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/language/english/unit_test_lang.php b/system/language/english/unit_test_lang.php index ea986ec36..d7a984dee 100644 --- a/system/language/english/unit_test_lang.php +++ b/system/language/english/unit_test_lang.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/language/english/upload_lang.php b/system/language/english/upload_lang.php index 5b07c4e30..2b60a064c 100644 --- a/system/language/english/upload_lang.php +++ b/system/language/english/upload_lang.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/libraries/Cache/Cache.php b/system/libraries/Cache/Cache.php index 537897eaf..f9768b10c 100644 --- a/system/libraries/Cache/Cache.php +++ b/system/libraries/Cache/Cache.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 @@ -150,14 +150,15 @@ class CI_Cache extends CI_Driver_Library { /** * Cache Save * - * @param string $id Cache ID - * @param mixed $data Data to store - * @param int $ttl = 60 Cache TTL (in seconds) + * @param string $id Cache ID + * @param mixed $data Data to store + * @param int $ttl Cache TTL (in seconds) + * @param bool $raw Whether to store the raw value * @return bool TRUE on success, FALSE on failure */ - public function save($id, $data, $ttl = 60) + public function save($id, $data, $ttl = 60, $raw = FALSE) { - return $this->{$this->_adapter}->save($this->key_prefix.$id, $data, $ttl); + return $this->{$this->_adapter}->save($this->key_prefix.$id, $data, $ttl, $raw); } // ------------------------------------------------------------------------ @@ -176,6 +177,34 @@ class CI_Cache extends CI_Driver_Library { // ------------------------------------------------------------------------ /** + * Increment a raw value + * + * @param string $id Cache ID + * @param int $offset Step/value to add + * @return mixed New value on success or FALSE on failure + */ + public function increment($id, $offset = 1) + { + return $this->{$this->_adapter}->increment($id, $offset); + } + + // ------------------------------------------------------------------------ + + /** + * Decrement a raw value + * + * @param string $id Cache ID + * @param int $offset Step/value to reduce by + * @return mixed New value on success or FALSE on failure + */ + public function decrement($id, $offset = 1) + { + return $this->{$this->_adapter}->decrement($id, $offset); + } + + // ------------------------------------------------------------------------ + + /** * Clean the cache * * @return bool TRUE on success, FALSE on failure diff --git a/system/libraries/Cache/drivers/Cache_apc.php b/system/libraries/Cache/drivers/Cache_apc.php index a84e7d2d3..d062103bd 100644 --- a/system/libraries/Cache/drivers/Cache_apc.php +++ b/system/libraries/Cache/drivers/Cache_apc.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 @@ -51,8 +51,14 @@ class CI_Cache_apc extends CI_Driver { $success = FALSE; $data = apc_fetch($id, $success); - return ($success === TRUE && is_array($data)) - ? unserialize($data[0]) : FALSE; + if ($success === TRUE) + { + return is_array($data) + ? unserialize($data[0]) + : $data; + } + + return FALSE; } // ------------------------------------------------------------------------ @@ -60,16 +66,21 @@ class CI_Cache_apc extends CI_Driver { /** * Cache Save * - * @param string Unique Key - * @param mixed Data to store - * @param int Length of time (in seconds) to cache the data - * - * @return bool true on success/false on failure + * @param string $id Cache ID + * @param mixed $data Data to store + * @param int $ttol Length of time (in seconds) to cache the data + * @param bool $raw Whether to store the raw value + * @return bool TRUE on success, FALSE on failure */ - public function save($id, $data, $ttl = 60) + public function save($id, $data, $ttl = 60, $raw = FALSE) { $ttl = (int) $ttl; - return apc_store($id, array(serialize($data), time(), $ttl), $ttl); + + return apc_store( + $id, + ($raw === TRUE ? $data : array(serialize($data), time(), $ttl)), + $ttl + ); } // ------------------------------------------------------------------------ @@ -88,6 +99,34 @@ class CI_Cache_apc extends CI_Driver { // ------------------------------------------------------------------------ /** + * Increment a raw value + * + * @param string $id Cache ID + * @param int $offset Step/value to add + * @return mixed New value on success or FALSE on failure + */ + public function increment($id, $offset = 1) + { + return apc_inc($id, $offset); + } + + // ------------------------------------------------------------------------ + + /** + * Decrement a raw value + * + * @param string $id Cache ID + * @param int $offset Step/value to reduce by + * @return mixed New value on success or FALSE on failure + */ + public function decrement($id, $offset = 1) + { + return apc_dec($id, $offset); + } + + // ------------------------------------------------------------------------ + + /** * Clean the cache * * @return bool false on failure/true on success diff --git a/system/libraries/Cache/drivers/Cache_dummy.php b/system/libraries/Cache/drivers/Cache_dummy.php index d9af3773b..521b9e6dd 100644 --- a/system/libraries/Cache/drivers/Cache_dummy.php +++ b/system/libraries/Cache/drivers/Cache_dummy.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 @@ -58,9 +58,10 @@ class CI_Cache_dummy extends CI_Driver { * @param string Unique Key * @param mixed Data to store * @param int Length of time (in seconds) to cache the data + * @param bool Whether to store the raw value * @return bool TRUE, Simulating success */ - public function save($id, $data, $ttl = 60) + public function save($id, $data, $ttl = 60, $raw = FALSE) { return TRUE; } @@ -81,6 +82,34 @@ class CI_Cache_dummy extends CI_Driver { // ------------------------------------------------------------------------ /** + * Increment a raw value + * + * @param string $id Cache ID + * @param int $offset Step/value to add + * @return mixed New value on success or FALSE on failure + */ + public function increment($id, $offset = 1) + { + return TRUE; + } + + // ------------------------------------------------------------------------ + + /** + * Decrement a raw value + * + * @param string $id Cache ID + * @param int $offset Step/value to reduce by + * @return mixed New value on success or FALSE on failure + */ + public function decrement($id, $offset = 1) + { + return TRUE; + } + + // ------------------------------------------------------------------------ + + /** * Clean the cache * * @return bool TRUE, simulating success diff --git a/system/libraries/Cache/drivers/Cache_file.php b/system/libraries/Cache/drivers/Cache_file.php index 769bd5a26..c6aa848fe 100644 --- a/system/libraries/Cache/drivers/Cache_file.php +++ b/system/libraries/Cache/drivers/Cache_file.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 @@ -62,25 +62,13 @@ class CI_Cache_file extends CI_Driver { /** * Fetch from cache * - * @param mixed unique key id - * @return mixed data on success/false on failure + * @param string $id Cache ID + * @return mixed Data on success, FALSE on failure */ public function get($id) { - if ( ! file_exists($this->_cache_path.$id)) - { - return FALSE; - } - - $data = unserialize(file_get_contents($this->_cache_path.$id)); - - if ($data['ttl'] > 0 && time() > $data['time'] + $data['ttl']) - { - unlink($this->_cache_path.$id); - return FALSE; - } - - return $data['data']; + $data = $this->_get($id); + return is_array($data) ? $data['data'] : FALSE; } // ------------------------------------------------------------------------ @@ -88,13 +76,13 @@ class CI_Cache_file extends CI_Driver { /** * Save into cache * - * @param string unique key - * @param mixed data to store - * @param int length of time (in seconds) the cache is valid - * - Default is 60 seconds - * @return bool true on success/false on failure + * @param string $id Cache ID + * @param mixed $data Data to store + * @param int $ttl Time to live in seconds + * @param bool $raw Whether to store the raw value (unused) + * @return bool TRUE on success, FALSE on failure */ - public function save($id, $data, $ttl = 60) + public function save($id, $data, $ttl = 60, $raw = FALSE) { $contents = array( 'time' => time(), @@ -127,6 +115,54 @@ class CI_Cache_file extends CI_Driver { // ------------------------------------------------------------------------ /** + * Increment a raw value + * + * @param string $id Cache ID + * @param int $offset Step/value to add + * @return New value on success, FALSE on failure + */ + public function increment($id, $offset = 1) + { + $data = $this->_get($id); + + if ($data === FALSE OR ! is_int($data['data'])) + { + return FALSE; + } + + $new_value = $data['data'] + $offset; + return $this->save($id, $new_value, $data['ttl']) + ? $new_value + : FALSE; + } + + // ------------------------------------------------------------------------ + + /** + * Decrement a raw value + * + * @param string $id Cache ID + * @param int $offset Step/value to reduce by + * @return New value on success, FALSE on failure + */ + public function decrement($id, $offset = 1) + { + $data = $this->_get($id); + + if ($data === FALSE OR ! is_int($data['data'])) + { + return FALSE; + } + + $new_value = $data['data'] - $offset; + return $this->save($id, $new_value, $data['ttl']) + ? $new_value + : FALSE; + } + + // ------------------------------------------------------------------------ + + /** * Clean the Cache * * @return bool false on failure/true on success @@ -200,6 +236,34 @@ class CI_Cache_file extends CI_Driver { return is_really_writable($this->_cache_path); } + // ------------------------------------------------------------------------ + + /** + * Get all data + * + * Internal method to get all the relevant data about a cache item + * + * @param string $id Cache ID + * @return mixed Data array on success or FALSE on failure + */ + protected function _get($id) + { + if ( ! file_exists($this->_cache_path.$id)) + { + return FALSE; + } + + $data = unserialize(file_get_contents($this->_cache_path.$id)); + + if ($data['ttl'] > 0 && time() > $data['time'] + $data['ttl']) + { + unlink($this->_cache_path.$id); + return FALSE; + } + + return $data; + } + } /* End of file Cache_file.php */ diff --git a/system/libraries/Cache/drivers/Cache_memcached.php b/system/libraries/Cache/drivers/Cache_memcached.php index d2a3a489d..bed606afb 100644 --- a/system/libraries/Cache/drivers/Cache_memcached.php +++ b/system/libraries/Cache/drivers/Cache_memcached.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 @@ -60,14 +60,14 @@ class CI_Cache_memcached extends CI_Driver { /** * Fetch from cache * - * @param mixed unique key id - * @return mixed data on success/false on failure + * @param string $id Cache ID + * @return mixed Data on success, FALSE on failure */ public function get($id) { $data = $this->_memcached->get($id); - return is_array($data) ? $data[0] : FALSE; + return is_array($data) ? $data[0] : $data; } // ------------------------------------------------------------------------ @@ -75,20 +75,26 @@ class CI_Cache_memcached extends CI_Driver { /** * Save * - * @param string unique identifier - * @param mixed data being cached - * @param int time to live - * @return bool true on success, false on failure + * @param string $id Cache ID + * @param mixed $data Data being cached + * @param int $ttl Time to live + * @param bool $raw Whether to store the raw value + * @return bool TRUE on success, FALSE on failure */ - public function save($id, $data, $ttl = 60) + public function save($id, $data, $ttl = 60, $raw = FALSE) { + if ($raw !== TRUE) + { + $data = array($data, time(), $ttl); + } + if (get_class($this->_memcached) === 'Memcached') { - return $this->_memcached->set($id, array($data, time(), $ttl), $ttl); + return $this->_memcached->set($id, $data, $ttl); } elseif (get_class($this->_memcached) === 'Memcache') { - return $this->_memcached->set($id, array($data, time(), $ttl), 0, $ttl); + return $this->_memcached->set($id, $data, 0, $ttl); } return FALSE; @@ -110,6 +116,34 @@ class CI_Cache_memcached extends CI_Driver { // ------------------------------------------------------------------------ /** + * Increment a raw value + * + * @param string $id Cache ID + * @param int $offset Step/value to add + * @return mixed New value on success or FALSE on failure + */ + public function increment($id, $offset = 1) + { + return $this->_memcached->increment($id, $offset); + } + + // ------------------------------------------------------------------------ + + /** + * Decrement a raw value + * + * @param string $id Cache ID + * @param int $offset Step/value to reduce by + * @return mixed New value on success or FALSE on failure + */ + public function decrement($id, $offset = 1) + { + return $this->_memcached->decrement($id, $offset); + } + + // ------------------------------------------------------------------------ + + /** * Clean the Cache * * @return bool false on failure/true on success diff --git a/system/libraries/Cache/drivers/Cache_redis.php b/system/libraries/Cache/drivers/Cache_redis.php index 40823fcb4..1c76426c5 100644 --- a/system/libraries/Cache/drivers/Cache_redis.php +++ b/system/libraries/Cache/drivers/Cache_redis.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 3.0 @@ -44,6 +44,7 @@ class CI_Cache_redis extends CI_Driver * @var array */ protected static $_default_config = array( + 'socket_type' => 'tcp', 'host' => '127.0.0.1', 'password' => NULL, 'port' => 6379, @@ -62,7 +63,7 @@ class CI_Cache_redis extends CI_Driver /** * Get cache * - * @param string Cache key identifier + * @param string Cache ID * @return mixed */ public function get($key) @@ -75,16 +76,17 @@ class CI_Cache_redis extends CI_Driver /** * Save cache * - * @param string Cache key identifier - * @param mixed Data to save - * @param int Time to live - * @return bool + * @param string $id Cache ID + * @param mixed $data Data to save + * @param int $ttl Time to live in seconds + * @param bool $raw Whether to store the raw value (unused) + * @return bool TRUE on success, FALSE on failure */ - public function save($key, $value, $ttl = NULL) + public function save($id, $data, $ttl = 60, $raw = FALSE) { return ($ttl) - ? $this->_redis->setex($key, $ttl, $value) - : $this->_redis->set($key, $value); + ? $this->_redis->setex($id, $ttl, $data) + : $this->_redis->set($id, $data); } // ------------------------------------------------------------------------ @@ -103,6 +105,38 @@ class CI_Cache_redis extends CI_Driver // ------------------------------------------------------------------------ /** + * Increment a raw value + * + * @param string $id Cache ID + * @param int $offset Step/value to add + * @return mixed New value on success or FALSE on failure + */ + public function increment($id, $offset = 1) + { + return $this->_redis->exists($id) + ? $this->_redis->incr($id, $offset) + : FALSE; + } + + // ------------------------------------------------------------------------ + + /** + * Decrement a raw value + * + * @param string $id Cache ID + * @param int $offset Step/value to reduce by + * @return mixed New value on success or FALSE on failure + */ + public function decrement($id, $offset = 1) + { + return $this->_redis->exists($id) + ? $this->_redis->decr($id, $offset) + : FALSE; + } + + // ------------------------------------------------------------------------ + + /** * Clean cache * * @return bool @@ -163,8 +197,7 @@ class CI_Cache_redis extends CI_Driver { if (extension_loaded('redis')) { - $this->_setup_redis(); - return TRUE; + return $this->_setup_redis(); } else { @@ -200,17 +233,33 @@ class CI_Cache_redis extends CI_Driver try { - $this->_redis->connect($config['host'], $config['port'], $config['timeout']); + if ($config['socket_type'] === 'unix') + { + $success = $this->_redis->connect($config['socket']); + } + else // tcp socket + { + $success = $this->_redis->connect($config['host'], $config['port'], $config['timeout']); + } + + if ( ! $success) + { + log_message('debug', 'Cache: Redis connection refused. Check the config.'); + return FALSE; + } } catch (RedisException $e) { - show_error('Redis connection refused. ' . $e->getMessage()); + log_message('debug', 'Cache: Redis connection refused ('.$e->getMessage().')'); + return FALSE; } if (isset($config['password'])) { $this->_redis->auth($config['password']); } + + return TRUE; } // ------------------------------------------------------------------------ diff --git a/system/libraries/Cache/drivers/Cache_wincache.php b/system/libraries/Cache/drivers/Cache_wincache.php index 80d3ac13d..f412a538d 100644 --- a/system/libraries/Cache/drivers/Cache_wincache.php +++ b/system/libraries/Cache/drivers/Cache_wincache.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 3.0 @@ -46,8 +46,8 @@ class CI_Cache_wincache extends CI_Driver { * Look for a value in the cache. If it exists, return the data, * if not, return FALSE * - * @param string - * @return mixed value that is stored/FALSE on failure + * @param string $id Cache Ide + * @return mixed Value that is stored/FALSE on failure */ public function get($id) { @@ -63,12 +63,13 @@ class CI_Cache_wincache extends CI_Driver { /** * Cache Save * - * @param string Unique Key - * @param mixed Data to store - * @param int Length of time (in seconds) to cache the data + * @param string $id Cache ID + * @param mixed $data Data to store + * @param int $ttl Time to live (in seconds) + * @param bool $raw Whether to store the raw value (unused) * @return bool true on success/false on failure */ - public function save($id, $data, $ttl = 60) + public function save($id, $data, $ttl = 60, $raw = FALSE) { return wincache_ucache_set($id, $data, $ttl); } @@ -89,6 +90,40 @@ class CI_Cache_wincache extends CI_Driver { // ------------------------------------------------------------------------ /** + * Increment a raw value + * + * @param string $id Cache ID + * @param int $offset Step/value to add + * @return mixed New value on success or FALSE on failure + */ + public function increment($id, $offset = 1) + { + $success = FALSE; + $value = wincache_ucache_inc($id, $offset, $success); + + return ($success === TRUE) ? $value : FALSE; + } + + // ------------------------------------------------------------------------ + + /** + * Decrement a raw value + * + * @param string $id Cache ID + * @param int $offset Step/value to reduce by + * @return mixed New value on success or FALSE on failure + */ + public function decrement($id, $offset = 1) + { + $success = FALSE; + $value = wincache_ucache_dec($id, $offset, $success); + + return ($success === TRUE) ? $value : FALSE; + } + + // ------------------------------------------------------------------------ + + /** * Clean the cache * * @return bool false on failure/true on success diff --git a/system/libraries/Calendar.php b/system/libraries/Calendar.php index 23d8ffb42..30f393318 100644 --- a/system/libraries/Calendar.php +++ b/system/libraries/Calendar.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -96,6 +96,13 @@ class CI_Calendar { public $next_prev_url = ''; /** + * Show days of other months + * + * @var bool + */ + public $show_other_days = FALSE; + + /** * Class constructor * * Loads the calendar language file and sets the default time reference. @@ -132,7 +139,7 @@ class CI_Calendar { * Accepts an associative array as input, containing display preferences * * @param array config preferences - * @return void + * @return CI_Calendar */ public function initialize($config = array()) { @@ -143,6 +150,14 @@ class CI_Calendar { $this->$key = $val; } } + + // Set the next_prev_url to the controller if required but not defined + if ($this->show_next_prev === TRUE && empty($this->next_prev_url)) + { + $this->next_prev_url = $this->CI->config->site_url($this->CI->router->class.'/'.$this->CI->router->method); + } + + return $this; } // -------------------------------------------------------------------- @@ -261,10 +276,10 @@ class CI_Calendar { for ($i = 0; $i < 7; $i++) { - $out .= ($is_current_month === TRUE && $day == $cur_day) ? $this->temp['cal_cell_start_today'] : $this->temp['cal_cell_start']; - if ($day > 0 && $day <= $total_days) { + $out .= ($is_current_month === TRUE && $day == $cur_day) ? $this->temp['cal_cell_start_today'] : $this->temp['cal_cell_start']; + if (isset($data[$day])) { // Cells with content @@ -279,14 +294,34 @@ class CI_Calendar { $this->temp['cal_cell_no_content_today'] : $this->temp['cal_cell_no_content']; $out .= str_replace('{day}', $day, $temp); } + + $out .= ($is_current_month === TRUE && $day == $cur_day) ? $this->temp['cal_cell_end_today'] : $this->temp['cal_cell_end']; + } + elseif ($this->show_other_days === TRUE) + { + $out .= $this->temp['cal_cell_start_other']; + + if ($day <= 0) + { + // Day of previous month + $prev_month = $this->adjust_date($month - 1, $year); + $prev_month_days = $this->get_total_days($prev_month['month'], $prev_month['year']); + $out .= str_replace('{day}', $prev_month_days + $day, $this->temp['cal_cell_other']); + } + else + { + // Day of next month + $out .= str_replace('{day}', $day - $total_days, $this->temp['cal_cell_other']); + } + + $out .= $this->temp['cal_cell_end_other']; } else { // Blank cells - $out .= $this->temp['cal_cell_blank']; + $out .= $this->temp['cal_cell_start'].$this->temp['cal_cell_blank'].$this->temp['cal_cell_end']; } - $out .= ($is_current_month === TRUE && $day == $cur_day) ? $this->temp['cal_cell_end_today'] : $this->temp['cal_cell_end']; $day++; } @@ -329,7 +364,7 @@ class CI_Calendar { * Get Day Names * * Returns an array of day names (Sunday, Monday, etc.) based - * on the type. Options: long, short, abrev + * on the type. Options: long, short, abr * * @param string * @return array @@ -457,13 +492,16 @@ class CI_Calendar { 'cal_row_start' => '<tr>', 'cal_cell_start' => '<td>', 'cal_cell_start_today' => '<td>', + 'cal_cell_start_other' => '<td style="color: #666;">', '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' => ' ', + 'cal_cell_other' => '{day}', 'cal_cell_end' => '</td>', 'cal_cell_end_today' => '</td>', + 'cal_cell_end_other' => '</td>', 'cal_row_end' => '</tr>', 'table_close' => '</table>' ); @@ -477,7 +515,7 @@ class CI_Calendar { * Harvests the data within the template {pseudo-variables} * used to display the calendar * - * @return void + * @return CI_Calendar */ public function parse_template() { @@ -485,12 +523,12 @@ class CI_Calendar { if ($this->template === '') { - return; + return $this; } $today = array('cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today'); - foreach (array('table_open', 'table_close', 'heading_row_start', 'heading_previous_cell', 'heading_title_cell', 'heading_next_cell', 'heading_row_end', 'week_row_start', 'week_day_cell', 'week_row_end', 'cal_row_start', 'cal_cell_start', 'cal_cell_content', 'cal_cell_no_content', 'cal_cell_blank', 'cal_cell_end', 'cal_row_end', 'cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today') as $val) + foreach (array('table_open', 'table_close', 'heading_row_start', 'heading_previous_cell', 'heading_title_cell', 'heading_next_cell', 'heading_row_end', 'week_row_start', 'week_day_cell', 'week_row_end', 'cal_row_start', 'cal_cell_start', 'cal_cell_content', 'cal_cell_no_content', 'cal_cell_blank', 'cal_cell_end', 'cal_row_end', 'cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today', 'cal_cell_start_other', 'cal_cell_other', 'cal_cell_end_other') as $val) { if (preg_match('/\{'.$val.'\}(.*?)\{\/'.$val.'\}/si', $this->template, $match)) { @@ -501,6 +539,8 @@ class CI_Calendar { $this->temp[$val] = $this->temp[substr($val, 0, -6)]; } } + + return $this; } } diff --git a/system/libraries/Cart.php b/system/libraries/Cart.php index edc300bd7..5a31a1d45 100644 --- a/system/libraries/Cart.php +++ b/system/libraries/Cart.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2006 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2006 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/libraries/Driver.php b/system/libraries/Driver.php index 1bc365cbc..d2e41d6dd 100644 --- a/system/libraries/Driver.php +++ b/system/libraries/Driver.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2006 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2006 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/libraries/Email.php b/system/libraries/Email.php index 082629a4c..93c19de5e 100644 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -399,9 +399,9 @@ class CI_Email { else { $this->_smtp_auth = ! ($this->smtp_user === '' && $this->smtp_pass === ''); - $this->_safe_mode = (bool) @ini_get('safe_mode'); } + $this->_safe_mode = ( ! is_php('5.4') && (bool) @ini_get('safe_mode')); $this->charset = strtoupper($this->charset); log_message('debug', 'Email Class Initialized'); @@ -451,7 +451,6 @@ class CI_Email { $this->clear(); $this->_smtp_auth = ! ($this->smtp_user === '' && $this->smtp_pass === ''); - $this->_safe_mode = (bool) @ini_get('safe_mode'); return $this; } @@ -711,18 +710,42 @@ class CI_Email { /** * Assign file attachments * - * @param string $filename + * @param string $file Can be local path, URL or buffered content * @param string $disposition = 'attachment' * @param string $newname = NULL * @param string $mime = '' * @return CI_Email */ - public function attach($filename, $disposition = '', $newname = NULL, $mime = '') + public function attach($file, $disposition = '', $newname = NULL, $mime = '') { + if ($mime === '') + { + if (strpos($file, '://') === FALSE && ! file_exists($file)) + { + $this->_set_error_message('lang:email_attachment_missing', $file); + return FALSE; + } + + if ( ! $fp = @fopen($file, FOPEN_READ)) + { + $this->_set_error_message('lang:email_attachment_unreadable', $file); + return FALSE; + } + + $file_content = stream_get_contents($fp); + $mime = $this->_mime_types(pathinfo($file, PATHINFO_EXTENSION)); + fclose($fp); + } + else + { + $file_content =& $file; // buffered file + } + $this->_attachments[] = array( - 'name' => array($filename, $newname), + 'name' => array($file, $newname), 'disposition' => empty($disposition) ? 'attachment' : $disposition, // Can also be 'inline' Not sure if it matters - 'type' => $mime + 'type' => $mime, + 'content' => chunk_split(base64_encode($file_content)) ); return $this; @@ -731,6 +754,35 @@ class CI_Email { // -------------------------------------------------------------------- /** + * Set and return attachment Content-ID + * + * Useful for attached inline pictures + * + * @param string $filename + * @return string + */ + public function attachment_cid($filename) + { + if ($this->multipart !== 'related') + { + $this->multipart = 'related'; // Thunderbird need this for inline images + } + + for ($i = 0, $c = count($this->_attachments); $i < $c; $i++) + { + if ($this->_attachments[$i]['name'][0] === $filename) + { + $this->_attachments[$i]['cid'] = uniqid(basename($this->_attachments[$i]['name'][0]).'@'); + return $this->_attachments[$i]['cid']; + } + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** * Add a Header Item * * @param string @@ -770,7 +822,7 @@ class CI_Email { * @param string * @return CI_Email */ - public function set_alt_message($str = '') + public function set_alt_message($str) { $this->alt_message = (string) $str; return $this; @@ -1362,47 +1414,22 @@ class CI_Email { $filename = $this->_attachments[$i]['name'][0]; $basename = ($this->_attachments[$i]['name'][1] === NULL) ? basename($filename) : $this->_attachments[$i]['name'][1]; - $ctype = $this->_attachments[$i]['type']; - $file_content = ''; - - if ($ctype === '') - { - if ( ! file_exists($filename)) - { - $this->_set_error_message('lang:email_attachment_missing', $filename); - return FALSE; - } - - $file = filesize($filename) +1; - - if ( ! $fp = fopen($filename, FOPEN_READ)) - { - $this->_set_error_message('lang:email_attachment_unreadable', $filename); - return FALSE; - } - - $ctype = $this->_mime_types(pathinfo($filename, PATHINFO_EXTENSION)); - $file_content = fread($fp, $file); - fclose($fp); - } - else - { - $file_content =& $this->_attachments[$i]['name'][0]; - } $attachment[$z++] = '--'.$this->_atc_boundary.$this->newline - .'Content-type: '.$ctype.'; ' + .'Content-type: '.$this->_attachments[$i]['type'].'; ' .'name="'.$basename.'"'.$this->newline .'Content-Disposition: '.$this->_attachments[$i]['disposition'].';'.$this->newline - .'Content-Transfer-Encoding: base64'.$this->newline; + .'Content-Transfer-Encoding: base64'.$this->newline + .(empty($this->_attachments[$i]['cid']) ? '' : 'Content-ID: <'.$this->_attachments[$i]['cid'].'>'.$this->newline); - $attachment[$z++] = chunk_split(base64_encode($file_content)); + $attachment[$z++] = $this->_attachments[$i]['content']; } $body .= implode($this->newline, $attachment).$this->newline.'--'.$this->_atc_boundary.'--'; $this->_finalbody = ($this->_get_protocol() === 'mail') ? $body : $hdr.$this->newline.$this->newline.$body; + return TRUE; } @@ -1517,7 +1544,7 @@ class CI_Email { { return mb_encode_mimeheader($str, $this->charset, 'Q', $this->crlf); } - elseif (extension_loaded('iconv')) + elseif (ICONV_ENABLED === TRUE) { $output = @iconv_mime_encode('', $str, array( @@ -1546,9 +1573,9 @@ class CI_Email { isset($chars) OR $chars = strlen($str); $output = '=?'.$this->charset.'?Q?'; - for ($i = 0, $length = strlen($output), $iconv = extension_loaded('iconv'); $i < $chars; $i++) + for ($i = 0, $length = strlen($output); $i < $chars; $i++) { - $chr = ($this->charset === 'UTF-8' && $iconv === TRUE) + $chr = ($this->charset === 'UTF-8' && ICONV_ENABLED === TRUE) ? '='.implode('=', str_split(strtoupper(bin2hex(iconv_substr($str, $i, 1, $this->charset))), 2)) : '='.strtoupper(bin2hex($str[$i])); @@ -2070,7 +2097,16 @@ class CI_Email { */ protected function _send_data($data) { - if ( ! fwrite($this->_smtp_connect, $data.$this->newline)) + $data .= $this->newline; + for ($written = 0, $length = strlen($data); $written < $length; $written += $result) + { + if (($result = fwrite($this->_smtp_connect, substr($data, $written))) === FALSE) + { + break; + } + } + + if ($result === FALSE) { $this->_set_error_message('lang:email_smtp_data_failure', $data); return FALSE; diff --git a/system/libraries/Encrypt.php b/system/libraries/Encrypt.php index 8ac5420de..f72bd2302 100644 --- a/system/libraries/Encrypt.php +++ b/system/libraries/Encrypt.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/libraries/Encryption.php b/system/libraries/Encryption.php new file mode 100644 index 000000000..3ce9f1b95 --- /dev/null +++ b/system/libraries/Encryption.php @@ -0,0 +1,887 @@ +<?php +/** + * CodeIgniter + * + * 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 EllisLab Dev Team + * @copyright Copyright (c) 2008 - 2014, 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 3.0 + * @filesource + */ +defined('BASEPATH') OR exit('No direct script access allowed'); + +/** + * CodeIgniter Encryption Class + * + * Provides two-way keyed encryption via PHP's MCrypt and/or OpenSSL extensions. + * + * @package CodeIgniter + * @subpackage Libraries + * @category Libraries + * @author Andrey Andreev + * @link http://codeigniter.com/user_guide/libraries/encryption.html + */ +class CI_Encryption { + + /** + * Encryption cipher + * + * @var string + */ + protected $_cipher = 'aes-128'; + + /** + * Cipher mode + * + * @var string + */ + protected $_mode = 'cbc'; + + /** + * Cipher handle + * + * @var mixed + */ + protected $_handle; + + /** + * Encryption key + * + * @var string + */ + protected $_key; + + /** + * PHP extension to be used + * + * @var string + */ + protected $_driver; + + /** + * List of usable drivers (PHP extensions) + * + * @var array + */ + protected $_drivers = array(); + + /** + * List of available modes + * + * @var array + */ + protected $_modes = array( + 'mcrypt' => array( + 'cbc' => 'cbc', + 'ecb' => 'ecb', + 'ofb' => 'nofb', + 'ofb8' => 'ofb', + 'cfb' => 'ncfb', + 'cfb8' => 'cfb', + 'ctr' => 'ctr', + 'stream' => 'stream' + ), + 'openssl' => array( + 'cbc' => 'cbc', + 'ecb' => 'ecb', + 'ofb' => 'ofb', + 'cfb' => 'cfb', + 'cfb8' => 'cfb8', + 'ctr' => 'ctr', + 'stream' => '', + 'gcm' => 'gcm', + 'xts' => 'xts' + ) + ); + + /** + * List of supported HMAC algorightms + * + * name => digest size pairs + * + * @var array + */ + protected $_digests = array( + 'sha224' => 28, + 'sha256' => 32, + 'sha384' => 48, + 'sha512' => 64 + ); + + // -------------------------------------------------------------------- + + /** + * Class constructor + * + * @param array $params Configuration parameters + * @return void + */ + public function __construct(array $params = array()) + { + $this->_drivers = array( + 'mcrypt' => defined('MCRYPT_DEV_URANDOM'), + // While OpenSSL is available for PHP 5.3.0, an IV parameter + // for the encrypt/decrypt functions is only available since 5.3.3 + 'openssl' => (is_php('5.3.3') && extension_loaded('openssl')) + ); + + if ( ! $this->_drivers['mcrypt'] && ! $this->_drivers['openssl']) + { + return show_error('Encryption: Unable to find an available encryption driver.'); + } + + $this->initialize($params); + if ( ! isset($this->_key) && strlen($key = config_item('encryption_key')) > 0) + { + $this->_key = $key; + } + + log_message('debug', 'Encryption Class Initialized'); + } + + // -------------------------------------------------------------------- + + /** + * Initialize + * + * @param array $params Configuration parameters + * @return CI_Encryption + */ + public function initialize(array $params) + { + if ( ! empty($params['driver'])) + { + if (isset($this->_drivers[$params['driver']])) + { + if ($this->_drivers[$params['driver']]) + { + $this->_driver = $params['driver']; + } + else + { + log_message('error', "Encryption: Driver '".$params['driver']."' is not available."); + } + } + else + { + log_message('error', "Encryption: Unknown driver '".$params['driver']."' cannot be configured."); + } + } + + if (empty($this->_driver)) + { + $this->_driver = ($this->_drivers['openssl'] === TRUE) + ? 'openssl' + : 'mcrypt'; + + log_message('debug', "Encryption: Auto-configured driver '".$this->_driver."'."); + } + + empty($params['key']) OR $this->_key = $params['key']; + $this->{'_'.$this->_driver.'_initialize'}($params); + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Initialize MCrypt + * + * @param array $params Configuration parameters + * @return void + */ + protected function _mcrypt_initialize($params) + { + if ( ! empty($params['cipher'])) + { + $params['cipher'] = strtolower($params['cipher']); + $this->_cipher_alias($params['cipher']); + + if ( ! in_array($params['cipher'], mcrypt_list_algorithms(), TRUE)) + { + log_message('error', 'Encryption: MCrypt cipher '.strtoupper($params['cipher']).' is not available.'); + } + else + { + $this->_cipher = $params['cipher']; + } + } + + if ( ! empty($params['mode'])) + { + $params['mode'] = strtolower($params['mode']); + if ( ! isset($this->_modes['mcrypt'][$params['mode']])) + { + log_message('error', 'Encryption: MCrypt mode '.strtotupper($params['mode']).' is not available.'); + } + else + { + $this->_mode = $this->_modes['mcrypt'][$params['mode']]; + } + } + + if (isset($this->_cipher, $this->_mode)) + { + if (is_resource($this->_handle) + && (strtolower(mcrypt_enc_get_algorithms_name($this->_handle)) !== $this->_cipher + OR strtolower(mcrypt_enc_get_modes_name($this->_handle)) !== $this->_mode) + ) + { + mcrypt_module_close($this->_handle); + } + + if ($this->_handle = mcrypt_module_open($this->_cipher, '', $this->_mode, '')) + { + log_message('debug', 'Encryption: MCrypt cipher '.strtoupper($this->_cipher).' initialized in '.strtoupper($this->_mode).' mode.'); + } + else + { + log_message('error', 'Encryption: Unable to initialize MCrypt with cipher '.strtoupper($this->_cipher).' in '.strtoupper($this->_mode).' mode.'); + } + } + } + + // -------------------------------------------------------------------- + + /** + * Initialize OpenSSL + * + * @param array $params Configuration parameters + * @return void + */ + protected function _openssl_initialize($params) + { + if ( ! empty($params['cipher'])) + { + $params['cipher'] = strtolower($params['cipher']); + $this->_cipher_alias($params['cipher']); + $this->_cipher = $params['cipher']; + } + + if ( ! empty($params['mode'])) + { + $params['mode'] = strtolower($params['mode']); + if ( ! isset($this->_modes['openssl'][$params['mode']])) + { + log_message('error', 'Encryption: OpenSSL mode '.strtotupper($params['mode']).' is not available.'); + } + else + { + $this->_mode = $this->_modes['openssl'][$params['mode']]; + } + } + + if (isset($this->_cipher, $this->_mode)) + { + // This is mostly for the stream mode, which doesn't get suffixed in OpenSSL + $handle = empty($this->_mode) + ? $this->_cipher + : $this->_cipher.'-'.$this->_mode; + + if ( ! in_array($handle, openssl_get_cipher_methods(), TRUE)) + { + $this->_handle = NULL; + log_message('error', 'Encryption: Unable to initialize OpenSSL with method '.strtoupper($handle).'.'); + } + else + { + $this->_handle = $handle; + log_message('debug', 'Encryption: OpenSSL initialized with method '.strtoupper($handle).'.'); + } + } + } + + // -------------------------------------------------------------------- + + /** + * Encrypt + * + * @param string $data Input data + * @param array $params Input parameters + * @return string + */ + public function encrypt($data, array $params = NULL) + { + if (($params = $this->_get_params($params)) === FALSE) + { + return FALSE; + } + + isset($params['key']) OR $params['key'] = $this->hkdf($this->_key, 'sha512', NULL, strlen($this->_key), 'encryption'); + + if (($data = $this->{'_'.$this->_driver.'_encrypt'}($data, $params)) === FALSE) + { + return FALSE; + } + + $params['base64'] && $data = base64_encode($data); + + if (isset($params['hmac_digest'])) + { + isset($params['hmac_key']) OR $params['hmac_key'] = $this->hkdf($this->_key, 'sha512', NULL, NULL, 'authentication'); + return hash_hmac($params['hmac_digest'], $data, $params['hmac_key'], ! $params['base64']).$data; + } + + return $data; + } + + // -------------------------------------------------------------------- + + /** + * Encrypt via MCrypt + * + * @param string $data Input data + * @param array $params Input parameters + * @return string + */ + protected function _mcrypt_encrypt($data, $params) + { + if ( ! is_resource($params['handle'])) + { + return FALSE; + } + elseif ( ! isset($params['iv'])) + { + // The greater-than-1 comparison is mostly a work-around for a bug, + // where 1 is returned for ARCFour instead of 0. + $params['iv'] = (($iv_size = mcrypt_enc_get_iv_size($params['handle'])) > 1) + ? mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM) + : NULL; + } + + // CAST-128 compatibility (http://tools.ietf.org/rfc/rfc2144.txt) + // + // RFC2144 says that keys shorter than 16 bytes are to be padded with + // zero bytes to 16 bytes, but (surprise) MCrypt doesn't do that. + if ($params['cipher'] === 'cast-128' && ($kl = strlen($params['key'])) < 16) + { + $params['key'] .= str_repeat("\x0", 16 - $kl); + } + + if (mcrypt_generic_init($params['handle'], $params['key'], $params['iv']) < 0) + { + if ($params['handle'] !== $this->_handle) + { + mcrypt_module_close($params['handle']); + } + + return FALSE; + } + + // Use PKCS#7 padding in order to ensure compatibility with OpenSSL + // and other implementations outside of PHP. + if (in_array(strtolower(mcrypt_enc_get_modes_name($params['handle'])), array('cbc', 'ecb'), TRUE)) + { + $block_size = mcrypt_enc_get_block_size($params['handle']); + $pad = $block_size - (strlen($data) % $block_size); + $data .= str_repeat(chr($pad), $pad); + } + + // Work-around for yet another strange behavior in MCrypt. + // + // When encrypting in ECB mode, the IV is ignored. Yet + // mcrypt_enc_get_iv_size() returns a value larger than 0 + // even if ECB is used AND mcrypt_generic_init() complains + // if you don't pass an IV with length equal to the said + // return value. + // + // This probably would've been fine (even though still wasteful), + // but OpenSSL isn't that dumb and we need to make the process + // portable, so ... + $data = (mcrypt_enc_get_modes_name($params['handle']) !== 'ECB') + ? $params['iv'].mcrypt_generic($params['handle'], $data) + : mcrypt_generic($params['handle'], $data); + + mcrypt_generic_deinit($params['handle']); + if ($params['handle'] !== $this->_handle) + { + mcrypt_module_close($params['handle']); + } + + return $data; + } + + // -------------------------------------------------------------------- + + /** + * Encrypt via OpenSSL + * + * @param string $data Input data + * @param array $params Input parameters + * @return string + */ + protected function _openssl_encrypt($data, $params) + { + if (empty($params['handle'])) + { + return FALSE; + } + elseif ( ! isset($params['iv'])) + { + $params['iv'] = ($iv_size = openssl_cipher_iv_length($params['handle'])) + ? openssl_random_pseudo_bytes($iv_size) + : NULL; + } + + $data = openssl_encrypt( + $data, + $params['handle'], + $params['key'], + 1, // DO NOT TOUCH! + $params['iv'] + ); + + if ($data === FALSE) + { + return FALSE; + } + + return $params['iv'].$data; + } + + // -------------------------------------------------------------------- + + /** + * Decrypt + * + * @param string $data Encrypted data + * @param array $params Input parameters + * @return string + */ + public function decrypt($data, array $params = NULL) + { + if (($params = $this->_get_params($params)) === FALSE) + { + return FALSE; + } + + if (isset($params['hmac_digest'])) + { + // This might look illogical, but it is done during encryption as well ... + // The 'base64' value is effectively an inverted "raw data" parameter + $digest_size = ($params['base64']) + ? $this->_digests[$params['hmac_digest']] * 2 + : $this->_digests[$params['hmac_digest']]; + + if (strlen($data) <= $digest_size) + { + return FALSE; + } + + $hmac_input = substr($data, 0, $digest_size); + $data = substr($data, $digest_size); + + isset($params['hmac_key']) OR $params['hmac_key'] = $this->hkdf($this->_key, 'sha512', NULL, NULL, 'authentication'); + $hmac_check = hash_hmac($params['hmac_digest'], $data, $params['hmac_key'], ! $params['base64']); + + // Time-attack-safe comparison + $diff = 0; + for ($i = 0; $i < $digest_size; $i++) + { + $diff |= ord($hmac_input[$i]) ^ ord($hmac_check[$i]); + } + + if ($diff !== 0) + { + return FALSE; + } + } + + if ($params['base64']) + { + $data = base64_decode($data); + } + + if (isset($params['iv']) && strncmp($params['iv'], $data, $iv_size = strlen($params['iv'])) === 0) + { + $data = substr($data, $iv_size); + } + + isset($params['key']) OR $params['key'] = $this->hkdf($this->_key, 'sha512', NULL, strlen($this->_key), 'encryption'); + + return $this->{'_'.$this->_driver.'_decrypt'}($data, $params); + } + + // -------------------------------------------------------------------- + + /** + * Decrypt via MCrypt + * + * @param string $data Encrypted data + * @param array $params Input parameters + * @return string + */ + protected function _mcrypt_decrypt($data, $params) + { + if ( ! is_resource($params['handle'])) + { + return FALSE; + } + elseif ( ! isset($params['iv'])) + { + // The greater-than-1 comparison is mostly a work-around for a bug, + // where 1 is returned for ARCFour instead of 0. + if (($iv_size = mcrypt_enc_get_iv_size($params['handle'])) > 1) + { + if (mcrypt_enc_get_modes_name($params['handle']) !== 'ECB') + { + $params['iv'] = substr($data, 0, $iv_size); + $data = substr($data, $iv_size); + } + else + { + // MCrypt is dumb and this is ignored, only size matters + $params['iv'] = str_repeat("\x0", $iv_size); + } + } + else + { + $params['iv'] = NULL; + } + } + + // CAST-128 compatibility (http://tools.ietf.org/rfc/rfc2144.txt) + // + // RFC2144 says that keys shorter than 16 bytes are to be padded with + // zero bytes to 16 bytes, but (surprise) MCrypt doesn't do that. + if ($params['cipher'] === 'cast-128' && ($kl = strlen($params['key'])) < 16) + { + $params['key'] .= str_repeat("\x0", 16 - $kl); + } + + if (mcrypt_generic_init($params['handle'], $params['key'], $params['iv']) < 0) + { + if ($params['handle'] !== $this->_handle) + { + mcrypt_module_close($params['handle']); + } + + return FALSE; + } + + $data = mdecrypt_generic($params['handle'], $data); + // Remove PKCS#7 padding, if necessary + if (in_array(strtolower(mcrypt_enc_get_modes_name($params['handle'])), array('cbc', 'ecb'), TRUE)) + { + $data = substr($data, 0, -ord($data[strlen($data)-1])); + } + + mcrypt_generic_deinit($params['handle']); + if ($params['handle'] !== $this->_handle) + { + mcrypt_module_close($params['handle']); + } + + return $data; + } + + // -------------------------------------------------------------------- + + /** + * Decrypt via OpenSSL + * + * @param string $data Encrypted data + * @param array $params Input parameters + * @return string + */ + protected function _openssl_decrypt($data, $params) + { + if ( ! isset($params['iv'])) + { + if ($iv_size = openssl_cipher_iv_length($params['handle'])) + { + $params['iv'] = substr($data, 0, $iv_size); + $data = substr($data, $iv_size); + } + else + { + $params['iv'] = NULL; + } + } + + return empty($params['handle']) + ? FALSE + : openssl_decrypt( + $data, + $params['handle'], + $params['key'], + 1, // DO NOT TOUCH! + $params['iv'] + ); + } + + // -------------------------------------------------------------------- + + /** + * Get params + * + * @param array $params Input parameters + * @return array + */ + protected function _get_params($params) + { + if (empty($params)) + { + return isset($this->_cipher, $this->_mode, $this->_key, $this->_handle) + ? array( + 'handle' => $this->_handle, + 'cipher' => $this->_cipher, + 'mode' => $this->_mode, + 'key' => NULL, + 'base64' => TRUE, + 'hmac_digest' => ($this->_mode !== 'gcm' ? 'sha512' : NULL), + 'hmac_key' => NULL + ) + : FALSE; + } + elseif ( ! isset($params['cipher'], $params['mode'], $params['key'])) + { + return FALSE; + } + + if (isset($params['mode'])) + { + $params['mode'] = strtolower($params['mode']); + if ( ! isset($this->_modes[$this->_driver][$params['mode']])) + { + return FALSE; + } + else + { + $params['mode'] = $this->_modes[$this->_driver][$params['mode']]; + } + } + + if ($params['mode'] === 'gcm' OR (isset($params['hmac']) && $params['hmac'] === FALSE)) + { + $params['hmac_digest'] = $params['hmac_key'] = NULL; + } + else + { + if ( ! isset($params['hmac_key'])) + { + return FALSE; + } + elseif (isset($params['hmac_digest'])) + { + $params['hmac_digest'] = strtolower($params['hmac_digest']); + if ( ! isset($this->_digests[$params['hmac_digest']])) + { + return FALSE; + } + } + else + { + $params['hmac_digest'] = 'sha512'; + } + } + + $params = array( + 'handle' => NULL, + 'cipher' => $params['cipher'], + 'mode' => $params['mode'], + 'key' => $params['key'], + 'iv' => isset($params['iv']) ? $params['iv'] : NULL, + 'base64' => isset($params['raw_data']) ? ! $params['raw_data'] : FALSE, + 'hmac_digest' => $params['hmac_digest'], + 'hmac_key' => $params['hmac_key'] + ); + + $this->_cipher_alias($params['cipher']); + $params['handle'] = ($params['cipher'] !== $this->_cipher OR $params['mode'] !== $this->_mode) + ? $this->{'_'.$this->_driver.'_get_handle'}($params['cipher'], $params['mode']) + : $this->_handle; + + return $params; + } + + // -------------------------------------------------------------------- + + /** + * Get MCrypt handle + * + * @param string $cipher Cipher name + * @param string $mode Encryption mode + * @return resource + */ + protected function _mcrypt_get_handle($cipher, $mode) + { + return mcrypt_module_open($cipher, '', $mode, ''); + } + + // -------------------------------------------------------------------- + + /** + * Get OpenSSL handle + * + * @param string $cipher Cipher name + * @param string $mode Encryption mode + * @return string + */ + protected function _openssl_get_handle($cipher, $mode) + { + // OpenSSL methods aren't suffixed with '-stream' for this mode + return ($mode === 'stream') + ? $cipher + : $cipher.'-'.$mode; + } + + // -------------------------------------------------------------------- + + /** + * Cipher alias + * + * Tries to translate cipher names between MCrypt and OpenSSL's "dialects". + * + * @param string $cipher Cipher name + * @return void + */ + protected function _cipher_alias(&$cipher) + { + static $dictionary; + + if (empty($dictionary)) + { + $dictionary = array( + 'mcrypt' => array( + 'aes-128' => 'rijndael-128', + 'aes-192' => 'rijndael-128', + 'aes-256' => 'rijndael-128', + 'des3-ede3' => 'tripledes', + 'bf' => 'blowfish', + 'cast5' => 'cast-128', + 'rc4' => 'arcfour', + 'rc4-40' => 'arcfour' + ), + 'openssl' => array( + 'rijndael-128' => 'aes-128', + 'tripledes' => 'des-ede3', + 'blowfish' => 'bf', + 'cast-128' => 'cast5', + 'arcfour' => 'rc4-40', + 'rc4' => 'rc4-40' + ) + ); + + // Notes: + // + // - Rijndael-128 is, at the same time all three of AES-128, + // AES-192 and AES-256. The only difference between them is + // the key size. Rijndael-192, Rijndael-256 on the other hand + // also have different block sizes and are NOT AES-compatible. + // + // - Blowfish is said to be supporting key sizes between + // 4 and 56 bytes, but it appears that between MCrypt and + // OpenSSL, only those of 16 and more bytes are compatible. + // Also, don't know what MCrypt's 'blowfish-compat' is. + // + // - CAST-128/CAST5 produces a longer cipher when encrypted via + // OpenSSL, but (strangely enough) can be decrypted by either + // extension anyway. + // Also, RFC2144 says that the cipher supports key sizes + // between 5 and 16 bytes by the implementation actually + // zero-padding them to 16 bytes, but MCrypt doesn't do that. + // + // - RC4 (ARCFour) has a strange implementation under OpenSSL. + // Its 'rc4-40' cipher method seems to work flawlessly, yet + // there's another one, 'rc4' that only works with a 16-byte key. + // + // - DES is compatible, but doesn't need an alias. + // + // Other seemingly matching ciphers between MCrypt, OpenSSL: + // + // - RC2 is NOT compatible and only an obscure forum post + // confirms that it is MCrypt's fault. + } + + if (isset($dictionary[$this->_driver][$cipher])) + { + $cipher = $dictionary[$this->_driver][$cipher]; + } + } + + // -------------------------------------------------------------------- + + /** + * HKDF + * + * @link https://tools.ietf.org/rfc/rfc5869.txt + * @param $key Input key + * @param $digest A SHA-2 hashing algorithm + * @param $salt Optional salt + * @param $length Output length (defaults to the selected digest size) + * @param $info Optional context/application-specific info + * @return string A pseudo-random key + */ + public function hkdf($key, $digest = 'sha512', $salt = NULL, $length = NULL, $info = '') + { + if ( ! isset($this->_digests[$digest])) + { + return FALSE; + } + + if (empty($length) OR ! is_int($length)) + { + $length = $this->_digests[$digest]; + } + elseif ($length > (255 * $this->_digests[$digest])) + { + return FALSE; + } + + isset($salt) OR $salt = str_repeat("\0", $this->_digests[$digest]); + + $prk = hash_hmac($digest, $key, $salt, TRUE); + $key = ''; + for ($key_block = '', $block_index = 1; strlen($key) < $length; $block_index++) + { + $key_block = hash_hmac($digest, $key_block.$info.chr($block_index), $prk, TRUE); + $key .= $key_block; + } + + return substr($key, 0, $length); + } + + // -------------------------------------------------------------------- + + /** + * __get() magic + * + * @param string $key Property name + * @return mixed + */ + public function __get($key) + { + // Because aliases + if ($key === 'mode') + { + return array_search($this->_mode, $this->_modes[$this->_driver], TRUE); + } + elseif (in_array($key, array('cipher', 'driver', 'drivers', 'digests'), TRUE)) + { + return $this->{'_'.$key}; + } + + return NULL; + } + +} + +/* End of file Encryption.php */ +/* Location: ./system/libraries/Encryption.php */
\ No newline at end of file diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php index 8b9bfa897..0c4f94914 100644 --- a/system/libraries/Form_validation.php +++ b/system/libraries/Form_validation.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -144,14 +144,16 @@ class CI_Form_validation { * Set Rules * * This function takes an array of field names and validation - * rules as input, validates the info, and stores it + * rules as input, any custom error messages, validates the info, + * and stores it * * @param mixed $field * @param string $label * @param mixed $rules + * @param array $errors * @return CI_Form_validation */ - public function set_rules($field, $label = '', $rules = '') + public function set_rules($field, $label = '', $rules = '', $errors = array()) { // No reason to set rules if we have no POST data // or a validation array has not been specified @@ -175,8 +177,11 @@ class CI_Form_validation { // If the field label wasn't passed we use the field name $label = isset($row['label']) ? $row['label'] : $row['field']; + // Add the custom error message array + $errors = (isset($row['errors']) && is_array($row['errors'])) ? $row['errors'] : array(); + // Here we go! - $this->set_rules($row['field'], $label, $row['rules']); + $this->set_rules($row['field'], $label, $row['rules'], $errors); } return $this; @@ -224,6 +229,7 @@ class CI_Form_validation { 'field' => $field, 'label' => $label, 'rules' => $rules, + 'errors' => $errors, 'is_array' => $is_array, 'keys' => $indexes, 'postdata' => NULL, @@ -246,14 +252,16 @@ class CI_Form_validation { * each array due to the limitations of CI's singleton * * @param array $data - * @return void + * @return CI_Form_validation */ - public function set_data($data = '') + public function set_data(array $data) { - if ( ! empty($data) && is_array($data)) + if ( ! empty($data)) { $this->validation_data = $data; } + + return $this; } // -------------------------------------------------------------------- @@ -304,12 +312,12 @@ class CI_Form_validation { * * Gets the error message associated with a particular field * - * @param string the field name - * @param string the html start tag - * @param strign the html end tag + * @param string $field Field name + * @param string $prefix HTML start tag + * @param string $suffix HTML end tag * @return string */ - public function error($field = '', $prefix = '', $suffix = '') + public function error($field, $prefix = '', $suffix = '') { if (empty($this->_field_data[$field]['error'])) { @@ -414,18 +422,15 @@ class CI_Form_validation { return FALSE; } - // Is there a validation rule for the particular URI being accessed? - $uri = ($group === '') ? trim($this->CI->uri->ruri_string(), '/') : $group; - - if ($uri !== '' && isset($this->_config_rules[$uri])) + if (empty($group)) { - $this->set_rules($this->_config_rules[$uri]); - } - else - { - $this->set_rules($this->_config_rules); + // Is there a validation rule for the particular URI being accessed? + $group = trim($this->CI->uri->ruri_string(), '/'); + isset($this->_config_rules[$group]) OR $group = $this->CI->router->class.'/'.$this->CI->router->method; } + $this->set_rules(isset($this->_config_rules[$group]) ? $this->_config_rules[$group] : $this->_config_rules); + // Were we able to set the rules correctly? if (count($this->_field_data) === 0) { @@ -605,7 +610,12 @@ class CI_Form_validation { // Set the message type $type = in_array('required', $rules) ? 'required' : 'isset'; - if (isset($this->_error_messages[$type])) + // Check if a custom message is defined + if (isset($this->_field_data[$row['field']]['errors'][$type])) + { + $line = $this->_field_data[$row['field']]['errors'][$type]; + } + elseif (isset($this->_error_messages[$type])) { $line = $this->_error_messages[$type]; } @@ -749,7 +759,12 @@ class CI_Form_validation { // Did the rule test negatively? If so, grab the error. if ($result === FALSE) { - if ( ! isset($this->_error_messages[$rule])) + // Check if a custom message is defined + if (isset($this->_field_data[$row['field']]['errors'][$rule])) + { + $line = $this->_field_data[$row['field']]['errors'][$rule]; + } + elseif ( ! isset($this->_error_messages[$rule])) { if (FALSE === ($line = $this->CI->lang->line('form_validation_'.$rule)) // DEPRECATED support for non-prefixed keys @@ -898,12 +913,19 @@ class CI_Form_validation { } $field = $this->_field_data[$field]['postdata']; + $value = (string) $value; if (is_array($field)) { - if ( ! in_array($value, $field)) + // Note: in_array('', array(0)) returns TRUE, do not use it + foreach ($field as &$v) { - return ''; + if ($value === $v) + { + return ' selected="selected"'; + } } + + return ''; } elseif (($field === '' OR $value === '') OR ($field !== $value)) { @@ -934,12 +956,19 @@ class CI_Form_validation { } $field = $this->_field_data[$field]['postdata']; + $value = (string) $value; if (is_array($field)) { - if ( ! in_array($value, $field)) + // Note: in_array('', array(0)) returns TRUE, do not use it + foreach ($field as &$v) { - return ''; + if ($value === $v) + { + return ' checked="checked"'; + } } + + return ''; } elseif (($field === '' OR $value === '') OR ($field !== $value)) { @@ -1509,7 +1538,7 @@ class CI_Form_validation { * Prevents subsequent validation routines from being affected by the * results of any previous validation routine due to the CI singleton. * - * @return void + * @return CI_Form_validation */ public function reset_validation() { @@ -1518,6 +1547,7 @@ class CI_Form_validation { $this->_error_array = array(); $this->_error_messages = array(); $this->error_string = ''; + return $this; } } diff --git a/system/libraries/Ftp.php b/system/libraries/Ftp.php index dc6bbd226..ef3b7d70d 100644 --- a/system/libraries/Ftp.php +++ b/system/libraries/Ftp.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -214,12 +214,12 @@ class CI_FTP { * Internally, this parameter is only used by the "mirror" function below. * * @param string $path - * @param bool $supress_debug + * @param bool $suppress_debug * @return bool */ - public function changedir($path = '', $supress_debug = FALSE) + public function changedir($path, $suppress_debug = FALSE) { - if ($path === '' OR ! $this->_is_conn()) + if ( ! $this->_is_conn()) { return FALSE; } @@ -228,7 +228,7 @@ class CI_FTP { if ($result === FALSE) { - if ($this->debug === TRUE && $supress_debug === FALSE) + if ($this->debug === TRUE && $suppress_debug === FALSE) { $this->_error('ftp_unable_to_changedir'); } @@ -247,7 +247,7 @@ class CI_FTP { * @param int $permissions * @return bool */ - public function mkdir($path = '', $permissions = NULL) + public function mkdir($path, $permissions = NULL) { if ($path === '' OR ! $this->_is_conn()) { @@ -260,7 +260,7 @@ class CI_FTP { { if ($this->debug === TRUE) { - $this->_error('ftp_unable_to_makdir'); + $this->_error('ftp_unable_to_mkdir'); } return FALSE; } @@ -392,7 +392,7 @@ class CI_FTP { { if ($this->debug === TRUE) { - $this->_error('ftp_unable_to_' . ($move === FALSE ? 'rename' : 'move')); + $this->_error('ftp_unable_to_'.($move === FALSE ? 'rename' : 'move')); } return FALSE; } diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php index b6a11a3a5..db45a80fc 100644 --- a/system/libraries/Image_lib.php +++ b/system/libraries/Image_lib.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -1245,22 +1245,37 @@ class CI_Image_lib { // offset flips itself automatically if ($this->wm_vrt_alignment === 'B') + { $this->wm_vrt_offset = $this->wm_vrt_offset * -1; + } if ($this->wm_hor_alignment === 'R') + { $this->wm_hor_offset = $this->wm_hor_offset * -1; + } // Set font width and height // These are calculated differently depending on // whether we are using the true type font or not if ($this->wm_use_truetype === TRUE) { - if ($this->wm_font_size === '') + if (empty($this->wm_font_size)) { $this->wm_font_size = 17; } - $fontwidth = $this->wm_font_size-($this->wm_font_size/4); + if (function_exists('imagettfbbox')) + { + $temp = imagettfbbox($this->wm_font_size, 0, $this->wm_font_path, $this->wm_text); + $temp = $temp[2] - $temp[0]; + + $fontwidth = $temp / strlen($this->wm_text); + } + else + { + $fontwidth = $this->wm_font_size - ($this->wm_font_size / 4); + } + $fontheight = $this->wm_font_size; $this->wm_vrt_offset += $this->wm_font_size; } @@ -1368,45 +1383,45 @@ class CI_Image_lib { public function image_create_gd($path = '', $image_type = '') { if ($path === '') + { $path = $this->full_src_path; + } if ($image_type === '') + { $image_type = $this->image_type; + } switch ($image_type) { - case 1 : - if ( ! function_exists('imagecreatefromgif')) - { - $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported')); - return FALSE; - } + case 1 : + if ( ! function_exists('imagecreatefromgif')) + { + $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported')); + return FALSE; + } - return imagecreatefromgif($path); - break; + return imagecreatefromgif($path); case 2 : - if ( ! function_exists('imagecreatefromjpeg')) - { - $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported')); - return FALSE; - } + if ( ! function_exists('imagecreatefromjpeg')) + { + $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported')); + return FALSE; + } - return imagecreatefromjpeg($path); - break; + return imagecreatefromjpeg($path); case 3 : - if ( ! function_exists('imagecreatefrompng')) - { - $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported')); - return FALSE; - } - - return imagecreatefrompng($path); - break; + if ( ! function_exists('imagecreatefrompng')) + { + $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported')); + return FALSE; + } + return imagecreatefrompng($path); + default: + $this->set_error(array('imglib_unsupported_imagecreate')); + return FALSE; } - - $this->set_error(array('imglib_unsupported_imagecreate')); - return FALSE; } // -------------------------------------------------------------------- diff --git a/system/libraries/Javascript.php b/system/libraries/Javascript.php index 26a16850c..c71a4204e 100644 --- a/system/libraries/Javascript.php +++ b/system/libraries/Javascript.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -34,6 +34,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @category Javascript * @author EllisLab Dev Team * @link http://codeigniter.com/user_guide/libraries/javascript.html + * @deprecated 3.0.0 This was never a good idea in the first place. */ class CI_Javascript { diff --git a/system/libraries/Javascript/Jquery.php b/system/libraries/Javascript/Jquery.php index ab78e8b2e..1cc3d2c21 100644 --- a/system/libraries/Javascript/Jquery.php +++ b/system/libraries/Javascript/Jquery.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/libraries/Migration.php b/system/libraries/Migration.php index cc6fe48f0..932b06ef0 100644 --- a/system/libraries/Migration.php +++ b/system/libraries/Migration.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2006 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2006 - 2014, 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 3.0 diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php index 10fb29dbd..da4b89232 100644 --- a/system/libraries/Pagination.php +++ b/system/libraries/Pagination.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -314,7 +314,7 @@ class CI_Pagination { * Initialize Preferences * * @param array $params Initialization parameters - * @return void + * @return CI_Pagination */ public function initialize($params = array()) { @@ -342,6 +342,8 @@ class CI_Pagination { } } } + + return $this; } // -------------------------------------------------------------------- @@ -354,7 +356,8 @@ class CI_Pagination { public function create_links() { // If our item count or per-page total is zero there is no need to continue. - if ($this->total_rows === 0 OR $this->per_page === 0) + // Note: DO NOT change the operator to === here! + if ($this->total_rows == 0 OR $this->per_page == 0) { return ''; } diff --git a/system/libraries/Parser.php b/system/libraries/Parser.php index c1f1ad73b..d23a53423 100644 --- a/system/libraries/Parser.php +++ b/system/libraries/Parser.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -187,26 +187,34 @@ class CI_Parser { */ protected function _parse_pair($variable, $data, $string) { - if (FALSE === ($match = $this->_match_pair($string, $variable))) + if (FALSE === ($matches = $this->_match_pair($string, $variable))) { return $string; } $str = ''; - foreach ($data as $row) + $search = $replace = array(); + foreach ($matches as $match) { - $temp = $match[1]; - foreach ($row as $key => $val) + $str = ''; + foreach ($data as $row) { - $temp = is_array($val) + $temp = $match[1]; + foreach ($row as $key => $val) + { + $temp = is_array($val) ? $this->_parse_pair($key, $val, $temp) : $this->_parse_single($key, $val, $temp); + } + + $str .= $temp; } - $str .= $temp; + $search[] = $match[0]; + $replace[] = $str; } - return str_replace($match[0], $str, $string); + return str_replace($search, $replace, $string); } // -------------------------------------------------------------------- @@ -214,14 +222,14 @@ class CI_Parser { /** * Matches a variable pair * - * @param string - * @param string + * @param string $string + * @param string $variable * @return mixed */ protected function _match_pair($string, $variable) { - return preg_match('|'.preg_quote($this->l_delim).$variable.preg_quote($this->r_delim).'(.+?)'.preg_quote($this->l_delim).'/'.$variable.preg_quote($this->r_delim).'|s', - $string, $match) + return preg_match_all('|'.preg_quote($this->l_delim).$variable.preg_quote($this->r_delim).'(.+?)'.preg_quote($this->l_delim).'/'.$variable.preg_quote($this->r_delim).'|s', + $string, $match, PREG_SET_ORDER) ? $match : FALSE; } diff --git a/system/libraries/Profiler.php b/system/libraries/Profiler.php index 9e9e7d08d..810a025a4 100644 --- a/system/libraries/Profiler.php +++ b/system/libraries/Profiler.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -278,6 +278,7 @@ class CI_Profiler { } $output .= "</table>\n</fieldset>"; + $count++; } return $output; @@ -307,10 +308,7 @@ class CI_Profiler { foreach ($_GET as $key => $val) { - if ( ! is_numeric($key)) - { - $key = "'".$key."'"; - } + is_int($key) OR $key = "'".$key."'"; $output .= '<tr><td style="width:50%;color:#000;background-color:#ddd;padding:5px;">$_GET[' .$key.'] </td><td style="width:50%;padding:5px;color:#cd6e00;font-weight:normal;background-color:#ddd;">' @@ -338,7 +336,7 @@ class CI_Profiler { ."\n" .'<legend style="color:#009900;"> '.$this->CI->lang->line('profiler_post_data')." </legend>\n"; - if (count($_POST) === 0) + if (count($_POST) === 0 && count($_FILES) === 0) { $output .= '<div style="color:#009900;font-weight:normal;padding:4px 0 4px 0;">'.$this->CI->lang->line('profiler_no_post').'</div>'; } @@ -348,10 +346,7 @@ class CI_Profiler { foreach ($_POST as $key => $val) { - if ( ! is_numeric($key)) - { - $key = "'".$key."'"; - } + is_int($key) OR $key = "'".$key."'"; $output .= '<tr><td style="width:50%;padding:5px;color:#000;background-color:#ddd;">$_POST[' .$key.'] </td><td style="width:50%;padding:5px;color:#009900;font-weight:normal;background-color:#ddd;">'; @@ -368,6 +363,21 @@ class CI_Profiler { $output .= "</td></tr>\n"; } + foreach ($_FILES as $key => $val) + { + is_int($key) OR $key = "'".$key."'"; + + $output .= '<tr><td style="width:50%;padding:5px;color:#000;background-color:#ddd;">$_FILES[' + .$key.'] </td><td style="width:50%;padding:5px;color:#009900;font-weight:normal;background-color:#ddd;">'; + + if (is_array($val) OR is_object($val)) + { + $output .= '<pre>'.htmlspecialchars(stripslashes(print_r($val, TRUE))).'</pre>'; + } + + $output .= "</td></tr>\n"; + } + $output .= "</table>\n"; } @@ -506,7 +516,7 @@ class CI_Profiler { .'<legend style="color:#000;"> '.$this->CI->lang->line('profiler_session_data').' (<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_session_data\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show').'</span>)</legend>' .'<table style="width:100%;display:none;" id="ci_profiler_session_data">'; - foreach ($this->CI->session->all_userdata() as $key => $val) + foreach ($this->CI->session->userdata() as $key => $val) { if (is_array($val) OR is_object($val)) { diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 659a0269e..905352bb3 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 @@ -102,10 +102,10 @@ class CI_Session extends CI_Driver_Library { */ public function __construct(array $params = array()) { - $CI =& get_instance(); + $_config =& get_instance()->config; // No sessions under CLI - if ($CI->input->is_cli_request()) + if (is_cli()) { return; } @@ -113,7 +113,7 @@ class CI_Session extends CI_Driver_Library { log_message('debug', 'CI_Session Class Initialized'); // Add possible extra entries to our valid drivers list - $drivers = isset($params['sess_valid_drivers']) ? $params['sess_valid_drivers'] : $CI->config->item('sess_valid_drivers'); + $drivers = isset($params['sess_valid_drivers']) ? $params['sess_valid_drivers'] : $_config->item('sess_valid_drivers'); if ( ! empty($drivers)) { $drivers = array_map('strtolower', (array) $drivers); @@ -121,7 +121,7 @@ class CI_Session extends CI_Driver_Library { } // Get driver to load - $driver = isset($params['sess_driver']) ? $params['sess_driver'] : $CI->config->item('sess_driver'); + $driver = isset($params['sess_driver']) ? $params['sess_driver'] : $_config->item('sess_driver'); if ( ! $driver) { log_message('debug', "Session: No driver name is configured, defaulting to 'cookie'."); @@ -238,9 +238,14 @@ class CI_Session extends CI_Driver_Library { * @param string Item key * @return string Item value or NULL if not found */ - public function userdata($item) + public function userdata($item = NULL) { - return isset($this->userdata[$item]) ? $this->userdata[$item] : NULL; + if (isset($item)) + { + return isset($this->userdata[$item]) ? $this->userdata[$item] : NULL; + } + + return isset($this->userdata) ? $this->userdata : array(); } // ------------------------------------------------------------------------ @@ -248,35 +253,12 @@ class CI_Session extends CI_Driver_Library { /** * Fetch all session data * + * @deprecated 3.0.0 Use userdata() with no parameters instead * @return array User data array */ public function all_userdata() { - return isset($this->userdata) ? $this->userdata : NULL; - } - - // ------------------------------------------------------------------------ - - /** - * Fetch all flashdata - * - * @return array Flash data array - */ - public function all_flashdata() - { - $out = array(); - - // loop through all userdata - foreach ($this->all_userdata() as $key => $val) - { - // if it contains flashdata, add it - if (strpos($key, self::FLASHDATA_KEY.self::FLASHDATA_OLD) !== FALSE) - { - $key = str_replace(self::FLASHDATA_KEY.self::FLASHDATA_OLD, '', $key); - $out[$key] = $val; - } - } - return $out; + return isset($this->userdata) ? $this->userdata : array(); } // ------------------------------------------------------------------------ @@ -288,7 +270,7 @@ class CI_Session extends CI_Driver_Library { * @param string Item value or empty string * @return void */ - public function set_userdata($newdata = array(), $newval = '') + public function set_userdata($newdata, $newval = '') { // Wrap params as array if singular if (is_string($newdata)) @@ -317,7 +299,7 @@ class CI_Session extends CI_Driver_Library { * @param mixed Item name or array of item names * @return void */ - public function unset_userdata($newdata = array()) + public function unset_userdata($newdata) { // Wrap single name as array if (is_string($newdata)) @@ -360,7 +342,7 @@ class CI_Session extends CI_Driver_Library { * @param string Item value or empty string * @return void */ - public function set_flashdata($newdata = array(), $newval = '') + public function set_flashdata($newdata, $newval = '') { // Wrap item as array if singular if (is_string($newdata)) @@ -417,11 +399,25 @@ class CI_Session extends CI_Driver_Library { * @param string Item key * @return string */ - public function flashdata($key) + public function flashdata($key = NULL) { - // Prepend key and retrieve value - $flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key; - return $this->userdata($flashdata_key); + if (isset($key)) + { + return $this->userdata(self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key); + } + + // Get our flashdata items from userdata + $out = array(); + foreach ($this->userdata() as $key => $val) + { + if (strpos($key, self::FLASHDATA_KEY.self::FLASHDATA_OLD) !== FALSE) + { + $key = str_replace(self::FLASHDATA_KEY.self::FLASHDATA_OLD, '', $key); + $out[$key] = $val; + } + } + + return $out; } // ------------------------------------------------------------------------ @@ -434,7 +430,7 @@ class CI_Session extends CI_Driver_Library { * @param int Item lifetime in seconds or 0 for default * @return void */ - public function set_tempdata($newdata = array(), $newval = '', $expire = 0) + public function set_tempdata($newdata, $newval = '', $expire = 0) { // Set expiration time $expire = time() + ($expire ? $expire : self::TEMP_EXP_DEF); @@ -475,7 +471,7 @@ class CI_Session extends CI_Driver_Library { * @param mixed Item name or array of item names * @return void */ - public function unset_tempdata($newdata = array()) + public function unset_tempdata($newdata) { // Get expirations list $expirations = $this->userdata(self::EXPIRATION_KEY); @@ -514,11 +510,25 @@ class CI_Session extends CI_Driver_Library { * @param string Item key * @return string */ - public function tempdata($key) + public function tempdata($key = NULL) { - // Prepend key and return value - $tempdata_key = self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key; - return $this->userdata($tempdata_key); + if (isset($key)) + { + return $this->userdata(self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key); + } + + // Get our tempdata items from userdata + $out = array(); + foreach ($this->userdata() as $key => $val) + { + if (strpos($key, self::FLASHDATA_KEY.self::FLASHDATA_EXP) !== FALSE) + { + $key = str_replace(self::FLASHDATA_KEY.self::FLASHDATA_EXP, '', $key); + $out[$key] = $val; + } + } + + return $out; } // ------------------------------------------------------------------------ @@ -531,13 +541,12 @@ class CI_Session extends CI_Driver_Library { */ protected function _flashdata_mark() { - foreach ($this->all_userdata() as $name => $value) + foreach ($this->userdata() as $name => $value) { $parts = explode(self::FLASHDATA_NEW, $name); if (count($parts) === 2) { - $new_name = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$parts[1]; - $this->set_userdata($new_name, $value); + $this->set_userdata(self::FLASHDATA_KEY.self::FLASHDATA_OLD.$parts[1], $value); $this->unset_userdata($name); } } @@ -552,7 +561,7 @@ class CI_Session extends CI_Driver_Library { */ protected function _flashdata_sweep() { - $userdata = $this->all_userdata(); + $userdata = $this->userdata(); foreach (array_keys($userdata) as $key) { if (strpos($key, self::FLASHDATA_OLD)) @@ -581,7 +590,7 @@ class CI_Session extends CI_Driver_Library { // Unset expired elements $now = time(); - $userdata = $this->all_userdata(); + $userdata = $this->userdata(); foreach (array_keys($userdata) as $key) { if (strpos($key, self::FLASHDATA_EXP) && $expirations[$key] < $now) diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index d3d22d03a..566c40bd8 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -165,6 +165,8 @@ class CI_Session_cookie extends CI_Session_driver { */ public $now; + // ------------------------------------------------------------------------ + /** * Default userdata keys * @@ -185,6 +187,15 @@ class CI_Session_cookie extends CI_Session_driver { protected $data_dirty = FALSE; /** + * Standardize newlines flag + * + * @var bool + */ + protected $_standardize_newlines; + + // ------------------------------------------------------------------------ + + /** * Initialize session driver object * * @return void @@ -209,9 +220,11 @@ class CI_Session_cookie extends CI_Session_driver { 'sess_time_to_update', 'time_reference', 'cookie_prefix', - 'encryption_key' + 'encryption_key', ); + $this->_standardize_newlines = (bool) config_item('standardize_newlines'); + foreach ($prefs as $key) { $this->$key = isset($this->_parent->params[$key]) @@ -227,7 +240,7 @@ class CI_Session_cookie extends CI_Session_driver { // Do we need encryption? If so, load the encryption class if ($this->sess_encrypt_cookie === TRUE) { - $this->CI->load->library('encrypt'); + $this->CI->load->library('encryption'); } // Check for database @@ -370,34 +383,45 @@ class CI_Session_cookie extends CI_Session_driver { return FALSE; } - $len = strlen($session) - 40; - - if ($len < 0) + if ($this->sess_encrypt_cookie === TRUE) { - log_message('debug', 'The session cookie was not signed.'); - return FALSE; + $session = $this->CI->encryption->decrypt($session); + if ($session === FALSE) + { + log_message('error', 'Session: Unable to decrypt the session cookie, possibly due to a HMAC mismatch.'); + return FALSE; + } } + else + { + if (($len = strlen($session) - 40) <= 0) + { + log_message('error', 'Session: The session cookie was not signed.'); + return FALSE; + } - // Check cookie authentication - $hmac = substr($session, $len); - $session = substr($session, 0, $len); + // Check cookie authentication + $hmac = substr($session, $len); + $session = substr($session, 0, $len); - if ($hmac !== hash_hmac('sha1', $session, $this->encryption_key)) - { - log_message('error', 'The session cookie data did not match what was expected.'); - $this->sess_destroy(); - return FALSE; - } + // Time-attack-safe comparison + $hmac_check = hash_hmac('sha1', $session, $this->encryption_key); + $diff = 0; + for ($i = 0; $i < 40; $i++) + { + $diff |= ord($hmac[$i]) ^ ord($hmac_check[$i]); + } - // Check for encryption - if ($this->sess_encrypt_cookie === TRUE) - { - // Decrypt the cookie data - $session = $this->CI->encrypt->decode($session); + if ($diff !== 0) + { + log_message('error', 'Session: HMAC mismatch. The session cookie data did not match what was expected.'); + $this->sess_destroy(); + return FALSE; + } } // Unserialize the session array - $session = $this->_unserialize($session); + $session = @unserialize($session); // Is the session data we unserialized an array with the correct format? if ( ! is_array($session) OR ! isset($session['session_id'], $session['ip_address'], $session['user_agent'], $session['last_activity'])) @@ -472,7 +496,7 @@ class CI_Session_cookie extends CI_Session_driver { $row = $query->row(); if ( ! empty($row->user_data)) { - $custom_data = $this->_unserialize($row->user_data); + $custom_data = unserialize(trim($row->user_data)); if (is_array($custom_data)) { @@ -608,7 +632,7 @@ class CI_Session_cookie extends CI_Session_driver { if ( ! empty($userdata)) { // Serialize the custom data array so we can store it - $set['user_data'] = $this->_serialize($userdata); + $set['user_data'] = serialize($userdata); } // Reset query builder values. @@ -695,16 +719,28 @@ class CI_Session_cookie extends CI_Session_driver { ? array_intersect_key($this->userdata, $this->defaults) : $this->userdata; + // The Input class will do this and since we use HMAC verification, + // unless we standardize here as well, the hash won't match. + if ($this->_standardize_newlines) + { + foreach (array_keys($this->userdata) as $key) + { + $this->userdata[$key] = preg_replace('/(?:\r\n|[\r\n])/', PHP_EOL, $this->userdata[$key]); + } + } + // Serialize the userdata for the cookie - $cookie_data = $this->_serialize($cookie_data); + $cookie_data = serialize($cookie_data); if ($this->sess_encrypt_cookie === TRUE) { - $cookie_data = $this->CI->encrypt->encode($cookie_data); + $cookie_data = $this->CI->encryption->encrypt($cookie_data); + } + else + { + // Require message authentication + $cookie_data .= hash_hmac('sha1', $cookie_data, $this->encryption_key); } - - // Require message authentication - $cookie_data .= hash_hmac('sha1', $cookie_data, $this->encryption_key); $expire = ($this->sess_expire_on_close === TRUE) ? 0 : $this->sess_expiration + time(); @@ -737,93 +773,6 @@ class CI_Session_cookie extends CI_Session_driver { // ------------------------------------------------------------------------ /** - * 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 - * - * @param mixed Data to serialize - * @return string Serialized data - */ - protected function _serialize($data) - { - if (is_array($data)) - { - array_walk_recursive($data, array(&$this, '_escape_slashes')); - } - elseif (is_string($data)) - { - $data = str_replace('\\', '{{slash}}', $data); - } - - return serialize($data); - } - - // ------------------------------------------------------------------------ - - /** - * Escape slashes - * - * This function converts any slashes found into a temporary marker - * - * @param string Value - * @param string Key - * @return void - */ - protected function _escape_slashes(&$val, $key) - { - if (is_string($val)) - { - $val = str_replace('\\', '{{slash}}', $val); - } - } - - // ------------------------------------------------------------------------ - - /** - * Unserialize - * - * This function unserializes a data string, then converts any - * temporary slash markers back to actual slashes - * - * @param mixed Data to unserialize - * @return mixed Unserialized data - */ - protected function _unserialize($data) - { - $data = @unserialize(trim($data)); - - if (is_array($data)) - { - array_walk_recursive($data, array(&$this, '_unescape_slashes')); - return $data; - } - - return is_string($data) ? str_replace('{{slash}}', '\\', $data) : $data; - } - - // ------------------------------------------------------------------------ - - /** - * Unescape slashes - * - * This function converts any slash markers back into actual slashes - * - * @param string Value - * @param string Key - * @return void - */ - protected function _unescape_slashes(&$val, $key) - { - if (is_string($val)) - { - $val = str_replace('{{slash}}', '\\', $val); - } - } - - // ------------------------------------------------------------------------ - - /** * Garbage collection * * This deletes expired session rows from database @@ -841,7 +790,7 @@ class CI_Session_cookie extends CI_Session_driver { $probability = ini_get('session.gc_probability'); $divisor = ini_get('session.gc_divisor'); - if ((mt_rand(0, $divisor) / $divisor) < $probability) + if (mt_rand(1, $divisor) <= $probability) { $expire = $this->now - $this->sess_expiration; $this->CI->db->delete($this->sess_table_name, 'last_activity < '.$expire); diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index c237ad059..4104652b8 100644 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/libraries/Table.php b/system/libraries/Table.php index b77fcf19d..ff96d9275 100644 --- a/system/libraries/Table.php +++ b/system/libraries/Table.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.3.1 @@ -93,7 +93,7 @@ class CI_Table { * * @var function */ - public $function = FALSE; + public $function = NULL; /** * Set the template from the table config file if it exists @@ -117,7 +117,7 @@ class CI_Table { /** * Set the template * - * @param array + * @param array $template * @return bool */ public function set_template($template) @@ -139,12 +139,12 @@ class CI_Table { * Can be passed as an array or discreet params * * @param mixed - * @return void + * @return CI_Table */ public function set_heading($args = array()) { - $args = func_get_args(); - $this->heading = $this->_prep_args($args); + $this->heading = $this->_prep_args(func_get_args()); + return $this; } // -------------------------------------------------------------------- @@ -155,9 +155,9 @@ class CI_Table { * columns. This allows a single array with many elements to be * displayed in a table that has a fixed column count. * - * @param array - * @param int - * @return void + * @param array $array + * @param int $col_limit + * @return array */ public function make_columns($array = array(), $col_limit = 0) { @@ -202,12 +202,13 @@ class CI_Table { * * Can be passed as an array or discreet params * - * @param mixed - * @return void + * @param mixed $value + * @return CI_Table */ public function set_empty($value) { $this->empty_cells = $value; + return $this; } // -------------------------------------------------------------------- @@ -218,12 +219,12 @@ class CI_Table { * Can be passed as an array or discreet params * * @param mixed - * @return void + * @return CI_Table */ public function add_row($args = array()) { - $args = func_get_args(); - $this->rows[] = $this->_prep_args($args); + $this->rows[] = $this->_prep_args(func_get_args()); + return $this; } // -------------------------------------------------------------------- @@ -241,26 +242,14 @@ class CI_Table { // If there is no $args[0], skip this and treat as an associative array // This can happen if there is only a single key, for example this is passed to table->generate // array(array('foo'=>'bar')) - if (isset($args[0]) && count($args) === 1 && is_array($args[0])) + if (isset($args[0]) && count($args) === 1 && is_array($args[0]) && ! isset($args[0]['data'])) { - // args sent as indexed array - if ( ! isset($args[0]['data'])) - { - foreach ($args[0] as $key => $val) - { - $args[$key] = (is_array($val) && isset($val['data'])) ? $val : array('data' => $val); - } - } + $args = $args[0]; } - else + + foreach ($args as $key => $val) { - foreach ($args as $key => $val) - { - if ( ! is_array($val)) - { - $args[$key] = array('data' => $val); - } - } + is_array($val) OR $args[$key] = array('data' => $val); } return $args; @@ -271,8 +260,8 @@ class CI_Table { /** * Add a table caption * - * @param string - * @return void + * @param string $caption + * @return CI_Table */ public function set_caption($caption) { @@ -284,28 +273,27 @@ class CI_Table { /** * Generate the table * - * @param mixed + * @param mixed $table_data * @return string */ public function generate($table_data = NULL) { // The table data can optionally be passed to this function // either as a database result object or an array - if ($table_data !== NULL) + if ( ! empty($table_data)) { - if (is_object($table_data)) + if ($table_data instanceof CI_DB_result) { - $this->_set_from_object($table_data); + $this->_set_from_db_result($table_data); } elseif (is_array($table_data)) { - $set_heading = (count($this->heading) !== 0 OR $this->auto_heading !== FALSE); - $this->_set_from_array($table_data, $set_heading); + $this->_set_from_array($table_data); } } // Is there anything to display? No? Smite them! - if (count($this->heading) === 0 && count($this->rows) === 0) + if (empty($this->heading) && empty($this->rows)) { return 'Undefined table data'; } @@ -313,8 +301,11 @@ class CI_Table { // Compile and validate the template date $this->_compile_template(); - // set a custom cell manipulation function to a locally scoped variable so its callable - $function = $this->function; + // Validate a possibly existing custom cell manipulation function + if (isset($this->function) && ! is_callable($this->function)) + { + $this->function = NULL; + } // Build the table! @@ -323,11 +314,11 @@ class CI_Table { // Add any caption here if ($this->caption) { - $out .= $this->newline.'<caption>'.$this->caption.'</caption>'.$this->newline; + $out .= '<caption>'.$this->caption.'</caption>'.$this->newline; } // Is there a table heading to display? - if (count($this->heading) > 0) + if ( ! empty($this->heading)) { $out .= $this->template['thead_open'].$this->newline.$this->template['heading_row_start'].$this->newline; @@ -350,7 +341,7 @@ class CI_Table { } // Build the table rows - if (count($this->rows) > 0) + if ( ! empty($this->rows)) { $out .= $this->template['tbody_open'].$this->newline; @@ -386,9 +377,9 @@ class CI_Table { { $out .= $this->empty_cells; } - elseif ($function !== FALSE && is_callable($function)) + elseif (isset($this->function)) { - $out .= call_user_func($function, $cell); + $out .= call_user_func($this->function, $cell); } else { @@ -417,13 +408,14 @@ class CI_Table { /** * Clears the table arrays. Useful if multiple tables are being generated * - * @return void + * @return CI_Table */ public function clear() { - $this->rows = array(); - $this->heading = array(); - $this->auto_heading = TRUE; + $this->rows = array(); + $this->heading = array(); + $this->auto_heading = TRUE; + return $this; } // -------------------------------------------------------------------- @@ -431,34 +423,20 @@ class CI_Table { /** * Set table data from a database result object * - * @param object + * @param CI_DB_result $db_result Database result object * @return void */ - protected function _set_from_object($query) + protected function _set_from_db_result($object) { - if ( ! is_object($query)) - { - return; - } - // First generate the headings from the table column names - if (count($this->heading) === 0) + if ($this->auto_heading === TRUE && empty($this->heading)) { - if ( ! is_callable(array($query, 'list_fields'))) - { - return; - } - - $this->heading = $this->_prep_args($query->list_fields()); + $this->heading = $this->_prep_args($object->list_fields()); } - // Next blast through the result array and build out the rows - if ($query->num_rows() > 0) + foreach ($object->result_array() as $row) { - foreach ($query->result_array() as $row) - { - $this->rows[] = $this->_prep_args($row); - } + $this->rows[] = $this->_prep_args($row); } } @@ -467,29 +445,19 @@ class CI_Table { /** * Set table data from an array * - * @param array - * @param bool + * @param array $data * @return void */ - protected function _set_from_array($data, $set_heading = TRUE) + protected function _set_from_array($data) { - if ( ! is_array($data) OR count($data) === 0) + if ($this->auto_heading === TRUE && empty($this->heading)) { - return FALSE; + $this->heading = $this->_prep_args(array_shift($data)); } - $i = 0; - foreach ($data as $row) + foreach ($data as &$row) { - // If a heading hasn't already been set we'll use the first row of the array as the heading - if ($i++ === 0 && count($data) > 1 && count($this->heading) === 0 && $set_heading === TRUE) - { - $this->heading = $this->_prep_args($row); - } - else - { - $this->rows[] = $this->_prep_args($row); - } + $this->rows[] = $this->_prep_args($row); } } @@ -528,31 +496,31 @@ class CI_Table { protected function _default_template() { return array( - 'table_open' => '<table border="0" cellpadding="4" cellspacing="0">', + 'table_open' => '<table border="0" cellpadding="4" cellspacing="0">', - 'thead_open' => '<thead>', - 'thead_close' => '</thead>', + 'thead_open' => '<thead>', + 'thead_close' => '</thead>', - 'heading_row_start' => '<tr>', - 'heading_row_end' => '</tr>', - 'heading_cell_start' => '<th>', - 'heading_cell_end' => '</th>', + 'heading_row_start' => '<tr>', + 'heading_row_end' => '</tr>', + 'heading_cell_start' => '<th>', + 'heading_cell_end' => '</th>', - 'tbody_open' => '<tbody>', - 'tbody_close' => '</tbody>', + 'tbody_open' => '<tbody>', + 'tbody_close' => '</tbody>', - 'row_start' => '<tr>', - 'row_end' => '</tr>', - 'cell_start' => '<td>', - 'cell_end' => '</td>', + 'row_start' => '<tr>', + 'row_end' => '</tr>', + 'cell_start' => '<td>', + 'cell_end' => '</td>', - 'row_alt_start' => '<tr>', - 'row_alt_end' => '</tr>', - 'cell_alt_start' => '<td>', - 'cell_alt_end' => '</td>', + 'row_alt_start' => '<tr>', + 'row_alt_end' => '</tr>', + 'cell_alt_start' => '<td>', + 'cell_alt_end' => '</td>', - 'table_close' => '</table>' - ); + 'table_close' => '</table>' + ); } } diff --git a/system/libraries/Trackback.php b/system/libraries/Trackback.php index 5a45be8dd..9fa4a8edb 100644 --- a/system/libraries/Trackback.php +++ b/system/libraries/Trackback.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -181,7 +181,14 @@ class CI_Trackback { if ($val !== 'url' && MB_ENABLED === TRUE) { - $_POST[$val] = mb_convert_encoding($_POST[$val], $this->charset, $this->data['charset']); + if (MB_ENABLED === TRUE) + { + $_POST[$val] = mb_convert_encoding($_POST[$val], $this->charset, $this->data['charset']); + } + elseif (ICONV_ENABLED === TRUE) + { + $_POST[$val] = @iconv($this->data['charset'], $this->charset.'//IGNORE', $_POST[$val]); + } } $_POST[$val] = ($val !== 'url') ? $this->convert_xml(strip_tags($_POST[$val])) : strip_tags($_POST[$val]); diff --git a/system/libraries/Typography.php b/system/libraries/Typography.php index dd79e850a..d5e4ee06b 100644 --- a/system/libraries/Typography.php +++ b/system/libraries/Typography.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 diff --git a/system/libraries/Unit_test.php b/system/libraries/Unit_test.php index 7a67c7276..cc882bc72 100644 --- a/system/libraries/Unit_test.php +++ b/system/libraries/Unit_test.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.3.1 @@ -81,7 +81,15 @@ class CI_Unit_test { * * @var array */ - protected $_test_items_visible = array(); + protected $_test_items_visible = array( + 'test_name', + 'test_datatype', + 'res_datatype', + 'result', + 'file', + 'line', + 'notes' + ); // -------------------------------------------------------------------- @@ -92,17 +100,6 @@ class CI_Unit_test { */ public function __construct() { - // These are the default items visible when a test is run. - $this->_test_items_visible = array ( - 'test_name', - 'test_datatype', - 'res_datatype', - 'result', - 'file', - 'line', - 'notes' - ); - log_message('debug', 'Unit Testing Class Initialized'); } @@ -113,10 +110,10 @@ class CI_Unit_test { * * Runs the supplied tests * - * @param array + * @param array $items * @return void */ - public function set_test_items($items = array()) + public function set_test_items($items) { if ( ! empty($items) && is_array($items)) { @@ -230,7 +227,7 @@ class CI_Unit_test { * * Causes the evaluation to use === rather than == * - * @param bool + * @param bool $state * @return void */ public function use_strict($state = TRUE) @@ -288,6 +285,7 @@ class CI_Unit_test { { $val = $line; } + $temp[$CI->lang->line('ut_'.$key, FALSE)] = $val; } @@ -396,4 +394,4 @@ function is_false($test) } /* End of file Unit_test.php */ -/* Location: ./system/libraries/Unit_test.php */ +/* Location: ./system/libraries/Unit_test.php */
\ No newline at end of file diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php index 15eb74bd5..983d832fd 100644 --- a/system/libraries/Upload.php +++ b/system/libraries/Upload.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -234,6 +234,13 @@ class CI_Upload { public $xss_clean = FALSE; /** + * Apache mod_mime fix flag + * + * @var bool + */ + public $mod_mime_fix = TRUE; + + /** * Temporary filename prefix * * @var string @@ -256,6 +263,13 @@ class CI_Upload { */ protected $_file_name_override = ''; + /** + * CI Singleton + * + * @var object + */ + protected $CI; + // -------------------------------------------------------------------- /** @@ -272,6 +286,7 @@ class CI_Upload { } $this->mimes =& get_mimes(); + $this->CI =& get_instance(); log_message('debug', 'Upload Class Initialized'); } @@ -314,6 +329,7 @@ class CI_Upload { 'remove_spaces' => TRUE, 'detect_mime' => TRUE, 'xss_clean' => FALSE, + 'mod_mime_fix' => TRUE, 'temp_prefix' => 'temp_file_', 'client_name' => '' ); @@ -471,8 +487,7 @@ class CI_Upload { } // Sanitize the file name for security - $CI =& get_instance(); - $this->file_name = $CI->security->sanitize_filename($this->file_name); + $this->file_name = $this->CI->security->sanitize_filename($this->file_name); // Truncate the file name if it's too long if ($this->max_filename > 0) @@ -1073,8 +1088,7 @@ class CI_Upload { return FALSE; } - $CI =& get_instance(); - return $CI->security->xss_clean($data, TRUE); + return $this->CI->security->xss_clean($data, TRUE); } // -------------------------------------------------------------------- @@ -1087,17 +1101,13 @@ class CI_Upload { */ public function set_error($msg) { - $CI =& get_instance(); - $CI->lang->load('upload'); + $this->CI->lang->load('upload'); - if ( ! is_array($msg)) - { - $msg = array($msg); - } + is_array($msg) OR $msg = array($msg); foreach ($msg as $val) { - $msg = ($CI->lang->line($val) === FALSE) ? $val : $CI->lang->line($val); + $msg = ($this->CI->lang->line($val) === FALSE) ? $val : $this->CI->lang->line($val); $this->error_msg[] = $msg; log_message('error', $msg); } @@ -1148,7 +1158,7 @@ class CI_Upload { */ protected function _prep_filename($filename) { - if (strpos($filename, '.') === FALSE OR $this->allowed_types === '*') + if ($this->mod_mime_fix === FALSE OR $this->allowed_types === '*' OR strpos($filename, '.') === FALSE) { return $filename; } @@ -1245,7 +1255,7 @@ class CI_Upload { } } - if ( (bool) @ini_get('safe_mode') === FALSE && function_usable('shell_exec')) + if ((bool) @ini_get('safe_mode') === FALSE && function_usable('shell_exec')) { $mime = @shell_exec($cmd); if (strlen($mime) > 0) diff --git a/system/libraries/User_agent.php b/system/libraries/User_agent.php index 50ac9be98..9bab8666e 100644 --- a/system/libraries/User_agent.php +++ b/system/libraries/User_agent.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -145,6 +145,15 @@ class CI_User_agent { public $robot = ''; /** + * HTTP Referer + * + * @var mixed + */ + public $referer; + + // -------------------------------------------------------------------- + + /** * Constructor * * Sets the User Agent and runs the compilation routine @@ -282,7 +291,7 @@ class CI_User_agent { { foreach ($this->browsers as $key => $val) { - if (preg_match('|'.preg_quote($key).'.*?([0-9\.]+)|i', $this->agent, $match)) + if (preg_match('|'.$key.'.*?([0-9\.]+)|i', $this->agent, $match)) { $this->is_browser = TRUE; $this->version = $match[1]; @@ -358,7 +367,7 @@ class CI_User_agent { { if ((count($this->languages) === 0) && ! empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { - $this->languages = explode(',', preg_replace('/(;q=[0-9\.]+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_LANGUAGE'])))); + $this->languages = explode(',', preg_replace('/(;\s?q=[0-9\.]+)|\s/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_LANGUAGE'])))); } if (count($this->languages) === 0) @@ -378,7 +387,7 @@ class CI_User_agent { { if ((count($this->charsets) === 0) && ! empty($_SERVER['HTTP_ACCEPT_CHARSET'])) { - $this->charsets = explode(',', preg_replace('/(;q=.+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_CHARSET'])))); + $this->charsets = explode(',', preg_replace('/(;\s?q=.+)|\s/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_CHARSET'])))); } if (count($this->charsets) === 0) @@ -471,24 +480,22 @@ class CI_User_agent { */ public function is_referral() { - static $result; - - if ( ! isset($result)) + if ( ! isset($this->referer)) { if (empty($_SERVER['HTTP_REFERER'])) { - $result = FALSE; + $this->referer = FALSE; } else { $referer_host = @parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST); $own_host = parse_url(config_item('base_url'), PHP_URL_HOST); - $result = ($referer_host && $referer_host !== $own_host); + $this->referer = ($referer_host && $referer_host !== $own_host); } } - return $result; + return $this->referer; } // -------------------------------------------------------------------- @@ -634,6 +641,34 @@ class CI_User_agent { return in_array(strtolower($charset), $this->charsets(), TRUE); } + // -------------------------------------------------------------------- + + /** + * Parse a custom user-agent string + * + * @param string $string + * @return void + */ + public function parse($string) + { + // Reset values + $this->is_browser = FALSE; + $this->is_robot = FALSE; + $this->is_mobile = FALSE; + $this->browser = ''; + $this->version = ''; + $this->mobile = ''; + $this->robot = ''; + + // Set the new user-agent string and parse it, unless empty + $this->agent = $string; + + if ( ! empty($string)) + { + $this->_compile_data(); + } + } + } /* End of file User_agent.php */ diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php index 16c5b0ed8..83dc00e45 100644 --- a/system/libraries/Xmlrpc.php +++ b/system/libraries/Xmlrpc.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -348,6 +348,11 @@ class CI_Xmlrpc { $parts = parse_url($url); + if (isset($parts['user'], $parts['pass'])) + { + $parts['host'] = $parts['user'].':'.$parts['pass'].'@'.$parts['host']; + } + $path = isset($parts['path']) ? $parts['path'] : '/'; if ( ! empty($parts['query'])) @@ -569,6 +574,21 @@ class XML_RPC_Client extends CI_Xmlrpc public $port = 80; /** + * + * Server username + * + * @var string + */ + public $username; + + /** + * Server password + * + * @var string + */ + public $password; + + /** * Proxy hostname * * @var string @@ -626,8 +646,16 @@ class XML_RPC_Client extends CI_Xmlrpc { parent::__construct(); + $url = parse_url('http://'.$server); + + if (isset($url['user'], $url['pass'])) + { + $this->username = $url['user']; + $this->password = $url['pass']; + } + $this->port = $port; - $this->server = $server; + $this->server = $url['host']; $this->path = $path; $this->proxy = $proxy; $this->proxy_port = $proxy_port; @@ -691,11 +719,20 @@ class XML_RPC_Client extends CI_Xmlrpc $op = 'POST '.$this->path.' HTTP/1.0'.$r .'Host: '.$this->server.$r .'Content-Type: text/xml'.$r + .(isset($this->username, $this->password) ? 'Authorization: Basic '.base64_encode($this->username.':'.$this->password).$r : '') .'User-Agent: '.$this->xmlrpcName.$r .'Content-Length: '.strlen($msg->payload).$r.$r .$msg->payload; - if ( ! fwrite($fp, $op, strlen($op))) + for ($written = 0, $length = strlen($op); $written < $length; $written += $result) + { + if (($result = fwrite($fp, substr($op, $written))) === FALSE) + { + break; + } + } + + if ($result === FALSE) { error_log($this->xmlrpcstr['http_error']); return new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']); @@ -855,10 +892,10 @@ class XML_RPC_Response /** * Decode * - * @param mixed + * @param mixed $array * @return array */ - public function decode($array = FALSE) + public function decode($array = NULL) { $CI =& get_instance(); @@ -870,9 +907,9 @@ class XML_RPC_Response { $array[$key] = $this->decode($array[$key]); } - else + elseif ($this->xss_clean) { - $array[$key] = ($this->xss_clean) ? $CI->security->xss_clean($array[$key]) : $array[$key]; + $array[$key] = $CI->security->xss_clean($array[$key]); } } @@ -885,9 +922,9 @@ class XML_RPC_Response { $result = $this->decode($result); } - else + elseif ($this->xss_clean) { - $result = ($this->xss_clean) ? $CI->security->xss_clean($result) : $result; + $result = $CI->security->xss_clean($result); } return $result; @@ -1084,15 +1121,15 @@ class XML_RPC_Message extends CI_Xmlrpc //------------------------------------- $parser = xml_parser_create($this->xmlrpc_defencoding); - - $this->xh[$parser] = array( - 'isf' => 0, - 'ac' => '', - 'headers' => array(), - 'stack' => array(), - 'valuestack' => array(), - 'isf_reason' => 0 - ); + $pname = (string) $parser; + $this->xh[$pname] = array( + 'isf' => 0, + 'ac' => '', + 'headers' => array(), + 'stack' => array(), + 'valuestack' => array(), + 'isf_reason' => 0 + ); xml_set_object($parser, $this); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, TRUE); @@ -1108,7 +1145,7 @@ class XML_RPC_Message extends CI_Xmlrpc { break; } - $this->xh[$parser]['headers'][] = $line; + $this->xh[$pname]['headers'][] = $line; } $data = implode("\r\n", $lines); @@ -1126,18 +1163,18 @@ class XML_RPC_Message extends CI_Xmlrpc xml_parser_free($parser); // Got ourselves some badness, it seems - if ($this->xh[$parser]['isf'] > 1) + if ($this->xh[$pname]['isf'] > 1) { if ($this->debug === TRUE) { - echo "---Invalid Return---\n".$this->xh[$parser]['isf_reason']."---Invalid Return---\n\n"; + echo "---Invalid Return---\n".$this->xh[$pname]['isf_reason']."---Invalid Return---\n\n"; } - return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']); + return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return'].' '.$this->xh[$pname]['isf_reason']); } - elseif ( ! is_object($this->xh[$parser]['value'])) + elseif ( ! is_object($this->xh[$pname]['value'])) { - return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']); + return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return'].' '.$this->xh[$pname]['isf_reason']); } // Display XML content for debugging @@ -1145,10 +1182,10 @@ class XML_RPC_Message extends CI_Xmlrpc { echo '<pre>'; - if (count($this->xh[$parser]['headers'] > 0)) + if (count($this->xh[$pname]['headers'] > 0)) { echo "---HEADERS---\n"; - foreach ($this->xh[$parser]['headers'] as $header) + foreach ($this->xh[$pname]['headers'] as $header) { echo $header."\n"; } @@ -1156,13 +1193,13 @@ class XML_RPC_Message extends CI_Xmlrpc } echo "---DATA---\n".htmlspecialchars($data)."\n---END DATA---\n\n---PARSED---\n"; - var_dump($this->xh[$parser]['value']); + var_dump($this->xh[$pname]['value']); echo "\n---END PARSED---</pre>"; } // Send response - $v = $this->xh[$parser]['value']; - if ($this->xh[$parser]['isf']) + $v = $this->xh[$pname]['value']; + if ($this->xh[$pname]['isf']) { $errno_v = $v->me['struct']['faultCode']; $errstr_v = $v->me['struct']['faultString']; @@ -1181,7 +1218,7 @@ class XML_RPC_Message extends CI_Xmlrpc $r = new XML_RPC_Response($v); } - $r->headers = $this->xh[$parser]['headers']; + $r->headers = $this->xh[$pname]['headers']; return $r; } @@ -1212,6 +1249,8 @@ class XML_RPC_Message extends CI_Xmlrpc */ public function open_tag($the_parser, $name) { + $the_parser = (string) $the_parser; + // If invalid nesting, then return if ($this->xh[$the_parser]['isf'] > 1) return; @@ -1311,6 +1350,8 @@ class XML_RPC_Message extends CI_Xmlrpc */ public function closing_tag($the_parser, $name) { + $the_parser = (string) $the_parser; + if ($this->xh[$the_parser]['isf'] > 1) return; // Remove current element from stack and set variable @@ -1443,6 +1484,8 @@ class XML_RPC_Message extends CI_Xmlrpc */ public function character_data($the_parser, $data) { + $the_parser = (string) $the_parser; + if ($this->xh[$the_parser]['isf'] > 1) return; // XML Fault found already // If a value has not been found @@ -1480,14 +1523,14 @@ class XML_RPC_Message extends CI_Xmlrpc /** * Output parameters * - * @param array + * @param array $array * @return array */ - public function output_parameters($array = FALSE) + public function output_parameters(array $array = array()) { $CI =& get_instance(); - if (is_array($array)) + if ( ! empty($array)) { while (list($key) = each($array)) { @@ -1495,11 +1538,11 @@ class XML_RPC_Message extends CI_Xmlrpc { $array[$key] = $this->output_parameters($array[$key]); } - else + elseif ($key !== 'bits' && $this->xss_clean) { // 'bits' is for the MetaWeblog API image bits // @todo - this needs to be made more general purpose - $array[$key] = ($key === 'bits' OR $this->xss_clean === FALSE) ? $array[$key] : $CI->security->xss_clean($array[$key]); + $array[$key] = $CI->security->xss_clean($array[$key]); } } @@ -1684,7 +1727,7 @@ class XML_RPC_Values extends CI_Xmlrpc { if ($this->mytype !== 0) { - echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />'; + echo '<strong>XML_RPC_Values</strong>: already initialized as a ['.$this->kindOf().']<br />'; return 0; } @@ -1705,7 +1748,7 @@ class XML_RPC_Values extends CI_Xmlrpc { if ($this->mytype !== 0) { - echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />'; + echo '<strong>XML_RPC_Values</strong>: already initialized as a ['.$this->kindOf().']<br />'; return 0; } $this->mytype = $this->xmlrpcTypes['struct']; diff --git a/system/libraries/Xmlrpcs.php b/system/libraries/Xmlrpcs.php index d263d789d..e8e06d756 100644 --- a/system/libraries/Xmlrpcs.php +++ b/system/libraries/Xmlrpcs.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -384,17 +384,13 @@ class CI_Xmlrpcs extends CI_Xmlrpc { { return call_user_func(array($this, $method_parts[1]), $m); } + elseif ($this->object === FALSE) + { + return get_instance()->$method_parts[1]($m); + } else { - if ($this->object === FALSE) - { - $CI =& get_instance(); - return $CI->$method_parts[1]($m); - } - else - { - return $this->object->$method_parts[1]($m); - } + return $this->object->$method_parts[1]($m); } } else diff --git a/system/libraries/Zip.php b/system/libraries/Zip.php index 6608f050e..40b661abc 100644 --- a/system/libraries/Zip.php +++ b/system/libraries/Zip.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 1.0 @@ -103,12 +103,12 @@ class CI_Zip { * * Lets you add a virtual directory into which you can place files. * - * @param mixed the directory name. Can be string or array + * @param mixed $directory the directory name. Can be string or array * @return void */ public function add_dir($directory) { - foreach ( (array) $directory as $dir) + foreach ((array) $directory as $dir) { if ( ! preg_match('|.+/$|', $dir)) { @@ -127,7 +127,7 @@ class CI_Zip { * * If this is a newly created file/dir, we will set the time to 'now' * - * @param string path to file + * @param string $dir path to file * @return array filemtime/filemdate */ protected function _get_mod_time($dir) @@ -146,9 +146,9 @@ class CI_Zip { /** * Add Directory * - * @param string the directory name - * @param int - * @param int + * @param string $dir the directory name + * @param int $file_mtime + * @param int $file_mdate * @return void */ protected function _add_dir($dir, $file_mtime, $file_mdate) @@ -199,8 +199,8 @@ class CI_Zip { * in the filename it will be placed within a directory. Make * sure you use add_dir() first to create the folder. * - * @param mixed - * @param string + * @param mixed $filepath A single filepath or an array of file => data pairs + * @param string $data Single file contents * @return void */ public function add_data($filepath, $data = NULL) @@ -225,10 +225,10 @@ class CI_Zip { /** * Add Data to Zip * - * @param string the file name/path - * @param string the data to be encoded - * @param int - * @param int + * @param string $filepath the file name/path + * @param string $data the data to be encoded + * @param int $file_mtime + * @param int $file_mdate * @return void */ protected function _add_data($filepath, $data, $file_mtime, $file_mdate) @@ -278,23 +278,26 @@ class CI_Zip { /** * Read the contents of a file and add it to the zip * - * @param string - * @param bool + * @param string $path + * @param bool $archive_filepath * @return bool */ - public function read_file($path, $preserve_filepath = FALSE) + public function read_file($path, $archive_filepath = FALSE) { - if ( ! file_exists($path)) + if (file_exists($path) && FALSE !== ($data = file_get_contents($path))) { - return FALSE; - } - - if (FALSE !== ($data = file_get_contents($path))) - { - $name = str_replace('\\', '/', $path); - if ($preserve_filepath === FALSE) + if (is_string($archive_filepath)) { - $name = preg_replace('|.*/(.+)|', '\\1', $name); + $name = str_replace('\\', '/', $archive_filepath); + } + else + { + $name = str_replace('\\', '/', $path); + + if ($archive_filepath === FALSE) + { + $name = preg_replace('|.*/(.+)|', '\\1', $name); + } } $this->add_data($name, $data); @@ -313,9 +316,9 @@ class CI_Zip { * sub-folders) and creates a zip based on it. Whatever directory structure * is in the original file path will be recreated in the zip file. * - * @param string path to source - * @param bool - * @param bool + * @param string $path path to source directory + * @param bool $preserve_filepath + * @param string $root_path * @return bool */ public function read_dir($path, $preserve_filepath = TRUE, $root_path = NULL) @@ -389,7 +392,7 @@ class CI_Zip { * * Lets you write a file * - * @param string the file name + * @param string $filepath the file name * @return bool */ public function archive($filepath) @@ -400,11 +403,19 @@ class CI_Zip { } flock($fp, LOCK_EX); - fwrite($fp, $this->get_zip()); + + for ($written = 0, $data = $this->get_zip(), $length = strlen($data); $written < $length; $written += $result) + { + if (($result = fwrite($fp, substr($data, $written))) === FALSE) + { + break; + } + } + flock($fp, LOCK_UN); fclose($fp); - return TRUE; + return is_int($result); } // -------------------------------------------------------------------- @@ -412,7 +423,7 @@ class CI_Zip { /** * Download * - * @param string the file name + * @param string $filename the file name * @return void */ public function download($filename = 'backup.zip') @@ -422,8 +433,7 @@ class CI_Zip { $filename .= '.zip'; } - $CI =& get_instance(); - $CI->load->helper('download'); + get_instance()->load->helper('download'); $get_zip = $this->get_zip(); $zip_content =& $get_zip; diff --git a/tests/Bootstrap.php b/tests/Bootstrap.php index c98d88531..439c7fdab 100644 --- a/tests/Bootstrap.php +++ b/tests/Bootstrap.php @@ -40,6 +40,32 @@ isset($_SERVER['REMOTE_ADDR']) OR $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; // Prep our test environment include_once $dir.'/mocks/core/common.php'; include_once SYSTEM_PATH.'core/Common.php'; + + +if (extension_loaded('mbstring')) +{ + defined('MB_ENABLED') OR define('MB_ENABLED', TRUE); + mb_internal_encoding('UTF-8'); + mb_substitute_character('none'); +} +else +{ + defined('MB_ENABLED') OR define('MB_ENABLED', FALSE); +} + +if (extension_loaded('iconv')) +{ + defined('ICONV_ENABLED') OR define('ICONV_ENABLED', TRUE); + iconv_set_encoding('internal_encoding', 'UTF-8'); +} +else +{ + defined('ICONV_ENABLED') OR define('ICONV_ENABLED', FALSE); +} + +include_once SYSTEM_PATH.'core/compat/mbstring.php'; +include_once SYSTEM_PATH.'core/compat/password.php'; + include_once $dir.'/mocks/autoloader.php'; spl_autoload_register('autoload'); diff --git a/tests/codeigniter/core/Benchmark_test.php b/tests/codeigniter/core/Benchmark_test.php index aff736a40..7fd0727e2 100644 --- a/tests/codeigniter/core/Benchmark_test.php +++ b/tests/codeigniter/core/Benchmark_test.php @@ -27,10 +27,34 @@ class Benchmark_test extends CI_TestCase { $this->assertEmpty($this->benchmark->elapsed_time('undefined_point')); $this->benchmark->mark('code_start'); - sleep(1); $this->benchmark->mark('code_end'); + // Override values, because time isn't testable, but make sure the markers were set + if (isset($this->benchmark->marker['code_start']) && is_float($this->benchmark->marker['code_start'])) + { + $this->benchmark->marker['code_start'] = 1389956144.1944; + } + + if (isset($this->benchmark->marker['code_end']) && is_float($this->benchmark->marker['code_end'])) + { + $this->benchmark->marker['code_end'] = 1389956145.1946; + } + $this->assertEquals('1', $this->benchmark->elapsed_time('code_start', 'code_end', 0)); + $this->assertEquals('1.0', $this->benchmark->elapsed_time('code_start', 'code_end', 1)); + $this->assertEquals('1.00', $this->benchmark->elapsed_time('code_start', 'code_end', 2)); + $this->assertEquals('1.000', $this->benchmark->elapsed_time('code_start', 'code_end', 3)); + $this->assertEquals('1.0002', $this->benchmark->elapsed_time('code_start', 'code_end', 4)); + $this->assertEquals('1.0002', $this->benchmark->elapsed_time('code_start', 'code_end')); + + // Test with non-existing 2nd marker, but again - we need to override the value + $this->benchmark->elapsed_time('code_start', 'code_end2'); + if (isset($this->benchmark->marker['code_end2']) && is_float($this->benchmark->marker['code_end2'])) + { + $this->benchmark->marker['code_end2'] = 1389956146.2046; + } + + $this->assertEquals('2.0102', $this->benchmark->elapsed_time('code_start', 'code_end2')); } // -------------------------------------------------------------------- diff --git a/tests/codeigniter/core/Config_test.php b/tests/codeigniter/core/Config_test.php index ba9a2c070..6a0a7a35f 100644 --- a/tests/codeigniter/core/Config_test.php +++ b/tests/codeigniter/core/Config_test.php @@ -180,7 +180,7 @@ class Config_test extends CI_TestCase { $cfg = array( 'one' => 'prime', 'two' => 2, - 'three' => true + 'three' => TRUE ); $this->ci_vfs_create($file.'.php', '<?php $config = '.var_export($cfg, TRUE).';', $this->ci_app_root, 'config'); $this->assertTrue($this->config->load($file, TRUE)); diff --git a/tests/codeigniter/core/Input_test.php b/tests/codeigniter/core/Input_test.php index 0a98e556c..95833fc91 100644 --- a/tests/codeigniter/core/Input_test.php +++ b/tests/codeigniter/core/Input_test.php @@ -138,13 +138,24 @@ class Input_test extends CI_TestCase { public function test_valid_ip() { - $ip_v4 = '192.18.0.1'; - $this->assertTrue($this->input->valid_ip($ip_v4)); + $this->assertTrue($this->input->valid_ip('192.18.0.1')); + $this->assertTrue($this->input->valid_ip('192.18.0.1', 'ipv4')); + $this->assertFalse($this->input->valid_ip('555.0.0.0')); + $this->assertFalse($this->input->valid_ip('2001:db8:0:85a3::ac1f:8001', 'ipv4')); + + // v6 tests + $this->assertFalse($this->input->valid_ip('192.18.0.1', 'ipv6')); + + $ip_v6 = array( + '2001:0db8:0000:85a3:0000:0000:ac1f:8001', + '2001:db8:0:85a3:0:0:ac1f:8001', + '2001:db8:0:85a3::ac1f:8001' + ); - $ip_v6 = array('2001:0db8:0000:85a3:0000:0000:ac1f:8001', '2001:db8:0:85a3:0:0:ac1f:8001', '2001:db8:0:85a3::ac1f:8001'); foreach ($ip_v6 as $ip) { $this->assertTrue($this->input->valid_ip($ip)); + $this->assertTrue($this->input->valid_ip($ip, 'ipv6')); } } @@ -171,4 +182,34 @@ class Input_test extends CI_TestCase { $this->assertTrue($this->input->is_ajax_request()); } + // -------------------------------------------------------------------- + + public function test_input_stream() + { + $this->markTestSkipped('TODO: Find a way to test input://'); + } + + // -------------------------------------------------------------------- + + public function test_set_cookie() + { + $this->markTestSkipped('TODO: Find a way to test HTTP headers'); + } + + public function test_ip_address() + { + // 127.0.0.1 is set in our Bootstrap file + $this->assertEquals('127.0.0.1', $this->input->ip_address()); + + // Invalid + $_SERVER['REMOTE_ADDR'] = 'invalid_ip_address'; + $this->input->ip_address = FALSE; // reset cached value + $this->assertEquals('0.0.0.0', $this->input->ip_address()); + + // TODO: Add proxy_ips tests + + // Back to reality + $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; // back to reality + } + }
\ No newline at end of file diff --git a/tests/codeigniter/core/Loader_test.php b/tests/codeigniter/core/Loader_test.php index 9ad3ca6b9..93ca5b223 100644 --- a/tests/codeigniter/core/Loader_test.php +++ b/tests/codeigniter/core/Loader_test.php @@ -31,15 +31,12 @@ class Loader_test extends CI_TestCase { $this->assertFalse($this->load->is_loaded(ucfirst($lib))); // Test loading as an array. - $this->assertNull($this->load->library(array($lib))); + $this->assertInstanceOf('CI_Loader', $this->load->library(array($lib))); $this->assertTrue(class_exists($class), $class.' does not exist'); $this->assertAttributeInstanceOf($class, $lib, $this->ci_obj); - // Test no lib given - $this->assertNull($this->load->library()); - // Test a string given to params - $this->assertNull($this->load->library($lib, ' ')); + $this->assertInstanceOf('CI_Loader', $this->load->library($lib, ' ')); // Create library w/o class $lib = 'bad_test_lib'; @@ -50,7 +47,7 @@ class Loader_test extends CI_TestCase { 'RuntimeException', 'CI Error: Unable to load the requested class: '.ucfirst($lib) ); - $this->assertNull($this->load->library($lib)); + $this->assertInstanceOf('CI_Loader', $this->load->library($lib)); } // -------------------------------------------------------------------- @@ -66,7 +63,7 @@ class Loader_test extends CI_TestCase { $this->ci_vfs_create($ext, '<?php class '.$ext.' extends '.$class.' { }', $this->ci_app_root, 'libraries'); // Test loading with extension - $this->assertNull($this->load->library($lib)); + $this->assertInstanceOf('CI_Loader', $this->load->library($lib)); $this->assertTrue(class_exists($class), $class.' does not exist'); $this->assertTrue(class_exists($ext), $ext.' does not exist'); $this->assertAttributeInstanceOf($class, $name, $this->ci_obj); @@ -74,13 +71,13 @@ class Loader_test extends CI_TestCase { // Test reloading with object name $obj = 'exttest'; - $this->assertNull($this->load->library($lib, NULL, $obj)); + $this->assertInstanceOf('CI_Loader', $this->load->library($lib, NULL, $obj)); $this->assertAttributeInstanceOf($class, $obj, $this->ci_obj); $this->assertAttributeInstanceOf($ext, $obj, $this->ci_obj); // Test reloading unset($this->ci_obj->$name); - $this->assertNull($this->load->library($lib)); + $this->assertInstanceOf('CI_Loader', $this->load->library($lib)); $this->assertObjectNotHasAttribute($name, $this->ci_obj); // Create baseless library @@ -94,7 +91,7 @@ class Loader_test extends CI_TestCase { 'RuntimeException', 'CI Error: Unable to load the requested class: '.$lib ); - $this->assertNull($this->load->library($lib)); + $this->assertInstanceOf('CI_Loader', $this->load->library($lib)); } // -------------------------------------------------------------------- @@ -117,7 +114,7 @@ class Loader_test extends CI_TestCase { // Test object name and config $obj = 'testy'; - $this->assertNull($this->load->library($lib, NULL, $obj)); + $this->assertInstanceOf('CI_Loader', $this->load->library($lib, NULL, $obj)); $this->assertTrue(class_exists($class), $class.' does not exist'); $this->assertAttributeInstanceOf($class, $obj, $this->ci_obj); $this->assertEquals($cfg, $this->ci_obj->$obj->config); @@ -136,7 +133,7 @@ class Loader_test extends CI_TestCase { $this->ci_vfs_create(ucfirst($lib), '<?php class '.$class.' { }', $this->ci_app_root, 'libraries'); // Load library - $this->assertNull($this->load->library($lib)); + $this->assertInstanceOf('CI_Loader', $this->load->library($lib)); // Was the model class instantiated. $this->assertTrue(class_exists($class), $class.' does not exist'); @@ -158,20 +155,17 @@ class Loader_test extends CI_TestCase { $this->ci_vfs_create(ucfirst($driver), $content, $this->ci_base_root, 'libraries/'.$dir); // Test loading as an array. - $this->assertNull($this->load->driver(array($driver))); + $this->assertInstanceOf('CI_Loader', $this->load->driver(array($driver))); $this->assertTrue(class_exists($class), $class.' does not exist'); $this->assertAttributeInstanceOf($class, $driver, $this->ci_obj); // Test loading as a library with a name $obj = 'testdrive'; - $this->assertNull($this->load->library($driver, NULL, $obj)); + $this->assertInstanceOf('CI_Loader', $this->load->library($driver, NULL, $obj)); $this->assertAttributeInstanceOf($class, $obj, $this->ci_obj); - // Test no driver given - $this->assertFalse($this->load->driver()); - // Test a string given to params - $this->assertNull($this->load->driver($driver, ' ')); + $this->assertInstanceOf('CI_Loader', $this->load->driver($driver, ' ')); } // -------------------------------------------------------------------- @@ -186,14 +180,14 @@ class Loader_test extends CI_TestCase { $this->ci_vfs_create($model, $content, $this->ci_app_root, 'models'); // Load model - $this->assertNull($this->load->model($model)); + $this->assertInstanceOf('CI_Loader', $this->load->model($model)); // Was the model class instantiated. $this->assertTrue(class_exists($model)); $this->assertObjectHasAttribute($model, $this->ci_obj); // Test no model given - $this->assertNull($this->load->model('')); + $this->assertInstanceOf('CI_Loader', $this->load->model('')); } // -------------------------------------------------------------------- @@ -212,7 +206,7 @@ class Loader_test extends CI_TestCase { // Load model $name = 'testors'; - $this->assertNull($this->load->model($subdir.'/'.$model, $name)); + $this->assertInstanceOf('CI_Loader', $this->load->model($subdir.'/'.$model, $name)); // Was the model class instantiated? $this->assertTrue(class_exists($model)); @@ -246,8 +240,8 @@ class Loader_test extends CI_TestCase { // public function testDatabase() // { - // $this->assertNull($this->load->database()); - // $this->assertNull($this->load->dbutil()); + // $this->assertInstanceOf('CI_Loader', $this->load->database()); + // $this->assertInstanceOf('CI_Loader', $this->load->dbutil()); // } // -------------------------------------------------------------------- @@ -271,7 +265,7 @@ class Loader_test extends CI_TestCase { $this->ci_instance_var('output', $output); // Test view output - $this->assertNull($this->load->view($view, array($var => $value))); + $this->assertInstanceOf('CI_Loader', $this->load->view($view, array($var => $value))); } // -------------------------------------------------------------------- @@ -317,8 +311,8 @@ class Loader_test extends CI_TestCase { $val1 = 'bar'; $key2 = 'boo'; $val2 = 'hoo'; - $this->assertNull($this->load->vars(array($key1 => $val1))); - $this->assertNull($this->load->vars($key2, $val2)); + $this->assertInstanceOf('CI_Loader', $this->load->vars(array($key1 => $val1))); + $this->assertInstanceOf('CI_Loader', $this->load->vars($key2, $val2)); $this->assertEquals($val1, $this->load->get_var($key1)); $this->assertEquals(array($key1 => $val1, $key2 => $val2), $this->load->get_vars()); } @@ -330,16 +324,16 @@ class Loader_test extends CI_TestCase { // Create helper in VFS $helper = 'test'; $func = '_my_helper_test_func'; - $content = '<?php function '.$func.'() { return true; } '; + $content = '<?php function '.$func.'() { return TRUE; } '; $this->ci_vfs_create($helper.'_helper', $content, $this->ci_base_root, 'helpers'); // Create helper extension $exfunc = '_my_extension_func'; - $content = '<?php function '.$exfunc.'() { return true; } '; + $content = '<?php function '.$exfunc.'() { return TRUE; } '; $this->ci_vfs_create($this->prefix.$helper.'_helper', $content, $this->ci_app_root, 'helpers'); // Load helper - $this->assertNull($this->load->helper($helper)); + $this->assertInstanceOf('CI_Loader', $this->load->helper($helper)); $this->assertTrue(function_exists($func), $func.' does not exist'); $this->assertTrue(function_exists($exfunc), $exfunc.' does not exist'); @@ -379,12 +373,12 @@ class Loader_test extends CI_TestCase { $helpers[] = $helper; $func = '_my_helper_test_func'.$i; $funcs[] = $func; - $files[$helper.'_helper'] = '<?php function '.$func.'() { return true; } '; + $files[$helper.'_helper'] = '<?php function '.$func.'() { return TRUE; } '; } $this->ci_vfs_create($files, NULL, $this->ci_base_root, 'helpers'); // Load helpers - $this->assertNull($this->load->helpers($helpers)); + $this->assertInstanceOf('CI_Loader', $this->load->helpers($helpers)); // Verify helper existence foreach ($funcs as $func) { @@ -401,7 +395,7 @@ class Loader_test extends CI_TestCase { $lang = $this->getMock('CI_Lang', array('load')); $lang->expects($this->once())->method('load')->with($file); $this->ci_instance_var('lang', $lang); - $this->assertNull($this->load->language($file)); + $this->assertInstanceOf('CI_Loader', $this->load->language($file)); } // -------------------------------------------------------------------- @@ -419,24 +413,24 @@ class Loader_test extends CI_TestCase { // Add path and verify $path = APPPATH.$dir.'/'; - $this->assertNull($this->load->add_package_path($path)); + $this->assertInstanceOf('CI_Loader', $this->load->add_package_path($path)); $this->assertContains($path, $this->load->get_package_paths(TRUE)); // Test successful load - $this->assertNull($this->load->library($lib)); + $this->assertInstanceOf('CI_Loader', $this->load->library($lib)); $this->assertTrue(class_exists($class), $class.' does not exist'); // Add another path $path2 = APPPATH.'another/'; - $this->assertNull($this->load->add_package_path($path2)); + $this->assertInstanceOf('CI_Loader', $this->load->add_package_path($path2)); $this->assertContains($path2, $this->load->get_package_paths(TRUE)); // Remove last path - $this->assertNull($this->load->remove_package_path()); + $this->assertInstanceOf('CI_Loader', $this->load->remove_package_path()); $this->assertNotContains($path2, $this->load->get_package_paths(TRUE)); // Remove path and verify restored paths - $this->assertNull($this->load->remove_package_path($path)); + $this->assertInstanceOf('CI_Loader', $this->load->remove_package_path($path)); $this->assertEquals($paths, $this->load->get_package_paths(TRUE)); // Test failed load without path @@ -463,7 +457,7 @@ class Loader_test extends CI_TestCase { // Create helper in VFS $helper = 'autohelp'; $hlp_func = '_autohelp_test_func'; - $content = '<?php function '.$hlp_func.'() { return true; }'; + $content = '<?php function '.$hlp_func.'() { return TRUE; }'; $this->ci_vfs_create($helper.'_helper', $content, $this->ci_app_root, 'helpers'); // Create library in VFS diff --git a/tests/codeigniter/core/Model_test.php b/tests/codeigniter/core/Model_test.php new file mode 100644 index 000000000..80dc97b3b --- /dev/null +++ b/tests/codeigniter/core/Model_test.php @@ -0,0 +1,37 @@ +<?php + +class Model_test extends CI_TestCase { + + private $ci_obj; + + public function set_up() + { + $loader = $this->ci_core_class('loader'); + $this->load = new $loader(); + $this->ci_obj = $this->ci_instance(); + $this->ci_set_core_class('model', 'CI_Model'); + + $model_code =<<<MODEL +<?php +class Test_model extends CI_Model { + + public \$property = 'foo'; + +} +MODEL; + + $this->ci_vfs_create('Test_model', $model_code, $this->ci_app_root, 'models'); + $this->load->model('test_model'); + } + + // -------------------------------------------------------------------- + + public function test__get() + { + $this->assertEquals('foo', $this->ci_obj->test_model->property); + + $this->ci_obj->controller_property = 'bar'; + $this->assertEquals('bar', $this->ci_obj->test_model->controller_property); + } + +}
\ No newline at end of file diff --git a/tests/codeigniter/core/Security_test.php b/tests/codeigniter/core/Security_test.php index 3f6e3b07a..433ad313f 100644 --- a/tests/codeigniter/core/Security_test.php +++ b/tests/codeigniter/core/Security_test.php @@ -5,7 +5,7 @@ class Security_test extends CI_TestCase { public function set_up() { // Set cookie for security test - $_COOKIE['ci_csrf_cookie'] = md5(uniqid(rand(), TRUE)); + $_COOKIE['ci_csrf_cookie'] = md5(uniqid(mt_rand(), TRUE)); // Set config for Security class $this->ci_set_config('csrf_protection', TRUE); diff --git a/tests/codeigniter/core/URI_test.php b/tests/codeigniter/core/URI_test.php index 7fa0e6265..6589c1f5a 100644 --- a/tests/codeigniter/core/URI_test.php +++ b/tests/codeigniter/core/URI_test.php @@ -26,6 +26,10 @@ class URI_test extends CI_TestCase { // -------------------------------------------------------------------- + /* + + This has been moved to the constructor + public function test_fetch_uri_string() { define('SELF', 'index.php'); @@ -86,9 +90,14 @@ class URI_test extends CI_TestCase { // uri_protocol: REQUEST_URI // uri_protocol: CLI } + */ // -------------------------------------------------------------------- + /* + + This has been moved into _set_uri_string() + public function test_explode_segments() { // Let's test the function's ability to clean up this mess @@ -107,16 +116,15 @@ class URI_test extends CI_TestCase { $this->assertEquals($a, $this->uri->segments); } } - + */ // -------------------------------------------------------------------- public function test_filter_uri() { - $this->uri->config->set_item('enable_query_strings', FALSE); - $this->uri->config->set_item('permitted_uri_chars', 'a-z 0-9~%.:_\-'); + $this->uri->_set_permitted_uri_chars('a-z 0-9~%.:_\-'); $str_in = 'abc01239~%.:_-'; - $str = $this->uri->_filter_uri($str_in); + $str = $this->uri->filter_uri($str_in); $this->assertEquals($str, $str_in); } @@ -126,11 +134,9 @@ class URI_test extends CI_TestCase { public function test_filter_uri_escaping() { // ensure escaping even if dodgey characters are permitted + $this->uri->_set_permitted_uri_chars('a-z 0-9~%.:_\-()$'); - $this->uri->config->set_item('enable_query_strings', FALSE); - $this->uri->config->set_item('permitted_uri_chars', 'a-z 0-9~%.:_\-()$'); - - $str = $this->uri->_filter_uri('$destroy_app(foo)'); + $str = $this->uri->filter_uri('$destroy_app(foo)'); $this->assertEquals($str, '$destroy_app(foo)'); } @@ -142,25 +148,8 @@ class URI_test extends CI_TestCase { $this->setExpectedException('RuntimeException'); $this->uri->config->set_item('enable_query_strings', FALSE); - $this->uri->config->set_item('permitted_uri_chars', 'a-z 0-9~%.:_\-'); - $this->uri->_filter_uri('$this()'); - } - - // -------------------------------------------------------------------- - - public function test_remove_url_suffix() - { - $this->uri->config->set_item('url_suffix', '.html'); - - $this->uri->uri_string = 'controller/method/index.html'; - $this->uri->_remove_url_suffix(); - - $this->assertEquals($this->uri->uri_string, 'controller/method/index'); - - $this->uri->uri_string = 'controller/method/index.htmlify.html'; - $this->uri->_remove_url_suffix(); - - $this->assertEquals($this->uri->uri_string, 'controller/method/index.htmlify'); + $this->uri->_set_permitted_uri_chars('a-z 0-9~%.:_\-'); + $this->uri->filter_uri('$this()'); } // -------------------------------------------------------------------- diff --git a/tests/codeigniter/core/Utf8_test.php b/tests/codeigniter/core/Utf8_test.php index caa7b6986..71299134e 100644 --- a/tests/codeigniter/core/Utf8_test.php +++ b/tests/codeigniter/core/Utf8_test.php @@ -11,10 +11,15 @@ class Utf8_test extends CI_TestCase { public function test_convert_to_utf8() { - $this->assertEquals( - $this->utf8->convert_to_utf8('òåñò', 'WINDOWS-1251'), - 'теÑÑ‚' - ); + $this->assertEquals('теÑÑ‚', $this->utf8->convert_to_utf8('òåñò', 'WINDOWS-1251')); + } + + // -------------------------------------------------------------------- + + public function test_is_ascii() + { + $this->assertTrue($this->utf8->is_ascii_test('foo bar')); + $this->assertFalse($this->utf8->is_ascii_test('теÑÑ‚')); } }
\ No newline at end of file diff --git a/tests/codeigniter/core/compat/mbstring_test.php b/tests/codeigniter/core/compat/mbstring_test.php new file mode 100644 index 000000000..415222446 --- /dev/null +++ b/tests/codeigniter/core/compat/mbstring_test.php @@ -0,0 +1,54 @@ +<?php + +class mbstring_test extends CI_TestCase { + + public function test_bootstrap() + { + if (MB_ENABLED) + { + return $this->markTestSkipped('ext/mbstring is loaded'); + } + + $this->assertTrue(function_exists('mb_strlen')); + $this->assertTrue(function_exists('mb_substr')); + } + + // ------------------------------------------------------------------------ + + /** + * @depends test_bootstrap + */ + public function test_mb_strlen() + { + $this->assertEquals(ICONV_ENABLED ? 4 : 8, mb_strlen('теÑÑ‚')); + $this->assertEquals(ICONV_ENABLED ? 4 : 8, mb_strlen('теÑÑ‚', 'UTF-8')); + } + + // ------------------------------------------------------------------------ + + /** + * @depends test_boostrap + */ + public function test_mb_strpos() + { + $this->assertEquals(ICONV_ENABLED ? 3 : 6, mb_strpos('теÑÑ‚', 'Ñ')); + $this->assertFalse(mb_strpos('теÑÑ‚', 'Ñ', 3)); + $this->assertEquals(ICONV_ENABLED ? 3 : 6, mb_strpos('теÑÑ‚', 'Ñ', 1, 'UTF-8')); + } + + // ------------------------------------------------------------------------ + + /** + * @depends test_boostrap + */ + public function test_mb_substr() + { + $this->assertEquals(ICONV_ENABLED ? 'Ñтинг' : 'еÑтинг', mb_substr('теÑтинг', 2)); + $this->assertEquals(ICONV_ENABLED ? 'нг' : 'г', mb_substr('теÑтинг', -2)); + $this->assertEquals(ICONV_ENABLED ? 'ÑÑ‚' : 'е', mb_substr('теÑтинг', 2, 2)); + $this->assertEquals(ICONV_ENABLED ? 'Ñтинг' : 'еÑтинг', mb_substr('теÑтинг', 2, 'UTF-8')); + $this->assertEquals(ICONV_ENABLED ? 'нг' : 'г', mb_substr('теÑтинг', -2, 'UTF-8')); + $this->assertEquals(ICONV_ENABLED ? 'ÑÑ‚' : 'е', mb_substr('теÑтинг', 2, 2, 'UTF-8')); + } + +}
\ No newline at end of file diff --git a/tests/codeigniter/core/compat/password_test.php b/tests/codeigniter/core/compat/password_test.php new file mode 100644 index 000000000..4014e7415 --- /dev/null +++ b/tests/codeigniter/core/compat/password_test.php @@ -0,0 +1,158 @@ +<?php + +class password_test extends CI_TestCase { + + public function test_bootstrap() + { + if (is_php('5.5')) + { + return $this->markTestSkipped('ext/standard/password is available on PHP 5.5'); + } + elseif ( ! is_php('5.3.7')) + { + $this->assertFalse(defined('PASSWORD_BCRYPT')); + return $this->markTestSkipped("PHP versions prior to 5.3.7 don't have the '2y' Blowfish version"); + } + elseif ( ! defined('CRYPT_BLOWFISH') OR CRYPT_BLOWFISH !== 1) + { + $this->assertFalse(defined('PASSWORD_BCRYPT')); + return $this->markTestSkipped('CRYPT_BLOWFISH is not available'); + } + + $this->assertTrue(defined('PASSWORD_BCRYPT')); + $this->assertTrue(defined('PASSWORD_DEFAULT')); + $this->assertEquals(1, PASSWORD_BCRYPT); + $this->assertEquals(PASSWORD_BCRYPT, PASSWORD_DEFAULT); + $this->assertTrue(function_exists('password_get_info')); + $this->assertTrue(function_exists('password_hash')); + $this->assertTrue(function_exists('password_needs_rehash')); + $this->assertTrue(function_exists('password_verify')); + } + + // ------------------------------------------------------------------------ + + /** + * password_get_info() test + * + * Borrowed from PHP's own tests + * + * @depends test_bootstrap + */ + public function test_password_get_info() + { + $expected = array( + 'algo' => 1, + 'algoName' => 'bcrypt', + 'options' => array('cost' => 10) + ); + + // default + $this->assertEquals($expected, password_get_info('$2y$10$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y')); + + $expected['options']['cost'] = 11; + + // cost + $this->assertEquals($expected, password_get_info('$2y$11$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y')); + + $expected = array( + 'algo' => 0, + 'algoName' => 'unknown', + 'options' => array() + ); + + // invalid length + $this->assertEquals($expected, password_get_info('$2y$11$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100')); + + // non-bcrypt + $this->assertEquals($expected, password_get_info('$1$rasmusle$rISCgZzpwk3UhDidwXvin0')); + } + + // ------------------------------------------------------------------------ + + /** + * password_hash() test + * + * Borrowed from PHP's own tests + * + * @depends test_bootstrap + */ + public function test_password_hash() + { + // FALSE is returned if no CSPRNG source is available + if ( ! defined('MCRYPT_DEV_URANDOM') && ! function_exists('openssl_random_pseudo_bytes') + && (DIRECTORY_SEPARATOR !== '/' OR ! is_readable('/dev/arandom') OR ! is_readable('/dev/urandom')) + ) + { + $this->assertFalse(password_hash('foo', PASSWORD_BCRYPT)); + } + else + { + $this->assertEquals(60, strlen(password_hash('foo', PASSWORD_BCRYPT))); + $this->assertTrue(($hash = password_hash('foo', PASSWORD_BCRYPT)) === crypt('foo', $hash)); + } + + $this->assertEquals( + '$2y$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi', + password_hash('rasmuslerdorf', PASSWORD_BCRYPT, array('cost' => 7, 'salt' => 'usesomesillystringforsalt')) + ); + + $this->assertEquals( + '$2y$10$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y', + password_hash('test', PASSWORD_BCRYPT, array('salt' => '123456789012345678901'.chr(0))) + ); + } + + // ------------------------------------------------------------------------ + + /** + * password_needs_rehash() test + * + * Borrowed from PHP's own tests + * + * @depends test_password_get_info + */ + public function test_password_needs_rehash() + { + // invalid hash: always rehash + $this->assertTrue(password_needs_rehash('', PASSWORD_BCRYPT)); + + // valid, because it's an unknown algorithm + $this->assertFalse(password_needs_rehash('', 0)); + + // valid with same cost + $this->assertFalse(password_needs_rehash('$2y$10$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y', PASSWORD_BCRYPT, array('cost' => 10))); + + // valid with same cost and additional parameters + $this->assertFalse(password_needs_rehash('$2y$10$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y', PASSWORD_BCRYPT, array('cost' => 10, 'foo' => 3))); + + // invalid: different (lower) cost + $this->assertTrue(password_needs_rehash('$2y$10$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y', PASSWORD_BCRYPT, array('cost' => 09))); + + // invalid: different (higher) cost + $this->assertTrue(password_needs_rehash('$2y$10$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y', PASSWORD_BCRYPT, array('cost' => 11))); + + // valid with default cost + $this->assertFalse(password_needs_rehash('$2y$'.str_pad(10, 2, '0', STR_PAD_LEFT).'$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y', PASSWORD_BCRYPT)); + + // invalid: 'foo' is cast to 0 + $this->assertTrue(password_needs_rehash('$2y$10$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y', PASSWORD_BCRYPT, array('cost' => 'foo'))); + } + + // ------------------------------------------------------------------------ + + /** + * password_verify() test + * + * Borrowed from PHP's own tests + * + * @depends test_bootstrap + */ + public function test_password_verify() + { + $this->assertFalse(password_verify(123, 123)); + $this->assertFalse(password_verify('foo', '$2a$07$usesomesillystringforsalt$')); + $this->assertFalse(password_verify('rasmusler', '$2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi')); + $this->assertTrue(password_verify('rasmuslerdorf', '$2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi')); + } + +}
\ No newline at end of file diff --git a/tests/codeigniter/helpers/text_helper_test.php b/tests/codeigniter/helpers/text_helper_test.php index d75d26208..7a7dc0a12 100644 --- a/tests/codeigniter/helpers/text_helper_test.php +++ b/tests/codeigniter/helpers/text_helper_test.php @@ -106,17 +106,19 @@ class Text_helper_test extends CI_TestCase { public function test_highlight_phrase() { $strs = array( - 'this is a phrase' => '<strong>this is</strong> a phrase', - 'this is another' => '<strong>this is</strong> another', - 'Gimme a test, Sally' => 'Gimme a test, Sally', - 'Or tell me what this is' => 'Or tell me what <strong>this is</strong>', - '' => '' + 'this is a phrase' => '<mark>this is</mark> a phrase', + 'this is another' => '<mark>this is</mark> another', + 'Gimme a test, Sally' => 'Gimme a test, Sally', + 'Or tell me what this is' => 'Or tell me what <mark>this is</mark>', + '' => '' ); foreach ($strs as $str => $expect) { $this->assertEquals($expect, highlight_phrase($str, 'this is')); } + + $this->assertEquals('<strong>this is</strong> a strong test', highlight_phrase('this is a strong test', 'this is', '<strong>', '</strong>')); } // ------------------------------------------------------------------------ diff --git a/tests/codeigniter/libraries/Calendar_test.php b/tests/codeigniter/libraries/Calendar_test.php index 952e8a8d2..768bc8573 100644 --- a/tests/codeigniter/libraries/Calendar_test.php +++ b/tests/codeigniter/libraries/Calendar_test.php @@ -169,30 +169,33 @@ class Calendar_test extends CI_TestCase { $this->assertEquals(31, $this->calendar->get_total_days(12, 2012)); } - function test_default_template() + public function test_default_template() { $array = array( - 'table_open' => '<table border="0" cellpadding="4" cellspacing="0">', - 'heading_row_start' => '<tr>', + 'table_open' => '<table border="0" cellpadding="4" cellspacing="0">', + 'heading_row_start' => '<tr>', 'heading_previous_cell' => '<th><a href="{previous_url}"><<</a></th>', 'heading_title_cell' => '<th colspan="{colspan}">{heading}</th>', - 'heading_next_cell' => '<th><a href="{next_url}">>></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>', + 'heading_next_cell' => '<th><a href="{next_url}">>></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' => '<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' => ' ', - 'cal_cell_end' => '</td>', + 'cal_cell_blank' => ' ', + 'cal_cell_end' => '</td>', 'cal_cell_end_today' => '</td>', - 'cal_row_end' => '</tr>', - 'table_close' => '</table>' + 'cal_row_end' => '</tr>', + 'table_close' => '</table>', + 'cal_cell_start_other' => '<td style="color: #666;">', + 'cal_cell_other' => '{day}', + 'cal_cell_end_other' => '</td>' ); $this->assertEquals($array, $this->calendar->default_template()); diff --git a/tests/codeigniter/libraries/Encryption_test.php b/tests/codeigniter/libraries/Encryption_test.php new file mode 100644 index 000000000..a8b5bc81e --- /dev/null +++ b/tests/codeigniter/libraries/Encryption_test.php @@ -0,0 +1,394 @@ +<?php + +class Encryption_test extends CI_TestCase { + + public function set_up() + { + $this->encryption = new Mock_Libraries_Encryption(); + } + + /** + * __construct test + * + * Covers behavior with $config['encryption_key'] set or not + */ + public function test___construct() + { + // Assume no configuration from set_up() + $this->assertNull($this->encryption->get_key()); + + // Try with an empty value + $this->ci_set_config('encryption_key'); + $this->encrypt = new Mock_Libraries_Encryption(); + $this->assertNull($this->encrypt->get_key()); + + $this->ci_set_config('encryption_key', str_repeat("\x0", 16)); + $this->encrypt = new Mock_Libraries_Encryption(); + $this->assertEquals(str_repeat("\x0", 16), $this->encrypt->get_key()); + } + + // -------------------------------------------------------------------- + + /** + * hkdf() test + * + * Applies test vectors described in Appendix A(1-3) RFC5869. + * Described vectors 4-7 SHA-1, which we don't support and are + * therefore excluded. + * + * Because our implementation is a single method instead of being + * split into hkdf_extract() and hkdf_expand(), we cannot test for + * the PRK value. As long as the OKM is correct though, it's fine. + * + * @link https://tools.ietf.org/rfc/rfc5869.txt + */ + public function test_hkdf() + { + $vectors = array( + // A.1: Basic test case with SHA-256 + array( + 'digest' => 'sha256', + 'ikm' => "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", + 'salt' => "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c", + 'length' => 42, + 'info' => "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9", + // 'prk' => "\x07\x77\x09\x36\x2c\x2e\x32\xdf\x0d\xdc\x3f\x0d\xc4\x7b\xba\x63\x90\xb6\xc7\x3b\xb5\x0f\x9c\x31\x22\xec\x84\x4a\xd7\xc2\xb3\xe5", + 'okm' => "\x3c\xb2\x5f\x25\xfa\xac\xd5\x7a\x90\x43\x4f\x64\xd0\x36\x2f\x2a\x2d\x2d\x0a\x90\xcf\x1a\x5a\x4c\x5d\xb0\x2d\x56\xec\xc4\xc5\xbf\x34\x00\x72\x08\xd5\xb8\x87\x18\x58\x65" + ), + // A.2: Test with SHA-256 and longer inputs/outputs + array( + 'digest' => 'sha256', + 'ikm' => "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f", + 'salt' => "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf", + 'length' => 82, + 'info' => "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", + // 'prk' => "\x06\xa6\xb8\x8c\x58\x53\x36\x1a\x06\x10\x4c\x9c\xeb\x35\xb4\x5c\xef\x76\x00\x14\x90\x46\x71\x01\x4a\x19\x3f\x40\xc1\x5f\xc2\x44", + 'okm' => "\xb1\x1e\x39\x8d\xc8\x03\x27\xa1\xc8\xe7\xf7\x8c\x59\x6a\x49\x34\x4f\x01\x2e\xda\x2d\x4e\xfa\xd8\xa0\x50\xcc\x4c\x19\xaf\xa9\x7c\x59\x04\x5a\x99\xca\xc7\x82\x72\x71\xcb\x41\xc6\x5e\x59\x0e\x09\xda\x32\x75\x60\x0c\x2f\x09\xb8\x36\x77\x93\xa9\xac\xa3\xdb\x71\xcc\x30\xc5\x81\x79\xec\x3e\x87\xc1\x4c\x01\xd5\xc1\xf3\x43\x4f\x1d\x87", + ), + // A.3: Test with SHA-256 and zero-length salt/info + array( + 'digest' => 'sha256', + 'ikm' => "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", + 'salt' => '', + 'length' => 42, + 'info' => '', + // 'prk' => "\x19\xef\x24\xa3\x2c\x71\x7b\x16\x7f\x33\xa9\x1d\x6f\x64\x8b\xdf\x96\x59\x67\x76\xaf\xdb\x63\x77\xac\x43\x4c\x1c\x29\x3c\xcb\x04", + 'okm' => "\x8d\xa4\xe7\x75\xa5\x63\xc1\x8f\x71\x5f\x80\x2a\x06\x3c\x5a\x31\xb8\xa1\x1f\x5c\x5e\xe1\x87\x9e\xc3\x45\x4e\x5f\x3c\x73\x8d\x2d\x9d\x20\x13\x95\xfa\xa4\xb6\x1a\x96\xc8", + ) + ); + + foreach ($vectors as $test) + { + $this->assertEquals( + $test['okm'], + $this->encryption->hkdf( + $test['ikm'], + $test['digest'], + $test['salt'], + $test['length'], + $test['info'] + ) + ); + } + + // Test default length, it must match the digest size + $this->assertEquals(64, strlen($this->encryption->hkdf('foobar', 'sha512'))); + + // Test maximum length (RFC5869 says that it must be up to 255 times the digest size) + $this->assertEquals(12240, strlen($this->encryption->hkdf('foobar', 'sha384', NULL, 48 * 255))); + $this->assertFalse($this->encryption->hkdf('foobar', 'sha224', NULL, 28 * 255 + 1)); + + // CI-specific test for an invalid digest + $this->assertFalse($this->encryption->hkdf('fobar', 'sha1')); + } + + // -------------------------------------------------------------------- + + /** + * _get_params() test + * + * @uses Mock_Libraries_Encryption::__get_params() + */ + public function test__get_params() + { + $key = str_repeat("\x0", 16); + + // Invalid custom parameters + $params = array( + // No cipher, mode or key + array('cipher' => 'aes-128', 'mode' => 'cbc'), + array('cipher' => 'aes-128', 'key' => $key), + array('mode' => 'cbc', 'key' => $key), + // No HMAC key or not a valid digest + array('cipher' => 'aes-128', 'mode' => 'cbc', 'key' => $key), + array('cipher' => 'aes-128', 'mode' => 'cbc', 'key' => $key, 'hmac_digest' => 'sha1', 'hmac_key' => $key), + // Invalid mode + array('cipher' => 'aes-128', 'mode' => 'foo', 'key' => $key, 'hmac_digest' => 'sha256', 'hmac_key' => $key) + ); + + for ($i = 0, $c = count($params); $i < $c; $i++) + { + $this->assertFalse($this->encryption->__get_params($params[$i])); + } + + // Valid parameters + $params = array( + 'cipher' => 'aes-128', + 'mode' => 'cbc', + 'key' => str_repeat("\x0", 16), + 'hmac_key' => str_repeat("\x0", 16) + ); + + $this->assertTrue(is_array($this->encryption->__get_params($params))); + + $params['iv'] = NULL; + $params['base64'] = TRUE; + $params['hmac_digest'] = 'sha512'; + + // Including all parameters + $params = array( + 'cipher' => 'aes-128', + 'mode' => 'cbc', + 'key' => str_repeat("\x0", 16), + 'iv' => str_repeat("\x0", 16), + 'raw_data' => TRUE, + 'hmac_key' => str_repeat("\x0", 16), + 'hmac_digest' => 'sha256' + ); + + $output = $this->encryption->__get_params($params); + unset($output['handle'], $params['raw_data']); + $params['base64'] = FALSE; + $this->assertEquals($params, $output); + + // HMAC disabled + unset($params['hmac_key'], $params['hmac_digest']); + $params['hmac'] = $params['raw_data'] = FALSE; + $output = $this->encryption->__get_params($params); + unset($output['handle'], $params['hmac'], $params['raw_data']); + $params['base64'] = TRUE; + $params['hmac_digest'] = $params['hmac_key'] = NULL; + $this->assertEquals($params, $output); + } + + // -------------------------------------------------------------------- + + /** + * initialize(), encrypt(), decrypt() test + * + * Testing the three methods separately is not realistic as they are + * designed to work together. A more thorough test for initialize() + * though is the OpenSSL/MCrypt compatibility test. + * + * @depends test_hkdf + * @depends test__get_params + */ + public function test_initialize_encrypt_decrypt() + { + $message = 'This is a plain-text message.'; + $key = "\xd0\xc9\x08\xc4\xde\x52\x12\x6e\xf8\xcc\xdb\x03\xea\xa0\x3a\x5c"; + + // Default state (AES-128/Rijndael-128 in CBC mode) + $this->encryption->initialize(array('key' => $key)); + + // Was the key properly set? + $this->assertEquals($key, $this->encryption->get_key()); + + $this->assertEquals($message, $this->encryption->decrypt($this->encryption->encrypt($message))); + + // Try DES in ECB mode, just for the sake of changing stuff + $this->encryption->initialize(array('cipher' => 'des', 'mode' => 'ecb')); + $this->assertEquals($message, $this->encryption->decrypt($this->encryption->encrypt($message))); + } + + // -------------------------------------------------------------------- + + /** + * encrypt(), decrypt test with custom parameters + * + * @depends test___get_params + */ + public function test_encrypt_decrypt_custom() + { + $message = 'Another plain-text message.'; + + // A random invalid parameter + $this->assertFalse($this->encryption->encrypt($message, array('foo'))); + $this->assertFalse($this->encryption->decrypt($message, array('foo'))); + + // Custom IV (we'll check it), no HMAC, binary output + $params = array( + 'cipher' => 'tripledes', + 'mode' => 'cfb', + 'key' => str_repeat("\x1", 16), + 'iv' => str_repeat("\x2", 8), + 'base64' => FALSE, + 'hmac' => FALSE + ); + + $ciphertext = $this->encryption->encrypt($message, $params); + $this->assertEquals(0, strncmp($params['iv'], $ciphertext, 8)); + + // IV should be found in the cipher-text, no matter if it was supplied or not + $this->assertEquals($message, $this->encryption->decrypt($ciphertext, $params)); + unset($params['iv']); + $this->assertEquals($message, $this->encryption->decrypt($ciphertext, $params)); + } + + // -------------------------------------------------------------------- + + /** + * _mcrypt_get_handle() test + */ + public function test__mcrypt_get_handle() + { + if ($this->encryption->drivers['mcrypt'] === FALSE) + { + return $this->markTestSkipped('Cannot test MCrypt because it is not available.'); + } + + $this->assertTrue(is_resource($this->encryption->__driver_get_handle('mcrypt', 'rijndael-128', 'cbc'))); + } + + // -------------------------------------------------------------------- + + /** + * _openssl_get_handle() test + */ + public function test__openssl_mcrypt_get_handle() + { + if ($this->encryption->drivers['openssl'] === FALSE) + { + return $this->markTestSkipped('Cannot test OpenSSL because it is not available.'); + } + + $this->assertEquals('aes-128-cbc', $this->encryption->__driver_get_handle('openssl', 'aes-128', 'cbc')); + $this->assertEquals('rc4-40', $this->encryption->__driver_get_handle('openssl', 'rc4-40', 'stream')); + } + + // -------------------------------------------------------------------- + + /** + * OpenSSL/MCrypt portability test + * + * Amongst the obvious stuff, _cipher_alias() is also tested here. + */ + public function test_portability() + { + if ( ! $this->encryption->drivers['mcrypt'] OR ! $this->encryption->drivers['openssl']) + { + $this->markTestSkipped('Both MCrypt and OpenSSL support are required for portability tests.'); + return; + } + + $message = 'This is a message encrypted via MCrypt and decrypted via OpenSSL, or vice-versa.'; + + // Format is: <Cipher name>, <Cipher mode>, <Key size> + $portable = array( + array('aes-128', 'cbc', 16), + array('aes-128', 'cfb', 16), + array('aes-128', 'cfb8', 16), + array('aes-128', 'ofb', 16), + array('aes-128', 'ecb', 16), + array('aes-128', 'ctr', 16), + array('aes-192', 'cbc', 24), + array('aes-192', 'cfb', 24), + array('aes-192', 'cfb8', 24), + array('aes-192', 'ofb', 24), + array('aes-192', 'ecb', 24), + array('aes-192', 'ctr', 24), + array('aes-256', 'cbc', 32), + array('aes-256', 'cfb', 32), + array('aes-256', 'cfb8', 32), + array('aes-256', 'ofb', 32), + array('aes-256', 'ecb', 32), + array('aes-256', 'ctr', 32), + array('des', 'cbc', 7), + array('des', 'cfb', 7), + array('des', 'cfb8', 7), + array('des', 'ofb', 7), + array('des', 'ecb', 7), + array('tripledes', 'cbc', 7), + array('tripledes', 'cfb', 7), + array('tripledes', 'cfb8', 7), + array('tripledes', 'ofb', 7), + array('tripledes', 'cbc', 14), + array('tripledes', 'cfb', 14), + array('tripledes', 'cfb8', 14), + array('tripledes', 'ofb', 14), + array('tripledes', 'cbc', 21), + array('tripledes', 'cfb', 21), + array('tripledes', 'cfb8', 21), + array('tripledes', 'ofb', 21), + array('blowfish', 'cbc', 16), + array('blowfish', 'cfb', 16), + array('blowfish', 'ofb', 16), + array('blowfish', 'ecb', 16), + array('blowfish', 'cbc', 56), + array('blowfish', 'cfb', 56), + array('blowfish', 'ofb', 56), + array('blowfish', 'ecb', 56), + array('cast5', 'cbc', 5), + array('cast5', 'cfb', 5), + array('cast5', 'ofb', 5), + array('cast5', 'ecb', 5), + array('cast5', 'cbc', 8), + array('cast5', 'cfb', 8), + array('cast5', 'ofb', 8), + array('cast5', 'ecb', 8), + array('cast5', 'cbc', 10), + array('cast5', 'cfb', 10), + array('cast5', 'ofb', 10), + array('cast5', 'ecb', 10), + array('cast5', 'cbc', 16), + array('cast5', 'cfb', 16), + array('cast5', 'ofb', 16), + array('cast5', 'ecb', 16), + array('rc4', 'stream', 5), + array('rc4', 'stream', 8), + array('rc4', 'stream', 16), + array('rc4', 'stream', 32), + array('rc4', 'stream', 64), + array('rc4', 'stream', 128), + array('rc4', 'stream', 256) + ); + $driver_index = array('mcrypt', 'openssl'); + + foreach ($portable as &$test) + { + // Add some randomness to the selected driver + $driver = mt_rand(0,1); + $params = array( + 'driver' => $driver_index[$driver], + 'cipher' => $test[0], + 'mode' => $test[1], + 'key' => openssl_random_pseudo_bytes($test[2]) + ); + + $this->encryption->initialize($params); + $ciphertext = $this->encryption->encrypt($message); + + $driver = (int) ! $driver; + $params['driver'] = $driver_index[$driver]; + + $this->encryption->initialize($params); + $this->assertEquals($message, $this->encryption->decrypt($ciphertext)); + } + } + + // -------------------------------------------------------------------- + + /** + * __get() test + */ + public function test_magic_get() + { + $this->assertNull($this->encryption->foo); + $this->assertEquals(array('mcrypt', 'openssl'), array_keys($this->encryption->drivers)); + + // 'stream' mode is translated into an empty string for OpenSSL + $this->encryption->initialize(array('cipher' => 'rc4', 'mode' => 'stream')); + $this->assertEquals('stream', $this->encryption->mode); + } + +}
\ No newline at end of file diff --git a/tests/codeigniter/libraries/Parser_test.php b/tests/codeigniter/libraries/Parser_test.php index 394c22692..3755cf1a0 100644 --- a/tests/codeigniter/libraries/Parser_test.php +++ b/tests/codeigniter/libraries/Parser_test.php @@ -33,7 +33,7 @@ class Parser_test extends CI_TestCase { // -------------------------------------------------------------------- - public function test_parse_simple_string() + public function test_parse_string() { $data = array( 'title' => 'Page Title', @@ -69,16 +69,12 @@ class Parser_test extends CI_TestCase { { $data = array( 'title' => 'Super Heroes', - 'powers' => array( - array( - 'invisibility' => 'yes', - 'flying' => 'no'), - ) + 'powers' => array(array('invisibility' => 'yes', 'flying' => 'no')) ); - $template = "{title}\n{powers}{invisibility}\n{flying}{/powers}"; + $template = "{title}\n{powers}{invisibility}\n{flying}{/powers}\nsecond:{powers} {invisibility} {flying}{/powers}"; - $this->assertEquals("Super Heroes\nyes\nno", $this->parser->parse_string($template, $data, TRUE)); + $this->assertEquals("Super Heroes\nyes\nno\nsecond: yes no", $this->parser->parse_string($template, $data, TRUE)); } // -------------------------------------------------------------------- @@ -87,11 +83,7 @@ class Parser_test extends CI_TestCase { { $data = array( 'title' => 'Super Heroes', - 'powers' => array( - array( - 'invisibility' => 'yes', - 'flying' => 'no'), - ) + 'powers' => array(array('invisibility' => 'yes', 'flying' => 'no')) ); $template = "{title}\n{powers}{invisibility}\n{flying}"; diff --git a/tests/codeigniter/libraries/Session_test.php b/tests/codeigniter/libraries/Session_test.php index 6edda99d7..6f1332384 100644 --- a/tests/codeigniter/libraries/Session_test.php +++ b/tests/codeigniter/libraries/Session_test.php @@ -8,7 +8,7 @@ class Session_test extends CI_TestCase { protected $settings = array( 'use_cookies' => 0, 'use_only_cookies' => 0, - 'cache_limiter' => false + 'cache_limiter' => FALSE ); protected $setting_vals = array(); protected $cookie_vals; @@ -91,7 +91,7 @@ class Session_test extends CI_TestCase { $cmsg1 = 'Some test data'; $cmsg2 = 42; $nmsg1 = 'Other test data'; - $nmsg2 = true; + $nmsg2 = TRUE; $this->session->cookie->set_userdata($key1, $cmsg1); $this->session->set_userdata($ckey2, $cmsg2); $this->session->native->set_userdata($key1, $nmsg1); @@ -156,11 +156,11 @@ class Session_test extends CI_TestCase { $this->session->native->set_userdata($ndata); // Make sure all values are present - $call = $this->session->cookie->all_userdata(); + $call = $this->session->cookie->userdata(); foreach ($cdata as $key => $value) { $this->assertEquals($value, $call[$key]); } - $nall = $this->session->native->all_userdata(); + $nall = $this->session->native->userdata(); foreach ($ndata as $key => $value) { $this->assertEquals($value, $nall[$key]); } @@ -283,8 +283,8 @@ class Session_test extends CI_TestCase { // Simulate page reload and verify independent messages $this->session->cookie->reload(); $this->session->native->reload(); - $this->assertEquals($cdata, $this->session->cookie->all_flashdata()); - $this->assertEquals($ndata, $this->session->native->all_flashdata()); + $this->assertEquals($cdata, $this->session->cookie->flashdata()); + $this->assertEquals($ndata, $this->session->native->flashdata()); // Keep messages $this->session->cookie->keep_flashdata($kdata); @@ -293,14 +293,14 @@ class Session_test extends CI_TestCase { // Simulate next page reload and verify message persistence $this->session->cookie->reload(); $this->session->native->reload(); - $this->assertEquals($cdata, $this->session->cookie->all_flashdata()); - $this->assertEquals($ndata, $this->session->native->all_flashdata()); + $this->assertEquals($cdata, $this->session->cookie->flashdata()); + $this->assertEquals($ndata, $this->session->native->flashdata()); // Simulate next page reload and verify absence of messages $this->session->cookie->reload(); $this->session->native->reload(); - $this->assertEmpty($this->session->cookie->all_flashdata()); - $this->assertEmpty($this->session->native->all_flashdata()); + $this->assertEmpty($this->session->cookie->flashdata()); + $this->assertEmpty($this->session->native->flashdata()); } /** @@ -329,8 +329,8 @@ class Session_test extends CI_TestCase { // Simulate page reload and make sure all values are present $this->session->cookie->reload(); $this->session->native->reload(); - $this->assertEquals($cdata, $this->session->cookie->all_flashdata()); - $this->assertEquals($ndata, $this->session->native->all_flashdata()); + $this->assertEquals($cdata, $this->session->cookie->flashdata()); + $this->assertEquals($ndata, $this->session->native->flashdata()); } /** diff --git a/tests/codeigniter/libraries/Table_test.php b/tests/codeigniter/libraries/Table_test.php index ce04b6a6d..8e7452474 100644 --- a/tests/codeigniter/libraries/Table_test.php +++ b/tests/codeigniter/libraries/Table_test.php @@ -34,7 +34,7 @@ class Table_test extends CI_TestCase { } /* - * @depends testPrepArgs + * @depends test_prep_args */ public function test_set_heading() { @@ -55,7 +55,7 @@ class Table_test extends CI_TestCase { } /* - * @depends testPrepArgs + * @depends test_prep_args */ public function test_add_row() { @@ -200,16 +200,14 @@ class Table_test extends CI_TestCase { public function test_set_from_array() { - $this->assertFalse($this->table->set_from_array('bogus')); - $this->assertFalse($this->table->set_from_array(NULL)); - $data = array( array('name', 'color', 'number'), array('Laura', 'Red', '22'), array('Katie', 'Blue') ); - $this->table->set_from_array($data, FALSE); + $this->table->auto_heading = FALSE; + $this->table->set_from_array($data); $this->assertEmpty($this->table->heading); $this->table->clear(); @@ -235,22 +233,14 @@ class Table_test extends CI_TestCase { public function test_set_from_object() { - // Make a stub of query instance - $query = new CI_TestCase(); - $query->list_fields = function(){ - return array('name', 'email'); - }; - $query->result_array = function(){ - return array( - array('name' => 'John Doe', 'email' => 'john@doe.com'), - array('name' => 'Foo Bar', 'email' => 'foo@bar.com'), - ); - }; - $query->num_rows = function(){ - return 2; - }; - - $this->table->set_from_object($query); + // This needs to be passed by reference to CI_DB_result::__construct() + $dummy = new stdClass(); + $dummy->conn_id = NULL; + $dummy->result_id = NULL; + + $db_result = new DB_result_dummy($dummy); + + $this->table->set_from_db_result($db_result); $expected = array( array('data' => 'name'), @@ -290,4 +280,21 @@ class Table_test extends CI_TestCase { $this->assertTrue(strpos($table, '<td>Small</td>') !== FALSE); } +} + +// We need this for the _set_from_db_result() test +class DB_result_dummy extends CI_DB_result +{ + public function list_fields() + { + return array('name', 'email'); + } + + public function result_array() + { + return array( + array('name' => 'John Doe', 'email' => 'john@doe.com'), + array('name' => 'Foo Bar', 'email' => 'foo@bar.com') + ); + } }
\ No newline at end of file diff --git a/tests/codeigniter/libraries/Useragent_test.php b/tests/codeigniter/libraries/Useragent_test.php index e3726554e..aed38b8c2 100644 --- a/tests/codeigniter/libraries/Useragent_test.php +++ b/tests/codeigniter/libraries/Useragent_test.php @@ -11,9 +11,7 @@ class UserAgent_test extends CI_TestCase { $_SERVER['HTTP_USER_AGENT'] = $this->_user_agent; $this->ci_vfs_clone('application/config/user_agents.php'); - $this->agent = new Mock_Libraries_UserAgent(); - $this->ci_instance_var('agent', $this->agent); } @@ -40,12 +38,27 @@ class UserAgent_test extends CI_TestCase { // -------------------------------------------------------------------- - public function test_util_is_functions() + public function test_is_functions() { $this->assertTrue($this->agent->is_browser()); + $this->assertTrue($this->agent->is_browser('Safari')); + $this->assertFalse($this->agent->is_browser('Firefox')); $this->assertFalse($this->agent->is_robot()); $this->assertFalse($this->agent->is_mobile()); + } + + // -------------------------------------------------------------------- + + public function test_referrer() + { + $_SERVER['HTTP_REFERER'] = 'http://codeigniter.com/user_guide/'; + $this->assertTrue($this->agent->is_referral()); + $this->assertEquals('http://codeigniter.com/user_guide/', $this->agent->referrer()); + + $this->agent->referer = NULL; + unset($_SERVER['HTTP_REFERER']); $this->assertFalse($this->agent->is_referral()); + $this->assertEquals('', $this->agent->referrer()); } // -------------------------------------------------------------------- @@ -63,7 +76,6 @@ class UserAgent_test extends CI_TestCase { $this->assertEquals('Safari', $this->agent->browser()); $this->assertEquals('533.20.27', $this->agent->version()); $this->assertEquals('', $this->agent->robot()); - $this->assertEquals('', $this->agent->referrer()); } // -------------------------------------------------------------------- @@ -71,14 +83,43 @@ class UserAgent_test extends CI_TestCase { public function test_charsets() { $_SERVER['HTTP_ACCEPT_CHARSET'] = 'utf8'; + $this->agent->charsets = array(); + $this->agent->charsets(); + $this->assertTrue($this->agent->accept_charset('utf8')); + $this->assertFalse($this->agent->accept_charset('foo')); + $this->assertEquals('utf8', $this->agent->charsets[0]); + + $_SERVER['HTTP_ACCEPT_CHARSET'] = ''; + $this->agent->charsets = array(); + $this->assertFalse($this->agent->accept_charset()); + $this->assertEquals('Undefined', $this->agent->charsets[0]); - $charsets = $this->agent->charsets(); - - $this->assertEquals('utf8', $charsets[0]); + $_SERVER['HTTP_ACCEPT_CHARSET'] = 'iso-8859-5, unicode-1-1; q=0.8'; + $this->agent->charsets = array(); + $this->assertTrue($this->agent->accept_charset('iso-8859-5')); + $this->assertTrue($this->agent->accept_charset('unicode-1-1')); + $this->assertFalse($this->agent->accept_charset('foo')); + $this->assertEquals('iso-8859-5', $this->agent->charsets[0]); + $this->assertEquals('unicode-1-1', $this->agent->charsets[1]); unset($_SERVER['HTTP_ACCEPT_CHARSET']); + } - $this->assertFalse($this->agent->accept_charset()); + public function test_parse() + { + $new_agent = 'Mozilla/5.0 (Android; Mobile; rv:13.0) Gecko/13.0 Firefox/13.0'; + $this->agent->parse($new_agent); + + $this->assertEquals('Android', $this->agent->platform()); + $this->assertEquals('Firefox', $this->agent->browser()); + $this->assertEquals('13.0', $this->agent->version()); + $this->assertEquals('', $this->agent->robot()); + $this->assertEquals('Android', $this->agent->mobile()); + $this->assertEquals($new_agent, $this->agent->agent_string()); + $this->assertTrue($this->agent->is_browser()); + $this->assertFalse($this->agent->is_robot()); + $this->assertTrue($this->agent->is_mobile()); + $this->assertTrue($this->agent->is_mobile('android')); } }
\ No newline at end of file diff --git a/tests/mocks/autoloader.php b/tests/mocks/autoloader.php index 3d216da1f..33942768d 100644 --- a/tests/mocks/autoloader.php +++ b/tests/mocks/autoloader.php @@ -14,26 +14,49 @@ function autoload($class) $dir = realpath(dirname(__FILE__)).DIRECTORY_SEPARATOR; $ci_core = array( - 'Benchmark', 'Config', 'Controller', - 'Exceptions', 'Hooks', 'Input', - 'Lang', 'Loader', 'Log', 'Model', - 'Output', 'Router', 'Security', - 'URI', 'Utf8', + 'Benchmark', + 'Config', + 'Controller', + 'Exceptions', + 'Hooks', + 'Input', + 'Lang', + 'Loader', + 'Log', + 'Model', + 'Output', + 'Router', + 'Security', + 'URI', + 'Utf8' ); $ci_libraries = array( - 'Calendar', 'Cart', 'Driver_Library', - 'Email', 'Encrypt', 'Form_validation', - 'Ftp', 'Image_lib', 'Javascript', - 'Migration', 'Pagination', 'Parser', - 'Profiler', 'Table', 'Trackback', - 'Typography', 'Unit_test', 'Upload', - 'User_agent', 'Xmlrpc', 'Zip' + 'Calendar', + 'Cart', + 'Driver_Library', + 'Email', + 'Encrypt', + 'Encryption', + 'Form_validation', + 'Ftp', + 'Image_lib', + 'Javascript', + 'Migration', + 'Pagination', + 'Parser', + 'Profiler', + 'Table', + 'Trackback', + 'Typography', + 'Unit_test', + 'Upload', + 'User_agent', + 'Xmlrpc', + 'Zip' ); - $ci_drivers = array( - 'Session', - ); + $ci_drivers = array('Session', 'Cache'); if (strpos($class, 'Mock_') === 0) { @@ -89,21 +112,7 @@ function autoload($class) if ( ! file_exists($file)) { - $trace = debug_backtrace(); - - if ($trace[2]['function'] === 'class_exists' OR $trace[2]['function'] === 'file_exists') - { - // If the autoload call came from `class_exists` or `file_exists`, - // we skipped and return FALSE - return FALSE; - } - elseif (($autoloader = spl_autoload_functions()) && end($autoloader) !== __FUNCTION__) - { - // If there was other custom autoloader, passed away - return FALSE; - } - - throw new InvalidArgumentException("Unable to load {$class}."); + return FALSE; } include_once($file); diff --git a/tests/mocks/core/common.php b/tests/mocks/core/common.php index 0ccfe1ea4..9eb6b0954 100644 --- a/tests/mocks/core/common.php +++ b/tests/mocks/core/common.php @@ -87,40 +87,6 @@ if ( ! function_exists('load_class')) } } -// This is sort of meh. Should probably be mocked up with -// controllable output, so that we can test some of our -// security code. The function itself will be tested in the -// bootstrap testsuite. -// -------------------------------------------------------------------- - -if ( ! function_exists('remove_invisible_characters')) -{ - function remove_invisible_characters($str, $url_encoded = TRUE) - { - $non_displayables = array(); - - // every control character except newline (dec 10) - // carriage return (dec 13), and horizontal tab (dec 09) - - if ($url_encoded) - { - $non_displayables[] = '/%0[0-8bcef]/'; // url encoded 00-08, 11, 12, 14, 15 - $non_displayables[] = '/%1[0-9a-f]/'; // url encoded 16-31 - } - - $non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S'; // 00-08, 11, 12, 14-31, 127 - - do - { - $str = preg_replace($non_displayables, '', $str, -1, $count); - } - while ($count); - - return $str; - } -} - - // Clean up error messages // -------------------------------------------------------------------- @@ -150,23 +116,6 @@ if ( ! function_exists('_exception_handler')) // We assume a few things about our environment ... // -------------------------------------------------------------------- - -if ( ! function_exists('is_php')) -{ - function is_php($version = '5.0.0') - { - return ! (version_compare(PHP_VERSION, $version) < 0); - } -} - -if ( ! function_exists('is_really_writable')) -{ - function is_really_writable($file) - { - return is_writable($file); - } -} - if ( ! function_exists('is_loaded')) { function &is_loaded() @@ -178,7 +127,7 @@ if ( ! function_exists('is_loaded')) if ( ! function_exists('log_message')) { - function log_message($level, $message, $php_error = FALSE) + function log_message($level, $message) { return TRUE; } @@ -190,4 +139,13 @@ if ( ! function_exists('set_status_header')) { return TRUE; } +} + +if ( ! function_exists('is_cli')) +{ + // In order to test HTTP functionality, we need to lie about this + function is_cli() + { + return FALSE; + } }
\ No newline at end of file diff --git a/tests/mocks/core/uri.php b/tests/mocks/core/uri.php index 94f75df64..96ec5afa1 100644 --- a/tests/mocks/core/uri.php +++ b/tests/mocks/core/uri.php @@ -10,17 +10,23 @@ class Mock_Core_URI extends CI_URI { // set predictable config values $test->ci_set_config(array( 'index_page' => 'index.php', - 'base_url' => 'http://example.com/', - 'subclass_prefix' => 'MY_' + 'base_url' => 'http://example.com/', + 'subclass_prefix' => 'MY_', + 'enable_query_strings' => FALSE, + 'permitted_uri_chars' => 'a-z 0-9~%.:_\-' )); $this->config = new $cls; + if ($this->config->item('enable_query_strings') !== TRUE OR is_cli()) + { + $this->_permitted_uri_chars = $this->config->item('permitted_uri_chars'); + } } - protected function _is_cli_request() + public function _set_permitted_uri_chars($value) { - return FALSE; + $this->_permitted_uri_chars = $value; } }
\ No newline at end of file diff --git a/tests/mocks/core/utf8.php b/tests/mocks/core/utf8.php index 068e74ac1..30b78adfe 100644 --- a/tests/mocks/core/utf8.php +++ b/tests/mocks/core/utf8.php @@ -3,24 +3,19 @@ class Mock_Core_Utf8 extends CI_Utf8 { /** - * We need to define several constants as - * the same process within CI_Utf8 class constructor. + * We need to define UTF8_ENABLED the same way that + * CI_Utf8 constructor does. * * @covers CI_Utf8::__construct() */ public function __construct() { defined('UTF8_ENABLED') OR define('UTF8_ENABLED', TRUE); + } - if (extension_loaded('mbstring')) - { - defined('MB_ENABLED') OR define('MB_ENABLED', TRUE); - mb_internal_encoding('UTF-8'); - } - else - { - defined('MB_ENABLED') OR define('MB_ENABLED', FALSE); - } + public function is_ascii_test($str) + { + return $this->_is_ascii($str); } }
\ No newline at end of file diff --git a/tests/mocks/libraries/encryption.php b/tests/mocks/libraries/encryption.php new file mode 100644 index 000000000..028eecc72 --- /dev/null +++ b/tests/mocks/libraries/encryption.php @@ -0,0 +1,39 @@ +<?php + +class Mock_Libraries_Encryption extends CI_Encryption { + + /** + * __get_params() + * + * Allows public calls to the otherwise protected _get_params(). + */ + public function __get_params($params) + { + return $this->_get_params($params); + } + + // -------------------------------------------------------------------- + + /** + * get_key() + * + * Allows checking for key changes. + */ + public function get_key() + { + return $this->_key; + } + + // -------------------------------------------------------------------- + + /** + * __driver_get_handle() + * + * Allows checking for _mcrypt_get_handle(), _openssl_get_handle() + */ + public function __driver_get_handle($driver, $cipher, $mode) + { + return $this->{'_'.$driver.'_get_handle'}($cipher, $mode); + } + +}
\ No newline at end of file diff --git a/user_guide_src/cilexer/cilexer/cilexer.py b/user_guide_src/cilexer/cilexer/cilexer.py index 1edc7e820..e9834ecb1 100644 --- a/user_guide_src/cilexer/cilexer/cilexer.py +++ b/user_guide_src/cilexer/cilexer/cilexer.py @@ -15,7 +15,7 @@ # through the world wide web, please send an email to # licensing@ellislab.com so we can send you a copy immediately. # -# Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) +# Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) # http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) diff --git a/user_guide_src/source/_themes/eldocs/layout.html b/user_guide_src/source/_themes/eldocs/layout.html index 7f2fe1a34..535c2f194 100644 --- a/user_guide_src/source/_themes/eldocs/layout.html +++ b/user_guide_src/source/_themes/eldocs/layout.html @@ -31,7 +31,7 @@ {%- for cssfile in css_files %} <link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" /> {%- endfor %} - + {%- if not embedded %} <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { @@ -46,11 +46,13 @@ <script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script> {%- endfor %} + <script type="text/javascript" src="{{ pathto('_static/asset/js/method-toc.js', 1) }}"></script> + {%- if favicon %} <link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/> {%- endif %} {%- endif %} - + {%- block linktags %} {%- if hasdoc('about') %} <link rel="author" title="{{ _('About these documents') }}" href="{{ pathto('about') }}" /> @@ -96,7 +98,7 @@ {%- block rootrellink %} <li><a href="{{ pathto(master_doc) }}">User Guide Home</a>{%- if pagename != 'index' %} {{ reldelim1 }}{%- endif %}</li> {%- endblock %} - + {%- for parent in parents %} <li><a href="{{ parent.link|e }}" {% if loop.last %}{{ accesskey("U") }}{% endif %}>{{ parent.title }}</a> {{ reldelim1 }}</li> {%- endfor %} @@ -117,8 +119,8 @@ {% if pagename not in exclude_comments -%} <!-- {user_guide_comments} --> {% endif %} - - {%- block footer %} + + {%- block footer %} <div id="footer"> <p class="top"><a href="#header" title="Return to top">Return to top</a></p> <p><a href="http://{{ project_domain }}/">{{ project }}</a> – Copyright © {{ copyright }}</a></p> diff --git a/user_guide_src/source/_themes/eldocs/static/asset/css/common.css b/user_guide_src/source/_themes/eldocs/static/asset/css/common.css index 648e33032..f0ce8c80c 100644 --- a/user_guide_src/source/_themes/eldocs/static/asset/css/common.css +++ b/user_guide_src/source/_themes/eldocs/static/asset/css/common.css @@ -16,13 +16,13 @@ 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. -Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) +Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) */ html, body, h1, h2, h3, h4, h5, h6, -p, ul, ol, li, dl, dd, dt, pre, form, fieldset{ margin: 0; padding: 0; } +p, ul, ol, li, dl, dd, dt, pre, form, fieldset{ margin: 0; padding: 0; } body{ background-color: #F9F9F9; color: #444444; font: normal normal 14px "Helvetica", "Arial", Sans-Serif; } @@ -34,10 +34,10 @@ pre, #table-contents .toctree-wrapper{ font-size: 12px; } dfn, var, -em.dfn, em.var{ - background-color: #FFFDED; - color: #578236; - font-style: italic; +em.dfn, em.var{ + background-color: #FFFDED; + color: #578236; + font-style: italic; padding: 3px; } @@ -53,7 +53,7 @@ h2{ font-size: 24px; font-weight: normal; } h1, h2, h3, h4, h5, h6{ margin-bottom: 20px; } -h2, h3{ border-bottom: 2px solid #EEEEEE; padding: 0 0 3px; } +h2, h3{ border-bottom: 2px solid #EEEEEE; padding: 0 0 3px; } h3{ border-color: #E5E5E5; border-width: 1px; } @@ -62,7 +62,7 @@ h4{ background-color: #FFFDED; display: inline-block; font-size: 18px; margin: 0 h1 a, h2 a{ font-weight: normal; } h1 a, h2 a, h3 a{ text-decoration: none; } - + h3, h5, h6{ font-size: 18px; margin: 20px 0; } h4, h5, h6{ font-size: 14px; } @@ -75,57 +75,67 @@ p, dl, ul, ol{ margin: 20px 0; } li > ol{ margin: 0; margin-left: 40px; } dl > dd{ margin-left: 20px; } - + li > p { margin: 0; } #expressionengine-user-guide li em { font-style: normal; } p, li, dd, dt, pre{ line-height: 1.5; } -table{ +table{ background-color: #F5FBFF; border: 1px solid #C8DEF0; border-collapse: collapse; margin-bottom: 20px; } - th, td{ - border: 0; + th, td{ + border: 0; border-bottom: 1px solid #C8DEF0; - padding: 8px; + padding: 8px; } - - th{ - background-color: #326B95; + + th{ + background-color: #326B95; color: #FFFFFF; - text-align: left; + text-align: left; } - + td{ font-size: 12px; } .descname{ color: #000080; font-weight: bold; } .descclassname{ color: #094776; } - + .class .descname{ font-size: 18px; font-style: italic; } .method .descname{ font-style: normal; } - + .class .property{ color: #094776; } - + .method big, - .method .optional{ color: #094776; padding: 0 4px 0 6px; } - + .method .optional + .function big, + .function .optional{ color: #094776; padding: 0 4px 0 6px; } + .class em, - .method em{ color: #008080; } - - .method dt{ margin: 20px 0; } - - .method table{ margin-bottom: 0; margin-left: 20px; } - + .method em, + .function em{ color: #008080; } + + .method dt, + .function dt{ margin: 20px 0; } + + .method table, + .function table{ margin-bottom: 0; margin-left: 20px; } + .method th, - .method td{ padding: 10px; } - - .method td > ul{ margin: 0; margin-left: 20px; } - .method td.field-body > p { margin: 0; margin-left: 20px; } + .method td, + .function th, + .function td{ padding: 10px; } + + .method td > ul, + .function td > ul{ margin: 0; margin-left: 20px; } + + .method td.field-body > p, + .function td.field-body > p { margin: 0; margin-left: 20px; } a:link, a:visited{ color: #1A5B8D; } @@ -133,11 +143,11 @@ a:visited{ color: #1A5B8D; } a:hover, a:active{ color: #742CAC; } -a.headerlink{ visibility: hidden; } +a.headerlink{ visibility: hidden; margin-left: 0.4em; } :hover > a.headerlink { visibility: visible; } -a img{ +a img{ border: 0; outline: 0; } @@ -157,37 +167,38 @@ fieldset{ border: 0; } .highlight-bash, .highlight-perl, .highlight-php, +.highlight-html, .cp-path, -.codeblock{ - background-color: #F9FEFF; - border: 1px solid #C8DEF0; +.codeblock{ + background-color: #F9FEFF; + border: 1px solid #C8DEF0; -moz-box-shadow: 4px 4px 0 rgba(0,0,0,0.03); -webkit-box-shadow: 4px 4px 0 rgba(0,0,0,0.03); box-shadow: 4px 4px 0 rgba(0,0,0,0.03); - margin: 20px 0; - padding: 10px 10px 8px; + margin: 20px 0; + padding: 10px 10px 8px; } .highlight-ci{ background-color: #FEFEFE; border-color: #E5E5E5; } .admonition p{ margin: 0; } - + .codeblock{ margin: 10px 0; } - + .cp-path{ background-color: #FAFFF6; border-color: #D1CDB0; } .important, .note{ background-color: #FFFFF2; border-color: #C8C8A5; } - -.admonition-title{ + +.admonition-title{ float: left; - font-weight: bold; - padding-right: 4px; - text-transform: uppercase; + font-weight: bold; + padding-right: 4px; + text-transform: uppercase; } .admonition-title:after{ content: ': '; } .highlighted{ background-color: #FFF09B; } - + #table-contents{ bottom: 0; left: -520px; @@ -195,7 +206,7 @@ fieldset{ border: 0; } top: 0; } -#table-contents .toctree-wrapper{ +#table-contents .toctree-wrapper{ background-color: #444444; background-color: rgba(0,0,0,0.9); *+background-color: #444444; @@ -209,16 +220,16 @@ fieldset{ border: 0; } } #table-contents .toctree-wrapper ul{margin-bottom: 0; margin-top: 0; } - + #table-contents .toctree-wrapper li{ color: #999999; line-height: 1.7; padding: 1px 0; } - + #table-contents .toctree-l1{ list-style-type: none; } - - #table-contents .toctree-l1 > a{ - background: transparent url(../../asset/img/paper-ico.gif) no-repeat 0 0; - font-size: 14px; + + #table-contents .toctree-l1 > a{ + background: transparent url(../../asset/img/paper-ico.gif) no-repeat 0 0; + font-size: 14px; font-weight: bold; - padding-left: 20px; + padding-left: 20px; } #header a:link, @@ -233,15 +244,15 @@ fieldset{ border: 0; } #content{ background-color: #FFFFFF; padding: 40px 40px 20px; } -#brand{ - background-color: #F5F5F5; - color: #FFFFFF; +#brand{ + background-color: #F5F5F5; + color: #FFFFFF; overflow: hidden; - padding: 10px 20px 13px; + padding: 10px 20px 13px; } #brand > *{ float: left; } - + #brand p{ font-size: 14px; margin: 2px 0 0 5px; } #brand.ci p{ margin-top: 8px; } @@ -250,51 +261,52 @@ fieldset{ border: 0; } #brand.mm{ background-color: #222627; } #brand.el{ background-color: #4A0202; } -#header{ +#header{ background-color: #3B7EB0; border-top: 2px solid #539ECC; - color: #FFFFFF; - overflow: hidden; - padding: 15px 15px 16px 20px; + color: #FFFFFF; + overflow: hidden; + padding: 15px 15px 16px 20px; } #header form{ float: right; overflow: hidden; } - + #header input{ float: left; } - + #header input[type="text"]{ background-color: #FFFFFF; border: 1px solid; border-color: #033861 #13598F #13598F #033861; - font-size: inherit; + font: inherit; margin-right: 5px; padding: 5px; width: 175px; } - + #header input[type="text"]:focus{ background-color: #FFFDED; outline: 0; } - + #header input[type="submit"]{ background: #F0F9FF url(../../asset/img/grades.gif) repeat-x 0 -58px; border: 1px solid #033861; color: #094776; cursor: pointer; + font: inherit; font-weight: bold; - padding: 5px 10px 4px; + padding: 5px 10px; text-transform: uppercase; } - + #header input[type="submit"]:hover{ background-position: 0 -83px; } - - #header ul{ + + #header ul{ float: left; list-style-type: none; - margin: 0; + margin: 0; overflow: hidden; } - + #header li{ float: left; margin: 4px 5px 0 0; } - + #footer{ background-color: #F9F9F9; border-top: 1px solid #CCCCCC; padding: 20px; } #footer p{ margin: 0; } @@ -322,8 +334,8 @@ fieldset{ border: 0; } -webkit-box-sizing: border-box; box-sizing: border-box; margin-bottom: 10px; - resize: none; - width: 100%; + resize: none; + width: 100%; } #comment_form input[type="submit"]{ margin-top: 10px; } @@ -349,6 +361,4 @@ fieldset{ border: 0; } h3,h4,h5,h6{ font-size: 14px; } } -@media screen and (-webkit-min-device-pixel-ratio:0){ - #header input[type="submit"]{ padding-bottom: 7px; } -} +#header input[type="submit"], x:-moz-any-link{ padding: 4px 10px; } diff --git a/user_guide_src/source/_themes/eldocs/static/asset/js/method-toc.js b/user_guide_src/source/_themes/eldocs/static/asset/js/method-toc.js new file mode 100644 index 000000000..a926b3da9 --- /dev/null +++ b/user_guide_src/source/_themes/eldocs/static/asset/js/method-toc.js @@ -0,0 +1,44 @@ +/* modified from http://stackoverflow.com/a/12459801 */ +$(function (){ + var createList = function(selector){ + + var ul = $('<ul>'); + var selected = $(selector); + + if (selected.length === 0){ + return; + } + + selected.clone().each(function (i,e){ + + var p = $(e).children('.descclassname'); + var n = $(e).children('.descname'); + var l = $(e).children('.headerlink'); + + var a = $('<a>'); + a.attr('href',l.attr('href')).attr('title', 'jump to ' + n + '()'); + + a.append(p).append(n); + + var entry = $('<li>').append(a); + ul.append(entry); + }); + return ul; + } + + var c = $('<div>'); + + var ul0 = c.clone().append($('.submodule-index')) + + customIndex = $('.custom-index'); + customIndex.empty(); + customIndex.append(ul0); + + var l = createList('dl.method > dt, dl.function > dt'); + if (l) { + var ul = c.clone() + .append('<h3>Methods / Functions</h3>') + .append(l); + } + customIndex.append(ul); +});
\ No newline at end of file diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst index 4f30a9aa7..ce84b7f54 100644 --- a/user_guide_src/source/changelog.rst +++ b/user_guide_src/source/changelog.rst @@ -20,10 +20,11 @@ Release Date: Not Released - PHP 5.1.6 is no longer supported. CodeIgniter now requires PHP 5.2.4. - Changed filenaming convention (class file names now must be Ucfirst and everything else in lowercase). + - Changed the default database driver to 'mysqli' (the old 'mysql' driver is DEPRECATED). - ``$_SERVER['CI_ENV']`` can now be set to control the ``ENVIRONMENT`` constant. - Added an optional backtrace to php-error template. - Added Android to the list of user agents. - - Added Windows 7, Windows 8, Android, Blackberry, iOS and PlayStation 3 to the list of user platforms. + - Added Windows 7, Windows 8, Windows 8.1, Android, Blackberry, iOS and PlayStation 3 to the list of user platforms. - Added Fennec (Firefox for mobile) to the list of mobile user agents. - Ability to log certain error types, not all under a threshold. - Added support for pem, p10, p12, p7a, p7c, p7m, p7r, p7s, crt, crl, der, kdb, rsa, cer, sst, csr Certs to mimes.php. @@ -55,29 +56,30 @@ Release Date: Not Released - 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>`. - Removed *cheatsheets* and *quick_reference* PDFs from the documentation. + - Added support non-HTML error templates for CLI applications. - Added availability checks where usage of dangerous functions like ``eval()`` and ``exec()`` is required. - Added support for changing the file extension of log files using ``$config['log_file_extension']``. + - Added support for turning newline standardization on/off via ``$config['standardize_newlines']``. - Helpers - :doc:`Date Helper <helpers/date_helper>` changes include: - - :php:func:`now()` now works with all timezone strings supported by PHP. - - Added an optional third parameter to :php:func:`timespan()` that constrains the number of time units displayed. - - Added an optional parameter to :php:func:`timezone_menu()` that allows more attributes to be added to the generated select tag. + - :func:`now()` now works with all timezone strings supported by PHP. + - Added an optional third parameter to :func:`timespan()` that constrains the number of time units displayed. + - Added an optional parameter to :func:`timezone_menu()` that allows more attributes to be added to the generated select tag. - Deprecated ``standard_date()``, which now just uses the native ``date()`` with `DateTime constants <http://www.php.net/manual/en/class.datetime.php#datetime.constants.types>`_. - - Added function :php:func:`date_range()` that generates a list of dates between a specified period. + - Added function :func:`date_range()` that generates a list of dates between a specified period. - :doc:`URL Helper <helpers/url_helper>` changes include: - - Deprecated *separator* options **dash** and **underscore** for function :php:func:`url_title()` (they are only aliases for '-' and '_' respectively). - - :php:func:`url_title()` will now trim extra dashes from beginning and end. - - :php:func:`anchor_popup()` will now fill the *href* attribute with the URL and its JS code will return FALSE instead. - - Added JS window name support to the :php:func:`anchor_popup()` function. - - Added support (auto-detection) for HTTP/1.1 response code 303 in :php:func:`redirect()`. - - Changed :php:func:`redirect()` to choose the **refresh** method only on IIS servers, instead of all servers on Windows (when **auto** is used). - - Changed :php:func:`anchor()`, :php:func:`anchor_popup()`, and :php:func:`redirect()` to support protocol-relative URLs (e.g. *//ellislab.com/codeigniter*). - - Added an optional second parameter to both :php:func:`base_url()` and :php:func:`site_url()` that allows enforcing of a protocol different than the one in the *base_url* configuration setting. + - Deprecated *separator* options **dash** and **underscore** for function :func:`url_title()` (they are only aliases for '-' and '_' respectively). + - :func:`url_title()` will now trim extra dashes from beginning and end. + - :func:`anchor_popup()` will now fill the *href* attribute with the URL and its JS code will return FALSE instead. + - Added JS window name support to the :func:`anchor_popup()` function. + - Added support (auto-detection) for HTTP/1.1 response codes 303, 307 in :func:`redirect()`. + - Changed :func:`redirect()` to choose the **refresh** method only on IIS servers, instead of all servers on Windows (when **auto** is used). + - Changed :func:`anchor()`, :func:`anchor_popup()`, and :func:`redirect()` to support protocol-relative URLs (e.g. *//ellislab.com/codeigniter*). - :doc:`HTML Helper <helpers/html_helper>` changes include: @@ -87,24 +89,24 @@ Release Date: Not Released - :doc:`Inflector Helper <helpers/inflector_helper>` changes include: - - Changed :php:func:`humanize()` to allow passing an input separator as its second parameter. - - Refactored :php:func:`plural()` and :php:func:`singular()` to avoid double pluralization and support more words. + - Changed :func:`humanize()` to allow passing an input separator as its second parameter. + - Refactored :func:`plural()` and :func:`singular()` to avoid double pluralization and support more words. - :doc:`Download Helper <helpers/download_helper>` changes include: - - Added an optional third parameter to :php:func:`force_download()` that enables/disables sending the actual file MIME type in the Content-Type header (disabled by default). - - Added a work-around in :php:func:`force_download()` for a bug Android <= 2.1, where the filename extension needs to be in uppercase. - - Added support for reading from an existing file path by passing NULL as the second parameter to :php:func:`force_download()` (useful for large files and/or safely transmitting binary data). + - Added an optional third parameter to :func:`force_download()` that enables/disables sending the actual file MIME type in the Content-Type header (disabled by default). + - Added a work-around in :func:`force_download()` for a bug Android <= 2.1, where the filename extension needs to be in uppercase. + - Added support for reading from an existing file path by passing NULL as the second parameter to :func:`force_download()` (useful for large files and/or safely transmitting binary data). - :doc:`Form Helper <helpers/form_helper>` changes include: - - :php:func:`form_dropdown()` will now also take an array for unity with other form helpers. - - :php:func:`form_prep()`'s second argument now only accepts a boolean value, which determines whether the value is escaped for a <textarea> or a regular <input> element. + - :func:`form_dropdown()` will now also take an array for unity with other form helpers. + - :func:`form_prep()`'s second argument now only accepts a boolean value, which determines whether the value is escaped for a <textarea> or a regular <input> element. - :doc:`Security Helper <helpers/security_helper>` changes include: - - :php:func:`do_hash()` now uses PHP's native ``hash()`` function (supporting more algorithms) and is deprecated. - - :php:func:`strip_image_tags()` is now an alias for the same method in the :doc:`Security Library <libraries/security>`. + - :func:`do_hash()` now uses PHP's native ``hash()`` function (supporting more algorithms) and is deprecated. + - :func:`strip_image_tags()` is now an alias for the same method in the :doc:`Security Library <libraries/security>`. - :doc:`Smiley Helper <helpers/smiley_helper>` changes include: @@ -114,28 +116,31 @@ Release Date: Not Released - :doc:`File Helper <helpers/file_helper>` changes include: - - :php:func:`set_realpath()` can now also handle file paths as opposed to just directories. - - Added an optional paramater to :php:func:`delete_files()` to enable it to skip deleting files such as *.htaccess* and *index.html*. + - :func:`set_realpath()` can now also handle file paths as opposed to just directories. + - Added an optional paramater to :func:`delete_files()` to enable it to skip deleting files such as *.htaccess* and *index.html*. - Deprecated function ``read_file()`` - it's just an alias for PHP's native ``file_get_contents()``. - :doc:`String Helper <helpers/string_helper>` changes include: - Deprecated function ``repeater()`` - it's just an alias for PHP's native ``str_repeat()``. - Deprecated function ``trim_slashes()`` - it's just an alias for PHP's native ``trim()`` (with a slash as its second argument). - - Deprecated randomization type options **unique** and **encrypt** for funcion :php:func:`random_string()` (they are only aliases for **md5** and **sha1** respectively). + - Deprecated randomization type options **unique** and **encrypt** for funcion :func:`random_string()` (they are only aliases for **md5** and **sha1** respectively). - :doc:`CAPTCHA Helper <helpers/captcha_helper>` changes include: - Added *word_length* and *pool* options to allow customization of the generated word. - Added *colors* configuration to allow customization for the *background*, *border*, *text* and *grid* colors. + - Added *filename* to the returned array elements. - - :doc:`Directory Helper <helpers/directory_helper>` :php:func:`directory_map()` will now append ``DIRECTORY_SEPARATOR`` to directory names in the returned array. - - :doc:`Array Helper <helpers/array_helper>` :php:func:`element()` and :php:func:`elements()` now return NULL instead of FALSE when the required elements don't exist. - - :doc:`Language Helper <helpers/language_helper>` :php:func:`lang()` now accepts an optional list of additional HTML attributes. + - :doc:`Directory Helper <helpers/directory_helper>` :func:`directory_map()` will now append ``DIRECTORY_SEPARATOR`` to directory names in the returned array. + - :doc:`Array Helper <helpers/array_helper>` :func:`element()` and :func:`elements()` now return NULL instead of FALSE when the required elements don't exist. + - :doc:`Language Helper <helpers/language_helper>` :func:`lang()` now accepts an optional list of additional HTML attributes. + - Changed the default tag for use in :doc:`Text Helper <helpers/text_helper>` :func:`highlight_phrase()` to ``<mark>`` (formerly ``<strong>``). - Deprecated the :doc:`Email Helper <helpers/email_helper>` as its ``valid_email()``, ``send_email()`` functions are now only aliases for PHP native functions ``filter_var()`` and ``mail()`` respectively. - Database + - DEPRECATED the 'mysql', 'sqlite', 'mssql' and 'pdo/dblib' (also known as 'pdo/mssql' or 'pdo/sybase') drivers. - Added **dsn** configuration setting for drivers that support DSN strings (PDO, PostgreSQL, Oracle, ODBC, CUBRID). - Added **schema** configuration setting (defaults to *public*) for drivers that might need it (currently used by PostgreSQL and ODBC). - Added subdrivers support (currently only used by PDO). @@ -155,6 +160,7 @@ Release Date: Not Released - Added support for SQLite3 database driver. - Added Interbase/Firebird database support via the *ibase* driver. - Added ODBC support for ``create_database()``, ``drop_database()`` and ``drop_table()`` in :doc:`Database Forge <database/forge>`. + - Added **save_queries** configuration setting to *application/config/database.php* (defaults to ``TRUE``). - :doc:`Query Builder <database/query_builder>` changes include: @@ -164,6 +170,7 @@ Release Date: Not Released - Added an optional parameter that allows to disable escaping (useful for custom fields) for methods ``join()``, ``order_by()``, ``where_in()``, ``or_where_in()``, ``where_not_in()``, ``or_where_not_in()``, ``insert()``, ``insert_batch()``. - Added support for ``join()`` with multiple conditions. - Added support for *USING* in ``join()``. + - Added support for *EXISTS* in ``where()``. - Added seed values support for random ordering with ``order_by(seed, 'RANDOM')``. - Changed ``limit()`` to ignore NULL values instead of always casting to integer. - Changed ``offset()`` to ignore empty values instead of always casting to integer. @@ -181,6 +188,7 @@ Release Date: Not Released - Server version checking is now done via ``mysqli::$server_info`` instead of running an SQL query. - Added persistent connections support for PHP >= 5.3. - Added support for ``backup()`` in :doc:`Database Utilities <database/utilities>`. + - Changed methods ``trans_begin()``, ``trans_commit()`` and ``trans_rollback()`` to use the PHP API instead of sending queries. - Improved support of the PDO driver, including: @@ -198,6 +206,7 @@ Release Date: Not Released - Removed ``limit()`` and ``order_by()`` support for *UPDATE* and *DELETE* queries as PostgreSQL does not support those features. - Added a work-around for dead persistent connections to be re-created after a database restart. - Changed ``db_connect()`` to include the (new) **schema** value into Postgre's **search_path** session variable. + - ``pg_escape_literal()`` is now used for escaping strings, if available. - Improved support of the CUBRID driver, including: @@ -213,6 +222,9 @@ Release Date: Not Released - Added port handling support for UNIX-based systems (MSSQL driver). - Added *OFFSET* support for SQL Server 2005 and above. - Added ``db_set_charset()`` support (MSSQL driver). + - Added a *scrollable* property to enable configuration of the cursor to use (SQLSRV driver). + - Added support and auto-detection for the ``SQLSRV_CURSOR_CLIENT_BUFFERED`` scrollable cursor flag (SQLSRV driver). + - Changed default behavior to not use ``SQLSRV_CURSOR_STATIC`` due to performance issues (SQLSRV driver). - Improved support of the Oracle (OCI8) driver, including: @@ -231,8 +243,9 @@ Release Date: Not Released - Added an optional second parameter to ``drop_table()`` that allows adding the **IF EXISTS** condition, which is no longer the default. - Added support for passing a custom database object to the loader. - - Deprecated ``add_column()``'s third method. *AFTER* clause should now be added to the field definition array instead. + - Added support for passing custom table attributes (such as ``ENGINE`` for MySQL) to ``create_table()``. - Added support for usage of the *FIRST* clause in ``add_column()`` for MySQL and CUBRID. + - Deprecated ``add_column()``'s third method. *AFTER* clause should now be added to the field definition array instead. - Overall improved support for all of the drivers. - :doc:`Database Utility <database/utilities>` changes include: @@ -244,24 +257,28 @@ Release Date: Not Released - Libraries + - Added a new :doc:`Encryption Library <libraries/encryption>` to replace the old, largely insecure :doc:`Encrypt Library <libraries/encrypt>`. + + - :doc:`Encrypt Library <libraries/encrypt>` changes include: + + - Deprecated the library in favor of the new :doc:`Encryption Library <libraries/encryption>`. + - Added support for hashing algorithms other than SHA1 and MD5. + - Removed previously deprecated ``sha1()`` 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 drivers can be added anywhere in package paths and be loaded with the library. - - Drivers interchangeable on the fly. - - New **tempdata** feature allows setting user data items with an expiration time. - - Added default ``$config['sess_driver']`` and ``$config['sess_valid_drivers']`` items to *config.php* file. - - Cookie driver now respects php.ini's *session.gc_probability* and *session.gc_divisor* settings. - - Cookie driver now uses HMAC authentication instead of the simple md5 checksum. - - The Cookie driver now also checks authentication on encrypted session data. - - Changed the Cookie driver to select only one row when using database sessions. - - Cookie driver now only writes to database at end of request when using database. - - Cookie driver now uses PHP functions for faster array manipulation when using database. - - Added ``all_flashdata()`` method to session class. Returns an associative array of only flashdata. - - Added ``has_userdata()`` method to verify existence of userdata item. - - Added ``tempdata()``, ``set_tempdata()``, and ``unset_tempdata()`` methods for manipulating tempdata. - - ``keep_flashdata()`` now accepts an array of keys. + - Library changed to :doc:`Driver <general/drivers>` with classic 'cookie' driver as the default. + - Added a 'native' PHP Session driver to work with ``$_SESSION``. + - Added a new **tempdata** feature that allows setting userdata items with expiration time (``tempdata()``, ``set_tempdata()``, ``unset_tempdata()``). + - Added default ``$config['sess_driver']`` and ``$config['sess_valid_drivers']`` items to *application/config.php* file. + - Changed 'cookie' driver to respect php.ini's *session.gc_probability* and *session.gc_divisor* settings. + - Changed 'cookie' driver to use HMAC authentication instead of a simple md5 checksum. + - Changed 'cookie' driver to select only one row when using database sessions. + - Changed 'cookie' driver to write to only write to the database at end of page execution. + - Changed method ``keep_flashdata()`` to also accept an array of keys. + - Changed methods ``userdata()``, ``flashdata()`` to return an array of all userdata/flashdata when no parameter is passed. + - Deprecated method ``all_userdata()`` - it is now just an alias for ``userdata()`` with no parameters. + - Added method ``has_userdata()`` that verifies the existence of a userdata item. - Added *debug* level log messages for key events in the session validation process. - :doc:`File Uploading Library <libraries/file_uploading>` changes include: @@ -271,8 +288,15 @@ Release Date: Not Released - Added the **min_width** and **min_height** options for images. - Removed method ``clean_file_name()`` and its usage in favor of :doc:`Security Library <libraries/security>`'s ``sanitize_filename()``. - Added **file_ext_tolower** config setting. + - Added **mod_mime_fix** option to disable suffixing multiple file extensions with an underscore. + + - :doc:`Calendar Library <libraries/calendar>` changes include: + + - Added method chaining support. + - Added configuration to generate days of other months instead of blank cells. + - Auto set *next_prev_url* if it is empty and *show_prev_next* is set to TRUE. - - :doc:`Cart library <libraries/cart>` changes include: + - :doc:`Cart Library <libraries/cart>` changes include: - ``insert()`` now auto-increments quantity for an item when inserted twice instead of resetting it, this is the default behaviour of large e-commerce sites. - *Product Name* strictness can be disabled by switching the ``$product_name_safe`` property to FALSE. @@ -280,7 +304,7 @@ Release Date: Not Released - Added method ``get_item()`` to enable retrieving data for a single cart item. - Added unicode support for product names. - - :doc:`Image Manipulation library <libraries/image_lib>` changes include: + - :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. @@ -289,7 +313,7 @@ Release Date: Not Released - 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: + - :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``. @@ -305,6 +329,7 @@ Release Date: Not Released - Added support for named parameters in error messages. - :doc:`Language <libraries/language>` line keys must now be prefixed with **form_validation_**. - Added rule **alpha_numeric_spaces**. + - Added support for custom error messages per field rule. - :doc:`Caching Library <libraries/caching>` changes include: @@ -312,13 +337,17 @@ Release Date: Not Released - Added Redis driver. - Added a *key_prefix* option for cache IDs. - Updated driver ``is_supported()`` methods to log at the "debug" level. + - Added option to store raw values instead of CI-formatted ones (APC, Memcache). + - Added atomic increment/decrement feature via ``increment()``, ``decrement()``. - - :doc:`Email library <libraries/email>` changes include: + - :doc:`E-mail Library <libraries/email>` changes include: - - Added custom filename to ``Email::attach()`` as ``$this->email->attach($filename, $disposition, $newname)``. - - Added possibility to send attachment as buffer string in ``Email::attach()`` as ``$this->email->attach($buffer, $disposition, $newname, $mime)``. + - Added a custom filename parameter to ``attach()`` as ``$this->email->attach($filename, $disposition, $newname)``. + - Added possibility to send attachment as buffer string in ``attach()`` as ``$this->email->attach($buffer, $disposition, $newname, $mime)``. + - Added possibility to attach remote files by passing a URL. + - Added method ``attachment_cid()`` to enable embedding inline attachments into HTML. - 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>`. + - Renamed method ``_set_header()`` to ``set_header()`` and made it public to enable adding custom headers. - Successfully sent emails will automatically clear the parameters. - Added a *return_path* parameter to the ``from()`` method. - Removed the second parameter (character limit) from internal method ``_prep_quoted_printable()`` as it is never used. @@ -327,58 +356,86 @@ Release Date: Not Released - Removed unused protected method ``_get_ip()`` (:doc:`Input Library <libraries/input>`'s ``ip_address()`` should be used anyway). - Internal method ``_prep_q_encoding()`` now utilizes PHP's *mbstring* and *iconv* extensions (when available) and no longer has a second (``$from``) argument. - Added an optional parameter to ``print_debugger()`` to allow specifying which parts of the message should be printed ('headers', 'subject', 'body'). - - Added SMTP keepalive option to avoid opening the connection for each ``Email::send()``. Accessible as ``$smtp_keepalive``. + - Added SMTP keepalive option to avoid opening the connection for each ``send()`` call. Accessible as ``$smtp_keepalive``. - Public method ``set_header()`` now filters the input by removing all "\\r" and "\\n" characters. - :doc:`Pagination Library <libraries/pagination>` changes include: + - Added method chaining support to ``initialize()`` method. - 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 `` `` 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. - :doc:`Profiler Library <general/profiling>` changes include: - Database object names are now being displayed. - The sum of all queries running times in seconds is now being displayed. - Added support for displaying the HTTP DNT ("Do Not Track") header. + - Added support for displaying ``$_FILES``. - :doc:`Migration Library <libraries/migration>` changes include: - Added support for timestamp-based migrations (enabled by default). - Added ``$config['migration_type']`` to allow switching between *sequential* and *timestamp* migrations. - - :doc:`User Agent Library <libraries/user_agent>` will now check if robots are pretending to be mobile clients (helps with e.g. Google indexing mobile website versions). - - Added support for setting :doc:`Table <libraries/table>` class defaults in a config file. + - :doc:`XML-RPC Library <libraries/xmlrpc>` changes include: + + - Added the ability to use a proxy. + - Added Basic HTTP authentication support. + + - :doc:`User Agent Library <libraries/user_agent>` changes include: + + - Added check to detect if robots are pretending to be mobile clients (helps with e.g. Google indexing mobile website versions). + - Added method ``parse()`` to allow parsing a custom user-agent string, different from the current visitor's. + + - :doc:`HTML Table Library <libraries/table>` changes include: + + - Added method chaining support. + - Added support for setting table class defaults in a config file. + + - :doc:`Zip Library <libraries/zip>` method ``read_file()`` can now also alter the original file path/name while adding files to an archive. + - :doc:`Trackback Library <libraries/trackback>` method ``receive()`` will now utilize ``iconv()`` if it is available but ``mb_convert_encoding()`` is not. - Core + - :doc:`Routing <general/routing>` changes include: + + - Added support for multiple levels of controller directories. + - Added support for per-directory *default_controller* and *404_override* classes. + - Added possibility to route requests using HTTP verbs. + - Added possibility to route requests using callbacks. + - Added a new reserved route (*translate_uri_dashes*) to allow usage of dashes in the controller and method URI segments. + - Deprecated methods ``fetch_directory()``, ``fetch_class()`` and ``fetch_method()`` in favor of their respective public properties. + - Removed method ``_set_overrides()`` and moved its logic to the class constructor. + - :doc:`URI Library <libraries/uri>` changes include: + - Added conditional PCRE UTF-8 support to the "invalid URI characters" check and removed the ``preg_quote()`` call from it to allow more flexibility. + - Renamed method ``_filter_uri()`` to ``filter_uri()``. - Changed private methods to protected so that MY_URI can override them. - Renamed internal method ``_parse_cli_args()`` to ``_parse_argv()``. - Renamed internal method ``_detect_uri()`` to ``_parse_request_uri()``. - Changed ``_parse_request_uri()`` to accept absolute URIs for compatibility with HTTP/1.1 as per `RFC2616 <http://www.ietf.org/rfc/rfc2616.txt>`. - Added protected method ``_parse_query_string()`` to URI paths in the the **QUERY_STRING** value, like ``_parse_request_uri()`` does. - Changed ``_fetch_uri_string()`` to try the **PATH_INFO** variable first when auto-detecting. + - Removed methods ``_remove_url_suffix()``, ``_explode_segments()`` and moved their logic into ``_set_uri_string()``. + - Removed method ``_fetch_uri_string()`` and moved its logic into the class constructor. + - Removed method ``_reindex_segments()``. - :doc:`Loader Library <libraries/loader>` changes include: + - Added method chaining support. - Added method ``get_vars()`` to the Loader to retrieve all variables loaded with ``$this->load->vars()``. - ``_ci_autoloader()`` is now a protected method. - Added autoloading of drivers with ``$autoload['drivers']``. - ``$config['rewrite_short_tags']`` now has no effect when using PHP 5.4 as ``<?=`` will always be available. - Changed method ``config()`` to return whatever ``CI_Config::load()`` returns instead of always being void. - - Added support for model aliasing on autoload. + - Added support for library and model aliasing on autoload. - Changed method ``is_loaded()`` to ask for the (case sensitive) library name instead of its instance name. - Removed ``$_base_classes`` property and unified all class data in ``$_ci_classes`` instead. + - Added method ``clear_vars()`` to allow clearing the cached variables for views. - :doc:`Input Library <libraries/input>` changes include: @@ -388,29 +445,36 @@ Release Date: Not Released - Changed method ``valid_ip()`` to use PHP's native ``filter_var()`` function. - Changed internal method ``_sanitize_globals()`` to skip enforcing reversal of *register_globals* in PHP 5.4+, where this functionality no longer exists. - Changed methods ``get()``, ``post()``, ``get_post()``, ``cookie()``, ``server()``, ``user_agent()`` to return NULL instead of FALSE when no value is found. + - Changed default value of the ``$xss_clean`` parameter to NULL for all methods that utilize it, the default value is now determined by the ``$config['global_xss_filtering']`` setting. - Added method ``post_get()`` and changed ``get_post()`` to search in GET data first. Both methods' names now properly match their GET/POST data search priorities. - Changed method ``_fetch_from_array()`` to parse array notation in field name. + - Added an option for ``_clean_input_keys()`` to return FALSE instead of terminating the whole script. + - Deprecated the ``is_cli_request()`` method, it is now an alias for the new :func:`is_cli()` common function. - :doc:`Common functions <general/common_functions>` changes include: - - Added function :php:func:`get_mimes()` to return the *application/config/mimes.php* array. - - Added support for HTTP code 303 ("See Other") in :php:func:`set_status_header()`. - - Removed redundant conditional to determine HTTP server protocol in :php:func:`set_status_header()`. + - Added function :func:`get_mimes()` to return the *application/config/mimes.php* array. + - Added support for HTTP code 303 ("See Other") in :func:`set_status_header()`. + - Removed redundant conditional to determine HTTP server protocol in :func:`set_status_header()`. - Changed ``_exception_handler()`` to respect php.ini *display_errors* setting. - - Added function :php:func:`is_https()` to check if a secure connection is used. - - Added function :php:func:`function_usable()` to check if a function exists and is not disabled by `Suhosin <http://www.hardened-php.net/suhosin/>`. + - Added function :func:`is_https()` to check if a secure connection is used. + - Added function :func:`is_cli()` to replace the ``CI_Input::is_cli_request()`` method. + - Added function :func:`function_usable()` to work around a bug in `Suhosin <http://www.hardened-php.net/suhosin/>`. + - Removed the third (`$php_error`) argument from function :func:`log_message()`. - :doc:`Output Library <libraries/output>` changes include: - Added a second argument to method ``set_content_type()`` that allows setting the document charset as well. - Added methods ``get_content_type()`` and ``get_header()``. - Added method ``delete_cache()``. + - Changed caching behavior to compress the output before storing it, if ``$config['compress_output']`` is enabled. - :doc:`Config Library <libraries/config>` changes include: - Changed ``site_url()`` method to accept an array as well. - Removed internal method ``_assign_to_config()`` and moved its implementation to *CodeIgniter.php* instead. - ``item()`` now returns NULL instead of FALSE when the required config item doesn't exist. + - Added an optional second parameter to both ``base_url()`` and ``site_url()`` that allows enforcing of a protocol different than the one in the *base_url* configuration setting. - :doc:`Security Library <libraries/security>` changes include: @@ -419,157 +483,161 @@ Release Date: Not Released - Added ``$config['csrf_exclude_uris']``, which allows you list URIs which will not have the CSRF validation methods run. - Modified method ``sanitize_filename()`` to read a public ``$filename_bad_chars`` property for getting the invalid characters list. - - :doc:`URI Routing <general/routing>` changes include: - - - Added possibility to route requests using callbacks. - - Added a new reserved route (*translate_uri_dashes*) to allow usage of dashes in the controller and method URI segments. - - Deprecated methods ``fetch_directory()``, ``fetch_class()`` and ``fetch_method()`` in favor of their respective public properties. - - :doc:`Language Library <libraries/language>` changes include: - - Changed method ``load()`` to filter the language name with ``ctype_digit()``. + - Changed method ``load()`` to filter the language name with ``ctype_alpha()``. - Added an optional second parameter to method ``line()`` to disable error login for line keys that were not found. - Language files are now loaded in a cascading style with the one in **system/** always loaded and overriden afterwards, if another one is found. + - :doc:`Hooks Library <general/hooks>` changes include: + + - Renamed method ``_call_hook()`` to ``call_hook()``. + - Class instances are now stored in order to maintain their state. + + - UTF-8 Library changes include: + + - ``UTF8_ENABLED`` now requires only one of `Multibyte String <http://php.net/mbstring>`_ or `iconv <http://php.net/iconv>`_ to be available instead of both. + - Changed method ``clean_string()`` to utilize ``mb_convert_encoding()`` if it is available but ``iconv()`` is not. + + - Added compatibility layers for PHP's `Multibyte string <http://php.net/mbstring>`_ (limited support) and `Password Hashing <http://php.net/password>` extensions. - Removed ``CI_CORE`` boolean constant from *CodeIgniter.php* (no longer Reactor and Core versions). - Log Library will now try to create the **log_path** directory if it doesn't exist. - Added support for HTTP-Only cookies with new config option *cookie_httponly* (default FALSE). - - Renamed method ``_call_hook()`` to ``call_hook()`` in the :doc:`Hooks Library <general/hooks>`. - ``$config['time_reference']`` now supports all timezone strings supported by PHP. + - Fatal PHP errors are now also passed to ``_exception_handler()``, so they can be logged. Bug fixes for 3.0 ------------------ - Fixed a bug where ``unlink()`` raised an error if cache file did not exist when you try to delete it. -- Fixed a bug (#181) where a mis-spelling was in the form validation language file. -- Fixed a bug (#159, #163) - :doc:`Query Builder <database/query_builder>` nested transactions didn't work properly due to ``_trans_depth`` not being incremented. +- Fixed a bug (#181) - a typo in the form validation language file. +- Fixed a bug (#159, #163) - :doc:`Query Builder <database/query_builder>` nested transactions didn't work properly due to ``$_trans_depth`` not being incremented. - Fixed a bug (#737, #75) - :doc:`Pagination <libraries/pagination>` anchor class was not set properly when using initialize method. -- Fixed a bug (#419) - :php:func:`auto_link()` didn't recognize URLs that come after a word boundary. +- Fixed a bug (#419) - :doc:`URL Helper <helpers/url_helper>` :func:`auto_link()` didn't recognize URLs that come after a word boundary. - Fixed a bug (#724) - :doc:`Form Validation Library <libraries/form_validation>` rule **is_unique** didn't check if a database connection exists. - Fixed a bug (#647) - :doc:`Zip Library <libraries/zip>` internal method ``_get_mod_time()`` didn't suppress possible "stat failed" errors generated by ``filemtime()``. - Fixed a bug (#157, #174) - :doc:`Image Manipulation Library <libraries/image_lib>` method ``clear()`` didn't completely clear properties. - Fixed a bug where :doc:`Database Forge <database/forge>` method ``create_table()`` with PostgreSQL database could lead to fetching the whole table. -- Fixed a bug (#795) - :doc:`Form Helper <helpers/form_helper>` :php:func:`form_open()` didn't add the default form *method* and *accept-charset* when an empty array is passed to it. -- Fixed a bug (#797) - :php:func:`timespan()` was using incorrect seconds for year and month. -- Fixed a bug in CI_Cart::contents() where if called without a TRUE (or equal) parameter, it would fail due to a typo. -- Fixed a bug (#696) - make oci_execute() calls inside num_rows() non-committing, since they are only there to reset which row is next in line for oci_fetch calls and thus don't need to be committed. +- Fixed a bug (#795) - :doc:`Form Helper <helpers/form_helper>` :func:`form_open()` didn't add the default form *method* and *accept-charset* when an empty array is passed to it. +- Fixed a bug (#797) - :doc:`Date Helper <helpers/date_helper>` :func:`timespan()` was using incorrect seconds for year and month. +- Fixed a bug in :doc:`Cart Library <libraries/cart>` method ``contents()`` where if called without a TRUE (or equal) parameter, it would fail due to a typo. +- Fixed a bug (#696) - make ``oci_execute()`` calls inside ``num_rows()`` non-committing, since they are only there to reset which row is next in line for oci_fetch calls and thus don't need to be committed. - Fixed a bug (#406) - SQLSRV DB driver not returning resource on ``db_pconnect()``. -- Fixed a bug in CI_Image_lib::gd_loaded() where it was possible for the script execution to end or a PHP E_WARNING message to be emitted. +- Fixed a bug in :doc:`Image Manipulation Library <libraries/image_lib>` method ``gd_loaded()`` where it was possible for the script execution to end or a PHP E_WARNING message to be emitted. - Fixed a bug in the :doc:`Pagination library <libraries/pagination>` where when use_page_numbers=TRUE previous link and page 1 link did not have the same url. -- Fixed a bug (#561) - Errors in :doc:`XML-RPC Library <libraries/xmlrpc>` were not properly escaped. -- Fixed a bug (#904) - ``CI_Loader::initialize()`` caused a PHP Fatal error to be triggered if error level E_STRICT is used. -- Fixed a hosting edge case where an empty $_SERVER['HTTPS'] variable would evaluate to 'on'. -- Fixed a bug (#154) - ``CI_Session::sess_update()`` caused the session to be destroyed on pages where multiple AJAX requests were executed at once. -- Fixed a possible bug in ``CI_Input::is_ajax_request()`` where some clients might not send the X-Requested-With HTTP header value exactly as 'XmlHttpRequest'. -- Fixed a bug (#1039) - MySQL's _backup() method failed due to a table name not being escaped. -- Fixed a bug (#1070) - CI_DB_driver::initialize() didn't set a character set if a database is not selected. -- Fixed a bug (#177) - CI_Form_validation::set_value() didn't set the default value if POST data is NULL. -- Fixed a bug (#68, #414) - Oracle's escape_str() didn't properly escape LIKE wild characters. -- Fixed a bug (#81) - ODBC's list_fields() and field_data() methods skipped the first column due to odbc_field_*() functions' index starting at 1 instead of 0. -- Fixed a bug (#129) - ODBC's num_rows() returned -1 in some cases, due to not all subdrivers supporting the odbc_num_rows() function. -- Fixed a bug (#153) - E_NOTICE being generated by getimagesize() in the :doc:`File Uploading Library <libraries/file_uploading>`. +- Fixed a bug (#561) - errors in :doc:`XML-RPC Library <libraries/xmlrpc>` were not properly escaped. +- Fixed a bug (#904) - :doc:`Loader Library <libraries/loader>` method ``initialize()`` caused a PHP Fatal error to be triggered if error level E_STRICT is used. +- Fixed a hosting edge case where an empty ``$_SERVER['HTTPS']`` variable would evaluate to 'on'. +- Fixed a bug (#154) - :doc:`Session Library <libraries/sessions>` method ``sess_update()`` caused the session to be destroyed on pages where multiple AJAX requests were executed at once. +- Fixed a possible bug in :doc:`Input Libary <libraries/input>` method ``is_ajax_request()`` where some clients might not send the X-Requested-With HTTP header value exactly as 'XmlHttpRequest'. +- Fixed a bug (#1039) - :doc:`Database Utilities <database/utilities>` internal method ``_backup()`` method failed for the 'mysql' driver due to a table name not being escaped. +- Fixed a bug (#1070) - ``CI_DB_driver::initialize()`` didn't set a character set if a database is not selected. +- Fixed a bug (#177) - :doc:`Form Validation Library <libraries/form_validation>` method ``set_value()`` didn't set the default value if POST data is NULL. +- Fixed a bug (#68, #414) - :Oracle's ``escape_str()`` didn't properly escape LIKE wild characters. +- Fixed a bug (#81) - ODBC's ``list_fields()`` and ``field_data()`` methods skipped the first column due to ``odbc_field_*()`` functions' index starting at 1 instead of 0. +- Fixed a bug (#129) - ODBC's ``num_rows()`` method 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 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 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 (#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 (#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 (#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 (#1101) - :doc:`Database Result <database/results>` method ``field_data()`` for 'mysql', 'mysqli' drivers 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 <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, :doc:`Email Library <libraries/email>` method ``send()`` was returning TRUE even if the connection/authentication against the server failed. +- 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 :doc:`Database Result <database/results>` implementation 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) - :doc:`Form Validation Library <libraries/form_validation>` method ``set_rules()`` depended on ``count($_POST)`` instead of actually checking if the request method 'POST' before aborting. +- Fixed a bug (#136) - PostgreSQL and MySQL's ``escape_str()`` method didn't properly escape LIKE wild characters. +- Fixed a bug in :doc:`Loader Library <libraries/loader>` method ``library()`` 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. -- Fixed a bug (#14) - create_database() method in the :doc:`Database Forge Library <database/forge>` didn't utilize the configured database character set. -- Fixed a bug (#23, #1238) - delete_all() in the `Database Caching Library <database/caching>` used to delete .htaccess and index.html files, which is a potential security risk. -- Fixed a bug in :doc:`Trackback Library <libraries/trackback>` method validate_url() where it didn't actually do anything, due to input not being passed by reference. -- Fixed a bug (#11, #183, #863) - CI_Form_validation::_execute() silently continued to the next rule, if a rule method/function is not found. +- Fixed a bug (#14) - :doc:`Database Forge <database/forge>` method ``create_database()`` didn't utilize the configured database character set. +- Fixed a bug (#23, #1238) - :doc:`Database Caching <database/caching>` method ``delete_all()`` used to delete .htaccess and index.html files, which is a potential security risk. +- Fixed a bug in :doc:`Trackback Library <libraries/trackback>` method ``validate_url()`` where it didn't actually do anything, due to input not being passed by reference. +- Fixed a bug (#11, #183, #863) - :doc:`Form Validation Library <libraries/form_validation>` method ``_execute()`` silently continued to the next rule, if a rule method/function is not found. - Fixed a bug (#122) - routed URI string was being reported incorrectly in sub-directories. -- Fixed a bug (#1242) - read_dir() in the :doc:`Zip Library <libraries/zip>` wasn't compatible with Windows. -- Fixed a bug (#306) - ODBC driver didn't have an _insert_batch() method, which resulted in fatal error being triggered when insert_batch() is used with it. -- Fixed a bug in MSSQL and SQLSrv's _truncate() where the TABLE keyword was missing. -- Fixed a bug in PDO's trans_commit() method where it failed due to an erroneous property name. -- Fixed a bug (#798) - update() used to ignore LIKE conditions that were set with like(). -- Fixed a bug in Oracle's and MSSQL's delete() methods where an erroneous SQL statement was generated when used with limit(). -- Fixed a bug in SQLSRV's delete() method where like() and limit() conditions were ignored. +- Fixed a bug (#1241) - :doc:`Zip Library <libraries/zip>` method ``read_dir()`` wasn't compatible with Windows. +- Fixed a bug (#306) - ODBC driver didn't have an ``_insert_batch()`` method, which resulted in fatal error being triggered when ``insert_batch()`` is used with it. +- Fixed a bug in MSSQL and SQLSrv's ``_truncate()`` where the TABLE keyword was missing. +- Fixed a bug in PDO's ``trans_commit()`` method where it failed due to an erroneous property name. +- Fixed a bug (#798) - :doc:`Query Builder <database/query_builder>` method ``update()`` used to ignore LIKE conditions that were set with ``like()``. +- Fixed a bug in Oracle's and MSSQL's ``delete()`` methods where an erroneous SQL statement was generated when used with ``limit()``. +- Fixed a bug in SQLSRV's ``delete()`` method where ``like()`` and ``limit()`` conditions were ignored. - 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 (#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. -- Fixed a bug (#121) - ``CI_DB_result::row()`` returned an array when there's no actual result to be returned. -- Fixed a bug (#319) - SQLSRV's affected_rows() method failed due to a scrollable cursor being created for write-type queries. -- Fixed a bug (#356) - PostgreSQL driver didn't have an _update_batch() method, which resulted in fatal error being triggered when update_batch() is used with it. +- Fixed a bug (#1349) - :doc:`File Uploading Library <libraries/file_uploading>` method ``get_extension()`` returned the original filename when it didn't have an actual extension. +- Fixed a bug (#1273) - :doc:`Query Builder <database/query_builder>` method ``set_update_batch()`` generated an E_NOTICE message. +- Fixed a bug (#44, #110) - :doc:`File Uploading Library <libraries/file_uploading>` method ``clean_file_name()`` didn't clear '!' and '#' characters. +- Fixed a bug (#121) - :doc:`Database Results <database/results>` method ``row()`` returned an array when there's no actual result to be returned. +- Fixed a bug (#319) - SQLSRV's ``affected_rows()`` method failed due to a scrollable cursor being created for write-type queries. +- Fixed a bug (#356) - :doc:`Database <database/index>` driver 'postgre' didn't have an ``_update_batch()`` method, which resulted in fatal error being triggered when ``update_batch()`` is used with it. - Fixed a bug (#784, #862) - :doc:`Database Forge <database/forge>` method ``create_table()`` failed on SQLSRV/MSSQL when used with 'IF NOT EXISTS'. -- Fixed a bug (#1419) - libraries/Driver.php had a static variable that was causing an error. -- Fixed a bug (#1411) - the :doc:`Email library <libraries/email>` used its own short list of MIMEs instead the one from config/mimes.php. -- Fixed a bug where the magic_quotes_runtime setting wasn't turned off for PHP 5.3 (where it is indeed deprecated, but not non-existent). -- Fixed a bug (#666) - :doc:`Output library <libraries/output>`'s set_content_type() method didn't set the document charset. +- Fixed a bug (#1419) - :doc:`Driver Library <general/creating_drivers>` had a static variable that was causing an error. +- Fixed a bug (#1411) - the :doc:`Email Library <libraries/email>` used its own short list of MIMEs instead the one from *config/mimes.php*. +- Fixed a bug where php.ini setting *magic_quotes_runtime* wasn't turned off for PHP 5.3 (where it is indeed deprecated, but not non-existent). +- Fixed a bug (#666) - :doc:`Output Library <libraries/output>` method ``set_content_type()`` 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 its extra arguments when the value passed to it is an array. -- Fixed a bug where ``_has_operator()`` didn't detect BETWEEN. -- Fixed a bug in :doc:`Query Builder <database/query_builder>`'s ``join()`` method where it failed with identifiers containing dashes. +- Fixed a bug (#706) - SQLSRV/MSSSQL :doc:`Database <database/index>` drivers didn't escape field names. +- Fixed a bug (#1452) - :doc:`Query Builder <database/query_builder>` method ``protect_identifiers()`` didn't properly detect identifiers with spaces in their names. +- Fixed a bug where :doc:`Query Builder <database/query_builder>` method ``protect_identifiers()`` ignored its extra arguments when the value passed to it is an array. +- Fixed a bug where :doc:`Query Builder <database/query_builder>` internal method ``_has_operator()`` didn't detect BETWEEN. +- Fixed a bug where :doc:`Query Builder <database/query_builder>` method ``join()`` 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 (#1321) - Core Exceptions class couldn't find the errors/ folder in some cases. -- 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. -- Fixed a bug (#10) - :doc:`URI Library <libraries/uri>` internal method _detect_uri() failed with paths containing a colon. -- Fixed a bug (#1387) - :doc:`Query Builder <database/query_builder>`'s from() method didn't escape table aliases. -- Fixed a bug (#520) - :doc:`Date Helper <helpers/date_helper>` function nice_date() failed when the optional second parameter is not passed. +- Fixed a bug (#7) - :doc:`Query Builder <database/query_builder>` method ``join()`` only escaped one set of conditions. +- Fixed a bug (#1321) - ``CI_Exceptions`` couldn't find the *errors/* directory in some cases. +- Fixed a bug (#1202) - :doc:`Encrypt Library <libraries/encrypt>` ``encode_from_legacy()`` didn't set back the encrypt mode on failure. +- Fixed a bug (#145) - :doc:`Database Class <database/index>` method ``compile_binds()`` failed when the bind marker was present in a literal string within the query. +- Fixed a bug in :doc:`Query Builder <database/query_builder>` method ``protect_identifiers()`` where if passed along with the field names, operators got escaped as well. +- Fixed a bug (#10) - :doc:`URI Library <libraries/uri>` internal method ``_detect_uri()`` failed with paths containing a colon. +- Fixed a bug (#1387) - :doc:`Query Builder <database/query_builder>` method ``from()`` didn't escape table aliases. +- Fixed a bug (#520) - :doc:`Date Helper <helpers/date_helper>` function :func:``nice_date()`` failed when the optional second parameter is not passed. - Fixed a bug (#167) - ``$config['permitted_uri_chars']`` didn't affect URL-encoded characters. -- Fixed a bug (#318) - :doc:`Profiling <general/profiling>` setting *query_toggle_count* was not settable as described in the manual. +- Fixed a bug (#318) - :doc:`Profiling Library <general/profiling>` setting *query_toggle_count* was not settable as described in the manual. - Fixed a bug (#938) - :doc:`Config Library <libraries/config>` method ``site_url()`` added a question mark to the URL string when query strings are enabled even if it already existed. - Fixed a bug (#999) - :doc:`Config Library <libraries/config>` method ``site_url()`` always appended ``$config['url_suffix']`` to the end of the URL string, regardless of whether a query string exists in it. -- Fixed a bug where :doc:`URL Helper <helpers/url_helper>` function ``anchor_popup()`` ignored the attributes argument if it is not an array. +- Fixed a bug where :doc:`URL Helper <helpers/url_helper>` function :func:`anchor_popup()` ignored the attributes argument if it is not an array. - Fixed a bug (#1328) - :doc:`Form Validation Library <libraries/form_validation>` didn't properly check the type of the form fields before processing them. - Fixed a bug (#79) - :doc:`Form Validation Library <libraries/form_validation>` didn't properly validate array fields that use associative keys or have custom indexes. - Fixed a bug (#427) - :doc:`Form Validation Library <libraries/form_validation>` method ``strip_image_tags()`` was an alias to a non-existent method. - Fixed a bug (#1545) - :doc:`Query Builder <database/query_builder>` method ``limit()`` wasn't executed properly under Oracle. -- Fixed a bug (#1551) - :doc:`Date Helper <helpers/date_helper>` function ``standard_date()`` didn't properly format *W3C* and *ATOM* standard dates. -- Fixed a bug in :doc:`Query Builder <database/query_builder>` method join() where literal values were escaped as if they were fields. +- Fixed a bug (#1551) - :doc:`Date Helper <helpers/date_helper>` function :func:`standard_date()` didn't properly format *W3C* and *ATOM* standard dates. +- Fixed a bug where :doc:`Query Builder <database/query_builder>` method ``join()`` escaped literal values as if they were fields. - Fixed a bug (#135) - PHP Error logging was impossible without the errors being displayed. -- 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 (#1613) - :doc:`Form Helper <helpers/form_helper>` functions :func:`form_multiselect()`, :func:`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 (#1757) - :doc:`Directory Helper <helpers/directory_helper>` function :func:`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 (#1692) - :doc:`Database Class <database/index>` method ``display_error()`` didn't properly trace the possible error source on Windows systems. +- Fixed a bug (#1745) - :doc:`Database Class <database/index>` method ``is_write_type()`` didn't return TRUE for LOAD queries. +- Fixed a bug (#1765) - :doc:`Database Class <database/index>` didn't properly detect connection errors for the 'mysqli' driver. - 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. -- Fixed a bug where ``MB_ENABLED`` was only declared if ``UTF8_ENABLED`` was set to TRUE. +- Fixed a bug where ``MB_ENABLED`` constant was only declared if ``UTF8_ENABLED`` was set to TRUE. - Fixed a bug where the :doc:`Session Library <libraries/sessions>` accepted cookies with *last_activity* values being in the future. - Fixed a bug (#1897) - :doc:`Email Library <libraries/email>` triggered PHP E_WARNING errors when *mail* protocol used and ``to()`` is never called. - Fixed a bug (#1409) - :doc:`Email Library <libraries/email>` didn't properly handle multibyte characters when applying Q-encoding to headers. -- Fixed a bug where :doc:`Email Library <libraries/email>` didn't honor its *wordwrap* setting while handling alternative messages. +- Fixed a bug where :doc:`Email Library <libraries/email>` ignored its *wordwrap* setting while handling alternative messages. - Fixed a bug (#1476, #1909) - :doc:`Pagination Library <libraries/pagination>` didn't take into account actual routing when determining the current page. - Fixed a bug (#1766) - :doc:`Query Builder <database/query_builder>` didn't always take into account the *dbprefix* setting. - Fixed a bug (#779) - :doc:`URI Class <libraries/uri>` didn't always trim slashes from the *uri_string* as shown in the documentation. - Fixed a bug (#134) - :doc:`Database Caching <database/caching>` method ``delete_cache()`` didn't work in some cases due to *cachedir* not being initialized properly. - Fixed a bug (#191) - :doc:`Loader Library <libraries/loader>` ignored attempts for (re)loading databases to ``get_instance()->db`` even when the old database connection is dead. - Fixed a bug (#1255) - :doc:`User Agent Library <libraries/user_agent>` method ``is_referral()`` only checked if ``$_SERVER['HTTP_REFERER']`` exists. -- Fixed a bug (#1146) - :doc:`Download Helper <helpers/download_helper>` function ``force_download()`` incorrectly sent *Cache-Control* directives *pre-check* and *post-check* to Internet Explorer. +- Fixed a bug (#1146) - :doc:`Download Helper <helpers/download_helper>` function :func:`force_download()` incorrectly sent *Cache-Control* directives *pre-check* and *post-check* to Internet Explorer. - Fixed a bug (#1811) - :doc:`URI Library <libraries/uri>` didn't properly cache segments for ``uri_to_assoc()`` and ``ruri_to_assoc()``. - Fixed a bug (#1506) - :doc:`Form Helpers <helpers/form_helper>` set empty *name* attributes. - Fixed a bug (#59) - :doc:`Query Builder <database/query_builder>` method ``count_all_results()`` ignored the DISTINCT clause. - Fixed a bug (#1624) - :doc:`Form Validation Library <libraries/form_validation>` rule **matches** didn't property handle array field names. -- Fixed a bug (#1630) - :doc:`Form Helper <helpers/form_helper>` function ``set_value()`` didn't escape HTML entities. -- Fixed a bug (#142) - :doc:`Form Helper <helpers/form_helper>` function ``form_dropdown()`` didn't escape HTML entities in option values. +- Fixed a bug (#1630) - :doc:`Form Helper <helpers/form_helper>` function :func:`set_value()` didn't escape HTML entities. +- Fixed a bug (#142) - :doc:`Form Helper <helpers/form_helper>` function :func:`form_dropdown()` didn't escape HTML entities in option values. - Fixed a bug (#50) - :doc:`Session Library <libraries/sessions>` unnecessarily stripped slashed from serialized data, making it impossible to read objects in a namespace. - Fixed a bug (#658) - :doc:`Routing <general/routing>` wildcard **:any** didn't work as advertised and matched multiple URI segments instead of all characters within a single segment. - Fixed a bug (#1938) - :doc:`Email Library <libraries/email>` removed multiple spaces inside a pre-formatted plain text message. @@ -578,37 +646,63 @@ Bug fixes for 3.0 - Fixed a bug - :doc:`Routing Library <general/routing>` didn't properly handle *default_controller* in a subdirectory when a method is also specified. - Fixed a bug (#953) - :doc:`post_controller_constructor hook <general/hooks>` wasn't called with a *404_override*. - Fixed a bug (#1220) - :doc:`Profiler Library <general/profiling>` didn't display information for database objects that are instantiated inside models. -- Fixed a bug (#1978) - :doc:`Directory Helper <helpers/directory_helper>` function :php:func:`directory_map()`'s return array didn't make a distinction between directories and file indexes when a directory with a numeric name is present. +- Fixed a bug (#1978) - :doc:`Directory Helper <helpers/directory_helper>` function :func:`directory_map()`'s return array didn't make a distinction between directories and file indexes when a directory with a numeric name is present. - Fixed a bug (#777) - :doc:`Loader Library <libraries/loader>` didn't look for helper extensions in added package paths. - Fixed a bug (#18) - :doc:`APC Cache <libraries/caching>` driver didn't (un)serialize data, resulting in failure to store objects. - Fixed a bug (#188) - :doc:`Unit Testing Library <libraries/unit_testing>` filled up logs with error messages for non-existing language keys. - Fixed a bug (#113) - :doc:`Form Validation Library <libraries/form_validation>` didn't properly handle empty fields that were specified as an array. - Fixed a bug (#2061) - :doc:`Routing Class <general/routing>` didn't properly sanitize directory, controller and function triggers with **enable_query_strings** set to TRUE. - Fixed a bug - SQLSRV didn't support ``escape_like_str()`` or escaping an array of values. -- Fixed a bug - :doc:`Database Results <database/results>` method ``list_fields()`` didn't reset its field pointer for the *mysql*, *mysqli* and *mssql* drivers. +- Fixed a bug - :doc:`Database Results <database/results>` method ``list_fields()`` didn't reset its field pointer for the 'mysql', 'mysqli' and 'mssql' drivers. - Fixed a bug (#73) - :doc:`Security Library <libraries/security>` method ``sanitize_filename()`` could be tricked by an XSS attack. - Fixed a bug (#2211) - :doc:`Migration Library <libraries/migration>` extensions couldn't execute ``CI_Migration::__construct()``. -- Fixed a bug (#2255) - :doc:`Email Library <libraries/email>` didn't apply ``smtp_timeout`` to socket reads and writes. -- Fixed a bug (#2239) - :doc:`Email Library <libraries/email>` improperly handled the Subject when used with ``bcc_batch_mode`` resulting in E_WARNING messages and an empty Subject. +- Fixed a bug (#2255) - :doc:`Email Library <libraries/email>` didn't apply *smtp_timeout* to socket reads and writes. +- Fixed a bug (#2239) - :doc:`Email Library <libraries/email>` improperly handled the Subject when used with *bcc_batch_mode* resulting in E_WARNING messages and an empty Subject. - Fixed a bug (#2234) - :doc:`Query Builder <database/query_builder>` didn't reset JOIN cache for write-type queries. - Fixed a bug (#2298) - :doc:`Database Results <database/results>` method ``next_row()`` kept returning the last row, allowing for infinite loops. -- Fixed a bug (#2236) - :doc:`Form Helper <helpers/form_helper>` function ``set_value()`` didn't parse array notation for keys if the rule was not present in the :doc:`Form Validation Library <libraries/form_validation>`. +- Fixed a bug (#2236, #2639) - :doc:`Form Helper <helpers/form_helper>` functions :func:`set_value()`, :func:`set_select()`, :func:`set_radio()`, :func:`set_checkbox()` didn't parse array notation for keys if the rule was not present in the :doc:`Form Validation Library <libraries/form_validation>`. - Fixed a bug (#2353) - :doc:`Query Builder <database/query_builder>` erroneously prefixed literal strings with **dbprefix**. - Fixed a bug (#78) - :doc:`Cart Library <libraries/cart>` didn't allow non-English letters in product names. - Fixed a bug (#77) - :doc:`Database Class <database/index>` didn't properly handle the transaction "test mode" flag. - Fixed a bug (#2380) - :doc:`URI Routing <general/routing>` method ``fetch_method()`` returned 'index' if the requested method name matches its controller name. - Fixed a bug (#2388) - :doc:`Email Library <libraries/email>` used to ignore attachment errors, resulting in broken emails being sent. - Fixed a bug (#2498) - :doc:`Form Validation Library <libraries/form_validation>` rule **valid_base64** only checked characters instead of actual validity. -- Fixed a bug (#2425) - OCI8 :doc:`database <database>` driver's method ``stored_procedure()`` didn't log an error unless **db_debug** was set to TRUE. +- Fixed a bug (#2425) - OCI8 :doc:`database <database/index>` driver method ``stored_procedure()`` didn't log an error unless **db_debug** was set to TRUE. - Fixed a bug (#2490) - :doc:`Database Class <database/queries>` method ``query()`` returning boolean instead of a result object for PostgreSQL-specific *INSERT INTO ... RETURNING* statements. - Fixed a bug (#249) - :doc:`Cache Library <libraries/caching>` didn't properly handle Memcache(d) configurations with missing options. -- Fixed a bug (#180) - :php:func:`config_item()` didn't take into account run-time configuration changes. +- Fixed a bug (#180) - :func:`config_item()` didn't take into account run-time configuration changes. - Fixed a bug (#2551) - :doc:`Loader Library <libraries/loader>` method ``library()`` didn't properly check if a class that is being loaded already exists. -- Fixed a bug (#2560) - :doc:`Form Helper <helpers/form_helper>` function :php:func:`form_open()` set the 'method="post"' attribute only if the passed attributes equaled an empty string. +- Fixed a bug (#2560) - :doc:`Form Helper <helpers/form_helper>` function :func:`form_open()` set the 'method="post"' attribute only if the passed attributes equaled an empty string. - Fixed a bug (#2585) - :doc:`Query Builder <database/query_builder>` methods ``min()``, ``max()``, ``avg()``, ``sum()`` didn't escape field names. - Fixed an edge case (#2583) in the :doc:`Email Library <libraries/email>` where `Suhosin <http://www.hardened-php.net/suhosin/>` blocked messages sent via ``mail()`` due to trailing newspaces in headers. -- Fixed a bug (#2590) - :php:func:`log_message()` didn't actually cache the ``CI_Log`` class instance. -- Fixed a bug (#2609) - :php:func:`get_config()` optional argument was only effective on first function call. Also, it can now add items, in addition to updating existing items. +- Fixed a bug (#2590) - :doc:`Common function <general/common_functions>` :func:`log_message()` didn't actually cache the ``CI_Log`` class instance. +- Fixed a bug (#2609) - :doc:`Common function <general/common_functions>` :func:`get_config()` optional argument was only effective on first function call. Also, it can now add items, in addition to updating existing items. +- Fixed a bug in the 'postgre' :doc:`database <database/index>` driver where the connection ID wasn't passed to ``pg_escape_string()``. +- Fixed a bug (#33) - Script execution was terminated when an invalid cookie key was encountered. +- Fixed a bug (#2681) - :doc:`Security Library <libraries/security>` method ``entity_decode()`` used the `PREG_REPLACE_EVAL` flag, which is deprecated since PHP 5.5. +- Fixed a bug (#2691) - nested :doc:`database <database/index>` transactions could end in a deadlock when an error is encountered with *db_debug* set to TRUE. +- Fixed a bug (#2515) - ``_exception_handler()`` used to send the 200 "OK" HTTP status code and didn't stop script exection even on fatal errors. +- Fixed a bug - Redis :doc:`Caching <libraries/caching>` driver didn't handle connection failures properly. +- Fixed a bug (#2756) - :doc:`Database Class <database/index>` executed the MySQL-specific `SET SESSION sql_mode` query for all drivers when the 'stricton' option is set. +- Fixed a bug (#2579) - :doc:`Query Builder <database/query_builder>` "no escape" functionality didn't work properly with query cache. +- Fixed a bug (#2237) - :doc:`Parser Library <libraries/parser>` failed if the same tag pair is used more than once within a template. +- Fixed a bug (#2268) - :doc:`Security Library <libraries/security>` didn't properly match JavaScript events. +- Fixed a bug (#2143) - :doc:`Form Validation Library <libraries/form_validation>` didn't check for rule groups named in a *controller/method* manner when trying to load from a config file. +- Fixed a bug (#2762) - :doc:`Hooks Class <general/hooks>` didn't properly check if the called class/function exists. +- Fixed a bug (#148) - :doc:`Input Library <libraries/input>` internal method ``_clean_input_data()`` assumed that it data is URL-encoded, stripping certain character sequences from it. +- Fixed a bug (#346) - with ``$config['global_xss_filtering']`` turned on, the ``$_GET``, ``$_POST``, ``$_COOKIE`` and ``$_SERVER`` superglobals were overwritten during initialization time, resulting in XSS filtering being either performed twice or there was no possible way to get the original data, even though options for this do exist. +- Fixed an edge case (#555) - :doc:`User Agent Library <libraries/user_agent>` reported an incorrect version Opera 10+ due to a non-standard user-agent string. +- Fixed a bug (#133) - :doc:`Text Helper <helpers/text_helper>` :func:`ascii_to_entities()` stripped the last character if it happens to be in the extended ASCII group. +- Fixed a bug (#2822) - ``fwrite()`` was used incorrectly throughout the whole framework, allowing incomplete writes when writing to a network stream and possibly a few other edge cases. +- Fixed a bug where :doc:`User Agent Library <libraries/user_agent>` methods ``accept_charset()`` and ``accept_lang()`` didn't properly parse HTTP headers that contain spaces. +- Fixed a bug where *default_controller* was called instad of triggering a 404 error if the current route is in a controller directory. +- Fixed a bug (#2737) - :doc:`XML-RPC Library <libraries/xmlrpc>` used objects as array keys, which triggered E_NOTICE messages. +- Fixed a bug (#2729) - :doc:`Security Library <libraries/security>` internal method ``_validate_entities()`` used overly-intrusive ``preg_replace()`` patterns that produced false-positives. +- Fixed a bug (#2771) - :doc:`Security Library <libraries/security>` method ``xss_clean()`` didn't take into account HTML5 entities. +- Fixed a bug in the :doc:`Session Library <libraries/sessions>` 'cookie' driver where authentication was not performed for encrypted cookies. +- Fixed a bug (#2856) - ODBC method ``affected_rows()`` passed an incorrect value to ``odbc_num_rows()``. +- Fixed a bug (#43) :doc:`Image Manipulation Library <libraries/image_lib>` method ``text_watermark()`` didn't properly determine watermark placement. +- Fixed a bug where :doc:`HTML Table Library <libraries/table>` ignored its *auto_heading* setting if headings were not already set. Version 2.1.4 ============= @@ -765,7 +859,6 @@ Bug fixes for 2.1.0 but the requested method did not. - Fixed a bug (Reactor #89) where MySQL export would fail if the table had hyphens or other non alphanumeric/underscore characters. -- Fixed a bug (#200) where MySQL queries would be malformed after calling $this->db->count_all() then $this->db->get() - Fixed a bug (#105) that stopped query errors from being logged unless database debugging was enabled - Fixed a bug (#160) - Removed unneeded array copy in the file cache driver. @@ -786,7 +879,7 @@ Bug fixes for 2.1.0 - Fixed a bug (#537) - Support for all wav type in browser. - Fixed a bug (#576) - Using ini_get() function to detect if apc is enabled or not. - Fixed invalid date time format in :doc:`Date helper <helpers/date_helper>` and :doc:`XMLRPC library <libraries/xmlrpc>`. -- Fixed a bug (#200) - MySQL queries would be malformed after calling count_all() then db->get(). +- Fixed a bug (#200) - MySQL queries would be malformed after calling db->count_all() then db->get(). Version 2.0.3 ============= @@ -1215,7 +1308,7 @@ Hg Tag: v2.0.0 - Documented append_output() in the :doc:`Output Class <libraries/output>`. - Documented a second argument in the decode() function for the - :doc:`Encryption Class <libraries/encryption>`. + :doc:`Encrypt Class <libraries/encrypt>`. - Documented db->close(). - Updated the router to support a default route with any number of segments. @@ -2180,7 +2273,7 @@ Bug fixes for Version 1.6.0 - Fixed a bug (#3003) in the Encryption Library to support modes other than MCRYPT_MODE_ECB - Fixed a bug (#3015) in the :doc:`User Agent - library <./libraries/user_agent>` where more then 2 languages + library <./libraries/user_agent>` where more than 2 languages where not reported with languages(). - Fixed a bug (#3017) in the :doc:`Email <./libraries/email>` library where some timezones were calculated incorrectly. diff --git a/user_guide_src/source/conf.py b/user_guide_src/source/conf.py index 6d77db060..3f9b2e476 100644 --- a/user_guide_src/source/conf.py +++ b/user_guide_src/source/conf.py @@ -41,7 +41,7 @@ master_doc = 'index' # General information about the project. project = u'CodeIgniter' -copyright = u'2013, EllisLab, Inc.' +copyright = u'2014, EllisLab, Inc.' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -224,7 +224,7 @@ man_pages = [ epub_title = u'CodeIgniter' epub_author = u'EllisLab, Inc.' epub_publisher = u'EllisLab, Inc.' -epub_copyright = u'2013, EllisLab, Inc.' +epub_copyright = u'2014, EllisLab, Inc.' # The language of the text. It defaults to the language option # or en if the language is not set. diff --git a/user_guide_src/source/contributing/index.rst b/user_guide_src/source/contributing/index.rst index 0771a4192..4d3fe6ede 100644 --- a/user_guide_src/source/contributing/index.rst +++ b/user_guide_src/source/contributing/index.rst @@ -33,7 +33,7 @@ PHP Style ========= All code must meet the `Style Guide -<http://codeigniter.com/user_guide/general/styleguide.html>`_, which is +<http://ellislab.com/codeigniter/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 diff --git a/user_guide_src/source/database/forge.rst b/user_guide_src/source/database/forge.rst index ca904ed00..48642ad7e 100644 --- a/user_guide_src/source/database/forge.rst +++ b/user_guide_src/source/database/forge.rst @@ -201,6 +201,15 @@ into the definition $this->dbforge->create_table('table_name', TRUE); // gives CREATE TABLE IF NOT EXISTS table_name +You could also pass optional table attributes, such as MySQL's ``ENGINE``:: + + $attributes = array('ENGINE' => 'InnoDB'); + $this->dbforge->create_table('table_name', FALSE, $attributes); + // produces: CREATE TABLE `table_name` (...) ENGINE = InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci + +.. note:: Unless you specify the ``CHARACTER SET`` and/or ``COLLATE`` attributes, + ``create_table()`` will always add them with your configured *char_set* + and *dbcollat* values, as long as they are not empty (MySQL only). Dropping a table ================ diff --git a/user_guide_src/source/database/helpers.rst b/user_guide_src/source/database/helpers.rst index e8a5ac801..77bf1b5d2 100644 --- a/user_guide_src/source/database/helpers.rst +++ b/user_guide_src/source/database/helpers.rst @@ -3,7 +3,7 @@ Query Helper Functions ###################### $this->db->insert_id() -======================= +====================== The insert ID number when performing database inserts. @@ -12,7 +12,7 @@ The insert ID number when performing database inserts. appropriate sequence to check for the insert id. $this->db->affected_rows() -=========================== +========================== Displays the number of affected rows, when doing "write" type queries (insert, update, etc.). @@ -22,8 +22,8 @@ Displays the number of affected rows, when doing "write" type queries affected rows. By default this hack is enabled but it can be turned off in the database driver file. -$this->db->count_all(); -======================== +$this->db->count_all() +====================== Permits you to determine the number of rows in a particular table. Submit the table name in the first parameter. Example:: @@ -47,8 +47,8 @@ Outputs the database version you are running:: echo $this->db->version(); -$this->db->last_query(); -========================= +$this->db->last_query() +======================= Returns the last query that was run (the query string, not the result). Example:: @@ -57,11 +57,12 @@ Example:: // Produces: SELECT * FROM sometable.... -The following two functions help simplify the process of writing -database INSERTs and UPDATEs. -$this->db->insert_string(); -============================ +.. note:: Disabling the **save_queries** setting in your database + configuration will render this function useless. + +$this->db->insert_string() +========================== This function simplifies the process of writing database inserts. It returns a correctly formatted SQL insert string. Example:: @@ -77,8 +78,8 @@ array with the data to be inserted. The above example produces:: .. note:: Values are automatically escaped, producing safer queries. -$this->db->update_string(); -============================ +$this->db->update_string() +========================== This function simplifies the process of writing database updates. It returns a correctly formatted SQL update string. Example:: @@ -95,4 +96,4 @@ array with the data to be updated, and the third parameter is the UPDATE table_name SET name = 'Rick', email = 'rick@example.com', url = 'example.com' WHERE author_id = 1 AND status = 'active' -.. note:: Values are automatically escaped, producing safer queries. +.. note:: Values are automatically escaped, producing safer queries.
\ No newline at end of file diff --git a/user_guide_src/source/database/query_builder.rst b/user_guide_src/source/database/query_builder.rst index 65609c1cb..5bfdfdb52 100644 --- a/user_guide_src/source/database/query_builder.rst +++ b/user_guide_src/source/database/query_builder.rst @@ -68,7 +68,7 @@ Example:: // Produces string: SELECT * FROM mytable The second parameter enables you to set whether or not the query builder query -will be reset (by default it will be—just like `$this->db->get()`):: +will be reset (by default it will be reset, just like when using `$this->db->get()`):: echo $this->db->limit(10,20)->get_compiled_select('mytable', FALSE); // Produces string: SELECT * FROM mytable LIMIT 20, 10 @@ -76,7 +76,7 @@ will be reset (by default it will be—just like `$this->db->get()`):: echo $this->db->select('title, content, date')->get_compiled_select(); - // Produces string: SELECT title, content, date FROM mytable + // Produces string: SELECT title, content, date FROM mytable LIMIT 20, 10 The key thing to notice in the above example is that the second query did not utilize `$this->db->from()`_ and did not pass a table name into the first @@ -665,10 +665,12 @@ will be reset (by default it will be--just like `$this->db->insert()`_):: // Produces string: INSERT INTO mytable (title, content) VALUES ('My Title', 'My Content') The key thing to notice in the above example is that the second query did not -utlize `$this->db->from()`_ nor did it pass a table name into the first +utlize `$this->db->from()` nor did it pass a table name into the first parameter. The reason this worked is because the query has not been executed -using `$this->db->insert()`_ which resets values or reset directly using -`$this->db->reset_query()`_. +using `$this->db->insert()` which resets values or reset directly using +`$this->db->reset_query()`. + +.. note:: This method doesn't work for batched inserts. $this->db->insert_batch() ========================= @@ -886,8 +888,9 @@ $this->db->get_compiled_update() This works exactly the same way as ``$this->db->get_compiled_insert()`` except that it produces an UPDATE SQL string instead of an INSERT SQL string. -For more information view documentation for `$this->db->get_compiled_insert()`_. +For more information view documentation for `$this->db->get_compiled_insert()`. +.. note:: This method doesn't work for batched updates. ************* Deleting Data @@ -1055,4 +1058,9 @@ run the query:: $data = $this->db->get()->result_array(); // Would execute and return an array of results of the following query: - // SELECT field1, field1 from mytable where field3 = 5;
\ No newline at end of file + // SELECT field1, field1 from mytable where field3 = 5; + +.. note:: Double calls to ``get_compiled_select()`` while you're using the + Query Builder Caching functionality and NOT resetting your queries + will results in the cache being merged twice. That in turn will + i.e. if you're caching a ``select()`` - select the same field twice.
\ No newline at end of file diff --git a/user_guide_src/source/documentation/index.rst b/user_guide_src/source/documentation/index.rst index e977566d2..b080c0efa 100644 --- a/user_guide_src/source/documentation/index.rst +++ b/user_guide_src/source/documentation/index.rst @@ -8,12 +8,28 @@ Markdown or Textile, you will quickly grasp reStructuredText. The focus is on readability, user friendliness, and an "I've got your hand, baby" feel. While they can be quite technical, we always write for humans! -A table of contents should always be included like the one below. -It is created automatically by inserting the ``.. contents::`` -directive on a line by itself. +A local table of contents should always be included like the one below. +It is created automatically by inserting the the following: -.. contents:: Page Contents +:: + .. contents:: + :local: + + .. raw:: html + + <div class="custom-index container"></div> + +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + +The <div> that is inserted as raw HTML is a hook for the documentation's +JavaScript to dynamically add links to any function and method definitions +contained in the current page. ************** Tools Required @@ -50,39 +66,39 @@ overlines. Other headings just use underlines, with the following hierarchy:: - for subsubsections ^ for subsubsubsections " for subsubsubsubsections (!) - + The :download:`TextMate ELDocs Bundle <./ELDocs.tmbundle.zip>` can help you create these with the following tab triggers:: title-> - + ########## Page Title ########## sec-> - + ************* Major Section ************* - + sub-> - + Subsection ========== - + sss-> - + SubSubSection ------------- - + ssss-> - + SubSubSubSection ^^^^^^^^^^^^^^^^ - + sssss-> - + SubSubSubSubSection (!) """"""""""""""""""""""" @@ -99,12 +115,9 @@ ReST: .. code-block:: rst - .. php:class:: Some_class - - some_method() - ============= + .. class:: Some_class - .. php:method:: some_method ( $foo [, $bar [, $bat]]) + .. method:: some_method ( $foo [, $bar [, $bat]]) This function will perform some action. The ``$bar`` array must contain a something and something else, and along with ``$bat`` is an optional @@ -114,8 +127,8 @@ ReST: :param mixed $bar: A data array that must contain aa something and something else :param bool $bat: whether or not to do something :returns: FALSE on failure, TRUE if successful - :rtype: Boolean - + :rtype: bool + :: $this->load->library('some_class'); @@ -131,29 +144,25 @@ ReST: { show_error('An Error Occurred Doing Some Method'); } - + .. note:: Here is something that you should be aware of when using some_method(). For real. - - See also :php:meth:`Some_class::should_do_something` - should_do_something() - ===================== + See also :meth:`Some_class::should_do_something` + - .. php:method:: should_do_something() + .. method:: should_do_something() - :returns: whether or something should be done or not - :rtype: Boolean + :returns: Whether or something should be done or not + :rtype: bool It creates the following display: -.. php:class:: Some_class +.. class:: Some_class -some_method() -============= - .. php:method:: some_method ( $foo [, $bar [, $bat]]) + .. method:: some_method ( $foo [, $bar [, $bat]]) This function will perform some action. The ``$bar`` array must contain a something and something else, and along with ``$bat`` is an optional @@ -163,8 +172,8 @@ some_method() :param mixed $bar: A data array that must contain aa something and something else :param bool $bat: whether or not to do something :returns: FALSE on failure, TRUE if successful - :rtype: Boolean - + :rtype: bool + :: $this->load->library('some_class'); @@ -180,16 +189,14 @@ some_method() { show_error('An Error Occurred Doing Some Method'); } - + .. note:: Here is something that you should be aware of when using some_method(). For real. - - See also :php:meth:`Some_class::should_do_something` -should_do_something() -===================== + See also :meth:`Some_class::should_do_something` + - .. php:method:: should_do_something() + .. method:: should_do_something() - :returns: whether or something should be done or not - :rtype: Boolean + :returns: Whether or something should be done or not + :rtype: bool
\ No newline at end of file diff --git a/user_guide_src/source/general/ancillary_classes.rst b/user_guide_src/source/general/ancillary_classes.rst index 5dc058ad4..edb3a14fb 100644 --- a/user_guide_src/source/general/ancillary_classes.rst +++ b/user_guide_src/source/general/ancillary_classes.rst @@ -9,7 +9,7 @@ resources. This is easily possible as you'll see. get_instance() ============== -.. php:function:: get_instance() +.. function:: get_instance() :returns: object of class CI_Controller @@ -48,7 +48,7 @@ Once you've assigned the object to a variable, you'll use that variable passed by reference:: $CI =& get_instance(); - + This is very important. Assigning by reference allows you to use the original CodeIgniter object rather than creating a copy of it. diff --git a/user_guide_src/source/general/caching.rst b/user_guide_src/source/general/caching.rst index 48385d6c9..f499f6e93 100644 --- a/user_guide_src/source/general/caching.rst +++ b/user_guide_src/source/general/caching.rst @@ -45,6 +45,9 @@ you. Once the tag is in place, your pages will begin being cached. caching will only work if you are generating display for your controller with a :doc:`view <./views>`. +.. important:: If you change configuration options that might affect + your output, you have to manually delete your cache files. + .. note:: Before the cache files can be written you must set the file permissions on your *application/cache/* directory such that it is writable. diff --git a/user_guide_src/source/general/cli.rst b/user_guide_src/source/general/cli.rst index 4145d5ccc..4f3b07d9e 100644 --- a/user_guide_src/source/general/cli.rst +++ b/user_guide_src/source/general/cli.rst @@ -23,7 +23,7 @@ but they are not always obvious. - Run your cron-jobs without needing to use *wget* or *curl* - Make your cron-jobs inaccessible from being loaded in the URL by - checking for ``$this->input->is_cli_request()`` + checking the return value of :func:`is_cli()`. - Make interactive "tasks" that can do things like set permissions, prune cache folders, run backups, etc. - Integrate with other applications in other languages. For example, a diff --git a/user_guide_src/source/general/common_functions.rst b/user_guide_src/source/general/common_functions.rst index 32e8a8be0..2ca7478ec 100644 --- a/user_guide_src/source/general/common_functions.rst +++ b/user_guide_src/source/general/common_functions.rst @@ -6,188 +6,183 @@ CodeIgniter uses a few functions for its operation that are globally defined, and are available to you at any point. These do not require loading any libraries or helpers. -is_php() -======== +.. contents:: + :local: -.. php:function:: is_php($version = '5.3.0') +.. raw:: html - :param string $version: Version number - :returns: bool + <div class="custom-index container"></div> + +.. function:: is_php([$version = '5.3.0']) -Determines of the PHP version being used is greater than the -supplied version number. + :param string $version: Version number + :returns: TRUE if the running PHP version is at least the one specified or FALSE if not + :rtype: bool -Example:: + Determines of the PHP version being used is greater than the + supplied version number. - if (is_php('5.3')) - { - $str = quoted_printable_encode($str); - } + Example:: -Returns boolean TRUE if the installed version of PHP is equal to or -greater than the supplied version number. Returns FALSE if the installed -version of PHP is lower than the supplied version number. + if (is_php('5.3')) + { + $str = quoted_printable_encode($str); + } -is_really_writable() -==================== + Returns boolean TRUE if the installed version of PHP is equal to or + greater than the supplied version number. Returns FALSE if the installed + version of PHP is lower than the supplied version number. -.. php:function:: is_really_writable($file) +.. function:: is_really_writable($file) :param string $file: File path - :returns: bool + :returns: TRUE if the path is writable, FALSE if not + :rtype: bool -``is_writable()`` returns TRUE on Windows servers when you really can't -write to the file as the OS reports to PHP as FALSE only if the -read-only attribute is marked. + ``is_writable()`` returns TRUE on Windows servers when you really can't + write to the file as the OS reports to PHP as FALSE only if the + read-only attribute is marked. -This function determines if a file is actually writable by attempting -to write to it first. Generally only recommended on platforms where -this information may be unreliable. + This function determines if a file is actually writable by attempting + to write to it first. Generally only recommended on platforms where + this information may be unreliable. -Example:: + Example:: - if (is_really_writable('file.txt')) - { - echo "I could write to this if I wanted to"; - } - else - { - echo "File is not writable"; - } + if (is_really_writable('file.txt')) + { + echo "I could write to this if I wanted to"; + } + else + { + echo "File is not writable"; + } -config_item() -============= + .. note:: See also `PHP bug #54709 <https://bugs.php.net/bug.php?id=54709>`_ for more info. -.. php:function:: config_item($key) +.. function:: config_item($key) :param string $key: Config item key - :returns: mixed + :returns: Configuration key value or FALSE if not found + :rtype: mixed -The :doc:`Config Library <../libraries/config>` is the preferred way of -accessing configuration information, however ``config_item()`` can be used -to retrieve single keys. See :doc:`Config Library <../libraries/config>` -documentation for more information. + The :doc:`Config Library <../libraries/config>` is the preferred way of + accessing configuration information, however ``config_item()`` can be used + to retrieve single keys. See :doc:`Config Library <../libraries/config>` + documentation for more information. -show_error() -============ - -.. php:function:: show_error($message, $status_code, $heading = 'An Error Was Encountered') +.. :noindex: function:: show_error($message, $status_code[, $heading = 'An Error Was Encountered']) :param mixed $message: Error message :param int $status_code: HTTP Response status code :param string $heading: Error page heading - :returns: void - -This function calls ``CI_Exception::show_error()``. For more info, -please see the :doc:`Error Handling <errors>` documentation. + :rtype: void -show_404() -========== + This function calls ``CI_Exception::show_error()``. For more info, + please see the :doc:`Error Handling <errors>` documentation. -.. php:function:: show_404($page = '', $log_error = TRUE) +.. :noindex: function:: show_404([$page = ''[, $log_error = TRUE]]) :param string $page: URI string :param bool $log_error: Whether to log the error - :returns: void + :rtype: void -This function calls ``CI_Exception::show_404()``. For more info, -please see the :doc:`Error Handling <errors>` documentation. + This function calls ``CI_Exception::show_404()``. For more info, + please see the :doc:`Error Handling <errors>` documentation. -log_message() -============= - -.. php:function:: log_message($level, $message, $php_error = FALSE) +.. :noindex: function:: log_message($level, $message) :param string $level: Log level: 'error', 'debug' or 'info' :param string $message: Message to log - :param bool $php_error: Whether we're logging a native PHP error message - :returns: void - -This function is an alias for ``CI_Log::write_log()``. For more info, -please see the :doc:`Error Handling <errors>` documentation. + :rtype: void -set_status_header() -=============================== + This function is an alias for ``CI_Log::write_log()``. For more info, + please see the :doc:`Error Handling <errors>` documentation. -.. php:function:: set_status_header($code, $text = '') +.. function:: set_status_header($code[, $text = '']) :param int $code: HTTP Reponse status code :param string $text: A custom message to set with the status code - :returns: void + :rtype: void -Permits you to manually set a server status header. Example:: + Permits you to manually set a server status header. Example:: - set_status_header(401); - // Sets the header as: Unauthorized + set_status_header(401); + // Sets the header as: Unauthorized -`See here <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html>`_ for -a full list of headers. + `See here <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html>`_ for + a full list of headers. -remove_invisible_characters() -============================= - -.. php:function:: remove_invisible_characters($str, $url_encoded = TRUE) +.. function:: remove_invisible_characters($str[, $url_encoded = TRUE]) :param string $str: Input string :param bool $url_encoded: Whether to remove URL-encoded characters as well - :returns: string + :returns: Sanitized string + :rtype: string -This function prevents inserting NULL characters between ASCII -characters, like Java\\0script. + This function prevents inserting NULL characters between ASCII + characters, like Java\\0script. -Example:: + Example:: - remove_invisible_characters('Java\\0script'); - // Returns: 'Javascript' + remove_invisible_characters('Java\\0script'); + // Returns: 'Javascript' -html_escape() -============= +.. function:: html_escape($var) -.. php:function:: html_escape($var) + :param mixed $var: Variable to escape (string or array) + :returns: HTML escaped string(s) + :rtype: mixed - :param mixed $var: Variable to escape - (string or array) - :returns: mixed + This function acts as an alias for PHP's native ``htmlspecialchars()`` + function, with the advantage of being able to accept an array of strings. -This function acts as an alias for PHP's native ``htmlspecialchars()`` -function, with the advantage of being able to accept an array of strings. + It is useful in preventing Cross Site Scripting (XSS). -It is useful in preventing Cross Site Scripting (XSS). +.. function:: get_mimes() -get_mimes() -=========== + :returns: An associative array of file types + :rtype: array -.. php:function:: get_mimes() + This function returns a *reference* to the MIMEs array from + *application/config/mimes.php*. - :returns: array +.. function:: is_https() -This function returns a *reference* to the MIMEs array from -*application/config/mimes.php*. + :returns: TRUE if currently using HTTP-over-SSL, FALSE if not + :rtype: bool -is_https() -========== + Returns TRUE if a secure (HTTPS) connection is used and FALSE + in any other case (including non-HTTP requests). -.. php:function:: is_https() +.. function:: is_cli() - :returns: bool + :returns: TRUE if currently running under CLI, FALSE otherwise + :rtype: bool -Returns TRUE if a secure (HTTPS) connection is used and FALSE -in any other case (including non-HTTP requests). + Returns TRUE if the application is run through the command line + and FALSE if not. -function_usable() -================= + .. note:: This function checks both if the ``PHP_SAPI`` value is 'cli' + or if the ``STDIN`` constant is defined. -.. php:function:: function_usable($function_name) +.. function:: function_usable($function_name) :param string $function_name: Function name - :returns: bool + :returns: TRUE if the function can be used, FALSE if not + :rtype: bool + + Returns TRUE if a function exists and is usable, FALSE otherwise. -Returns TRUE if a function exists and is usable, FALSE otherwise. + This function runs a ``function_exists()`` check and if the + `Suhosin extension <http://www.hardened-php.net/suhosin/>` is loaded, + checks if it doesn't disable the function being checked. -This function runs a ``function_exists()`` check and if the -`Suhosin extension <http://www.hardened-php.net/suhosin/>` is loaded, -checks if it doesn't disable the function being checked. + It is useful if you want to check for the availability of functions + such as ``eval()`` and ``exec()``, which are dangerous and might be + disabled on servers with highly restrictive security policies. -It is useful if you want to check for the availability of functions -such as ``eval()`` and ``exec()``, which are dangerous and might be -disabled on servers with highly restrictive security policies.
\ No newline at end of file + .. note:: This function was introduced because Suhosin terminated + script execution, but this turned out to be a bug. A fix + has been available for some time (version 0.9.34), but is + unfortunately not released yet.
\ No newline at end of file diff --git a/user_guide_src/source/general/controllers.rst b/user_guide_src/source/general/controllers.rst index d8ef824fb..bc8319dd8 100644 --- a/user_guide_src/source/general/controllers.rst +++ b/user_guide_src/source/general/controllers.rst @@ -107,7 +107,7 @@ You should see your new message. Passing URI Segments to your methods ==================================== -If your URI contains more then two segments they will be passed to your +If your URI contains more than two segments they will be passed to your method as parameters. For example, let's say you have a URI like this:: diff --git a/user_guide_src/source/general/creating_libraries.rst b/user_guide_src/source/general/creating_libraries.rst index 4beb600da..a1e1b3e78 100644 --- a/user_guide_src/source/general/creating_libraries.rst +++ b/user_guide_src/source/general/creating_libraries.rst @@ -44,7 +44,8 @@ The Class File Classes should have this basic prototype:: - <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); + <?php + defined('BASEPATH') OR exit('No direct script access allowed'); class Someclass { diff --git a/user_guide_src/source/general/errors.rst b/user_guide_src/source/general/errors.rst index f12d992f8..26c26bea1 100644 --- a/user_guide_src/source/general/errors.rst +++ b/user_guide_src/source/general/errors.rst @@ -21,23 +21,20 @@ without having to worry about class/function scoping. CodeIgniter also returns a status code whenever a portion of the core calls ``exit()``. This exit status code is separate from the HTTP status code, and serves as a notice to other processes that may be watching of -whether the script completed successfully, or if not, what kind of -problem it encountered that caused it to abort. These values are +whether the script completed successfully, or if not, what kind of +problem it encountered that caused it to abort. These values are defined in *application/config/constants.php*. While exit status codes are most useful in CLI settings, returning the proper code helps server software keep track of your scripts and the health of your application. The following functions let you generate errors: -show_error() -============ - -.. php:function:: show_error($message, $status_code, $heading = 'An Error Was Encountered') +.. function:: show_error($message, $status_code, $heading = 'An Error Was Encountered') :param mixed $message: Error message :param int $status_code: HTTP Response status code :param string $heading: Error page heading - :returns: void + :rtype: void This function will display the error message supplied to it using the following error template:: @@ -49,17 +46,14 @@ code should be sent with the error. If ``$status_code`` is less than 100, the HTTP status code will be set to 500, and the exit status code will be set to ``$status_code + EXIT__AUTO_MIN``. If that value is larger than ``EXIT__AUTO_MAX``, or if ``$status_code`` is 100 or higher, the exit -status code will be set to ``EXIT_ERROR``. You can check in +status code will be set to ``EXIT_ERROR``. You can check in *application/config/constants.php* for more detail. -show_404() -========== - -.. php:function:: show_404($page = '', $log_error = TRUE) +.. function:: show_404($page = '', $log_error = TRUE) :param string $page: URI string :param bool $log_error: Whether to log the error - :returns: void + :rtype: void This function will display the 404 error message supplied to it using the following error template:: @@ -74,15 +68,12 @@ not found. CodeIgniter automatically logs any ``show_404()`` calls. Setting the optional second parameter to FALSE will skip logging. -log_message() -============= - -.. php:function:: log_message($level, $message, $php_error = FALSE) +.. function:: log_message($level, $message, $php_error = FALSE) :param string $level: Log level: 'error', 'debug' or 'info' :param string $message: Message to log :param bool $php_error: Whether we're logging a native PHP error message - :returns: void + :rtype: void This function lets you write messages to your log files. You must supply one of three "levels" in the first parameter, indicating what type of diff --git a/user_guide_src/source/general/hooks.rst b/user_guide_src/source/general/hooks.rst index fc5da5b80..1046c48ae 100644 --- a/user_guide_src/source/general/hooks.rst +++ b/user_guide_src/source/general/hooks.rst @@ -59,7 +59,7 @@ defined in your associative hook array: Multiple Calls to the Same Hook =============================== -If want to use the same hook point with more then one script, simply +If want to use the same hook point with more than one script, simply make your array declaration multi-dimensional, like this:: $hook['pre_controller'][] = array( diff --git a/user_guide_src/source/general/profiling.rst b/user_guide_src/source/general/profiling.rst index 6dbd0be16..f29af8102 100644 --- a/user_guide_src/source/general/profiling.rst +++ b/user_guide_src/source/general/profiling.rst @@ -80,4 +80,8 @@ Key Description **session_data** Data stored in the current session TRUE **query_toggle_count** The number of queries after which the query block will default to 25 hidden. -======================= =================================================================== ========
\ No newline at end of file +======================= =================================================================== ======== + +.. note:: Disabling the **save_queries** setting in your database configuration + will also effectively disable profiling for database queries and render + the 'queries' setting above useless.
\ No newline at end of file diff --git a/user_guide_src/source/general/requirements.rst b/user_guide_src/source/general/requirements.rst index 104923625..0b67e8e3a 100644 --- a/user_guide_src/source/general/requirements.rst +++ b/user_guide_src/source/general/requirements.rst @@ -2,14 +2,15 @@ Server Requirements ################### -- `PHP <http://www.php.net/>`_ version 5.2.4 or newer. -- A Database is required for most web application programming. - Currently supported databases are: - - MySQL (5.1+) via the *mysql* (deprecated), *mysqli* and *pdo* drivers - - Oracle via the *oci8* and *pdo* drivers - - PostgreSQL via the *postgre* and *pdo* drivers - - MS SQL via the *mssql*, *sqlsrv* (version 2005 and above only) and *pdo* drivers - - SQLite via the *sqlite* (version 2), *sqlite3* (version 3) and *pdo* drivers - - CUBRID via the *cubrid* and *pdo* drivers - - Interbase/Firebird via the *ibase* and *pdo* drivers - - ODBC via the *odbc* and *pdo* drivers (you should know that ODBC is actually an abstraction layer)
\ No newline at end of file +- `PHP <http://www.php.net/>`_ version 5.2.4 or newer. +- A Database is required for most web application programming. + + Currently supported databases are: + - MySQL (5.1+) via the *mysql* (deprecated), *mysqli* and *pdo* drivers + - Oracle via the *oci8* and *pdo* drivers + - PostgreSQL via the *postgre* and *pdo* drivers + - MS SQL via the *mssql*, *sqlsrv* (version 2005 and above only) and *pdo* drivers + - SQLite via the *sqlite* (version 2), *sqlite3* (version 3) and *pdo* drivers + - CUBRID via the *cubrid* and *pdo* drivers + - Interbase/Firebird via the *ibase* and *pdo* drivers + - ODBC via the *odbc* and *pdo* drivers (you should know that ODBC is actually an abstraction layer)
\ No newline at end of file diff --git a/user_guide_src/source/general/reserved_names.rst b/user_guide_src/source/general/reserved_names.rst index ccc17d61b..81a05ace6 100644 --- a/user_guide_src/source/general/reserved_names.rst +++ b/user_guide_src/source/general/reserved_names.rst @@ -25,22 +25,22 @@ your controller any of these: Functions --------- -- :php:func:`is_php()` -- :php:func:`is_really_writable()` +- :func:`is_php()` +- :func:`is_really_writable()` - ``load_class()`` - ``is_loaded()`` - ``get_config()`` -- :php:func:`config_item()` -- :php:func:`show_error()` -- :php:func:`show_404()` -- :php:func:`log_message()` -- :php:func:`set_status_header()` -- :php:func:`get_mimes()` -- :php:func:`html_escape()` -- :php:func:`remove_invisible_characters()` -- :php:func:`is_https()` -- :php:func:`function_usable()` -- :php:func:`get_instance()` +- :func:`config_item()` +- :func:`show_error()` +- :func:`show_404()` +- :func:`log_message()` +- :func:`set_status_header()` +- :func:`get_mimes()` +- :func:`html_escape()` +- :func:`remove_invisible_characters()` +- :func:`is_https()` +- :func:`function_usable()` +- :func:`get_instance()` - ``_exception_handler()`` - ``_stringify_attributes()`` @@ -61,6 +61,9 @@ Constants - APPPATH - VIEWPATH - CI_VERSION +- MB_ENABLED +- ICONV_ENABLED +- UTF8_ENABLED - FILE_READ_MODE - FILE_WRITE_MODE - DIR_READ_MODE diff --git a/user_guide_src/source/general/routing.rst b/user_guide_src/source/general/routing.rst index 5520f59fe..0b91d3fa9 100644 --- a/user_guide_src/source/general/routing.rst +++ b/user_guide_src/source/general/routing.rst @@ -142,6 +142,29 @@ routing rules to process the back-references. Example:: return 'catalog/product_edit/' . strtolower($product_type) . '/' . $id; }; +Using HTTP verbs in routes +========================== + +It is possible to use HTTP verbs (request method) to define your routing rules. +This is particularly useful when building RESTful applications. You can use standard HTTP +verbs (GET, PUT, POST, DELETE, PATCH) or a custom one such (e.g. PURGE). HTTP verb rules +are case-insensitive. All you need to do is to add the verb as an array key to your route. +Example:: + + $route['products']['put'] = 'product/insert'; + +In the above example, a PUT request to URI "products" would call the ``Product::insert()`` +controller method. + +:: + + $route['products/(:num)']['DELETE'] = 'product/delete/$1'; + +A DELETE request to URL with "products" as first the segment and a number in the second will be +mapped to the ``Product::delete()`` method, passing the numeric value as the first parameter. + +Using HTTP verbs is of course, optional. + Reserved Routes =============== diff --git a/user_guide_src/source/general/styleguide.rst b/user_guide_src/source/general/styleguide.rst index 5613eabec..6718bc342 100644 --- a/user_guide_src/source/general/styleguide.rst +++ b/user_guide_src/source/general/styleguide.rst @@ -565,7 +565,7 @@ the ability to change this in the php.ini, you can often enable it with:: ini_set('display_errors', 1); .. note:: Setting the `display_errors - <http://php.net/manual/en/ref.errorfunc.php#ini.display-errors>`_ + <http://php.net/manual/en/errorfunc.configuration.php#ini.display-errors>`_ setting with ``ini_set()`` at runtime is not identical to having it enabled in the PHP environment. Namely, it will not have any effect if the script has fatal errors. diff --git a/user_guide_src/source/helpers/array_helper.rst b/user_guide_src/source/helpers/array_helper.rst index 9435b3ac7..4805f581a 100644 --- a/user_guide_src/source/helpers/array_helper.rst +++ b/user_guide_src/source/helpers/array_helper.rst @@ -5,7 +5,12 @@ Array Helper The Array Helper file contains functions that assist in working with arrays. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== @@ -14,114 +19,115 @@ This helper is loaded using the following code:: $this->load->helper('array'); + +Available Functions +=================== + The following functions are available: -element() -========= -.. php:function:: element($item, $array, $default = NULL) +.. function:: element($item, $array[, $default = NULL]) :param string $item: Item to fetch from the array :param array $array: Input array :param bool $default: What to return if the array isn't valid :returns: NULL on failure or the array item. + :rtype: mixed -Lets you fetch an item from an array. The function tests whether the -array index is set and whether it has a value. If a value exists it is -returned. If a value does not exist it returns NULL, or whatever you've -specified as the default value via the third parameter. + Lets you fetch an item from an array. The function tests whether the + array index is set and whether it has a value. If a value exists it is + returned. If a value does not exist it returns NULL, or whatever you've + specified as the default value via the third parameter. -Example:: + Example:: - $array = array( - 'color' => 'red', - 'shape' => 'round', - 'size' => '' - ); + $array = array( + 'color' => 'red', + 'shape' => 'round', + 'size' => '' + ); - echo element('color', $array); // returns "red" - echo element('size', $array, 'foobar'); // returns "foobar" + echo element('color', $array); // returns "red" + echo element('size', $array, 'foobar'); // returns "foobar" -elements() -========== -.. php:function:: elements($items, $array, $default = NULL) +.. function:: elements($items, $array[, $default = NULL]) :param string $item: Item to fetch from the array :param array $array: Input array :param bool $default: What to return if the array isn't valid :returns: NULL on failure or the array item. + :rtype: mixed -Lets you fetch a number of items from an array. The function tests -whether each of the array indices is set. If an index does not exist it -is set to NULL, or whatever you've specified as the default value via -the third parameter. + Lets you fetch a number of items from an array. The function tests + whether each of the array indices is set. If an index does not exist it + is set to NULL, or whatever you've specified as the default value via + the third parameter. -Example:: + Example:: - $array = array( - 'color' => 'red', - 'shape' => 'round', - 'radius' => '10', - 'diameter' => '20' - ); + $array = array( + 'color' => 'red', + 'shape' => 'round', + 'radius' => '10', + 'diameter' => '20' + ); - $my_shape = elements(array('color', 'shape', 'height'), $array); + $my_shape = elements(array('color', 'shape', 'height'), $array); -The above will return the following array:: + The above will return the following array:: - array( - 'color' => 'red', - 'shape' => 'round', - 'height' => NULL - ); + array( + 'color' => 'red', + 'shape' => 'round', + 'height' => NULL + ); -You can set the third parameter to any default value you like. -:: + You can set the third parameter to any default value you like. + :: - $my_shape = elements(array('color', 'shape', 'height'), $array, 'foobar'); + $my_shape = elements(array('color', 'shape', 'height'), $array, 'foobar'); -The above will return the following array:: + The above will return the following array:: - array( Â Â Â Â - 'color' => 'red', - 'shape' => 'round', - 'height' => 'foobar' - ); + array( Â Â Â Â + 'color' => 'red', + 'shape' => 'round', + 'height' => 'foobar' + ); -This is useful when sending the ``$_POST`` array to one of your Models. -This prevents users from sending additional POST data to be entered into -your tables. + This is useful when sending the ``$_POST`` array to one of your Models. + This prevents users from sending additional POST data to be entered into + your tables. -:: + :: - $this->load->model('post_model'); - $this->post_model->update( - elements(array('id', 'title', 'content'), $_POST) - ); + $this->load->model('post_model'); + $this->post_model->update( + elements(array('id', 'title', 'content'), $_POST) + ); -This ensures that only the id, title and content fields are sent to be -updated. + This ensures that only the id, title and content fields are sent to be + updated. -random_element() -================ -.. php:function:: random_element($array) +.. function:: random_element($array) :param array $array: Input array - :returns: string (a random element from the array) + :returns: A random element from the array + :rtype: mixed -Takes an array as input and returns a random element from it. + Takes an array as input and returns a random element from it. -Usage example:: + Usage example:: - $quotes = array( - "I find that the harder I work, the more luck I seem to have. - Thomas Jefferson", - "Don't stay in bed, unless you can make money in bed. - George Burns", - "We didn't lose the game; we just ran out of time. - Vince Lombardi", - "If everything seems under control, you're not going fast enough. - Mario Andretti", - "Reality is merely an illusion, albeit a very persistent one. - Albert Einstein", - "Chance favors the prepared mind - Louis Pasteur" - ); + $quotes = array( + "I find that the harder I work, the more luck I seem to have. - Thomas Jefferson", + "Don't stay in bed, unless you can make money in bed. - George Burns", + "We didn't lose the game; we just ran out of time. - Vince Lombardi", + "If everything seems under control, you're not going fast enough. - Mario Andretti", + "Reality is merely an illusion, albeit a very persistent one. - Albert Einstein", + "Chance favors the prepared mind - Louis Pasteur" + ); - echo random_element($quotes);
\ No newline at end of file + echo random_element($quotes);
\ No newline at end of file diff --git a/user_guide_src/source/helpers/captcha_helper.rst b/user_guide_src/source/helpers/captcha_helper.rst index 3c56addf3..d83490b8e 100644 --- a/user_guide_src/source/helpers/captcha_helper.rst +++ b/user_guide_src/source/helpers/captcha_helper.rst @@ -5,55 +5,24 @@ CAPTCHA Helper The CAPTCHA Helper file contains functions that assist in creating CAPTCHA images. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== -This helper is loaded using the following code -:: +This helper is loaded using the following code:: $this->load->helper('captcha'); -The following functions are available: - -create_captcha() -================ - -.. php:function:: function create_captcha($data = '', $img_path = '', $img_url = '', $font_path = '') - - :param array $data: Array of data for the CAPTCHA - :param string $img_path: Path to create the image in - :param string $img_url: URL to the CAPTCHA image folder - :param string $font_path: Server path to font - :returns: array('word' => $word, 'time' => $now, 'image' => $img) - -Takes an array of information to generate the CAPTCHA as input and -creates the image to your specifications, returning an array of -associative data about the image. - -:: - - array( - 'image' => IMAGE TAG - 'time' => TIMESTAMP (in microtime) - 'word' => CAPTCHA WORD - ) - -The **image** is the actual image tag:: - - <img src="http://example.com/captcha/12345.jpg" width="140" height="50" /> - -The **time** is the micro timestamp used as the image name without the -file extension. It will be a number like this: 1139612155.3422 - -The **word** is the word that appears in the captcha image, which if not -supplied to the function, will be a random string. - Using the CAPTCHA helper ------------------------- +======================== -Once loaded you can generate a captcha like this:: +Once loaded you can generate a CAPTCHA like this:: $vals = array( 'word' => 'Random word', @@ -132,7 +101,7 @@ CAPTCHA will be shown you'll have something like this:: $this->db->query($query); echo 'Submit the word you see below:'; - echo $cap['image']; + echo $cap['image']; echo '<input type="text" name="captcha" value="" />'; Then, on the page that accepts the submission you'll have something like @@ -152,4 +121,40 @@ this:: if ($row->count == 0) { Â Â Â Â echo 'You must submit the word that appears in the image.'; - }
\ No newline at end of file + } + +Available Functions +=================== + +The following functions are available: + +.. function:: create_captcha([$data = ''[, $img_path = ''[, $img_url = ''[, $font_path = '']]]]) + + :param array $data: Array of data for the CAPTCHA + :param string $img_path: Path to create the image in + :param string $img_url: URL to the CAPTCHA image folder + :param string $font_path: Server path to font + :returns: array('word' => $word, 'time' => $now, 'image' => $img) + :rtype: array + + Takes an array of information to generate the CAPTCHA as input and + creates the image to your specifications, returning an array of + associative data about the image. + + :: + + array( + 'image' => IMAGE TAG + 'time' => TIMESTAMP (in microtime) + 'word' => CAPTCHA WORD + ) + + The **image** is the actual image tag:: + + <img src="http://example.com/captcha/12345.jpg" width="140" height="50" /> + + The **time** is the micro timestamp used as the image name without the + file extension. It will be a number like this: 1139612155.3422 + + The **word** is the word that appears in the captcha image, which if not + supplied to the function, will be a random string.
\ No newline at end of file diff --git a/user_guide_src/source/helpers/cookie_helper.rst b/user_guide_src/source/helpers/cookie_helper.rst index c41193c3c..22fd0f77f 100644 --- a/user_guide_src/source/helpers/cookie_helper.rst +++ b/user_guide_src/source/helpers/cookie_helper.rst @@ -5,7 +5,12 @@ Cookie Helper The Cookie Helper file contains functions that assist in working with cookies. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== @@ -14,14 +19,15 @@ This helper is loaded using the following code:: $this->load->helper('cookie'); +Available Functions +=================== + The following functions are available: -set_cookie() -============ -.. php:function:: set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE) +.. function:: set_cookie($name[, $value = ''[, $expire = ''[, $domain = ''[, $path = '/'[, $prefix = ''[, $secure = FALSE[, $httponly = FALSE]]]]]]]]) - :param string $name: Cookie name + :param mixed $name: Cookie name *or* associative array of all of the parameters available to this function :param string $value: Cookie value :param int $expire: Number of seconds until expiration :param string $domain: Cookie domain (usually: .yourdomain.com) @@ -29,49 +35,44 @@ set_cookie() :param string $prefix: Cookie name prefix :param bool $secure: Whether to only send the cookie through HTTPS :param bool $httponly: Whether to hide the cookie from JavaScript - :returns: void + :rtype: void -This helper function gives you view file friendly syntax to set browser -cookies. Refer to the :doc:`Input Library <../libraries/input>` for a -description of its use, as this function is an alias for -``CI_Input::set_cookie()``. + This helper function gives you view file friendly syntax to set browser + cookies. Refer to the :doc:`Input Library <../libraries/input>` for a + description of its use, as this function is an alias for + ``CI_Input::set_cookie()``. -get_cookie() -============ -.. php:function:: get_cookie($index = '', $xss_clean = FALSE) +.. function:: get_cookie($index[, $xss_clean = NULL]]) :param string $index: Cookie name :param bool $xss_clean: Whether to apply XSS filtering to the returned value - :returns: mixed + :returns: The cookie value or NULL if not found + :rtype: mixed -This helper function gives you view file friendly syntax to get browser -cookies. Refer to the :doc:`Input Library <../libraries/input>` for a -description of itsuse, as this function is an alias for ``CI_Input::cookie()``. + This helper function gives you view file friendly syntax to get browser + cookies. Refer to the :doc:`Input Library <../libraries/input>` for a + description of its use, as this function is an alias for ``CI_Input::cookie()``. -delete_cookie() -=============== -.. php:function:: delete_cookie($name = '', $domain = '', $path = '/', $prefix = '') +.. function:: delete_cookie($name[, $domain = ''[, $path = '/'[, $prefix = '']]]]) :param string $name: Cookie name :param string $domain: Cookie domain (usually: .yourdomain.com) :param string $path: Cookie path :param string $prefix: Cookie name prefix - :returns: void - -Lets you delete a cookie. Unless you've set a custom path or other -values, only the name of the cookie is needed. - -:: + :rtype: void - delete_cookie('name'); + Lets you delete a cookie. Unless you've set a custom path or other + values, only the name of the cookie is needed. + :: -This function is otherwise identical to ``set_cookie()``, except that it -does not have the value and expiration parameters. You can submit an -array of values in the first parameter or you can set discrete -parameters. + delete_cookie('name'); -:: + This function is otherwise identical to ``set_cookie()``, except that it + does not have the value and expiration parameters. You can submit an + array of values in the first parameter or you can set discrete + parameters. + :: - delete_cookie($name, $domain, $path, $prefix)
\ No newline at end of file + delete_cookie($name, $domain, $path, $prefix)
\ No newline at end of file diff --git a/user_guide_src/source/helpers/date_helper.rst b/user_guide_src/source/helpers/date_helper.rst index 5dfee8b48..39a9cb325 100644 --- a/user_guide_src/source/helpers/date_helper.rst +++ b/user_guide_src/source/helpers/date_helper.rst @@ -4,7 +4,12 @@ Date Helper The Date Helper file contains functions that help you work with dates. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== @@ -13,396 +18,368 @@ This helper is loaded using the following code:: $this->load->helper('date'); +Available Functions +=================== + The following functions are available: -now() -===== -.. php:function:: now($timezone = NULL) +.. function:: now([$timezone = NULL]) :param string $timezone: Timezone - :returns: int - -Returns the current time as a UNIX timestamp, referenced either to your server's -local time or any PHP suported timezone, based on the "time reference" setting -in your config file. If you do not intend to set your master time reference to -any other PHP supported timezone (which you'll typically do if you run a site -that lets each user set their own timezone settings) there is no benefit to using -this function over PHP's ``time()`` function. - -:: + :returns: UNIX timestamp + :rtype: int - echo now('Australia/Victoria'); + Returns the current time as a UNIX timestamp, referenced either to your server's + local time or any PHP suported timezone, based on the "time reference" setting + in your config file. If you do not intend to set your master time reference to + any other PHP supported timezone (which you'll typically do if you run a site + that lets each user set their own timezone settings) there is no benefit to using + this function over PHP's ``time()`` function. + :: -If a timezone is not provided, it will return ``time()`` based on the -**time_reference** setting. + echo now('Australia/Victoria'); -mdate() -======= + If a timezone is not provided, it will return ``time()`` based on the + **time_reference** setting. -.. php:function:: mdate($datestr = '', $time = '') +.. function:: mdate([$datestr = ''[, $time = '']]) - :param string $datestr: Date string - :param int $time: UNIX timestamp - :returns: int - -This function is identical to PHP's `date() <http://www.php.net/date>`_ -function, except that it lets you use MySQL style date codes, where each -code letter is preceded with a percent sign, e.g. `%Y %m %d` + :param string $datestr: Date string + :param int $time: UNIX timestamp + :returns: MySQL-formatted date + :rtype: string -The benefit of doing dates this way is that you don't have to worry -about escaping any characters that are not date codes, as you would -normally have to do with the ``date()`` function. + This function is identical to PHP's `date() <http://www.php.net/date>`_ + function, except that it lets you use MySQL style date codes, where each + code letter is preceded with a percent sign, e.g. `%Y %m %d` -Example:: + The benefit of doing dates this way is that you don't have to worry + about escaping any characters that are not date codes, as you would + normally have to do with the ``date()`` function. - $datestring = 'Year: %Y Month: %m Day: %d - %h:%i %a'; - $time = time(); - echo mdate($datestring, $time); + Example:: -If a timestamp is not included in the second parameter the current time -will be used. + $datestring = 'Year: %Y Month: %m Day: %d - %h:%i %a'; + $time = time(); + echo mdate($datestring, $time); -standard_date() -=============== + If a timestamp is not included in the second parameter the current time + will be used. -.. php:function:: standard_date($fmt = 'DATE_RFC822', $time = NULL) +.. function:: standard_date([$fmt = 'DATE_RFC822'[, $time = NULL]]) :param string $fmt: Date format - :param int $time: UNIX timestamp - :returns: string - -Lets you generate a date string in one of several standardized formats. + :param int $time: UNIX timestamp + :returns: Formatted date or FALSE on invalid format + :rtype: string -Example:: + Lets you generate a date string in one of several standardized formats. - $format = 'DATE_RFC822'; - $time = time(); - echo standard_date($format, $time); + Example:: -.. note:: This function is DEPRECATED.Use the native ``date()`` combined with - `DateTime's format constants - <http://www.php.net/manual/en/class.datetime.php#datetime.constants.types>`_ - instead: + $format = 'DATE_RFC822'; + $time = time(); + echo standard_date($format, $time); - | - | echo date(DATE_RFC822, time()); + .. note:: This function is DEPRECATED. Use the native ``date()`` combined with + `DateTime's format constants + <http://www.php.net/manual/en/class.datetime.php#datetime.constants.types>`_ + instead:: -Supported formats ------------------ + echo date(DATE_RFC822, time()); -=============== ======================= ====================================== -Constant Description Example -=============== ======================= ====================================== -DATE_ATOM Atom 2005-08-15T16:13:03+0000 -DATE_COOKIE HTTP Cookies Sun, 14 Aug 2005 16:13:03 UTC -DATE_ISO8601 ISO-8601 2005-08-14T16:13:03+00:00 -DATE_RFC822 RFC 822 Sun, 14 Aug 05 16:13:03 UTC -DATE_RFC850 RFC 850 Sunday, 14-Aug-05 16:13:03 UTC -DATE_RFC1036 RFC 1036 Sunday, 14-Aug-05 16:13:03 UTC -DATE_RFC1123 RFC 1123 Sun, 14 Aug 2005 16:13:03 UTC -DATE_RFC2822 RFC 2822 Sun, 14 Aug 2005 16:13:03 +0000 -DATE_RSS RSS Sun, 14 Aug 2005 16:13:03 UTC -DATE_W3C W3C 2005-08-14T16:13:03+0000 -=============== ======================= ====================================== + **Supported formats:** -local_to_gmt() -============== + =============== ======================= ====================================== + Constant Description Example + =============== ======================= ====================================== + DATE_ATOM Atom 2005-08-15T16:13:03+0000 + DATE_COOKIE HTTP Cookies Sun, 14 Aug 2005 16:13:03 UTC + DATE_ISO8601 ISO-8601 2005-08-14T16:13:03+00:00 + DATE_RFC822 RFC 822 Sun, 14 Aug 05 16:13:03 UTC + DATE_RFC850 RFC 850 Sunday, 14-Aug-05 16:13:03 UTC + DATE_RFC1036 RFC 1036 Sunday, 14-Aug-05 16:13:03 UTC + DATE_RFC1123 RFC 1123 Sun, 14 Aug 2005 16:13:03 UTC + DATE_RFC2822 RFC 2822 Sun, 14 Aug 2005 16:13:03 +0000 + DATE_RSS RSS Sun, 14 Aug 2005 16:13:03 UTC + DATE_W3C W3C 2005-08-14T16:13:03+0000 + =============== ======================= ====================================== -.. php:function:: local_to_gmt($time = '') +.. function:: local_to_gmt([$time = '']) :param int $time: UNIX timestamp - :returns: string + :returns: UNIX timestamp + :rtype: int -Takes a UNIX timestamp as input and returns it as GMT. + Takes a UNIX timestamp as input and returns it as GMT. -Example:: + Example:: - $gmt = local_to_gmt(time()); + $gmt = local_to_gmt(time()); -gmt_to_local() -============== +.. function:: gmt_to_local([$time = ''[, $timezone = 'UTC'[, $dst = FALSE]]]) -.. php:function:: gmt_to_local($time = '', $timezone = 'UTC', $dst = FALSE) - - :param int $time: UNIX timestamp + :param int $time: UNIX timestamp :param string $timezone: Timezone - :param bool $dst: Whether DST is active - :returns: int - -Takes a UNIX timestamp (referenced to GMT) as input, and converts it to -a localized timestamp based on the timezone and Daylight Saving Time -submitted. + :param bool $dst: Whether DST is active + :returns: UNIX timestamp + :rtype: int -Example:: + Takes a UNIX timestamp (referenced to GMT) as input, and converts it to + a localized timestamp based on the timezone and Daylight Saving Time + submitted. - $timestamp = 1140153693; - $timezone = 'UM8'; - $daylight_saving = TRUE; - echo gmt_to_local($timestamp, $timezone, $daylight_saving); + Example:: + $timestamp = 1140153693; + $timezone = 'UM8'; + $daylight_saving = TRUE; + echo gmt_to_local($timestamp, $timezone, $daylight_saving); -.. note:: For a list of timezones see the reference at the bottom of this page. -mysql_to_unix() -=============== + .. note:: For a list of timezones see the reference at the bottom of this page. -.. php:function:: mysql_to_unix($time = '') +.. function:: mysql_to_unix([$time = '']) - :param int $time: UNIX timestamp - :returns: int + :param string $time: MySQL timestamp + :returns: UNIX timestamp + :rtype: int -Takes a MySQL Timestamp as input and returns it as a UNIX timestamp. + Takes a MySQL Timestamp as input and returns it as a UNIX timestamp. -Example:: + Example:: - $unix = mysql_to_unix('20061124092345'); + $unix = mysql_to_unix('20061124092345'); -unix_to_human() -=============== - -.. php:function:: unix_to_human($time = '', $seconds = FALSE, $fmt = 'us') +.. function:: unix_to_human([$time = ''[, $seconds = FALSE[, $fmt = 'us']]]) :param int $time: UNIX timestamp :param bool $seconds: Whether to show seconds :param string $fmt: format (us or euro) - :returns: integer - -Takes a UNIX timestamp as input and returns it in a human readable -format with this prototype:: + :returns: Formatted date + :rtype: string - YYYY-MM-DD HH:MM:SS AM/PM + Takes a UNIX timestamp as input and returns it in a human readable + format with this prototype:: -This can be useful if you need to display a date in a form field for -submission. + YYYY-MM-DD HH:MM:SS AM/PM -The time can be formatted with or without seconds, and it can be set to -European or US format. If only the timestamp is submitted it will return -the time without seconds formatted for the U.S. + This can be useful if you need to display a date in a form field for + submission. -Examples:: + The time can be formatted with or without seconds, and it can be set to + European or US format. If only the timestamp is submitted it will return + the time without seconds formatted for the U.S. - $now = time(); - echo unix_to_human($now); // U.S. time, no seconds - echo unix_to_human($now, TRUE, 'us'); // U.S. time with seconds - echo unix_to_human($now, TRUE, 'eu'); // Euro time with seconds + Examples:: -human_to_unix() -=============== + $now = time(); + echo unix_to_human($now); // U.S. time, no seconds + echo unix_to_human($now, TRUE, 'us'); // U.S. time with seconds + echo unix_to_human($now, TRUE, 'eu'); // Euro time with seconds -.. php:function:: human_to_unix($datestr = '') +.. function:: human_to_unix([$datestr = '']) - :param int $datestr: Date string - :returns: int UNIX timestamp or FALSE on failure + :param int $datestr: Date string + :returns: UNIX timestamp or FALSE on failure + :rtype: int -The opposite of the :php:func:`unix_to_time()` function. Takes a "human" -time as input and returns it as a UNIX timestamp. This is useful if you -accept "human" formatted dates submitted via a form. Returns boolean FALSE -date string passed to it is not formatted as indicated above. + The opposite of the :func:`unix_to_time()` function. Takes a "human" + time as input and returns it as a UNIX timestamp. This is useful if you + accept "human" formatted dates submitted via a form. Returns boolean FALSE + date string passed to it is not formatted as indicated above. -Example:: + Example:: - $now = time(); - $human = unix_to_human($now); - $unix = human_to_unix($human); + $now = time(); + $human = unix_to_human($now); + $unix = human_to_unix($human); -nice_date() -=========== - -.. php:function:: nice_date($bad_date = '', $format = FALSE) +.. function:: nice_date([$bad_date = ''[, $format = FALSE]]) :param int $bad_date: The terribly formatted date-like string :param string $format: Date format to return (same as PHP's ``date()`` function) - :returns: string - -This function can take a number poorly-formed date formats and convert -them into something useful. It also accepts well-formed dates. + :returns: Formatted date + :rtype: string -The function will return a UNIX timestamp by default. You can, optionally, -pass a format string (the same type as the PHP ``date()`` function accepts) -as the second parameter. + This function can take a number poorly-formed date formats and convert + them into something useful. It also accepts well-formed dates. -Example:: + The function will return a UNIX timestamp by default. You can, optionally, + pass a format string (the same type as the PHP ``date()`` function accepts) + as the second parameter. - $bad_date = '199605'; - // Should Produce: 1996-05-01 - $better_date = nice_date($bad_date, 'Y-m-d'); + Example:: - $bad_date = '9-11-2001'; - // Should Produce: 2001-09-11 - $better_date = nice_date($bad_date, 'Y-m-d'); + $bad_date = '199605'; + // Should Produce: 1996-05-01 + $better_date = nice_date($bad_date, 'Y-m-d'); -timespan() -========== + $bad_date = '9-11-2001'; + // Should Produce: 2001-09-11 + $better_date = nice_date($bad_date, 'Y-m-d'); -.. php:function:: timespan($seconds = 1, $time = '', $units = '') +.. function:: timespan([$seconds = 1[, $time = ''[, $units = '']]]) :param int $seconds: Number of seconds :param string $time: UNIX timestamp :param int $units: Number of time units to display - :returns: string + :returns: Formatted time difference + :rtype: string -Formats a UNIX timestamp so that is appears similar to this:: + Formats a UNIX timestamp so that is appears similar to this:: - 1 Year, 10 Months, 2 Weeks, 5 Days, 10 Hours, 16 Minutes + 1 Year, 10 Months, 2 Weeks, 5 Days, 10 Hours, 16 Minutes -The first parameter must contain a UNIX timestamp. -The second parameter must contain a timestamp that is greater that the -first timestamp. -The thirdparameter is optional and limits the number of time units to display. + The first parameter must contain a UNIX timestamp. + The second parameter must contain a timestamp that is greater that the + first timestamp. + The thirdparameter is optional and limits the number of time units to display. -If the second parameter empty, the current time will be used. + If the second parameter empty, the current time will be used. -The most common purpose for this function is to show how much time has -elapsed from some point in time in the past to now. + The most common purpose for this function is to show how much time has + elapsed from some point in time in the past to now. -Example:: + Example:: - $post_date = '1079621429'; - $now = time(); - $units = 2; - echo timespan($post_date, $now, $units); + $post_date = '1079621429'; + $now = time(); + $units = 2; + echo timespan($post_date, $now, $units); -.. note:: The text generated by this function is found in the following language - file: `language/<your_lang>/date_lang.php` + .. note:: The text generated by this function is found in the following language + file: `language/<your_lang>/date_lang.php` -days_in_month() -=============== - -.. php:function:: days_in_month($month = 0, $year = '') +.. function:: days_in_month([$month = 0[, $year = '']]) :param int $month: a numeric month :param int $year: a numeric year - :returns: int - -Returns the number of days in a given month/year. Takes leap years into -account. + :returns: Count of days in the specified month + :rtype: int -Example:: + Returns the number of days in a given month/year. Takes leap years into + account. - echo days_in_month(06, 2005); + Example:: -If the second parameter is empty, the current year will be used. + echo days_in_month(06, 2005); -date_range() -============ + If the second parameter is empty, the current year will be used. -.. php:function:: date_range($unix_start = '', $mixed = '', $is_unix = TRUE, $format = 'Y-m-d') +.. function:: date_range([$unix_start = ''[, $mixed = ''[, $is_unix = TRUE[, $format = 'Y-m-d']]]]) :param int $unix_start: UNIX timestamp of the range start date :param int $mixed: UNIX timestamp of the range end date or interval in days :param bool $is_unix: set to FALSE if $mixed is not a timestamp :param string $format: Output date format, same as in ``date()`` - :returns: array - -Returns a list of dates within a specified period. + :returns: An array of dates + :rtype: array -Example:: + Returns a list of dates within a specified period. - $range = date_range('2012-01-01', '2012-01-15'); - echo "First 15 days of 2012:"; - foreach ($range as $date) - { - echo $date."\n"; - } + Example:: -timezones() -=========== + $range = date_range('2012-01-01', '2012-01-15'); + echo "First 15 days of 2012:"; + foreach ($range as $date) + { + echo $date."\n"; + } -.. php:function:: timezones($tz = '') +.. function:: timezones([$tz = '']) - :param string $tz: a numeric timezone - :returns: string + :param string $tz: A numeric timezone + :returns: Hour difference from UTC + :rtype: int -Takes a timezone reference (for a list of valid timezones, see the -"Timezone Reference" below) and returns the number of hours offset from -UTC. + Takes a timezone reference (for a list of valid timezones, see the + "Timezone Reference" below) and returns the number of hours offset from + UTC. -Example:: + Example:: - echo timezones('UM5'); + echo timezones('UM5'); -This function is useful when used with :php:func:`timezone_menu()`. + This function is useful when used with :func:`timezone_menu()`. -timezone_menu() -=============== - -.. php:function:: timezone_menu($default = 'UTC', $class = '', $name = 'timezones', $attributes = '') +.. function:: timezone_menu([$default = 'UTC'[, $class = ''[, $name = 'timezones'[, $attributes = '']]]]) :param string $default: Timezone :param string $class: Class name :param string $name: Menu name :param mixed $attributes: HTML attributes - :returns: string - -Generates a pull-down menu of timezones, like this one: - -.. raw:: html - - <form action="#"> - <select name="timezones"> - <option value='UM12'>(UTC -12:00) Baker/Howland Island</option> - <option value='UM11'>(UTC -11:00) Samoa Time Zone, Niue</option> - <option value='UM10'>(UTC -10:00) Hawaii-Aleutian Standard Time, Cook Islands, Tahiti</option> - <option value='UM95'>(UTC -9:30) Marquesas Islands</option> - <option value='UM9'>(UTC -9:00) Alaska Standard Time, Gambier Islands</option> - <option value='UM8'>(UTC -8:00) Pacific Standard Time, Clipperton Island</option> - <option value='UM7'>(UTC -7:00) Mountain Standard Time</option> - <option value='UM6'>(UTC -6:00) Central Standard Time</option> - <option value='UM5'>(UTC -5:00) Eastern Standard Time, Western Caribbean Standard Time</option> - <option value='UM45'>(UTC -4:30) Venezuelan Standard Time</option> - <option value='UM4'>(UTC -4:00) Atlantic Standard Time, Eastern Caribbean Standard Time</option> - <option value='UM35'>(UTC -3:30) Newfoundland Standard Time</option> - <option value='UM3'>(UTC -3:00) Argentina, Brazil, French Guiana, Uruguay</option> - <option value='UM2'>(UTC -2:00) South Georgia/South Sandwich Islands</option> - <option value='UM1'>(UTC -1:00) Azores, Cape Verde Islands</option> - <option value='UTC' selected='selected'>(UTC) Greenwich Mean Time, Western European Time</option> - <option value='UP1'>(UTC +1:00) Central European Time, West Africa Time</option> - <option value='UP2'>(UTC +2:00) Central Africa Time, Eastern European Time, Kaliningrad Time</option> - <option value='UP3'>(UTC +3:00) Moscow Time, East Africa Time</option> - <option value='UP35'>(UTC +3:30) Iran Standard Time</option> - <option value='UP4'>(UTC +4:00) Azerbaijan Standard Time, Samara Time</option> - <option value='UP45'>(UTC +4:30) Afghanistan</option> - <option value='UP5'>(UTC +5:00) Pakistan Standard Time, Yekaterinburg Time</option> - <option value='UP55'>(UTC +5:30) Indian Standard Time, Sri Lanka Time</option> - <option value='UP575'>(UTC +5:45) Nepal Time</option> - <option value='UP6'>(UTC +6:00) Bangladesh Standard Time, Bhutan Time, Omsk Time</option> - <option value='UP65'>(UTC +6:30) Cocos Islands, Myanmar</option> - <option value='UP7'>(UTC +7:00) Krasnoyarsk Time, Cambodia, Laos, Thailand, Vietnam</option> - <option value='UP8'>(UTC +8:00) Australian Western Standard Time, Beijing Time, Irkutsk Time</option> - <option value='UP875'>(UTC +8:45) Australian Central Western Standard Time</option> - <option value='UP9'>(UTC +9:00) Japan Standard Time, Korea Standard Time, Yakutsk Time</option> - <option value='UP95'>(UTC +9:30) Australian Central Standard Time</option> - <option value='UP10'>(UTC +10:00) Australian Eastern Standard Time, Vladivostok Time</option> - <option value='UP105'>(UTC +10:30) Lord Howe Island</option> - <option value='UP11'>(UTC +11:00) Magadan Time, Solomon Islands, Vanuatu</option> - <option value='UP115'>(UTC +11:30) Norfolk Island</option> - <option value='UP12'>(UTC +12:00) Fiji, Gilbert Islands, Kamchatka Time, New Zealand Standard Time</option> - <option value='UP1275'>(UTC +12:45) Chatham Islands Standard Time</option> - <option value='UP13'>(UTC +13:00) Phoenix Islands Time, Tonga</option> - <option value='UP14'>(UTC +14:00) Line Islands</option> - </select> - </form> - - -This menu is useful if you run a membership site in which your users are -allowed to set their local timezone value. - -The first parameter lets you set the "selected" state of the menu. For -example, to set Pacific time as the default you will do this:: - - echo timezone_menu('UM8'); - -Please see the timezone reference below to see the values of this menu. - -The second parameter lets you set a CSS class name for the menu. - -The fourth parameter lets you set one or more attributes on the generated select tag. - -.. note:: The text contained in the menu is found in the following - language file: `language/<your_lang>/date_lang.php` - + :returns: HTML drop down menu with time zones + :rtype: string + + Generates a pull-down menu of timezones, like this one: + + .. raw:: html + + <form action="#"> + <select name="timezones"> + <option value='UM12'>(UTC -12:00) Baker/Howland Island</option> + <option value='UM11'>(UTC -11:00) Samoa Time Zone, Niue</option> + <option value='UM10'>(UTC -10:00) Hawaii-Aleutian Standard Time, Cook Islands, Tahiti</option> + <option value='UM95'>(UTC -9:30) Marquesas Islands</option> + <option value='UM9'>(UTC -9:00) Alaska Standard Time, Gambier Islands</option> + <option value='UM8'>(UTC -8:00) Pacific Standard Time, Clipperton Island</option> + <option value='UM7'>(UTC -7:00) Mountain Standard Time</option> + <option value='UM6'>(UTC -6:00) Central Standard Time</option> + <option value='UM5'>(UTC -5:00) Eastern Standard Time, Western Caribbean Standard Time</option> + <option value='UM45'>(UTC -4:30) Venezuelan Standard Time</option> + <option value='UM4'>(UTC -4:00) Atlantic Standard Time, Eastern Caribbean Standard Time</option> + <option value='UM35'>(UTC -3:30) Newfoundland Standard Time</option> + <option value='UM3'>(UTC -3:00) Argentina, Brazil, French Guiana, Uruguay</option> + <option value='UM2'>(UTC -2:00) South Georgia/South Sandwich Islands</option> + <option value='UM1'>(UTC -1:00) Azores, Cape Verde Islands</option> + <option value='UTC' selected='selected'>(UTC) Greenwich Mean Time, Western European Time</option> + <option value='UP1'>(UTC +1:00) Central European Time, West Africa Time</option> + <option value='UP2'>(UTC +2:00) Central Africa Time, Eastern European Time, Kaliningrad Time</option> + <option value='UP3'>(UTC +3:00) Moscow Time, East Africa Time</option> + <option value='UP35'>(UTC +3:30) Iran Standard Time</option> + <option value='UP4'>(UTC +4:00) Azerbaijan Standard Time, Samara Time</option> + <option value='UP45'>(UTC +4:30) Afghanistan</option> + <option value='UP5'>(UTC +5:00) Pakistan Standard Time, Yekaterinburg Time</option> + <option value='UP55'>(UTC +5:30) Indian Standard Time, Sri Lanka Time</option> + <option value='UP575'>(UTC +5:45) Nepal Time</option> + <option value='UP6'>(UTC +6:00) Bangladesh Standard Time, Bhutan Time, Omsk Time</option> + <option value='UP65'>(UTC +6:30) Cocos Islands, Myanmar</option> + <option value='UP7'>(UTC +7:00) Krasnoyarsk Time, Cambodia, Laos, Thailand, Vietnam</option> + <option value='UP8'>(UTC +8:00) Australian Western Standard Time, Beijing Time, Irkutsk Time</option> + <option value='UP875'>(UTC +8:45) Australian Central Western Standard Time</option> + <option value='UP9'>(UTC +9:00) Japan Standard Time, Korea Standard Time, Yakutsk Time</option> + <option value='UP95'>(UTC +9:30) Australian Central Standard Time</option> + <option value='UP10'>(UTC +10:00) Australian Eastern Standard Time, Vladivostok Time</option> + <option value='UP105'>(UTC +10:30) Lord Howe Island</option> + <option value='UP11'>(UTC +11:00) Magadan Time, Solomon Islands, Vanuatu</option> + <option value='UP115'>(UTC +11:30) Norfolk Island</option> + <option value='UP12'>(UTC +12:00) Fiji, Gilbert Islands, Kamchatka Time, New Zealand Standard Time</option> + <option value='UP1275'>(UTC +12:45) Chatham Islands Standard Time</option> + <option value='UP13'>(UTC +13:00) Phoenix Islands Time, Tonga</option> + <option value='UP14'>(UTC +14:00) Line Islands</option> + </select> + </form> + + + This menu is useful if you run a membership site in which your users are + allowed to set their local timezone value. + + The first parameter lets you set the "selected" state of the menu. For + example, to set Pacific time as the default you will do this:: + + echo timezone_menu('UM8'); + + Please see the timezone reference below to see the values of this menu. + + The second parameter lets you set a CSS class name for the menu. + + The fourth parameter lets you set one or more attributes on the generated select tag. + + .. note:: The text contained in the menu is found in the following + language file: `language/<your_lang>/date_lang.php` Timezone Reference ================== @@ -411,47 +388,47 @@ The following table indicates each timezone and its location. Note some of the location lists have been abridged for clarity and formatting. -=========== ===================================================================== -Time Zone Location -=========== ===================================================================== -UM12 (UTC - 12:00) Baker/Howland Island -UM11 (UTC - 11:00) Samoa Time Zone, Niue -UM10 (UTC - 10:00) Hawaii-Aleutian Standard Time, Cook Islands -UM95 (UTC - 09:30) Marquesas Islands -UM9 (UTC - 09:00) Alaska Standard Time, Gambier Islands -UM8 (UTC - 08:00) Pacific Standard Time, Clipperton Island -UM7 (UTC - 11:00) Mountain Standard Time -UM6 (UTC - 06:00) Central Standard Time -UM5 (UTC - 05:00) Eastern Standard Time, Western Caribbean -UM45 (UTC - 04:30) Venezuelan Standard Time -UM4 (UTC - 04:00) Atlantic Standard Time, Eastern Caribbean -UM35 (UTC - 03:30) Newfoundland Standard Time -UM3 (UTC - 03:00) Argentina, Brazil, French Guiana, Uruguay -UM2 (UTC - 02:00) South Georgia/South Sandwich Islands -UM1 (UTC -1:00) Azores, Cape Verde Islands -UTC (UTC) Greenwich Mean Time, Western European Time -UP1 (UTC +1:00) Central European Time, West Africa Time -UP2 (UTC +2:00) Central Africa Time, Eastern European Time -UP3 (UTC +3:00) Moscow Time, East Africa Time -UP35 (UTC +3:30) Iran Standard Time -UP4 (UTC +4:00) Azerbaijan Standard Time, Samara Time -UP45 (UTC +4:30) Afghanistan -UP5 (UTC +5:00) Pakistan Standard Time, Yekaterinburg Time -UP55 (UTC +5:30) Indian Standard Time, Sri Lanka Time -UP575 (UTC +5:45) Nepal Time -UP6 (UTC +6:00) Bangladesh Standard Time, Bhutan Time, Omsk Time -UP65 (UTC +6:30) Cocos Islands, Myanmar -UP7 (UTC +7:00) Krasnoyarsk Time, Cambodia, Laos, Thailand, Vietnam -UP8 (UTC +8:00) Australian Western Standard Time, Beijing Time -UP875 (UTC +8:45) Australian Central Western Standard Time -UP9 (UTC +9:00) Japan Standard Time, Korea Standard Time, Yakutsk -UP95 (UTC +9:30) Australian Central Standard Time -UP10 (UTC +10:00) Australian Eastern Standard Time, Vladivostok Time -UP105 (UTC +10:30) Lord Howe Island -UP11 (UTC +11:00) Magadan Time, Solomon Islands, Vanuatu -UP115 (UTC +11:30) Norfolk Island -UP12 (UTC +12:00) Fiji, Gilbert Islands, Kamchatka, New Zealand -UP1275 (UTC +12:45) Chatham Islands Standard Time -UP13 (UTC +13:00) Phoenix Islands Time, Tonga -UP14 (UTC +14:00) Line Islands +=========== ===================================================================== +Time Zone Location +=========== ===================================================================== +UM12 (UTC - 12:00) Baker/Howland Island +UM11 (UTC - 11:00) Samoa Time Zone, Niue +UM10 (UTC - 10:00) Hawaii-Aleutian Standard Time, Cook Islands +UM95 (UTC - 09:30) Marquesas Islands +UM9 (UTC - 09:00) Alaska Standard Time, Gambier Islands +UM8 (UTC - 08:00) Pacific Standard Time, Clipperton Island +UM7 (UTC - 11:00) Mountain Standard Time +UM6 (UTC - 06:00) Central Standard Time +UM5 (UTC - 05:00) Eastern Standard Time, Western Caribbean +UM45 (UTC - 04:30) Venezuelan Standard Time +UM4 (UTC - 04:00) Atlantic Standard Time, Eastern Caribbean +UM35 (UTC - 03:30) Newfoundland Standard Time +UM3 (UTC - 03:00) Argentina, Brazil, French Guiana, Uruguay +UM2 (UTC - 02:00) South Georgia/South Sandwich Islands +UM1 (UTC -1:00) Azores, Cape Verde Islands +UTC (UTC) Greenwich Mean Time, Western European Time +UP1 (UTC +1:00) Central European Time, West Africa Time +UP2 (UTC +2:00) Central Africa Time, Eastern European Time +UP3 (UTC +3:00) Moscow Time, East Africa Time +UP35 (UTC +3:30) Iran Standard Time +UP4 (UTC +4:00) Azerbaijan Standard Time, Samara Time +UP45 (UTC +4:30) Afghanistan +UP5 (UTC +5:00) Pakistan Standard Time, Yekaterinburg Time +UP55 (UTC +5:30) Indian Standard Time, Sri Lanka Time +UP575 (UTC +5:45) Nepal Time +UP6 (UTC +6:00) Bangladesh Standard Time, Bhutan Time, Omsk Time +UP65 (UTC +6:30) Cocos Islands, Myanmar +UP7 (UTC +7:00) Krasnoyarsk Time, Cambodia, Laos, Thailand, Vietnam +UP8 (UTC +8:00) Australian Western Standard Time, Beijing Time +UP875 (UTC +8:45) Australian Central Western Standard Time +UP9 (UTC +9:00) Japan Standard Time, Korea Standard Time, Yakutsk +UP95 (UTC +9:30) Australian Central Standard Time +UP10 (UTC +10:00) Australian Eastern Standard Time, Vladivostok Time +UP105 (UTC +10:30) Lord Howe Island +UP11 (UTC +11:00) Magadan Time, Solomon Islands, Vanuatu +UP115 (UTC +11:30) Norfolk Island +UP12 (UTC +12:00) Fiji, Gilbert Islands, Kamchatka, New Zealand +UP1275 (UTC +12:45) Chatham Islands Standard Time +UP13 (UTC +13:00) Phoenix Islands Time, Tonga +UP14 (UTC +14:00) Line Islands =========== =====================================================================
\ No newline at end of file diff --git a/user_guide_src/source/helpers/directory_helper.rst b/user_guide_src/source/helpers/directory_helper.rst index a785ebc8c..3004316a8 100644 --- a/user_guide_src/source/helpers/directory_helper.rst +++ b/user_guide_src/source/helpers/directory_helper.rst @@ -5,7 +5,12 @@ Directory Helper The Directory Helper file contains functions that assist in working with directories. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== @@ -16,64 +21,63 @@ This helper is loaded using the following code $this->load->helper('directory'); +Available Functions +=================== + The following functions are available: -directory_map() -=============== - -This function reads the directory path specified in the first parameter -and builds an array representation of it and all its contained files. - -.. php:method:: directory_map($source_dir[, $directory_depth = 0[, $hidden = FALSE]]) - - :param string $source_dir: path to the ource directory - :param integer $directory_depth: depth of directories to traverse (0 = - fully recursive, 1 = current dir, etc) - :param boolean $hidden: whether to include hidden directories - -Examples:: - - $map = directory_map('./mydirectory/'); - -.. note:: Paths are almost always relative to your main index.php file. - - -Sub-folders contained within the directory will be mapped as well. If -you wish to control the recursion depth, you can do so using the second -parameter (integer). A depth of 1 will only map the top level directory:: - - $map = directory_map('./mydirectory/', 1); - -By default, hidden files will not be included in the returned array. To -override this behavior, you may set a third parameter to true (boolean):: - - $map = directory_map('./mydirectory/', FALSE, TRUE); - -Each folder name will be an array index, while its contained files will -be numerically indexed. Here is an example of a typical array:: - - Array (    - [libraries] => Array    - (        - [0] => benchmark.html        - [1] => config.html        - ["database/"] => Array - (              - [0] => query_builder.html              - [1] => binds.html              - [2] => configuration.html - [3] => connecting.html              - [4] => examples.html              - [5] => fields.html              - [6] => index.html - [7] => queries.html - )        - [2] => email.html        - [3] => file_uploading.html        - [4] => image_lib.html        - [5] => input.html        - [6] => language.html        - [7] => loader.html        - [8] => pagination.html        - [9] => uri.html - )
\ No newline at end of file + +.. function:: directory_map($source_dir[, $directory_depth = 0[, $hidden = FALSE]]) + + :param string $source_dir: Path to the ource directory + :param int $directory_depth: Depth of directories to traverse (0 = fully recursive, 1 = current dir, etc) + :param bool $hidden: Whether to include hidden directories + :returns: An array of files + :rtype: array + + Examples:: + + $map = directory_map('./mydirectory/'); + + .. note:: Paths are almost always relative to your main index.php file. + + + Sub-folders contained within the directory will be mapped as well. If + you wish to control the recursion depth, you can do so using the second + parameter (integer). A depth of 1 will only map the top level directory:: + + $map = directory_map('./mydirectory/', 1); + + By default, hidden files will not be included in the returned array. To + override this behavior, you may set a third parameter to true (boolean):: + + $map = directory_map('./mydirectory/', FALSE, TRUE); + + Each folder name will be an array index, while its contained files will + be numerically indexed. Here is an example of a typical array:: + + Array (    + [libraries] => Array    + (        + [0] => benchmark.html        + [1] => config.html        + ["database/"] => Array + (              + [0] => query_builder.html              + [1] => binds.html              + [2] => configuration.html + [3] => connecting.html              + [4] => examples.html              + [5] => fields.html              + [6] => index.html + [7] => queries.html + )        + [2] => email.html        + [3] => file_uploading.html        + [4] => image_lib.html        + [5] => input.html        + [6] => language.html        + [7] => loader.html        + [8] => pagination.html        + [9] => uri.html + )
\ No newline at end of file diff --git a/user_guide_src/source/helpers/download_helper.rst b/user_guide_src/source/helpers/download_helper.rst index 860c568b9..f374d491f 100644 --- a/user_guide_src/source/helpers/download_helper.rst +++ b/user_guide_src/source/helpers/download_helper.rst @@ -4,7 +4,12 @@ Download Helper The Download Helper lets you download data to your desktop. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== @@ -13,38 +18,39 @@ This helper is loaded using the following code:: $this->load->helper('download'); +Available Functions +=================== + The following functions are available: -force_download() -================ -.. php:function:: force_download($filename = '', $data = '', $set_mime = FALSE) +.. function:: force_download([$filename = ''[, $data = ''[, $set_mime = FALSE]]]) :param string $filename: Filename :param mixed $data: File contents :param bool $set_mime: Whether to try to send the actual MIME type - :returns: void + :rtype: void -Generates server headers which force data to be downloaded to your -desktop. Useful with file downloads. The first parameter is the **name -you want the downloaded file to be named**, the second parameter is the -file data. + Generates server headers which force data to be downloaded to your + desktop. Useful with file downloads. The first parameter is the **name + you want the downloaded file to be named**, the second parameter is the + file data. -If you set the second parameter to NULL and ``$filename`` is an existing, readable -file path, then its content will be read instead. + If you set the second parameter to NULL and ``$filename`` is an existing, readable + file path, then its content will be read instead. -If you set the third parameter to boolean TRUE, then the actual file MIME type -(based on the filename extension) will be sent, so that if your browser has a -handler for that type - it can use it. + If you set the third parameter to boolean TRUE, then the actual file MIME type + (based on the filename extension) will be sent, so that if your browser has a + handler for that type - it can use it. -Example:: + Example:: - $data = 'Here is some text!'; - $name = 'mytext.txt'; - force_download($name, $data); + $data = 'Here is some text!'; + $name = 'mytext.txt'; + force_download($name, $data); -If you want to download an existing file from your server you'll need to -do the following:: + If you want to download an existing file from your server you'll need to + do the following:: - // Contents of photo.jpg will be automatically read - force_download('/path/to/photo.jpg', NULL);
\ No newline at end of file + // Contents of photo.jpg will be automatically read + force_download('/path/to/photo.jpg', NULL);
\ No newline at end of file diff --git a/user_guide_src/source/helpers/email_helper.rst b/user_guide_src/source/helpers/email_helper.rst index 10adf1d0e..b665ce548 100644 --- a/user_guide_src/source/helpers/email_helper.rst +++ b/user_guide_src/source/helpers/email_helper.rst @@ -6,9 +6,14 @@ The Email Helper provides some assistive functions for working with Email. For a more robust email solution, see CodeIgniter's :doc:`Email Class <../libraries/email>`. -.. contents:: Page Contents +.. important:: The Email helper is **deprecated**. -.. important:: The Email helper is DEPRECATED. +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== @@ -17,51 +22,53 @@ This helper is loaded using the following code:: $this->load->helper('email'); +Available Functions +=================== + The following functions are available: -valid_email() -============= -.. php:function:: valid_email($email) +.. function:: valid_email($email) - :param string $email: Email address - :returns: bool + :param string $email: E-mail address + :returns: TRUE if a valid email is supplied, FALSE otherwise + :rtype: bool -Checks if the input is a correctly formatted e-mail address. Note that is -doesn't actually prove that the address will be able recieve mail, but -simply that it is a validly formed address. + Checks if the input is a correctly formatted e-mail address. Note that is + doesn't actually prove that the address will be able recieve mail, but + simply that it is a validly formed address. -Example:: + Example:: - if (valid_email('email@somesite.com')) - { - echo 'email is valid'; - } - else - { - echo 'email is not valid'; - } + if (valid_email('email@somesite.com')) + { + echo 'email is valid'; + } + else + { + echo 'email is not valid'; + } -.. note:: All that this function does is to use PHP's native ``filter_var()``: - | - | (bool) filter_var($email, FILTER_VALIDATE_EMAIL); + .. note:: All that this function does is to use PHP's native ``filter_var()``:: -send_email() -============ + (bool) filter_var($email, FILTER_VALIDATE_EMAIL); -.. php:function:: send_email($recipient, $subject, $message) +.. function:: send_email($recipient, $subject, $message) :param string $recipient: E-mail address :param string $subject: Mail subject :param string $message: Message body - :returns: bool + :returns: TRUE if the mail was successfully sent, FALSE in case of an error + :rtype: bool + + Sends an email using PHP's native `mail() <http://www.php.net/function.mail>`_ + function. + + .. note:: All that this function does is to use PHP's native ``mail`` -Sends an email using PHP's native `mail() <http://www.php.net/function.mail>`_ -function. + :: -.. note:: All that this function does is to use PHP's native ``mail``: - | - | mail($recipient, $subject, $message); + mail($recipient, $subject, $message); -For a more robust email solution, see CodeIgniter's :doc:`Email Library -<../libraries/email>`. + For a more robust email solution, see CodeIgniter's :doc:`Email Library + <../libraries/email>`.
\ No newline at end of file diff --git a/user_guide_src/source/helpers/file_helper.rst b/user_guide_src/source/helpers/file_helper.rst index 194d4348f..59cabcce2 100644 --- a/user_guide_src/source/helpers/file_helper.rst +++ b/user_guide_src/source/helpers/file_helper.rst @@ -4,7 +4,12 @@ File Helper The File Helper file contains functions that assist in working with files. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== @@ -13,204 +18,185 @@ This helper is loaded using the following code:: $this->load->helper('file'); +Available Functions +=================== + The following functions are available: -read_file() -=========== -.. php:function:: read_file($file) +.. function:: read_file($file) :param string $file: File path - :returns: string or FALSE on failure + :returns: File contents or FALSE on failure + :rtype: string -Returns the data contained in the file specified in the path. + Returns the data contained in the file specified in the path. -Example:: + Example:: - $string = read_file('./path/to/file.php'); + $string = read_file('./path/to/file.php'); -The path can be a relative or full server path. Returns FALSE (boolean) on failure. + The path can be a relative or full server path. Returns FALSE (boolean) on failure. -.. note:: The path is relative to your main site index.php file, NOT your - controller or view files. CodeIgniter uses a front controller so paths - are always relative to the main site index. + .. note:: The path is relative to your main site index.php file, NOT your + controller or view files. CodeIgniter uses a front controller so paths + are always relative to the main site index. -.. note:: This function is DEPRECATED. Use the native ``file_get_contents()`` - instead. + .. note:: This function is DEPRECATED. Use the native ``file_get_contents()`` + instead. -.. important:: If your server is running an **open_basedir** restriction this - function might not work if you are trying to access a file above the - calling script. + .. important:: If your server is running an **open_basedir** restriction this + function might not work if you are trying to access a file above the + calling script. -write_file() -============ - -.. php:function:: write_file($path, $data, $mode = 'wb') +.. function:: write_file($path, $data[, $mode = 'wb']) :param string $path: File path :param string $data: Data to write to file :param string $mode: ``fopen()`` mode - :returns: bool - -Writes data to the file specified in the path. If the file does not exist then the -function will create it. + :returns: TRUE if the write was successful, FALSE in case of an error + :rtype: bool -Example:: + Writes data to the file specified in the path. If the file does not exist then the + function will create it. - $data = 'Some file data'; - if ( ! write_file('./path/to/file.php', $data)) - { Â Â Â Â - echo 'Unable to write the file'; - } - else - { Â Â Â Â - echo 'File written!'; - } + Example:: -You can optionally set the write mode via the third parameter:: + $data = 'Some file data'; + if ( ! write_file('./path/to/file.php', $data)) + { Â Â Â Â + echo 'Unable to write the file'; + } + else + { Â Â Â Â + echo 'File written!'; + } - write_file('./path/to/file.php', $data, 'r+'); + You can optionally set the write mode via the third parameter:: -The default mode is 'wb'. Please see the `PHP user guide <http://php.net/fopen>`_ -for mode options. + write_file('./path/to/file.php', $data, 'r+'); -.. note: In order for this function to write data to a file, its permissions must - be set such that it is writable (666, 777, etc.). If the file does not - already exist, the directory containing it must be writable. + The default mode is 'wb'. Please see the `PHP user guide <http://php.net/fopen>`_ + for mode options. -.. note:: The path is relative to your main site index.php file, NOT your - controller or view files. CodeIgniter uses a front controller so paths - are always relative to the main site index. + .. note: In order for this function to write data to a file, its permissions must + be set such that it is writable (666, 777, etc.). If the file does not + already exist, the directory containing it must be writable. -.. note:: This function acquires an exclusive lock on the file while writing to it. + .. note:: The path is relative to your main site index.php file, NOT your + controller or view files. CodeIgniter uses a front controller so paths + are always relative to the main site index. -delete_files() -============== + .. note:: This function acquires an exclusive lock on the file while writing to it. -.. php:function:: delete_files($path, $del_dir = FALSE, $htdocs = FALSE) +.. function:: delete_files($path[, $del_dir = FALSE[, $htdocs = FALSE]]) :param string $path: Directory path :param bool $del_dir: Whether to also delete directories :param bool $htdocs: Whether to skip deleting .htaccess and index page files - :returns: bool + :returns: TRUE on success, FALSE in case of an error + :rtype: bool -Deletes ALL files contained in the supplied path. + Deletes ALL files contained in the supplied path. -Example:: + Example:: - delete_files('./path/to/directory/'); + delete_files('./path/to/directory/'); -If the second parameter is set to TRUE, any directories contained within the supplied -root path will be deleted as well. + If the second parameter is set to TRUE, any directories contained within the supplied + root path will be deleted as well. -Example:: + Example:: - delete_files('./path/to/directory/', TRUE); + delete_files('./path/to/directory/', TRUE); -.. note:: The files must be writable or owned by the system in order to be deleted. + .. note:: The files must be writable or owned by the system in order to be deleted. -get_filenames() -=============== - -.. php:function:: get_filenames($source_dir, $include_path = FALSE) +.. function:: get_filenames($source_dir[, $include_path = FALSE]) :param string $source_dir: Directory path :param bool $include_path: Whether to include the path as part of the filenames - :returns: array + :returns: An array of file names + :rtype: array -Takes a server path as input and returns an array containing the names of all files -contained within it. The file path can optionally be added to the file names by setting -the second parameter to TRUE. + Takes a server path as input and returns an array containing the names of all files + contained within it. The file path can optionally be added to the file names by setting + the second parameter to TRUE. -Example:: + Example:: - $controllers = get_filenames(APPPATH.'controllers/'); + $controllers = get_filenames(APPPATH.'controllers/'); -get_dir_file_info() -=================== - -.. php:function:: get_dir_file_info($source_dir, $top_level_only) +.. function:: get_dir_file_info($source_dir, $top_level_only) :param string $source_dir: Directory path - :param bool $top_level_only: Whether to look only at the specified directory - (excluding sub-directories) - :returns: array - -Reads the specified directory and builds an array containing the filenames, filesize, -dates, and permissions. Sub-folders contained within the specified path are only read -if forced by sending the second parameter to FALSE, as this can be an intensive -operation. + :param bool $top_level_only: Whether to look only at the specified directory (excluding sub-directories) + :returns: An array containing info on the supplied directory's contents + :rtype: array -Example:: + Reads the specified directory and builds an array containing the filenames, filesize, + dates, and permissions. Sub-folders contained within the specified path are only read + if forced by sending the second parameter to FALSE, as this can be an intensive + operation. - $models_info = get_dir_file_info(APPPATH.'models/'); + Example:: -get_file_info() -=============== + $models_info = get_dir_file_info(APPPATH.'models/'); -.. php:function: get_file_info($file, $returned_values = array('name', 'server_path', 'size', 'date')) +.. function:: get_file_info($file[, $returned_values = array('name', 'server_path', 'size', 'date')]) :param string $file: File path :param array $returned_values: What type of info to return - :returns: array or FALSE on failure - -Given a file and path, returns (optionally) the *name*, *path*, *size* and *date modified* -information attributes for a file. Second parameter allows you to explicitly declare what -information you want returned. - -Valid ``$returned_values`` options are: `name`, `size`, `date`, `readable`, `writeable`, -`executable` and `fileperms`. + :returns: An array containing info on the specified file or FALSE on failure + :rtype: array -.. note:: The *writable* attribute is checked via PHP's ``is_writeable()`` function, which - known to have issues on the IIS webserver. Consider using *fileperms* instead, - which returns information from PHP's ``fileperms()`` function. + Given a file and path, returns (optionally) the *name*, *path*, *size* and *date modified* + information attributes for a file. Second parameter allows you to explicitly declare what + information you want returned. -get_mime_by_extension() -======================= + Valid ``$returned_values`` options are: `name`, `size`, `date`, `readable`, `writeable`, + `executable` and `fileperms`. -.. php:function:: get_mime_by_extension($filename) +.. function:: get_mime_by_extension($filename) :param string $filename: File name - :returns: string or FALSE on failure + :returns: MIME type string or FALSE on failure + :rtype: string -Translates a filename extension into a MIME type based on *config/mimes.php*. -Returns FALSE if it can't determine the type, or read the MIME config file. + Translates a filename extension into a MIME type based on *config/mimes.php*. + Returns FALSE if it can't determine the type, or read the MIME config file. -:: + :: - $file = 'somefile.png'; - echo $file.' is has a mime type of '.get_mime_by_extension($file); + $file = 'somefile.png'; + echo $file.' is has a mime type of '.get_mime_by_extension($file); -.. note:: This is not an accurate way of determining file MIME types, and - is here strictly for convenience. It should not be used for security - purposes. + .. note:: This is not an accurate way of determining file MIME types, and + is here strictly for convenience. It should not be used for security + purposes. -symbolic_permissions() -====================== - -.. php:function:: symbolic_permissions($perms) +.. function:: symbolic_permissions($perms) :param int $perms: Permissions - :returns: string - -Takes numeric permissions (such as is returned by ``fileperms()``) and returns -standard symbolic notation of file permissions. + :returns: Symbolic permissions string + :rtype: string -:: + Takes numeric permissions (such as is returned by ``fileperms()``) and returns + standard symbolic notation of file permissions. - echo symbolic_permissions(fileperms('./index.php')); // -rw-r--r-- + :: -octal_permissions() -=================== + echo symbolic_permissions(fileperms('./index.php')); // -rw-r--r-- -.. php:function:: octal_permissions($perms) +.. function:: octal_permissions($perms) :param int $perms: Permissions - :returns: string + :returns: Octal permissions string + :rtype: string -Takes numeric permissions (such as is returned by ``fileperms()``) and returns -a three character octal notation of file permissions. + Takes numeric permissions (such as is returned by ``fileperms()``) and returns + a three character octal notation of file permissions. -:: + :: - echo octal_permissions(fileperms('./index.php')); // 644
\ No newline at end of file + echo octal_permissions(fileperms('./index.php')); // 644
\ No newline at end of file diff --git a/user_guide_src/source/helpers/form_helper.rst b/user_guide_src/source/helpers/form_helper.rst index f49027baa..4fa5f246b 100644 --- a/user_guide_src/source/helpers/form_helper.rst +++ b/user_guide_src/source/helpers/form_helper.rst @@ -5,7 +5,12 @@ Form Helper The Form Helper file contains functions that assist in working with forms. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== @@ -14,713 +19,684 @@ This helper is loaded using the following code:: $this->load->helper('form'); +Available Functions +=================== + The following functions are available: -form_open() -=========== -.. php:function:: form_open($action = '', $attributes = '', $hidden = array()) +.. function:: form_open([$action = ''[, $attributes = ''[, $hidden = array()]]]) :param string $action: Form action/target URI string :param array $attributes: HTML attributes :param array $hidden: An array of hidden fields' definitions - :returns: string + :returns: An HTML form opening tag + :rtype: string -Creates an opening form tag with a base URL **built from your config preferences**. -It will optionally let you add form attributes and hidden input fields, and -will always add the `accept-charset` attribute based on the charset value in your -config file. + Creates an opening form tag with a base URL **built from your config preferences**. + It will optionally let you add form attributes and hidden input fields, and + will always add the `accept-charset` attribute based on the charset value in your + config file. -The main benefit of using this tag rather than hard coding your own HTML is that -it permits your site to be more portable in the event your URLs ever change. + The main benefit of using this tag rather than hard coding your own HTML is that + it permits your site to be more portable in the event your URLs ever change. -Here's a simple example:: + Here's a simple example:: - echo form_open('email/send'); + echo form_open('email/send'); -The above example would create a form that points to your base URL plus the -"email/send" URI segments, like this:: + The above example would create a form that points to your base URL plus the + "email/send" URI segments, like this:: - <form method="post" accept-charset="utf-8" action="http://example.com/index.php/email/send"> + <form method="post" accept-charset="utf-8" action="http://example.com/index.php/email/send"> -Adding Attributes -^^^^^^^^^^^^^^^^^ + **Adding Attributes** -Attributes can be added by passing an associative array to the second -parameter, like this:: + Attributes can be added by passing an associative array to the second + parameter, like this:: - $attributes = array('class' => 'email', 'id' => 'myform'); - echo form_open('email/send', $attributes); + $attributes = array('class' => 'email', 'id' => 'myform'); + echo form_open('email/send', $attributes); -Alternatively, you can specify the second parameter as a string:: + Alternatively, you can specify the second parameter as a string:: - echo form_open('email/send', 'class="email" id="myform"'); + echo form_open('email/send', 'class="email" id="myform"'); -The above examples would create a form similar to this:: + The above examples would create a form similar to this:: - <form method="post" accept-charset="utf-8" action="http://example.com/index.php/email/send" class="email" id="myform"> + <form method="post" accept-charset="utf-8" action="http://example.com/index.php/email/send" class="email" id="myform"> -Adding Hidden Input Fields -^^^^^^^^^^^^^^^^^^^^^^^^^^ + **Adding Hidden Input Fields** -Hidden fields can be added by passing an associative array to the -third parameter, like this:: + Hidden fields can be added by passing an associative array to the + third parameter, like this:: - $hidden = array('username' => 'Joe', 'member_id' => '234'); - echo form_open('email/send', '', $hidden); + $hidden = array('username' => 'Joe', 'member_id' => '234'); + echo form_open('email/send', '', $hidden); -You can skip the second parameter by passing any falsy value to it. + You can skip the second parameter by passing any falsy value to it. -The above example would create a form similar to this:: + The above example would create a form similar to this:: - <form method="post" accept-charset="utf-8" action="http://example.com/index.php/email/send"> - <input type="hidden" name="username" value="Joe" /> - <input type="hidden" name="member_id" value="234" /> + <form method="post" accept-charset="utf-8" action="http://example.com/index.php/email/send"> + <input type="hidden" name="username" value="Joe" /> + <input type="hidden" name="member_id" value="234" /> -form_open_multipart() -===================== -.. php:function:: form_open_multipart($action = '', $attributes = array(), $hidden = array()) +.. function:: form_open_multipart([$action = ''[, $attributes = array()[, $hidden = array()]]) :param string $action: Form action/target URI string :param array $attributes: HTML attributes :param array $hidden: An array of hidden fields' definitions - :returns: string + :returns: An HTML multipart form opening tag + :rtype: string -This function is absolutely identical to :php:func:`form_open()` above, -except that it adds a *multipart* attribute, which is necessary if you -would like to use the form to upload files with. + This function is absolutely identical to :func:`form_open()` above, + except that it adds a *multipart* attribute, which is necessary if you + would like to use the form to upload files with. -form_hidden() -============= -.. php:function:: form_hidden($name, $value = '') +.. function:: form_hidden($name[, $value = '']) :param string $name: Field name :param string $value: Field value - :returns: string - -Lets you generate hidden input fields. You can either submit a -name/value string to create one field:: + :returns: An HTML hidden input field tag + :rtype: string - form_hidden('username', 'johndoe'); - // Would produce: <input type="hidden" name="username" value="johndoe" /> + Lets you generate hidden input fields. You can either submit a + name/value string to create one field:: -... or you can submit an associative array to create multiple fields:: + form_hidden('username', 'johndoe'); + // Would produce: <input type="hidden" name="username" value="johndoe" /> - $data = array( - 'name' => 'John Doe', - 'email' => 'john@example.com', - 'url' => 'http://example.com' - ); + ... or you can submit an associative array to create multiple fields:: - echo form_hidden($data); + $data = array( + 'name' => 'John Doe', + 'email' => 'john@example.com', + 'url' => 'http://example.com' + ); - /* - Would produce: - <input type="hidden" name="name" value="John Doe" /> - <input type="hidden" name="email" value="john@example.com" /> - <input type="hidden" name="url" value="http://example.com" /> - */ + echo form_hidden($data); -You can also pass an associative array to the value field:: + /* + Would produce: + <input type="hidden" name="name" value="John Doe" /> + <input type="hidden" name="email" value="john@example.com" /> + <input type="hidden" name="url" value="http://example.com" /> + */ - $data = array( - 'name' => 'John Doe', - 'email' => 'john@example.com', - 'url' => 'http://example.com' - ); + You can also pass an associative array to the value field:: - echo form_hidden('my_array', $data); + $data = array( + 'name' => 'John Doe', + 'email' => 'john@example.com', + 'url' => 'http://example.com' + ); - /* - Would produce: + echo form_hidden('my_array', $data); - <input type="hidden" name="my_array[name]" value="John Doe" /> - <input type="hidden" name="my_array[email]" value="john@example.com" /> - <input type="hidden" name="my_array[url]" value="http://example.com" /> - */ + /* + Would produce: -If you want to create hidden input fields with extra attributes:: + <input type="hidden" name="my_array[name]" value="John Doe" /> + <input type="hidden" name="my_array[email]" value="john@example.com" /> + <input type="hidden" name="my_array[url]" value="http://example.com" /> + */ - $data = array( - 'type' => 'hidden', - 'name' => 'email', - 'id' => 'hiddenemail', - 'value' => 'john@example.com', - 'class' => 'hiddenemail' - ); + If you want to create hidden input fields with extra attributes:: - echo form_input($data); + $data = array( + 'type' => 'hidden', + 'name' => 'email', + 'id' => 'hiddenemail', + 'value' => 'john@example.com', + 'class' => 'hiddenemail' + ); - /* - Would produce: + echo form_input($data); - <input type="hidden" name="email" value="john@example.com" id="hiddenemail" class="hiddenemail" /> - */ + /* + Would produce: -form_input() -============ + <input type="hidden" name="email" value="john@example.com" id="hiddenemail" class="hiddenemail" /> + */ -.. php:function:: form_input($data = '', $value = '', $extra = '') +.. function:: form_input([$data = ''[, $value = ''[, $extra = '']]) :param array $data: Field attributes data :param string $value: Field value :param string $extra: Extra attributes to be added to the tag *as is* - :returns: string - -Lets you generate a standard text input field. You can minimally pass -the field name and value in the first and second parameter:: + :returns: An HTML text input field tag + :rtype: string - echo form_input('username', 'johndoe'); + Lets you generate a standard text input field. You can minimally pass + the field name and value in the first and second parameter:: -Or you can pass an associative array containing any data you wish your -form to contain:: + echo form_input('username', 'johndoe'); - $data = array( - 'name' => 'username', - 'id' => 'username', - 'value' => 'johndoe', - 'maxlength' => '100', - 'size' => '50', - 'style' => 'width:50%' - ); + Or you can pass an associative array containing any data you wish your + form to contain:: - echo form_input($data); + $data = array( + 'name' => 'username', + 'id' => 'username', + 'value' => 'johndoe', + 'maxlength' => '100', + 'size' => '50', + 'style' => 'width:50%' + ); - /* - Would produce: + echo form_input($data); - <input type="text" name="username" value="johndoe" id="username" maxlength="100" size="50" style="width:50%" /> - */ + /* + Would produce: -If you would like your form to contain some additional data, like -JavaScript, you can pass it as a string in the third parameter:: + <input type="text" name="username" value="johndoe" id="username" maxlength="100" size="50" style="width:50%" /> + */ - $js = 'onClick="some_function()"'; - echo form_input('username', 'johndoe', $js); + If you would like your form to contain some additional data, like + JavaScript, you can pass it as a string in the third parameter:: -form_password() -=============== + $js = 'onClick="some_function()"'; + echo form_input('username', 'johndoe', $js); -.. php:function:: form_password($data = '', $value = '', $extra = '') +.. function:: form_password([$data = ''[, $value = ''[, $extra = '']]]) :param array $data: Field attributes data :param string $value: Field value :param string $extra: Extra attributes to be added to the tag *as is* - :returns: string + :returns: An HTML password input field tag + :rtype: string -This function is identical in all respects to the :php:func:`form_input()` -function above except that it uses the "password" input type. + This function is identical in all respects to the :func:`form_input()` + function above except that it uses the "password" input type. -form_upload() -============= -.. php:function:: form_upload($data = '', $value = '', $extra = '') +.. function:: form_upload([$data = ''[, $value = ''[, $extra = '']]]) :param array $data: Field attributes data :param string $value: Field value :param string $extra: Extra attributes to be added to the tag *as is* - :returns: string + :returns: An HTML file upload input field tag + :rtype: string -This function is identical in all respects to the :php:func:`form_input()` -function above except that it uses the "file" input type, allowing it to -be used to upload files. + This function is identical in all respects to the :func:`form_input()` + function above except that it uses the "file" input type, allowing it to + be used to upload files. -form_textarea() -=============== -.. php:function:: form_textarea($data = '', $value = '', $extra = '') +.. function:: form_textarea([$data = ''[, $value = ''[, $extra = '']]]) :param array $data: Field attributes data :param string $value: Field value :param string $extra: Extra attributes to be added to the tag *as is* - :returns: string + :returns: An HTML textarea tag + :rtype: string -This function is identical in all respects to the :php:func:`form_input()` -function above except that it generates a "textarea" type. + This function is identical in all respects to the :func:`form_input()` + function above except that it generates a "textarea" type. -.. note: Instead of the *maxlength* and *size* attributes in the above example, - you will instead specify *rows* and *cols*. + .. note:: Instead of the *maxlength* and *size* attributes in the above example, + you will instead specify *rows* and *cols*. -form_dropdown() -=============== - -.. php:function:: form_dropdown($name = '', $options = array(), $selected = array(), $extra = '') +.. function:: form_dropdown([$name = ''[, $options = array()[, $selected = array()[, $extra = '']]]]) :param string $name: Field name :param array $options: An associative array of options to be listed :param array $selected: List of fields to mark with the *selected* attribute :param string $extra: Extra attributes to be added to the tag *as is* - :returns: string - -Lets you create a standard drop-down field. The first parameter will -contain the name of the field, the second parameter will contain an -associative array of options, and the third parameter will contain the -value you wish to be selected. You can also pass an array of multiple -items through the third parameter, and CodeIgniter will create a -multiple select for you. - -Example:: - - $options = array( - 'small' => 'Small Shirt', - 'med' => 'Medium Shirt', - 'large' => 'Large Shirt', - 'xlarge' => 'Extra Large Shirt', - ); - - $shirts_on_sale = array('small', 'large'); - echo form_dropdown('shirts', $options, 'large'); - - /* - Would produce: - - <select name="shirts"> - <option value="small">Small Shirt</option> - <option value="med">Medium Shirt</option> - <option value="large" selected="selected">Large Shirt</option> - <option value="xlarge">Extra Large Shirt</option> - </select> - */ + :returns: An HTML dropdown select field tag + :rtype: string - echo form_dropdown('shirts', $options, $shirts_on_sale); + Lets you create a standard drop-down field. The first parameter will + contain the name of the field, the second parameter will contain an + associative array of options, and the third parameter will contain the + value you wish to be selected. You can also pass an array of multiple + items through the third parameter, and CodeIgniter will create a + multiple select for you. - /* - Would produce: + Example:: - <select name="shirts" multiple="multiple"> - <option value="small" selected="selected">Small Shirt</option> - <option value="med">Medium Shirt</option> - <option value="large" selected="selected">Large Shirt</option> - <option value="xlarge">Extra Large Shirt</option> - </select> - */ + $options = array( + 'small' => 'Small Shirt', + 'med' => 'Medium Shirt', + 'large' => 'Large Shirt', + 'xlarge' => 'Extra Large Shirt', + ); + + $shirts_on_sale = array('small', 'large'); + echo form_dropdown('shirts', $options, 'large'); + + /* + Would produce: + + <select name="shirts"> + <option value="small">Small Shirt</option> + <option value="med">Medium Shirt</option> + <option value="large" selected="selected">Large Shirt</option> + <option value="xlarge">Extra Large Shirt</option> + </select> + */ -If you would like the opening <select> to contain additional data, like -an id attribute or JavaScript, you can pass it as a string in the fourth -parameter:: + echo form_dropdown('shirts', $options, $shirts_on_sale); - $js = 'id="shirts" onChange="some_function();"'; - echo form_dropdown('shirts', $options, 'large', $js); + /* + Would produce: -If the array passed as ``$options`` is a multidimensional array, then -``form_dropdown()`` will produce an <optgroup> with the array key as the -label. + <select name="shirts" multiple="multiple"> + <option value="small" selected="selected">Small Shirt</option> + <option value="med">Medium Shirt</option> + <option value="large" selected="selected">Large Shirt</option> + <option value="xlarge">Extra Large Shirt</option> + </select> + */ -form_multiselect() -================== + If you would like the opening <select> to contain additional data, like + an id attribute or JavaScript, you can pass it as a string in the fourth + parameter:: -.. php:function:: form_multiselect($name = '', $options = array(), $selected = array(), $extra = '') + $js = 'id="shirts" onChange="some_function();"'; + echo form_dropdown('shirts', $options, 'large', $js); + + If the array passed as ``$options`` is a multidimensional array, then + ``form_dropdown()`` will produce an <optgroup> with the array key as the + label. + + +.. function:: form_multiselect([$name = ''[, $options = array()[, $selected = array()[, $extra = '']]]]) :param string $name: Field name :param array $options: An associative array of options to be listed :param array $selected: List of fields to mark with the *selected* attribute :param string $extra: Extra attributes to be added to the tag *as is* - :returns: string + :returns: An HTML dropdown multiselect field tag + :rtype: string -Lets you create a standard multiselect field. The first parameter will -contain the name of the field, the second parameter will contain an -associative array of options, and the third parameter will contain the -value or values you wish to be selected. + Lets you create a standard multiselect field. The first parameter will + contain the name of the field, the second parameter will contain an + associative array of options, and the third parameter will contain the + value or values you wish to be selected. -The parameter usage is identical to using :php:func:`form_dropdown()` above, -except of course that the name of the field will need to use POST array -syntax, e.g. foo[]. + The parameter usage is identical to using :func:`form_dropdown()` above, + except of course that the name of the field will need to use POST array + syntax, e.g. foo[]. -form_fieldset() -=============== -.. php:function:: form_fieldset($legend_text = '', $attributes = array()) +.. function:: form_fieldset([$legend_text = ''[, $attributes = array()]]) :param string $legend_text: Text to put in the <legend> tag :param array $attributes: Attributes to be set on the <fieldset> tag - :returns: string + :returns: An HTML fieldset opening tag + :rtype: string -Lets you generate fieldset/legend fields. + Lets you generate fieldset/legend fields. -Example:: + Example:: - echo form_fieldset('Address Information'); - echo "<p>fieldset content here</p>\n"; - echo form_fieldset_close(); + echo form_fieldset('Address Information'); + echo "<p>fieldset content here</p>\n"; + echo form_fieldset_close(); - /* - Produces: + /* + Produces: - <fieldset> - <legend>Address Information</legend> - <p>form content here</p> - </fieldset> - */ + <fieldset> + <legend>Address Information</legend> + <p>form content here</p> + </fieldset> + */ -Similar to other functions, you can submit an associative array in the -second parameter if you prefer to set additional attributes:: + Similar to other functions, you can submit an associative array in the + second parameter if you prefer to set additional attributes:: - $attributes = array( - 'id' => 'address_info', - 'class' => 'address_info' - ); + $attributes = array( + 'id' => 'address_info', + 'class' => 'address_info' + ); - echo form_fieldset('Address Information', $attributes); - echo "<p>fieldset content here</p>\n"; - echo form_fieldset_close(); + echo form_fieldset('Address Information', $attributes); + echo "<p>fieldset content here</p>\n"; + echo form_fieldset_close(); - /* - Produces: + /* + Produces: - <fieldset id="address_info" class="address_info"> - <legend>Address Information</legend> - <p>form content here</p> - </fieldset> - */ + <fieldset id="address_info" class="address_info"> + <legend>Address Information</legend> + <p>form content here</p> + </fieldset> + */ -form_fieldset_close() -===================== -.. php:function:: form_fieldset_close($extra = '') +.. function:: form_fieldset_close([$extra = '']) :param string $extra: Anything to append after the closing tag, *as is* - :returns: string + :returns: An HTML fieldset closing tag + :rtype: string + -Produces a closing </fieldset> tag. The only advantage to using this -function is it permits you to pass data to it which will be added below -the tag. For example + Produces a closing </fieldset> tag. The only advantage to using this + function is it permits you to pass data to it which will be added below + the tag. For example -:: + :: - $string = '</div></div>'; - echo form_fieldset_close($string); - // Would produce: </fieldset></div></div> + $string = '</div></div>'; + echo form_fieldset_close($string); + // Would produce: </fieldset></div></div> -form_checkbox() -=============== -.. php:function:: form_checkbox($data = '', $value = '', $checked = FALSE, $extra = '') +.. function:: form_checkbox([$data = ''[, $value = ''[, $checked = FALSE[, $extra = '']]]]) :param array $data: Field attributes data :param string $value: Field value :param bool $checked: Whether to mark the checkbox as being *checked* :param string $extra: Extra attributes to be added to the tag *as is* - :returns: string + :returns: An HTML checkbox input tag + :rtype: string -Lets you generate a checkbox field. Simple example:: + Lets you generate a checkbox field. Simple example:: - echo form_checkbox('newsletter', 'accept', TRUE); - // Would produce: <input type="checkbox" name="newsletter" value="accept" checked="checked" /> + echo form_checkbox('newsletter', 'accept', TRUE); + // Would produce: <input type="checkbox" name="newsletter" value="accept" checked="checked" /> -The third parameter contains a boolean TRUE/FALSE to determine whether -the box should be checked or not. + The third parameter contains a boolean TRUE/FALSE to determine whether + the box should be checked or not. -Similar to the other form functions in this helper, you can also pass an -array of attributes to the function:: + Similar to the other form functions in this helper, you can also pass an + array of attributes to the function:: - $data = array( - 'name' => 'newsletter', - 'id' => 'newsletter', - 'value' => 'accept', - 'checked' => TRUE, - 'style' => 'margin:10px' - ); + $data = array( + 'name' => 'newsletter', + 'id' => 'newsletter', + 'value' => 'accept', + 'checked' => TRUE, + 'style' => 'margin:10px' + ); - echo form_checkbox($data); - // Would produce: <input type="checkbox" name="newsletter" id="newsletter" value="accept" checked="checked" style="margin:10px" /> + echo form_checkbox($data); + // Would produce: <input type="checkbox" name="newsletter" id="newsletter" value="accept" checked="checked" style="margin:10px" /> -Also as with other functions, if you would like the tag to contain -additional data like JavaScript, you can pass it as a string in the -fourth parameter:: + Also as with other functions, if you would like the tag to contain + additional data like JavaScript, you can pass it as a string in the + fourth parameter:: - $js = 'onClick="some_function()"'; - echo form_checkbox('newsletter', 'accept', TRUE, $js) + $js = 'onClick="some_function()"'; + echo form_checkbox('newsletter', 'accept', TRUE, $js) -form_radio() -============ -.. php:function:: form_radio($data = '', $value = '', $checked = FALSE, $extra = '') +.. function:: form_radio([$data = ''[, $value = ''[, $checked = FALSE[, $extra = '']]]]) :param array $data: Field attributes data :param string $value: Field value :param bool $checked: Whether to mark the radio button as being *checked* :param string $extra: Extra attributes to be added to the tag *as is* - :returns: string + :returns: An HTML radio input tag + :rtype: string -This function is identical in all respects to the :php:func:`form_checkbox()` -function above except that it uses the "radio" input type. + This function is identical in all respects to the :func:`form_checkbox()` + function above except that it uses the "radio" input type. -form_label() -============ -.. php:function:: form_label($label_text = '', $id = '', $attributes = array()) +.. function:: form_label([$label_text = ''[, $id = ''[, $attributes = array()]]]) :param string $label_text: Text to put in the <label> tag :param string $id: ID of the form element that we're making a label for :param string $attributes: HTML attributes - :returns: string + :returns: An HTML field label tag + :rtype: string -Lets you generate a <label>. Simple example:: + Lets you generate a <label>. Simple example:: - echo form_label('What is your Name', 'username'); - // Would produce: <label for="username">What is your Name</label> + echo form_label('What is your Name', 'username'); + // Would produce: <label for="username">What is your Name</label> -Similar to other functions, you can submit an associative array in the -third parameter if you prefer to set additional attributes. + Similar to other functions, you can submit an associative array in the + third parameter if you prefer to set additional attributes. -Example:: + Example:: - $attributes = array( - 'class' => 'mycustomclass', - 'style' => 'color: #000;' - ); + $attributes = array( + 'class' => 'mycustomclass', + 'style' => 'color: #000;' + ); - echo form_label('What is your Name', 'username', $attributes); - // Would produce: <label for="username" class="mycustomclass" style="color: #000;">What is your Name</label> + echo form_label('What is your Name', 'username', $attributes); + // Would produce: <label for="username" class="mycustomclass" style="color: #000;">What is your Name</label> -form_submit() -============= -.. php:function:: form_submit($data = '', $value = '', $extra = '') +.. function:: form_submit([$data = ''[, $value = ''[, $extra = '']]]) :param string $data: Button name :param string $value: Button value :param string $extra: Extra attributes to be added to the tag *as is* - :returns: string + :returns: An HTML input submit tag + :rtype: string -Lets you generate a standard submit button. Simple example:: + Lets you generate a standard submit button. Simple example:: - echo form_submit('mysubmit', 'Submit Post!'); - // Would produce: <input type="submit" name="mysubmit" value="Submit Post!" /> + echo form_submit('mysubmit', 'Submit Post!'); + // Would produce: <input type="submit" name="mysubmit" value="Submit Post!" /> -Similar to other functions, you can submit an associative array in the -first parameter if you prefer to set your own attributes. The third -parameter lets you add extra data to your form, like JavaScript. + Similar to other functions, you can submit an associative array in the + first parameter if you prefer to set your own attributes. The third + parameter lets you add extra data to your form, like JavaScript. -form_reset() -============ -.. php:function:: form_reset($data = '', $value = '', $extra = '') +.. function:: form_reset([$data = ''[, $value = ''[, $extra = '']]]) :param string $data: Button name :param string $value: Button value :param string $extra: Extra attributes to be added to the tag *as is* - :returns: string + :returns: An HTML input reset button tag + :rtype: string -Lets you generate a standard reset button. Use is identical to -:php:func:`form_submit()`. + Lets you generate a standard reset button. Use is identical to + :func:`form_submit()`. -form_button() -============= -.. php:function:: form_button($data = '', $content = '', $extra = '') +.. function:: form_button([$data = ''[, $content = ''[, $extra = '']]]) :param string $data: Button name :param string $content: Button label :param string $extra: Extra attributes to be added to the tag *as is* - :returns: string + :returns: An HTML button tag + :rtype: string -Lets you generate a standard button element. You can minimally pass the -button name and content in the first and second parameter:: + Lets you generate a standard button element. You can minimally pass the + button name and content in the first and second parameter:: - echo form_button('name','content'); - // Would produce: <button name="name" type="button">Content</button> + echo form_button('name','content'); + // Would produce: <button name="name" type="button">Content</button> -Or you can pass an associative array containing any data you wish your -form to contain:: + Or you can pass an associative array containing any data you wish your + form to contain:: - $data = array( - 'name' => 'button', - 'id' => 'button', - 'value' => 'true', - 'type' => 'reset', - 'content' => 'Reset' - ); + $data = array( + 'name' => 'button', + 'id' => 'button', + 'value' => 'true', + 'type' => 'reset', + 'content' => 'Reset' + ); - echo form_button($data); - // Would produce: <button name="button" id="button" value="true" type="reset">Reset</button> + echo form_button($data); + // Would produce: <button name="button" id="button" value="true" type="reset">Reset</button> -If you would like your form to contain some additional data, like -JavaScript, you can pass it as a string in the third parameter:: + If you would like your form to contain some additional data, like + JavaScript, you can pass it as a string in the third parameter:: - $js = 'onClick="some_function()"'; - echo form_button('mybutton', 'Click Me', $js); + $js = 'onClick="some_function()"'; + echo form_button('mybutton', 'Click Me', $js); -form_close() -============ -.. php:function:: form_close($extra = '') +.. function:: form_close([$extra = '']) :param string $extra: Anything to append after the closing tag, *as is* - :returns: string + :returns: An HTML form closing tag + :rtype: string -Produces a closing </form> tag. The only advantage to using this -function is it permits you to pass data to it which will be added below -the tag. For example:: + Produces a closing </form> tag. The only advantage to using this + function is it permits you to pass data to it which will be added below + the tag. For example:: - $string = '</div></div>'; - echo form_close($string); - // Would produce: </form> </div></div> + $string = '</div></div>'; + echo form_close($string); + // Would produce: </form> </div></div> -form_prep() -=========== -.. php:function:: form_prep($str = '', $is_textarea = FALSE) +.. function:: form_prep([$str = ''[, $is_textarea = FALSE]]) :param string $str: Value to escape :param bool $is_textarea: Whether we're preparing for <textarea> or a regular input tag - :returns: string + :returns: Escaped value + :rtype: string -Allows you to safely use HTML and characters such as quotes within form -elements without breaking out of the form. + Allows you to safely use HTML and characters such as quotes within form + elements without breaking out of the form. -Consider this example:: + Consider this example:: - $string = 'Here is a string containing "quoted" text.'; - <input type="text" name="myform" value="$string" /> + $string = 'Here is a string containing "quoted" text.'; + <input type="text" name="myform" value="$string" /> -Since the above string contains a set of quotes it will cause the form -to break. The ``form_prep()`` function converts HTML so that it can be used -safely:: + Since the above string contains a set of quotes it will cause the form + to break. The ``form_prep()`` function converts HTML so that it can be used + safely:: - <input type="text" name="myform" value="<?php echo form_prep($string); ?>" /> + <input type="text" name="myform" value="<?php echo form_prep($string); ?>" /> -.. note:: If you use any of the form helper functions listed in this page the form - values will be prepped automatically, so there is no need to call this - function. Use it only if you are creating your own form elements. + .. note:: If you use any of the form helper functions listed in this page the form + values will be prepped automatically, so there is no need to call this + function. Use it only if you are creating your own form elements. -set_value() -=========== -.. php:function:: set_value($field = '', $default = '', $is_textarea = FALSE) +.. function:: set_value([$field = ''[, $default = ''[, $is_textarea = FALSE]]]) :param string $field: Field name :param string $default: Default value :param bool $is_textarea: Whether we're setting <textarea> content - :returns: string + :returns: Field value + :rtype: string -Permits you to set the value of an input form or textarea. You must -supply the field name via the first parameter of the function. The -second (optional) parameter allows you to set a default value for the -form. + Permits you to set the value of an input form or textarea. You must + supply the field name via the first parameter of the function. The + second (optional) parameter allows you to set a default value for the + form. -Example:: + Example:: - <input type="text" name="quantity" value="<?=set_value('quantity', '0');?>" size="50" /> + <input type="text" name="quantity" value="<?=set_value('quantity', '0');?>" size="50" /> -The above form will show "0" when loaded for the first time. + The above form will show "0" when loaded for the first time. -set_select() -============ -.. php:function:: set_select($field = '', $value = '', $default = FALSE) +.. function:: set_select([$field = ''[, $value = ''[, $default = FALSE]]]) :param string $field: Field name :param string $value: Value to check for :param string $default: Whether the value is also a default one - :returns: string - -If you use a <select> menu, this function permits you to display the -menu item that was selected. + :returns: 'selected' attribute or an empty string + :rtype: string -The first parameter must contain the name of the select menu, the second -parameter must contain the value of each item, and the third (optional) -parameter lets you set an item as the default (use boolean TRUE/FALSE). + If you use a <select> menu, this function permits you to display the + menu item that was selected. -Example:: + The first parameter must contain the name of the select menu, the second + parameter must contain the value of each item, and the third (optional) + parameter lets you set an item as the default (use boolean TRUE/FALSE). - <select name="myselect"> - <option value="one" <?php echo set_select('myselect', 'one', TRUE); ?> >One</option> - <option value="two" <?php echo set_select('myselect', 'two'); ?> >Two</option> - <option value="three" <?php echo set_select('myselect', 'three'); ?> >Three</option> - </select> + Example:: -set_checkbox() -============== + <select name="myselect"> + <option value="one" <?php echo set_select('myselect', 'one', TRUE); ?> >One</option> + <option value="two" <?php echo set_select('myselect', 'two'); ?> >Two</option> + <option value="three" <?php echo set_select('myselect', 'three'); ?> >Three</option> + </select> -.. php:function:: set_checkbox($field = '', $value = '', $default = FALSE) +.. function:: set_checkbox([$field = ''[, $value = ''[, $default = FALSE]]]) :param string $field: Field name :param string $value: Value to check for :param string $default: Whether the value is also a default one - :returns: string + :returns: 'checked' attribute or an empty string + :rtype: string -Permits you to display a checkbox in the state it was submitted. + Permits you to display a checkbox in the state it was submitted. -The first parameter must contain the name of the checkbox, the second -parameter must contain its value, and the third (optional) parameter -lets you set an item as the default (use boolean TRUE/FALSE). + The first parameter must contain the name of the checkbox, the second + parameter must contain its value, and the third (optional) parameter + lets you set an item as the default (use boolean TRUE/FALSE). -Example:: + Example:: - <input type="checkbox" name="mycheck" value="1" <?php echo set_checkbox('mycheck', '1'); ?> /> - <input type="checkbox" name="mycheck" value="2" <?php echo set_checkbox('mycheck', '2'); ?> /> + <input type="checkbox" name="mycheck" value="1" <?php echo set_checkbox('mycheck', '1'); ?> /> + <input type="checkbox" name="mycheck" value="2" <?php echo set_checkbox('mycheck', '2'); ?> /> -set_radio() -=========== - -.. php:function:: set_radio($field = '', $value = '', $default = FALSE) +.. function:: set_radio([$field = ''[, $value = ''[, $default = FALSE]]]) :param string $field: Field name :param string $value: Value to check for :param string $default: Whether the value is also a default one - :returns: string - -Permits you to display radio buttons in the state they were submitted. -This function is identical to the :php:func:`set_checkbox()` function above. + :returns: 'checked' attribute or an empty string + :rtype: string -Example:: + Permits you to display radio buttons in the state they were submitted. + This function is identical to the :func:`set_checkbox()` function above. - <input type="radio" name="myradio" value="1" <?php echo set_radio('myradio', '1', TRUE); ?> /> - <input type="radio" name="myradio" value="2" <?php echo set_radio('myradio', '2'); ?> /> + Example:: -.. note:: If you are using the Form Validation class, you must always specify - a rule for your field, even if empty, in order for the ``set_*()`` - functions to work. This is because if a Form Validation object is - defined, the control for ``set_*()`` is handed over to a method of the - class instead of the generic helper function. + <input type="radio" name="myradio" value="1" <?php echo set_radio('myradio', '1', TRUE); ?> /> + <input type="radio" name="myradio" value="2" <?php echo set_radio('myradio', '2'); ?> /> -form_error() -============ + .. note:: If you are using the Form Validation class, you must always specify + a rule for your field, even if empty, in order for the ``set_*()`` + functions to work. This is because if a Form Validation object is + defined, the control for ``set_*()`` is handed over to a method of the + class instead of the generic helper function. -.. php:function:: form_error($field = '', $prefix = '', $suffix = '') +.. function:: form_error([$field = ''[, $prefix = ''[, $suffix = '']]]) :param string $field: Field name :param string $prefix: Error opening tag :param string $suffix: Error closing tag - :returns: string + :returns: HTML-formatted form validation error message(s) + :rtype: string -Returns a validation error message from the :doc:`Form Validation Library -<../libraries/form_validation>`, associated with the specified field name. -You can optionally specify opening and closing tag(s) to put around the error -message. + Returns a validation error message from the :doc:`Form Validation Library + <../libraries/form_validation>`, associated with the specified field name. + You can optionally specify opening and closing tag(s) to put around the error + message. -Example:: + Example:: - // Assuming that the 'username' field value was incorrect: - echo form_error('myfield', '<div class="error">', '</div>'); + // Assuming that the 'username' field value was incorrect: + echo form_error('myfield', '<div class="error">', '</div>'); - // Would produce: <div class="error">Error message associated with the "username" field.</div> + // Would produce: <div class="error">Error message associated with the "username" field.</div> -validation_errors() -=================== -.. php:function:: validation_errors($prefix = '', $suffix = '') +.. function:: validation_errors([$prefix = ''[, $suffix = '']]) :param string $prefix: Error opening tag :param string $suffix: Error closing tag - :returns: string + :returns: HTML-formatted form validation error message(s) + :rtype: string -Similarly to the :php:func:`form_error()` function, returns all validation -error messages produced by the :doc:`Form Validation Library -<../libraries/form_validation>`, with optional opening and closing tags -around each of the messages. + Similarly to the :func:`form_error()` function, returns all validation + error messages produced by the :doc:`Form Validation Library + <../libraries/form_validation>`, with optional opening and closing tags + around each of the messages. -Example:: + Example:: - echo validation_errors('<span class="error">', '</span>'); + echo validation_errors('<span class="error">', '</span>'); - /* - Would produce, e.g.: + /* + Would produce, e.g.: - <span class="error">The "email" field doesn't contain a valid e-mail address!</span> - <span class="error">The "password" field doesn't match the "repeat_password" field!</span> + <span class="error">The "email" field doesn't contain a valid e-mail address!</span> + <span class="error">The "password" field doesn't match the "repeat_password" field!</span> - */
\ No newline at end of file + */
\ No newline at end of file diff --git a/user_guide_src/source/helpers/html_helper.rst b/user_guide_src/source/helpers/html_helper.rst index df53ebd2f..3324da8c0 100644 --- a/user_guide_src/source/helpers/html_helper.rst +++ b/user_guide_src/source/helpers/html_helper.rst @@ -5,7 +5,12 @@ HTML Helper The HTML Helper file contains functions that assist in working with HTML. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== @@ -14,94 +19,95 @@ This helper is loaded using the following code:: $this->load->helper('html'); +Available Functions +=================== + The following functions are available: -br() -==== -.. php:function:: br($count = 1) +.. function:: br([$count = 1]) :param int $count: Number of times to repeat the tag - :returns: string + :returns: HTML line break tag + :rtype: string -Generates line break tags (<br />) based on the number you submit. -Example:: + Generates line break tags (<br />) based on the number you submit. + Example:: - echo br(3); + echo br(3); -The above would produce: <br /><br /><br /> + The above would produce: -heading() -========= + .. code-block:: html -.. php:function:: heading($data = '', $h = '1', $attributes = '') + <br /><br /><br /> + +.. function:: heading([$data = ''[, $h = '1'[, $attributes = '']]]) :param string $data: Content :param string $h: Heading level :param array $attributes: HTML attributes - :returns: string + :returns: HTML heading tag + :rtype: string + + Lets you create HTML heading tags. The first parameter will contain the + data, the second the size of the heading. Example:: -Lets you create HTML heading tags. The first parameter will contain the -data, the second the size of the heading. Example:: + echo heading('Welcome!', 3); - echo heading('Welcome!', 3); + The above would produce: <h3>Welcome!</h3> -The above would produce: <h3>Welcome!</h3> + Additionally, in order to add attributes to the heading tag such as HTML + classes, ids or inline styles, a third parameter is available:: -Additionally, in order to add attributes to the heading tag such as HTML -classes, ids or inline styles, a third parameter is available:: + echo heading('Welcome!', 3, 'class="pink"') - echo heading('Welcome!', 3, 'class="pink"') + The above code produces: -The above code produces: <h3 class="pink">Welcome!<<h3> + .. code-block:: html -img() -===== + <h3 class="pink">Welcome!<h3> -.. php:function:: img($src = '', $index_page = FALSE, $attributes = '') +.. function:: img([$src = ''[, $index_page = FALSE[, $attributes = '']]]) :param string $src: Image source data :param bool $index_page: Whether to treat $src as a routed URI string :param array $attributes: HTML attributes - :returns: string - -Lets you create HTML <img /> tags. The first parameter contains the -image source. Example:: + :returns: HTML image tag + :rtype: string - echo img('images/picture.jpg'); // gives <img src="http://site.com/images/picture.jpg" /> + Lets you create HTML <img /> tags. The first parameter contains the + image source. Example:: -There is an optional second parameter that is a TRUE/FALSE value that -specifics if the *src* should have the page specified by -``$config['index_page']`` added to the address it creates. -Presumably, this would be if you were using a media controller:: + echo img('images/picture.jpg'); // gives <img src="http://site.com/images/picture.jpg" /> - echo img('images/picture.jpg', TRUE); // gives <img src="http://site.com/index.php/images/picture.jpg" alt="" /> + There is an optional second parameter that is a TRUE/FALSE value that + specifics if the *src* should have the page specified by + ``$config['index_page']`` added to the address it creates. + Presumably, this would be if you were using a media controller:: + echo img('images/picture.jpg', TRUE); // gives <img src="http://site.com/index.php/images/picture.jpg" alt="" /> -Additionally, an associative array can be passed to the ``img()`` function -for complete control over all attributes and values. If an *alt* attribute -is not provided, CodeIgniter will generate an empty string. + Additionally, an associative array can be passed to the ``img()`` function + for complete control over all attributes and values. If an *alt* attribute + is not provided, CodeIgniter will generate an empty string. -Example:: + Example:: - $image_properties = array(           - 'src' => 'images/picture.jpg',           - 'alt' => 'Me, demonstrating how to eat 4 slices of pizza at one time',  - 'class' => 'post_images',           - 'width' => '200',           - 'height'=> '200',           - 'title' => 'That was quite a night',           - 'rel' => 'lightbox' - ); + $image_properties = array( + 'src' => 'images/picture.jpg', + 'alt' => 'Me, demonstrating how to eat 4 slices of pizza at one time', + 'class' => 'post_images', + 'width' => '200', + 'height'=> '200', + 'title' => 'That was quite a night', + 'rel' => 'lightbox' + ); - img($image_properties); - // <img src="http://site.com/index.php/images/picture.jpg" alt="Me, demonstrating how to eat 4 slices of pizza at one time" class="post_images" width="200" height="200" title="That was quite a night" rel="lightbox" /> + img($image_properties); + // <img src="http://site.com/index.php/images/picture.jpg" alt="Me, demonstrating how to eat 4 slices of pizza at one time" class="post_images" width="200" height="200" title="That was quite a night" rel="lightbox" /> - -link_tag() -========== - -.. php:function:: ling_tag($href = '', $rel = 'stylesheet', $type = 'text/css', $title = '', $media = '', $index_page = FALSE) +.. function:: link_tag([$href = ''[, $rel = 'stylesheet'[, $type = 'text/css'[, $title = ''[, $media = ''[, $index_page = FALSE]]]]]]) :param string $href: What are we linking to :param string $rel: Relation type @@ -109,300 +115,284 @@ link_tag() :param string $title: Link title :param string $media: Media type :param bool $index_page: Whether to treat $src as a routed URI string - :returns: string - -Lets you create HTML <link /> tags. This is useful for stylesheet links, -as well as other links. The parameters are *href*, with optional *rel*, -*type*, *title*, *media* and *index_page*. + :returns: HTML link tag + :rtype: string -*index_page* is a boolean value that specifies if the *href* should have -the page specified by ``$config['index_page']`` added to the address it creates. + Lets you create HTML <link /> tags. This is useful for stylesheet links, + as well as other links. The parameters are *href*, with optional *rel*, + *type*, *title*, *media* and *index_page*. -Example:: + *index_page* is a boolean value that specifies if the *href* should have + the page specified by ``$config['index_page']`` added to the address it creates. - echo link_tag('css/mystyles.css'); - // gives <link href="http://site.com/css/mystyles.css" rel="stylesheet" type="text/css" /> + Example:: + echo link_tag('css/mystyles.css'); + // gives <link href="http://site.com/css/mystyles.css" rel="stylesheet" type="text/css" /> -Further examples:: + Further examples:: - echo link_tag('favicon.ico', 'shortcut icon', 'image/ico'); - // <link href="http://site.com/favicon.ico" rel="shortcut icon" type="image/ico" /> + echo link_tag('favicon.ico', 'shortcut icon', 'image/ico'); + // <link href="http://site.com/favicon.ico" rel="shortcut icon" type="image/ico" /> - echo link_tag('feed', 'alternate', 'application/rss+xml', 'My RSS Feed'); - // <link href="http://site.com/feed" rel="alternate" type="application/rss+xml" title="My RSS Feed" /> + echo link_tag('feed', 'alternate', 'application/rss+xml', 'My RSS Feed'); + // <link href="http://site.com/feed" rel="alternate" type="application/rss+xml" title="My RSS Feed" /> -Additionally, an associative array can be passed to the ``link()`` function -for complete control over all attributes and values:: + Additionally, an associative array can be passed to the ``link()`` function + for complete control over all attributes and values:: - $link = array(           - 'href' => 'css/printer.css', - 'rel' => 'stylesheet', - 'type' => 'text/css', - 'media' => 'print' - ); + $link = array( + 'href' => 'css/printer.css', + 'rel' => 'stylesheet', + 'type' => 'text/css', + 'media' => 'print' + ); - echo link_tag($link); - // <link href="http://site.com/css/printer.css" rel="stylesheet" type="text/css" media="print" /> + echo link_tag($link); + // <link href="http://site.com/css/printer.css" rel="stylesheet" type="text/css" media="print" /> -nbs() -===== - -.. php:function:: nbs($num = 1) +.. function:: nbs([$num = 1]) :param int $num: Number of space entities to produce - :returns: string + :returns: A sequence of non-breaking space HTML entities + :rtype: string + + Generates non-breaking spaces ( ) based on the number you submit. + Example:: -Generates non-breaking spaces ( ) based on the number you submit. -Example:: + echo nbs(3); - echo nbs(3); + The above would produce: -The above would produce:: + .. code-block:: html - + -ul() and ol() -============= -.. php:function:: ul($list, $attributes = '') +.. function:: ul($list[, $attributes = '']) :param array $list: List entries :param array $attributes: HTML attributes - :returns: string - -Permits you to generate ordered or unordered HTML lists from simple or -multi-dimensional arrays. Example:: + :returns: HTML-formatted unordered list + :rtype: string - $list = array( - 'red', - 'blue', - 'green', - 'yellow' - ); + Permits you to generate ordered or unordered HTML lists from simple or + multi-dimensional arrays. Example:: - $attributes = array( - 'class' => 'boldlist', - 'id' => 'mylist' - ); - - echo ul($list, $attributes); - -The above code will produce this:: - - <ul class="boldlist" id="mylist"> - <li>red</li> - <li>blue</li> - <li>green</li> - <li>yellow</li> - </ul> - -Here is a more complex example, using a multi-dimensional array:: - - $attributes = array( - 'class' => 'boldlist', - 'id' => 'mylist' - ); - - $list = array( - 'colors' => array( + $list = array( 'red', 'blue', - 'green' - ), - 'shapes' => array( - 'round', - 'square', - 'circles' => array( - 'ellipse', - 'oval', - 'sphere' - ) - ), - 'moods' => array( - 'happy', - 'upset' => array( - 'defeated' => array( - 'dejected', - 'disheartened', - 'depressed' - ), - 'annoyed', - 'cross', - 'angry' + 'green', + 'yellow' + ); + + $attributes = array( + 'class' => 'boldlist', + 'id' => 'mylist' + ); + + echo ul($list, $attributes); + + The above code will produce this: + + .. code-block:: html + + <ul class="boldlist" id="mylist"> + <li>red</li> + <li>blue</li> + <li>green</li> + <li>yellow</li> + </ul> + + Here is a more complex example, using a multi-dimensional array:: + + $attributes = array( + 'class' => 'boldlist', + 'id' => 'mylist' + ); + + $list = array( + 'colors' => array( + 'red', + 'blue', + 'green' + ), + 'shapes' => array( + 'round', + 'square', + 'circles' => array( + 'ellipse', + 'oval', + 'sphere' + ) + ), + 'moods' => array( + 'happy', + 'upset' => array( + 'defeated' => array( + 'dejected', + 'disheartened', + 'depressed' + ), + 'annoyed', + 'cross', + 'angry' + ) ) - ) - ); - - echo ul($list, $attributes); - -The above code will produce this:: - - <ul class="boldlist" id="mylist"> - <li>colors - <ul> - <li>red</li> - <li>blue</li> - <li>green</li> - </ul> - </li> - <li>shapes - <ul> - <li>round</li> - <li>suare</li> - <li>circles - <ul> - <li>elipse</li> - <li>oval</li> - <li>sphere</li> - </ul> - </li> - </ul> - </li> - <li>moods - <ul> - <li>happy</li> - <li>upset - <ul> - <li>defeated - <ul> - <li>dejected</li> - <li>disheartened</li> - <li>depressed</li> - </ul> - </li> - <li>annoyed</li> - <li>cross</li> - <li>angry</li> - </ul> - </li> - </ul> - </li> - </ul> - -.. php:function:: ol($list, $attributes = '') + ); + + echo ul($list, $attributes); + + The above code will produce this: + + .. code-block:: html + + <ul class="boldlist" id="mylist"> + <li>colors + <ul> + <li>red</li> + <li>blue</li> + <li>green</li> + </ul> + </li> + <li>shapes + <ul> + <li>round</li> + <li>suare</li> + <li>circles + <ul> + <li>elipse</li> + <li>oval</li> + <li>sphere</li> + </ul> + </li> + </ul> + </li> + <li>moods + <ul> + <li>happy</li> + <li>upset + <ul> + <li>defeated + <ul> + <li>dejected</li> + <li>disheartened</li> + <li>depressed</li> + </ul> + </li> + <li>annoyed</li> + <li>cross</li> + <li>angry</li> + </ul> + </li> + </ul> + </li> + </ul> + +.. function:: ol($list, $attributes = '') :param array $list: List entries :param array $attributes: HTML attributes - :returns: string + :returns: HTML-formatted ordered list + :rtype: string -Identical to :php:func:`ul()`, only it produces the <ol> tag for -ordered lists instead of <ul>. + Identical to :func:`ul()`, only it produces the <ol> tag for + ordered lists instead of <ul>. -meta() -====== - -.. php:function:: meta($name = '', $content = '', $type = 'name', $newline = "\n") +.. function:: meta([$name = ''[, $content = ''[, $type = 'name'[, $newline = "\n"]]]]) :param string $name: Meta name :param string $content: Meta content :param string $type: Meta type :param string $newline: Newline character - :returns: string - -Helps you generate meta tags. You can pass strings to the function, or -simple arrays, or multidimensional ones. - -Examples:: - - echo meta('description', 'My Great site'); - // Generates: <meta name="description" content="My Great Site" /> - - echo meta('Content-type', 'text/html; charset=utf-8', 'equiv'); - // Note the third parameter. Can be "equiv" or "name" - // Generates: <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> - - echo meta(array('name' => 'robots', 'content' => 'no-cache')); - // Generates: <meta name="robots" content="no-cache" /> - - $meta = array( - array( - 'name' => 'robots', - 'content' => 'no-cache' - ), - array( - 'name' => 'description', - 'content' => 'My Great Site' - ), - array( - 'name' => 'keywords', - 'content' => 'love, passion, intrigue, deception' - ), - array( - 'name' => 'robots', - 'content' => 'no-cache' - ), - array( - 'name' => 'Content-type', - 'content' => 'text/html; charset=utf-8', 'type' => 'equiv' - ) - ); - - echo meta($meta); - // Generates: - // <meta name="robots" content="no-cache" /> - // <meta name="description" content="My Great Site" /> - // <meta name="keywords" content="love, passion, intrigue, deception" /> - // <meta name="robots" content="no-cache" /> - // <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> - -doctype() -========= - -.. php:function:: doctype($type = 'xhtml1-strict') + :returns: HTML meta tag + :rtype: string + + Helps you generate meta tags. You can pass strings to the function, or + simple arrays, or multidimensional ones. + + Examples:: + + echo meta('description', 'My Great site'); + // Generates: <meta name="description" content="My Great Site" /> + + echo meta('Content-type', 'text/html; charset=utf-8', 'equiv'); + // Note the third parameter. Can be "equiv" or "name" + // Generates: <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> + + echo meta(array('name' => 'robots', 'content' => 'no-cache')); + // Generates: <meta name="robots" content="no-cache" /> + + $meta = array( + array( + 'name' => 'robots', + 'content' => 'no-cache' + ), + array( + 'name' => 'description', + 'content' => 'My Great Site' + ), + array( + 'name' => 'keywords', + 'content' => 'love, passion, intrigue, deception' + ), + array( + 'name' => 'robots', + 'content' => 'no-cache' + ), + array( + 'name' => 'Content-type', + 'content' => 'text/html; charset=utf-8', 'type' => 'equiv' + ) + ); - :param string $type: Doctype name + echo meta($meta); + // Generates: + // <meta name="robots" content="no-cache" /> + // <meta name="description" content="My Great Site" /> + // <meta name="keywords" content="love, passion, intrigue, deception" /> + // <meta name="robots" content="no-cache" /> + // <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> -Helps you generate document type declarations, or DTD's. XHTML 1.0 -Strict is used by default, but many doctypes are available. - -Example:: - - echo doctype(); // <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - - echo doctype('html4-trans'); // <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> - -The following is a list of doctype choices. These are configurable, and -pulled from application/config/doctypes.php - -+-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| Doctype | Option | Result | -+===============================+==============================+==================================================================================================================================================+ -| XHTML 1.1 | doctype('xhtml11') | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> | -+-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| XHTML 1.0 Strict | doctype('xhtml1-strict') | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | -+-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| XHTML 1.0 Transitional | doctype('xhtml1-trans') | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | -+-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| XHTML 1.0 Frameset | doctype('xhtml1-frame') | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> | -+-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| XHTML Basic 1.1 | doctype('xhtml-basic11') | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd"> | -+-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| HTML 5 | doctype('html5') | <!DOCTYPE html> | -+-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| HTML 4 Strict | doctype('html4-strict') | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | -+-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| HTML 4 Transitional | doctype('html4-trans') | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | -+-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| HTML 4 Frameset | doctype('html4-frame') | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd"> | -+-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| MathML 1.01 | doctype('mathml1') | <!DOCTYPE math SYSTEM "http://www.w3.org/Math/DTD/mathml1/mathml.dtd"> | -+-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| MathML 2.0 | doctype('mathml2') | <!DOCTYPE math PUBLIC "-//W3C//DTD MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/mathml2.dtd"> | -+-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SVG 1.0 | doctype('svg10') | <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> | -+-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SVG 1.1 Full | doctype('svg11') | <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> | -+-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SVG 1.1 Basic | doctype('svg11-basic') | <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd"> | -+-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SVG 1.1 Tiny | doctype('svg11-tiny') | <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> | -+-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| XHTML+MathML+SVG (XHTML host) | doctype('xhtml-math-svg-xh') | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd"> | -+-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| XHTML+MathML+SVG (SVG host) | doctype('xhtml-math-svg-sh') | <!DOCTYPE svg:svg PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd"> | -+-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| XHTML+RDFa 1.0 | doctype('xhtml-rdfa-1') | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd"> | -+-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| XHTML+RDFa 1.1 | doctype('xhtml-rdfa-2') | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.1//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-2.dtd"> | -+-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
\ No newline at end of file + +.. function:: doctype([$type = 'xhtml1-strict']) + + :param string $type: Doctype name + :returns: HTML DocType tag + :rtype: string + + Helps you generate document type declarations, or DTD's. XHTML 1.0 + Strict is used by default, but many doctypes are available. + + Example:: + + echo doctype(); // <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + + echo doctype('html4-trans'); // <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> + + The following is a list of doctype choices. These are configurable, and + pulled from application/config/doctypes.php + + =============================== =================== ================================================================================================================================================== + Document type Option Result + =============================== =================== ================================================================================================================================================== + XHTML 1.1 xhtml11 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> + XHTML 1.0 Strict xhtml1-strict <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + XHTML 1.0 Transitional xhtml1-trans <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + XHTML 1.0 Frameset xhtml1-frame <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> + XHTML Basic 1.1 xhtml-basic11 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd"> + HTML 5 html5 <!DOCTYPE html> + HTML 4 Strict html4-strict <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> + HTML 4 Transitional html4-trans <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> + HTML 4 Frameset html4-frame <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd"> + MathML 1.01 mathml1 <!DOCTYPE math SYSTEM "http://www.w3.org/Math/DTD/mathml1/mathml.dtd"> + MathML 2.0 mathml2 <!DOCTYPE math PUBLIC "-//W3C//DTD MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/mathml2.dtd"> + SVG 1.0 svg10 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> + SVG 1.1 Full svg11 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> + SVG 1.1 Basic svg11-basic <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd"> + SVG 1.1 Tiny svg11-tiny <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> + XHTML+MathML+SVG (XHTML host) xhtml-math-svg-xh <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd"> + XHTML+MathML+SVG (SVG host) xhtml-math-svg-sh <!DOCTYPE svg:svg PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd"> + XHTML+RDFa 1.0 xhtml-rdfa-1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd"> + XHTML+RDFa 1.1 xhtml-rdfa-2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.1//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-2.dtd"> + =============================== =================== ==================================================================================================================================================
\ No newline at end of file diff --git a/user_guide_src/source/helpers/inflector_helper.rst b/user_guide_src/source/helpers/inflector_helper.rst index 1f54b76c0..d0cb17c18 100644 --- a/user_guide_src/source/helpers/inflector_helper.rst +++ b/user_guide_src/source/helpers/inflector_helper.rst @@ -5,7 +5,12 @@ Inflector Helper The Inflector Helper file contains functions that permits you to change words to plural, singular, camel case, etc. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== @@ -14,86 +19,78 @@ This helper is loaded using the following code:: $this->load->helper('inflector'); +Available Functions +=================== + The following functions are available: -singular() -========== -.. php:function:: singular($str) +.. function:: singular($str) :param string $str: Input string - :returns: string - -Changes a plural word to singular. Example:: + :returns: A singular word + :rtype: string - echo singular('dogs'); // Prints 'dog' + Changes a plural word to singular. Example:: -plural() -======== + echo singular('dogs'); // Prints 'dog' -.. php:function:: plural($str) +.. function:: plural($str) :param string $str: Input string - :returns: string + :returns: A plular word + :rtype: string -Changes a singular word to plural. Example:: + Changes a singular word to plural. Example:: - echo plural('dog'); // Prints 'dogs' + echo plural('dog'); // Prints 'dogs' -camelize() -========== - -.. php:function:: camelize($str) +.. function:: camelize($str) :param string $str: Input string - :returns: string - -Changes a string of words separated by spaces or underscores to camel -case. Example:: + :returns: Camelized string + :rtype: string - echo camelize('my_dog_spot'); // Prints 'myDogSpot' + Changes a string of words separated by spaces or underscores to camel + case. Example:: -underscore() -============ + echo camelize('my_dog_spot'); // Prints 'myDogSpot' -.. php:function:: camelize($str) +.. function:: underscore($str) :param string $str: Input string - :returns: string + :returns: String containing underscores instead of spaces + :rtype: string -Takes multiple words separated by spaces and underscores them. -Example:: + Takes multiple words separated by spaces and underscores them. + Example:: - echo underscore('my dog spot'); // Prints 'my_dog_spot' + echo underscore('my dog spot'); // Prints 'my_dog_spot' -humanize() -========== - -.. php:function:: camelize($str) +.. function:: humanize($str[, $separator = '_']) :param string $str: Input string :param string $separator: Input separator - :returns: string - -Takes multiple words separated by underscores and adds spaces between -them. Each word is capitalized. + :returns: Humanized string + :rtype: string -Example:: + Takes multiple words separated by underscores and adds spaces between + them. Each word is capitalized. - echo humanize('my_dog_spot'); // Prints 'My Dog Spot' + Example:: -To use dashes instead of underscores:: + echo humanize('my_dog_spot'); // Prints 'My Dog Spot' - echo humanize('my-dog-spot', '-'); // Prints 'My Dog Spot' + To use dashes instead of underscores:: -is_countable() -============== + echo humanize('my-dog-spot', '-'); // Prints 'My Dog Spot' -.. php:function:: is_countable($word) +.. function:: is_countable($word) :param string $word: Input string - :returns: bool + :returns: TRUE if the word is countable or FALSE if not + :rtype: bool -Checks if the given word has a plural version. Example:: + Checks if the given word has a plural version. Example:: - is_countable('equipment'); // Returns FALSE
\ No newline at end of file + is_countable('equipment'); // Returns FALSE
\ No newline at end of file diff --git a/user_guide_src/source/helpers/language_helper.rst b/user_guide_src/source/helpers/language_helper.rst index 1911e3bfd..e4d093725 100644 --- a/user_guide_src/source/helpers/language_helper.rst +++ b/user_guide_src/source/helpers/language_helper.rst @@ -5,7 +5,12 @@ Language Helper The Language Helper file contains functions that assist in working with language files. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== @@ -14,23 +19,25 @@ This helper is loaded using the following code:: $this->load->helper('language'); +Available Functions +=================== + The following functions are available: -lang() -====== -.. php:function:: lang($line, $for = '', $attributes = array()) +.. function:: lang($line[, $for = ''[, $attributes = array()]]) - :param string $line: Language line key - :param string $for: HTML "for" attribute (ID of the element we're creating a label for) - :param array $attributes: Any additional HTML attributes - :returns: string + :param string $line: Language line key + :param string $for: HTML "for" attribute (ID of the element we're creating a label for) + :param array $attributes: Any additional HTML attributes + :returns: HTML-formatted language line label + :rtype: string -This function returns a line of text from a loaded language file with -simplified syntax that may be more desirable for view files than -``CI_Lang::line()``. + This function returns a line of text from a loaded language file with + simplified syntax that may be more desirable for view files than + ``CI_Lang::line()``. -Example:: + Example:: - echo lang('language_key', 'form_item_id', array('class' => 'myClass'); - // Outputs: <label for="form_item_id" class="myClass">Language line</label>
\ No newline at end of file + echo lang('language_key', 'form_item_id', array('class' => 'myClass')); + // Outputs: <label for="form_item_id" class="myClass">Language line</label>
\ No newline at end of file diff --git a/user_guide_src/source/helpers/number_helper.rst b/user_guide_src/source/helpers/number_helper.rst index 8e0ebda5e..2de4457d9 100644 --- a/user_guide_src/source/helpers/number_helper.rst +++ b/user_guide_src/source/helpers/number_helper.rst @@ -5,7 +5,12 @@ Number Helper The Number Helper file contains functions that help you work with numeric data. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== @@ -14,32 +19,34 @@ This helper is loaded using the following code:: $this->load->helper('number'); +Available Functions +=================== + The following functions are available: -byte_format() -============= -.. php:function:: byte_format($num, $precision = 1) +.. function:: byte_format($num[, $precision = 1]) :param mixed $num: Number of bytes :param int $precision: Floating point precision - :returns: string - -Formats numbers as bytes, based on size, and adds the appropriate -suffix. Examples:: - - echo byte_format(456); // Returns 456 Bytes - echo byte_format(4567); // Returns 4.5 KB - echo byte_format(45678); // Returns 44.6 KB - echo byte_format(456789); // Returns 447.8 KB - echo byte_format(3456789); // Returns 3.3 MB - echo byte_format(12345678912345); // Returns 1.8 GB - echo byte_format(123456789123456789); // Returns 11,228.3 TB - -An optional second parameter allows you to set the precision of the -result:: - - echo byte_format(45678, 2); // Returns 44.61 KB - -.. note:: The text generated by this function is found in the following - language file: `language/<your_lang>/number_lang.php`
\ No newline at end of file + :returns: Formatted data size string + :rtype: string + + Formats numbers as bytes, based on size, and adds the appropriate + suffix. Examples:: + + echo byte_format(456); // Returns 456 Bytes + echo byte_format(4567); // Returns 4.5 KB + echo byte_format(45678); // Returns 44.6 KB + echo byte_format(456789); // Returns 447.8 KB + echo byte_format(3456789); // Returns 3.3 MB + echo byte_format(12345678912345); // Returns 1.8 GB + echo byte_format(123456789123456789); // Returns 11,228.3 TB + + An optional second parameter allows you to set the precision of the + result:: + + echo byte_format(45678, 2); // Returns 44.61 KB + + .. note:: The text generated by this function is found in the following + language file: *language/<your_lang>/number_lang.php*
\ No newline at end of file diff --git a/user_guide_src/source/helpers/path_helper.rst b/user_guide_src/source/helpers/path_helper.rst index 3a271b28f..705ca23b9 100644 --- a/user_guide_src/source/helpers/path_helper.rst +++ b/user_guide_src/source/helpers/path_helper.rst @@ -5,7 +5,12 @@ Path Helper The Path Helper file contains functions that permits you to work with file paths on the server. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== @@ -14,33 +19,35 @@ This helper is loaded using the following code:: $this->load->helper('path'); +Available Functions +=================== + The following functions are available: -set_realpath() -============== -.. php:function:: set_realpath($path, $check_existance = FALSE) +.. function:: set_realpath($path[, $check_existance = FALSE]) :param string $path: Path :param bool $check_existance: Whether to check if the path actually exists - :returns: string + :returns: An absolute path + :rtype: string + + This function will return a server path without symbolic links or + relative directory structures. An optional second argument will + cause an error to be triggered if the path cannot be resolved. -This function will return a server path without symbolic links or -relative directory structures. An optional second argument will -cause an error to be triggered if the path cannot be resolved. + Examples:: -Examples:: + $file = '/etc/php5/apache2/php.ini'; + echo set_realpath($file); // Prints '/etc/php5/apache2/php.ini' - $file = '/etc/php5/apache2/php.ini'; - echo set_realpath($file); // Prints '/etc/php5/apache2/php.ini' + $non_existent_file = '/path/to/non-exist-file.txt'; + echo set_realpath($non_existent_file, TRUE); // Shows an error, as the path cannot be resolved + echo set_realpath($non_existent_file, FALSE); // Prints '/path/to/non-exist-file.txt' - $non_existent_file = '/path/to/non-exist-file.txt'; - echo set_realpath($non_existent_file, TRUE); // Shows an error, as the path cannot be resolved - echo set_realpath($non_existent_file, FALSE); // Prints '/path/to/non-exist-file.txt' + $directory = '/etc/php5'; + echo set_realpath($directory); // Prints '/etc/php5/' - $directory = '/etc/php5'; - echo set_realpath($directory); // Prints '/etc/php5/' - - $non_existent_directory = '/path/to/nowhere'; - echo set_realpath($non_existent_directory, TRUE); // Shows an error, as the path cannot be resolved - echo set_realpath($non_existent_directory, FALSE); // Prints '/path/to/nowhere'
\ No newline at end of file + $non_existent_directory = '/path/to/nowhere'; + echo set_realpath($non_existent_directory, TRUE); // Shows an error, as the path cannot be resolved + echo set_realpath($non_existent_directory, FALSE); // Prints '/path/to/nowhere'
\ No newline at end of file diff --git a/user_guide_src/source/helpers/security_helper.rst b/user_guide_src/source/helpers/security_helper.rst index 21bf53490..2e26890b0 100644 --- a/user_guide_src/source/helpers/security_helper.rst +++ b/user_guide_src/source/helpers/security_helper.rst @@ -4,7 +4,12 @@ Security Helper The Security Helper file contains security related functions. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== @@ -13,92 +18,89 @@ This helper is loaded using the following code:: $this->load->helper('security'); +Available Functions +=================== + The following functions are available: -xss_clean() -=========== -.. php:function:: xss_clean($str, $is_image = FALSE) +.. function:: xss_clean($str[, $is_image = FALSE]) :param string $str: Input data :param bool $is_image: Whether we're dealing with an image - :returns: string + :returns: XSS-clean string + :rtype: string -Provides Cross Site Script Hack filtering. + Provides Cross Site Script Hack filtering. -This function is an alias for ``CI_Input::xss_clean()``. For more info, -please see the :doc:`Input Library <../libraries/input>` documentation. + This function is an alias for ``CI_Input::xss_clean()``. For more info, + please see the :doc:`Input Library <../libraries/input>` documentation. -sanitize_filename() -=================== - -.. php:function:: sanitize_filename($filename) +.. function:: sanitize_filename($filename) :param string $filename: Filename - :returns: string + :returns: Sanitized file name + :rtype: string -Provides protection against directory traversal. + Provides protection against directory traversal. -This function is an alias for ``CI_Security::sanitize_filename()``. -For more info, please see the :doc:`Security Library <../libraries/security>` -documentation. + This function is an alias for ``CI_Security::sanitize_filename()``. + For more info, please see the :doc:`Security Library <../libraries/security>` + documentation. -do_hash() -========= -.. php:function:: do_hash($str, $type = 'sha1') +.. function:: do_hash($str[, $type = 'sha1']) :param string $str: Input :param string $type: Algorithm - :returns: string + :returns: Hex-formatted hash + :rtype: string -Permits you to create one way hashes suitable for encrypting -passwords. Will use SHA1 by default. + Permits you to create one way hashes suitable for encrypting + passwords. Will use SHA1 by default. -See `hash_algos() <http://php.net/function.hash_algos>`_ -for a full list of supported algorithms. + See `hash_algos() <http://php.net/function.hash_algos>`_ + for a full list of supported algorithms. -Examples:: + Examples:: - $str = do_hash($str); // SHA1 - $str = do_hash($str, 'md5'); // MD5 + $str = do_hash($str); // SHA1 + $str = do_hash($str, 'md5'); // MD5 -.. note:: This function was formerly named ``dohash()``, which has been - removed in favor of ``do_hash()``. + .. note:: This function was formerly named ``dohash()``, which has been + removed in favor of ``do_hash()``. -.. note:: This function is DEPRECATED. Use the native ``hash()`` instead. + .. note:: This function is DEPRECATED. Use the native ``hash()`` instead. -strip_image_tags() -================== -.. php:function:: strip_image_tags($str) +.. function:: strip_image_tags($str) - :param string $str: Input - :returns: string + :param string $str: Input string + :returns: The input string with no image tags + :rtype: string -This is a security function that will strip image tags from a string. -It leaves the image URL as plain text. + This is a security function that will strip image tags from a string. + It leaves the image URL as plain text. -Example:: + Example:: - $string = strip_image_tags($string); + $string = strip_image_tags($string); -This function is an alias for ``CI_Security::strip_image_tags()``. For -more info, please see the :doc:`Security Library <../libraries/security>` -documentation. + This function is an alias for ``CI_Security::strip_image_tags()``. For + more info, please see the :doc:`Security Library <../libraries/security>` + documentation. -encode_php_tags() -================= -.. php:function:: encode_php_tags($str) +.. function:: encode_php_tags($str) - :param string $str: Input - :returns: string + :param string $str: Input string + :returns: Safely formatted string + :rtype: string -This is a security function that converts PHP tags to entities. + This is a security function that converts PHP tags to entities. -.. note: :php:func:`xss_clean()` does this automatically, if you use it. + .. note:: :func:`xss_clean()` does this automatically, if you use it. -Example:: + Example:: - $string = encode_php_tags($string);
\ No newline at end of file + $string = encode_php_tags($string);
\ No newline at end of file diff --git a/user_guide_src/source/helpers/smiley_helper.rst b/user_guide_src/source/helpers/smiley_helper.rst index cfd52ffbc..b98084089 100644 --- a/user_guide_src/source/helpers/smiley_helper.rst +++ b/user_guide_src/source/helpers/smiley_helper.rst @@ -5,7 +5,12 @@ Smiley Helper The Smiley Helper file contains functions that let you manage smileys (emoticons). -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== @@ -46,7 +51,7 @@ The Controller In your **application/controllers/** directory, create a file called Smileys.php and place the code below in it. -.. important:: Change the URL in the :php:func:`get_clickable_smileys()` +.. important:: Change the URL in the :func:`get_clickable_smileys()` function below so that it points to your smiley folder. You'll notice that in addition to the smiley helper, we are also using @@ -100,65 +105,62 @@ links a generic name that will be tied to a specific id in your view. $image_array = get_smiley_links("http://example.com/images/smileys/", "comment_textarea_alias"); To map the alias to the field id, pass them both into the -:php:func:`smiley_js()` function:: +:func:`smiley_js()` function:: $image_array = smiley_js("comment_textarea_alias", "comments"); -get_clickable_smileys() -======================= +Available Functions +=================== -.. php:function:: get_clickable_smileys($image_url, $alias = '', $smileys = NULL) +.. function:: get_clickable_smileys($image_url[, $alias = ''[, $smileys = NULL]]) :param string $image_url: URL path to the smileys directory :param string $alias: Field alias - :returns: array + :returns: An array of ready to use smileys + :rtype: array -Returns an array containing your smiley images wrapped in a clickable -link. You must supply the URL to your smiley folder and a field id or -field alias. + Returns an array containing your smiley images wrapped in a clickable + link. You must supply the URL to your smiley folder and a field id or + field alias. -Example:: + Example:: - $image_array = get_smiley_links("http://example.com/images/smileys/", "comment"); + $image_array = get_clickable_smileys('http://example.com/images/smileys/', 'comment'); -smiley_js() -=========== - -.. php:function:: smiley_js($alias = '', $field_id = '', $inline = TRUE) +.. function:: smiley_js([$alias = ''[, $field_id = ''[, $inline = TRUE]]]) :param string $alias: Field alias :param string $field_id: Field ID :param bool $inline: Whether we're inserting an inline smiley + :returns: Smiley-enabling JavaScript code + :rtype: string -Generates the JavaScript that allows the images to be clicked and -inserted into a form field. If you supplied an alias instead of an id -when generating your smiley links, you need to pass the alias and -corresponding form id into the function. This function is designed to be -placed into the <head> area of your web page. - -Example:: + Generates the JavaScript that allows the images to be clicked and + inserted into a form field. If you supplied an alias instead of an id + when generating your smiley links, you need to pass the alias and + corresponding form id into the function. This function is designed to be + placed into the <head> area of your web page. - <?php echo smiley_js(); ?> + Example:: -parse_smileys() -=============== + <?php echo smiley_js(); ?> -.. php:function:: parse_smileys($str = '', $image_url = '', $smileys = NULL) +.. function:: parse_smileys([$str = ''[, $image_url = ''[, $smileys = NULL]]]) :param string $str: Text containing smiley codes :param string $image_url: URL path to the smileys directory :param array $smileys: An array of smileys - :returns: string - -Takes a string of text as input and replaces any contained plain text -smileys into the image equivalent. The first parameter must contain your -string, the second must contain the URL to your smiley folder + :returns: Parsed smileys + :rtype: string -Example:: + Takes a string of text as input and replaces any contained plain text + smileys into the image equivalent. The first parameter must contain your + string, the second must contain the URL to your smiley folder - $str = 'Here are some smileys: :-) ;-)'; - $str = parse_smileys($str, "http://example.com/images/smileys/"); - echo $str; + Example:: + $str = 'Here are some smileys: :-) ;-)'; + $str = parse_smileys($str, 'http://example.com/images/smileys/'); + echo $str; .. |smile!| image:: ../images/smile.gif
\ No newline at end of file diff --git a/user_guide_src/source/helpers/string_helper.rst b/user_guide_src/source/helpers/string_helper.rst index d0d302476..922bc6b8d 100644 --- a/user_guide_src/source/helpers/string_helper.rst +++ b/user_guide_src/source/helpers/string_helper.rst @@ -5,7 +5,12 @@ String Helper The String Helper file contains functions that assist in working with strings. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== @@ -14,214 +19,202 @@ This helper is loaded using the following code:: $this->load->helper('string'); +Available Functions +=================== + The following functions are available: -random_string() -=============== -.. php:function:: random_string($type = 'alnum', $len = 8) +.. function:: random_string([$type = 'alnum'[, $len = 8]]) :param string $type: Randomization type :param int $len: Output string length - :returns: string - -Generates a random string based on the type and length you specify. -Useful for creating passwords or generating random hashes. + :returns: A random string + :rtype: string -The first parameter specifies the type of string, the second parameter -specifies the length. The following choices are available: + Generates a random string based on the type and length you specify. + Useful for creating passwords or generating random hashes. -- **alpha**: A string with lower and uppercase letters only. -- **alnum**: Alpha-numeric string with lower and uppercase characters. -- **basic**: A random number based on ``mt_rand()``. -- **numeric**: Numeric string. -- **nozero**: Numeric string with no zeros. -- **md5**: An encrypted random number based on ``md5()`` (fixed length of 32). -- **sha1**: An encrypted random number based on ``sha1()`` (fixed length of 40). + The first parameter specifies the type of string, the second parameter + specifies the length. The following choices are available: -Usage example:: + - **alpha**: A string with lower and uppercase letters only. + - **alnum**: Alpha-numeric string with lower and uppercase characters. + - **basic**: A random number based on ``mt_rand()``. + - **numeric**: Numeric string. + - **nozero**: Numeric string with no zeros. + - **md5**: An encrypted random number based on ``md5()`` (fixed length of 32). + - **sha1**: An encrypted random number based on ``sha1()`` (fixed length of 40). - echo random_string('alnum', 16); + Usage example:: -.. note:: Usage of the *unique* and *encrypt* types is DEPRECATED. They - are just aliases for *md5* and *sha1* respectively. + echo random_string('alnum', 16); -increment_string() -================== + .. note:: Usage of the *unique* and *encrypt* types is DEPRECATED. They + are just aliases for *md5* and *sha1* respectively. -.. php:function:: increment_string($str, $separator = '_', $first = 1) +.. function:: increment_string($str[, $separator = '_'[, $first = 1]]) :param string $str: Input string :param string $separator: Separator to append a duplicate number with :param int $first: Starting number - :returns: string + :returns: An incremented string + :rtype: string -Increments a string by appending a number to it or increasing the -number. Useful for creating "copies" or a file or duplicating database -content which has unique titles or slugs. + Increments a string by appending a number to it or increasing the + number. Useful for creating "copies" or a file or duplicating database + content which has unique titles or slugs. -Usage example:: + Usage example:: - echo increment_string('file', '_'); // "file_1" - echo increment_string('file', '-', 2); // "file-2" - echo increment_string('file_4'); // "file_5" + echo increment_string('file', '_'); // "file_1" + echo increment_string('file', '-', 2); // "file-2" + echo increment_string('file_4'); // "file_5" -alternator() -============ -.. php:function:: alternator($args) +.. function:: alternator($args) :param mixed $args: A variable number of arguments - :returns: mixed + :returns: Alternated string(s) + :rtype: mixed -Allows two or more items to be alternated between, when cycling through -a loop. Example:: + Allows two or more items to be alternated between, when cycling through + a loop. Example:: - for ($i = 0; $i < 10; $i++) - { Â Â Â Â - echo alternator('string one', 'string two'); - } + for ($i = 0; $i < 10; $i++) + { Â Â Â Â + echo alternator('string one', 'string two'); + } -You can add as many parameters as you want, and with each iteration of -your loop the next item will be returned. + You can add as many parameters as you want, and with each iteration of + your loop the next item will be returned. -:: + :: - for ($i = 0; $i < 10; $i++) - { Â Â Â Â - echo alternator('one', 'two', 'three', 'four', 'five'); - } + for ($i = 0; $i < 10; $i++) + { Â Â Â Â + echo alternator('one', 'two', 'three', 'four', 'five'); + } -.. note:: To use multiple separate calls to this function simply call the - function with no arguments to re-initialize. + .. note:: To use multiple separate calls to this function simply call the + function with no arguments to re-initialize. -repeater() -========== - -.. php:function:: repeater($data, $num = 1) +.. function:: repeater($data[, $num = 1]) :param string $data: Input :param int $num: Number of times to repeat - :returns: string + :returns: Repeated string + :rtype: string -Generates repeating copies of the data you submit. Example:: + Generates repeating copies of the data you submit. Example:: - $string = "\n"; - echo repeater($string, 30); + $string = "\n"; + echo repeater($string, 30); -The above would generate 30 newlines. + The above would generate 30 newlines. -.. note:: This function is DEPRECATED. Use the native ``str_repeat()`` - instead. + .. note:: This function is DEPRECATED. Use the native ``str_repeat()`` + instead. -reduce_double_slashes() -======================= -.. php:function:: reduce_double_slashes($str) +.. function:: reduce_double_slashes($str) :param string $str: Input string - :returns: string + :returns: A string with normalized slashes + :rtype: string -Converts double slashes in a string to a single slash, except those -found in URL protocol prefixes (e.g. http://). + Converts double slashes in a string to a single slash, except those + found in URL protocol prefixes (e.g. http://). -Example:: + Example:: - $string = "http://example.com//index.php"; - echo reduce_double_slashes($string); // results in "http://example.com/index.php" + $string = "http://example.com//index.php"; + echo reduce_double_slashes($string); // results in "http://example.com/index.php" -strip_slashes() -=============== -.. php:function:: strip_slashes($data) +.. function:: strip_slashes($data) - :param array $data: Input - :returns: array + :param mixed $data: Input string or an array of strings + :returns: String(s) with stripped slashes + :rtype: mixed -Removes any slashes from an array of strings. + Removes any slashes from an array of strings. -Example:: - - $str = array( - 'question'Â Â => 'Is your name O\'reilly?', - 'answer' => 'No, my name is O\'connor.' - ); - - $str = strip_slashes($str); - -The above will return the following array:: + Example:: - array( - 'question'Â Â => "Is your name O'reilly?", - 'answer' => "No, my name is O'connor." - ); + $str = array( + 'question'Â Â => 'Is your name O\'reilly?', + 'answer' => 'No, my name is O\'connor.' + ); -.. note:: For historical reasons, this function will also accept - and handle string inputs. This however makes it just an - alias for ``stripslashes()``. + $str = strip_slashes($str); -trim_slashes() -============== + The above will return the following array:: -.. php:function:: trim_slashes($str) + array( + 'question'Â Â => "Is your name O'reilly?", + 'answer' => "No, my name is O'connor." + ); - :param string $str: Input string - :returns: string + .. note:: For historical reasons, this function will also accept + and handle string inputs. This however makes it just an + alias for ``stripslashes()``. -Removes any leading/trailing slashes from a string. Example:: +.. function:: trim_slashes($str) - $string = "/this/that/theother/"; - echo trim_slashes($string); // results in this/that/theother + :param string $str: Input string + :returns: Slash-trimmed string + :rtype: string -.. note:: This function is DEPRECATED. Use the native ``trim()`` instead: - | - | trim($str, '/'); + Removes any leading/trailing slashes from a string. Example:: -reduce_multiples() -================== + $string = "/this/that/theother/"; + echo trim_slashes($string); // results in this/that/theother -.. php:function:: reduce_multiples($str, $character = '', $trim = FALSE) + .. note:: This function is DEPRECATED. Use the native ``trim()`` instead: + | + | trim($str, '/'); + +.. function:: reduce_multiples($str[, $character = ''[, $trim = FALSE]]) :param string $str: Text to search in :param string $character: Character to reduce :param bool $trim: Whether to also trim the specified character - :returns: string - -Reduces multiple instances of a particular character occuring directly -after each other. Example:: + :returns: Reduced string + :rtype: string - $string = "Fred, Bill,, Joe, Jimmy"; - $string = reduce_multiples($string,","); //results in "Fred, Bill, Joe, Jimmy" + Reduces multiple instances of a particular character occuring directly + after each other. Example:: -If the third parameter is set to TRUE it will remove occurences of the -character at the beginning and the end of the string. Example:: + $string = "Fred, Bill,, Joe, Jimmy"; + $string = reduce_multiples($string,","); //results in "Fred, Bill, Joe, Jimmy" - $string = ",Fred, Bill,, Joe, Jimmy,"; - $string = reduce_multiples($string, ", ", TRUE); //results in "Fred, Bill, Joe, Jimmy" + If the third parameter is set to TRUE it will remove occurrences of the + character at the beginning and the end of the string. Example:: -quotes_to_entities() -==================== + $string = ",Fred, Bill,, Joe, Jimmy,"; + $string = reduce_multiples($string, ", ", TRUE); //results in "Fred, Bill, Joe, Jimmy" -.. php:function:: quotes_to_entities($str) +.. function:: quotes_to_entities($str) :param string $str: Input string - :returns: string + :returns: String with quotes converted to HTML entities + :rtype: string -Converts single and double quotes in a string to the corresponding HTML -entities. Example:: + Converts single and double quotes in a string to the corresponding HTML + entities. Example:: - $string = "Joe's \"dinner\""; - $string = quotes_to_entities($string); //results in "Joe's "dinner"" + $string = "Joe's \"dinner\""; + $string = quotes_to_entities($string); //results in "Joe's "dinner"" -strip_quotes() -============== -.. php:function:: strip_quotes($str) +.. function:: strip_quotes($str) :param string $str: Input string - :returns: string + :returns: String with quotes stripped + :rtype: string -Removes single and double quotes from a string. Example:: + Removes single and double quotes from a string. Example:: - $string = "Joe's \"dinner\""; - $string = strip_quotes($string); //results in "Joes dinner"
\ No newline at end of file + $string = "Joe's \"dinner\""; + $string = strip_quotes($string); //results in "Joes dinner"
\ No newline at end of file diff --git a/user_guide_src/source/helpers/text_helper.rst b/user_guide_src/source/helpers/text_helper.rst index aec36c9a7..88a6d0658 100644 --- a/user_guide_src/source/helpers/text_helper.rst +++ b/user_guide_src/source/helpers/text_helper.rst @@ -5,7 +5,12 @@ Text Helper The Text Helper file contains functions that assist in working with text. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== @@ -14,216 +19,208 @@ This helper is loaded using the following code:: $this->load->helper('text'); -The following functions are available: +Available Functions +=================== -word_limiter() -============== +The following functions are available: -.. php:function:: word_limiter($str, $limit = 100, $end_char = '…') +.. function:: word_limiter($str[, $limit = 100[, $end_char = '…']]) :param string $str: Input string :param int $limit: Limit :param string $end_char: End character (usually an ellipsis) - :returns: string + :returns: Word-limited string + :rtype: string -Truncates a string to the number of *words* specified. Example:: + Truncates a string to the number of *words* specified. Example:: - $string = "Here is a nice text string consisting of eleven words."; - $string = word_limiter($string, 4); - // Returns: Here is a nice… + $string = "Here is a nice text string consisting of eleven words."; + $string = word_limiter($string, 4); + // Returns: Here is a nice -The third parameter is an optional suffix added to the string. By -default it adds an ellipsis. + The third parameter is an optional suffix added to the string. By + default it adds an ellipsis. -character_limiter() -=================== -.. php:function:: character_limiter($str, $n = 500, $end_char = '…') +.. function:: character_limiter($str[, $n = 500[, $end_char = '…']]) :param string $str: Input string :param int $n: Number of characters :param string $end_char: End character (usually an ellipsis) - :returns: string + :returns: Character-limited string + :rtype: string -Truncates a string to the number of *characters* specified. It -maintains the integrity of words so the character count may be slightly -more or less then what you specify. + Truncates a string to the number of *characters* specified. It + maintains the integrity of words so the character count may be slightly + more or less than what you specify. -Example:: + Example:: - $string = "Here is a nice text string consisting of eleven words."; - $string = character_limiter($string, 20); - // Returns: Here is a nice text string… + $string = "Here is a nice text string consisting of eleven words."; + $string = character_limiter($string, 20); + // Returns: Here is a nice text string -The third parameter is an optional suffix added to the string, if -undeclared this helper uses an ellipsis. + The third parameter is an optional suffix added to the string, if + undeclared this helper uses an ellipsis. -.. note:: If you need to truncate to an exact number of characters please - see the :ref:`ellipsize()` function below. - -ascii_to_entities() -=================== + .. note:: If you need to truncate to an exact number of characters please + see the :func:`ellipsize()` function below. -.. php:function:: ascii_to_entities($str) +.. function:: ascii_to_entities($str) :param string $str: Input string - :returns: string + :returns: A string with ASCII values converted to entities + :rtype: string -Converts ASCII values to character entities, including high ASCII and MS -Word characters that can cause problems when used in a web page, so that -they can be shown consistently regardless of browser settings or stored -reliably in a database. There is some dependence on your server's -supported character sets, so it may not be 100% reliable in all cases, -but for the most part it should correctly identify characters outside -the normal range (like accented characters). + Converts ASCII values to character entities, including high ASCII and MS + Word characters that can cause problems when used in a web page, so that + they can be shown consistently regardless of browser settings or stored + reliably in a database. There is some dependence on your server's + supported character sets, so it may not be 100% reliable in all cases, + but for the most part it should correctly identify characters outside + the normal range (like accented characters). -Example:: + Example:: - $string = ascii_to_entities($string); + $string = ascii_to_entities($string); -entities_to_ascii() -=================== - -.. php:function::entities_to_ascii($str, $all = TRUE) +.. function::entities_to_ascii($str[, $all = TRUE]) :param string $str: Input string :param bool $all: Whether to convert unsafe entities as well - :returns: string + :returns: A string with HTML entities converted to ASCII characters + :rtype: string -This function does the opposite of :php:func:`ascii_to_entities()`. -It turns character entities back into ASCII. + This function does the opposite of :func:`ascii_to_entities()`. + It turns character entities back into ASCII. -convert_accented_characters() -============================= - -.. php:function:: convert_accented_characters($str) +.. function:: convert_accented_characters($str) :param string $str: Input string - :returns: string - -Transliterates high ASCII characters to low ASCII equivalents. Useful -when non-English characters need to be used where only standard ASCII -characters are safely used, for instance, in URLs. + :returns: A string with accented characters converted + :rtype: string -Example:: + Transliterates high ASCII characters to low ASCII equivalents. Useful + when non-English characters need to be used where only standard ASCII + characters are safely used, for instance, in URLs. - $string = convert_accented_characters($string); + Example:: -.. note:: This function uses a companion config file - `application/config/foreign_chars.php` to define the to and - from array for transliteration. + $string = convert_accented_characters($string); -word_censor() -============= + .. note:: This function uses a companion config file + `application/config/foreign_chars.php` to define the to and + from array for transliteration. -.. php:function:: word_censor($str, $censored, $replacement = '') +.. function:: word_censor($str, $censored[, $replacement = '']) :param string $str: Input string :param array $censored: List of bad words to censor :param string $replacement: What to replace bad words with - :returns: string + :returns: Censored string + :rtype: string -Enables you to censor words within a text string. The first parameter -will contain the original string. The second will contain an array of -words which you disallow. The third (optional) parameter can contain -a replacement value for the words. If not specified they are replaced -with pound signs: ####. + Enables you to censor words within a text string. The first parameter + will contain the original string. The second will contain an array of + words which you disallow. The third (optional) parameter can contain + a replacement value for the words. If not specified they are replaced + with pound signs: ####. -Example:: + Example:: - $disallowed = array('darn', 'shucks', 'golly', 'phooey'); - $string = word_censor($string, $disallowed, 'Beep!'); + $disallowed = array('darn', 'shucks', 'golly', 'phooey'); + $string = word_censor($string, $disallowed, 'Beep!'); -highlight_code() -================ - -.. php:function:: highlight_code($str) +.. function:: highlight_code($str) :param string $str: Input string - :returns: string + :returns: String with code highlighted via HTML + :rtype: string -Colorizes a string of code (PHP, HTML, etc.). Example:: + Colorizes a string of code (PHP, HTML, etc.). Example:: - $string = highlight_code($string); + $string = highlight_code($string); -The function uses PHP's ``highlight_string()`` function, so the -colors used are the ones specified in your php.ini file. + The function uses PHP's ``highlight_string()`` function, so the + colors used are the ones specified in your php.ini file. -highlight_phrase() -================== -.. php:function:: highlight_phrase($str, $phrase, $tag_open = '<strong>', $tag_close = '</strong>') +.. function:: highlight_phrase($str, $phrase[, $tag_open = '<mark>'[, $tag_close = '</mark>']]) :param string $str: Input string :param string $phrase: Phrase to highlight :param string $tag_open: Opening tag used for the highlight :param string $tag_close: Closing tag for the highlight - :returns: string + :returns: String with a phrase highlighted via HTML + :rtype: string + + Will highlight a phrase within a text string. The first parameter will + contain the original string, the second will contain the phrase you wish + to highlight. The third and fourth parameters will contain the + opening/closing HTML tags you would like the phrase wrapped in. -Will highlight a phrase within a text string. The first parameter will -contain the original string, the second will contain the phrase you wish -to highlight. The third and fourth parameters will contain the -opening/closing HTML tags you would like the phrase wrapped in. + Example:: -Example:: + $string = "Here is a nice text string about nothing in particular."; + echo highlight_phrase($string, "nice text", '<span style="color:#990000;">', '</span>'); - $string = "Here is a nice text string about nothing in particular."; - echo highlight_phrase($string, "nice text", '<span style="color:#990000;">', '</span>'); + The above code prints:: -The above code prints:: + Here is a <span style="color:#990000;">nice text</span> string about nothing in particular. - Here is a <span style="color:#990000;">nice text</span> string about nothing in particular. + .. note:: This function used to use the ``<strong>`` tag by default. Older browsers + might not support the new HTML5 mark tag, so it is recommended that you + insert the following CSS code into your stylesheet if you need to support + such browsers:: -word_wrap() -=========== + mark { + background: #ff0; + color: #000; + }; -.. php:function:: word_wrap($str, $charlim = 76) +.. function:: word_wrap($str[, $charlim = 76]) :param string $str: Input string :param int $charlim: Character limit - :returns: string - -Wraps text at the specified *character* count while maintaining -complete words. - -Example:: + :returns: Word-wrapped string + :rtype: string - $string = "Here is a simple string of text that will help us demonstrate this function."; - echo word_wrap($string, 25); + Wraps text at the specified *character* count while maintaining + complete words. - // Would produce: Here is a simple string of text that will help us demonstrate this function + Example:: -.. _ellipsize(): + $string = "Here is a simple string of text that will help us demonstrate this function."; + echo word_wrap($string, 25); -ellipsize() -=========== + // Would produce: Here is a simple string of text that will help us demonstrate this function -.. php:function:: ellipsize($str, $max_length, $position = 1, $ellipsis = '…') +.. function:: ellipsize($str, $max_length[, $position = 1[, $ellipsis = '…']]) :param string $str: Input string :param int $max_length: String length limit - :param mixed $position: Position to split at - (int or float) + :param mixed $position: Position to split at (int or float) :param string $ellipsis: What to use as the ellipsis character - :returns: string + :returns: Ellipsized string + :rtype: string -This function will strip tags from a string, split it at a defined -maximum length, and insert an ellipsis. + This function will strip tags from a string, split it at a defined + maximum length, and insert an ellipsis. -The first parameter is the string to ellipsize, the second is the number -of characters in the final string. The third parameter is where in the -string the ellipsis should appear from 0 - 1, left to right. For -example. a value of 1 will place the ellipsis at the right of the -string, .5 in the middle, and 0 at the left. + The first parameter is the string to ellipsize, the second is the number + of characters in the final string. The third parameter is where in the + string the ellipsis should appear from 0 - 1, left to right. For + example. a value of 1 will place the ellipsis at the right of the + string, .5 in the middle, and 0 at the left. -An optional forth parameter is the kind of ellipsis. By default, -… will be inserted. + An optional forth parameter is the kind of ellipsis. By default, + … will be inserted. -Example:: + Example:: - $str = 'this_string_is_entirely_too_long_and_might_break_my_design.jpg'; - echo ellipsize($str, 32, .5); + $str = 'this_string_is_entirely_too_long_and_might_break_my_design.jpg'; + echo ellipsize($str, 32, .5); -Produces:: + Produces:: - this_string_is_e…ak_my_design.jpg
\ No newline at end of file + this_string_is_e…ak_my_design.jpg
\ No newline at end of file diff --git a/user_guide_src/source/helpers/typography_helper.rst b/user_guide_src/source/helpers/typography_helper.rst index 3c81687ac..deb3d164e 100644 --- a/user_guide_src/source/helpers/typography_helper.rst +++ b/user_guide_src/source/helpers/typography_helper.rst @@ -5,7 +5,12 @@ Typography Helper The Typography Helper file contains functions that help your format text in semantically relevant ways. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== @@ -14,58 +19,57 @@ This helper is loaded using the following code:: $this->load->helper('typography'); +Available Functions +=================== + The following functions are available: -auto_typography() -================= -.. php:function:: auto_typography($str, $reduce_linebreaks = FALSE) +.. function:: auto_typography($str[, $reduce_linebreaks = FALSE]) :param string $str: Input string :param bool $reduce_linebreaks: Whether to reduce multiple instances of double newlines to two - :returns: string + :returns: HTML-formatted typography-safe string + :rtype: string -Formats text so that it is semantically and typographically correct -HTML. + Formats text so that it is semantically and typographically correct + HTML. -This function is an alias for ``CI_Typography::auto_typography``. -For more info, please see the :doc:`Typography Library -<../libraries/typography>` documentation. + This function is an alias for ``CI_Typography::auto_typography``. + For more info, please see the :doc:`Typography Library + <../libraries/typography>` documentation. -Usage example:: + Usage example:: - $string = auto_typography($string); + $string = auto_typography($string); -.. note:: Typographic formatting can be processor intensive, particularly if - you have a lot of content being formatted. If you choose to use this - function you may want to consider `caching <../general/caching>` your - pages. + .. note:: Typographic formatting can be processor intensive, particularly if + you have a lot of content being formatted. If you choose to use this + function you may want to consider `caching <../general/caching>` your + pages. -nl2br_except_pre() -================== -.. php:function:: nl2br_except_pre($str) +.. function:: nl2br_except_pre($str) :param string $str: Input string - :returns: string - -Converts newlines to <br /> tags unless they appear within <pre> tags. -This function is identical to the native PHP ``nl2br()`` function, -except that it ignores <pre> tags. + :returns: String with HTML-formatted line breaks + :rtype: string -Usage example:: + Converts newlines to <br /> tags unless they appear within <pre> tags. + This function is identical to the native PHP ``nl2br()`` function, + except that it ignores <pre> tags. - $string = nl2br_except_pre($string); + Usage example:: -entity_decode() -=============== + $string = nl2br_except_pre($string); -.. php:function:: entity_decode($str, $charset = NULL) +.. function:: entity_decode($str, $charset = NULL) :param string $str: Input string :param string $charset: Character set - :returns: string + :returns: String with decoded HTML entities + :rtype: string -This function is an alias for ``CI_Security::entity_decode()``. -Fore more info, please see the :doc:`Security Library -<../libraries/security>` documentation.
\ No newline at end of file + This function is an alias for ``CI_Security::entity_decode()``. + Fore more info, please see the :doc:`Security Library + <../libraries/security>` documentation.
\ No newline at end of file diff --git a/user_guide_src/source/helpers/url_helper.rst b/user_guide_src/source/helpers/url_helper.rst index 7a49f188d..3bdcb8e17 100644 --- a/user_guide_src/source/helpers/url_helper.rst +++ b/user_guide_src/source/helpers/url_helper.rst @@ -4,7 +4,12 @@ URL Helper The URL Helper file contains functions that assist in working with URLs. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== @@ -15,371 +20,354 @@ This helper is loaded using the following code:: The following functions are available: -site_url() -========== +Available Functions +=================== -.. php:function:: site_url($uri = '', $protocol = NULL) +.. function:: site_url([$uri = ''[, $protocol = NULL]]) :param string $uri: URI string :param string $protocol: Protocol, e.g. 'http' or 'https' - :returns: string - -Returns your site URL, as specified in your config file. The index.php -file (or whatever you have set as your site **index_page** in your config -file) will be added to the URL, as will any URI segments you pass to the -function, plus the **url_suffix** as set in your config file. + :returns: Site URL + :rtype: string -You are encouraged to use this function any time you need to generate a -local URL so that your pages become more portable in the event your URL -changes. + Returns your site URL, as specified in your config file. The index.php + file (or whatever you have set as your site **index_page** in your config + file) will be added to the URL, as will any URI segments you pass to the + function, plus the **url_suffix** as set in your config file. -Segments can be optionally passed to the function as a string or an -array. Here is a string example:: + You are encouraged to use this function any time you need to generate a + local URL so that your pages become more portable in the event your URL + changes. - echo site_url('news/local/123'); + Segments can be optionally passed to the function as a string or an + array. Here is a string example:: -The above example would return something like: -*http://example.com/index.php/news/local/123* + echo site_url('news/local/123'); -Here is an example of segments passed as an array:: + The above example would return something like: + *http://example.com/index.php/news/local/123* - $segments = array('news', 'local', '123'); - echo site_url($segments); + Here is an example of segments passed as an array:: -This function is an alias for ``CI_Config::site_url()``. For more info, -please see the :doc:`Config Library <../libraries/config>` documentation. + $segments = array('news', 'local', '123'); + echo site_url($segments); -base_url() -=========== + This function is an alias for ``CI_Config::site_url()``. For more info, + please see the :doc:`Config Library <../libraries/config>` documentation. -.. php:function:: base_url($uri = '', $protocol = NULL) +.. function:: base_url($uri = '', $protocol = NULL) :param string $uri: URI string :param string $protocol: Protocol, e.g. 'http' or 'https' - :returns: string + :returns: Base URL + :rtype: string -Returns your site base URL, as specified in your config file. Example:: + Returns your site base URL, as specified in your config file. Example:: - echo base_url(); + echo base_url(); -This function returns the same thing as :php:func:`site_url()`, without -the *index_page* or *url_suffix* being appended. + This function returns the same thing as :func:`site_url()`, without + the *index_page* or *url_suffix* being appended. -Also like :php:func:`site_url()`, you can supply segments as a string or -an array. Here is a string example:: + Also like :func:`site_url()`, you can supply segments as a string or + an array. Here is a string example:: - echo base_url("blog/post/123"); + echo base_url("blog/post/123"); -The above example would return something like: -*http://example.com/blog/post/123* + The above example would return something like: + *http://example.com/blog/post/123* -This is useful because unlike :php:func:`site_url()`, you can supply a -string to a file, such as an image or stylesheet. For example:: + This is useful because unlike :func:`site_url()`, you can supply a + string to a file, such as an image or stylesheet. For example:: - echo base_url("images/icons/edit.png"); + echo base_url("images/icons/edit.png"); -This would give you something like: -*http://example.com/images/icons/edit.png* + This would give you something like: + *http://example.com/images/icons/edit.png* -This function is an alias for ``CI_Config::base_url()``. For more info, -please see the :doc:`Config Library <../libraries/config>` documentation. + This function is an alias for ``CI_Config::base_url()``. For more info, + please see the :doc:`Config Library <../libraries/config>` documentation. -current_url() -============= +.. function:: current_url() -.. php:function:: current_url() + :returns: The current URL + :rtype: string - :returns: string + Returns the full URL (including segments) of the page being currently + viewed. -Returns the full URL (including segments) of the page being currently -viewed. + .. note:: Calling this function is the same as doing this: + | + | site_url(uri_string()); -.. note:: Calling this function is the same as doing this: - | - | site_url(uri_string()); -uri_string() -============ +.. function:: uri_string() -.. php:function:: uri_string() + :returns: An URI string + :rtype: string - :returns: string + Returns the URI segments of any page that contains this function. + For example, if your URL was this:: -Returns the URI segments of any page that contains this function. -For example, if your URL was this:: + http://some-site.com/blog/comments/123 - http://some-site.com/blog/comments/123 + The function would return:: -The function would return:: + blog/comments/123 - blog/comments/123 + This function is an alias for ``CI_Config::uri_string()``. For more info, + please see the :doc:`Config Library <../libraries/config>` documentation. -This function is an alias for ``CI_Config::uri_string()``. For more info, -please see the :doc:`Config Library <../libraries/config>` documentation. -index_page() -============ +.. function:: index_page() -.. php:function:: index_page() + :returns: 'index_page' value + :rtype: mixed - :returns: string + Returns your site **index_page**, as specified in your config file. + Example:: -Returns your site **index_page**, as specified in your config file. -Example:: + echo index_page(); - echo index_page(); - -anchor() -======== - -.. php:function:: anchor($uri = '', $title = '', $attributes = '') +.. function:: anchor($uri = '', $title = '', $attributes = '') :param string $uri: URI string :param string $title: Anchor title :param mixed $attributes: HTML attributes - :returns: string + :returns: HTML hyperlink (anchor tag) + :rtype: string -Creates a standard HTML anchor link based on your local site URL. + Creates a standard HTML anchor link based on your local site URL. -The first parameter can contain any segments you wish appended to the -URL. As with the :php:func:`site_url()` function above, segments can -be a string or an array. + The first parameter can contain any segments you wish appended to the + URL. As with the :func:`site_url()` function above, segments can + be a string or an array. -.. note:: If you are building links that are internal to your application - do not include the base URL (http://...). This will be added - automatically from the information specified in your config file. - Include only the URI segments you wish appended to the URL. + .. note:: If you are building links that are internal to your application + do not include the base URL (http://...). This will be added + automatically from the information specified in your config file. + Include only the URI segments you wish appended to the URL. -The second segment is the text you would like the link to say. If you -leave it blank, the URL will be used. + The second segment is the text you would like the link to say. If you + leave it blank, the URL will be used. -The third parameter can contain a list of attributes you would like -added to the link. The attributes can be a simple string or an -associative array. + The third parameter can contain a list of attributes you would like + added to the link. The attributes can be a simple string or an + associative array. -Here are some examples:: + Here are some examples:: - echo anchor('news/local/123', 'My News', 'title="News title"'); - // Prints: <a href="http://example.com/index.php/news/local/123" title="News title">My News</a> + echo anchor('news/local/123', 'My News', 'title="News title"'); + // Prints: <a href="http://example.com/index.php/news/local/123" title="News title">My News</a> - echo anchor('news/local/123', 'My News', array('title' => 'The best news!')); - // Prints: <a href="http://example.com/index.php/news/local/123" title="The best news!">My News</a> + echo anchor('news/local/123', 'My News', array('title' => 'The best news!')); + // Prints: <a href="http://example.com/index.php/news/local/123" title="The best news!">My News</a> - echo anchor('', 'Click here'); - // Prints: <a href="http://example.com">Click Here</a> + echo anchor('', 'Click here'); + // Prints: <a href="http://example.com">Click Here</a> -anchor_popup() -============== -.. php:function:: anchor_popup($uri = '', $title = '', $attributes = FALSE) +.. function:: anchor_popup($uri = '', $title = '', $attributes = FALSE) :param string $uri: URI string :param string $title: Anchor title :param mixed $attributes: HTML attributes - :returns: string + :returns: Pop-up hyperlink + :rtype: string -Nearly identical to the :php:func:``anchor()`` function except that it -opens the URL in a new window. You can specify JavaScript window -attributes in the third parameter to control how the window is opened. -If the third parameter is not set it will simply open a new window with -your own browser settings. + Nearly identical to the :func:`anchor()` function except that it + opens the URL in a new window. You can specify JavaScript window + attributes in the third parameter to control how the window is opened. + If the third parameter is not set it will simply open a new window with + your own browser settings. -Here is an example with attributes:: + Here is an example with attributes:: - $atts = array( - 'width' => 800, - 'height' => 600, - 'scrollbars' => 'yes', - 'status'Â Â Â Â Â => 'yes', - 'resizable'Â Â => 'yes', - 'screenx' => 0, - 'screeny' => 0, - 'window_name' => '_blank' - ); + $atts = array( + 'width' => 800, + 'height' => 600, + 'scrollbars' => 'yes', + 'status'Â Â Â Â Â => 'yes', + 'resizable'Â Â => 'yes', + 'screenx' => 0, + 'screeny' => 0, + 'window_name' => '_blank' + ); - echo anchor_popup('news/local/123', 'Click Me!', $atts); + echo anchor_popup('news/local/123', 'Click Me!', $atts); -.. note:: The above attributes are the function defaults so you only need to - set the ones that are different from what you need. If you want the - function to use all of its defaults simply pass an empty array in the - third parameter: - | - | echo anchor_popup('news/local/123', 'Click Me!', array()); + .. note:: The above attributes are the function defaults so you only need to + set the ones that are different from what you need. If you want the + function to use all of its defaults simply pass an empty array in the + third parameter: + | + | echo anchor_popup('news/local/123', 'Click Me!', array()); -.. note:: The **window_name** is not really an attribute, but an argument to - the JavaScript `window.open() <http://www.w3schools.com/jsref/met_win_open.asp>` - method, which accepts either a window name or a window target. + .. note:: The **window_name** is not really an attribute, but an argument to + the JavaScript `window.open() <http://www.w3schools.com/jsref/met_win_open.asp>` + method, which accepts either a window name or a window target. -.. note:: Any other attribute than the listed above will be parsed as an - HTML attribute to the anchor tag. + .. note:: Any other attribute than the listed above will be parsed as an + HTML attribute to the anchor tag. -mailto() -======== -.. php:function:: mailto($email, $title = '', $attributes = '') +.. function:: mailto($email, $title = '', $attributes = '') :param string $email: E-mail address :param string $title: Anchor title :param mixed $attributes: HTML attributes - :returns: string + :returns: A "mail to" hyperlink + :rtype: string -Creates a standard HTML e-mail link. Usage example:: + Creates a standard HTML e-mail link. Usage example:: - echo mailto('me@my-site.com', 'Click Here to Contact Me'); + echo mailto('me@my-site.com', 'Click Here to Contact Me'); -As with the :php:func:`anchor()` tab above, you can set attributes using the -third parameter:: + As with the :func:`anchor()` tab above, you can set attributes using the + third parameter:: - $attributes = array('title' => 'Mail me'); - echo mailto('me@my-site.com', 'Contact Me', $attributes); + $attributes = array('title' => 'Mail me'); + echo mailto('me@my-site.com', 'Contact Me', $attributes); -safe_mailto() -============= - -.. php:function:: safe_mailto($email, $title = '', $attributes = '') +.. function:: safe_mailto($email, $title = '', $attributes = '') :param string $email: E-mail address :param string $title: Anchor title :param mixed $attributes: HTML attributes - :returns: string - -Identical to the :php:func:`mailto()` function except it writes an obfuscated -version of the *mailto* tag using ordinal numbers written with JavaScript to -help prevent the e-mail address from being harvested by spam bots. + :returns: A spam-safe "mail to" hyperlink + :rtype: string -auto_link() -=========== + Identical to the :func:`mailto()` function except it writes an obfuscated + version of the *mailto* tag using ordinal numbers written with JavaScript to + help prevent the e-mail address from being harvested by spam bots. -.. php:function:: auto_link($str, $type = 'both', $popup = FALSE) +.. function:: auto_link($str, $type = 'both', $popup = FALSE) :param string $str: Input string :param string $type: Link type ('email', 'url' or 'both') :param bool $popup: Whether to create popup links - :returns: string + :returns: Linkified string + :rtype: string -Automatically turns URLs and e-mail addresses contained in a string into -links. Example:: + Automatically turns URLs and e-mail addresses contained in a string into + links. Example:: - $string = auto_link($string); + $string = auto_link($string); -The second parameter determines whether URLs and e-mails are converted or -just one or the other. Default behavior is both if the parameter is not -specified. E-mail links are encoded as :php:func:`safe_mailto()` as shown -above. + The second parameter determines whether URLs and e-mails are converted or + just one or the other. Default behavior is both if the parameter is not + specified. E-mail links are encoded as :func:`safe_mailto()` as shown + above. -Converts only URLs:: + Converts only URLs:: - $string = auto_link($string, 'url'); + $string = auto_link($string, 'url'); -Converts only e-mail addresses:: + Converts only e-mail addresses:: - $string = auto_link($string, 'email'); + $string = auto_link($string, 'email'); -The third parameter determines whether links are shown in a new window. -The value can be TRUE or FALSE (boolean):: + The third parameter determines whether links are shown in a new window. + The value can be TRUE or FALSE (boolean):: - $string = auto_link($string, 'both', TRUE); + $string = auto_link($string, 'both', TRUE); -url_title() -=========== -.. php:function:: url_title($str, $separator = '-', $lowercase = FALSE) +.. function:: url_title($str, $separator = '-', $lowercase = FALSE) :param string $str: Input string :param string $separator: Word separator :param string $lowercase: Whether to transform the output string to lower-case - :returns: string + :returns: URL-formatted string + :rtype: string -Takes a string as input and creates a human-friendly URL string. This is -useful if, for example, you have a blog in which you'd like to use the -title of your entries in the URL. Example:: + Takes a string as input and creates a human-friendly URL string. This is + useful if, for example, you have a blog in which you'd like to use the + title of your entries in the URL. Example:: - $title = "What's wrong with CSS?"; - $url_title = url_title($title); - // Produces: Whats-wrong-with-CSS + $title = "What's wrong with CSS?"; + $url_title = url_title($title); + // Produces: Whats-wrong-with-CSS -The second parameter determines the word delimiter. By default dashes -are used. Preferred options are: **-** (dash) or **_** (underscore) + The second parameter determines the word delimiter. By default dashes + are used. Preferred options are: **-** (dash) or **_** (underscore) -Example:: + Example:: - $title = "What's wrong with CSS?"; - $url_title = url_title($title, 'underscore'); - // Produces: Whats_wrong_with_CSS + $title = "What's wrong with CSS?"; + $url_title = url_title($title, 'underscore'); + // Produces: Whats_wrong_with_CSS -.. note:: Old usage of 'dash' and 'underscore' as the second parameter - is DEPRECATED. + .. note:: Old usage of 'dash' and 'underscore' as the second parameter + is DEPRECATED. -The third parameter determines whether or not lowercase characters are -forced. By default they are not. Options are boolean TRUE/FALSE. + The third parameter determines whether or not lowercase characters are + forced. By default they are not. Options are boolean TRUE/FALSE. -Example:: + Example:: - $title = "What's wrong with CSS?"; - $url_title = url_title($title, 'underscore', TRUE); - // Produces: whats_wrong_with_css + $title = "What's wrong with CSS?"; + $url_title = url_title($title, 'underscore', TRUE); + // Produces: whats_wrong_with_css -prep_url() ----------- -.. php:function:: prep_url($str = '') +.. function:: prep_url($str = '') :param string $str: URL string - :returns: string + :returns: Protocol-prefixed URL string + :rtype: string -This function will add http:// in the event that a protocol prefix -is missing from a URL. + This function will add http:// in the event that a protocol prefix + is missing from a URL. -Pass the URL string to the function like this:: + Pass the URL string to the function like this:: - $url = prep_url('example.com'); + $url = prep_url('example.com'); -redirect() -========== -.. php:function:: redirect($uri = '', $method = 'auto', $code = NULL) +.. function:: redirect($uri = '', $method = 'auto', $code = NULL) :param string $uri: URI string :param string $method: Redirect method ('auto', 'location' or 'refresh') :param string $code: HTTP Response code (usually 302 or 303) - :returns: void + :rtype: void -Does a "header redirect" to the URI specified. If you specify the full -site URL that link will be built, but for local links simply providing -the URI segments to the controller you want to direct to will create the -link. The function will build the URL based on your config file values. + Does a "header redirect" to the URI specified. If you specify the full + site URL that link will be built, but for local links simply providing + the URI segments to the controller you want to direct to will create the + 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 **auto**, **location** and **refresh**, -with location 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. + The optional second parameter allows you to force a particular redirection + method. The available methods are **auto**, **location** and **refresh**, + with location 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. -The optional third parameter allows you to send a specific HTTP Response -Code - this could be used for example to create 301 redirects for search -engine purposes. The default Response Code is 302. The third parameter is -*only* available with **location** redirects, and not *refresh*. Examples:: + The optional third parameter allows you to send a specific HTTP Response + Code - this could be used for example to create 301 redirects for search + engine purposes. The default Response Code is 302. The third parameter is + *only* available with **location** redirects, and not *refresh*. Examples:: - if ($logged_in == FALSE) - { Â Â Â Â Â - redirect('/login/form/'); - } + if ($logged_in == FALSE) + { Â Â Â Â Â + redirect('/login/form/'); + } - // with 301 redirect - redirect('/article/13', 'location', 301); + // with 301 redirect + redirect('/article/13', 'location', 301); -.. note:: In order for this function to work it must be used before anything - is outputted to the browser since it utilizes server headers. + .. note:: In order for this function to work it must be used before anything + is outputted to the browser since it utilizes server headers. -.. note:: For very fine grained control over headers, you should use the - `Output Library </libraries/output>` ``set_header()`` method. + .. note:: For very fine grained control over headers, you should use the + `Output Library </libraries/output>` ``set_header()`` method. -.. 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. + .. 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. -.. note:: When the **location** method is used, an HTTP status code of 303 - will *automatically* be selected when the page is currently accessed - via POST and HTTP/1.1 is used. + .. note:: When the **location** method is used, an HTTP status code of 303 + will *automatically* be selected when the page is currently accessed + via POST and HTTP/1.1 is used. -.. important:: This function will terminate script execution.
\ No newline at end of file + .. important:: This function will terminate script execution.
\ No newline at end of file diff --git a/user_guide_src/source/helpers/xml_helper.rst b/user_guide_src/source/helpers/xml_helper.rst index be848bcd1..a40ea9ad3 100644 --- a/user_guide_src/source/helpers/xml_helper.rst +++ b/user_guide_src/source/helpers/xml_helper.rst @@ -5,7 +5,12 @@ XML Helper The XML Helper file contains functions that assist in working with XML data. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> Loading this Helper =================== @@ -16,23 +21,35 @@ This helper is loaded using the following code $this->load->helper('xml'); +Available Functions +=================== + The following functions are available: -xml_convert() -===================== +.. function:: xml_convert($str[, $protect_all = FALSE]) -Takes a string as input and converts the following reserved XML -characters to entities: + :param string $str: the text string to convert + :param bool $protect_all: Whether to protect all content that looks like a potential entity instead of just numbered entities, e.g. &foo; + :returns: XML-converted string + :rtype: string -- Ampersands: & -- Less then and greater than characters: < > -- Single and double quotes: ' " -- Dashes: - + Takes a string as input and converts the following reserved XML + characters to entities: -This function ignores ampersands if they are part of existing character -entities. Example + - Ampersands: & + - Less than and greater than characters: < > + - Single and double quotes: ' " + - Dashes: - -:: + This function ignores ampersands if they are part of existing numbered + character entities, e.g. {. Example:: + + $string = '<p>Here is a paragraph & an entity ({).</p>'; + $string = xml_convert($string); + echo $string; + + outputs: - $string = xml_convert($string); + .. code-block:: html + <p>Here is a paragraph & an entity ({).</p>
\ No newline at end of file diff --git a/user_guide_src/source/installation/upgrade_200.rst b/user_guide_src/source/installation/upgrade_200.rst index 29f44bd9e..948b1bc58 100644 --- a/user_guide_src/source/installation/upgrade_200.rst +++ b/user_guide_src/source/installation/upgrade_200.rst @@ -50,11 +50,11 @@ to :: Step 4: Update stored encrypted data ==================================== -.. note:: If your application does not use the Encryption library, does +.. note:: If your application does not use the Encrypt library, does not store Encrypted data permanently, or is on an environment that does not support Mcrypt, you may skip this step. -The Encryption library has had a number of improvements, some for +The Encrypt library has had a number of improvements, some for encryption strength and some for performance, that has an unavoidable consequence of making it no longer possible to decode encrypted data produced by the original version of this library. To help with the @@ -65,7 +65,7 @@ replace stale encrypted data with fresh in your applications, either on the fly or en masse. Please read `how to use this -method <../libraries/encryption.html#legacy>`_ in the Encryption library +method <../libraries/encrypt.html#legacy>`_ in the Encrypt library documentation. Step 5: Remove loading calls for the compatibility helper. diff --git a/user_guide_src/source/installation/upgrade_300.rst b/user_guide_src/source/installation/upgrade_300.rst index e8fdd0b15..59df7c303 100644 --- a/user_guide_src/source/installation/upgrade_300.rst +++ b/user_guide_src/source/installation/upgrade_300.rst @@ -119,11 +119,18 @@ need to rename the `$active_record` variable to `$query_builder` // $active_record = TRUE; $query_builder = TRUE; -******************************************* -Step 8: Move your error templates directory -******************************************* +************************************ +Step 8: Replace your error templates +************************************ -In version 3.0.0, the errors folder has been moved from _application/errors* to _application/views/errors*. +In CodeIgniter 3.0, the error templates are now considered as views and have been moved to the +_application/views/errors* directory. + +Furthermore, we've added support for CLI error templates in plain-text format that unlike HTML, +is suitable for the command line. This of course requires another level of separation. + +It is safe to move your old templates from _application/errors* to _application/views/errors/html*, +but you'll have to copy the new _application/views/errors/cli* directory from the CodeIgniter archive. ******************************************************* Step 9: Update your config/routes.php containing (:any) @@ -181,8 +188,39 @@ Many methods and functions now return NULL instead of FALSE when the required it - element() - elements() +******************************* +Step 11: Usage of XSS filtering +******************************* + +Many functions in CodeIgniter allow you to use its XSS filtering feature +on demand by passing a boolean parameter. The default value of that +parameter used to be boolean FALSE, but it is now changed to NULL and it +will be dynamically determined by your ``$config['global_xss_filtering']`` +value. + +If you used to manually pass a boolean value for the ``$xss_filter`` +parameter or if you've always had ``$config['global_xss_filtering']`` set +to FALSE, then this change doesn't concern you. + +Otherwise however, please review your usage of the following functions: + + - :doc:`Input Library <../libraries/input>` + + - input->get() + - input->post() + - input->get_post() + - input->cookie() + - input->server() + - input->input_stream() + + - :doc:`Cookie Helper <../helpers/cookie_helper>` :func:`get_cookie()` + +.. important:: Another related change is that the ``$_GET``, ``$_POST``, + ``$_COOKIE`` and ``$_SERVER`` superglobals are no longer + automatically overwritten when global XSS filtering is turned on. + ******************************************************** -Step 11: Update usage of Input Class's get_post() method +Step 12: Update usage of Input Class's get_post() method ******************************************************** Previously, the :doc:`Input Class <../libraries/input>` method ``get_post()`` @@ -193,14 +231,14 @@ A method has been added, ``post_get()``, which searches in POST then in GET, as ``get_post()`` was doing before. *********************************************************************** -Step 12: Update usage of Directory Helper's directory_map() function +Step 13: Update usage of Directory Helper's directory_map() function *********************************************************************** In the resulting array, directories now end with a trailing directory separator (i.e. a slash, usually). ************************************************************* -Step 13: Update usage of Database Forge's drop_table() method +Step 14: Update usage of Database Forge's drop_table() method ************************************************************* Up until now, ``drop_table()`` added an IF EXISTS clause by default or it didn't work @@ -222,7 +260,7 @@ If your application relies on IF EXISTS, you'll have to change its usage. all drivers with the exception of ODBC. *********************************************************** -Step 14: Change usage of Email library with multiple emails +Step 15: Change usage of Email library with multiple emails *********************************************************** The :doc:`Email Library <../libraries/email>` will automatically clear the @@ -237,7 +275,7 @@ pass FALSE as the first parameter in the ``send()`` method: } *************************************************** -Step 15: Update your Form_validation language lines +Step 16: Update your Form_validation language lines *************************************************** Two improvements have been made to the :doc:`Form Validation Library @@ -268,7 +306,7 @@ files and error messages format: later. **************************************************************** -Step 16: Remove usage of (previously) deprecated functionalities +Step 17: Remove usage of (previously) deprecated functionalities **************************************************************** In addition to the ``$autoload['core']`` configuration setting, there's a @@ -280,7 +318,7 @@ The SHA1 library The previously deprecated SHA1 library has been removed, alter your code to use PHP's native ``sha1()`` function to generate a SHA1 hash. -Additionally, the ``sha1()`` method in the :doc:`Encryption Library <../libraries/encryption>` has been removed. +Additionally, the ``sha1()`` method in the :doc:`Encrypt Library <../libraries/encrypt>` has been removed. The EXT constant ================ @@ -295,6 +333,44 @@ Smiley helper js_insert_smiley() :doc:`Smiley Helper <../helpers/smiley_helper>` function ``js_insert_smiley()`` has been deprecated since CodeIgniter 1.7.2 and is now removed. You'll need to switch to ``smiley_js()`` instead. +The Encrypt library +=================== + +Following numerous vulnerability reports, the :doc:`Encrypt Library <../libraries/encrypt>` has +been deprecated and a new, :doc:`Encryption Library <../libraries/encryption>` is added to take +its place. + +The new library requires either the `MCrypt extension <http://php.net/mcrypt>`_ (and /dev/urandom +availability) or PHP 5.3.3 and the `OpenSSL extension <http://php.net/openssl>`_. +While this might be rather inconvenient, it is a requirement that allows us to have properly +implemented cryptographic functions. + +.. note:: The :doc:`Encrypt Library <../libraries/encrypt>` is still available for the purpose + of keeping backwards compatibility. + +.. important:: You are strongly encouraged to switch to the new :doc:`Encryption Library + <../libraries/encryption>` as soon as possible! + +Database drivers 'mysql', 'sqlite', 'mssql', 'pdo/dblib' +======================================================== + +The **mysql** driver utilizes the old 'mysql' PHP extension, known for its aging code base and +many low-level problems. The extension is deprecated as of PHP 5.5 and CodeIgniter deprecates +it in version 3.0, switching the default configured MySQL driver to **mysqli**. + +Please use either the 'mysqli' or 'pdo/mysql' drivers for MySQL. The old 'mysql' driver will be +removed at some point in the future. + +The **sqlite**, **mssql** and **pdo/dblib** (also known as pdo/mssql or pdo/sybase) drivers +all depend on PHP extensions that for different reasons no longer exist since PHP 5.3. + +Therefore we are now deprecating these drivers as we will have to remove them in one of the next +CodeIgniter versions. You should use the more advanced, **sqlite3**, **sqlsrv** or **pdo/sqlsrv** +drivers respectively. + +.. note:: These drivers are still available, but you're strongly encouraged to switch to other ones + sooner rather than later. + Security helper do_hash() ========================= @@ -317,7 +393,7 @@ CodeIgniter 3.1+. String helper repeater() ======================== -:doc:`String Helper <../helpers/string_helper>` function :php:func:`repeater()` is now just an alias for +:doc:`String Helper <../helpers/string_helper>` function :func:`repeater()` is now just an alias for PHP's native ``str_repeat()`` function. It is deprecated and scheduled for removal in CodeIgniter 3.1+. .. note:: This function is still available, but you're strongly encouraged to remove its usage sooner @@ -326,7 +402,7 @@ PHP's native ``str_repeat()`` function. It is deprecated and scheduled for remov String helper trim_slashes() ============================ -:doc:`String Helper <../helpers/string_helper>` function :php:func:`trim_slashes()` is now just an alias +:doc:`String Helper <../helpers/string_helper>` function :func:`trim_slashes()` is now just an alias for PHP's native ``trim()`` function (with a slash passed as its second argument). It is deprecated and scheduled for removal in CodeIgniter 3.1+. @@ -338,8 +414,8 @@ Email helper functions :doc:`Email Helper <../helpers/email_helper>` only has two functions - - :php:func:`valid_email()` - - :php:func:`send_email()` + - :func:`valid_email()` + - :func:`send_email()` Both of them are now aliases for PHP's native ``filter_var()`` and ``mail()`` functions, respectively. Therefore the :doc:`Email Helper <../helpers/email_helper>` altogether is being deprecated and @@ -389,7 +465,7 @@ CodeIgniter 3.1+. String helper random_string() types 'unique' and 'encrypt' ========================================================== -When using the :doc:`String Helper <../helpers/string_helper>` function :php:func:`random_string()`, +When using the :doc:`String Helper <../helpers/string_helper>` function :func:`random_string()`, you should no longer pass the **unique** and **encrypt** randomization types. They are only aliases for **md5** and **sha1** respectively and are now deprecated and scheduled for removal in CodeIgniter 3.1+. @@ -400,7 +476,7 @@ in CodeIgniter 3.1+. URL helper url_title() separators 'dash' and 'underscore' ========================================================= -When using the :doc:`URL Helper <../helpers/url_helper>` function :php:func:`url_title()`, you +When using the :doc:`URL Helper <../helpers/url_helper>` function :func:`url_title()`, you should no longer pass **dash** or **underscore** as the word separator. This function will now accept any character and you should just pass the chosen character directly, so you should write '-' instead of 'dash' and '_' instead of 'underscore'. @@ -411,6 +487,21 @@ in CodeIgniter 3.1+. .. note:: These options are still available, but you're strongly encouraged to remove their usage sooner rather than later. +Session Library method all_userdata() +===================================== + +As seen in the :doc:`Change Log <../changelog>`, :doc:`Session Library <../libraries/sessions>` +method ``userdata()`` now allows you to fetch all userdata by simply omitting its parameter:: + + $this->session->userdata(); + +This makes the ``all_userdata()`` method redudant and therefore it is now just an alias for +``userdata()`` with the above shown usage and is being deprecated and scheduled for removal +in CodeIgniter 3.1+. + +.. note:: This method is still available, but you're strongly encouraged to remove its usage + sooner rather than later. + Database Forge method add_column() with an AFTER clause ======================================================= @@ -457,4 +548,71 @@ then you can now just access the properties instead:: $this->router->method; .. note:: Those methods are still available, but you're strongly encouraged to remove their usage - sooner rather than later.
\ No newline at end of file + sooner rather than later. + +Input library method is_cli_request() +===================================== + +Calls to the ``CI_Input::is_cli_request()`` method are necessary at many places +in the CodeIgniter internals and this is often before the :doc:`Input Library +<../libraries/input>` is loaded. Because of that, it is being replaced by a common +function named :func:`is_cli()` and this method is now just an alias. + +The new function is both available at all times for you to use and shorter to type. + +:: + + // Old + $this->input->is_cli_request(); + + // New + is_cli(); + +``CI_Input::is_cli_request()`` is now now deprecated and scheduled for removal in +CodeIgniter 3.1+. + +.. note:: This method is still available, but you're strongly encouraged to remove its usage + sooner rather than later. + +Config library method system_url() +================================== + +Usage of ``CI_Config::system_url()`` encourages insecure coding practices. +Namely, your CodeIgniter *system/* directory shouldn't be publicly accessible +from a security point of view. + +Because of this, this method is now deprecated and scheduled for removal in +CodeIgniter 3.1+. + +.. note:: This method is still available, but you're strongly encouraged to remove its usage + sooner rather than later. + +====================== +The Javascript library +====================== + +The :doc:`Javascript Library <../libraries/javascript>` has always had an +'experimental' status and was never really useful, nor a proper solution. + +It is now deprecated and scheduled for removal in CodeIgniter 3.1+. + +.. note:: This library is still available, but you're strongly encouraged to remove its usage + sooner rather than later. + +*********************************************************** +Step 18: Check your usage of Text helper highlight_phrase() +*********************************************************** + +The default HTML tag used by :doc:`Text Helper <../helpers/text_helper>` function +:func:`highlight_phrase()` has been changed from ``<strong>`` to the new HTML5 +tag ``<mark>``. + +Unless you've used your own highlighting tags, this might cause trouble +for your visitors who use older web browsers such as Internet Explorer 8. +We therefore suggest that you add the following code to your CSS files +in order to avoid backwards compatibility with old browsers:: + + mark { + background: #ff0; + color: #000; + }; diff --git a/user_guide_src/source/libraries/benchmark.rst b/user_guide_src/source/libraries/benchmark.rst index 5b86142dd..ddbe04869 100644 --- a/user_guide_src/source/libraries/benchmark.rst +++ b/user_guide_src/source/libraries/benchmark.rst @@ -13,10 +13,16 @@ invoked, and ended by the output class right before sending the final view to the browser, enabling a very accurate timing of the entire system execution to be shown. -.. contents:: Table of Contents +.. contents:: + :local: +.. raw:: html + + <div class="custom-index container"></div> + +************************* Using the Benchmark Class -========================= +************************* The Benchmark class can be used within your :doc:`controllers </general/controllers>`, @@ -68,7 +74,7 @@ _end. Each pair of points must otherwise be named identically. Example:: // Some code happens here... - $this->benchmark->mark('my_mark_end'); + $this->benchmark->mark('my_mark_end'); $this->benchmark->mark('another_mark_start'); @@ -120,3 +126,43 @@ this pseudo-variable, if you prefer not to use the pure PHP:: {memory_usage} + +*************** +Class Reference +*************** + +.. class:: CI_Benchmark + + .. method:: mark($name) + + :param string $name: the name you wish to assign to your marker + :rtype: void + + Sets a benchmark marker. + + .. method:: elapsed_time([$point1 = ''[, $point2 = ''[, $decimals = 4]]]) + + :param string $point1: a particular marked point + :param string $point2: a particular marked point + :param int $decimals: number of decimal places for precision + :returns: Elapsed time + :rtype: string + + Calculates and returns the time difference between two marked points. + + If the first parameter is empty this function instead returns the + ``{elapsed_time}`` pseudo-variable. This permits the full system + execution time to be shown in a template. The output class will + swap the real value for this variable. + + + .. method:: memory_usage() + + :returns: Memory usage info + :rtype: string + + Simply returns the ``{memory_usage}`` marker. + + This permits it to be put it anywhere in a template without the memory + being calculated until the end. The :doc:`Output Class <output>` will + swap the real value for this variable.
\ No newline at end of file diff --git a/user_guide_src/source/libraries/caching.rst b/user_guide_src/source/libraries/caching.rst index 8d7b4c440..caece1aee 100644 --- a/user_guide_src/source/libraries/caching.rst +++ b/user_guide_src/source/libraries/caching.rst @@ -7,7 +7,12 @@ fast and dynamic caching. All but file-based caching require specific server requirements, and a Fatal Exception will be thrown if server requirements are not met. -.. contents:: Table of Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> ************* Example Usage @@ -20,16 +25,16 @@ available in the hosting environment. :: $this->load->driver('cache', array('adapter' => 'apc', 'backup' => 'file')); - + if ( ! $foo = $this->cache->get('foo')) { echo 'Saving to the cache!<br />'; $foo = 'foobarbaz!'; - + // Save into the cache for 5 minutes $this->cache->save('foo', $foo, 300); } - + echo $foo; You can also prefix cache item names via the **key_prefix** setting, which is useful @@ -43,28 +48,24 @@ to avoid collisions when you're running multiple applications on the same enviro $this->cache->get('foo'); // Will get the cache entry named 'my_foo' -****************** -Function Reference -****************** +*************** +Class Reference +*************** -.. php:class:: CI_Cache +.. class:: CI_Cache -is_supported() -============== + .. method:: is_supported($driver) - .. php:method:: is_supported ( $driver ) + :param string $driver: the name of the caching driver + :returns: TRUE if supported, FALSE if not + :rtype: bool - This function is automatically called when accessing drivers via - $this->cache->get(). However, if the individual drivers are used, make - sure to call this function to ensure the driver is supported in the + This method is automatically called when accessing drivers via + ``$this->cache->get()``. However, if the individual drivers are used, + make sure to call this method to ensure the driver is supported in the hosting environment. - - :param string $driver: the name of the caching driver - :returns: TRUE if supported, FALSE if not - :rtype: Boolean - :: - + if ($this->cache->apc->is_supported() { if ($data = $this->cache->apc->get('my_cache')) @@ -73,103 +74,112 @@ is_supported() } } + .. method:: get($id) -get() -===== - - .. php:method:: get ( $id ) - - This function will attempt to fetch an item from the cache store. If the - item does not exist, the function will return FALSE. + :param string $id: Cache item name + :returns: Item value or FALSE if not found + :rtype: mixed - :param string $id: name of cached item - :returns: The item if it exists, FALSE if it does not - :rtype: Mixed - + This method will attempt to fetch an item from the cache store. If the + item does not exist, the method will return FALSE. :: $foo = $this->cache->get('my_cached_item'); + .. method:: save($id, $data[, $ttl = 60[, $raw = FALSE]]) -save() -====== - - .. php:method:: save ( $id , $data [, $ttl]) - - This function will save an item to the cache store. If saving fails, the - function will return FALSE. - - :param string $id: name of the cached item - :param mixed $data: the data to save - :param int $ttl: Time To Live, in seconds (default 60) - :returns: TRUE on success, FALSE on failure - :rtype: Boolean + :param string $id: Cache item name + :param mixed $data: the data to save + :param int $ttl: Time To Live, in seconds (default 60) + :param bool $raw: Whether to store the raw value + :returns: TRUE on success, FALSE on failure + :rtype: string + This method will save an item to the cache store. If saving fails, the + method will return FALSE. :: $this->cache->save('cache_item_id', 'data_to_cache'); - -delete() -======== - .. php:method:: delete ( $id ) - - This function will delete a specific item from the cache store. If item - deletion fails, the function will return FALSE. + .. note:: The ``$raw`` parameter is only utilized by APC and Memcache, + in order to allow usage of ``increment()`` and ``decrement()``. - :param string $id: name of cached item - :returns: TRUE if deleted, FALSE if the deletion fails - :rtype: Boolean - + .. method:: delete($id) + + :param string $id: name of cached item + :returns: TRUE on success, FALSE on failure + :rtype: bool + + This method will delete a specific item from the cache store. If item + deletion fails, the method will return FALSE. :: $this->cache->delete('cache_item_id'); -clean() -======= + .. method:: increment($id[, $offset = 1]) - .. php:method:: clean ( ) - - This function will 'clean' the entire cache. If the deletion of the - cache files fails, the function will return FALSE. + :param string $id: Cache ID + :param int $offset: Step/value to add + :returns: New value on success, FALSE on failure + :rtype: mixed - :returns: TRUE if deleted, FALSE if the deletion fails - :rtype: Boolean - + Performs atomic incrementation of a raw stored value. :: - $this->cache->clean(); + // 'iterator' has a value of 2 + + $this->cache->increment('iterator'); // 'iterator' is now 3 + + $this->cache->increment('iterator', 3); // 'iterator' is now 6 + + .. method:: decrement($id[, $offset = 1]) + + :param string $id: Cache ID + :param int $offset: Step/value to reduce by + :returns: New value on success, FALSE on failure + :rtype: mixed -cache_info() -============ + Performs atomic decrementation of a raw stored value. + :: + + // 'iterator' has a value of 6 + + $this->cache->decrement('iterator'); // 'iterator' is now 5 + + $this->cache->decrement('iterator', 2); // 'iterator' is now 3 + + .. method:: clean() + + :returns: TRUE on success, FALSE on failure + :rtype: bool - .. php:method:: cache_info ( ) + This method will 'clean' the entire cache. If the deletion of the + cache files fails, the method will return FALSE. + :: + + $this->cache->clean(); - This function will return information on the entire cache. + .. method:: cache_info() - :returns: information on the entire cache - :rtype: Mixed - + :returns: Information on the entire cache database + :rtype: mixed + + This method will return information on the entire cache. :: var_dump($this->cache->cache_info()); - + .. note:: The information returned and the structure of the data is dependent on which adapter is being used. - -get_metadata() -============== + .. method:: get_metadata($id) - .. php:method:: get_metadata ( $id ) - - This function will return detailed information on a specific item in the + :param string $id: Cache item name + :returns: Metadata for the cached item + :rtype: mixed + + This method will return detailed information on a specific item in the cache. - - :param string $id: name of cached item - :returns: metadadta for the cached item - :rtype: Mixed - :: var_dump($this->cache->get_metadata('my_cached_item')); @@ -184,7 +194,7 @@ Drivers Alternative PHP Cache (APC) Caching =================================== -All of the functions listed above can be accessed without passing a +All of the methods listed above can be accessed without passing a specific adapter to the driver loader as follows:: $this->load->driver('cache'); @@ -201,7 +211,7 @@ allows for pieces of view files to be cached. Use this with care, and make sure to benchmark your application, as a point can come where disk I/O will negate positive gains by caching. -All of the functions listed above can be accessed without passing a +All of the methods listed above can be accessed without passing a specific adapter to the driver loader as follows:: $this->load->driver('cache'); @@ -227,7 +237,7 @@ WinCache Caching Under Windows, you can also utilize the WinCache driver. -All of the functions listed above can be accessed without passing a +All of the methods listed above can be accessed without passing a specific adapter to the driver loader as follows:: $this->load->driver('cache'); @@ -239,17 +249,28 @@ For more information on WinCache, please see Redis Caching ============= +Redis is an in-memory key-value store which can operate in LRU cache mode. +To use it, you need Redis server and phpredis PHP extension +`https://github.com/nicolasff/phpredis <https://github.com/nicolasff/phpredis>`_. + +Config options to connect to redis server must be stored in the application/config/redis.php file. +Available options are:: + + $config['socket_type'] = 'tcp'; //`tcp` or `unix` + $config['socket'] = '/var/run/redis.sock'; // in case of `unix` socket type + $config['host'] = '127.0.0.1'; + $config['password'] = NULL; + $config['port'] = 6379; + $config['timeout'] = 0; + All of the methods listed above can be accessed without passing a specific adapter to the driver loader as follows:: $this->load->driver('cache'); $this->cache->redis->save('foo', 'bar', 10); -.. important:: Redis may require one or more of the following options: - **host**, **post**, **timeout**, **password**. - -The Redis PHP extension repository is located at -`https://github.com/nicolasff/phpredis <https://github.com/nicolasff/phpredis>`_. +For more information on Redis, please see +`http://redis.io <http://redis.io>`_. Dummy Cache =========== diff --git a/user_guide_src/source/libraries/calendar.rst b/user_guide_src/source/libraries/calendar.rst index 3964db25e..2263aa404 100644 --- a/user_guide_src/source/libraries/calendar.rst +++ b/user_guide_src/source/libraries/calendar.rst @@ -7,6 +7,17 @@ calendars can be formatted through the use of a calendar template, allowing 100% control over every aspect of its design. In addition, you can pass data to your calendar cells. +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + +*************************** +Using the Calendaring Class +*************************** + Initializing the Class ====================== @@ -86,21 +97,23 @@ The above code would start the calendar on saturday, use the "long" month heading, and the "short" day names. More information regarding preferences below. -====================== =========== =============================================== =================================================================== -Preference Default Options Description -====================== =========== =============================================== =================================================================== -**template** None None A string containing your calendar template. - See the template section below. -**local_time** time() None A Unix timestamp corresponding to the current time. -**start_day** sunday Any week day (sunday, monday, tuesday, etc.) Sets the day of the week the calendar should start on. -**month_type** long long, short Determines what version of the month name to use in the header. - long = January, short = Jan. -**day_type** abr long, short, abr Determines what version of the weekday names to use in - the column headers. long = Sunday, short = Sun, abr = Su. -**show_next_prev** FALSE TRUE/FALSE (boolean) Determines whether to display links allowing you to toggle - to next/previous months. See information on this feature below. -**next_prev_url** None A URL Sets the basepath used in the next/previous calendar links. -====================== =========== =============================================== =================================================================== +====================== ================= ============================================ =================================================================== +Preference Default Options Description +====================== ================= ============================================ =================================================================== +**template** None None A string containing your calendar template. + See the template section below. +**local_time** time() None A Unix timestamp corresponding to the current time. +**start_day** sunday Any week day (sunday, monday, tuesday, etc.) Sets the day of the week the calendar should start on. +**month_type** long long, short Determines what version of the month name to use in the header. + long = January, short = Jan. +**day_type** abr long, short, abr Determines what version of the weekday names to use in + the column headers. long = Sunday, short = Sun, abr = Su. +**show_next_prev** FALSE TRUE/FALSE (boolean) Determines whether to display links allowing you to toggle + to next/previous months. See information on this feature below. +**next_prev_url** controller/method A URL Sets the basepath used in the next/previous calendar links. +**show_other_days** FALSE TRUE/FALSE (boolean) Determines whether to display days of other months that share the + first or last week of the calendar month. +====================== ================= ============================================ =================================================================== Showing Next/Previous Month Links @@ -123,7 +136,8 @@ You'll notice a few things about the above example: - You must set the "show_next_prev" to TRUE. - You must supply the URL to the controller containing your calendar in - the "next_prev_url" preference. + the "next_prev_url" preference. If you don't, it will be set to the current + *controller/method*. - You must supply the "year" and "month" to the calendar generating function via the URI segments where they appear (Note: The calendar class automatically adds the year/month to the base URL you @@ -154,6 +168,8 @@ pair of pseudo-variables as shown here:: {cal_row_start}<tr>{/cal_row_start} {cal_cell_start}<td>{/cal_cell_start} + {cal_cell_start_today}<td>{/cal_cell_start_today} + {cal_cell_start_other}<td class="other-month">{/cal_cell_start_other} {cal_cell_content}<a href="{content}">{day}</a>{/cal_cell_content} {cal_cell_content_today}<div class="highlight"><a href="{content}">{day}</a></div>{/cal_cell_content_today} @@ -163,7 +179,11 @@ pair of pseudo-variables as shown here:: {cal_cell_blank} {/cal_cell_blank} + {cal_cell_other}{day}{cal_cel_other} + {cal_cell_end}</td>{/cal_cell_end} + {cal_cell_end_today}</td>{/cal_cell_end_today} + {cal_cell_end_other}</td>{/cal_cell_end_other} {cal_row_end}</tr>{/cal_row_end} {table_close}</table>{/table_close} @@ -171,4 +191,98 @@ pair of pseudo-variables as shown here:: $this->load->library('calendar', $prefs); - echo $this->calendar->generate();
\ No newline at end of file + echo $this->calendar->generate(); + +*************** +Class Reference +*************** + +.. class:: CI_Calendar + + .. method:: initialize([$config = array()]) + + :param array $config: Configuration parameters + :returns: CI_Calendar instance (method chaining) + :rtype: CI_Calendar + + Initializes the Calendaring preferences. Accepts an associative array as input, containing display preferences. + + .. method:: generate([$year = ''[, $month = ''[, $data = array()]]]) + + :param int $year: Year + :param int $month: Month + :param array $data: Data to be shown in the calendar cells + :returns: HTML-formatted calendar + :rtype: string + + Generate the calendar. + + + .. method:: get_month_name($month) + + :param int $month: Month + :returns: Month name + :rtype: string + + Generates a textual month name based on the numeric month provided. + + .. method:: get_day_names($day_type = '') + + :param string $day_type: 'long', 'short', or 'abr' + :returns: Array of day names + :rtype: array + + Returns an array of day names (Sunday, Monday, etc.) based on the type + provided. Options: long, short, abr. If no ``$day_type`` is provided (or + if an invalid type is provided) this method will return the "abbreviated" + style. + + .. method:: adjust_date($month, $year) + + :param int $month: Month + :param int $year: Year + :returns: An associative array containing month and year + :rtype: array + + This method makes sure that you have a valid month/year. For example, if + you submit 13 as the month, the year will increment and the month will + become January:: + + print_r($this->calendar->adjust_date(13, 2014)); + + outputs:: + + Array + ( Â Â Â + [month] => '01' + [year] => '2015' + ) + + .. method:: get_total_days($month, $year) + + :param int $month: Month + :param int $year: Year + :returns: Count of days in the specified month + :rtype: int + + Total days in a given month:: + + echo $this->calendar->get_total_days(2, 2012); + // 29 + + .. method:: default_template() + + :returns: An array of template values + :rtype: array + + Sets the default template. This method is used when you have not created + your own template. + + + .. method:: parse_template() + + :returns: CI_Calendar instance (method chaining) + :rtype: CI_Calendar + + Harvests the data within the template ``{pseudo-variables}`` used to + display the calendar.
\ No newline at end of file diff --git a/user_guide_src/source/libraries/cart.rst b/user_guide_src/source/libraries/cart.rst index 716e94bcb..fb92c280a 100644 --- a/user_guide_src/source/libraries/cart.rst +++ b/user_guide_src/source/libraries/cart.rst @@ -11,7 +11,16 @@ Please note that the Cart Class ONLY provides the core "cart" functionality. It does not provide shipping, credit card authorization, or other processing components. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + +******************** +Using the Cart Class +******************** Initializing the Shopping Cart Class ==================================== @@ -29,7 +38,7 @@ use the $this->load->library function:: $this->load->library('cart'); Once loaded, the Cart object will be available using:: - + $this->cart .. note:: The Cart Class will load and initialize the Session Class @@ -179,7 +188,7 @@ helper </helpers/form_helper>`. </table> <p><?php echo form_submit('', 'Update your Cart'); ?></p> - + Updating The Cart ================= @@ -197,7 +206,7 @@ function: 'qty' => 3 ); - $this->cart->update($data); + $this->cart->update($data); // Or a multi-dimensional array @@ -236,73 +245,125 @@ the product ID and any options associated with it. In nearly all cases, updating the cart will be something the user does via the "view cart" page, so as a developer, it is unlikely that you -will ever have to concern yourself with the "row ID", other then making +will ever have to concern yourself with the "row ID", other than making sure your "view cart" page contains this information in a hidden form field, and making sure it gets passed to the update function when the update form is submitted. Please examine the construction of the "view cart" page above for more information. -Function Reference -================== +*************** +Class Reference +*************** + +.. class:: CI_Cart + + .. attribute:: $product_id_rules = '\.a-z0-9_-' + + These are the regular expression rules that we use to validate the product + ID - alpha-numeric, dashes, underscores, or periods by default + + .. attribute:: $product_name_rules = '\w \-\.\:' + + These are the regular expression rules that we use to validate the product ID and product name - alpha-numeric, dashes, underscores, colons or periods by + default + + .. attribute:: $product_name_safe = TRUE + + Whether or not to only allow safe product names. Default TRUE. + + + .. method:: insert([$items = array()]) + + :param array $items: Items to insert into the cart + :returns: TRUE on success, FALSE on failure + :rtype: bool + + Insert items into the cart and save it to the session table. Returns TRUE + on success and FALSE on failure. + + + .. method:: update([$items = array()]) + + :param array $items: Items to update in the cart + :returns: TRUE on success, FALSE on failure + :rtype: bool + + This method permits the quantity of a given item to be changed. + Typically it is called from the "view cart" page if a user makes changes + to the quantity before checkout. That array must contain the product ID + and quantity for each item. + + .. method:: remove($rowid) + + :param int $rowid: ID of the item to remove from the cart + :returns: TRUE on success, FALSE on failure + :rtype: bool + + Allows you to remove an item from the shopping cart by passing it the + ``$rowid``. + + .. method:: total() + + :returns: Total amount + :rtype: int + + Displays the total amount in the cart. -$this->cart->insert(); -********************** -Permits you to add items to the shopping cart, as outlined above. + .. method:: total_items() -$this->cart->update(); -********************** + :returns: Total amount of items in the cart + :rtype: int -Permits you to update items in the shopping cart, as outlined above. + Displays the total number of items in the cart. -$this->cart->remove(rowid); -*************************** -Allows you to remove an item from the shopping cart by passing it the rowid. + .. method:: contents([$newest_first = FALSE]) -$this->cart->total(); -********************* + :param bool $newest_first: Whether to order the array with newest items first + :returns: An array of cart contents + :rtype: array -Displays the total amount in the cart. + Returns an array containing everything in the cart. You can sort the + order by which the array is returned by passing it TRUE where the contents + will be sorted from newest to oldest, otherwise it is sorted from oldest + to newest. -$this->cart->total_items(); -*************************** + .. method:: get_item($row_id) -Displays the total number of items in the cart. + :param int $row_id: Row ID to retrieve + :returns: Array of item data + :rtype: array -$this->cart->contents(boolean); -******************************* + Returns an array containing data for the item matching the specified row + ID, or FALSE if no such item exists. -Returns an array containing everything in the cart. You can sort the order, -by which this is returned by passing it "true" where the contents will be sorted -from newest to oldest, by leaving this function blank, you'll automatically just get -first added to the basket to last added to the basket. + .. method:: has_options($row_id = '') -$this->cart->get_item($row_id); -******************************* + :param int $row_id: Row ID to inspect + :returns: TRUE if options exist, FALSE otherwise + :rtype: bool -Returns an array containing data for the item matching the specified row ID, -or FALSE if no such item exists. + Returns TRUE (boolean) if a particular row in the cart contains options. + This method is designed to be used in a loop with ``contents()``, since + you must pass the rowid to this function, as shown in the Displaying + the Cart example above. -$this->cart->has_options($row_id); -********************************** + .. method:: product_options([$row_id = '']) -Returns TRUE (boolean) if a particular row in the cart contains options. -This function is designed to be used in a loop with -$this->cart->contents(), since you must pass the rowid to this function, -as shown in the Displaying the Cart example above. + :param int $row_id: Row ID + :returns: Array of product options + :rtype: array -$this->cart->product_options($row_id); -************************************** + Returns an array of options for a particular product. This method is + designed to be used in a loop with ``contents()``, since you + must pass the rowid to this method, as shown in the Displaying the + Cart example above. -Returns an array of options for a particular product. This function is -designed to be used in a loop with $this->cart->contents(), since you -must pass the rowid to this function, as shown in the Displaying the -Cart example above. + .. method:: destroy() -$this->cart->destroy(); -*********************** + :rtype: void -Permits you to destroy the cart. This function will likely be called -when you are finished processing the customer's order. + Permits you to destroy the cart. This method will likely be called + when you are finished processing the customer's order.
\ No newline at end of file diff --git a/user_guide_src/source/libraries/config.rst b/user_guide_src/source/libraries/config.rst index 654dc4ded..3116b768a 100644 --- a/user_guide_src/source/libraries/config.rst +++ b/user_guide_src/source/libraries/config.rst @@ -9,7 +9,16 @@ These preferences can come from the default config file .. note:: This class is initialized automatically by the system so there is no need to do it manually. -.. contents:: Page Contents +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + +***************************** +Working with the Config Class +***************************** Anatomy of a Config File ======================== @@ -157,27 +166,87 @@ folders: that you wish to change for your environment. The config items declared in your environment folders always overwrite those in your global config files. -Helper Functions -================ -The config class has the following helper functions: +*************** +Class Reference +*************** -$this->config->site_url(); -*************************** +.. class:: CI_Config -This function retrieves the URL to your site, along with the "index" -value you've specified in the config file. + .. attribute:: $config -$this->config->base_url(); -*************************** + Array of all loaded config values -This function retrieves the URL to your site, plus an optional path such -as to a stylesheet or image. + .. attribute:: $is_loaded -The two functions above are normally accessed via the corresponding -functions in the :doc:`URL Helper </helpers/url_helper>`. + Array of all loaded config files -$this->config->system_url(); -***************************** -This function retrieves the URL to your system folder. + .. method:: item($item[, $index='']) + + :param string $item: Config item name + :param string $index: Index name + :returns: Config item value or NULL if not found + :rtype: mixed + + Fetch a config file item. + + .. method:: set_item($item, $value) + + :param string $item: Config item name + :param string $value: Config item value + :rtype: void + + Sets a config file item to the specified value. + + .. method:: slash_item($item) + + :param string $item: config item name + :returns: Config item value with a trailing forward slash or NULL if not found + :rtype: mixed + + This method is identical to ``item()``, except it appends a forward + slash to the end of the item, if it exists. + + .. method:: load([$file = ''[, $use_sections = FALSE[, $fail_gracefully = FALSE]]]) + + :param string $file: Configuration file name + :param bool $use_sections: Whether config values shoud be loaded into their own section (index of the main config array) + :param bool $fail_gracefully: Whether to return FALSE or to display an error message + :returns: TRUE on success, FALSE on failure + :rtype: bool + + Loads a configuration file. + + .. method:: site_url() + + :returns: Site URL + :rtype: string + + This method retrieves the URL to your site, along with the "index" value + you've specified in the config file. + + This method is normally accessed via the corresponding functions in the + :doc:`URL Helper </helpers/url_helper>`. + + .. method:: base_url() + + :returns: Base URL + :rtype: string + + This method retrieves the URL to your site, plus an optional path such + as to a stylesheet or image. + + This method is normally accessed via the corresponding functions in the + :doc:`URL Helper </helpers/url_helper>`. + + .. method:: system_url() + + :returns: URL pointing at your CI system/ directory + :rtype: string + + This method retrieves the URL to your CodeIgniter system/ directory. + + .. note:: This method is DEPRECATED because it encourages usage of + insecure coding practices. Your *system/* directory shouldn't + be publicly accessible.
\ 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 39629ece1..ebfde809b 100644 --- a/user_guide_src/source/libraries/email.rst +++ b/user_guide_src/source/libraries/email.rst @@ -16,6 +16,17 @@ CodeIgniter's robust Email Class supports the following features: BCC batches. - Email Debugging tools +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + +*********************** +Using the Email Library +*********************** + Sending Email ============= @@ -31,12 +42,12 @@ This example assumes you are sending the email from one of your $this->load->library('email'); $this->email->from('your@example.com', 'Your Name'); - $this->email->to('someone@example.com'); - $this->email->cc('another@another-example.com'); - $this->email->bcc('them@their-example.com'); + $this->email->to('someone@example.com'); + $this->email->cc('another@another-example.com'); + $this->email->bcc('them@their-example.com'); $this->email->subject('Email Test'); - $this->email->message('Testing the email class.'); + $this->email->message('Testing the email class.'); $this->email->send(); @@ -83,7 +94,7 @@ Preference Default Value Options Descript =================== ====================== ============================ ======================================================================= **useragent** CodeIgniter None The "user agent". **protocol** mail mail, sendmail, or smtp The mail sending protocol. -**mailpath** /usr/sbin/sendmail None The server path to Sendmail. +**mailpath** /usr/sbin/sendmail None The server path to Sendmail. **smtp_host** No Default None SMTP Server Address. **smtp_user** No Default None SMTP Username. **smtp_pass** No Default None SMTP Password. @@ -106,206 +117,289 @@ Preference Default Value Options Descript **dsn** FALSE TRUE or FALSE (boolean) Enable notify message from server =================== ====================== ============================ ======================================================================= -Email Methods Reference -======================= +Overriding Word Wrapping +======================== -$this->email->from() --------------------- +If you have word wrapping enabled (recommended to comply with RFC 822) +and you have a very long link in your email it can get wrapped too, +causing it to become un-clickable by the person receiving it. +CodeIgniter lets you manually override word wrapping within part of your +message like this:: -Sets the email address and name of the person sending the email:: + The text of your email that + gets wrapped normally. - $this->email->from('you@example.com', 'Your Name'); + {unwrap}http://example.com/a_long_link_that_should_not_be_wrapped.html{/unwrap} -You can also set a Return-Path, to help redirect undelivered mail:: + More text that will be + wrapped normally. - $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() ------------------------- +Place the item you do not want word-wrapped between: {unwrap} {/unwrap} -Sets the reply-to address. If the information is not provided the -information in the "from" method is used. Example:: +*************** +Class Reference +*************** - $this->email->reply_to('you@example.com', 'Your Name'); +.. class:: CI_Email -$this->email->to() ------------------- + .. method:: from($from[, $name = ''[, $return_path = NULL]]) -Sets the email address(s) of the recipient(s). Can be a single email, a -comma-delimited list or an array:: + :param string $from: "From" e-mail address + :param string $name: "From" display name + :param string $return_path: Optional email address to redirect undelivered e-mail to + :returns: CI_Email instance (method chaining) + :rtype: CI_Email - $this->email->to('someone@example.com'); + Sets the email address and name of the person sending the email:: -:: + $this->email->from('you@example.com', 'Your Name'); - $this->email->to('one@example.com, two@example.com, three@example.com'); + You can also set a Return-Path, to help redirect undelivered mail:: -:: + $this->email->from('you@example.com', 'Your Name', 'returned_emails@example.com'); - $list = array('one@example.com', 'two@example.com', 'three@example.com'); + .. note:: Return-Path can't be used if you've configured 'smtp' as + your protocol. - $this->email->to($list); + .. method:: reply_to($replyto[, $name = '']) -$this->email->cc() ------------------- + :param string $replyto: E-mail address for replies + :param string $name: Display name for the reply-to e-mail address + :returns: CI_Email instance (method chaining) + :rtype: CI_Email -Sets the CC email address(s). Just like the "to", can be a single email, -a comma-delimited list or an array. + Sets the reply-to address. If the information is not provided the + information in the :meth:from method is used. Example:: -$this->email->bcc() -------------------- + $this->email->reply_to('you@example.com', 'Your Name'); -Sets the BCC email address(s). Just like the "to", can be a single -email, a comma-delimited list or an array. + .. method:: to($to) -$this->email->subject() ------------------------ + :param mixed $to: Comma-delimited string or an array of e-mail addresses + :returns: CI_Email instance (method chaining) + :rtype: CI_Email -Sets the email subject:: + Sets the email address(s) of the recipient(s). Can be a single e-mail, + a comma-delimited list or an array:: - $this->email->subject('This is my subject'); + $this->email->to('someone@example.com'); -$this->email->message() ------------------------ + :: -Sets the email message body:: + $this->email->to('one@example.com, two@example.com, three@example.com'); - $this->email->message('This is my message'); + :: -$this->email->set_alt_message() -------------------------------- + $this->email->to( + array('one@example.com', 'two@example.com', 'three@example.com') + ); -Sets the alternative email message body:: + .. method:: cc($cc) - $this->email->set_alt_message('This is the alternative message'); + :param mixed $cc: Comma-delimited string or an array of e-mail addresses + :returns: CI_Email instance (method chaining) + :rtype: CI_Email -This is an optional message string which can be used if you send HTML -formatted email. It lets you specify an alternative message with no HTML -formatting which is added to the header string for people who do not -accept HTML email. If you do not set your own message CodeIgniter will -extract the message from your HTML email and strip the tags. + Sets the CC email address(s). Just like the "to", can be a single e-mail, + a comma-delimited list or an array. -$this->email->set_header() --------------------------- + .. method:: bcc($bcc[, $limit = '']) -Appends additional headers to the e-mail:: + :param mixed $bcc: Comma-delimited string or an array of e-mail addresses + :param int $limit: Maximum number of e-mails to send per batch + :returns: CI_Email instance (method chaining) + :rtype: CI_Email - $this->email->set_header('Header1', 'Value1'); - $this->email->set_header('Header2', 'Value2'); + Sets the BCC email address(s). Just like the ``to()`` method, can be a single + e-mail, a comma-delimited list or an array. -$this->email->clear() ---------------------- + If ``$limit`` is set, "batch mode" will be enabled, which will send + the emails to batches, with each batch not exceeding the specified + ``$limit``. -Initializes all the email variables to an empty state. This method is -intended for use if you run the email sending method in a loop, -permitting the data to be reset between cycles. + .. method:: subject($subject) -:: + :param string $subject: E-mail subject line + :returns: CI_Email instance (method chaining) + :rtype: CI_Email - foreach ($list as $name => $address) - { - $this->email->clear(); + Sets the email subject:: - $this->email->to($address); - $this->email->from('your@example.com'); - $this->email->subject('Here is your info '.$name); - $this->email->message('Hi '.$name.' Here is the info you requested.'); - $this->email->send(); - } + $this->email->subject('This is my subject'); -If you set the parameter to TRUE any attachments will be cleared as -well:: + .. method:: message($body) - $this->email->clear(TRUE); + :param string $body: E-mail message body + :returns: CI_Email instance (method chaining) + :rtype: CI_Email -$this->email->send() --------------------- + Sets the e-mail message body:: -The Email sending method. Returns boolean TRUE or FALSE based on -success or failure, enabling it to be used conditionally:: + $this->email->message('This is my message'); - if ( ! $this->email->send()) - { - // Generate error - } + .. method:: set_alt_message($str) -This method will automatically clear all parameters if the request was -successful. To stop this behaviour pass FALSE:: + :param string $str: Alternative e-mail message body + :returns: CI_Email instance (method chaining) + :rtype: CI_Email - if ($this->email->send(FALSE)) - { - // Parameters won't be cleared - } + Sets the alternative e-mail message body:: -.. note:: In order to use the ``print_debugger()`` method, you need - to avoid clearing the email parameters. + $this->email->set_alt_message('This is the alternative message'); -$this->email->attach() ----------------------- + This is an optional message string which can be used if you send + HTML formatted email. It lets you specify an alternative message + with no HTML formatting which is added to the header string for + people who do not accept HTML email. If you do not set your own + message CodeIgniter will extract the message from your HTML email + and strip the tags. -Enables you to send an attachment. Put the file path/name in the first -parameter. Note: Use a file path, not a URL. For multiple attachments -use the method multiple times. For example:: + .. method:: set_header($header, $value) - $this->email->attach('/path/to/photo1.jpg'); - $this->email->attach('/path/to/photo2.jpg'); - $this->email->attach('/path/to/photo3.jpg'); + :param string $header: Header name + :param string $value: Header value + :returns: CI_Email instance (method chaining) + :rtype: CI_Email -To use the default disposition (attachment), leave the second parameter blank, -otherwise use a custom disposition:: + Appends additional headers to the e-mail:: - $this->email->attach('image.jpg', 'inline'); + $this->email->set_header('Header1', 'Value1'); + $this->email->set_header('Header2', 'Value2'); -If you'd like to use a custom file name, you can use the third paramater:: + .. method:: clear([$clear_attachments = FALSE]) - $this->email->attach('filename.pdf', 'attachment', 'report.pdf'); + :param bool $clear_attachments: Whether or not to clear attachments + :returns: CI_Email instance (method chaining) + :rtype: CI_Email -If you need to use a buffer string instead of a real - physical - file you can -use the first parameter as buffer, the third parameter as file name and the fourth -parameter as mime-type:: + Initializes all the email variables to an empty state. This method + is intended for use if you run the email sending method in a loop, + permitting the data to be reset between cycles. - $this->email->attach($buffer, 'attachment', 'report.pdf', 'application/pdf'); + :: -$this->email->print_debugger() ------------------------------- + foreach ($list as $name => $address) + { + $this->email->clear(); -Returns a string containing any server messages, the email headers, and -the email messsage. Useful for debugging. + $this->email->to($address); + $this->email->from('your@example.com'); + $this->email->subject('Here is your info '.$name); + $this->email->message('Hi '.$name.' Here is the info you requested.'); + $this->email->send(); + } -You can optionally specify which parts of the message should be printed. -Valid options are: **headers**, **subject**, **body**. + If you set the parameter to TRUE any attachments will be cleared as + well:: -Example:: + $this->email->clear(TRUE); - // You need to pass FALSE while sending in order for the email data - // to not be cleared - if that happens, print_debugger() would have - // nothing to output. - $this->email->send(FALSE); + .. method:: send([$auto_clear = TRUE]) - // Will only print the email headers, excluding the message subject and body - $this->email->print_debugger(array('headers')); + :param bool $auto_clear: Whether to clear message data automatically + :returns: TRUE on success, FALSE on failure + :rtype: bool -.. note:: By default, all of the raw data will be printed. + The e-mail sending method. Returns boolean TRUE or FALSE based on + success or failure, enabling it to be used conditionally:: -Overriding Word Wrapping -======================== + if ( ! $this->email->send()) + { + // Generate error + } -If you have word wrapping enabled (recommended to comply with RFC 822) -and you have a very long link in your email it can get wrapped too, -causing it to become un-clickable by the person receiving it. -CodeIgniter lets you manually override word wrapping within part of your -message like this:: + This method will automatically clear all parameters if the request was + successful. To stop this behaviour pass FALSE:: - The text of your email that - gets wrapped normally. + if ($this->email->send(FALSE)) + { + // Parameters won't be cleared + } - {unwrap}http://example.com/a_long_link_that_should_not_be_wrapped.html{/unwrap} + .. note:: In order to use the ``print_debugger()`` method, you need + to avoid clearing the email parameters. - More text that will be - wrapped normally. - + .. method:: attach($filename[, $disposition = ''[, $newname = NULL[, $mime = '']]]) + + :param string $filename: File name + :param string $disposition: 'disposition' of the attachment. Most + email clients make their own decision regardless of the MIME + specification used here. https://www.iana.org/assignments/cont-disp/cont-disp.xhtml + :param string $newname: Custom file name to use in the e-mail + :param string $mime: MIME type to use (useful for buffered data) + :returns: CI_Email instance (method chaining) + :rtype: CI_Email + + Enables you to send an attachment. Put the file path/name in the first + parameter. For multiple attachments use the method multiple times. + For example:: + + $this->email->attach('/path/to/photo1.jpg'); + $this->email->attach('/path/to/photo2.jpg'); + $this->email->attach('/path/to/photo3.jpg'); + + To use the default disposition (attachment), leave the second parameter blank, + otherwise use a custom disposition:: + + $this->email->attach('image.jpg', 'inline'); + + You can also use a URL:: + + $this->email->attach('http://example.com/filename.pdf'); + + If you'd like to use a custom file name, you can use the third paramater:: + + $this->email->attach('filename.pdf', 'attachment', 'report.pdf'); + + If you need to use a buffer string instead of a real - physical - file you can + use the first parameter as buffer, the third parameter as file name and the fourth + parameter as mime-type:: + + $this->email->attach($buffer, 'attachment', 'report.pdf', 'application/pdf'); + + .. method:: attachment_cid($filename) + + :param string $filename: Existing attachment filename + :returns: Attachment Content-ID or FALSE if not found + :rtype: string + + Sets and returns an attachment's Content-ID, which enables your to embed an inline + (picture) attachment into HTML. First parameter must be the already attached file name. + :: + + $filename = '/img/photo1.jpg'; + $this->email->attach($filename); + foreach ($list as $address) + { + $this->email->to($address); + $cid = $this->email->attach_cid($filename); + $this->email->message('<img src='cid:". $cid ."' alt="photo1" />'); + $this->email->send(); + } + + .. note:: Content-ID for each e-mail must be re-created for it to be unique. + + .. method:: print_debugger([$include = array('headers', 'subject', 'body')]) + + :param array $include: Which parts of the message to print out + :returns: Formatted debug data + :rtype: string + + Returns a string containing any server messages, the email headers, and + the email messsage. Useful for debugging. + + You can optionally specify which parts of the message should be printed. + Valid options are: **headers**, **subject**, **body**. + + Example:: + + // You need to pass FALSE while sending in order for the email data + // to not be cleared - if that happens, print_debugger() would have + // nothing to output. + $this->email->send(FALSE); + + // Will only print the email headers, excluding the message subject and body + $this->email->print_debugger(array('headers')); -Place the item you do not want word-wrapped between: {unwrap} {/unwrap}
\ No newline at end of file + .. note:: By default, all of the raw data will be printed.
\ No newline at end of file diff --git a/user_guide_src/source/libraries/encrypt.rst b/user_guide_src/source/libraries/encrypt.rst new file mode 100644 index 000000000..faff39975 --- /dev/null +++ b/user_guide_src/source/libraries/encrypt.rst @@ -0,0 +1,203 @@ +############# +Encrypt Class +############# + +The Encrypt Class provides two-way data encryption. It uses a scheme +that either compiles the message using a randomly hashed bitwise XOR +encoding scheme, or is encrypted using the Mcrypt library. If Mcrypt is +not available on your server the encoded message will still provide a +reasonable degree of security for encrypted sessions or other such +"light" purposes. If Mcrypt is available, you'll be provided with a high +degree of security appropriate for storage. + +.. important:: This library has been DEPRECATED and is only kept for + backwards compatibility. Please use the new :doc:`Encryption Library + <encryption>`. + +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + +************************* +Using the Encrypt Library +************************* + +Setting your Key +================ + +A *key* is a piece of information that controls the cryptographic +process and permits an encrypted string to be decoded. In fact, the key +you chose will provide the **only** means to decode data that was +encrypted with that key, so not only must you choose the key carefully, +you must never change it if you intend use it for persistent data. + +It goes without saying that you should guard your key carefully. Should +someone gain access to your key, the data will be easily decoded. If +your server is not totally under your control it's impossible to ensure +key security so you may want to think carefully before using it for +anything that requires high security, like storing credit card numbers. + +To take maximum advantage of the encryption algorithm, your key should +be 32 characters in length (256 bits). The key should be as random a +string as you can concoct, with numbers and uppercase and lowercase +letters. Your key should **not** be a simple text string. In order to be +cryptographically secure it needs to be as random as possible. + +Your key can be either stored in your **application/config/config.php**, or +you can design your own storage mechanism and pass the key dynamically +when encoding/decoding. + +To save your key to your **application/config/config.php**, open the file +and set:: + + $config['encryption_key'] = "YOUR KEY"; + +Message Length +============== + +It's important for you to know that the encoded messages the encryption +function generates will be approximately 2.6 times longer than the +original message. For example, if you encrypt the string "my super +secret data", which is 21 characters in length, you'll end up with an +encoded string that is roughly 55 characters (we say "roughly" because +the encoded string length increments in 64 bit clusters, so it's not +exactly linear). Keep this information in mind when selecting your data +storage mechanism. Cookies, for example, can only hold 4K of +information. + +Initializing the Class +====================== + +Like most other classes in CodeIgniter, the Encrypt class is +initialized in your controller using the ``$this->load->library()`` +method:: + + $this->load->library('encrypt'); + +Once loaded, the Encrypt library object will be available using:: + + $this->encrypt + +*************** +Class Reference +*************** + +.. class:: CI_Encrypt + + .. method:: encode($string[, $key = '']) + + :param string $string: Data to encrypt + :param string $key: Encryption key + :returns: Encrypted string + :rtype: string + + Performs the data encryption and returns it as a string. Example:: + + $msg = 'My secret message'; + + $encrypted_string = $this->encrypt->encode($msg); + + You can optionally pass your encryption key via the second parameter if + you don't want to use the one in your config file:: + + $msg = 'My secret message'; + $key = 'super-secret-key'; + + $encrypted_string = $this->encrypt->encode($msg, $key); + + .. method:: decode($string[, $key = '']) + + :param string $string: String to decrypt + :param string $key: Encryption key + :returns: Plain-text string + :rtype: string + + Decrypts an encoded string. Example:: + + $encrypted_string = 'APANtByIGI1BpVXZTJgcsAG8GZl8pdwwa84'; + + $plaintext_string = $this->encrypt->decode($encrypted_string); + + You can optionally pass your encryption key via the second parameter if + you don't want to use the one in your config file:: + + $msg = 'My secret message'; + $key = 'super-secret-key'; + + $encrypted_string = $this->encrypt->decode($msg, $key); + + .. method:: set_cipher($cipher) + + :param int $cipher: Valid PHP MCrypt cypher constant + :returns: CI_Encrypt instance (method chaining) + :rtype: CI_Encrypt + + Permits you to set an Mcrypt cipher. By default it uses + ``MCRYPT_RIJNDAEL_256``. Example:: + + $this->encrypt->set_cipher(MCRYPT_BLOWFISH); + + Please visit php.net for a list of `available ciphers <http://php.net/mcrypt>`_. + + If you'd like to manually test whether your server supports MCrypt you + can use:: + + echo extension_loaded('mcrypt') ? 'Yup' : 'Nope'; + + .. method:: set_mode($mode) + + :param int $mode: Valid PHP MCrypt mode constant + :returns: CI_Encrypt instance (method chaining) + :rtype: CI_Encrypt + + Permits you to set an Mcrypt mode. By default it uses **MCRYPT_MODE_CBC**. + Example:: + + $this->encrypt->set_mode(MCRYPT_MODE_CFB); + + Please visit php.net for a list of `available modes <http://php.net/mcrypt>`_. + + .. method:: encode_from_legacy($string[, $legacy_mode = MCRYPT_MODE_ECB[, $key = '']]) + + :param string $string: String to encrypt + :param int $legacy_mode: Valid PHP MCrypt cipher constant + :param string $key: Encryption key + :returns: Newly encrypted string + :rtype: string + + Enables you to re-encode data that was originally encrypted with + CodeIgniter 1.x to be compatible with the Encrypt library in + CodeIgniter 2.x. It is only necessary to use this method if you have + encrypted data stored permanently such as in a file or database and are + on a server that supports Mcrypt. "Light" use encryption such as + encrypted session data or transitory encrypted flashdata require no + intervention on your part. However, existing encrypted Sessions will be + destroyed since data encrypted prior to 2.x will not be decoded. + + .. important:: + **Why only a method to re-encode the data instead of maintaining legacy + methods for both encoding and decoding?** The algorithms in the + Encrypt library have improved in CodeIgniter 2.x both for performance + and security, and we do not wish to encourage continued use of the older + methods. You can of course extend the Encryption library if you wish and + replace the new methods with the old and retain seamless compatibility + with CodeIgniter 1.x encrypted data, but this a decision that a + developer should make cautiously and deliberately, if at all. + + :: + + $new_data = $this->encrypt->encode_from_legacy($old_encrypted_string); + + ====================== =============== ======================================================================= + Parameter Default Description + ====================== =============== ======================================================================= + **$orig_data** n/a The original encrypted data from CodeIgniter 1.x's Encryption library + **$legacy_mode** MCRYPT_MODE_ECB The Mcrypt mode that was used to generate the original encrypted data. + CodeIgniter 1.x's default was MCRYPT_MODE_ECB, and it will assume that + to be the case unless overridden by this parameter. + **$key** n/a The encryption key. This it typically specified in your config file as + outlined above. + ====================== =============== =======================================================================
\ No newline at end of file diff --git a/user_guide_src/source/libraries/encryption.rst b/user_guide_src/source/libraries/encryption.rst index a38122203..cedc8d381 100644 --- a/user_guide_src/source/libraries/encryption.rst +++ b/user_guide_src/source/libraries/encryption.rst @@ -1,164 +1,555 @@ -################ -Encryption Class -################ - -The Encryption Class provides two-way data encryption. It uses a scheme -that either compiles the message using a randomly hashed bitwise XOR -encoding scheme, or is encrypted using the Mcrypt library. If Mcrypt is -not available on your server the encoded message will still provide a -reasonable degree of security for encrypted sessions or other such -"light" purposes. If Mcrypt is available, you'll be provided with a high -degree of security appropriate for storage. - -Setting your Key +################## +Encryption Library +################## + +The Encryption Library provides two-way data encryption. To do so in +a cryptographically secure way, it utilizes PHP extensions that are +unfortunately not always available on all systems. +You must meet one of the following dependancies in order to use this +library: + +- `OpenSSL <http://php.net/openssl>`_ (and PHP 5.3.3) +- `MCrypt <http://php.net/mcrypt>`_ (and `MCRYPT_DEV_URANDOM` availability) + +If neither of the above dependancies is met, we simply cannot offer +you a good enough implementation to meet the high standards required +for proper cryptography. + +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + +**************************** +Using the Encryption Library +**************************** + +Initializing the Class +====================== + +Like most other classes in CodeIgniter, the Encryption library is +initialized in your controller using the ``$this->load->library()`` +method:: + + $this->load->library('encrypt'); + +Once loaded, the Encryption library object will be available using:: + + $this->encrypt + +Default behavior ================ -A *key* is a piece of information that controls the cryptographic -process and permits an encrypted string to be decoded. In fact, the key -you chose will provide the **only** means to decode data that was -encrypted with that key, so not only must you choose the key carefully, -you must never change it if you intend use it for persistent data. +By default, the Encryption Library will use the AES-128 cipher in CBC +mode, using your configured *encryption_key* and SHA512 HMAC authentication. + +.. note:: AES-128 is chosen both because it is proven to be strong and + because of its wide availability across different cryptographic + software and programming languages' APIs. + +However, the *encryption_key* is not used as is. + +If you are somewhat familiar with cryptography, you should already know +that a HMAC also requires a secret key and using the same key for both +encryption and authentication is a bad practice. + +Because of that, two separate keys are derived from your already configured +*encryption_key*: one for encryption and one for authentication. This is +done via a technique called `HMAC-based Key Derivation Function +<http://en.wikipedia.org/wiki/HKDF>`_ (HKDF). + +Setting your encryption_key +=========================== + +An *encryption key* is a piece of information that controls the +cryptographic process and permits a plain-text string to be encrypted, +and afterwards - decrypted. It is the secret "ingredient" in the whole +process that allows you to be the only one who is able to decrypt data +that you've decided to hide from the eyes of the public. +After one key is used to encrypt data, that same key provides the **only** +means to decrypt it, so not only must you chose one carefully, but you +must not lose it or you will also use the encrypted data. + +It must be noted that to ensure maximum security, such key *should* not +only be as strong as possible, but also often changed. Such behavior +however is rarely practical or possible to implement, and that is why +CodeIgniter gives you the ability to configure a single key that is to be +used (almost) every time. It goes without saying that you should guard your key carefully. Should -someone gain access to your key, the data will be easily decoded. If +someone gain access to your key, the data will be easily decrypted. If your server is not totally under your control it's impossible to ensure key security so you may want to think carefully before using it for anything that requires high security, like storing credit card numbers. -To take maximum advantage of the encryption algorithm, your key should -be 32 characters in length (256 bits). The key should be as random a -string as you can concoct, with numbers and uppercase and lowercase -letters. Your key should **not** be a simple text string. In order to be -cryptographically secure it needs to be as random as possible. +Your encryption key should be as long as the encyption algorithm in use +allows. For AES-128, that's 128 bits or 16 bytes (charcters) long. The +key should be as random as possible and it should **not** be a simple +text string. + +You will find a table below that shows the supported key lengths of +different ciphers. -Your key can be either stored in your **application/config/config.php**, or +The key can be either stored in your *application/config/config.php*, or you can design your own storage mechanism and pass the key dynamically -when encoding/decoding. +when encrypting/decrypting. -To save your key to your **application/config/config.php**, open the file +To save your key to your *application/config/config.php*, open the file and set:: - $config['encryption_key'] = "YOUR KEY"; + $config['encryption_key'] = 'YOUR KEY'; + +.. _ciphers-and-modes: + +Supported encryption ciphers and modes +====================================== + +.. note:: The terms 'cipher' and 'encryption algorithm' are interchangeable. + +Portable ciphers +---------------- + +Because MCrypt and OpenSSL (also called drivers throughout this document) +each support different sets of encryption algorithms and often implement +them in different ways, our Encryption library is designed to use them in +a portable fashion, or in other words - it enables you to use them +interchangeably, at least for the ciphers supported by both drivers. + +It is also implemented in a way that aims to match the standard +implementations in other programming languages and libraries. + +Here's a list of the so called "portable" ciphers, where +"CodeIgniter name" is the string value that you'd have to pass to the +Encryption library to use that cipher: + +======================== ================== ============================ =============================== +Cipher name CodeIgniter name Key lengths (bits / bytes) Supported modes +======================== ================== ============================ =============================== +AES-128 / Rijndael-128 aes-128 128 / 16 CBC, CTR, CFB, CFB8, OFB, ECB +AES-192 aes-192 192 / 24 CBC, CTR, CFB, CFB8, OFB, ECB +AES-256 aes-256 256 / 32 CBC, CTR, CFB, CFB8, OFB, ECB +DES des 56 / 7 CBC, CFB, CFB8, OFB, ECB +TripleDES tripledes 56 / 7, 112 / 14, 168 / 21 CBC, CFB, CFB8, OFB +Blowfish blowfish 128-448 / 16-56 CBC, CFB, OFB, ECB +CAST5 / CAST-128 cast5 40-128 / 5-16 CBC, CFB, OFB, ECB +RC4 / ARCFour rc4 40-2048 / 5-256 Stream +======================== ================== ============================ =============================== + +.. important:: Because of how MCrypt works, if you fail to provide a key + with the appropriate length, you might end up using a different + algorithm than the one configured, so be really careful with that! + +.. note:: In case it isn't clear from the above table, Blowfish, CAST5 + and RC4 support variable length keys. That is, any number in the + shown ranges is valid, although in bit terms that only happens + in 8-bit increments. + +.. note:: Even though CAST5 supports key lengths lower than 128 bits + (16 bytes), in fact they will just be zero-padded to the + maximum length, as specified in `RFC 2144 + <http://tools.ietf.org/rfc/rfc2144.txt>`_. + +.. note:: Blowfish supports key lengths as small as 32 bits (4 bytes), but + our tests have shown that only lengths of 128 bits (16 bytes) or + higher are properly supported by both MCrypt and OpenSSL. It is + also a bad practice to use such low-length keys anyway. + +Driver-specific ciphers +----------------------- + +As noted above, MCrypt and OpenSSL support different sets of encryption +ciphers. For portability reasons and because we haven't tested them +properly, we do not advise you to use the ones that are driver-specific, +but regardless, here's a list of most of them: + + +============== ========= ============================== ========================================= +Cipher name Driver Key lengths (bits / bytes) Supported modes +============== ========= ============================== ========================================= +AES-128 OpenSSL 128 / 16 CBC, CTR, CFB, CFB8, OFB, ECB, GCM, XTS +AES-192 OpenSSL 192 / 24 CBC, CTR, CFB, CFB8, OFB, ECB, GCM, XTS +AES-256 OpenSSL 256 / 32 CBC, CTR, CFB, CFB8, OFB, ECB, GCM, XTS +Rijndael-128 MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB +Rijndael-192 MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB +Rijndael-256 MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB +GOST MCrypt 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB +Twofish MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB +CAST-256 MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB +Loki97 MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB +SaferPlus MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB +Serpent MCrypt 128 / 16, 192 / 24, 256 / 32 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB +XTEA MCrypt 128 / 16 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB +RC2 MCrypt 8-1024 / 1-128 CBC, CTR, CFB, CFB8, OFB, OFB8, ECB +RC2 OpenSSL 8-1024 / 1-128 CBC, CFB, OFB, ECB +Camellia-128 OpenSSL 128 / 16 CBC, CFB, CFB8, OFB, ECB +Camellia-192 OpenSSL 192 / 24 CBC, CFB, CFB8, OFB, ECB +Camellia-256 OpenSSL 256 / 32 CBC, CFB, CFB8, OFB, ECB +Seed OpenSSL 128 / 16 CBC, CFB, OFB, ECB +============== ========= ============================== ========================================= + +.. note:: If you wish to use one of those ciphers, you'd have to pass + its name in lower-case to the Encryption library. + +.. note:: You've probably noticed that all AES cipers (and Rijndael-128) + are also listed in the portable ciphers list. This is because + drivers support different modes for these ciphers. Also, it is + important to note that AES-128 and Rijndael-128 are actually + the same cipher, but **only** when used with a 128-bit key. + +.. note:: RC2 is listed as supported by both MCrypt and OpenSSL. + However, both drivers implement them differently and they + are not portable. It is probably worth noting that we only + found one obscure source confirming that it is MCrypt that + is not properly implementing it. + +.. _encryption-modes: + +Encryption modes +---------------- + +Different modes of encryption have different characteristics and serve +for different purposes. Some are stronger than others, some are faster +and some offer extra features. +We are not going in depth into that here, we'll leave that to the +cryptography experts. The table below is to provide brief informational +reference to our more experienced users. If you are a beginner, just +stick to the CBC mode - it is widely accepted as strong and secure for +general purposes. + +=========== ================== ================= =================================================================================================================================================== +Mode name CodeIgniter name Driver support Additional info +=========== ================== ================= =================================================================================================================================================== +CBC cbc MCrypt, OpenSSL A safe default choice +CTR ctr MCrypt, OpenSSL Considered as theoretically better than CBC, but not as widely available +CFB cfb MCrypt, OpenSSL N/A +CFB8 cfb8 MCrypt, OpenSSL Same as CFB, but operates in 8-bit mode (not recommended). +OFB ofb MCrypt, OpenSSL N/A +OFB8 ofb8 MCrypt Same as OFB, but operates in 8-bit mode (not recommended). +ECB ecb MCrypt, OpenSSL Ignores IV (not recommended). +GCM gcm OpenSSL Provides authentication and therefore doesn't need a HMAC. +XTS xts OpenSSL Usually used for encrypting random access data such as RAM or hard-disk storage. +Stream stream MCrypt, OpenSSL This is not actually a mode, it just says that a stream cipher is being used. Required because of the general cipher+mode initialization process. +=========== ================== ================= =================================================================================================================================================== Message Length ============== -It's important for you to know that the encoded messages the encryption -function generates will be approximately 2.6 times longer than the -original message. For example, if you encrypt the string "my super -secret data", which is 21 characters in length, you'll end up with an -encoded string that is roughly 55 characters (we say "roughly" because -the encoded string length increments in 64 bit clusters, so it's not -exactly linear). Keep this information in mind when selecting your data -storage mechanism. Cookies, for example, can only hold 4K of -information. +It's probably important for you to know that an encrypted string is usually +longer than the original, plain-text string (depending on the cipher). -Initializing the Class -====================== +This is influenced by the cipher algorithm itself, the IV prepended to the +cipher-text and (unless you are using GCM mode) the HMAC authentication +message that is also prepended. Furthermore, the encrypted message is also +Base64-encoded so that it is safe for storage and transmission, regardless +of a possible character set in use. -Like most other classes in CodeIgniter, the Encryption class is -initialized in your controller using the **$this->load->library** function:: +Keep this information in mind when selecting your data storage mechanism. +Cookies, for example, can only hold 4K of information. - $this->load->library('encrypt'); +.. _configuration: + +Configuring the library +======================= -Once loaded, the Encrypt library object will be available using: -$this->encrypt +For usability, performance, but also historical reasons tied to our old +:doc:`Encrypt Class <encrypt>`, the Encryption library is designed to +use repeatedly the same driver, encryption cipher, mode and key. -$this->encrypt->encode() -======================== +As noted in the "Default behavior" section above, this means using an +auto-detected driver (OpenSSL has a higher priority), the AES-128 ciper +in CBC mode, and your ``$config['encryption_key']`` value. -Performs the data encryption and returns it as a string. Example:: +If you wish to change that however, you need to use the ``initialize()`` +method. It accepts an associative array of parameters, all of which are +optional: - $msg = 'My secret message'; +======== =============================================== +Option Possible values +======== =============================================== +driver 'mcrypt', 'openssl' +cipher Cipher name (see :ref:`ciphers-and-modes`) +mode Encryption mode (see :ref:`encryption-modes`) +key Encryption key +======== =============================================== - $encrypted_string = $this->encrypt->encode($msg); - +For example, if you were to change the encryption algorithm and +mode to AES-256 in CTR mode, this is what you should do:: -You can optionally pass your encryption key via the second parameter if -you don't want to use the one in your config file:: + $this->encryption->initialize( + array( + 'cipher' => 'aes-256', + 'mode' => 'ctr', + 'key' => '<a 32-character random string>' + ) + ); - $msg = 'My secret message'; - $key = 'super-secret-key'; +Note that we only mentioned that you want to change the ciper and mode, +but we also included a key in the example. As previously noted, it is +important that you choose a key with a proper size for the used algorithm. - $encrypted_string = $this->encrypt->encode($msg, $key); +There's also the ability to change the driver, if for some reason you +have both, but want to use MCrypt instead of OpenSSL:: -$this->encrypt->decode() -======================== + // Switch to the MCrypt driver + $this->encryption->initialize(array('driver' => 'mcrypt')); -Decrypts an encoded string. Example:: + // Switch back to the OpenSSL driver + $this->encryption->initialize(array('driver' => 'openssl')); - $encrypted_string = 'APANtByIGI1BpVXZTJgcsAG8GZl8pdwwa84'; +Encrypting and decrypting data +============================== - $plaintext_string = $this->encrypt->decode($encrypted_string); +Encrypting and decrypting data with the already configured library +settings is simple. As simple as just passing the string to the +``encrypt()`` and/or ``decrypt()`` methods:: -You can optionally pass your encryption key via the second parameter if -you don't want to use the one in your config file:: + $plain_text = 'This is a plain-text message!'; + $ciphertext = $this->encryption->encrypt($plain_text); - $msg = 'My secret message'; - $key = 'super-secret-key'; + // Outputs: This is a plain-text message! + echo $this->encryption->decrypt($ciphertext); - $encrypted_string = $this->encrypt->decode($msg, $key); +And that's it! The Encryption library will do everything necessary +for the whole process to be cryptographically secure out-of-the-box. +You don't need to worry about it. -$this->encrypt->set_cipher(); -============================== +.. important:: Both methods will return FALSE in case of an error. + While for ``encrypt()`` this can only mean incorrect + configuration, you should always check the return value + of ``decrypt()`` in production code. + +How it works +------------ + +If you must know how the process works, here's what happens under +the hood: + +- ``$this->encryption->encrypt($plain_text)`` + + #. Derive an encryption key and a HMAC key from your configured + *encryption_key* via HKDF, using the SHA-512 digest algorithm. + + #. Generate a random initialization vector (IV). + + #. Encrypt the data via AES-128 in CBC mode (or another previously + configured cipher and mode), using the above-mentioned derived + encryption key and IV. + + #. Prepend said IV to the resulting cipher-text. + + #. Base64-encode the resulting string, so that it can be safely + stored or transferred without worrying about character sets. + + #. Create a SHA-512 HMAC authentication message using the derived + HMAC key to ensure data integrity and prepend it to the Base64 + string. + +- ``$this->encryption->decrypt($ciphertext)`` + + #. Derive an encryption key and a HMAC key from your configured + *encryption_key* via HKDF, using the SHA-512 digest algorithm. + Because your configured *encryption_key* is the same, this + will produce the same result as in the ``encrypt()`` method + above - otherwise you won't be able to decrypt it. + + #. Check if the string is long enough, separate the HMAC out of + it and validate if it is correct (this is done in a way that + prevents timing attacks agains it). Return FALSE if either of + the checks fails. + + #. Base64-decode the string. + + #. Separate the IV out of the cipher-text and decrypt the said + cipher-text using that IV and the derived encryption key. + +.. _custom-parameters: + +Using custom parameters +----------------------- + +Let's say you have to interact with another system that is out +of your control and uses another method to encrypt data. A +method that will most certainly not match the above-described +sequence and probably not use all of the steps either. + +The Encryption library allows you to change how its encryption +and decryption processes work, so that you can easily tailor a +custom solution for such situations. + +.. note:: It is possible to use the library in this way, without + setting an *encryption_key* in your configuration file. + +All you have to do is to pass an associative array with a few +parameters to either the ``encrypt()`` or ``decrypt()`` method. +Here's an example:: + + // Assume that we have $ciphertext, $key and $hmac_key + // from on outside source + + $message = $this->encryption->decrypt( + $ciphertext, + array( + 'cipher' => 'blowfish', + 'mode' => 'cbc', + 'key' => $key, + 'hmac_digest' => 'sha256', + 'hmac_key' => $hmac_key + ) + ); + +In the above example, we are decrypting a message that was encrypted +using the Blowfish cipher in CBC mode and authenticated via a SHA-256 +HMAC. + +.. important:: Note that both 'key' and 'hmac_key' are used in this + example. When using custom parameters, encryption and HMAC keys + are not derived like the default behavior of the library is. + +Below is a list of the available options. + +However, unless you really need to and you know what you are doing, +we advise you to not change the encryption process as this could +impact security, so please do so with caution. + +============= =============== ============================= ====================================================== +Option Default value Mandatory / Optional Description +============= =============== ============================= ====================================================== +cipher N/A Yes Encryption algorithm (see :ref:`ciphers-and-modes`). +mode N/A Yes Encryption mode (see :ref:`encryption-modes`). +key N/A Yes Encryption key. +iv N/A No Initialization vector (IV). + If not provided it will be automatically generated + during encryption and looked for during decryption. +hmac TRUE No Whether to use a HMAC. + Boolean. If set to FALSE, then *hmac_digest* and + *hmac_key* will be ignored. +hmac_digest sha512 No HMAC message digest algorithm (see :ref:`digests`). +hmac_key N/A Yes, unless *hmac* is FALSE HMAC key. +raw_data FALSE No Whether the cipher-text should be raw. + Boolean. If set to TRUE, then Base64 encoding and + decoding will not be performed and HMAC will not + be a hexadecimal string. +============= =============== ============================= ====================================================== + +.. important:: ``encrypt()`` and ``decrypt()`` will return FALSE if + a mandatory parameter is not provided or if a provided + value is incorrect. This includes *hmac_key*, unless *hmac* + is set to FALSE. + +.. note:: If GCM mode is used, *hmac* will always be FALSE. This is + because GCM mode itself provides authentication. + +.. _digests: + +Supported HMAC authentication algorithms +---------------------------------------- + +For HMAC message authentication, the Encryption library supports +usage of the SHA-2 family of algorithms: + +=========== ==================== ============================ +Algorithm Raw length (bytes) Hex-encoded length (bytes) +=========== ==================== ============================ +sha512 64 128 +sha384 48 96 +sha256 32 64 +sha224 28 56 +=========== ==================== ============================ + +The reason for not including other popular algorithms, such as +MD5 or SHA1 is that they are no longer considered secure enough +and as such, we don't want to encourage their usage. +If you absolutely need to use them, it is easy to do so via PHP's +native `hash_hmac() <http://php.net/hash_hmac()>`_ function. + +Stronger algorithms of course will be added in the future as they +appear and become widely available. + +*************** +Class Reference +*************** + +.. class:: CI_Encryption + + .. method:: initialize($params) + + :param array $params: Configuration parameters + :returns: CI_Encryption instance (method chaining) + :rtype: CI_Encryption + + Initializes (configures) the library to use a different + driver, cipher, mode or key. + + Example:: + + $this->encryption->initialize( + array('mode' => 'ctr') + ); + + Please refer to the :ref:`configuration` section for detailed info. + + .. method:: encrypt($data[, $params = NULL]) + + :param string $data: Data to encrypt + :param array $params: Optional parameters + :returns: Encrypted data or FALSE on failure + :rtype: string + + Encrypts the input data and returns its ciphertext. + + Example:: + + $ciphertext = $this->encryption->encrypt('My secret message'); + + Please refer to the :ref:`custom-parameters` section for information + on the optional parameters. -Permits you to set an Mcrypt cipher. By default it uses -**MCRYPT_RIJNDAEL_256**. Example:: + .. method:: decrypt($data[, $params = NULL]) - $this->encrypt->set_cipher(MCRYPT_BLOWFISH); + :param string $data: Data to decrypt + :param array $params: Optional parameters + :returns: Decrypted data or FALSE on failure + :rtype: string -Please visit php.net for a list of `available -ciphers <http://php.net/mcrypt>`_. + Decrypts the input data and returns it in plain-text. -If you'd like to manually test whether your server supports Mcrypt you -can use:: + Example:: - echo ( ! function_exists('mcrypt_encrypt')) ? 'Nope' : 'Yup'; + echo $this->encryption->decrypt($ciphertext); -$this->encrypt->set_mode(); -============================ + Please refer to the :ref:`custom-parameters` secrion for information + on the optional parameters. -Permits you to set an Mcrypt mode. By default it uses **MCRYPT_MODE_CBC**. -Example:: + .. method:: hkdf($key[, $digest = 'sha512'[, $salt = NULL[, $length = NULL[, $info = '']]]]) - $this->encrypt->set_mode(MCRYPT_MODE_CFB); + :param string $key: Input key material + :param string $digest: A SHA-2 family digest algorithm + :param string $salt: Optional salt + :param int $length: Optional output length + :param string $info: Optional context/application-specific info + :returns: A pseudo-random key or FALSE on failure -Please visit php.net for a list of `available -modes <http://php.net/mcrypt>`_. + Derives a key from another, presumably weaker key. -$this->encrypt->encode_from_legacy($orig_data, $legacy_mode = MCRYPT_MODE_ECB, $key = ''); -========================================================================================== + This method is used internally to derive an encryption and HMAC key + from your configured *encryption_key*. -Enables you to re-encode data that was originally encrypted with -CodeIgniter 1.x to be compatible with the Encryption library in -CodeIgniter 2.x. It is only necessary to use this method if you have -encrypted data stored permanently such as in a file or database and are -on a server that supports Mcrypt. "Light" use encryption such as -encrypted session data or transitory encrypted flashdata require no -intervention on your part. However, existing encrypted Sessions will be -destroyed since data encrypted prior to 2.x will not be decoded. + It is publicly available due to its otherwise general purpose. It is + described in `RFC 5869 <https://tools.ietf.org/rfc/rfc5869.txt>`_. -.. important:: - **Why only a method to re-encode the data instead of maintaining legacy - methods for both encoding and decoding?** The algorithms in the - Encryption library have improved in CodeIgniter 2.x both for performance - and security, and we do not wish to encourage continued use of the older - methods. You can of course extend the Encryption library if you wish and - replace the new methods with the old and retain seamless compatibility - with CodeIgniter 1.x encrypted data, but this a decision that a - developer should make cautiously and deliberately, if at all. + However, as opposed to the description in RFC 5869, this implementation + doesn't support SHA1. -:: + Example:: - $new_data = $this->encrypt->encode_from_legacy($old_encrypted_string); + $hmac_key = $this->encryption->hkdf( + $key, + 'sha512', + NULL, + NULL, + 'authentication' + ); -====================== =============== ======================================================================= -Parameter Default Description -====================== =============== ======================================================================= -**$orig_data** n/a The original encrypted data from CodeIgniter 1.x's Encryption library -**$legacy_mode** MCRYPT_MODE_ECB The Mcrypt mode that was used to generate the original encrypted data. - CodeIgniter 1.x's default was MCRYPT_MODE_ECB, and it will assume that - to be the case unless overridden by this parameter. -**$key** n/a The encryption key. This it typically specified in your config file as - outlined above. -====================== =============== =======================================================================
\ No newline at end of file + // $hmac_key is a pseudo-random key with a length of 64 bytes
\ No newline at end of file diff --git a/user_guide_src/source/libraries/file_uploading.rst b/user_guide_src/source/libraries/file_uploading.rst index a295d7427..d7ba3a6c1 100644 --- a/user_guide_src/source/libraries/file_uploading.rst +++ b/user_guide_src/source/libraries/file_uploading.rst @@ -5,6 +5,13 @@ File Uploading Class CodeIgniter's File Uploading Class permits files to be uploaded. You can set various preferences, restricting the type and size of the files. +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + *********** The Process *********** @@ -224,6 +231,11 @@ Preference Default Value Options Descripti **detect_mime** TRUE TRUE/FALSE (boolean) If set to TRUE, a server side detection of the file type will be performed to avoid code injection attacks. DO NOT disable this option unless you have no other option as that would cause a security risk. +**mod_mime_fix** TRUE TRUE/FALSE (boolean) If set to TRUE, multiple filename extensions will be suffixed with an + underscore in order to avoid triggering `Apache mod_mime + <http://httpd.apache.org/docs/2.0/mod/mod_mime.html#multipleext>`_. + DO NOT turn off this option if your upload directory is public, as this + is a security risk. ============================ ================= ======================= ====================================================================== Setting preferences in a config file @@ -240,105 +252,97 @@ preferences in a config file. Class Reference *************** -The following methods are available: +.. class:: CI_Upload -$this->upload->do_upload() -========================== + .. method:: do_upload([$field = 'userfile']) -Performs the upload based on the preferences you've set. + :param string $field: Name of the form field + :returns: TRUE on success, FALSE on failure + :rtype: bool -.. note:: By default the upload routine expects the file to come from - a form field called userfile, and the form must be of type - "multipart". + Performs the upload based on the preferences you've set. -:: + .. note:: By default the upload routine expects the file to come from + a form field called userfile, and the form must be of type + "multipart". - <form method="post" action="some_action" enctype="multipart/form-data" /> + :: -If you would like to set your own field name simply pass its value to -the ``do_upload()`` method:: + <form method="post" action="some_action" enctype="multipart/form-data" /> - $field_name = "some_field_name"; - $this->upload->do_upload($field_name); + If you would like to set your own field name simply pass its value to + the ``do_upload()`` method:: -$this->upload->display_errors() -=============================== + $field_name = "some_field_name"; + $this->upload->do_upload($field_name); -Retrieves any error messages if the ``do_upload()`` method returned -false. The method does not echo automatically, it returns the data so -you can assign it however you need. + .. method:: display_errors([$open = '<p>'[, $close = '</p>']]) -Formatting Errors -***************** + :param string $open: Opening markup + :param string $close: Closing markup + :returns: Formatted error message(s) + :rtype: string -By default the above method wraps any errors within <p> tags. You can -set your own delimiters like this:: + Retrieves any error messages if the ``do_upload()`` method returned + false. The method does not echo automatically, it returns the data so + you can assign it however you need. - $this->upload->display_errors('<p>', '</p>'); + **Formatting Errors** -$this->upload->data() -===================== + By default the above method wraps any errors within <p> tags. You can + set your own delimiters like this:: -This is a helper method that returns an array containing all of the -data related to the file you uploaded. Here is the array prototype:: + $this->upload->display_errors('<p>', '</p>'); - Array - ( - [file_name] => mypic.jpg - [file_type] => image/jpeg - [file_path] => /path/to/your/upload/ - [full_path] => /path/to/your/upload/jpg.jpg - [raw_name] => mypic - [orig_name] => mypic.jpg - [client_name] => mypic.jpg - [file_ext] => .jpg - [file_size] => 22.2 - [is_image] => 1 - [image_width] => 800 - [image_height] => 600 - [image_type] => jpeg - [image_size_str] => width="800" height="200" - ) -To return one element from the array:: + .. method:: data([$index = NULL]) - $this->upload->data('file_name'); // Returns: mypic.jpg + :param string $data: Element to return instead of the full array + :returns: Information about the uploaded file + :rtype: mixed -Explanation -*********** + This is a helper method that returns an array containing all of the + data related to the file you uploaded. Here is the array prototype:: + + Array + ( + [file_name] => mypic.jpg + [file_type] => image/jpeg + [file_path] => /path/to/your/upload/ + [full_path] => /path/to/your/upload/jpg.jpg + [raw_name] => mypic + [orig_name] => mypic.jpg + [client_name] => mypic.jpg + [file_ext] => .jpg + [file_size] => 22.2 + [is_image] => 1 + [image_width] => 800 + [image_height] => 600 + [image_type] => jpeg + [image_size_str] => width="800" height="200" + ) + + To return one element from the array:: + + $this->upload->data('file_name'); // Returns: mypic.jpg + + Here's a table explaining the above-displayed array items: -Here is an explanation of the above array items. - -Item -Description -**file_name** -The name of the file that was uploaded including the file extension. -**file_type** -The file's Mime type -**file_path** -The absolute server path to the file -**full_path** -The absolute server path including the file name -**raw_name** -The file name without the extension -**orig_name** -The original file name. This is only useful if you use the encrypted -name option. -**client_name** -The file name as supplied by the client user agent, prior to any file -name preparation or incrementing. -**file_ext** -The file extension with period -**file_size** -The file size in kilobytes -**is_image** -Whether the file is an image or not. 1 = image. 0 = not. -**image_width** -Image width. -**image_height** -Image height -**image_type** -Image type. Typically the file extension without the period. -**image_size_str** -A string containing the width and height. Useful to put into an image -tag.
\ No newline at end of file + ================ ==================================================================================================== + Item Description + ================ ==================================================================================================== + file_name Name of the file that was uploaded, including the filename extension + file_type File MIME type identifier + file_path Absolute server path to the file + full_path Absolute server path, including the file name + raw_name File name, without the extension + orig_name Original file name. This is only useful if you use the encrypted name option. + client_name File name as supplied by the client user agent, prior to any file name preparation or incrementing + file_ext Filename extension, period included + file_size File size in kilobytes + is_image Whether the file is an image or not. 1 = image. 0 = not. + image_width Image width + image_height Image height + image_type Image type (usually the file name extension without the period) + image_size_str A string containing the width and height (useful to put into an image tag) + ================ ====================================================================================================
\ No newline at end of file diff --git a/user_guide_src/source/libraries/form_validation.rst b/user_guide_src/source/libraries/form_validation.rst index 032cff23b..988d6fa25 100644 --- a/user_guide_src/source/libraries/form_validation.rst +++ b/user_guide_src/source/libraries/form_validation.rst @@ -200,6 +200,7 @@ The above method takes **three** parameters as input: message. For example, if your field is named "user" you might give it a human name of "Username". #. The validation rules for this form field. +#. (optional) Set custom error messages on any rules given for current field. If not provided will use the default one. .. note:: If you would like the field name to be stored in a language file, please see :ref:`translating-field-names`. @@ -225,7 +226,9 @@ Your controller should now look like this:: $this->load->library('form_validation'); $this->form_validation->set_rules('username', 'Username', 'required'); - $this->form_validation->set_rules('password', 'Password', 'required'); + $this->form_validation->set_rules('password', 'Password', 'required', + array('required' => 'You must provide a %s.') + ); $this->form_validation->set_rules('passconf', 'Password Confirmation', 'required'); $this->form_validation->set_rules('email', 'Email', 'required'); @@ -263,7 +266,10 @@ you use this approach, you must name your array keys as indicated:: array( 'field' => 'password', 'label' => 'Password', - 'rules' => 'required' + 'rules' => 'required', + 'errors' => array( + 'required' => 'You must provide a %s.', + ), ), array( 'field' => 'passconf', @@ -285,7 +291,14 @@ Cascading Rules CodeIgniter lets you pipe multiple rules together. Let's try it. Change your rules in the third parameter of rule setting method, like this:: - $this->form_validation->set_rules('username', 'Username', 'required|min_length[5]|max_length[12]|is_unique[users.username]'); + $this->form_validation->set_rules( + 'username', 'Username', + 'required|min_length[5]|max_length[12]|is_unique[users.username]', + array( + 'required' => 'You have not provided %s.', + 'is_unique' => 'This %s already exists.' + ) + ); $this->form_validation->set_rules('password', 'Password', 'required'); $this->form_validation->set_rules('passconf', 'Password Confirmation', 'required|matches[password]'); $this->form_validation->set_rules('email', 'Email', 'required|valid_email|is_unique[users.email]'); @@ -340,10 +353,10 @@ commonly is:: set_value('field name') Open your myform.php view file and update the **value** in each field -using the ``set_value()`` function: +using the :func:`set_value()` function: -**Don't forget to include each field name in the ``set_value()`` -functions!** +**Don't forget to include each field name in the :func:`set_value()` +function calls!** :: @@ -380,11 +393,11 @@ Now reload your page and submit the form so that it triggers an error. Your form fields should now be re-populated .. note:: The :ref:`class-reference` section below - contains functions that permit you to re-populate <select> menus, + contains methods that permit you to re-populate <select> menus, radio buttons, and checkboxes. -**Important Note:** If you use an array as the name of a form field, you -must supply it as an array to the function. Example:: +.. important:: If you use an array as the name of a form field, you + must supply it as an array to the function. Example:: <input type="text" name="colors[]" value="<?php echo set_value('colors[]'); ?>" size="50" /> @@ -469,16 +482,23 @@ Setting Error Messages All of the native error messages are located in the following language file: **system/language/english/form_validation_lang.php** -To set your own custom message you can either edit that file, or use the -following method:: +To set your own global custom message for a rule, you can either +edit that file, or use the following method:: $this->form_validation->set_message('rule', 'Error Message'); +If you need to set a custom error message for a particular field on +some particular rule, use the set_rules() method:: + + $this->form_validation->set_rules('field_name', 'Field Label', 'rule1|rule2|rule3', + array('rule2' => 'Error Message on rule2 for this field_name') + ); + Where rule corresponds to the name of a particular rule, and Error Message is the text you would like displayed. -If you'd like to include a field's "human" name, or the optional -parameter some rules allow for (such as max_length), you can add the +If you'd like to include a field's "human" name, or the optional +parameter some rules allow for (such as max_length), you can add the **{field}** and **{param}** tags to your message, respectively:: $this->form_validation->set_message('min_length', '{field} must have at least {param} characters.'); @@ -559,7 +579,7 @@ Showing Errors Individually =========================== If you prefer to show an error message next to each form field, rather -than as a list, you can use the ``form_error()`` function. +than as a list, you can use the :func:`form_error()` function. Try it! Change your form so that it looks like this:: @@ -860,14 +880,15 @@ use: ========================= ========== ============================================================================================= ======================= Rule Parameter Description Example ========================= ========== ============================================================================================= ======================= -**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] -**differs** Yes Returns FALSE if the form element does not differ from the one in the parameter. differs[form_item] -**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 +**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] +**differs** Yes Returns FALSE if the form element does not differ from the one in the parameter. differs[form_item] +**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] +**min_length** Yes Returns FALSE if the form element is shorter than the parameter value. min_length[3] +**max_length** Yes Returns FALSE if the form element is longer than 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] numeric. **greater_than_equal_to** Yes Returns FALSE if the form element is less than the parameter value, greater_than_equal_to[8] @@ -876,15 +897,15 @@ Rule Parameter Description not numeric. **less_than_equal_to** Yes Returns FALSE if the form element is greater than the parameter value, less_than_equal_to[8] or not numeric. -**alpha** No Returns FALSE if the form element contains anything other than alphabetical characters. +**alpha** No Returns FALSE if the form element contains anything other than alphabetical characters. **alpha_numeric** No Returns FALSE if the form element contains anything other than alpha-numeric characters. **alpha_numeric_spaces** No Returns FALSE if the form element contains anything other than alpha-numeric characters - or spaces. Should be used after trim to avoid spaces at the beginning or end. -**alpha_dash** No Returns FALSE if the form element contains anything other than alpha-numeric characters, - underscores or dashes. -**numeric** No Returns FALSE if the form element contains anything other than numeric characters. -**integer** No Returns FALSE if the form element contains anything other than an integer. -**decimal** No Returns FALSE if the form element contains anything other than a decimal number. + or spaces. Should be used after trim to avoid spaces at the beginning or end. +**alpha_dash** No Returns FALSE if the form element contains anything other than alpha-numeric characters, + underscores or dashes. +**numeric** No Returns FALSE if the form element contains anything other than numeric characters. +**integer** No Returns FALSE if the form element contains anything other than an integer. +**decimal** No Returns FALSE if the form element contains anything other than a decimal number. **is_natural** No Returns FALSE if the form element contains anything other than a natural number: 0, 1, 2, 3, etc. **is_natural_no_zero** No Returns FALSE if the form element contains anything other than a natural @@ -933,154 +954,118 @@ Name Parameter Description Class Reference *************** -.. php:class:: Form_validation +.. class:: CI_Form_validation -The following methods are intended for use in your controller. + .. method:: set_rules($field[, $label = ''[, $rules = '']]) -$this->form_validation->set_rules() -=================================== - - .. php:method:: set_rules ($field, $label = '', $rules = '') - - :param string $field: The field name - :param string $label: The field label - :param mixed $rules: The rules, as a string with rules separated by a pipe "|", or an array or rules. - :rtype: Object + :param string $field: Field name + :param string $label: Field label + :param mixed $rules: Validation rules, as a string list separated by a pipe "|", or as an array or rules + :returns: CI_Form_validation instance (method chaining) + :rtype: CI_Form_validation Permits you to set validation rules, as described in the tutorial sections above: - - :ref:`setting-validation-rules` - - :ref:`saving-groups` + - :ref:`setting-validation-rules` + - :ref:`saving-groups` -$this->form_validation->run() -============================= - - .. php:method:: run ($group = '') + .. method:: run([$group = '']) - :param string $group: The name of the validation group to run - :rtype: Boolean + :param string $group: The name of the validation group to run + :returns: TRUE on success, FALSE if validation failed + :rtype: bool Runs the validation routines. Returns boolean TRUE on success and FALSE on failure. You can optionally pass the name of the validation group via the method, as described in: :ref:`saving-groups` -$this->form_validation->set_message() -===================================== - - .. php:method:: set_message ($lang, $val = '') + .. method:: set_message($lang[, $val = '']) - :param string $lang: The rule the message is for - :param string $val: The message - :rtype: Object + :param string $lang: The rule the message is for + :param string $val: The message + :returns: CI_Form_validation instance (method chaining) + :rtype: CI_Form_validation Permits you to set custom error messages. See :ref:`setting-error-messages` -$this->form_validation->set_data() -================================== - - .. php:method:: set_data ($data = '') + .. method:: set_error_delimiters([$prefix = '<p>'[, $suffix = '</p>']]) + + :param string $prefix: Error message prefix + :param string $suffix: Error message suffix + :returns: CI_Form_validation instance (method chaining) + :rtype: CI_Form_validation + + Sets the default prefix and suffix for error messages. + + .. method:: set_data($data) - :param array $data: The data to validate + :param array $data: Array of data validate + :returns: CI_Form_validation instance (method chaining) + :rtype: CI_Form_validation Permits you to set an array for validation, instead of using the default - $_POST array. + ``$_POST`` array. -$this->form_validation->reset_validation() -========================================== + .. method:: reset_validation() - .. php:method:: reset_validation () + :returns: CI_Form_validation instance (method chaining) + :rtype: CI_Form_validation Permits you to reset the validation when you validate more than one array. This method should be called before validating each new array. -$this->form_validation->error_array() -===================================== - - .. php:method:: error_array () + .. method:: error_array() - :rtype: Array + :returns: Array of error messages + :rtype: array Returns the error messages as an array. -.. _helper-functions: + .. method:: error_string([$prefix = ''[, $suffix = '']]) -**************** -Helper Reference -**************** + :param string $prefix: Error message prefix + :param string $suffix: Error message suffix + :returns: Error messages as a string + :rtype: string -The following helper functions are available for use in the view files -containing your forms. Note that these are procedural functions, so they -**do not** require you to prepend them with $this->form_validation. + Returns all error messages (as returned from error_array()) formatted as a + string and separated by a newline character. -form_error() -============ + .. method:: error($field[, $prefix = ''[, $suffix = '']]) -Shows an individual error message associated with the field name -supplied to the function. Example:: + :param string $field: Field name + :param string $prefix: Optional prefix + :param string $suffix: Optional suffix + :returns: Error message string + :rtype: string - <?php echo form_error('username'); ?> + Returns the error message for a specific field, optionally adding a + prefix and/or suffix to it (usually HTML tags). -The error delimiters can be optionally specified. See the -:ref:`changing-delimiters` section above. + .. method:: has_rule($field) -validation_errors() -=================== + :param string $field: Field name + :returns: TRUE if the field has rules set, FALSE if not + :rtype: bool -Shows all error messages as a string: Example:: + Checks to see if there is a rule set for the specified field. - <?php echo validation_errors(); ?> - -The error delimiters can be optionally specified. See the -:ref:`changing-delimiters` section above. - -set_value() -=========== - -Permits you to set the value of an input form or textarea. You must -supply the field name via the first parameter of the function. The -second (optional) parameter allows you to set a default value for the -form. Example:: - - <input type="text" name="quantity" value="<?php echo set_value('quantity', '0'); ?>" size="50" /> - -The above form will show "0" when loaded for the first time. - -set_select() -============ - -If you use a <select> menu, this function permits you to display the -menu item that was selected. The first parameter must contain the name -of the select menu, the second parameter must contain the value of each -item, and the third (optional) parameter lets you set an item as the -default (use boolean TRUE/FALSE). - -Example:: - - <select name="myselect"> - <option value="one" <?php echo set_select('myselect', 'one', TRUE); ?> >One</option> - <option value="two" <?php echo set_select('myselect', 'two'); ?> >Two</option> - <option value="three" <?php echo set_select('myselect', 'three'); ?> >Three</option> - </select> - -set_checkbox() -============== - -Permits you to display a checkbox in the state it was submitted. The -first parameter must contain the name of the checkbox, the second -parameter must contain its value, and the third (optional) parameter -lets you set an item as the default (use boolean TRUE/FALSE). Example:: - - <input type="checkbox" name="mycheck[]" value="1" <?php echo set_checkbox('mycheck[]', '1'); ?> /> - <input type="checkbox" name="mycheck[]" value="2" <?php echo set_checkbox('mycheck[]', '2'); ?> /> +.. _helper-functions: -set_radio() -=========== +**************** +Helper Reference +**************** -Permits you to display radio buttons in the state they were submitted. -This function is identical to the **set_checkbox()** function above. +Please refer to the :doc:`Form Helper <../helpers/form_helper>` manual for +the following functions: -:: +- :func:`form_error()` +- :func:`validation_errors()` +- :func:`set_value()` +- :func:`set_select()` +- :func:`set_checkbox()` +- :func:`set_radio()` - <input type="radio" name="myradio" value="1" <?php echo set_radio('myradio', '1', TRUE); ?> /> - <input type="radio" name="myradio" value="2" <?php echo set_radio('myradio', '2'); ?> /> +Note that these are procedural functions, so they **do not** require you +to prepend them with ``$this->form_validation``.
\ No newline at end of file diff --git a/user_guide_src/source/libraries/ftp.rst b/user_guide_src/source/libraries/ftp.rst index 05a3fdcc8..dd9440443 100644 --- a/user_guide_src/source/libraries/ftp.rst +++ b/user_guide_src/source/libraries/ftp.rst @@ -10,9 +10,19 @@ directory to be recreated remotely via FTP. .. note:: SFTP and SSL FTP protocols are not supported, only standard FTP. -********************** +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + +************************** +Working with the FTP Class +************************** + Initializing the Class -********************** +====================== Like most other classes in CodeIgniter, the FTP class is initialized in your controller using the $this->load->library function:: @@ -27,7 +37,6 @@ Usage Examples In this example a connection is opened to the FTP server, and a local file is read and uploaded in ASCII mode. The file permissions are set to 755. - :: $this->load->library('ftp'); @@ -44,7 +53,6 @@ file is read and uploaded in ASCII mode. The file permissions are set to $this->ftp->close(); In this example a list of files is retrieved from the server. - :: $this->load->library('ftp'); @@ -63,7 +71,6 @@ In this example a list of files is retrieved from the server. $this->ftp->close(); In this example a local directory is mirrored on the server. - :: $this->load->library('ftp'); @@ -79,171 +86,221 @@ In this example a local directory is mirrored on the server. $this->ftp->close(); -****************** -Function Reference -****************** +*************** +Class Reference +*************** -$this->ftp->connect() -===================== +.. class:: CI_FTP -Connects and logs into to the FTP server. Connection preferences are set -by passing an array to the function, or you can store them in a config -file. + .. method:: connect([$config = array()]) -Here is an example showing how you set preferences manually:: + :param array $config: Connection values + :returns: TRUE on success, FALSE on failure + :rtype: bool - $this->load->library('ftp'); + Connects and logs into to the FTP server. Connection preferences are set + by passing an array to the function, or you can store them in a config + file. - $config['hostname'] = 'ftp.example.com'; - $config['username'] = 'your-username'; - $config['password'] = 'your-password'; - $config['port'] = 21; - $config['passive'] = FALSE; - $config['debug'] = TRUE; + Here is an example showing how you set preferences manually:: - $this->ftp->connect($config); + $this->load->library('ftp'); -Setting FTP Preferences in a Config File -**************************************** + $config['hostname'] = 'ftp.example.com'; + $config['username'] = 'your-username'; + $config['password'] = 'your-password'; + $config['port'] = 21; + $config['passive'] = FALSE; + $config['debug'] = TRUE; -If you prefer you can store your FTP preferences in a config file. -Simply create a new file called the ftp.php, add the $config array in -that file. Then save the file at config/ftp.php and it will be used -automatically. + $this->ftp->connect($config); -Available connection options -**************************** + **Setting FTP Preferences in a Config File** -- **hostname** - the FTP hostname. Usually something like: - ftp.example.com -- **username** - the FTP username. -- **password** - the FTP password. -- **port** - The port number. Set to 21 by default. -- **debug** - TRUE/FALSE (boolean). Whether to enable debugging to - display error messages. -- **passive** - TRUE/FALSE (boolean). Whether to use passive mode. - Passive is set automatically by default. + If you prefer you can store your FTP preferences in a config file. + Simply create a new file called the ftp.php, add the $config array in + that file. Then save the file at *application/config/ftp.php* and it + will be used automatically. -$this->ftp->upload() -==================== + **Available connection options** -Uploads a file to your server. You must supply the local path and the -remote path, and you can optionally set the mode and permissions. -Example:: + ============== =============== ============================================================================= + Option name Default value Description + ============== =============== ============================================================================= + **hostname** n/a FTP hostname (usually something like: ftp.example.com) + **username** n/a FTP username + **password** n/a FTP password + **port** 21 FTP server port number + **debug** FALSE TRUE/FALSE (boolean): Whether to enable debugging to display error messages + **passive** TRUE TRUE/FALSE (boolean): Whether to use passive mode + ============== =============== ============================================================================= - $this->ftp->upload('/local/path/to/myfile.html', '/public_html/myfile.html', 'ascii', 0775); + .. method:: upload($locpath, $rempath[, $mode = 'auto'[, $permissions = NULL]]) -**Mode options are:** ascii, binary, and auto (the default). If auto is -used it will base the mode on the file extension of the source file. + :param string $locpath: Local file path + :param string $rempath: Remote file path + :param string $mode: FTP mode, defaults to 'auto' (options are: 'auto', 'binary', 'ascii') + :param int $permissions: File permissions (octal) + :returns: TRUE on success, FALSE on failure + :rtype: bool -If set, permissions have to be passed as an octal value. + Uploads a file to your server. You must supply the local path and the + remote path, and you can optionally set the mode and permissions. + Example:: -$this->ftp->download() -====================== + $this->ftp->upload('/local/path/to/myfile.html', '/public_html/myfile.html', 'ascii', 0775); -Downloads a file from your server. You must supply the remote path and -the local path, and you can optionally set the mode. Example:: + If 'auto' mode is used it will base the mode on the file extension of the source file. - $this->ftp->download('/public_html/myfile.html', '/local/path/to/myfile.html', 'ascii'); + If set, permissions have to be passed as an octal value. -**Mode options are:** ascii, binary, and auto (the default). If auto is -used it will base the mode on the file extension of the source file. + .. method:: download($rempath, $locpath[, $mode = 'auto']) -Returns FALSE if the download does not execute successfully (including -if PHP does not have permission to write the local file) + :param string $rempath: Remote file path + :param string $locpath: Local file path + :param string $mode: FTP mode, defaults to 'auto' (options are: 'auto', 'binary', 'ascii') + :returns: TRUE on success, FALSE on failure + :rtype: bool -$this->ftp->rename() -==================== + Downloads a file from your server. You must supply the remote path and + the local path, and you can optionally set the mode. Example:: -Permits you to rename a file. Supply the source file name/path and the -new file name/path. + $this->ftp->download('/public_html/myfile.html', '/local/path/to/myfile.html', 'ascii'); -:: + If 'auto' mode is used it will base the mode on the file extension of the source file. - // Renames green.html to blue.html - $this->ftp->rename('/public_html/foo/green.html', '/public_html/foo/blue.html'); + Returns FALSE if the download does not execute successfully + (including if PHP does not have permission to write the local file). -$this->ftp->move() -================== + .. method:: rename($old_file, $new_file[, $move = FALSE]) -Lets you move a file. Supply the source and destination paths:: + :param string $old_file: Old file name + :param string $new_file: New file name + :param bool $move: Whether a move is being performed + :returns: TRUE on success, FALSE on failure + :rtype: bool - // Moves blog.html from "joe" to "fred" - $this->ftp->move('/public_html/joe/blog.html', '/public_html/fred/blog.html'); + Permits you to rename a file. Supply the source file name/path and the new file name/path. + :: -Note: if the destination file name is different the file will be -renamed. + // Renames green.html to blue.html + $this->ftp->rename('/public_html/foo/green.html', '/public_html/foo/blue.html'); -$this->ftp->delete_file() -========================== + .. method:: move($old_file, $new_file) -Lets you delete a file. Supply the source path with the file name. + :param string $old_file: Old file name + :param string $new_file: New file name + :returns: TRUE on success, FALSE on failure + :rtype: bool -:: + Lets you move a file. Supply the source and destination paths:: - $this->ftp->delete_file('/public_html/joe/blog.html'); + // Moves blog.html from "joe" to "fred" + $this->ftp->move('/public_html/joe/blog.html', '/public_html/fred/blog.html'); -$this->ftp->delete_dir() -========================= + .. note:: If the destination file name is different the file will be renamed. -Lets you delete a directory and everything it contains. Supply the -source path to the directory with a trailing slash. + .. method:: delete_file($filepath) -**Important** Be VERY careful with this function. It will recursively -delete **everything** within the supplied path, including sub-folders -and all files. Make absolutely sure your path is correct. Try using the -list_files() function first to verify that your path is correct. + :param string $filepath: Path to file to delete + :returns: TRUE on success, FALSE on failure + :rtype: bool -:: + Lets you delete a file. Supply the source path with the file name. + :: - $this->ftp->delete_dir('/public_html/path/to/folder/'); + $this->ftp->delete_file('/public_html/joe/blog.html'); -$this->ftp->list_files() -========================= + .. method:: delete_dir($filepath) -Permits you to retrieve a list of files on your server returned as an -array. You must supply the path to the desired directory. + :param string $filepath: Path to directory to delete + :returns: TRUE on success, FALSE on failure + :rtype: bool -:: + Lets you delete a directory and everything it contains. Supply the + source path to the directory with a trailing slash. - $list = $this->ftp->list_files('/public_html/'); + .. important:: Be VERY careful with this method! + It will recursively delete **everything** within the supplied path, + including sub-folders and all files. Make absolutely sure your path + is correct. Try using ``list_files()`` first to verify that your path is correct. - print_r($list); + :: -$this->ftp->mirror() -==================== + $this->ftp->delete_dir('/public_html/path/to/folder/'); -Recursively reads a local folder and everything it contains (including -sub-folders) and creates a mirror via FTP based on it. Whatever the -directory structure of the original file path will be recreated on the -server. You must supply a source path and a destination path:: + .. method:: list_files([$path = '.']) - $this->ftp->mirror('/path/to/myfolder/', '/public_html/myfolder/'); + :param string $path: Directory path + :returns: An array list of files or FALSE on failure + :rtype: array -$this->ftp->mkdir() -=================== + Permits you to retrieve a list of files on your server returned as an + array. You must supply the path to the desired directory. + :: -Lets you create a directory on your server. Supply the path ending in -the folder name you wish to create, with a trailing slash. Permissions -can be set by passed an octal value in the second parameter (if you are -running PHP 5). + $list = $this->ftp->list_files('/public_html/'); + print_r($list); -:: + .. method:: mirror($locpath, $rempath) + + :param string $locpath: Local path + :param string $rempath: Remote path + :returns: TRUE on success, FALSE on failure + :rtype: bool + + Recursively reads a local folder and everything it contains (including + sub-folders) and creates a mirror via FTP based on it. Whatever the + directory structure of the original file path will be recreated on the + server. You must supply a source path and a destination path:: + + $this->ftp->mirror('/path/to/myfolder/', '/public_html/myfolder/'); + + .. method:: mkdir($path[, $permissions = NULL]) + + :param string $path: Path to directory to create + :param int $permissions: Permissions (octal) + :returns: TRUE on success, FALSE on failure + :rtype: bool + + Lets you create a directory on your server. Supply the path ending in + the folder name you wish to create, with a trailing slash. + + Permissions can be set by passing an octal value in the second parameter. + :: + + // Creates a folder named "bar" + $this->ftp->mkdir('/public_html/foo/bar/', DIR_WRITE_MODE); + + .. method:: chmod($path, $perm) + + :param string $path: Path to alter permissions for + :param int $perm: Permissions (octal) + :returns: TRUE on success, FALSE on failure + :rtype: bool + + Permits you to set file permissions. Supply the path to the file or + directory you wish to alter permissions on:: + + // Chmod "bar" to 777 + $this->ftp->chmod('/public_html/foo/bar/', DIR_WRITE_MODE); + + .. method:: changedir($path[, $suppress_debug = FALSE]) - // Creates a folder named "bar" - $this->ftp->mkdir('/public_html/foo/bar/', DIR_WRITE_MODE); + :param string $path: Directory path + :param bool $suppress_debug: Whether to turn off debug messages for this command + :returns: TRUE on success, FALSE on failure + :rtype: bool -$this->ftp->chmod() -=================== + Changes the current working directory to the specified path. -Permits you to set file permissions. Supply the path to the file or -folder you wish to alter permissions on:: + The ``$suppress_debug`` parameter is useful in case you want to use this method + as an ``is_dir()`` alternative for FTP. - // Chmod "bar" to 777 - $this->ftp->chmod('/public_html/foo/bar/', DIR_WRITE_MODE); + .. method:: close() -$this->ftp->close(); -==================== + :returns: TRUE on success, FALSE on failure + :rtype: bool -Closes the connection to your server. It's recommended that you use this -when you are finished uploading. + Closes the connection to your server. It's recommended that you use this + when you are finished uploading.
\ No newline at end of file diff --git a/user_guide_src/source/libraries/image_lib.rst b/user_guide_src/source/libraries/image_lib.rst index dcdccbd92..16acf090b 100644 --- a/user_guide_src/source/libraries/image_lib.rst +++ b/user_guide_src/source/libraries/image_lib.rst @@ -19,6 +19,13 @@ ImageMagick order for the script to calculate the image properties. The image processing, however, will be performed with the library you specify. +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + ********************** Initializing the Class ********************** @@ -29,7 +36,7 @@ in your controller using the $this->load->library function:: $this->load->library('image_lib'); Once the library is loaded it will be ready for use. The image library -object you will use to call all functions is: $this->image_lib +object you will use to call all functions is: ``$this->image_lib`` Processing an Image =================== @@ -67,18 +74,17 @@ ratio. The thumbnail will be called *mypic_thumb.jpg* while processing images you may need to limit their maximum size, and/or adjust PHP memory limits. -Processing Functions -==================== +Processing Methods +================== -There are four available processing functions: +There are four available processing methods: - $this->image_lib->resize() - $this->image_lib->crop() - $this->image_lib->rotate() - $this->image_lib->watermark() -- $this->image_lib->clear() -These functions return boolean TRUE upon success and FALSE for failure. +These methods return boolean TRUE upon success and FALSE for failure. If they fail you can retrieve the error message using this function:: echo $this->image_lib->display_errors(); @@ -88,7 +94,7 @@ error upon failure, like this:: if ( ! $this->image_lib->resize()) { - echo $this->image_lib->display_errors(); + echo $this->image_lib->display_errors(); } .. note:: You can optionally specify the HTML formatting to be applied to @@ -97,6 +103,8 @@ error upon failure, like this:: $this->image_lib->display_errors('<p>', '</p>'); +.. _processing-preferences: + Preferences =========== @@ -146,7 +154,7 @@ Preference Default Value Options pixels. If the source image size does not allow perfect resizing to those dimensions, this setting determines which axis should be used as the hard value. "auto" sets the axis automatically based on whether the - image is taller then wider, or vice versa. + image is taller than wider, or vice versa. **rotation_angle** None 90, 180, 270, vrt, hor Specifies the angle of rotation when rotating images. Note that PHP X rotates counter-clockwise, so a 90 degree rotation to the right must be specified as 270. @@ -162,134 +170,10 @@ Setting preferences in a config file If you prefer not to set preferences using the above method, you can instead put them into a config file. Simply create a new file called image_lib.php, add the $config array in that file. Then save the file -in: config/image_lib.php and it will be used automatically. You will -NOT need to use the $this->image_lib->initialize function if you save +in *config/image_lib.php* and it will be used automatically. You will +NOT need to use the ``$this->image_lib->initialize()`` method if you save your preferences in a config file. -$this->image_lib->resize() -=========================== - -The image resizing function lets you resize the original image, create a -copy (with or without resizing), or create a thumbnail image. - -For practical purposes there is no difference between creating a copy -and creating a thumbnail except a thumb will have the thumbnail marker -as part of the name (ie, mypic_thumb.jpg). - -All preferences listed in the table above are available for this -function except these three: rotation_angle, x_axis, and y_axis. - -Creating a Thumbnail --------------------- - -The resizing function will create a thumbnail file (and preserve the -original) if you set this preference to TRUE:: - - $config['create_thumb'] = TRUE; - -This single preference determines whether a thumbnail is created or not. - -Creating a Copy ---------------- - -The resizing function will create a copy of the image file (and preserve -the original) if you set a path and/or a new filename using this -preference:: - - $config['new_image'] = '/path/to/new_image.jpg'; - -Notes regarding this preference: - -- If only the new image name is specified it will be placed in the same - folder as the original -- If only the path is specified, the new image will be placed in the - destination with the same name as the original. -- If both the path and image name are specified it will placed in its - own destination and given the new name. - -Resizing the Original Image ---------------------------- - -If neither of the two preferences listed above (create_thumb, and -new_image) are used, the resizing function will instead target the -original image for processing. - -$this->image_lib->crop() -========================= - -The cropping function works nearly identically to the resizing function -except it requires that you set preferences for the X and Y axis (in -pixels) specifying where to crop, like this:: - - $config['x_axis'] = '100'; - $config['y_axis'] = '40'; - -All preferences listed in the table above are available for this -function except these: rotation_angle, create_thumb, new_image. - -Here's an example showing how you might crop an image:: - - $config['image_library'] = 'imagemagick'; - $config['library_path'] = '/usr/X11R6/bin/'; - $config['source_image'] = '/path/to/image/mypic.jpg'; - $config['x_axis'] = '100'; - $config['y_axis'] = '60'; - - $this->image_lib->initialize($config); - - if ( ! $this->image_lib->crop()) - { - 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. - -$this->image_lib->rotate() -=========================== - -The image rotation function requires that the angle of rotation be set -via its preference:: - - $config['rotation_angle'] = '90'; - -There are 5 rotation options: - -#. 90 - rotates counter-clockwise by 90 degrees. -#. 180 - rotates counter-clockwise by 180 degrees. -#. 270 - rotates counter-clockwise by 270 degrees. -#. hor - flips the image horizontally. -#. vrt - flips the image vertically. - -Here's an example showing how you might rotate an image:: - - $config['image_library'] = 'netpbm'; - $config['library_path'] = '/usr/bin/'; - $config['source_image'] = '/path/to/image/mypic.jpg'; - $config['rotation_angle'] = 'hor'; - - $this->image_lib->initialize($config); - - if ( ! $this->image_lib->rotate()) - { - echo $this->image_lib->display_errors(); - } - -$this->image_lib->clear() -========================== - -The clear function resets all of the values used when processing an -image. You will want to call this if you are processing images in a -loop. - -:: - - $this->image_lib->clear(); - - ****************** Image Watermarking ****************** @@ -310,10 +194,12 @@ There are two types of watermarking that you can use: image (usually a transparent PNG or GIF) containing your watermark over the source image. +.. _watermarking: + Watermarking an Image ===================== -Just as with the other functions (resizing, cropping, and rotating) the +Just as with the other methods (resizing, cropping, and rotating) the general process for watermarking involves setting the preferences corresponding to the action you intend to perform, then calling the watermark function. Here is an example:: @@ -423,3 +309,164 @@ Preference Default Value Options Description coordinate to a pixel representative of the color you want to be transparent. ======================= =================== =================== ========================================================================== + +*************** +Class Reference +*************** + +.. class:: CI_Image_lib + + .. method:: initialize([$props = array()]) + + :param array $props: Image processing preferences + :returns: TRUE on success, FALSE in case of invalid settings + :rtype: bool + + Initializes the class for processing an image. + + .. method:: resize() + + :returns: TRUE on success, FALSE on failure + :rtype: bool + + The image resizing method lets you resize the original image, create a + copy (with or without resizing), or create a thumbnail image. + + For practical purposes there is no difference between creating a copy + and creating a thumbnail except a thumb will have the thumbnail marker + as part of the name (i.e. mypic_thumb.jpg). + + All preferences listed in the :ref:`processing-preferences` table are available for this + method except these three: *rotation_angle*, *x_axis* and *y_axis*. + + **Creating a Thumbnail** + + The resizing method will create a thumbnail file (and preserve the + original) if you set this preference to TRUE:: + + $config['create_thumb'] = TRUE; + + This single preference determines whether a thumbnail is created or not. + + **Creating a Copy** + + The resizing method will create a copy of the image file (and preserve + the original) if you set a path and/or a new filename using this + preference:: + + $config['new_image'] = '/path/to/new_image.jpg'; + + Notes regarding this preference: + + - If only the new image name is specified it will be placed in the same + folder as the original + - If only the path is specified, the new image will be placed in the + destination with the same name as the original. + - If both the path and image name are specified it will placed in its + own destination and given the new name. + + **Resizing the Original Image** + + If neither of the two preferences listed above (create_thumb, and + new_image) are used, the resizing method will instead target the + original image for processing. + + .. method:: crop() + + :returns: TRUE on success, FALSE on failure + :rtype: bool + + The cropping method works nearly identically to the resizing function + except it requires that you set preferences for the X and Y axis (in + pixels) specifying where to crop, like this:: + + $config['x_axis'] = 100; + $config['y_axis'] = 40; + + All preferences listed in the :ref:`processing-preferences` table are available for this + method except these: *rotation_angle*, *create_thumb* and *new_image*. + + Here's an example showing how you might crop an image:: + + $config['image_library'] = 'imagemagick'; + $config['library_path'] = '/usr/X11R6/bin/'; + $config['source_image'] = '/path/to/image/mypic.jpg'; + $config['x_axis'] = 100; + $config['y_axis'] = 60; + + $this->image_lib->initialize($config); + + if ( ! $this->image_lib->crop()) + { + echo $this->image_lib->display_errors(); + } + + .. note:: Without a visual interface it is difficult to crop images, so this + method 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. + + .. method:: rotate() + + :returns: TRUE on success, FALSE on failure + :rtype: bool + + The image rotation method requires that the angle of rotation be set + via its preference:: + + $config['rotation_angle'] = '90'; + + There are 5 rotation options: + + #. 90 - rotates counter-clockwise by 90 degrees. + #. 180 - rotates counter-clockwise by 180 degrees. + #. 270 - rotates counter-clockwise by 270 degrees. + #. hor - flips the image horizontally. + #. vrt - flips the image vertically. + + Here's an example showing how you might rotate an image:: + + $config['image_library'] = 'netpbm'; + $config['library_path'] = '/usr/bin/'; + $config['source_image'] = '/path/to/image/mypic.jpg'; + $config['rotation_angle'] = 'hor'; + + $this->image_lib->initialize($config); + + if ( ! $this->image_lib->rotate()) + { + echo $this->image_lib->display_errors(); + } + + .. method:: watermark() + + :returns: TRUE on success, FALSE on failure + :rtype: bool + + Creates a watermark over an image, please refer to the :ref:`watermarking` + section for more info. + + .. method:: clear() + + :rtype: void + + The clear method resets all of the values used when processing an + image. You will want to call this if you are processing images in a + loop. + + :: + + $this->image_lib->clear(); + + .. method:: display_errors([$open = '<p>[, $close = '</p>']]) + + :param string $open: Error message opening tag + :param string $close: Error message closing tag + :returns: Error messages + :rtype: string + + Returns all detected errors formatted as a string. + :: + + echo $this->image_lib->diplay_errors();
\ No newline at end of file diff --git a/user_guide_src/source/libraries/input.rst b/user_guide_src/source/libraries/input.rst index fb245d7cd..6162a6664 100644 --- a/user_guide_src/source/libraries/input.rst +++ b/user_guide_src/source/libraries/input.rst @@ -10,6 +10,13 @@ The Input Class serves two purposes: .. note:: This class is initialized automatically by the system so there is no need to do it manually. +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + Security Filtering ================== @@ -17,7 +24,7 @@ The security filtering method is called automatically when a new :doc:`controller <../general/controllers>` is invoked. It does the following: -- If $config['allow_get_array'] is FALSE (default is TRUE), destroys +- If ``$config['allow_get_array']`` is FALSE (default is TRUE), destroys the global GET array. - Destroys all global variables in the event register_globals is turned on. @@ -25,7 +32,8 @@ following: (and a few other) characters. - Provides XSS (Cross-site Scripting Hacks) filtering. This can be enabled globally, or upon request. -- Standardizes newline characters to \\n(In Windows \\r\\n) +- Standardizes newline characters to ``PHP_EOL`` (\\n in UNIX-based OSes, + \\r\\n under Windows). This is configurable. XSS Filtering ============= @@ -33,7 +41,7 @@ XSS Filtering The Input class has the ability to filter input automatically to prevent cross-site scripting attacks. If you want the filter to run automatically every time it encounters POST or COOKIE data you can -enable it by opening your application/config/config.php file and setting +enable it by opening your *application/config/config.php* file and setting this:: $config['global_xss_filtering'] = TRUE; @@ -44,7 +52,7 @@ information on using XSS Filtering in your application. Using POST, GET, COOKIE, or SERVER Data ======================================= -CodeIgniter comes with four helper methods that let you fetch POST, GET, +CodeIgniter comes with helper methods that let you fetch POST, GET, COOKIE or SERVER items. The main advantage of using the provided methods rather than fetching an item directly (``$_POST['something']``) is that the methods will check to see if the item is set and return @@ -58,270 +66,344 @@ With CodeIgniter's built in methods you can simply do this:: $something = $this->input->post('something'); -The four methods are: +The main methods are: -- $this->input->post() -- $this->input->get() -- $this->input->cookie() -- $this->input->server() +- ``$this->input->post()`` +- ``$this->input->get()`` +- ``$this->input->cookie()`` +- ``$this->input->server()`` -$this->input->post() -==================== +Using the php://input stream +============================ -The first parameter will contain the name of the POST item you are -looking for:: +If you want to utilize the PUT, DELETE, PATCH or other exotic request +methods, they can only be accessed via a special input stream, that +can only be read once. This isn't as easy as just reading from e.g. +the ``$_POST`` array, because it will always exist and you can try +and access multiple variables without caring that you might only have +one shot at all of the POST data. - $this->input->post('some_data'); +CodeIgniter will take care of that for you, and you can access data +from the **php://input** stream at any time, just by calling the +``input_stream()`` method:: -The method returns NULL if the item you are attempting to retrieve -does not exist. + $this->input->input_stream('key'); -The second optional parameter lets you run the data through the XSS -filter. It's enabled by setting the second parameter to boolean TRUE; +Similar to other methods such as ``get()`` and ``post()``, if the +requested data is not found, it will return NULL and you can also +decide whether to run the data through ``xss_clean()`` by passing +a boolean value as the second parameter:: -:: + $this->input->input_stream('key', TRUE); // XSS Clean + $this->input->input_stream('key', FALSE); // No XSS filter - $this->input->post('some_data', TRUE); +.. note:: You can utilize ``method()`` in order to know if you're reading + PUT, DELETE or PATCH data. -To return an array of all POST items call without any parameters. +*************** +Class Reference +*************** -To return all POST items and pass them through the XSS filter set the -first parameter NULL while setting the second parameter to boolean; +.. class:: CI_Input -The method returns NULL if there are no items in the POST. + .. method:: post([$index = NULL[, $xss_clean = NULL]]) -:: + :param string $index: POST parameter name + :param bool $xss_clean: Whether to apply XSS filtering + :returns: $_POST if no parameters supplied, otherwise the POST value if found or NULL if not + :rtype: mixed - $this->input->post(NULL, TRUE); // returns all POST items with XSS filter - $this->input->post(); // returns all POST items without XSS filter + The first parameter will contain the name of the POST item you are + looking for:: -$this->input->get() -=================== + $this->input->post('some_data'); -This method is identical to the POST method, only it fetches GET data -:: + The method returns NULL if the item you are attempting to retrieve + does not exist. - $this->input->get('some_data', TRUE); + The second optional parameter lets you run the data through the XSS + filter. It's enabled by setting the second parameter to boolean TRUE + or by setting your ``$config['global_xss_filtering']`` to TRUE. + :: -To return an array of all GET items call without any parameters. + $this->input->post('some_data', TRUE); -To return all GET items and pass them through the XSS filter set the -first parameter NULL while setting the second parameter to boolean; + To return an array of all POST items call without any parameters. -The method returns NULL if there are no items in the GET. + To return all POST items and pass them through the XSS filter set the + first parameter NULL while setting the second parameter to boolean TRUE. + :: -:: + $this->input->post(NULL, TRUE); // returns all POST items with XSS filter + $this->input->post(NULL, FALSE); // returns all POST items without XSS filter - $this->input->get(NULL, TRUE); // returns all GET items with XSS filter - $this->input->get(); // returns all GET items without XSS filtering + .. method:: get([$index = NULL[, $xss_clean = NULL]]) + :param string $index: GET parameter name + :param bool $xss_clean: Whether to apply XSS filtering + :returns: $_GET if no parameters supplied, otherwise the GET value if found or NULL if not + :rtype: mixed -$this->input->post_get() -======================== + This method is identical to ``post()``, only it fetches GET data. + :: -This method will search through both the POST and GET streams for -data, looking first in POST, and then in GET:: + $this->input->get('some_data', TRUE); - $this->input->post_get('some_data', TRUE); + To return an array of all GET items call without any parameters. -$this->input->get_post() -======================== + To return all GET items and pass them through the XSS filter set the + first parameter NULL while setting the second parameter to boolean TRUE. + :: -This method will search through both the POST and GET streams for -data, looking first in GET, and then in POST:: + $this->input->get(NULL, TRUE); // returns all GET items with XSS filter + $this->input->get(NULL, FALSE); // returns all GET items without XSS filtering - $this->input->get_post('some_data', TRUE); + .. method:: post_get($index[, $xss_clean = NULL]) -$this->input->cookie() -====================== + :param string $index: POST/GET parameter name + :param bool $xss_clean: Whether to apply XSS filtering + :returns: POST/GET value if found, NULL if not + :rtype: mixed -This method is identical to the POST method, only it fetches cookie data -:: + This method works pretty much the same way as ``post()`` and ``get()``, + only combined. It will search through both POST and GET streams for data, + looking in POST first, and then in GET:: - $this->input->cookie('some_cookie'); - $this->input->cookie('some_cookie, TRUE); // with XSS filter + $this->input->post_get('some_data', TRUE); + .. method:: get_post($index[, $xss_clean = NULL]) -$this->input->server() -====================== + :param string $index: GET/POST parameter name + :param bool $xss_clean: Whether to apply XSS filtering + :returns: GET/POST value if found, NULL if not + :rtype: mixed -This method is identical to the above methods, only it fetches server -server data:: + This method works the same way as ``post_get()`` only it looks for GET + data first. - $this->input->server('some_data'); + $this->input->get_post('some_data', TRUE); -Using the php://input stream -============================ + .. note:: This method used to act EXACTLY like ``post_get()``, but it's + behavior has changed in CodeIgniter 3.0. -If you want to utilize the PUT, DELETE, PATCH or other exotic request -methods, they can only be accessed via a special input stream, that -can only be read once. This isn't as easy as just reading from e.g. -the ``$_POST`` array, because it will always exist and you can try -and access multiple variables without caring that you might only have -one shot at all of the POST data. + .. method:: cookie([$index = NULL[, $xss_clean = NULL]]) -CodeIgniter will take care of that for you, and you can access data -from the **php://input** stream at any time, just by calling the -``input_stream()`` method:: + :param string $index: COOKIE parameter name + :param bool $xss_clean: Whether to apply XSS filtering + :returns: $_COOKIE if no parameters supplied, otherwise the COOKIE value if found or NULL if not + :rtype: mixed - $this->input->input_stream('key'); + This method is identical to ``post()`` and ``get()``, only it fetches cookie + data:: -Similar to the methods above, if the requested data is not found, it -will return NULL and you can also decide whether to run the data -through ``xss_clean()`` by passing a boolean value as the second -parameter:: + $this->input->cookie('some_cookie'); + $this->input->cookie('some_cookie, TRUE); // with XSS filter - $this->input->input_stream('key', TRUE); // XSS Clean - $this->input->input_stream('key', FALSE); // No XSS filter + .. method:: server($index[, $xss_clean = NULL]) -.. note:: You can utilize method() in order to know if you're reading - PUT, DELETE or PATCH data. + :param string $index: Value name + :param bool $xss_clean: Whether to apply XSS filtering + :returns: $_SERVER item value if found, NULL if not + :rtype: mixed + + This method is identical to the ``post()``, ``get()`` and ``cookie()`` + methods, only it fetches server data (``$_SERVER``):: + + $this->input->server('some_data'); + + .. method:: input_stream([$index = NULL[, $xss_clean = NULL]]) + + :param string $index: Key name + :param bool $xss_clean: Whether to apply XSS filtering + :returns: Input stream array if no parameters supplied, otherwise the specified value if found or NULL if not + :rtype: mixed + + This method is identical to ``get()``, ``post()`` and ``cookie()``, + only it fetches the *php://input* stream data. + + .. method:: set_cookie($name = ''[, $value = ''[, $expire = ''[, $domain = ''[, $path = '/'[, $prefix = ''[, $secure = FALSE[, $httponly = FALSE]]]]]]]) + + :param mixed $name: Cookie name or an array of parameters + :param string $value: Cookie value + :param int $expire: Cookie expiration time in seconds + :param string $domain: Cookie domain + :param string $path: Cookie path + :param string $prefix: Cookie name prefix + :param bool $secure: Whether to only transfer the cookie through HTTPS + :param bool $httponly: Whether to only make the cookie accessible for HTTP requests (no JavaScript) + :rtype: void + + + Sets a cookie containing the values you specify. There are two ways to + pass information to this method so that a cookie can be set: Array + Method, and Discrete Parameters: + + **Array Method** + + Using this method, an associative array is passed to the first + parameter:: + + $cookie = array( + 'name' => 'The Cookie Name', + 'value' => 'The Value', + 'expire' => '86500', + 'domain' => '.some-domain.com', + 'path' => '/', + 'prefix' => 'myprefix_', + 'secure' => TRUE + ); -$this->input->set_cookie() -========================== + $this->input->set_cookie($cookie); -Sets a cookie containing the values you specify. There are two ways to -pass information to this method so that a cookie can be set: Array -Method, and Discrete Parameters: + **Notes** -Array Method -^^^^^^^^^^^^ + Only the name and value are required. To delete a cookie set it with the + expiration blank. -Using this method, an associative array is passed to the first -parameter:: + The expiration is set in **seconds**, which will be added to the current + time. Do not include the time, but rather only the number of seconds + from *now* that you wish the cookie to be valid. If the expiration is + set to zero the cookie will only last as long as the browser is open. - $cookie = array( - 'name' => 'The Cookie Name', - 'value' => 'The Value', - 'expire' => '86500', - 'domain' => '.some-domain.com', - 'path' => '/', - 'prefix' => 'myprefix_', - 'secure' => TRUE - ); + For site-wide cookies regardless of how your site is requested, add your + URL to the **domain** starting with a period, like this: + .your-domain.com - $this->input->set_cookie($cookie); + The path is usually not needed since the method sets a root path. -**Notes:** + The prefix is only needed if you need to avoid name collisions with + other identically named cookies for your server. -Only the name and value are required. To delete a cookie set it with the -expiration blank. + The secure boolean is only needed if you want to make it a secure cookie + by setting it to TRUE. -The expiration is set in **seconds**, which will be added to the current -time. Do not include the time, but rather only the number of seconds -from *now* that you wish the cookie to be valid. If the expiration is -set to zero the cookie will only last as long as the browser is open. + **Discrete Parameters** -For site-wide cookies regardless of how your site is requested, add your -URL to the **domain** starting with a period, like this: -.your-domain.com + If you prefer, you can set the cookie by passing data using individual + parameters:: -The path is usually not needed since the method sets a root path. + $this->input->set_cookie($name, $value, $expire, $domain, $path, $prefix, $secure); -The prefix is only needed if you need to avoid name collisions with -other identically named cookies for your server. + .. method:: ip_address() -The secure boolean is only needed if you want to make it a secure cookie -by setting it to TRUE. + :returns: Visitor's IP address or '0.0.0.0' if not valid + :rtype: string -Discrete Parameters -^^^^^^^^^^^^^^^^^^^ + Returns the IP address for the current user. If the IP address is not + valid, the method will return '0.0.0.0':: -If you prefer, you can set the cookie by passing data using individual -parameters:: + echo $this->input->ip_address(); - $this->input->set_cookie($name, $value, $expire, $domain, $path, $prefix, $secure); + .. important:: This method takes into account the ``$config['proxy_ips']`` + setting and will return the reported HTTP_X_FORWARDED_FOR, + HTTP_CLIENT_IP, HTTP_X_CLIENT_IP or HTTP_X_CLUSTER_CLIENT_IP + address for the allowed IP addresses. + .. method:: valid_ip($ip[, $which = '']) -$this->input->ip_address() -========================== + :param string $ip: IP address + :param string $which: IP protocol ('ipv4' or 'ipv6') + :returns: TRUE if the address is valid, FALSE if not + :rtype: bool -Returns the IP address for the current user. If the IP address is not -valid, the method will return an IP of: 0.0.0.0 + Takes an IP address as input and returns TRUE or FALSE (boolean) depending + on whether it is valid or not. -:: + .. note:: The $this->input->ip_address() method above automatically + validates the IP address. - echo $this->input->ip_address(); + :: -$this->input->valid_ip($ip) -=========================== + if ( ! $this->input->valid_ip($ip)) + { + echo 'Not Valid'; + } + else + { + echo 'Valid'; + } -Takes an IP address as input and returns TRUE or FALSE (boolean) if it -is valid or not. + Accepts an optional second string parameter of 'ipv4' or 'ipv6' to specify + an IP format. The default checks for both formats. -.. note:: The $this->input->ip_address() method above automatically - validates the IP address. + .. method:: user_agent() -:: + :returns: User agent string or NULL if not set + :rtype: mixed - if ( ! $this->input->valid_ip($ip)) - { - echo 'Not Valid'; - } - else - { - echo 'Valid'; - } + Returns the user agent string (web browser) being used by the current user, + or NULL if it's not available. + :: -Accepts an optional second string parameter of 'ipv4' or 'ipv6' to specify -an IP format. The default checks for both formats. + echo $this->input->user_agent(); -$this->input->user_agent() -========================== + See the :doc:`User Agent Class <user_agent>` for methods which extract + information from the user agent string. -Returns the user agent (web browser) being used by the current user. -Returns FALSE if it's not available. + .. method:: request_headers([$xss_clean = FALSE]) -:: + :param bool $xss_clean: Whether to apply XSS filtering + :returns: An array of HTTP request headers + :rtype: array - echo $this->input->user_agent(); + Returns an array of HTTP request headers. + Useful if running in a non-Apache environment where + `apache_request_headers() <http://php.net/apache_request_headers>`_ + will not be supported. + :: -See the :doc:`User Agent Class <user_agent>` for methods which extract -information from the user agent string. + $headers = $this->input->request_headers(); -$this->input->request_headers() -=============================== + .. method:: get_request_header($index[, $xss_clean = FALSE]) -Useful if running in a non-Apache environment where -`apache_request_headers() <http://php.net/apache_request_headers>`_ -will not be supported. Returns an array of headers. + :param string $index: HTTP request header name + :param bool $xss_clean: Whether to apply XSS filtering + :returns: An HTTP request header or NULL if not found + :rtype: string -:: + Returns a single member of the request headers array or NULL + if the searched header is not found. + :: - $headers = $this->input->request_headers(); + $this->input->get_request_header('some-header', TRUE); -$this->input->get_request_header() -================================== + .. method:: is_ajax_request() -Returns a single member of the request headers array. + :returns: TRUE if it is an Ajax request, FALSE if not + :rtype: bool -:: + Checks to see if the HTTP_X_REQUESTED_WITH server header has been + set, and returns boolean TRUE if it is or FALSE if not. - $this->input->get_request_header('some-header', TRUE); + .. method:: is_cli_request() -$this->input->is_ajax_request() -=============================== + :returns: TRUE if it is a CLI request, FALSE if not + :rtype: bool -Checks to see if the HTTP_X_REQUESTED_WITH server header has been -set, and returns a boolean response. + Checks to see if the application was run from the command-line + interface. -$this->input->is_cli_request() -============================== + .. note:: This method checks both the PHP SAPI name currently in use + and if the ``STDIN`` constant is defined, which is usually a + failsafe way to see if PHP is being run via the command line. -Checks to see if the STDIN constant is set, which is a failsafe way to -see if PHP is being run on the command line. + :: -:: + $this->input->is_cli_request() - $this->input->is_cli_request() + .. note:: This method is DEPRECATED and is now just an alias for the + :func:`is_cli()` function. -$this->input->method() -====================== + .. method:: method([$upper = FALSE]) -Returns the $_SERVER['REQUEST_METHOD'], optional set uppercase or lowercase (default lowercase). + :param bool $upper: Whether to return the request method name in upper or lower case + :returns: HTTP request method + :rtype: string -:: + Returns the ``$_SERVER['REQUEST_METHOD']``, with the option to set it + in uppercase or lowercase. + :: - echo $this->input->method(TRUE); // Outputs: POST - echo $this->input->method(FALSE); // Outputs: post - echo $this->input->method(); // Outputs: post
\ No newline at end of file + echo $this->input->method(TRUE); // Outputs: POST + echo $this->input->method(FALSE); // Outputs: post + echo $this->input->method(); // Outputs: post
\ No newline at end of file diff --git a/user_guide_src/source/libraries/javascript.rst b/user_guide_src/source/libraries/javascript.rst index 393d4e321..9d0237e57 100644 --- a/user_guide_src/source/libraries/javascript.rst +++ b/user_guide_src/source/libraries/javascript.rst @@ -1,31 +1,52 @@ -.. note:: This driver is experimental. Its feature set and - implementation may change in future releases. - ################ Javascript Class ################ +.. note:: This library is DEPRECATED and should not be used. It has always + been with an 'experimental' status and is now no longer supported. + Currently only kept for backwards compatibility. + CodeIgniter provides a library to help you with certain common functions that you may want to use with Javascript. Please note that CodeIgniter does not require the jQuery library to run, and that any scripting library will work equally well. The jQuery library is simply presented as a convenience if you choose to use it. +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + +************************** +Using the Javascript Class +************************** + Initializing the Class ====================== To initialize the Javascript class manually in your controller -constructor, use the $this->load->library function. Currently, the only -available library is jQuery, which will automatically be loaded like -this:: +constructor, use the ``$this->load->library()`` method. Currently, +the only available library is jQuery, which will automatically be +loaded like this:: $this->load->library('javascript'); -The Javascript class also accepts parameters, js_library_driver -(string) default 'jquery' and autoload (bool) default TRUE. You may -override the defaults if you wish by sending an associative array:: +The Javascript class also accepts parameters: + +- js_library_driver (string) *default: 'jquery'* +- autoload (bool) *default: TRUE* - $this->load->library('javascript', array('js_library_driver' => 'scripto', 'autoload' => FALSE)); +You may override the defaults by sending an associative array:: + + $this->load->library( + 'javascript', + array( + 'js_library_driver' => 'scripto', + 'autoload' => FALSE + ) + ); Again, presently only 'jquery' is available. You may wish to set autoload to FALSE, though, if you do not want the jQuery library to @@ -34,7 +55,8 @@ is useful if you are loading it from a location outside of CodeIgniter, or already have the script tag in your markup. Once loaded, the jQuery library object will be available using: -$this->javascript + + $this->javascript Setup and Configuration ======================= @@ -47,8 +69,8 @@ application. As Javascript is a client side language, the library must be able to write content into your final output. This generally means a view. -You'll need to include the following variables in the <head> sections of -your output. +You'll need to include the following variables in the ``<head>`` +sections of your output. :: @@ -56,17 +78,17 @@ your output. <?php echo $script_head;?> -$library_src, is where the actual library file will be loaded, as well -as any subsequent plugin script calls; $script_head is where specific -events, functions and other commands will be rendered. +``$library_src``, is where the actual library file will be loaded, as +well as any subsequent plugin script calls; $script_head is where +specific events, functions and other commands will be rendered. Set the path to the librarys with config items ---------------------------------------------- There are some configuration items in Javascript library. These can -either be set in application/config.php, within its own -config/javascript.php file, or within any controller usings the -set_item() function. +either be set in *application/config.php*, within its own +*config/javascript.php* file, or within any controller usings the +``set_item()`` function. An image to be used as an "ajax loader", or progress indicator. Without one, the simple text message of "loading" will appear when Ajax calls @@ -84,7 +106,7 @@ The jQuery Class ================ To initialize the jQuery class manually in your controller constructor, -use the $this->load->library function:: +use the ``$this->load->library()`` method:: $this->load->library('javascript/jquery'); @@ -96,30 +118,29 @@ library as follows:: $this->load->library('javascript/jquery', FALSE); Once loaded, the jQuery library object will be available using: -$this->jquery + + $this->jquery jQuery Events ============= Events are set using the following syntax. - :: $this->jquery->event('element_path', code_to_run()); - In the above example: - "event" is any of blur, change, click, dblclick, error, focus, hover, keydown, keyup, load, mousedown, mouseup, mouseover, mouseup, resize, scroll, or unload. -- "element_path" is any valid `jQuery - selector <http://docs.jquery.com/Selectors>`_. Due to jQuery's unique +- "element_path" is any valid `jQuery selector + <http://docs.jquery.com/Selectors>`_. Due to jQuery's unique selector syntax, this is usually an element id, or CSS selector. For - example "#notice_area" would effect <div id="notice_area">, and + example "#notice_area" would effect ``<div id="notice_area">``, and "#content a.notice" would effect all anchors with a class of "notice" in the div with id "content". -- "code_to_run()" is script your write yourself, or an action such as +- "``code_to_run()``" is script your write yourself, or an action such as an effect from the jQuery library below. Effects @@ -298,4 +319,4 @@ description to come calendar() ---------- -description to come +description to come
\ No newline at end of file diff --git a/user_guide_src/source/libraries/language.rst b/user_guide_src/source/libraries/language.rst index d288cd65e..3014d8f09 100644 --- a/user_guide_src/source/libraries/language.rst +++ b/user_guide_src/source/libraries/language.rst @@ -19,11 +19,22 @@ your **application/language/** directory. .. note:: Each language should be stored in its own folder. For example, the English files are located at: system/language/english +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + +************************ +Using the Language Class +************************ + Creating Language Files ======================= -Language files must be named with **_lang.php** as the file extension. For -example, let's say you want to create a file containing error messages. +Language files must be named with **_lang.php** as the filename extension. +For example, let's say you want to create a file containing error messages. You might name it: error_lang.php Within the file you will assign each line of text to an array called @@ -79,7 +90,7 @@ Using language lines as form labels ----------------------------------- This feature has been deprecated from the language library and moved to -the :php:func:`lang()` function of the :doc:`Language Helper +the :func:`lang()` function of the :doc:`Language Helper <../helpers/language_helper>`. Auto-loading Languages @@ -89,4 +100,32 @@ If you find that you need a particular language globally throughout your application, you can tell CodeIgniter to :doc:`auto-load <../general/autoloader>` it during system initialization. This is done by opening the **application/config/autoload.php** file and adding the -language(s) to the autoload array.
\ No newline at end of file +language(s) to the autoload array. + +*************** +Class Reference +*************** + +.. class:: CI_Lang + + .. method:: load($langfile[, $idiom = ''[, $return = FALSE[, $add_suffix = TRUE[, $alt_path = '']]]]) + + :param string $langfile: Language file to load + :param string $idiom: Language name (i.e. 'english') + :param bool $return: Whether to return the loaded array of translations + :param bool $add_suffix: Whether to add the '_lang' suffix to the language file name + :param string $alt_path: An alternative path to look in for the language file + :returns: Array of language lines if $return is set to TRUE, otherwise void + :rtype: mixed + + Loads a language file. + + .. method:: line($line[, $log_errors = TRUE]) + + :param string $line: Language line key name + :param bool $log_errors: Whether to log an error if the line isn't found + :returns: Language line string or FALSE on failure + :rtype: string + + Fetches a single translation line from the already loaded language files, + based on the line's name.
\ No newline at end of file diff --git a/user_guide_src/source/libraries/loader.rst b/user_guide_src/source/libraries/loader.rst index 19446a9c8..107b3ece3 100644 --- a/user_guide_src/source/libraries/loader.rst +++ b/user_guide_src/source/libraries/loader.rst @@ -11,363 +11,450 @@ can be libraries (classes) :doc:`View files <../general/views>`, .. note:: This class is initialized automatically by the system so there is no need to do it manually. -The following methods are available in this class: +.. contents:: + :local: -$this->load->library('class_name', $config, 'object name') -========================================================== +.. raw:: html -This method is used to load core classes. Where class_name is the -name of the class you want to load. + <div class="custom-index container"></div> -.. note:: We use the terms "class" and "library" interchangeably. +Application "Packages" +====================== -For example, if you would like to send email with CodeIgniter, the first -step is to load the email class within your controller:: +An application package allows for the easy distribution of complete sets +of resources in a single directory, complete with its own libraries, +models, helpers, config, and language files. It is recommended that +these packages be placed in the application/third_party directory. Below +is a sample map of an package directory. - $this->load->library('email'); +The following is an example of a directory for an application package +named "Foo Bar". -Once loaded, the library will be ready for use, using -$this->email->*some_method*(). +:: -Library files can be stored in subdirectories within the main -"libraries" directory, or within your personal application/libraries -directory. To load a file located in a subdirectory, simply include the -path, relative to the "libraries" directory. For example, if you have -file located at:: + /application/third_party/foo_bar - libraries/flavors/Chocolate.php + config/ + helpers/ + language/ + libraries/ + models/ -You will load it using:: +Whatever the purpose of the "Foo Bar" application package, it has its +own config files, helpers, language files, libraries, and models. To use +these resources in your controllers, you first need to tell the Loader +that you are going to be loading resources from a package, by adding the +package path via the ``add_package_path()`` method. - $this->load->library('flavors/chocolate'); +Package view files +------------------ -You may nest the file in as many subdirectories as you want. +By Default, package view files paths are set when ``add_package_path()`` +is called. View paths are looped through, and once a match is +encountered that view is loaded. -Additionally, multiple libraries can be loaded at the same time by -passing an array of libraries to the load method. +In this instance, it is possible for view naming collisions within +packages to occur, and possibly the incorrect package being loaded. To +ensure against this, set an optional second parameter of FALSE when +calling ``add_package_path()``. :: - $this->load->library(array('email', 'table')); + $this->load->add_package_path(APPPATH.'my_app', FALSE); + $this->load->view('my_app_index'); // Loads + $this->load->view('welcome_message'); // Will not load the default welcome_message b/c the second param to add_package_path is FALSE -Setting options ---------------- + // Reset things + $this->load->remove_package_path(APPPATH.'my_app'); -The second (optional) parameter allows you to optionally pass -configuration setting. You will typically pass these as an array:: + // Again without the second parameter: + $this->load->add_package_path(APPPATH.'my_app'); + $this->load->view('my_app_index'); // Loads + $this->load->view('welcome_message'); // Loads - $config = array ( - 'mailtype' => 'html', - 'charset' => 'utf-8, - 'priority' => '1' - ); +*************** +Class Reference +*************** - $this->load->library('email', $config); +.. class:: CI_Loader -Config options can usually also be set via a config file. Each library -is explained in detail in its own page, so please read the information -regarding each one you would like to use. + .. method:: library($library[, $params = NULL[, $object_name = NULL]]) -Please take note, when multiple libraries are supplied in an array for -the first parameter, each will receive the same parameter information. + :param mixed $library: Library name as a string or an array with multiple libraries + :param array $params: Optional array of parameters to pass to the loaded library's constructor + :param string $object_name: Optional object name to assign the library to + :returns: CI_Loader instance (method chaining) + :rtype: CI_Loader -Assigning a Library to a different object name ----------------------------------------------- + This method is used to load core classes. -If the third (optional) parameter is blank, the library will usually be -assigned to an object with the same name as the library. For example, if -the library is named Calendar, it will be assigned to a variable named -$this->calendar. + .. note:: We use the terms "class" and "library" interchangeably. -If you prefer to set your own class names you can pass its value to the -third parameter:: + For example, if you would like to send email with CodeIgniter, the first + step is to load the email class within your controller:: - $this->load->library('calendar', '', 'my_calendar'); + $this->load->library('email'); - // Calendar class is now accessed using: - $this->my_calendar + Once loaded, the library will be ready for use, using ``$this->email``. -Please take note, when multiple libraries are supplied in an array for -the first parameter, this parameter is discarded. + Library files can be stored in subdirectories within the main + "libraries" directory, or within your personal *application/libraries* + directory. To load a file located in a subdirectory, simply include the + path, relative to the "libraries" directory. For example, if you have + file located at:: -$this->load->driver('parent_name', $config, 'object name') -========================================================== + libraries/flavors/Chocolate.php -This method is used to load driver libraries. Where parent_name is the -name of the parent class you want to load. + You will load it using:: -As an example, if you would like to use sessions with CodeIgniter, the first -step is to load the session driver within your controller:: + $this->load->library('flavors/chocolate'); - $this->load->driver('session'); + You may nest the file in as many subdirectories as you want. -Once loaded, the library will be ready for use, using -$this->session->*some_method*(). + Additionally, multiple libraries can be loaded at the same time by + passing an array of libraries to the load method. + :: -Driver files must be stored in a subdirectory within the main -"libraries" directory, or within your personal application/libraries -directory. The subdirectory must match the parent class name. Read the -:doc:`Drivers <../general/drivers>` description for details. + $this->load->library(array('email', 'table')); -Additionally, multiple driver libraries can be loaded at the same time by -passing an array of drivers to the load method. + **Setting options** -:: + The second (optional) parameter allows you to optionally pass + configuration setting. You will typically pass these as an array:: - $this->load->driver(array('session', 'cache')); + $config = array ( + 'mailtype' => 'html', + 'charset' => 'utf-8, + 'priority' => '1' + ); -Setting options ---------------- + $this->load->library('email', $config); -The second (optional) parameter allows you to optionally pass -configuration settings. You will typically pass these as an array:: + Config options can usually also be set via a config file. Each library + is explained in detail in its own page, so please read the information + regarding each one you would like to use. - $config = array( - 'sess_driver' => 'cookie', - 'sess_encrypt_cookie' => true, - 'encryption_key' => 'mysecretkey' - ); + Please take note, when multiple libraries are supplied in an array for + the first parameter, each will receive the same parameter information. - $this->load->driver('session', $config); + **Assigning a Library to a different object name** -Config options can usually also be set via a config file. Each library -is explained in detail in its own page, so please read the information -regarding each one you would like to use. + If the third (optional) parameter is blank, the library will usually be + assigned to an object with the same name as the library. For example, if + the library is named Calendar, it will be assigned to a variable named + ``$this->calendar``. -Assigning a Driver to a different object name ---------------------------------------------- + If you prefer to set your own class names you can pass its value to the + third parameter:: -If the third (optional) parameter is blank, the library will be assigned -to an object with the same name as the parent class. For example, if -the library is named Session, it will be assigned to a variable named -``$this->session``. + $this->load->library('calendar', NULL, 'my_calendar'); -If you prefer to set your own class names you can pass its value to the -third parameter:: + // Calendar class is now accessed using: + $this->my_calendar - $this->load->library('session', '', 'my_session'); + Please take note, when multiple libraries are supplied in an array for + the first parameter, this parameter is discarded. - // Session class is now accessed using: - $this->my_session + .. method:: driver($library[, $params = NULL[, $object_name]]) -.. note:: Driver libraries may also be loaded with the ``library()`` method, - but it is faster to use ``driver()``. + :param mixed $library: Library name as a string or an array with multiple libraries + :param array $params: Optional array of parameters to pass to the loaded library's constructor + :param string $object_name: Optional object name to assign the library to + :returns: CI_Loader instance (method chaining) + :rtype: CI_Loader -$this->load->view('file_name', $data, TRUE/FALSE) -================================================= + This method is used to load driver libraries, acts very much like the + ``library()`` method. -This method is used to load your View files. If you haven't read the -:doc:`Views <../general/views>` section of the user guide it is -recommended that you do since it shows you how this method is -typically used. + As an example, if you would like to use sessions with CodeIgniter, the first + step is to load the session driver within your controller:: -The first parameter is required. It is the name of the view file you -would like to load. + $this->load->driver('session'); -.. note:: The .php file extension does not need to be specified unless - you use something other than .php. + Once loaded, the library will be ready for use, using ``$this->session``. -The second **optional** parameter can take an associative array or an -object as input, which it runs through the PHP -`extract() <http://www.php.net/extract>`_ function to convert to variables -that can be used in your view files. Again, read the -:doc:`Views <../general/views>` page to learn how this might be useful. + Driver files must be stored in a subdirectory within the main + "libraries" directory, or within your personal *application/libraries* + directory. The subdirectory must match the parent class name. Read the + :doc:`Drivers <../general/drivers>` description for details. -The third **optional** parameter lets you change the behavior of the -method so that it returns data as a string rather than sending it to -your browser. This can be useful if you want to process the data in some -way. If you set the parameter to true (boolean) it will return data. The -default behavior is false, which sends it to your browser. Remember to -assign it to a variable if you want the data returned:: + Additionally, multiple driver libraries can be loaded at the same time by + passing an array of drivers to the load method. + :: - $string = $this->load->view('myfile', '', true); + $this->load->driver(array('session', 'cache')); -$this->load->model('model_name'); -================================== + **Setting options** -:: + The second (optional) parameter allows you to optionally pass + configuration settings. You will typically pass these as an array:: - $this->load->model('model_name'); + $config = array( + 'sess_driver' => 'cookie', + 'sess_encrypt_cookie' => true, + 'encryption_key' => 'mysecretkey' + ); + $this->load->driver('session', $config); -If your model is located in a subdirectory, include the relative path -from your models directory. For example, if you have a model located at -application/models/blog/Queries.php you'll load it using:: + Config options can usually also be set via a config file. Each library + is explained in detail in its own page, so please read the information + regarding each one you would like to use. - $this->load->model('blog/queries'); + **Assigning a Driver to a different object name** -If you would like your model assigned to a different object name you can -specify it via the second parameter of the loading method:: + If the third (optional) parameter is blank, the library will be assigned + to an object with the same name as the parent class. For example, if + the library is named Session, it will be assigned to a variable named + ``$this->session``. - $this->load->model('model_name', 'fubar'); - $this->fubar->method(); + If you prefer to set your own class names you can pass its value to the + third parameter:: -$this->load->database('options', TRUE/FALSE) -============================================ + $this->load->library('session', '', 'my_session'); -This method lets you load the database class. The two parameters are -**optional**. Please see the :doc:`database <../database/index>` -section for more info. + // Session class is now accessed using: + $this->my_session -$this->load->vars($array) -========================= + .. method:: view($view[, $vars = array()[, return = FALSE]]) -This method takes an associative array as input and generates -variables using the PHP `extract <http://www.php.net/extract>`_ -method. This method produces the same result as using the second -parameter of the ``$this->load->view()`` method above. The reason you -might want to use this method independently is if you would like to -set some global variables in the constructor of your controller and have -them become available in any view file loaded from any method. You can -have multiple calls to this method. The data get cached and merged -into one array for conversion to variables. + :param string $view: View name + :param array $vars: An associative array of variables + :param bool $return: Whether to return the loaded view + :returns: View content string if $return is set to TRUE, otherwise CI_Loader instance (method chaining) + :rtype: mixed -$this->load->get_var($key) -========================== + This method is used to load your View files. If you haven't read the + :doc:`Views <../general/views>` section of the user guide it is + recommended that you do since it shows you how this method is + typically used. -This method checks the associative array of variables available to -your views. This is useful if for any reason a var is set in a library -or another controller method using ``$this->load->vars()``. + The first parameter is required. It is the name of the view file you + would like to load. -$this->load->get_vars() -======================= + .. note:: The .php file extension does not need to be specified unless + you use something other than .php. -This method retrieves all variables available to your views. + The second **optional** parameter can take an associative array or an + object as input, which it runs through the PHP + `extract() <http://www.php.net/extract>`_ function to convert to variables + that can be used in your view files. Again, read the + :doc:`Views <../general/views>` page to learn how this might be useful. -$this->load->helper('file_name') -================================ + The third **optional** parameter lets you change the behavior of the + method so that it returns data as a string rather than sending it to + your browser. This can be useful if you want to process the data in some + way. If you set the parameter to TRUE (boolean) it will return data. The + default behavior is FALSE, which sends it to your browser. Remember to + assign it to a variable if you want the data returned:: -This method loads helper files, where file_name is the name of the -file, without the _helper.php extension. + $string = $this->load->view('myfile', '', TRUE); -$this->load->file('filepath/filename', TRUE/FALSE) -================================================== + .. method:: vars($vars[, $val = '']) -This is a generic file loading method. Supply the filepath and name in -the first parameter and it will open and read the file. By default the -data is sent to your browser, just like a View file, but if you set the -second parameter to true (boolean) it will instead return the data as a -string. + :param mixed $vars: An array of variables or a single variable name + :param mixed $val: Optional variable value + :returns: CI_Loader instance (method chaining) + :rtype: CI_Loader -$this->load->language('file_name') -================================== + This method takes an associative array as input and generates + variables using the PHP `extract() <http://www.php.net/extract>`_ + function. This method produces the same result as using the second + parameter of the ``$this->load->view()`` method above. The reason you + might want to use this method independently is if you would like to + set some global variables in the constructor of your controller and have + them become available in any view file loaded from any method. You can + have multiple calls to this method. The data get cached and merged + into one array for conversion to variables. -This method is an alias of the :doc:`language loading -method <language>`: ``$this->lang->load()`` + .. method:: get_var($key) -$this->load->config('file_name') -================================ + :param string $key: Variable name key + :returns: Value if key is found, NULL if not + :rtype: mixed -This method is an alias of the :doc:`config file loading -method <config>`: ``$this->config->load()`` + This method checks the associative array of variables available to + your views. This is useful if for any reason a var is set in a library + or another controller method using ``$this->load->vars()``. -$this->load->is_loaded('library_name') -====================================== + .. method:: get_vars() -The ``is_loaded()`` method allows you to check if a class has already -been loaded or not. + :returns: An array of all assigned view variables + :rtype: array -.. note:: The word "class" here refers to libraries and drivers. + This method retrieves all variables available to your views. -If the requested class has been loaded, the method returns its assigned -name in the CI Super-object and FALSE if it's not:: + .. method:: clear_vars() - $this->load->library('form_validation'); - $this->load->is_loaded('Form_validation'); // returns 'form_validation' + :returns: CI_Loader instance (method chaining) + :rtype: CI_Loader - $this->load->is_loaded('Nonexistent_library'); // returns FALSE + Clears cached view variables. -.. important:: If you have more than one instance of a class (assigned to - different properties), then the first one will be returned. + .. method:: model($model[, $name = ''[, $db_conn = FALSE]]) -:: + :param mixed $model: Model name or an array containing multiple models + :param string $name: Optional object name to assign the model to + :param string $db_conn: Optional database configuration group to load + :returns: CI_Loader instance (method chaining) + :rtype: CI_Loader - $this->load->library('form_validation', $config, 'fv'); - $this->load->library('form_validation'); + :: - $this->load->is_loaded('Form_validation'); // returns 'fv' + $this->load->model('model_name'); -Application "Packages" -====================== -An application package allows for the easy distribution of complete sets -of resources in a single directory, complete with its own libraries, -models, helpers, config, and language files. It is recommended that -these packages be placed in the application/third_party directory. Below -is a sample map of an package directory + If your model is located in a subdirectory, include the relative path + from your models directory. For example, if you have a model located at + *application/models/blog/Queries.php* you'll load it using:: -Sample Package "Foo Bar" Directory Map -====================================== + $this->load->model('blog/queries'); -The following is an example of a directory for an application package -named "Foo Bar". + If you would like your model assigned to a different object name you can + specify it via the second parameter of the loading method:: -:: + $this->load->model('model_name', 'fubar'); + $this->fubar->method(); - /application/third_party/foo_bar + .. method:: database([$params = ''[, $return = FALSE[, $query_builder = NULL]]]) - config/ - helpers/ - language/ - libraries/ - models/ + :param mixed $params: Database group name or configuration options + :param bool $return: Whether to return the loaded database object + :param bool $query_builder: Whether to load the Query Builder + :returns: Loaded CI_DB instance or FALSE on failure if $return is set to TRUE, otherwise CI_Loader instance (method chaining) + :rtype: mixed -Whatever the purpose of the "Foo Bar" application package, it has its -own config files, helpers, language files, libraries, and models. To use -these resources in your controllers, you first need to tell the Loader -that you are going to be loading resources from a package, by adding the -package path. + This method lets you load the database class. The two parameters are + **optional**. Please see the :doc:`database <../database/index>` + section for more info. -$this->load->add_package_path() ---------------------------------- + .. method:: dbforge([$db = NULL[, $return = FALSE]]) -Adding a package path instructs the Loader class to prepend a given path -for subsequent requests for resources. As an example, the "Foo Bar" -application package above has a library named Foo_bar.php. In our -controller, we'd do the following:: + :param object $db: Database object + :param bool $return: Whether to return the Database Forge instance + :returns: Loaded CI_DB_forge instance if $return is set to TRUE, otherwise CI_Loader instance (method chaining) + :rtype: mixed - $this->load->add_package_path(APPPATH.'third_party/foo_bar/'); - $this->load->library('foo_bar'); + Loads the :doc:`Database Forge <../database/forge>` class, please refer + to that manual for more info. -$this->load->remove_package_path() ------------------------------------- + .. method:: dbutil([$db = NULL[, $return = FALSE]]) -When your controller is finished using resources from an application -package, and particularly if you have other application packages you -want to work with, you may wish to remove the package path so the Loader -no longer looks in that directory for resources. To remove the last path -added, simply call the method with no parameters. + :param object $db: Database object + :param bool $return: Whether to return the Database Utilities instance + :returns: Loaded CI_DB_utility instance if $return is set to TRUE, otherwise CI_Loader instance (method chaining) + :rtype: mixed -$this->load->remove_package_path() ------------------------------------- + Loads the :doc:`Database Utilities <../database/utilities>` class, please + refer to that manual for more info. -Or to remove a specific package path, specify the same path previously -given to add_package_path() for a package.:: + .. method:: helper($helpers) - $this->load->remove_package_path(APPPATH.'third_party/foo_bar/'); + :param mixed $helpers: Helper name as a string or an array containing multiple helpers + :returns: CI_Loader instance (method chaining) + :rtype: CI_Loader -Package view files ------------------- + This method loads helper files, where file_name is the name of the + file, without the _helper.php extension. -By Default, package view files paths are set when add_package_path() -is called. View paths are looped through, and once a match is -encountered that view is loaded. + .. method:: file($path[, $return = FALSE]) -In this instance, it is possible for view naming collisions within -packages to occur, and possibly the incorrect package being loaded. To -ensure against this, set an optional second parameter of FALSE when -calling add_package_path(). + :param string $path: File path + :param bool $return: Whether to return the loaded file + :returns: File contents if $return is set to TRUE, otherwise CI_Loader instance (method chaining) + :rtype: mixed -:: + This is a generic file loading method. Supply the filepath and name in + the first parameter and it will open and read the file. By default the + data is sent to your browser, just like a View file, but if you set the + second parameter to boolean TRUE it will instead return the data as a + string. - $this->load->add_package_path(APPPATH.'my_app', FALSE); - $this->load->view('my_app_index'); // Loads - $this->load->view('welcome_message'); // Will not load the default welcome_message b/c the second param to add_package_path is FALSE + .. method:: language($files[, $lang = '']) - // Reset things - $this->load->remove_package_path(APPPATH.'my_app'); + :param mixed $files: Language file name or an array of multiple language files + :param string $lang: Language name + :returns: CI_Loader instance (method chaining) + :rtype: CI_Loader - // Again without the second parameter: - $this->load->add_package_path(APPPATH.'my_app'); - $this->load->view('my_app_index'); // Loads - $this->load->view('welcome_message'); // Loads
\ No newline at end of file + This method is an alias of the :doc:`language loading + method <language>`: ``$this->lang->load()``. + + .. method:: config($file[, $use_sections = FALSE[, $fail_gracefully = FALSE]]) + + :param string $file: Configuration file name + :param bool $use_sections: Whether configuration values should be loaded into their own section + :param bool $fail_gracefully: Whether to just return FALSE in case of failure + :returns: TRUE on success, FALSE on failure + :rtype: bool + + This method is an alias of the :doc:`config file loading + method <config>`: ``$this->config->load()`` + + .. method:: is_loaded($class) + + :param string $class: Class name + :returns: Singleton property name if found, FALSE if not + :rtype: mixed + + Allows you to check if a class has already been loaded or not. + + .. note:: The word "class" here refers to libraries and drivers. + + If the requested class has been loaded, the method returns its assigned + name in the CI Super-object and FALSE if it's not:: + + $this->load->library('form_validation'); + $this->load->is_loaded('Form_validation'); // returns 'form_validation' + + $this->load->is_loaded('Nonexistent_library'); // returns FALSE + + .. important:: If you have more than one instance of a class (assigned to + different properties), then the first one will be returned. + + :: + + $this->load->library('form_validation', $config, 'fv'); + $this->load->library('form_validation'); + + $this->load->is_loaded('Form_validation'); // returns 'fv' + + .. method:: add_package_path($path[, $view_cascade = TRUE]) + + :param string $path: Path to add + :param bool $view_cascade: Whether to use cascading views + :returns: CI_Loader instance (method chaining) + :rtype: CI_Loader + + Adding a package path instructs the Loader class to prepend a given path + for subsequent requests for resources. As an example, the "Foo Bar" + application package above has a library named Foo_bar.php. In our + controller, we'd do the following:: + + $this->load->add_package_path(APPPATH.'third_party/foo_bar/') + ->library('foo_bar'); + + .. method:: remove_package_path([$path = '']) + + :param string $path: Path to remove + :returns: CI_Loader instance (method chaining) + :rtype: CI_Loader + + When your controller is finished using resources from an application + package, and particularly if you have other application packages you + want to work with, you may wish to remove the package path so the Loader + no longer looks in that directory for resources. To remove the last path + added, simply call the method with no parameters. + + Or to remove a specific package path, specify the same path previously + given to ``add_package_path()`` for a package.:: + + $this->load->remove_package_path(APPPATH.'third_party/foo_bar/'); + + .. method:: get_package_paths([$include_base = TRUE]) + + :param bool $include_base: Whether to include BASEPATH + :returns: An array of package paths + :rtype: array + + Returns all currently available package paths.
\ No newline at end of file diff --git a/user_guide_src/source/libraries/migration.rst b/user_guide_src/source/libraries/migration.rst index 9dc3c08da..e8ea1d977 100644 --- a/user_guide_src/source/libraries/migration.rst +++ b/user_guide_src/source/libraries/migration.rst @@ -10,8 +10,15 @@ 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->migration->current()** to work out which migrations should be run. -The current version is found in **config/migration.php**. +call ``$this->migration->current()`` to work out which migrations should be run. +The current version is found in **application/config/migration.php**. + +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> ******************** Migration file names @@ -28,23 +35,24 @@ method taken. Two numbering styles are available: helps prevent numbering conflicts when working in a team environment, and is the preferred scheme in CodeIgniter 3.0 and later. -The desired style may be selected using the **$config['migration_type']** -setting in your **migration.php** config file. +The desired style may be selected using the ``$config['migration_type']`` +setting in your *application/config/migration.php* file. Regardless of which numbering style you choose to use, prefix your migration files with the migration number followed by an underscore and a descriptive name for the migration. For example: -* **001_add_blog.php** (sequential numbering) -* **20121031100537_add_blog.php** (timestamp numbering) +* 001_add_blog.php (sequential numbering) +* 20121031100537_add_blog.php (timestamp numbering) ****************** Create a 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 **20121031100537_add_blog.php**.:: +migrations go in the **application/migrations/** directory and have names such +as *20121031100537_add_blog.php*. +:: <?php @@ -80,7 +88,7 @@ as **20121031100537_add_blog.php**.:: } } -Then in **application/config/migration.php** set **$config['migration_version'] = 1;**. +Then in **application/config/migration.php** set ``$config['migration_version'] = 1;``. ************* Usage Example @@ -93,54 +101,18 @@ to update the schema.:: class Migrate extends CI_Controller { - public function index() - { - $this->load->library('migration'); - - if ($this->migration->current() === FALSE) - { - show_error($this->migration->error_string()); - } - } - } - -****************** -Function Reference -****************** - -$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']**.:: + public function index() + { + $this->load->library('migration'); - $this->load->library('migration'); + if ($this->migration->current() === FALSE) + { + show_error($this->migration->error_string()); + } + } - $this->migration->version(5); + } ********************* Migration Preferences @@ -161,3 +133,52 @@ Preference Default Options Des **migration_type** 'timestamp' 'timestamp' / 'sequential' The type of numeric identifier used to name migration files. ========================== ====================== ========================== ============================================= + +*************** +Class Reference +*************** + +.. class:: CI_Migration + + .. method:: current() + + :returns: TRUE if no migrations are found, current version string on success, FALSE on failure + :rtype: mixed + + Migrates up to the current version (whatever is set for + ``$config['migration_version']`` in *application/config/migration.php*). + + .. method:: error_string() + + :returns: Error messages + :rtype: string + + This returns a string of errors that were detected while performing a migration. + + .. method:: find_migrations() + + :returns: An array of migration files + :rtype: array + + An array of migration filenames are returned that are found in the **migration_path** property. + + .. method:: latest() + + :returns: TRUE if no migrations are found, current version string on success, FALSE on failure + :rtype: mixed + + 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. + + .. method:: version($target_version) + + :param mixed $target_version: Migration version to process + :returns: TRUE if no migrations are found, current version string on success, FALSE on failure + :rtype: mixed + + 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->migration->version(5);
\ No newline at end of file diff --git a/user_guide_src/source/libraries/output.rst b/user_guide_src/source/libraries/output.rst index a3d67b847..e49ea5366 100644 --- a/user_guide_src/source/libraries/output.rst +++ b/user_guide_src/source/libraries/output.rst @@ -2,7 +2,7 @@ Output Class ############ -The Output class is a small class with one main function: To send the +The Output class is a core class with one main function: To send the finalized web page to the requesting browser. It is also responsible for :doc:`caching <../general/caching>` your web pages, if you use that feature. @@ -16,159 +16,193 @@ use the :doc:`Loader <../libraries/loader>` class to load a view file, it's automatically passed to the Output class, which will be called automatically by CodeIgniter at the end of system execution. It is possible, however, for you to manually intervene with the output if you -need to, using either of the two following functions: +need to. -$this->output->set_output(); -============================= +.. contents:: + :local: -Permits you to manually set the final output string. Usage example:: +.. raw:: html - $this->output->set_output($data); + <div class="custom-index container"></div> -.. important:: If you do set your output manually, it must be the last - thing done in the function you call it from. For example, if you build a - page in one of your controller functions, don't set the output until the - end. +*************** +Class Reference +*************** -$this->output->set_content_type(); -==================================== +.. class:: CI_Output -Permits you to set the mime-type of your page so you can serve JSON -data, JPEG's, XML, etc easily. + .. attribute:: $parse_exec_vars = TRUE; -:: + Enables/disables parsing of the {elapsed_time} and {memory_usage} pseudo-variables. - $this->output - ->set_content_type('application/json') - ->set_output(json_encode(array('foo' => 'bar'))); + CodeIgniter will parse those tokens in your output by default. To disable this, set + this property to FALSE in your controller. + :: - $this->output - ->set_content_type('jpeg') // You could also use ".jpeg" which will have the full stop removed before looking in config/mimes.php - ->set_output(file_get_contents('files/something.jpg')); + $this->output->parse_exec_vars = FALSE; -.. important:: Make sure any non-mime string you pass to this method - exists in config/mimes.php or it will have no effect. + .. method:: set_output($output) -You can also set the character set of the document, by passing a second argument:: + :param string $output: String to set the output to + :returns: CI_Output instance (method chaining) + :rtype: CI_Output - $this->output->set_content_type('css', 'utf-8'); + Permits you to manually set the final output string. Usage example:: -$this->output->get_content_type() -================================= + $this->output->set_output($data); -Returns the Content-Type HTTP header that's currently in use, -excluding the character set value. + .. important:: If you do set your output manually, it must be the last thing done + in the function you call it from. For example, if you build a page in one + of your controller methods, don't set the output until the end. - $mime = $this->output->get_content_type(); + .. method:: set_content_type($mime_type[, $charset = NULL]) -.. note:: If not set, the default return value is 'text/html'. + :param string $mime_type: MIME Type idenitifer string + :param string $charset: Character set + :returns: CI_Output instance (method chaining) + :rtype: CI_Output -$this->output->get_header() -=========================== + Permits you to set the mime-type of your page so you can serve JSON data, JPEG's, XML, etc easily. + :: -Gets the requested HTTP header value, if set. + $this->output + ->set_content_type('application/json') + ->set_output(json_encode(array('foo' => 'bar'))); -If the header is not set, NULL will be returned. -If an empty value is passed to the method, it will return FALSE. + $this->output + ->set_content_type('jpeg') // You could also use ".jpeg" which will have the full stop removed before looking in config/mimes.php + ->set_output(file_get_contents('files/something.jpg')); -Example:: + .. important:: Make sure any non-mime string you pass to this method + exists in *application/config/mimes.php* or it will have no effect. - $this->output->set_content_type('text/plain', 'UTF-8'); - echo $this->output->get_header('content-type'); - // Outputs: text/plain; charset=utf-8 + You can also set the character set of the document, by passing a second argument:: -.. note:: The header name is compared in a case-insensitive manner. + $this->output->set_content_type('css', 'utf-8'); -.. note:: Raw headers sent via PHP's native ``header()`` function are - also detected. + .. method:: get_content_type() -$this->output->get_output() -=========================== + :returns: Content-Type string + :rtype: string -Permits you to manually retrieve any output that has been sent for -storage in the output class. Usage example:: + Returns the Content-Type HTTP header that's currently in use, excluding the character set value. + :: - $string = $this->output->get_output(); + $mime = $this->output->get_content_type(); -Note that data will only be retrievable from this function if it has -been previously sent to the output class by one of the CodeIgniter -functions like $this->load->view(). + .. note:: If not set, the default return value is 'text/html'. -$this->output->append_output(); -================================ + .. method:: get_header($header) -Appends data onto the output string. Usage example:: + :param string $header: HTTP header name + :returns: HTTP response header or NULL if not found + :rtype: mixed - $this->output->append_output($data); + Returns the requested HTTP header value, or NULL if the requested header is not set. + Example:: -$this->output->set_header(); -============================= + $this->output->set_content_type('text/plain', 'UTF-8'); + echo $this->output->get_header('content-type'); + // Outputs: text/plain; charset=utf-8 -Permits you to manually set server headers, which the output class will -send for you when outputting the final rendered display. Example:: + .. note:: The header name is compared in a case-insensitive manner. - $this->output->set_header("HTTP/1.0 200 OK"); - $this->output->set_header("HTTP/1.1 200 OK"); - $this->output->set_header('Last-Modified: '.gmdate('D, d M Y H:i:s', $last_update).' GMT'); - $this->output->set_header("Cache-Control: no-store, no-cache, must-revalidate"); - $this->output->set_header("Cache-Control: post-check=0, pre-check=0"); - $this->output->set_header("Pragma: no-cache"); + .. note:: Raw headers sent via PHP's native ``header()`` function are also detected. -$this->output->set_status_header(code, 'text'); -================================================= + .. method:: get_output() -Permits you to manually set a server status header. Example:: + :returns: Output string + :rtype: string - $this->output->set_status_header('401'); - // Sets the header as: Unauthorized + Permits you to manually retrieve any output that has been sent for + storage in the output class. Usage example:: -`See here <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html>`_ for -a full list of headers. + $string = $this->output->get_output(); -.. note:: This method is an alias for :doc:`Common function <../general/common_functions>` - ``set_status_header()``. + Note that data will only be retrievable from this function if it has + been previously sent to the output class by one of the CodeIgniter + functions like ``$this->load->view()``. -$this->output->enable_profiler(); -================================== + .. method:: append_output($output) -Permits you to enable/disable the -:doc:`Profiler <../general/profiling>`, which will display benchmark -and other data at the bottom of your pages for debugging and -optimization purposes. + :param string $output: Additional output data to append + :returns: CI_Output instance (method chaining) + :rtype: CI_Output -To enable the profiler place the following function anywhere within your -:doc:`Controller <../general/controllers>` functions:: + Appends data onto the output string. + :: - $this->output->enable_profiler(TRUE); + $this->output->append_output($data); -When enabled a report will be generated and inserted at the bottom of -your pages. + .. method:: set_header($header[, $replace = TRUE]) -To disable the profiler you will use:: + :param string $header: HTTP response header + :param bool $replace: Whether to replace the old header value, if it is already set + :returns: CI_Output instance (method chaining) + :rtype: CI_Output - $this->output->enable_profiler(FALSE); + Permits you to manually set server headers, which the output class will + send for you when outputting the final rendered display. Example:: -$this->output->set_profiler_sections(); -========================================= + $this->output->set_header('HTTP/1.0 200 OK'); + $this->output->set_header('HTTP/1.1 200 OK'); + $this->output->set_header('Last-Modified: '.gmdate('D, d M Y H:i:s', $last_update).' GMT'); + $this->output->set_header('Cache-Control: no-store, no-cache, must-revalidate'); + $this->output->set_header('Cache-Control: post-check=0, pre-check=0'); + $this->output->set_header('Pragma: no-cache'); -Permits you to enable/disable specific sections of the Profiler when -enabled. Please refer to the :doc:`Profiler <../general/profiling>` -documentation for further information. + .. method:: set_status_header([$code = 200[, $text = '']]) -$this->output->cache(); -======================= + :param int $code: HTTP status code + :param string $text: Optional message + :returns: CI_Output instance (method chaining) + :rtype: CI_Output -The CodeIgniter output library also controls caching. For more -information, please see the :doc:`caching -documentation <../general/caching>`. + Permits you to manually set a server status header. Example:: -Parsing Execution Variables -=========================== + $this->output->set_status_header('401'); + // Sets the header as: Unauthorized -CodeIgniter will parse the pseudo-variables {elapsed_time} and -{memory_usage} in your output by default. To disable this, set the -$parse_exec_vars class property to FALSE in your controller. -:: + `See here <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html>`_ for a full list of headers. - $this->output->parse_exec_vars = FALSE; + .. note:: This method is an alias for :doc:`Common function <../general/common_functions>` + :func:`set_status_header()`. + .. method:: enable_profiler([$val = TRUE]) + + :param bool $val: Whether to enable or disable the Profiler + :returns: CI_Output instance (method chaining) + :rtype: CI_Output + + Permits you to enable/disable the :doc:`Profiler <../general/profiling>`, which will display benchmark + and other data at the bottom of your pages for debugging and optimization purposes. + + To enable the profiler place the following line anywhere within your + :doc:`Controller <../general/controllers>` methods:: + + $this->output->enable_profiler(TRUE); + + When enabled a report will be generated and inserted at the bottom of your pages. + + To disable the profiler you would use:: + + $this->output->enable_profiler(FALSE); + + .. method:: set_profiler_sections($sections) + + :param array $sections: Profiler sections + :returns: CI_Output instance (method chaining) + :rtype: CI_Output + + Permits you to enable/disable specific sections of the Profiler when it is enabled. + Please refer to the :doc:`Profiler <../general/profiling>` documentation for further information. + + .. method:: cache($time) + + :param int $time: Cache expiration time in seconds + :returns: CI_Output instance (method chaining) + :rtype: CI_Output + + Caches the current page for the specified amount of seconds. + + For more information, please see the :doc:`caching documentation <../general/caching>`.
\ No newline at end of file diff --git a/user_guide_src/source/libraries/pagination.rst b/user_guide_src/source/libraries/pagination.rst index d9d3f5092..ee12d9e6f 100644 --- a/user_guide_src/source/libraries/pagination.rst +++ b/user_guide_src/source/libraries/pagination.rst @@ -5,6 +5,13 @@ Pagination Class CodeIgniter's Pagination class is very easy to use, and it is 100% customizable, either dynamically or via stored preferences. +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + If you are not familiar with the term "pagination", it refers to links that allows you to navigate from page to page, like this:: @@ -15,7 +22,7 @@ Example ******* Here is a simple example showing how to create pagination in one of your -:doc:`controller <../general/controllers>` functions:: +:doc:`controller <../general/controllers>` methods:: $this->load->library('pagination'); @@ -30,8 +37,8 @@ Here is a simple example showing how to create pagination in one of your Notes ===== -The $config array contains your configuration variables. It is passed to -the $this->pagination->initialize function as shown above. Although +The ``$config`` array contains your configuration variables. It is passed to +the ``$this->pagination->initialize()`` method as shown above. Although there are some twenty items you can configure, at minimum you need the three shown. Here is a description of what those items represent: @@ -46,7 +53,7 @@ three shown. Here is a description of what those items represent: - **per_page** The number of items you intend to show per page. In the above example, you would be showing 20 items per page. -The create_links() function returns an empty string when there is no +The ``create_links()`` method returns an empty string when there is no pagination to show. Setting preferences in a config file @@ -54,9 +61,9 @@ Setting preferences in a config file If you prefer not to set preferences using the above method, you can instead put them into a config file. Simply create a new file called -pagination.php, add the $config array in that file. Then save the file -in: config/pagination.php and it will be used automatically. You will -NOT need to use the $this->pagination->initialize function if you save +pagination.php, add the ``$config`` array in that file. Then save the file +in *application/config/pagination.php* and it will be used automatically. +You will NOT need to use ``$this->pagination->initialize()`` if you save your preferences in a config file. ************************** @@ -67,14 +74,14 @@ The following is a list of all the preferences you can pass to the initialization function to tailor the display. $config['uri_segment'] = 3; -============================ +=========================== The pagination function automatically determines which segment of your URI contains the page number. If you need something different you can specify it. $config['num_links'] = 2; -========================== +========================= 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 @@ -92,25 +99,19 @@ $config['page_query_string'] = TRUE; By default, the pagination library assume you are using :doc:`URI Segments <../general/urls>`, and constructs your links something -like - -:: +like:: http://example.com/index.php/test/page/20 - -If you have $config['enable_query_strings'] set to TRUE your links +If you have ``$config['enable_query_strings']`` set to TRUE your links will automatically be re-written using Query Strings. This option can -also be explictly set. Using $config['page_query_string'] set to TRUE, -the pagination link will become. - -:: +also be explictly set. Using ``$config['page_query_string']`` set to TRUE, +the pagination link will become:: http://example.com/index.php?c=test&m=page&per_page=20 - Note that "per_page" is the default query string passed, however can be -configured using $config['query_string_segment'] = 'your_string' +configured using ``$config['query_string_segment'] = 'your_string'`` $config['reuse_query_string'] = FALSE; ====================================== @@ -118,9 +119,7 @@ $config['reuse_query_string'] = FALSE; By default your Query String arguments (nothing to do with other query string options) will be ignored. Setting this config to TRUE will add existing query string arguments back into the -URL after the URI segment and before the suffix - -:: +URL after the URI segment and before the suffix.:: http://example.com/index.php/test/page/20?query=search%term @@ -128,13 +127,13 @@ This helps you mix together normal :doc:`URI Segments <../general/urls>` as well as query string arguments, which until 3.0 was not possible. $config['prefix'] = ''; -================================== +======================= A custom prefix added to the path. The prefix value will be right before the offset segment. $config['suffix'] = ''; -================================== +======================= A custom suffix added to the path. The sufix value will be right after the offset segment. @@ -144,15 +143,15 @@ Adding Enclosing Markup *********************** If you would like to surround the entire pagination with some markup you -can do it with these two prefs: +can do it with these two preferences: $config['full_tag_open'] = '<p>'; -=================================== +================================= The opening tag placed on the left side of the entire result. $config['full_tag_close'] = '</p>'; -===================================== +=================================== The closing tag placed on the right side of the entire result. @@ -161,18 +160,18 @@ Customizing the First Link ************************** $config['first_link'] = 'First'; -================================= +================================ The text you would like shown in the "first" link on the left. If you do not want this link rendered, you can set its value to FALSE. $config['first_tag_open'] = '<div>'; -====================================== +==================================== The opening tag for the "first" link. $config['first_tag_close'] = '</div>'; -======================================== +====================================== The closing tag for the "first" link. @@ -181,18 +180,18 @@ Customizing the Last Link ************************* $config['last_link'] = 'Last'; -=============================== +============================== The text you would like shown in the "last" link on the right. If you do not want this link rendered, you can set its value to FALSE. $config['last_tag_open'] = '<div>'; -===================================== +=================================== The opening tag for the "last" link. $config['last_tag_close'] = '</div>'; -======================================= +===================================== The closing tag for the "last" link. @@ -201,18 +200,18 @@ Customizing the "Next" Link *************************** $config['next_link'] = '>'; -=============================== +============================== The text you would like shown in the "next" page link. If you do not want this link rendered, you can set its value to FALSE. $config['next_tag_open'] = '<div>'; -===================================== +=================================== The opening tag for the "next" link. $config['next_tag_close'] = '</div>'; -======================================= +===================================== The closing tag for the "next" link. @@ -221,18 +220,18 @@ Customizing the "Previous" Link ******************************* $config['prev_link'] = '<'; -=============================== +============================== The text you would like shown in the "previous" page link. If you do not want this link rendered, you can set its value to FALSE. $config['prev_tag_open'] = '<div>'; -===================================== +=================================== The opening tag for the "previous" link. $config['prev_tag_close'] = '</div>'; -======================================= +===================================== The closing tag for the "previous" link. @@ -241,12 +240,12 @@ Customizing the "Current Page" Link *********************************** $config['cur_tag_open'] = '<b>'; -================================== +================================ The opening tag for the "current" link. $config['cur_tag_close'] = '</b>'; -==================================== +================================== The closing tag for the "current" link. @@ -255,12 +254,12 @@ Customizing the "Digit" Link **************************** $config['num_tag_open'] = '<div>'; -==================================== +================================== The opening tag for the "digit" link. $config['num_tag_close'] = '</div>'; -====================================== +==================================== The closing tag for the "digit" link. @@ -280,9 +279,7 @@ Adding attributes to anchors If you want to add an extra attribute to be added to every link rendered by the pagination class, you can set them as key/value pairs in the -"attributes" config - -:: +"attributes" config:: // Produces: class="myclass" $config['attributes'] = array('class' => 'myclass'); @@ -300,4 +297,25 @@ you can pass boolean FALSE as a regular attribute :: - $config['attributes']['rel'] = FALSE;
\ No newline at end of file + $config['attributes']['rel'] = FALSE; + +*************** +Class Reference +*************** + +.. class:: CI_Pagination + + .. method:: initialize([$params = array()]) + + :param array $params: Configuration parameters + :returns: CI_Pagination instance (method chaining) + :rtype: CI_Pagination + + Initializes the Pagination class with your preferred options. + + .. method:: create_links() + + :returns: HTML-formatted pagination + :rtype: string + + Returns a "pagination" bar, containing the generated links or an empty string if there's just a single page.
\ No newline at end of file diff --git a/user_guide_src/source/libraries/parser.rst b/user_guide_src/source/libraries/parser.rst index 0b77ae4b9..5af504a03 100644 --- a/user_guide_src/source/libraries/parser.rst +++ b/user_guide_src/source/libraries/parser.rst @@ -35,6 +35,13 @@ representations that allow you to eliminate PHP from your templates template parsing solution. We've kept it very lean on purpose in order to maintain maximum performance. +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + Initializing the Class ====================== @@ -46,15 +53,10 @@ in your controller using the $this->load->library function:: Once loaded, the Parser library object will be available using: $this->parser -The following functions are available in this library: - -$this->parser->parse() -====================== - -This method accepts a template name and data array as input, and it -generates a parsed version. Example:: +Parsing templates +================= - $this->load->library('parser'); +You can use the ``parse()`` method to parse (or render) simple templates, like this:: $data = array( 'blog_title' => 'My Blog Title', @@ -77,12 +79,6 @@ third parameter:: $string = $this->parser->parse('blog_template', $data, TRUE); -$this->parser->parse_string() -============================== - -This method works exactly like parse(), only accepts a string as the -first parameter in place of a view file. - Variable Pairs ============== @@ -147,3 +143,37 @@ function:: $this->parser->parse('blog_template', $data); +*************** +Class Reference +*************** + +.. class:: CI_Parser + + .. method:: parse($template, $data[, $return = FALSE]) + + :param string $template: Path to view file + :param array $data: Variable data + :param bool $return: Whether to only return the parsed template + :returns: Parsed template string + :rtype: string + + Parses a template from the provided path and variables. + + .. method:: parse_string($template, $data[, $return = FALSE]) + + :param string $template: Path to view file + :param array $data: Variable data + :param bool $return: Whether to only return the parsed template + :returns: Parsed template string + :rtype: string + + This method works exactly like ``parse()``, only it accepts the template as a + string instead of loading a view file. + + .. method:: set_delimiters([$l = '{'[, $r = '}']]) + + :param string $l: Left delimiter + :param string $r: Right delimiter + :rtype: void + + Sets the delimiters (opening and closing) for a value "tag" in a template.
\ No newline at end of file diff --git a/user_guide_src/source/libraries/security.rst b/user_guide_src/source/libraries/security.rst index 05553142f..fb875a0d9 100644 --- a/user_guide_src/source/libraries/security.rst +++ b/user_guide_src/source/libraries/security.rst @@ -5,6 +5,13 @@ Security Class The Security Class contains methods that help you create a secure application, processing input data for security. +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + XSS Filtering ============= @@ -23,12 +30,7 @@ Note: This function should only be used to deal with data upon submission. It's not something that should be used for general runtime processing since it requires a fair amount of processing overhead. -To filter data through the XSS filter use this function: - -$this->security->xss_clean() -============================ - -Here is an usage example:: +To filter data through the XSS filter use the ``xss_clean()`` method:: $data = $this->security->xss_clean($data); @@ -38,10 +40,10 @@ application/config/config.php file and setting this:: $config['global_xss_filtering'] = TRUE; -Note: If you use the form validation class, it gives you the option of -XSS filtering as well. +.. note:: If you use the form validation class, it gives you the option of + XSS filtering as well. -An optional second parameter, is_image, allows this function to be used +An optional second parameter, *is_image*, allows this function to be used to test images for potential XSS attacks, useful for file upload security. When this second parameter is set to TRUE, instead of returning an altered string, the function returns TRUE if the image is @@ -52,45 +54,26 @@ browser may attempt to execute. if ($this->security->xss_clean($file, TRUE) === FALSE) { - // file failed the XSS test + // file failed the XSS test } -$this->security->sanitize_filename() -==================================== - -When accepting filenames from user input, it is best to sanitize them to -prevent directory traversal and other security related issues. To do so, -use the sanitize_filename() method of the Security class. Here is an -example:: - - $filename = $this->security->sanitize_filename($this->input->post('filename')); - -If it is acceptable for the user input to include relative paths, e.g. -file/in/some/approved/folder.txt, you can set the second optional -parameter, $relative_path to TRUE. - -:: - - $filename = $this->security->sanitize_filename($this->input->post('filename'), TRUE); - Cross-site request forgery (CSRF) ================================= -You can enable CSRF protection by opening your -application/config/config.php file and setting this:: +You can enable CSRF protection by altering your **application/config/config.php** +file in the following way:: $config['csrf_protection'] = TRUE; If you use the :doc:`form helper <../helpers/form_helper>`, then -``form_open()`` will automatically insert a hidden csrf field in -your forms. If not, then you can use ``csrf_get_token_name()`` -and ``csrf_get_hash()`` - +:func:`form_open()` will automatically insert a hidden csrf field in +your forms. If not, then you can use ``get_csrf_token_name()`` +and ``get_csrf_hash()`` :: $csrf = array( - 'name' => $this->security->csrf_get_token_name(), - 'hash' => $this->security->csrf_get_hash() + 'name' => $this->security->get_csrf_token_name(), + 'hash' => $this->security->get_csrf_hash() ); ... @@ -114,15 +97,63 @@ by editing the 'csrf_exclude_uris' config parameter:: $config['csrf_exclude_uris'] = array('api/person/add'); -$this->security->get_csrf_token_name() -====================================== +*************** +Class Reference +*************** + +.. class:: CI_Security + + .. method:: xss_clean($str[, $is_image = FALSE]) + + :param mixed $str: Input string or an array of strings + :returns: XSS-clean data + :rtype: mixed + + Tries to remove XSS exploits from the input data and returns the cleaned string. + If the optional second parameter is set to true, it will return boolean TRUE if the image is safe to use and FALSE if malicious data was detected in it. + + .. method:: sanitize_filename($str[, $relative_path = FALSE]) + + :param string $str: File name/path + :param bool $relative_path: Whether to preserve any directories in the file path + :returns: Sanitized file name/path + :rtype: string + + Tries to sanitize filenames in order to prevent directory traversal attempts + and other security threats, which is particularly useful for files that were supplied via user input. + :: + + $filename = $this->security->sanitize_filename($this->input->post('filename')); + + If it is acceptable for the user input to include relative paths, e.g. + *file/in/some/approved/folder.txt*, you can set the second optional parameter, ``$relative_path`` to TRUE. + :: + + $filename = $this->security->sanitize_filename($this->input->post('filename'), TRUE); + + .. method:: get_csrf_token_name() + + :returns: CSRF token name + :rtype: string + + Returns the CSRF token name (the ``$config['csrf_token_name']`` value). + + .. method:: get_csrf_hash() + + :returns: CSRF hash + :rtype: string + + Returns the CSRF hash value. Useful in combination with ``get_csrf_token_name()`` + for manually building forms or sending valid AJAX POST requests. + + .. method:: entity_decode($str[, $charset = NULL]) -Returns the CSRF token name, which is set by -``$config['csrf_token_name']``. + :param string $str: Input string + :param string $charset: Character set of the input string + :returns: Entity-decoded string + :rtype: string -$this->security->get_csrf_hash() -================================ + This method acts a lot like PHP's own native ``html_entity_decode()`` function in ENT_COMPAT mode, only + it tries to detect HTML entities that don't end in a semicolon because some browsers allow that. -Returns the CSRF hash value. Useful in combination with -``get_csrf_token_name()`` for manually building forms or -sending valid AJAX POST requests.
\ No newline at end of file + If the ``$charset`` parameter is left empty, then your configured ``$config['charset']`` value will be used.
\ No newline at end of file diff --git a/user_guide_src/source/libraries/sessions.rst b/user_guide_src/source/libraries/sessions.rst index 36c7c1d32..f05f86af1 100644 --- a/user_guide_src/source/libraries/sessions.rst +++ b/user_guide_src/source/libraries/sessions.rst @@ -9,6 +9,17 @@ which supports usage of the native PHP Session mechanism. In addition, you may create your own `Custom Drivers`_ to store session data however you wish, while still taking advantage of the features of the Session class. +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + +*********************** +Using the Session Class +*********************** + Initializing a Session ====================== @@ -21,12 +32,13 @@ initializing the class will cause it to read, create, and update sessions. To initialize the Session class manually in your controller constructor, -use the $this->load->driver function:: +use the ``$this->load->driver`` function:: $this->load->driver('session'); -Once loaded, the Sessions library object will be available using: -$this->session +Once loaded, the Sessions library object will be available using:: + + $this->session How do Sessions work? ===================== @@ -62,10 +74,10 @@ prototype:: [array] ( - 'session_id' => random hash, - 'ip_address' => 'string - user IP address', - 'user_agent' => 'string - user agent data', - 'last_activity' => timestamp + 'session_id' => random hash, + 'ip_address' => 'string - user IP address', + 'user_agent' => 'string - user agent data', + 'last_activity' => timestamp ) .. note:: Sessions are only updated every five minutes by default to @@ -91,6 +103,23 @@ fetch. For example, to fetch the session ID you will do this:: .. note:: The function returns NULL if the item you are trying to access does not exist. +If you want to retrieve all of the existing userdata, you can simply +omit the item key parameter:: + + $this->session->userdata(); + + /** + * Produces something similar to: + * + * Array + * ( + * [session_id] => 4a5a5dca22728fb0a84364eeb405b601 + * [ip_address] => 127.0.0.1 + * [user_agent] => Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; + * [last_activity] => 1303142623 + * ) + */ + Adding Custom Session Data ========================== @@ -112,43 +141,26 @@ Where $array is an associative array containing your new data. Here's an example:: $newdata = array( - 'username' => 'johndoe', - 'email' => 'johndoe@some-site.com', - 'logged_in' => TRUE - ); + 'username' => 'johndoe', + 'email' => 'johndoe@some-site.com', + 'logged_in' => TRUE + ); $this->session->set_userdata($newdata); -If you want to add userdata one value at a time, set_userdata() also +If you want to add userdata one value at a time, ``set_userdata()`` also supports this syntax. :: $this->session->set_userdata('some_name', 'some_value'); -If you want to verify that a userdata value exists, call has_userdata(). +If you want to verify that a userdata value exists, call ``has_userdata()``. :: $this->session->has_userdata('some_name'); -Retrieving All Session Data -=========================== - -An array of all userdata can be retrieved as follows:: - - $this->session->all_userdata() - -And returns an associative array like the following:: - - Array - ( - [session_id] => 4a5a5dca22728fb0a84364eeb405b601 - [ip_address] => 127.0.0.1 - [user_agent] => Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; - [last_activity] => 1303142623 - ) - Removing Session Data ===================== @@ -185,8 +197,8 @@ To add flashdata:: $this->session->set_flashdata('item', 'value'); -You can also pass an array to set_flashdata(), in the same manner as -set_userdata(). +You can also pass an array to ``set_flashdata()``, in the same manner as +``set_userdata()``. To read a flashdata variable:: @@ -194,11 +206,11 @@ To read a flashdata variable:: An array of all flashdata can be retrieved as follows:: - $this->session->all_flashdata(); + $this->session->flashdata(); If you find that you need to preserve a flashdata variable through an -additional request, you can do so using the keep_flashdata() function. +additional request, you can do so using the ``keep_flashdata()`` function. You can either pass a single item or an array of flashdata items to keep. :: @@ -206,6 +218,8 @@ You can either pass a single item or an array of flashdata items to keep. $this->session->keep_flashdata('item'); $this->session->keep_flashdata(array('item1', 'item2', 'item3')); +.. note:: The function will return NULL if the item cannot be found. + Tempdata ======== @@ -219,7 +233,7 @@ To add tempdata:: $this->session->set_tempdata('item', 'value', $expire); -You can also pass an array to set_tempdata():: +You can also pass an array to ``set_tempdata()``:: $tempdata = array('newuser' => TRUE, 'message' => 'Thanks for joining!'); @@ -232,8 +246,12 @@ To read a tempdata variable:: $this->session->tempdata('item'); +And of course, if you want to retrieve all existing tempdata:: + + $this->session->tempdata(); + If you need to remove a tempdata value before it expires, -use unset_tempdata():: +use ``unset_tempdata()``:: $this->session->unset_tempdata('item'); @@ -246,13 +264,13 @@ To clear the current session:: .. note:: This function should be the last one called, and even flash variables will no longer be available. If you only want some items - destroyed and not all, use unset_userdata(). + destroyed and not all, use ``unset_userdata()``. Session Preferences =================== You'll find the following Session related preferences in your -application/config/config.php file: +*application/config/config.php* file: =========================== =============== =========================== ========================================================================== Preference Default Options Description @@ -271,7 +289,8 @@ Preference Default Options Descript table before enabling this option (Cookie driver only). **sess_table_name** ci_sessions Any valid SQL table name The name of the session database table (Cookie driver only). **sess_time_to_update** 300 Time in seconds This options controls how often the session class will regenerate itself - and create a new session id. + and create a new session ID. Setting it to 0 will disable session + ID regeneartion. **sess_match_ip** FALSE TRUE/FALSE (boolean) Whether to match the user's IP address when reading the session data. Note that some ISPs dynamically changes the IP, so if you want a non-expiring session you will likely set this to FALSE. @@ -303,7 +322,7 @@ installed, and `Custom Drivers`_ may also be installed by the user. Typically, only one driver will be used at a time, but CodeIgniter does support loading multiple drivers. If a specific valid driver is called, it will be automatically loaded. Or, an additional driver may be explicitly -loaded by calling load_driver():: +loaded by ``calling load_driver()``:: $this->session->load_driver('native'); @@ -328,7 +347,7 @@ the call to unset the *native* 'foo' value. The drivers maintain independent sets of values, regardless of key names. A specific driver may also be explicitly selected for use by pursuant -methods with the select_driver() call:: +methods with the ``select_driver()`` call:: $this->session->select_driver('native'); @@ -390,11 +409,24 @@ session class:: KEY `last_activity_idx` (`last_activity`) ); +Or if you're using PostgreSQL:: + + CREATE TABLE ci_sessions ( + session_id varchar(40) DEFAULT '0' NOT NULL, + ip_address varchar(45) DEFAULT '0' NOT NULL, + user_agent varchar(120) NOT NULL, + last_activity bigint DEFAULT 0 NOT NULL, + user_data text NOT NULL, + PRIMARY KEY (session_id) + ); + + CREATE INDEX last_activity_idx ON ci_sessions(last_activity); + .. note:: By default the table is called ci_sessions, but you can name it anything you want as long as you update the - application/config/config.php file so that it contains the name you have - chosen. Once you have created your database table you can enable the - database option in your config.php file as follows:: + *application/config/config.php* file so that it contains the name + you have chosen. Once you have created your database table you + can enable the database option in your config.php file as follows:: $config['sess_use_database'] = TRUE; @@ -422,7 +454,7 @@ You may also :doc:`create your own <../general/creating_drivers>` custom session drivers. A session driver basically manages an array of name/value pairs with some sort of storage mechanism. -To make a new driver, extend CI_Session_driver. Overload the initialize() +To make a new driver, extend CI_Session_driver. Overload the ``initialize()`` method and read or create session data. Then implement a save handler to write changed data to storage (sess_save), a destroy handler to remove deleted data (sess_destroy), a regenerate handler to make a new session ID @@ -430,6 +462,7 @@ deleted data (sess_destroy), a regenerate handler to make a new session ID Your initial class might look like:: class CI_Session_custom extends CI_Session_driver { + protected function initialize() { // Read existing session data or create a new one @@ -454,15 +487,16 @@ Your initial class might look like:: { // Return a reference to your userdata array } + } -Notice that get_userdata() returns a reference so the parent library is +Notice that ``get_userdata()`` returns a reference so the parent library is accessing the same array the driver object is using. This saves memory and avoids synchronization issues during usage. Put your driver in the libraries/Session/drivers folder anywhere in your package paths. This includes the application directory, the system directory, -or any path you add with $CI->load->add_package_path(). Your driver must be +or any path you add with ``$CI->load->add_package_path()``. Your driver must be named CI_Session_<name>, and your filename must be Session_<name>.php, preferably also capitalized, such as:: @@ -483,3 +517,186 @@ without making it the initially loaded driver, set 'sess_valid_drivers' in your config.php file to an array including your driver name:: $config['sess_valid_drivers'] = array('sess_driver'); + +*************** +Class Reference +*************** + +.. class:: CI_Session + + .. method:: load_driver($driver) + + :param string $driver: Driver name + :returns: Instance of currently loaded session driver + :rtype: mixed + + Loads a session storage driver + + .. method:: select_driver($driver) + + :param string $driver: Driver name + :rtype: void + + Selects default session storage driver. + + .. method:: sess_destroy() + + :rtype: void + + Destroys current session + + .. note:: This method should be the last one called, and even flash + variables will no longer be available after it is used. + If you only want some items destroyed and not all, use + ``unset_userdata()``. + + .. method:: sess_regenerate([$destroy = FALSE]) + + :param bool $destroy: Whether to destroy session data + :rtype: void + + Regenerate the current session data. + + .. method:: userdata([$item = NULL]) + + :param string $item: Session item name + :returns: Item value if found, NULL if not or an array of all userdata if $item parameter is not used + :rtype: mixed + + If no parameter is passed, it will return an associative array of all existing userdata. + + Otherwise returns a string containing the value of the passed item or NULL if the item is not found. + Example:: + + $this->session->userdata('user'); + //returns example@example.com considering the set_userdata example. + + .. method:: all_userdata() + + :returns: An array of all userdata + :rtype: array + + Returns an array with all of the session userdata items. + + .. note:: This method is DEPRECATED. Use ``userdata()`` with no parameters instead. + + .. method:: &get_userdata() + + :returns: A reference to the userdata array + :rtype: &array + + Returns a reference to the userdata array. + + .. method:: set_userdata($newdata[, $newval = '']) + + :param mixed $newdata: Item name or array of items + :param mixed $newval: Item value or empty string (not required if $newdata is array) + :rtype: void + + Sets items into session example usages:: + + $this->session->set_userdata('user', 'example@example.com'); + // adds item user with value example@example.com to the session + + $this->session->set_userdata(array('user'=>'example@example.com')); + // does the same as the above example - adds item user with value example@example.com to the session + + .. method:: unset_userdata($item) + + :param mixed $item: Item name or an array containing multiple items + :rtype: void + + Unsets previously set items from the session. Example:: + + $this->session->unset_userdata('user'); + //unsets 'user' from session data. + + $this->session->unset_userdata(array('user', 'useremail')); + //unsets both 'user' and 'useremail' from the session data. + + .. method:: has_userdata($item) + + :param string $item: Item name + :returns: TRUE if item exists, FALSE if not + :rtype: bool + + Checks if an item exists in the session. + + .. method:: flashdata([$item = NULL]) + + :param string $item: Flashdata item name + :returns: Item value if found, NULL if not or an array of all flashdata if $item parameter is not used + :rtype: mixed + + If no parameter is passed, it will return an associative array of all existing flashdata. + + Otherwise returns a string containing the value of the passed item or NULL if the item is not found. + Example:: + + $this->session->flashdata('message'); + //returns 'Test message.' considering the set_flashdata example. + + .. method:: set_flashdata($newdata[, $newval = '']) + + :param mixed $newdata: Item name or an array of items + :param mixed $newval: Item value or empty string (not required if $newdata is array) + :rtype: void + + Sets items into session flashdata example usages:: + + $this->session->set_flashdata('message', 'Test message.'); + // adds item 'message' with value 'Test message.' to the session flashdata + + $this->session->set_flashdata(array('message'=>'Test message.')); + // does the same as the above example - adds item 'message' with value 'Test message.' + to the session flashdata + + .. method:: keep_flashdata($item) + + :param mixed $item: Item name or an array containing multiple flashdata items + :rtype: void + + Keeps items into flashdata for one more request. + + .. method:: tempdata([$item = NULL]) + + :param string $item: Tempdata item name + :returns: Item value if found, NULL if not or an array of all tempdata if $item parameter is not used + :rtype: mixed + + If no parameter is passed, it will return an associative array of all existing tempdata. + + Otherwise returns a string containing the value of the passed item or NULL if the item is not found. + Example:: + + $this->session->tempdata('message'); + //returns 'Test message.' considering the set_tempdata example. + + .. method:: set_tempdata($newdata[, $newval = ''[, $expire = 0]]) + + :param mixed $newdata: Item name or array containing multiple items + :param string $newval: Item value or empty string (not required if $newdata is array) + :param int $expire: Lifetime in seconds (0 for default) + :rtype: void + + Sets items into session tempdata example:: + + $this->session->set_tempdata('message', 'Test message.', '60'); + // adds item 'message' with value 'Test message.' to the session tempdata for 60 seconds + + $this->session->set_tempdata(array('message'=>'Test message.')); + // does the same as the above example - adds item 'message' with value 'Test message.' + to the session tempdata for the default value of + + .. method:: unset_tempdata($item) + + :param mixed $item: Item name or an array containing multiple items + :rtype: void + + Unsets previously set items from tempdata. Example:: + + $this->session->unset_tempdata('user'); + //unsets 'user' from tempdata. + + $this->session->unset_tempdata(array('user', 'useremail')); + //unsets both 'user' and 'useremail' from the tempdata.
\ No newline at end of file diff --git a/user_guide_src/source/libraries/table.rst b/user_guide_src/source/libraries/table.rst index 6a808abc2..9d95eddfc 100644 --- a/user_guide_src/source/libraries/table.rst +++ b/user_guide_src/source/libraries/table.rst @@ -5,48 +5,60 @@ HTML Table Class The Table Class provides functions that enable you to auto-generate HTML tables from arrays or database result sets. +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + +********************* +Using the Table Class +********************* + Initializing the Class ====================== Like most other classes in CodeIgniter, the Table class is initialized -in your controller using the $this->load->library function:: +in your controller using the ``$this->load->library()`` method:: $this->load->library('table'); -Once loaded, the Table library object will be available using: -$this->table +Once loaded, the Table library object will be available using:: + + $this->table Examples ======== Here is an example showing how you can create a table from a multi-dimensional array. Note that the first array index will become the -table heading (or you can set your own headings using the set_heading() -function described in the function reference below). +table heading (or you can set your own headings using the ``set_heading()`` +method described in the function reference below). :: $this->load->library('table'); $data = array( - array('Name', 'Color', 'Size'), - array('Fred', 'Blue', 'Small'), - array('Mary', 'Red', 'Large'), - array('John', 'Green', 'Medium') - ); + array('Name', 'Color', 'Size'), + array('Fred', 'Blue', 'Small'), + array('Mary', 'Red', 'Large'), + array('John', 'Green', 'Medium') + ); echo $this->table->generate($data); Here is an example of a table created from a database query result. The table class will automatically generate the headings based on the table -names (or you can set your own headings using the set_heading() -function described in the function reference below). +names (or you can set your own headings using the ``set_heading()`` +method described in the class reference below). :: $this->load->library('table'); - $query = $this->db->query("SELECT * FROM my_table"); + $query = $this->db->query('SELECT * FROM my_table'); echo $this->table->generate($query); @@ -82,28 +94,28 @@ Changing the Look of Your Table The Table Class permits you to set a table template with which you can specify the design of your layout. Here is the template prototype:: - $tmpl = array ( - 'table_open' => '<table border="0" cellpadding="4" cellspacing="0">', + $template = array( + 'table_open' => '<table border="0" cellpadding="4" cellspacing="0">', - 'heading_row_start' => '<tr>', - 'heading_row_end' => '</tr>', - 'heading_cell_start' => '<th>', - 'heading_cell_end' => '</th>', + 'heading_row_start' => '<tr>', + 'heading_row_end' => '</tr>', + 'heading_cell_start' => '<th>', + 'heading_cell_end' => '</th>', - 'row_start' => '<tr>', - 'row_end' => '</tr>', - 'cell_start' => '<td>', - 'cell_end' => '</td>', + 'row_start' => '<tr>', + 'row_end' => '</tr>', + 'cell_start' => '<td>', + 'cell_end' => '</td>', - 'row_alt_start' => '<tr>', - 'row_alt_end' => '</tr>', - 'cell_alt_start' => '<td>', - 'cell_alt_end' => '</td>', + 'row_alt_start' => '<tr>', + 'row_alt_end' => '</tr>', + 'cell_alt_start' => '<td>', + 'cell_alt_end' => '</td>', - 'table_close' => '</table>' - ); + 'table_close' => '</table>' + ); - $this->table->set_template($tmpl); + $this->table->set_template($template); .. note:: You'll notice there are two sets of "row" blocks in the template. These permit you to create alternating row colors or design @@ -113,157 +125,167 @@ You are NOT required to submit a complete template. If you only need to change parts of the layout you can simply submit those elements. In this example, only the table opening tag is being changed:: - $tmpl = array ( 'table_open' => '<table border="1" cellpadding="2" cellspacing="1" class="mytable">' ); + $template = array( + 'table_open' => '<table border="1" cellpadding="2" cellspacing="1" class="mytable">' + ); - $this->table->set_template($tmpl); + $this->table->set_template($template); You can also set defaults for these in a config file. -****************** -Function Reference -****************** +*************** +Class Reference +*************** -$this->table->generate() -======================== +.. class:: CI_Table -Returns a string containing the generated table. Accepts an optional -parameter which can be an array or a database result object. + .. attribute:: $function = NULL -$this->table->set_caption() -============================ + Allows you to specify a native PHP function or a valid function array object to be applied to all cell data. + :: -Permits you to add a caption to the table. + $this->load->library('table'); -:: + $this->table->set_heading('Name', 'Color', 'Size'); + $this->table->add_row('Fred', '<strong>Blue</strong>', 'Small'); - $this->table->set_caption('Colors'); + $this->table->function = 'htmlspecialchars'; + echo $this->table->generate(); -$this->table->set_heading() -============================ + In the above example, all cell data would be ran through PHP's :php:func:`htmlspecialchars()` function, resulting in:: -Permits you to set the table heading. You can submit an array or -discrete params:: + <td>Fred</td><td><strong>Blue</strong></td><td>Small</td> - $this->table->set_heading('Name', 'Color', 'Size'); + .. method:: generate([$table_data = NULL]) -:: + :param mixed $table_data: Data to populate the table rows with + :returns: HTML table + :rtype: string - $this->table->set_heading(array('Name', 'Color', 'Size')); + Returns a string containing the generated table. Accepts an optional parameter which can be an array or a database result object. -$this->table->add_row() -======================== + .. method:: set_caption($caption) -Permits you to add a row to your table. You can submit an array or -discrete params:: + :param string $caption: Table caption + :returns: CI_Table instance (method chaining) + :rtype: CI_Table - $this->table->add_row('Blue', 'Red', 'Green'); + Permits you to add a caption to the table. + :: -:: + $this->table->set_caption('Colors'); - $this->table->add_row(array('Blue', 'Red', 'Green')); + .. method:: set_heading([$args = array()[, ...]]) -If you would like to set an individual cell's tag attributes, you can -use an associative array for that cell. The associative key 'data' -defines the cell's data. Any other key => val pairs are added as -key='val' attributes to the tag:: + :param mixed $args: An array or multiple strings containing the table column titles + :returns: CI_Table instance (method chaining) + :rtype: CI_Table - $cell = array('data' => 'Blue', 'class' => 'highlight', 'colspan' => 2); - $this->table->add_row($cell, 'Red', 'Green'); + Permits you to set the table heading. You can submit an array or discrete params:: - // generates - // <td class='highlight' colspan='2'>Blue</td><td>Red</td><td>Green</td> + $this->table->set_heading('Name', 'Color', 'Size'); -$this->table->make_columns() -============================= + $this->table->set_heading(array('Name', 'Color', 'Size')); -This function takes a one-dimensional array as input and creates a -multi-dimensional array with a depth equal to the number of columns -desired. This allows a single array with many elements to be displayed -in a table that has a fixed column count. Consider this example:: + .. method:: add_row([$args = array()[, ...]]) - $list = array('one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve'); + :param mixed $args: An array or multiple strings containing the row values + :returns: CI_Table instance (method chaining) + :rtype: CI_Table - $new_list = $this->table->make_columns($list, 3); + Permits you to add a row to your table. You can submit an array or discrete params:: - $this->table->generate($new_list); + $this->table->add_row('Blue', 'Red', 'Green'); - // Generates a table with this prototype + $this->table->add_row(array('Blue', 'Red', 'Green')); - <table border="0" cellpadding="4" cellspacing="0"> - <tr> - <td>one</td><td>two</td><td>three</td> - </tr><tr> - <td>four</td><td>five</td><td>six</td> - </tr><tr> - <td>seven</td><td>eight</td><td>nine</td> - </tr><tr> - <td>ten</td><td>eleven</td><td>twelve</td></tr> - </table> + If you would like to set an individual cell's tag attributes, you can use an associative array for that cell. + The associative key **data** defines the cell's data. Any other key => val pairs are added as key='val' attributes to the tag:: -$this->table->set_template() -============================= + $cell = array('data' => 'Blue', 'class' => 'highlight', 'colspan' => 2); + $this->table->add_row($cell, 'Red', 'Green'); -Permits you to set your template. You can submit a full or partial -template. + // generates + // <td class='highlight' colspan='2'>Blue</td><td>Red</td><td>Green</td> -:: + .. method:: make_columns([$array = array()[, $col_limit = 0]]) - $tmpl = array ( 'table_open' => '<table border="1" cellpadding="2" cellspacing="1" class="mytable">' ); + :param array $array: An array containing multiple rows' data + :param int $col_limit: Count of columns in the table + :returns: An array of HTML table columns + :rtype: array - $this->table->set_template($tmpl); + This method takes a one-dimensional array as input and creates a multi-dimensional array with a depth equal to the number of columns desired. + This allows a single array with many elements to be displayed in a table that has a fixed column count. Consider this example:: -$this->table->set_empty() -========================== + $list = array('one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve'); -Let's you set a default value for use in any table cells that are empty. -You might, for example, set a non-breaking space:: + $new_list = $this->table->make_columns($list, 3); - $this->table->set_empty(" "); + $this->table->generate($new_list); -$this->table->clear() -===================== + // Generates a table with this prototype -Lets you clear the table heading and row data. If you need to show -multiple tables with different data you should to call this function -after each table has been generated to empty the previous table -information. Example:: + <table border="0" cellpadding="4" cellspacing="0"> + <tr> + <td>one</td><td>two</td><td>three</td> + </tr><tr> + <td>four</td><td>five</td><td>six</td> + </tr><tr> + <td>seven</td><td>eight</td><td>nine</td> + </tr><tr> + <td>ten</td><td>eleven</td><td>twelve</td></tr> + </table> - $this->load->library('table'); - $this->table->set_heading('Name', 'Color', 'Size'); - $this->table->add_row('Fred', 'Blue', 'Small'); - $this->table->add_row('Mary', 'Red', 'Large'); - $this->table->add_row('John', 'Green', 'Medium'); + .. method:: set_template($template) - echo $this->table->generate(); + :param array $template: An associative array containing template values + :returns: TRUE on success, FALSE on failure + :rtype: bool - $this->table->clear(); + Permits you to set your template. You can submit a full or partial template. + :: - $this->table->set_heading('Name', 'Day', 'Delivery'); - $this->table->add_row('Fred', 'Wednesday', 'Express'); - $this->table->add_row('Mary', 'Monday', 'Air'); - $this->table->add_row('John', 'Saturday', 'Overnight'); + $template = array( + 'table_open' => '<table border="1" cellpadding="2" cellspacing="1" class="mytable">' + ); + + $this->table->set_template($template); - echo $this->table->generate(); + .. method:: set_empty($value) -$this->table->function -====================== + :param mixed $value: Value to put in empty cells + :returns: CI_Table instance (method chaining) + :rtype: CI_Table -Allows you to specify a native PHP function or a valid function array -object to be applied to all cell data. + Lets you set a default value for use in any table cells that are empty. + You might, for example, set a non-breaking space:: -:: + $this->table->set_empty(" "); - $this->load->library('table'); + .. method:: clear() - $this->table->set_heading('Name', 'Color', 'Size'); - $this->table->add_row('Fred', '<strong>Blue</strong>', 'Small'); + :returns: CI_Table instance (method chaining) + :rtype: CI_Table - $this->table->function = 'htmlspecialchars'; - echo $this->table->generate(); + Lets you clear the table heading and row data. If you need to show multiple tables with different data you should to call this method + after each table has been generated to clear the previous table information. Example:: + + $this->load->library('table'); + + $this->table->set_heading('Name', 'Color', 'Size'); + $this->table->add_row('Fred', 'Blue', 'Small'); + $this->table->add_row('Mary', 'Red', 'Large'); + $this->table->add_row('John', 'Green', 'Medium'); + + echo $this->table->generate(); -In the above example, all cell data would be ran through PHP's -htmlspecialchars() function, resulting in:: + $this->table->clear(); - <td>Fred</td><td><strong>Blue</strong></td><td>Small</td> + $this->table->set_heading('Name', 'Day', 'Delivery'); + $this->table->add_row('Fred', 'Wednesday', 'Express'); + $this->table->add_row('Mary', 'Monday', 'Air'); + $this->table->add_row('John', 'Saturday', 'Overnight'); + echo $this->table->generate();
\ No newline at end of file diff --git a/user_guide_src/source/libraries/trackback.rst b/user_guide_src/source/libraries/trackback.rst index f9e0df882..22859a13d 100644 --- a/user_guide_src/source/libraries/trackback.rst +++ b/user_guide_src/source/libraries/trackback.rst @@ -8,16 +8,28 @@ receive Trackback data. If you are not familiar with Trackbacks you'll find more information `here <http://en.wikipedia.org/wiki/Trackback>`_. +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + +************************* +Using the Trackback Class +************************* + Initializing the Class ====================== Like most other classes in CodeIgniter, the Trackback class is -initialized in your controller using the $this->load->library function:: +initialized in your controller using the ``$this->load->library()`` method:: $this->load->library('trackback'); -Once loaded, the Trackback library object will be available using: -$this->trackback +Once loaded, the Trackback library object will be available using:: + + $this->trackback Sending Trackbacks ================== @@ -28,38 +40,37 @@ similar to this example:: $this->load->library('trackback'); $tb_data = array( - 'ping_url' => 'http://example.com/trackback/456', - 'url' => 'http://www.my-example.com/blog/entry/123', - 'title' => 'The Title of My Entry', - 'excerpt' => 'The entry content.', - 'blog_name' => 'My Blog Name', - 'charset' => 'utf-8' - ); + 'ping_url' => 'http://example.com/trackback/456', + 'url' => 'http://www.my-example.com/blog/entry/123', + 'title' => 'The Title of My Entry', + 'excerpt' => 'The entry content.', + 'blog_name' => 'My Blog Name', + 'charset' => 'utf-8' + ); if ( ! $this->trackback->send($tb_data)) { - echo $this->trackback->display_errors(); + echo $this->trackback->display_errors(); } else { - echo 'Trackback was sent!'; + echo 'Trackback was sent!'; } Description of array data: - **ping_url** - The URL of the site you are sending the Trackback to. - You can send Trackbacks to multiple URLs by separating each URL with - a comma. + You can send Trackbacks to multiple URLs by separating each URL with a comma. - **url** - The URL to YOUR site where the weblog entry can be seen. - **title** - The title of your weblog entry. -- **excerpt** - The content of your weblog entry. Note: the Trackback - class will automatically send only the first 500 characters of your - entry. It will also strip all HTML. +- **excerpt** - The content of your weblog entry. - **blog_name** - The name of your weblog. -- **charset** - The character encoding your weblog is written in. If - omitted, UTF-8 will be used. +- **charset** - The character encoding your weblog is written in. If omitted, UTF-8 will be used. -The Trackback sending function returns TRUE/FALSE (boolean) on success +.. note:: the Trackback class will automatically send only the first 500 characters of your + entry. It will also strip all HTML. + +The Trackback sending method returns TRUE/FALSE (boolean) on success or failure. If it fails, you can retrieve the error message using:: $this->trackback->display_errors(); @@ -107,16 +118,16 @@ Before you can receive Trackbacks you must create a table in which to store them. Here is a basic prototype for such a table:: CREATE TABLE trackbacks ( - tb_id int(10) unsigned NOT NULL auto_increment, - entry_id int(10) unsigned NOT NULL default 0, - url varchar(200) NOT NULL, - title varchar(100) NOT NULL, - excerpt text NOT NULL, - blog_name varchar(100) NOT NULL, - tb_date int(10) NOT NULL, - ip_address varchar(45) NOT NULL, - PRIMARY KEY `tb_id` (`tb_id`), - KEY `entry_id` (`entry_id`) + tb_id int(10) unsigned NOT NULL auto_increment, + entry_id int(10) unsigned NOT NULL default 0, + url varchar(200) NOT NULL, + title varchar(100) NOT NULL, + excerpt text NOT NULL, + blog_name varchar(100) NOT NULL, + tb_date int(10) NOT NULL, + ip_address varchar(45) NOT NULL, + PRIMARY KEY `tb_id` (`tb_id`), + KEY `entry_id` (`entry_id`) ); The Trackback specification only requires four pieces of information to @@ -129,33 +140,31 @@ Processing a Trackback Here is an example showing how you will receive and process a Trackback. The following code is intended for use within the controller function -where you expect to receive Trackbacks. - -:: +where you expect to receive Trackbacks.:: $this->load->library('trackback'); $this->load->database(); if ($this->uri->segment(3) == FALSE) { - $this->trackback->send_error("Unable to determine the entry ID"); + $this->trackback->send_error('Unable to determine the entry ID'); } if ( ! $this->trackback->receive()) { - $this->trackback->send_error("The Trackback did not contain valid data"); + $this->trackback->send_error('The Trackback did not contain valid data'); } $data = array( - 'tb_id' => '', - 'entry_id' => $this->uri->segment(3), - 'url' => $this->trackback->data('url'), - 'title' => $this->trackback->data('title'), - 'excerpt' => $this->trackback->data('excerpt'), - 'blog_name' => $this->trackback->data('blog_name'), - 'tb_date' => time(), - 'ip_address' => $this->input->ip_address() - ); + 'tb_id' => '', + 'entry_id' => $this->uri->segment(3), + 'url' => $this->trackback->data('url'), + 'title' => $this->trackback->data('title'), + 'excerpt' => $this->trackback->data('excerpt'), + 'blog_name' => $this->trackback->data('blog_name'), + 'tb_date' => time(), + 'ip_address' => $this->input->ip_address() + ); $sql = $this->db->insert_string('trackbacks', $data); $this->db->query($sql); @@ -199,3 +208,132 @@ message using:: .. note:: The above code contains no data validation, which you are encouraged to add. + +*************** +Class Reference +*************** + +.. class:: CI_Trackback + + .. attribute:: $data = array('url' => '', 'title' => '', 'excerpt' => '', 'blog_name' => '', 'charset' => '') + + Trackback data array. + + .. attribute:: $convert_ascii = TRUE + + Whether to convert high ASCII and MS Word characters to HTML entities. + + .. method:: send($tb_data) + + :param array $tb_data: Trackback data + :returns: TRUE on success, FALSE on failure + :rtype: bool + + Send trackback. + + .. method:: receive() + + :returns: TRUE on success, FALSE on failure + :rtype: bool + + This method simply validates the incoming TB data, returning TRUE on success and FALSE on failure. + If the data is valid it is set to the ``$this->data`` array so that it can be inserted into a database. + + .. method:: send_error([$message = 'Incomplete information') + + :param string $message: Error message + :rtype: void + + Responses to a trackback request with an error message. + + .. note:: This method will terminate script execution. + + .. method:: send_success() + + :rtype: void + + Responses to a trackback request with a success message. + + .. note:: This method will terminate script execution. + + .. method:: data($item) + + :param string $item: Data key + :returns: Data value or empty string if not found + :rtype: string + + Returns a single item from the reponse data array. + + .. method:: process($url, $data) + + :param string $url: Target url + :param string $data: Raw POST data + :returns: TRUE on success, FALSE on failure + :rtype: bool + + Opens a socket connection and passes the data to the server, returning TRUE on success and FALSE on failure. + + .. method:: extract_urls($urls) + + :param string $urls: Comma-separated URL list + :returns: Array of URLs + :rtype: array + + This method lets multiple trackbacks to be sent. It takes a string of URLs (separated by comma or space) and puts each URL into an array. + + .. method:: validate_url(&$url) + + :param string $url: Trackback URL + :rtype: void + + Simply adds the *http://* prefix it it's not already present in the URL. + + .. method:: get_id($url) + + :param string $url: Trackback URL + :returns: URL ID or FALSE on failure + :rtype: string + + Find and return a trackback URL's ID or FALSE on failure. + + .. method:: convert_xml($str) + + :param string $str: Input string + :returns: Converted string + :rtype: string + + Converts reserved XML characters to entities. + + .. method:: limit_characters($str[, $n = 500[, $end_char = '…']]) + + :param string $str: Input string + :param int $n: Max characters number + :param string $end_char: Character to put at end of string + :returns: Shortened string + :rtype: string + + Limits the string based on the character count. Will preserve complete words. + + .. method:: convert_ascii($str) + + :param string $str: Input string + :returns: Converted string + :rtype: string + + Converts high ASCII text and MS Word special characterss to HTML entities. + + .. method:: set_error($msg) + + :param string $msg: Error message + :rtype: void + + Set an log an error message. + + .. method:: display_errors([$open = '<p>'[, $close = '</p>']]) + + :param string $open: Open tag + :param string $close: Close tag + :returns: HTML formatted error messages + :rtype: string + + Returns error messages formatted in HTML or an empty string if there are no errors.
\ No newline at end of file diff --git a/user_guide_src/source/libraries/typography.rst b/user_guide_src/source/libraries/typography.rst index db3f227be..65fea9d8e 100644 --- a/user_guide_src/source/libraries/typography.rst +++ b/user_guide_src/source/libraries/typography.rst @@ -2,104 +2,106 @@ Typography Class ################ -The Typography Class provides functions that help you format text. +The Typography Class provides methods that help you format text. + +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + +************************** +Using the Typography Class +************************** Initializing the Class ====================== Like most other classes in CodeIgniter, the Typography class is -initialized in your controller using the $this->load->library function:: +initialized in your controller using the ``$this->load->library()`` method:: $this->load->library('typography'); -Once loaded, the Typography library object will be available using: -$this->typography +Once loaded, the Typography library object will be available using:: -auto_typography() -================== + $this->typography -Formats text so that it is semantically and typographically correct -HTML. Takes a string as input and returns it with the following -formatting: +*************** +Class Reference +*************** -- Surrounds paragraphs within <p></p> (looks for double line breaks to - identify paragraphs). -- Single line breaks are converted to <br />, except those that appear - within <pre> tags. -- Block level elements, like <div> tags, are not wrapped within - paragraphs, but their contained text is if it contains paragraphs. -- Quotes are converted to correctly facing curly quote entities, except - those that appear within tags. -- Apostrophes are converted to curly apostrophe entities. -- Double dashes (either like -- this or like--this) are converted to - em—dashes. -- Three consecutive periods either preceding or following a word are - converted to ellipsis… -- Double spaces following sentences are converted to non-breaking - spaces to mimic double spacing. +.. class:: CI_Typography -Usage example:: + .. attribute:: $protect_braced_quotes = FALSE - $string = $this->typography->auto_typography($string); + When using the Typography library in conjunction with the :doc:`Template Parser library <parser>` + it can often be desirable to protect single and double quotes within curly braces. + To enable this, set the ``protect_braced_quotes`` class property to TRUE. -Parameters ----------- + Usage example:: -There is one optional parameters that determines whether the parser -should reduce more then two consecutive line breaks down to two. Use -boolean TRUE or FALSE. + $this->load->library('typography'); + $this->typography->protect_braced_quotes = TRUE; -By default the parser does not reduce line breaks. In other words, if no -parameters are submitted, it is the same as doing this:: + .. method auto_typography($str[, $reduce_linebreaks = FALSE]) - $string = $this->typography->auto_typography($string, FALSE); + :param string $str: Input string + :param bool $reduce_linebreaks: Whether to reduce consequitive linebreaks + :returns: HTML typography-safe string + :rtype: string -.. note:: Typographic formatting can be processor intensive, - particularly if you have a lot of content being formatted. If you choose - to use this function you may want to consider :doc:`caching <../general/caching>` - your pages. + Formats text so that it is semantically and typographically correct HTML. + Takes a string as input and returns it with the following formatting: -format_characters() -==================== + - Surrounds paragraphs within <p></p> (looks for double line breaks to identify paragraphs). + - Single line breaks are converted to <br />, except those that appear within <pre> tags. + - Block level elements, like <div> tags, are not wrapped within paragraphs, but their contained text is if it contains paragraphs. + - Quotes are converted to correctly facing curly quote entities, except those that appear within tags. + - Apostrophes are converted to curly apostrophe entities. + - Double dashes (either like -- this or like--this) are converted to em—dashes. + - Three consecutive periods either preceding or following a word are converted to ellipsis (…). + - Double spaces following sentences are converted to non-breaking spaces to mimic double spacing. -This function is similar to the auto_typography function above, except -that it only does character conversion: + Usage example:: -- Quotes are converted to correctly facing curly quote entities, except - those that appear within tags. -- Apostrophes are converted to curly apostrophe entities. -- Double dashes (either like -- this or like--this) are converted to - em—dashes. -- Three consecutive periods either preceding or following a word are - converted to ellipsis… -- Double spaces following sentences are converted to non-breaking - spaces to mimic double spacing. + $string = $this->typography->auto_typography($string); -Usage example:: + There is one optional parameter that determines whether the parser should reduce more than two consecutive line breaks down to two. + Pass boolean TRUE to enable reducing line breaks:: - $string = $this->typography->format_characters($string); + $string = $this->typography->auto_typography($string, TRUE); -nl2br_except_pre() -==================== + .. note:: Typographic formatting can be processor intensive, particularly if you have a lot of content being formatted. + If you choose to use this method you may want to consider :doc:`caching <../general/caching>` your pages. -Converts newlines to <br /> tags unless they appear within <pre> tags. -This function is identical to the native PHP nl2br() function, except -that it ignores <pre> tags. + .. method:: format_characters($str) -Usage example:: + :param string $str: Input string + :returns: Formatted string + :rtype: string - $string = $this->typography->nl2br_except_pre($string); + This method is similar to ``auto_typography()`` above, except that it only does character conversion: -protect_braced_quotes -======================= + - Quotes are converted to correctly facing curly quote entities, except those that appear within tags. + - Apostrophes are converted to curly apostrophe entities. + - Double dashes (either like -- this or like--this) are converted to em—dashes. + - Three consecutive periods either preceding or following a word are converted to ellipsis (…). + - Double spaces following sentences are converted to non-breaking spaces to mimic double spacing. -When using the Typography library in conjunction with the Template -Parser library it can often be desirable to protect single and double -quotes within curly braces. To enable this, set the -protect_braced_quotes class property to TRUE. + Usage example:: -Usage example:: + $string = $this->typography->format_characters($string); - $this->load->library('typography'); - $this->typography->protect_braced_quotes = TRUE; + .. method:: nl2br_except_pre($str) + + :param string $str: Input string + :returns: Formatted string + :rtype: string + + Converts newlines to <br /> tags unless they appear within <pre> tags. + This method is identical to the native PHP :php:func:`nl2br()` function, except that it ignores <pre> tags. + + Usage example:: + $string = $this->typography->nl2br_except_pre($string);
\ No newline at end of file diff --git a/user_guide_src/source/libraries/unit_testing.rst b/user_guide_src/source/libraries/unit_testing.rst index 6bd91bf88..0bc860f61 100644 --- a/user_guide_src/source/libraries/unit_testing.rst +++ b/user_guide_src/source/libraries/unit_testing.rst @@ -11,6 +11,13 @@ evaluation function and two result functions. It's not intended to be a full-blown test suite but rather a simple mechanism to evaluate your code to determine if it is producing the correct data type and result. +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + Initializing the Class ====================== @@ -19,16 +26,15 @@ initialized in your controller using the $this->load->library function:: $this->load->library('unit_test'); -Once loaded, the Unit Test object will be available using: $this->unit +Once loaded, the Unit Test object will be available using ``$this->unit`` Running Tests ============= -Running a test involves supplying a test and an expected result to the -following function: +Running a test involves supplying a test and an expected result in the +following way: -$this->unit->run( test, expected result, 'test name', 'notes'); -=============================================================== + $this->unit->run('test', 'expected result', 'test name', 'notes'); Where test is the result of the code you wish to test, expected result is the data type you expect, test name is an optional name you can give @@ -114,7 +120,7 @@ Enabling/Disabling Unit Testing If you would like to leave some testing in place in your scripts, but not have it run unless you need it, you can disable unit testing using:: - $this->unit->active(FALSE) + $this->unit->active(FALSE); Unit Test Display ================= @@ -150,15 +156,85 @@ template. Note the required pseudo-variables:: $str = ' <table border="0" cellpadding="4" cellspacing="1"> - {rows} - <tr> - <td>{item}</td> - <td>{result}</td> - </tr> - {/rows} + {rows} + <tr> + <td>{item}</td> + <td>{result}</td> + </tr> + {/rows} </table>'; $this->unit->set_template($str); .. note:: Your template must be declared **before** running the unit test process. + +*************** +Class Reference +*************** + +.. class:: CI_Unit_test + + .. method:: set_test_items($items) + + :param array $items: List of visible test items + :returns: void + + Sets a list of items that should be visible in tests. + Valid options are: + + - test_name + - test_datatype + - res_datatype + - result + - file + - line + - notes + + .. method:: run($test[, $expected = TRUE[, $test_name = 'undefined'[, $notes = '']]]) + + :param mixed $test: Test data + :param mixed $expected: Expected result + :param string $test_name: Test name + :param string $notes: Any notes to be attached to the test + :returns: Test report + :rtype: string + + Runs unit tests. + + .. method:: report([$result = array()]) + + :param array $result: Array containing tests results + :returns: Test report + :rtype: string + + Generates a report about already complete tests. + + .. method:: use_strict([$state = TRUE]) + + :param bool $state: Strict state flag + :rtype: void + + Enables/disables strict type comparison in tests. + + .. method:: active([$state = TRUE]) + + :param bool $state: Whether to enable testing + :rtype: void + + Enables/disables unit testing. + + .. method:: result([$results = array()]) + + :param array $results: Tests results list + :returns: Array of raw result data + :rtype: array + + Returns raw tests results data. + + .. method:: set_template($template) + + :param string $template: Test result template + :rtype: void + + Sets the template for displaying tests results.
\ No newline at end of file diff --git a/user_guide_src/source/libraries/uri.rst b/user_guide_src/source/libraries/uri.rst index bb959b002..7db758ce7 100644 --- a/user_guide_src/source/libraries/uri.rst +++ b/user_guide_src/source/libraries/uri.rst @@ -2,187 +2,232 @@ URI Class ######### -The URI Class provides functions that help you retrieve information from +The URI Class provides methods that help you retrieve information from your URI strings. If you use URI routing, you can also retrieve information about the re-routed segments. .. note:: This class is initialized automatically by the system so there is no need to do it manually. -$this->uri->segment(n) -====================== +.. contents:: + :local: -Permits you to retrieve a specific segment. Where n is the segment -number you wish to retrieve. Segments are numbered from left to right. -For example, if your full URL is this:: +.. raw:: html - http://example.com/index.php/news/local/metro/crime_is_up + <div class="custom-index container"></div> -The segment numbers would be this: +*************** +Class Reference +*************** -#. news -#. local -#. metro -#. crime_is_up +.. class:: CI_URI -By default the function returns NULL if the segment does not -exist. There is an optional second parameter that permits you to set -your own default value if the segment is missing. For example, this -would tell the function to return the number zero in the event of -failure:: + .. method:: segment($n[, $no_result = NULL]) - $product_id = $this->uri->segment(3, 0); + :param int $n: Segment index number + :param mixed $no_result: What to return if the searched segment is not found + :returns: Segment value or $no_result value if not found + :rtype: mixed -It helps avoid having to write code like this:: + Permits you to retrieve a specific segment. Where n is the segment + number you wish to retrieve. Segments are numbered from left to right. + For example, if your full URL is this:: - if ($this->uri->segment(3) === FALSE) - { - $product_id = 0; - } - else - { - $product_id = $this->uri->segment(3); - } + http://example.com/index.php/news/local/metro/crime_is_up -$this->uri->rsegment(n) -======================= + The segment numbers would be this: -This function is identical to the previous one, except that it lets you -retrieve a specific segment from your re-routed URI in the event you are -using CodeIgniter's :doc:`URI Routing <../general/routing>` feature. + #. news + #. local + #. metro + #. crime_is_up -$this->uri->slash_segment(n) -============================= + The optional second parameter defaults to NULL and allows you to set the return value + of this method when the requested URI segment is missing. + For example, this would tell the method to return the number zero in the event of failure:: -This function is almost identical to $this->uri->segment(), except it -adds a trailing and/or leading slash based on the second parameter. If -the parameter is not used, a trailing slash added. Examples:: + $product_id = $this->uri->segment(3, 0); - $this->uri->slash_segment(3); - $this->uri->slash_segment(3, 'leading'); - $this->uri->slash_segment(3, 'both'); + It helps avoid having to write code like this:: -Returns: + if ($this->uri->segment(3) === FALSE) + { + $product_id = 0; + } + else + { + $product_id = $this->uri->segment(3); + } -#. segment/ -#. /segment -#. /segment/ + .. method:: rsegment($n[, $no_result = NULL]) -$this->uri->slash_rsegment(n) -============================== + :param int $n: Segment index number + :param mixed $no_result: What to return if the searched segment is not found + :returns: Routed segment value or $no_result value if not found + :rtype: mixed -This function is identical to the previous one, except that it lets you -add slashes a specific segment from your re-routed URI in the event you -are using CodeIgniter's :doc:`URI Routing <../general/routing>` -feature. + This method is identical to ``segment()``, except that it lets you retrieve + a specific segment from your re-routed URI in the event you are + using CodeIgniter's :doc:`URI Routing <../general/routing>` feature. -$this->uri->uri_to_assoc(n) -============================= + .. method:: slash_segment($n[, $where = 'trailing']) -This function lets you turn URI segments into and associative array of -key/value pairs. Consider this URI:: + :param int $n: Segment index number + :param string $where: Where to add the slash ('trailing' or 'leading') + :returns: Segment value, prepended/suffixed with a forward slash, or a slash if not found + :rtype: string - index.php/user/search/name/joe/location/UK/gender/male + This method is almost identical to ``segment()``, except it + adds a trailing and/or leading slash based on the second parameter. + If the parameter is not used, a trailing slash added. Examples:: -Using this function you can turn the URI into an associative array with -this prototype:: + $this->uri->slash_segment(3); + $this->uri->slash_segment(3, 'leading'); + $this->uri->slash_segment(3, 'both'); - [array] - ( - 'name' => 'joe' - 'location' => 'UK' - 'gender' => 'male' - ) + Returns: -The first parameter of the function lets you set an offset. By default -it is set to 3 since your URI will normally contain a -controller/function in the first and second segments. Example:: + #. segment/ + #. /segment + #. /segment/ - $array = $this->uri->uri_to_assoc(3); + .. method:: slash_rsegment($n[, $where = 'trailing']) - echo $array['name']; + :param int $n: Segment index number + :param string $where: Where to add the slash ('trailing' or 'leading') + :returns: Routed segment value, prepended/suffixed with a forward slash, or a slash if not found + :rtype: string -The second parameter lets you set default key names, so that the array -returned by the function will always contain expected indexes, even if -missing from the URI. Example:: + This method is identical to ``slash_segment()``, except that it lets you + add slashes a specific segment from your re-routed URI in the event you + are using CodeIgniter's :doc:`URI Routing <../general/routing>` + feature. - $default = array('name', 'gender', 'location', 'type', 'sort'); + .. method:: uri_to_assoc([$n = 3[, $default = array()]]) - $array = $this->uri->uri_to_assoc(3, $default); + :param int $n: Segment index number + :param array $default: Default values + :returns: Associative URI segments array + :rtype: array -If the URI does not contain a value in your default, an array index will -be set to that name, with a value of FALSE. + This method lets you turn URI segments into and associative array of + key/value pairs. Consider this URI:: -Lastly, if a corresponding value is not found for a given key (if there -is an odd number of URI segments) the value will be set to FALSE -(boolean). + index.php/user/search/name/joe/location/UK/gender/male -$this->uri->ruri_to_assoc(n) -============================== + Using this method you can turn the URI into an associative array with + this prototype:: -This function is identical to the previous one, except that it creates -an associative array using the re-routed URI in the event you are using -CodeIgniter's :doc:`URI Routing <../general/routing>` feature. + [array] + ( + 'name' => 'joe' + 'location' => 'UK' + 'gender' => 'male' + ) -$this->uri->assoc_to_uri() -============================ + The first parameter lets you set an offset, which defaults to 3 since your + URI will normally contain a controller/method pair in the first and second segments. + Example:: -Takes an associative array as input and generates a URI string from it. -The array keys will be included in the string. Example:: + $array = $this->uri->uri_to_assoc(3); + echo $array['name']; - $array = array('product' => 'shoes', 'size' => 'large', 'color' => 'red'); + The second parameter lets you set default key names, so that the array + returned will always contain expected indexes, even if missing from the URI. + Example:: - $str = $this->uri->assoc_to_uri($array); + $default = array('name', 'gender', 'location', 'type', 'sort'); + $array = $this->uri->uri_to_assoc(3, $default); - // Produces: product/shoes/size/large/color/red + If the URI does not contain a value in your default, an array index will + be set to that name, with a value of NULL. -$this->uri->uri_string() -========================= + Lastly, if a corresponding value is not found for a given key (if there + is an odd number of URI segments) the value will be set to NULL. -Returns a string with the complete URI. For example, if this is your -full URL:: + .. method:: ruri_to_assoc([$n = 3[, $default = array()]]) - http://example.com/index.php/news/local/345 + :param int $n: Segment index number + :param array $default: Default values + :returns: Associative routed URI segments array + :rtype: array -The function would return this:: + This method is identical to ``uri_to_assoc()``, except that it creates + an associative array using the re-routed URI in the event you are using + CodeIgniter's :doc:`URI Routing <../general/routing>` feature. - news/local/345 + .. method:: assoc_to_uri($array) -$this->uri->ruri_string() -========================== + :param array $array: Input array of key/value pairs + :returns: URI string + :rtype: string -This function is identical to the previous one, except that it returns -the re-routed URI in the event you are using CodeIgniter's :doc:`URI -Routing <../general/routing>` feature. + Takes an associative array as input and generates a URI string from it. + The array keys will be included in the string. Example:: -$this->uri->total_segments() -============================= + $array = array('product' => 'shoes', 'size' => 'large', 'color' => 'red'); + $str = $this->uri->assoc_to_uri($array); -Returns the total number of segments. + // Produces: product/shoes/size/large/color/red -$this->uri->total_rsegments() -============================== + .. method:: uri_string() -This function is identical to the previous one, except that it returns -the total number of segments in your re-routed URI in the event you are -using CodeIgniter's :doc:`URI Routing <../general/routing>` feature. + :returns: URI string + :rtype: string -$this->uri->segment_array() -============================ + Returns a string with the complete URI. For example, if this is your full URL:: -Returns an array containing the URI segments. For example:: + http://example.com/index.php/news/local/345 - $segs = $this->uri->segment_array(); + The method would return this:: - foreach ($segs as $segment) - { - echo $segment; - echo '<br />'; - } + news/local/345 -$this->uri->rsegment_array() -============================= + .. method:: ruri_string() -This function is identical to the previous one, except that it returns -the array of segments in your re-routed URI in the event you are using -CodeIgniter's :doc:`URI Routing <../general/routing>` feature. + :returns: Routed URI string + :rtype: string + + This method is identical to ``uri_string()``, except that it returns + the re-routed URI in the event you are using CodeIgniter's :doc:`URI + Routing <../general/routing>` feature. + + .. method:: total_segments() + + :returns: Count of URI segments + :rtype: int + + Returns the total number of segments. + + .. method:: total_rsegments() + + :returns: Count of routed URI segments + :rtype: int + + This method is identical to ``total_segments()``, except that it returns + the total number of segments in your re-routed URI in the event you are + using CodeIgniter's :doc:`URI Routing <../general/routing>` feature. + + .. method:: segment_array() + + :returns: URI segments array + :rtype: array + + Returns an array containing the URI segments. For example:: + + $segs = $this->uri->segment_array(); + + foreach ($segs as $segment) + { + echo $segment; + echo '<br />'; + } + + .. method:: rsegment_array() + + :returns: Routed URI segments array + :rtype: array + + This method is identical to ``segment_array()``, except that it returns + the array of segments in your re-routed URI in the event you are using + CodeIgniter's :doc:`URI Routing <../general/routing>` feature.
\ No newline at end of file diff --git a/user_guide_src/source/libraries/user_agent.rst b/user_guide_src/source/libraries/user_agent.rst index 97abd2244..517382a65 100644 --- a/user_guide_src/source/libraries/user_agent.rst +++ b/user_guide_src/source/libraries/user_agent.rst @@ -7,6 +7,17 @@ about the browser, mobile device, or robot visiting your site. In addition you can get referrer information as well as language and supported character-set information. +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + +************************** +Using the User Agent Class +************************** + Initializing the Class ====================== @@ -15,7 +26,7 @@ initialized in your controller using the $this->load->library function:: $this->load->library('user_agent'); -Once loaded, the object will be available using: $this->agent +Once loaded, the object will be available using: ``$this->agent`` User Agent Definitions ====================== @@ -38,163 +49,200 @@ is available. if ($this->agent->is_browser()) { - $agent = $this->agent->browser().' '.$this->agent->version(); + $agent = $this->agent->browser().' '.$this->agent->version(); } elseif ($this->agent->is_robot()) { - $agent = $this->agent->robot(); + $agent = $this->agent->robot(); } elseif ($this->agent->is_mobile()) { - $agent = $this->agent->mobile(); + $agent = $this->agent->mobile(); } else { - $agent = 'Unidentified User Agent'; + $agent = 'Unidentified User Agent'; } echo $agent; echo $this->agent->platform(); // Platform info (Windows, Linux, Mac, etc.) -****************** -Function Reference -****************** +*************** +Class Reference +*************** -$this->agent->is_browser() -=========================== +.. class:: CI_User_agent -Returns TRUE/FALSE (boolean) if the user agent is a known web browser. + .. method:: is_browser([$key = NULL]) -:: + :param string $key: Optional browser name + :returns: TRUE if the user agent is a (specified) browser, FALSE if not + :rtype: bool - if ($this->agent->is_browser('Safari')) - { - echo 'You are using Safari.'; - } - elseif ($this->agent->is_browser()) - { - echo 'You are using a browser.'; - } - + Returns TRUE/FALSE (boolean) if the user agent is a known web browser. + :: -.. note:: The string "Safari" in this example is an array key in the - list of browser definitions. You can find this list in - application/config/user_agents.php if you want to add new browsers or - change the stings. + if ($this->agent->is_browser('Safari')) + { + echo 'You are using Safari.'; + } + elseif ($this->agent->is_browser()) + { + echo 'You are using a browser.'; + } -$this->agent->is_mobile() -========================== + .. note:: The string "Safari" in this example is an array key in the list of browser definitions. + You can find this list in **application/config/user_agents.php** if you want to add new + browsers or change the stings. -Returns TRUE/FALSE (boolean) if the user agent is a known mobile device. + .. method:: is_mobile([$key = NULL]) -:: + :param string $key: Optional mobile device name + :returns: TRUE if the user agent is a (specified) mobile device, FALSE if not + :rtype: bool - if ($this->agent->is_mobile('iphone')) - { - $this->load->view('iphone/home'); - } - elseif ($this->agent->is_mobile()) - { - $this->load->view('mobile/home'); - } - else - { - $this->load->view('web/home'); - } - + Returns TRUE/FALSE (boolean) if the user agent is a known mobile device. + :: -$this->agent->is_robot() -========================= + if ($this->agent->is_mobile('iphone')) + { + $this->load->view('iphone/home'); + } + elseif ($this->agent->is_mobile()) + { + $this->load->view('mobile/home'); + } + else + { + $this->load->view('web/home'); + } -Returns TRUE/FALSE (boolean) if the user agent is a known robot. + .. method:: is_robot([$key = NULL]) -.. note:: The user agent library only contains the most common robot - definitions. It is not a complete list of bots. There are hundreds of - them so searching for each one would not be very efficient. If you find - that some bots that commonly visit your site are missing from the list - you can add them to your application/config/user_agents.php file. + :param string $key: Optional robot name + :returns: TRUE if the user agent is a (specified) robot, FALSE if not + :rtype: bool -$this->agent->is_referral() -============================ + Returns TRUE/FALSE (boolean) if the user agent is a known robot. -Returns TRUE/FALSE (boolean) if the user agent was referred from another -site. + .. note:: The user agent library only contains the most common robot definitions. It is not a complete list of bots. + There are hundreds of them so searching for each one would not be very efficient. If you find that some bots + that commonly visit your site are missing from the list you can add them to your + **application/config/user_agents.php** file. -$this->agent->browser() -======================= + .. method:: is_referral() -Returns a string containing the name of the web browser viewing your -site. + :returns: TRUE if the user agent is a referral, FALSE if not + :rtype: bool -$this->agent->version() -======================= + Returns TRUE/FALSE (boolean) if the user agent was referred from another site. -Returns a string containing the version number of the web browser -viewing your site. + .. method:: browser() -$this->agent->mobile() -====================== + :returns: Detected browser or an empty string + :rtype: string -Returns a string containing the name of the mobile device viewing your -site. + Returns a string containing the name of the web browser viewing your site. -$this->agent->robot() -===================== + .. method:: version() -Returns a string containing the name of the robot viewing your site. + :returns: Detected browser version or an empty string + :rtype: string -$this->agent->platform() -======================== + Returns a string containing the version number of the web browser viewing your site. -Returns a string containing the platform viewing your site (Linux, -Windows, OS X, etc.). + .. method:: mobile() -$this->agent->referrer() -======================== + :returns: Detected mobile device brand or an empty string + :rtype: string -The referrer, if the user agent was referred from another site. -Typically you'll test for this as follows:: + Returns a string containing the name of the mobile device viewing your site. - if ($this->agent->is_referral()) - { - echo $this->agent->referrer(); - } + .. method:: robot() -$this->agent->agent_string() -============================= + :returns: Detected robot name or an empty string + :rtype: string -Returns a string containing the full user agent string. Typically it -will be something like this:: + Returns a string containing the name of the robot viewing your site. - Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.0.4) Gecko/20060613 Camino/1.0.2 + .. method:: platform() -$this->agent->accept_lang() -============================ + :returns: Detected operating system or an empty string + :rtype: string -Lets you determine if the user agent accepts a particular language. -Example:: + Returns a string containing the platform viewing your site (Linux, Windows, OS X, etc.). - if ($this->agent->accept_lang('en')) - { - echo 'You accept English!'; - } + .. method:: referrer() -.. note:: This function is not typically very reliable since some - browsers do not provide language info, and even among those that do, it - is not always accurate. + :returns: Detected referrer or an empty string + :rtype: string -$this->agent->accept_charset() -=============================== + The referrer, if the user agent was referred from another site. Typically you'll test for this as follows:: -Lets you determine if the user agent accepts a particular character set. -Example:: + if ($this->agent->is_referral()) + { + echo $this->agent->referrer(); + } - if ($this->agent->accept_charset('utf-8')) - { - echo 'You browser supports UTF-8!'; - } + .. method:: agent_string() + + :returns: Full user agent string or an empty string + :rtype: string + + Returns a string containing the full user agent string. Typically it will be something like this:: + + Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.0.4) Gecko/20060613 Camino/1.0.2 + + .. method:: accept_lang([$lang = 'en']) + + :param string $lang: Language key + :returns: TRUE if provided language is accepted, FALSE if not + :rtype: bool + + Lets you determine if the user agent accepts a particular language. Example:: + + if ($this->agent->accept_lang('en')) + { + echo 'You accept English!'; + } + + .. note:: This method is not typically very reliable since some browsers do not provide language info, + and even among those that do, it is not always accurate. + + .. method:: languages() + + :returns: An array list of accepted languages + :rtype: array + + Returns an array of languages supported by the user agent. + + .. method:: accept_charset([$charset = 'utf-8']) + + :param string $charset: Character set + :returns: TRUE if the character set is accepted, FALSE if not + :rtype: bool + + Lets you determine if the user agent accepts a particular character set. Example:: + + if ($this->agent->accept_charset('utf-8')) + { + echo 'You browser supports UTF-8!'; + } + + .. note:: This method is not typically very reliable since some browsers do not provide character-set info, + and even among those that do, it is not always accurate. + + .. method:: charsets() + + :returns: An array list of accepted character sets + :rtype: array + + Returns an array of character sets accepted by the user agent. + + .. method:: parse($string) + + :param string $string: A custom user-agent string + :rtype: void -.. note:: This function is not typically very reliable since some - browsers do not provide character-set info, and even among those that - do, it is not always accurate. + Parses a custom user-agent string, different from the one reported by the current visitor.
\ No newline at end of file diff --git a/user_guide_src/source/libraries/xmlrpc.rst b/user_guide_src/source/libraries/xmlrpc.rst index d2d695ee3..c2e9a1113 100644 --- a/user_guide_src/source/libraries/xmlrpc.rst +++ b/user_guide_src/source/libraries/xmlrpc.rst @@ -5,6 +5,13 @@ XML-RPC and XML-RPC Server Classes CodeIgniter's XML-RPC classes permit you to send requests to another server, or set up your own XML-RPC server to receive requests. +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + **************** What is XML-RPC? **************** @@ -24,8 +31,11 @@ it to determine which class/method should be called to process the request. Once processed, the server will then send back a response message. -For detailed specifications, you can visit the -`XML-RPC <http://www.xmlrpc.com/>`_ site. +For detailed specifications, you can visit the `XML-RPC <http://www.xmlrpc.com/>`_ site. + +*********************** +Using the XML-RPC Class +*********************** Initializing the Class ====================== @@ -113,16 +123,17 @@ If you use data types other than strings, or if you have several different data types, you will place each parameter into its own array, with the data type in the second position:: - $request = array ( - array('John', 'string'), - array('Doe', 'string'), - array(FALSE, 'boolean'), - array(12345, 'int') - ); + $request = array( + array('John', 'string'), + array('Doe', 'string'), + array(FALSE, 'boolean'), + array(12345, 'int') + ); $this->xmlrpc->request($request); The `Data Types <#datatypes>`_ section below has a full list of data types. + Creating an XML-RPC Server ========================== @@ -160,7 +171,7 @@ not part of the CodeIgniter super object. In other words, if an XML-RPC Client sends a request for the new_post method, your server will load the My_blog class and call the new_entry function. If the request is for the update_post method, your server -will load the My_blog class and call the update_entry function. +will load the My_blog class and call the ``update_entry()`` method. The function names in the above example are arbitrary. You'll decide what they should be called on your server, or if you are using @@ -170,7 +181,7 @@ function names. There are two additional configuration keys you may make use of when initializing the server class: debug can be set to TRUE in order to enable debugging, and xss_clean may be set to FALSE to prevent sending -data through the Security library's xss_clean function. +data through the Security library's ``xss_clean()`` method. Processing Server Requests ========================== @@ -196,49 +207,52 @@ have access to the *request parameters* enabling you to process the request. When you are done you will send a Response back to the Client. Below is a real-world example, using the Blogger API. One of the methods -in the Blogger API is getUserInfo(). Using this method, an XML-RPC +in the Blogger API is ``getUserInfo()``. Using this method, an XML-RPC Client can send the Server a username and password, in return the Server sends back information about that particular user (nickname, user ID, email address, etc.). Here is how the processing function might look:: class My_blog extends CI_Controller { - function getUserInfo($request) - { - $username = 'smitty'; - $password = 'secretsmittypass'; + public function getUserInfo($request) + { + $username = 'smitty'; + $password = 'secretsmittypass'; - $this->load->library('xmlrpc'); + $this->load->library('xmlrpc'); - $parameters = $request->output_parameters(); + $parameters = $request->output_parameters(); - if ($parameters['1'] != $username AND $parameters['2'] != $password) - { - return $this->xmlrpc->send_error_message('100', 'Invalid Access'); - } + if ($parameters[1] != $username && $parameters[2] != $password) + { + return $this->xmlrpc->send_error_message('100', 'Invalid Access'); + } - $response = array(array('nickname' => array('Smitty','string'), - 'userid' => array('99','string'), - 'url' => array('http://yoursite.com','string'), - 'email' => array('jsmith@yoursite.com','string'), - 'lastname' => array('Smith','string'), - 'firstname' => array('John','string') - ), - 'struct'); + $response = array( + array( + 'nickname' => array('Smitty', 'string'), + 'userid' => array('99', 'string'), + 'url' => array('http://yoursite.com', 'string'), + 'email' => array('jsmith@yoursite.com', 'string'), + 'lastname' => array('Smith', 'string'), + 'firstname' => array('John', 'string') + ), + 'struct' + ); - return $this->xmlrpc->send_response($response); - } + return $this->xmlrpc->send_response($response); + } } Notes: ------ -The output_parameters() function retrieves an indexed array +The ``output_parameters()`` method retrieves an indexed array corresponding to the request parameters sent by the client. In the above example, the output parameters will be the username and password. If the username and password sent by the client were not valid, and -error message is returned using send_error_message(). +error message is returned using ``send_error_message()``. If the operation was successful, the client will be sent back a response array containing the user's info. @@ -252,22 +266,22 @@ single item**. This item can be an array with several additional arrays, but there can be only one primary array index. In other words, the basic prototype is this:: - $response = array('Response data', 'array'); + $response = array('Response data', 'array'); Responses, however, usually contain multiple pieces of information. In order to accomplish this we must put the response into its own array so that the primary array continues to contain a single piece of data. Here's an example showing how this might be accomplished:: - $response = array ( - array( - 'first_name' => array('John', 'string'), - 'last_name' => array('Doe', 'string'), - 'member_id' => array(123435, 'int'), - 'todo_list' => array(array('clean house', 'call mom', 'water plants'), 'array'), - ), - 'struct' - ); + $response = array( + array( + 'first_name' => array('John', 'string'), + 'last_name' => array('Doe', 'string'), + 'member_id' => array(123435, 'int'), + 'todo_list' => array(array('clean house', 'call mom', 'water plants'), 'array'), + ), + 'struct' + ); Notice that the above array is formatted as a struct. This is the most common data type for responses. @@ -362,17 +376,16 @@ folder:: $parameters = $request->output_parameters(); $response = array( - array( - 'you_said' => $parameters[0], - 'i_respond' => 'Not bad at all.' - ), - 'struct' - ); + array( + 'you_said' => $parameters[0], + 'i_respond' => 'Not bad at all.' + ), + 'struct' + ); return $this->xmlrpc->send_response($response); } } - ?> Try it! @@ -387,7 +400,7 @@ back to you. The client you created sends a message ("How's is going?") to the server, along with a request for the "Greetings" method. The Server -receives the request and maps it to the "process" function, where a +receives the request and maps it to the ``process()`` method, where a response is sent back. Using Associative Arrays In a Request Parameter @@ -397,22 +410,21 @@ If you wish to use an associative array in your method parameters you will need to use a struct datatype:: $request = array( - array( - // Param 0 - array( - 'name'=>'John' - ), - 'struct' - ), - array( - // Param 1 - array( - 'size'=>'large', - 'shape'=>'round' - ), - 'struct' - ) - ); + array( + // Param 0 + array('name' => 'John'), + 'struct' + ), + array( + // Param 1 + array( + 'size' => 'large', + 'shape'=>'round' + ), + 'struct' + ) + ); + $this->xmlrpc->request($request); You can retrieve the associative array when processing the request in @@ -425,114 +437,142 @@ the Server. $size = $parameters[1]['size']; $shape = $parameters[1]['shape']; -************************** -XML-RPC Function Reference -************************** +Data Types +========== -$this->xmlrpc->server() -======================= +According to the `XML-RPC spec <http://www.xmlrpc.com/spec>`_ there are +seven types of values that you can send via XML-RPC: -Sets the URL and port number of the server to which a request is to be -sent:: +- *int* or *i4* +- *boolean* +- *string* +- *double* +- *dateTime.iso8601* +- *base64* +- *struct* (contains array of values) +- *array* (contains array of values) - $this->xmlrpc->server('http://www.sometimes.com/pings.php', 80); +*************** +Class Reference +*************** -$this->xmlrpc->timeout() -======================== +.. class:: CI_Xmlrpc -Set a time out period (in seconds) after which the request will be -canceled:: + .. method:: initialize([$config = array()]) - $this->xmlrpc->timeout(6); + :param array $config: Configuration data + :rtype: void -$this->xmlrpc->method() -======================= + Initializes the XML-RPC library. Accepts an associative array containing your settings. -Sets the method that will be requested from the XML-RPC server:: + .. method:: server($url[, $port = 80[, $proxy = FALSE[, $proxy_port = 8080]]]) - $this->xmlrpc->method('method'); + :param string $url: XML-RPC server URL + :param int $port: Server port + :param string $proxy: Optional proxy + :param int $proxy_port: Proxy listening port + :rtype: void -Where method is the name of the method. + Sets the URL and port number of the server to which a request is to be sent:: -$this->xmlrpc->request() -======================== + $this->xmlrpc->server('http://www.sometimes.com/pings.php', 80); -Takes an array of data and builds request to be sent to XML-RPC server:: + Basic HTTP authentication is also supported, simply add it to the server URL:: - $request = array(array('My Photoblog', 'string'), 'http://www.yoursite.com/photoblog/'); - $this->xmlrpc->request($request); + $this->xmlrpc->server('http://user:pass@localhost/', 80); -$this->xmlrpc->send_request() -============================== + .. method:: timeout($seconds = 5) -The request sending function. Returns boolean TRUE or FALSE based on -success for failure, enabling it to be used conditionally. + :param int $seconds: Timeout in seconds + :rtype: void -$this->xmlrpc->set_debug(TRUE); -================================ + Set a time out period (in seconds) after which the request will be canceled:: -Enables debugging, which will display a variety of information and error -data helpful during development. + $this->xmlrpc->timeout(6); -$this->xmlrpc->display_error() -=============================== + .. method:: method($function) -Returns an error message as a string if your request failed for some -reason. + :param string $function: Method name + :rtype: void -:: + Sets the method that will be requested from the XML-RPC server:: - echo $this->xmlrpc->display_error(); + $this->xmlrpc->method('method'); -$this->xmlrpc->display_response() -================================== + Where method is the name of the method. -Returns the response from the remote server once request is received. -The response will typically be an associative array. + .. method:: request($incoming) -:: + :param array $incoming: Request data + :rtype: void - $this->xmlrpc->display_response(); + Takes an array of data and builds request to be sent to XML-RPC server:: -$this->xmlrpc->send_error_message() -===================================== + $request = array(array('My Photoblog', 'string'), 'http://www.yoursite.com/photoblog/'); + $this->xmlrpc->request($request); -This function lets you send an error message from your server to the -client. First parameter is the error number while the second parameter -is the error message. + .. method:: send_request() -:: + :returns: TRUE on success, FALSE on failure + :rtype: bool - return $this->xmlrpc->send_error_message('123', 'Requested data not available'); + The request sending method. Returns boolean TRUE or FALSE based on success for failure, enabling it to be used conditionally. -$this->xmlrpc->send_response() -=============================== + .. method set_debug($flag = TRUE) -Lets you send the response from your server to the client. An array of -valid data values must be sent with this method. + :param bool $flag: Debug status flag + :rtype: void -:: + Enables or disables debugging, which will display a variety of information and error data helpful during development. - $response = array( - array( - 'flerror' => array(FALSE, 'boolean'), - 'message' => "Thanks for the ping!" - ) - 'struct'); - return $this->xmlrpc->send_response($response); + .. method:: display_error() -Data Types -========== + :returns: Error message string + :rtype: string -According to the `XML-RPC spec <http://www.xmlrpc.com/spec>`_ there are -seven types of values that you can send via XML-RPC: + Returns an error message as a string if your request failed for some reason. + :: -- *int* or *i4* -- *boolean* -- *string* -- *double* -- *dateTime.iso8601* -- *base64* -- *struct* (contains array of values) -- *array* (contains array of values) + echo $this->xmlrpc->display_error(); + + .. method:: display_response() + + :returns: Response + :rtype: mixed + + Returns the response from the remote server once request is received. The response will typically be an associative array. + :: + + $this->xmlrpc->display_response(); + + .. method:: send_error_message($number, $message) + :param int $number: Error number + :param string $message: Error message + :returns: XML_RPC_Response instance + :rtype: XML_RPC_Response + + This method lets you send an error message from your server to the client. + First parameter is the error number while the second parameter is the error message. + :: + + return $this->xmlrpc->send_error_message(123, 'Requested data not available'); + + .. method send_response($response) + + :param array $response: Response data + :returns: XML_RPC_Response instance + :rtype: XML_RPC_Response + + Lets you send the response from your server to the client. An array of valid data values must be sent with this method. + :: + + $response = array( + array( + 'flerror' => array(FALSE, 'boolean'), + 'message' => "Thanks for the ping!" + ), + 'struct' + ); + + return $this->xmlrpc->send_response($response);
\ No newline at end of file diff --git a/user_guide_src/source/libraries/zip.rst b/user_guide_src/source/libraries/zip.rst index c27718273..5ff7d07d6 100644 --- a/user_guide_src/source/libraries/zip.rst +++ b/user_guide_src/source/libraries/zip.rst @@ -6,6 +6,17 @@ CodeIgniter's Zip Encoding Class classes permit you to create Zip archives. Archives can be downloaded to your desktop or saved to a directory. +.. contents:: + :local: + +.. raw:: html + + <div class="custom-index container"></div> + +**************************** +Using the Zip Encoding Class +**************************** + Initializing the Class ====================== @@ -35,174 +46,180 @@ your server, and download it to your desktop. // Download the file to your desktop. Name it "my_backup.zip" $this->zip->download('my_backup.zip'); -****************** -Function Reference -****************** +*************** +Class Reference +*************** -$this->zip->add_data() -======================= +.. class:: CI_Zip -Permits you to add data to the Zip archive. The first parameter must -contain the name you would like given to the file, the second parameter -must contain the file data as a string:: + .. method:: add_data($filepath[, $data = NULL]) - $name = 'my_bio.txt'; - $data = 'I was born in an elevator...'; + :param mixed $filepath: A single file path or an array of file => data pairs + :param array $data: File contents (ignored if $filepath is an array) + :rtype: void - $this->zip->add_data($name, $data); + Adds data to the Zip archive. Can work both in single and multiple files mode. -You are allowed multiple calls to this function in order to add several -files to your archive. Example:: + When adding a single file, the first parameter must contain the name you would like given to the file and the second must contain the file contents:: - $name = 'mydata1.txt'; - $data = 'A Data String!'; - $this->zip->add_data($name, $data); + $name = 'mydata1.txt'; + $data = 'A Data String!'; + $this->zip->add_data($name, $data); - $name = 'mydata2.txt'; - $data = 'Another Data String!'; - $this->zip->add_data($name, $data); + $name = 'mydata2.txt'; + $data = 'Another Data String!'; + $this->zip->add_data($name, $data); + + When adding multiple files, the first parameter must contain *file => contents* pairs and the second parameter is ignored:: -Or you can pass multiple files using an array:: + $data = array( + 'mydata1.txt' => 'A Data String!', + 'mydata2.txt' => 'Another Data String!' + ); - $data = array( - 'mydata1.txt' => 'A Data String!', - 'mydata2.txt' => 'Another Data String!' - ); + $this->zip->add_data($data); - $this->zip->add_data($data); + If you would like your compressed data organized into sub-directories, simply include the path as part of the filename(s):: - $this->zip->download('my_backup.zip'); + $name = 'personal/my_bio.txt'; + $data = 'I was born in an elevator...'; -If you would like your compressed data organized into sub-folders, -include the path as part of the filename:: + $this->zip->add_data($name, $data); - $name = 'personal/my_bio.txt'; - $data = 'I was born in an elevator...'; + The above example will place my_bio.txt inside a folder called personal. - $this->zip->add_data($name, $data); + .. method:: add_dir($directory) -The above example will place my_bio.txt inside a folder called -personal. + :param mixed $directory: Directory name string or an array of multiple directories + :rtype: void -$this->zip->add_dir() -====================== + Permits you to add a directory. Usually this method is unnecessary since you can place your data into directories when using + ``$this->zip->add_data()``, but if you would like to create an empty directory you can do so:: -Permits you to add a directory. Usually this function is unnecessary -since you can place your data into folders when using -$this->zip->add_data(), but if you would like to create an empty folder -you can do so. Example:: + $this->zip->add_dir('myfolder'); // Creates a directory called "myfolder" - $this->zip->add_dir('myfolder'); // Creates a folder called "myfolder" + .. method:: read_file($path[, $archive_filepath = FALSE]) -$this->zip->read_file() -======================== + :param string $path: Path to file + :param mixed $archive_filepath: New file name/path (string) or (boolean) whether to maintain the original filepath + :returns: TRUE on success, FALSE on failure + :rtype: bool -Permits you to compress a file that already exists somewhere on your -server. Supply a file path and the zip class will read it and add it to -the archive:: + Permits you to compress a file that already exists somewhere on your server. + Supply a file path and the zip class will read it and add it to the archive:: - $path = '/path/to/photo.jpg'; + $path = '/path/to/photo.jpg'; - $this->zip->read_file($path); + $this->zip->read_file($path); - // Download the file to your desktop. Name it "my_backup.zip" - $this->zip->download('my_backup.zip'); + // Download the file to your desktop. Name it "my_backup.zip" + $this->zip->download('my_backup.zip'); -If you would like the Zip archive to maintain the directory structure of -the file in it, pass TRUE (boolean) in the second parameter. Example:: + If you would like the Zip archive to maintain the directory structure of + the file in it, pass TRUE (boolean) in the second parameter. Example:: - $path = '/path/to/photo.jpg'; + $path = '/path/to/photo.jpg'; - $this->zip->read_file($path, TRUE); + $this->zip->read_file($path, TRUE); - // Download the file to your desktop. Name it "my_backup.zip" - $this->zip->download('my_backup.zip'); + // Download the file to your desktop. Name it "my_backup.zip" + $this->zip->download('my_backup.zip'); -In the above example, photo.jpg will be placed inside two folders: -path/to/ + In the above example, photo.jpg will be placed into the *path/to/* directory. -$this->zip->read_dir() -======================= + You can also specify a new name (path included) for the added file on the fly:: -Permits you to compress a folder (and its contents) that already exists -somewhere on your server. Supply a file path to the directory and the -zip class will recursively read it and recreate it as a Zip archive. All -files contained within the supplied path will be encoded, as will any -sub-folders contained within it. Example:: + $path = '/path/to/photo.jpg'; + $new_path = '/new/path/some_photo.jpg'; - $path = '/path/to/your/directory/'; + $this->zip->read_file($path, $new_path); - $this->zip->read_dir($path); + // Download ZIP archive containing /new/path/some_photo.jpg + $this->zip->download('my_archive.zip'); - // Download the file to your desktop. Name it "my_backup.zip" - $this->zip->download('my_backup.zip'); + .. method:: read_dir($path[, $preserve_filepath = TRUE[, $root_path = NULL]]) -By default the Zip archive will place all directories listed in the -first parameter inside the zip. If you want the tree preceding the -target folder to be ignored you can pass FALSE (boolean) in the second -parameter. Example:: + :param string $path: Path to directory + :param bool $preserve_filepath: Whether to maintain the original path + :param string $root_path: Part of the path to exclude from the archive directory + :returns: TRUE on success, FALSE on failure + :rtype: bool - $path = '/path/to/your/directory/'; + Permits you to compress a directory (and its contents) that already exists somewhere on your server. + Supply a path to the directory and the zip class will recursively read and recreate it as a Zip archive. + All files contained within the supplied path will be encoded, as will any sub-directories contained within it. Example:: - $this->zip->read_dir($path, FALSE); + $path = '/path/to/your/directory/'; -This will create a ZIP with the folder "directory" inside, then all -sub-folders stored correctly inside that, but will not include the -folders /path/to/your. + $this->zip->read_dir($path); -$this->zip->archive() -===================== + // Download the file to your desktop. Name it "my_backup.zip" + $this->zip->download('my_backup.zip'); -Writes the Zip-encoded file to a directory on your server. Submit a -valid server path ending in the file name. Make sure the directory is -writable (666 or 777 is usually OK). Example:: + By default the Zip archive will place all directories listed in the first parameter inside the zip. + If you want the tree preceding the target directory to be ignored you can pass FALSE (boolean) in the second parameter. Example:: - $this->zip->archive('/path/to/folder/myarchive.zip'); // Creates a file named myarchive.zip + $path = '/path/to/your/directory/'; -$this->zip->download() -====================== + $this->zip->read_dir($path, FALSE); -Causes the Zip file to be downloaded from your server. The function must -be passed the name you would like the zip file called. Example:: + This will create a ZIP with a directory named "directory" inside, then all sub-directories stored correctly inside that, but will not include the + */path/to/your* part of the path. - $this->zip->download('latest_stuff.zip'); // File will be named "latest_stuff.zip" + .. method:: archive($filepath) -.. note:: Do not display any data in the controller in which you call - this function since it sends various server headers that cause the - download to happen and the file to be treated as binary. + :param string $filepath: Path to target zip archive + :returns: TRUE on success, FALSE on failure + :rtype: bool -$this->zip->get_zip() -====================== + Writes the Zip-encoded file to a directory on your server. Submit a valid server path ending in the file name. + Make sure the directory is writable (660 or 666 is usually OK). Example:: -Returns the Zip-compressed file data. Generally you will not need this -function unless you want to do something unique with the data. Example:: + $this->zip->archive('/path/to/folder/myarchive.zip'); // Creates a file named myarchive.zip - $name = 'my_bio.txt'; - $data = 'I was born in an elevator...'; + .. method:: download($filename = 'backup.zip') - $this->zip->add_data($name, $data); + :param string $filename: Archive file name + :rtype: void - $zip_file = $this->zip->get_zip(); + Causes the Zip file to be downloaded from your server. You must pass the name you would like the zip file called. Example:: -$this->zip->clear_data() -========================= + $this->zip->download('latest_stuff.zip'); // File will be named "latest_stuff.zip" -The Zip class caches your zip data so that it doesn't need to recompile -the Zip archive for each function you use above. If, however, you need -to create multiple Zips, each with different data, you can clear the -cache between calls. Example:: + .. note:: Do not display any data in the controller in which you call + this method since it sends various server headers that cause the + download to happen and the file to be treated as binary. - $name = 'my_bio.txt'; - $data = 'I was born in an elevator...'; + .. method:: get_zip() - $this->zip->add_data($name, $data); - $zip_file = $this->zip->get_zip(); + :returns: Zip file content + :rtype: string + + Returns the Zip-compressed file data. Generally you will not need this method unless you want to do something unique with the data. Example:: + + $name = 'my_bio.txt'; + $data = 'I was born in an elevator...'; + + $this->zip->add_data($name, $data); + + $zip_file = $this->zip->get_zip(); + + .. method:: clear_data() + + :rtype: void + + The Zip class caches your zip data so that it doesn't need to recompile the Zip archive for each method you use above. + If, however, you need to create multiple Zip archives, each with different data, you can clear the cache between calls. Example:: - $this->zip->clear_data(); + $name = 'my_bio.txt'; + $data = 'I was born in an elevator...'; - $name = 'photo.jpg'; - $this->zip->read_file("/path/to/photo.jpg"); // Read the file's contents + $this->zip->add_data($name, $data); + $zip_file = $this->zip->get_zip(); + $this->zip->clear_data(); - $this->zip->download('myphotos.zip'); + $name = 'photo.jpg'; + $this->zip->read_file("/path/to/photo.jpg"); // Read the file's contents + $this->zip->download('myphotos.zip');
\ No newline at end of file diff --git a/user_guide_src/source/overview/at_a_glance.rst b/user_guide_src/source/overview/at_a_glance.rst index 6dcfdbb14..da323b907 100644 --- a/user_guide_src/source/overview/at_a_glance.rst +++ b/user_guide_src/source/overview/at_a_glance.rst @@ -111,4 +111,4 @@ CodeIgniter has a Friendly Community of Users ============================================= Our growing community of users can be seen actively participating in our -`Community Forums <http://codeigniter.com/forums/>`_. +`Community Forums <http://ellislab.com/forums/>`_. diff --git a/user_guide_src/source/overview/getting_started.rst b/user_guide_src/source/overview/getting_started.rst index 5157d4860..feaad5908 100644 --- a/user_guide_src/source/overview/getting_started.rst +++ b/user_guide_src/source/overview/getting_started.rst @@ -19,6 +19,6 @@ Reference** and **Helper Reference** pages to learn to utilize the native libraries and helper files. Feel free to take advantage of our `Community -Forums <http://codeigniter.com/forums/>`_ if you have questions or -problems, and our `Wiki <http://codeigniter.com/wiki/>`_ to see code +Forums <http://ellislab.com/forums/>`_ if you have questions or +problems, and our `Wiki <https://github.com/EllisLab/CodeIgniter/wiki>`_ to see code examples posted by other users. diff --git a/user_guide_src/source/tutorial/conclusion.rst b/user_guide_src/source/tutorial/conclusion.rst index 48fbdcc8a..a5f69b4e7 100644 --- a/user_guide_src/source/tutorial/conclusion.rst +++ b/user_guide_src/source/tutorial/conclusion.rst @@ -20,7 +20,7 @@ CodeIgniter within a few days. If you still have questions about the framework or your own CodeIgniter code, you can: -- Check out our `forums <http://codeigniter.com/forums>`_ -- Visit our `IRC chatroom <http://codeigniter.com/wiki/IRC>`_ -- Explore the `Wiki <http://codeigniter.com/wiki/>`_ +- Check out our `forums <http://ellislab.com/forums>`_ +- Visit our `IRC chatroom <https://github.com/EllisLab/CodeIgniter/wiki/IRC>`_ +- Explore the `Wiki <https://github.com/EllisLab/CodeIgniter/wiki/>`_ diff --git a/user_guide_src/source/tutorial/static_pages.rst b/user_guide_src/source/tutorial/static_pages.rst index 330a50ecf..36bcd2df9 100644 --- a/user_guide_src/source/tutorial/static_pages.rst +++ b/user_guide_src/source/tutorial/static_pages.rst @@ -72,7 +72,7 @@ includes the following code: :: - <em>© 2013</em> + <em>© 2014</em> </body> <html> |