From 6be28745c75c3542058fc7833c773e3b44ad3b92 Mon Sep 17 00:00:00 2001 From: Evan Sharp Date: Sat, 15 May 2021 11:38:09 -0700 Subject: [PATCH 0001/1246] Add information for apache mod_userdir Resolution of issue #4471 --- .../source/installation/running.rst | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/user_guide_src/source/installation/running.rst b/user_guide_src/source/installation/running.rst index 4d00260ffcea..deb9bea50693 100644 --- a/user_guide_src/source/installation/running.rst +++ b/user_guide_src/source/installation/running.rst @@ -129,6 +129,72 @@ e.g., ``apache2/conf/extra/httpd-vhost.conf``:: If your project folder is not a subfolder of the Apache document root, then your element may need a nested element to grant the web server access to the files. +With mod_userdir (shared hosts) +-------------------------------- + +A common practice in shared hosting environments is to use the Apache module "mod_userdir" to enable per-user Virtual Hosts automatically. Additional configuration is required to allow CodeIgniter4 to be run from these per-user directories. + +The following assumes that the server is already configured for mod_userdir. A guide to enabling this module is available `in the Apache documentation `_. + +Because CodeIgniter4 requires the server to find the framework front controller at ``/public/index.php``, you must specify this location as an alternative to search for the request, even if CodeIgniter4 is installed within the per-user web directory. + +The default user web directory ``~/public_html`` is specified by the default ``UserDir`` directive, typically in ``/apache2/mods-available/userdir.conf`` or ``/apache2/conf/extra/httpd-userdir.conf``:: + + UserDir public_html + +So you will need to configure Apache to look for CodeIgniter's public directory first before trying to serve the default:: + + UserDir "public_html/public" "public_html" + +Be sure to specify options and permissions for the CodeIgniter public directory as well. A ``userdir.conf`` might look like:: + + + UserDir "public_html/public" "public_html" + UserDir disabled root + + + AllowOverride All + Options MultiViews Indexes FollowSymLinks + + # Apache <= 2.2: + #Order allow,deny + # Allow from all + + # Apache >= 2.4: + Require all granted + + + # Apache <= 2.2: + #Order deny,allow + # Deny from all + + # Apache >= 2.4: + Require all denied + + + + + AllowOverride All + Options MultiViews Indexes FollowSymLinks + + # Apache <= 2.2: + #Order allow,deny + #Allow from all + + # Apache >= 2.4: + Require all granted + + + # Apache <= 2.2: + #Order deny,allow + #Deny from all + + # Apache >= 2.4: + Require all denied + + + + Testing ------- From 4206bcc41ec182d181d6c6ecd7cc9f73069455d8 Mon Sep 17 00:00:00 2001 From: Evan Sharp Date: Mon, 17 May 2021 06:52:34 -0700 Subject: [PATCH 0002/1246] Update user_guide_src/source/installation/running.rst Co-authored-by: MGatner --- user_guide_src/source/installation/running.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/installation/running.rst b/user_guide_src/source/installation/running.rst index deb9bea50693..9b5ed53b2c14 100644 --- a/user_guide_src/source/installation/running.rst +++ b/user_guide_src/source/installation/running.rst @@ -136,7 +136,7 @@ A common practice in shared hosting environments is to use the Apache module "mo The following assumes that the server is already configured for mod_userdir. A guide to enabling this module is available `in the Apache documentation `_. -Because CodeIgniter4 requires the server to find the framework front controller at ``/public/index.php``, you must specify this location as an alternative to search for the request, even if CodeIgniter4 is installed within the per-user web directory. +Because CodeIgniter4 expects the server to find the framework front controller at ``/public/index.php`` by default, you must specify this location as an alternative to search for the request (even if CodeIgniter4 is installed within the per-user web directory). The default user web directory ``~/public_html`` is specified by the default ``UserDir`` directive, typically in ``/apache2/mods-available/userdir.conf`` or ``/apache2/conf/extra/httpd-userdir.conf``:: From 032e8fdc7373dc5f4f05f79ee6c183eb4cbeda2a Mon Sep 17 00:00:00 2001 From: Evan Sharp Date: Mon, 17 May 2021 06:52:41 -0700 Subject: [PATCH 0003/1246] Update user_guide_src/source/installation/running.rst Co-authored-by: MGatner --- user_guide_src/source/installation/running.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/installation/running.rst b/user_guide_src/source/installation/running.rst index 9b5ed53b2c14..3c0abeeae114 100644 --- a/user_guide_src/source/installation/running.rst +++ b/user_guide_src/source/installation/running.rst @@ -138,7 +138,7 @@ The following assumes that the server is already configured for mod_userdir. A g Because CodeIgniter4 expects the server to find the framework front controller at ``/public/index.php`` by default, you must specify this location as an alternative to search for the request (even if CodeIgniter4 is installed within the per-user web directory). -The default user web directory ``~/public_html`` is specified by the default ``UserDir`` directive, typically in ``/apache2/mods-available/userdir.conf`` or ``/apache2/conf/extra/httpd-userdir.conf``:: +The default user web directory ``~/public_html`` is specified by the ``UserDir`` directive, typically in ``/apache2/mods-available/userdir.conf`` or ``/apache2/conf/extra/httpd-userdir.conf``:: UserDir public_html From ff77f3b7e909519e23170095be64a164deb76b59 Mon Sep 17 00:00:00 2001 From: Evan Sharp Date: Mon, 17 May 2021 06:52:46 -0700 Subject: [PATCH 0004/1246] Update user_guide_src/source/installation/running.rst Co-authored-by: MGatner --- user_guide_src/source/installation/running.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/installation/running.rst b/user_guide_src/source/installation/running.rst index 3c0abeeae114..0e7e666ec963 100644 --- a/user_guide_src/source/installation/running.rst +++ b/user_guide_src/source/installation/running.rst @@ -165,7 +165,7 @@ Be sure to specify options and permissions for the CodeIgniter public directory # Apache <= 2.2: - #Order deny,allow + # Order deny,allow # Deny from all # Apache >= 2.4: From fbb4cb735753716136de030dd7efb6fdca5ff37e Mon Sep 17 00:00:00 2001 From: Evan Sharp Date: Mon, 17 May 2021 06:52:58 -0700 Subject: [PATCH 0005/1246] Update user_guide_src/source/installation/running.rst Co-authored-by: MGatner --- user_guide_src/source/installation/running.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/user_guide_src/source/installation/running.rst b/user_guide_src/source/installation/running.rst index 0e7e666ec963..c1b5017748f6 100644 --- a/user_guide_src/source/installation/running.rst +++ b/user_guide_src/source/installation/running.rst @@ -186,8 +186,8 @@ Be sure to specify options and permissions for the CodeIgniter public directory # Apache <= 2.2: - #Order deny,allow - #Deny from all + # Order deny,allow + # Deny from all # Apache >= 2.4: Require all denied From 2b3798cf0f016446a0e103f009c22777ce3ff656 Mon Sep 17 00:00:00 2001 From: Evan Sharp Date: Mon, 17 May 2021 06:53:02 -0700 Subject: [PATCH 0006/1246] Update user_guide_src/source/installation/running.rst Co-authored-by: MGatner --- user_guide_src/source/installation/running.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/user_guide_src/source/installation/running.rst b/user_guide_src/source/installation/running.rst index c1b5017748f6..a7b1bb034a41 100644 --- a/user_guide_src/source/installation/running.rst +++ b/user_guide_src/source/installation/running.rst @@ -178,8 +178,8 @@ Be sure to specify options and permissions for the CodeIgniter public directory Options MultiViews Indexes FollowSymLinks # Apache <= 2.2: - #Order allow,deny - #Allow from all + # Order allow,deny + # Allow from all # Apache >= 2.4: Require all granted From 5fa4159d90afd3fe2d9e51128633d1eaaf52f6ee Mon Sep 17 00:00:00 2001 From: Evan Sharp Date: Mon, 17 May 2021 06:53:10 -0700 Subject: [PATCH 0007/1246] Update user_guide_src/source/installation/running.rst Co-authored-by: MGatner --- user_guide_src/source/installation/running.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/installation/running.rst b/user_guide_src/source/installation/running.rst index a7b1bb034a41..45e92387dee1 100644 --- a/user_guide_src/source/installation/running.rst +++ b/user_guide_src/source/installation/running.rst @@ -157,7 +157,7 @@ Be sure to specify options and permissions for the CodeIgniter public directory Options MultiViews Indexes FollowSymLinks # Apache <= 2.2: - #Order allow,deny + # Order allow,deny # Allow from all # Apache >= 2.4: From 979b2f16d148784091657a39e710ac311afddb6f Mon Sep 17 00:00:00 2001 From: "John Paul E. Balandan, CPA" Date: Tue, 4 Jan 2022 02:18:37 +0800 Subject: [PATCH 0008/1246] Update modified Kint files in `ThirdParty` --- .../ThirdParty/Kint/Renderer/CliRenderer.php | 29 +++++++++++++++++-- .../ThirdParty/Kint/Renderer/RichRenderer.php | 15 ++++++++-- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/system/ThirdParty/Kint/Renderer/CliRenderer.php b/system/ThirdParty/Kint/Renderer/CliRenderer.php index f86671ff1cf3..12b18d036b62 100644 --- a/system/ThirdParty/Kint/Renderer/CliRenderer.php +++ b/system/ThirdParty/Kint/Renderer/CliRenderer.php @@ -59,6 +59,15 @@ class CliRenderer extends TextRenderer */ public static $min_terminal_width = 40; + /** + * Which stream to check for VT100 support on windows. + * + * null uses STDOUT if it's defined + * + * @var null|resource + */ + public static $windows_stream = null; + protected static $terminal_width = null; protected $windows_output = false; @@ -69,8 +78,22 @@ public function __construct() { parent::__construct(); - if (!self::$force_utf8) { - $this->windows_output = KINT_WIN; + if (!self::$force_utf8 && KINT_WIN) { + if (!KINT_PHP72) { + $this->windows_output = true; + } else { + $stream = self::$windows_stream; + + if (!$stream && \defined('STDOUT')) { + $stream = STDOUT; + } + + if (!$stream) { + $this->windows_output = true; + } else { + $this->windows_output = !\sapi_windows_vt100_support($stream); + } + } } if (!self::$terminal_width) { @@ -153,7 +176,7 @@ protected function utf8ToWindows($string) { return \str_replace( ['┌', '═', '┐', '│', '└', '─', '┘'], - ["\xda", "\xdc", "\xbf", "\xb3", "\xc0", "\xc4", "\xd9"], + [' ', '=', ' ', '|', ' ', '-', ' '], $string ); } diff --git a/system/ThirdParty/Kint/Renderer/RichRenderer.php b/system/ThirdParty/Kint/Renderer/RichRenderer.php index 94b7f98ab71f..46a8827ded56 100644 --- a/system/ThirdParty/Kint/Renderer/RichRenderer.php +++ b/system/ThirdParty/Kint/Renderer/RichRenderer.php @@ -133,6 +133,9 @@ class RichRenderer extends Renderer public static $always_pre_render = false; + public static $js_nonce = null; + public static $css_nonce = null; + protected $plugin_objs = []; protected $expand = false; protected $force_pre_render = false; @@ -389,10 +392,18 @@ public function preRender() switch ($type) { case 'script': - $output .= ''; + $output .= '' - . '' - . '' + . '' + . '' . $kintScript . PHP_EOL; From e7b0727e8d42833bbee5a38476a76ade10bd4f5b Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 31 Dec 2021 13:55:42 +0900 Subject: [PATCH 0057/1246] config: fix incorrect property name --- env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/env b/env index 7b52d6690441..e11bb08e0493 100644 --- a/env +++ b/env @@ -60,7 +60,7 @@ # contentsecuritypolicy.scriptSrc = 'self' # contentsecuritypolicy.styleSrc = 'self' # contentsecuritypolicy.imageSrc = 'self' -# contentsecuritypolicy.base_uri = null +# contentsecuritypolicy.baseURI = null # contentsecuritypolicy.childSrc = null # contentsecuritypolicy.connectSrc = 'self' # contentsecuritypolicy.fontSrc = null From d548118c264dedc1dde45b6ca0afcd550462b49f Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 31 Dec 2021 14:01:36 +0900 Subject: [PATCH 0058/1246] feat: add config for disabling to replace nonce tag automatically --- app/Config/ContentSecurityPolicy.php | 7 ++++ env | 1 + system/HTTP/ContentSecurityPolicy.php | 11 +++++++ .../system/HTTP/ContentSecurityPolicyTest.php | 32 +++++++++++++++++++ 4 files changed, 51 insertions(+) diff --git a/app/Config/ContentSecurityPolicy.php b/app/Config/ContentSecurityPolicy.php index b4450d5ed422..aa18ba9f1060 100644 --- a/app/Config/ContentSecurityPolicy.php +++ b/app/Config/ContentSecurityPolicy.php @@ -178,4 +178,11 @@ class ContentSecurityPolicy extends BaseConfig * @var string */ public $scriptNonceTag = '{csp-script-nonce}'; + + /** + * Replace nonce tag automatically + * + * @var bool + */ + public $autoNonce = true; } diff --git a/env b/env index e11bb08e0493..83def018081f 100644 --- a/env +++ b/env @@ -75,6 +75,7 @@ # contentsecuritypolicy.upgradeInsecureRequests = false # contentsecuritypolicy.styleNonceTag = '{csp-style-nonce}' # contentsecuritypolicy.scriptNonceTag = '{csp-script-nonce}' +# contentsecuritypolicy.autoNonce = true #-------------------------------------------------------------------- # COOKIE diff --git a/system/HTTP/ContentSecurityPolicy.php b/system/HTTP/ContentSecurityPolicy.php index fb70c613549a..341411013d0e 100644 --- a/system/HTTP/ContentSecurityPolicy.php +++ b/system/HTTP/ContentSecurityPolicy.php @@ -204,6 +204,13 @@ class ContentSecurityPolicy */ protected $scriptNonceTag = '{csp-script-nonce}'; + /** + * Replace nonce tag automatically + * + * @var bool + */ + protected $autoNonce = true; + /** * An array of header info since we have * to build ourself before passing to Response. @@ -288,6 +295,10 @@ public function getScriptNonce(): string */ public function finalize(ResponseInterface &$response) { + if ($this->autoNonce === false) { + return; + } + $this->generateNonces($response); $this->buildHeaders($response); } diff --git a/tests/system/HTTP/ContentSecurityPolicyTest.php b/tests/system/HTTP/ContentSecurityPolicyTest.php index 5525309d7a2f..fa95d9ba9fb6 100644 --- a/tests/system/HTTP/ContentSecurityPolicyTest.php +++ b/tests/system/HTTP/ContentSecurityPolicyTest.php @@ -480,6 +480,38 @@ public function testBodyScriptNonceCustomScriptTag() $this->assertStringContainsString('nonce=', $response->getBody()); } + public function testBodyScriptNonceDisableAutoNonce() + { + $config = new CSPConfig(); + $config->autoNonce = false; + $csp = new ContentSecurityPolicy($config); + + $response = new Response(new App()); + $response->pretend(true); + $body = 'Blah blah {csp-script-nonce} blah blah'; + $response->setBody($body); + + $csp->finalize($response); + + $this->assertStringContainsString('{csp-script-nonce}', $response->getBody()); + } + + public function testBodyStyleNonceDisableAutoNonce() + { + $config = new CSPConfig(); + $config->autoNonce = false; + $csp = new ContentSecurityPolicy($config); + + $response = new Response(new App()); + $response->pretend(true); + $body = 'Blah blah {csp-style-nonce} blah blah'; + $response->setBody($body); + + $csp->finalize($response); + + $this->assertStringContainsString('{csp-style-nonce}', $response->getBody()); + } + /** * @runInSeparateProcess * @preserveGlobalState disabled From bc52fad6678b3600e2d62139a032dbd5a2482192 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 31 Dec 2021 14:13:57 +0900 Subject: [PATCH 0059/1246] refactor: use csp_script_nonce() and csp_script_nonce() in Kint --- system/Debug/Kint/RichRenderer.php | 4 ++-- tests/system/CommonFunctionsTest.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/system/Debug/Kint/RichRenderer.php b/system/Debug/Kint/RichRenderer.php index 756cac75e144..8210fb21e1c2 100644 --- a/system/Debug/Kint/RichRenderer.php +++ b/system/Debug/Kint/RichRenderer.php @@ -36,11 +36,11 @@ public function preRender() switch ($type) { case 'script': - $output .= ''; + $output .= ''; break; case 'style': - $output .= ''; + $output .= ''; break; default: diff --git a/tests/system/CommonFunctionsTest.php b/tests/system/CommonFunctionsTest.php index f55f55fb45b4..51eb7f94938f 100644 --- a/tests/system/CommonFunctionsTest.php +++ b/tests/system/CommonFunctionsTest.php @@ -527,7 +527,7 @@ public function testDWithCSP() $config->CSPEnabled = true; Kint::$cli_detection = false; - $this->expectOutputRegex('/ + .. literalinclude:: html_helper/010.php + :lines: 2- Alternately, an associative array can be passed to the ``script_tag()`` function - for complete control over all attributes and values:: + for complete control over all attributes and values: - $script = ['src' => 'js/printer.js']; - - echo script_tag($script); - // + .. literalinclude:: html_helper/011.php + :lines: 2- .. php:function:: ul($list[, $attributes = '']) @@ -162,21 +142,10 @@ The following functions are available: :rtype: string Permits you to generate unordered HTML lists from simple or - multi-dimensional arrays. Example:: - - $list = [ - 'red', - 'blue', - 'green', - 'yellow', - ]; + multi-dimensional arrays. Example: - $attributes = [ - 'class' => 'boldlist', - 'id' => 'mylist', - ]; - - echo ul($list, $attributes); + .. literalinclude:: html_helper/012.php + :lines: 2- The above code will produce this: @@ -189,44 +158,10 @@ The following functions are available:
  • yellow
  • - Here is a more complex example, using a multi-dimensional array:: - - $attributes = [ - 'class' => 'boldlist', - 'id' => 'mylist', - ]; - - $list = [ - 'colors' => [ - 'red', - 'blue', - 'green', - ], - 'shapes' => [ - 'round', - 'square', - 'circles' => [ - 'ellipse', - 'oval', - 'sphere', - ], - ], - 'moods' => [ - 'happy', - 'upset' => [ - 'defeated' => [ - 'dejected', - 'disheartened', - 'depressed', - ], - 'annoyed', - 'cross', - 'angry', - ] - ] - ]; - - echo ul($list, $attributes); + Here is a more complex example, using a multi-dimensional array: + + .. literalinclude:: html_helper/013.php + :lines: 2- The above code will produce this: @@ -295,32 +230,10 @@ The following functions are available: :rtype: string Permits you to generate HTML video element from simple or - source arrays. Example:: - - $tracks = [ - track('subtitles_no.vtt', 'subtitles', 'no', 'Norwegian No'), - track('subtitles_yes.vtt', 'subtitles', 'yes', 'Norwegian Yes') - ]; - - echo video('test.mp4', 'Your browser does not support the video tag.', 'controls'); - - echo video( - 'http://www.codeigniter.com/test.mp4', - 'Your browser does not support the video tag.', - 'controls', - $tracks - ); - - echo video([ - source('movie.mp4', 'video/mp4', 'class="test"'), - source('movie.ogg', 'video/ogg'), - source('movie.mov', 'video/quicktime'), - source('movie.ogv', 'video/ogv; codecs=dirac, speex') - ], - 'Your browser does not support the video tag.', - 'class="test" controls', - $tracks - ); + source arrays. Example: + + .. literalinclude:: html_helper/014.php + :lines: 2- The above code will produce this: @@ -367,10 +280,10 @@ The following functions are available: :rtype: string Lets you create HTML ```` tags. The first parameter contains the - source source. Example:: + source source. Example: - echo source('movie.mp4', 'video/mp4', 'class="test"'); - // + .. literalinclude:: html_helper/015.php + :lines: 2- .. php:function:: embed($src = ''[, $type = false[, $attributes = ''[, $indexPage = false]]]) @@ -382,10 +295,10 @@ The following functions are available: :rtype: string Lets you create HTML ```` tags. The first parameter contains the - embed source. Example:: + embed source. Example: - echo embed('movie.mov', 'video/quicktime', 'class="test"'); - // + .. literalinclude:: html_helper/016.php + :lines: 2- .. php:function:: object($data = ''[, $type = false[, $attributes = '']]) @@ -397,19 +310,10 @@ The following functions are available: :rtype: string Lets you create HTML ```` tags. The first parameter contains the - object data. Example:: + object data. Example: - echo object('movie.swf', 'application/x-shockwave-flash', 'class="test"'); - - echo object( - 'movie.swf', - 'application/x-shockwave-flash', - 'class="test"', - [ - param('foo', 'bar', 'ref', 'class="test"'), - param('hello', 'world', 'ref', 'class="test"') - ] - ); + .. literalinclude:: html_helper/017.php + :lines: 2- The above code will produce this: @@ -431,10 +335,10 @@ The following functions are available: :rtype: string Lets you create HTML ```` tags. The first parameter contains the - param source. Example:: + param source. Example: - echo param('movie.mov', 'video/quicktime', 'class="test"'); - // + .. literalinclude:: html_helper/018.php + :lines: 2- .. php:function:: track($name = ''[, $type = false[, $attributes = '']]) @@ -445,10 +349,10 @@ The following functions are available: :rtype: string Generates a track element to specify timed tracks. The tracks are - formatted in WebVTT format. Example:: + formatted in WebVTT format. Example: - echo track('subtitles_no.vtt', 'subtitles', 'no', 'Norwegian No'); - // + .. literalinclude:: html_helper/019.php + :lines: 2- .. php:function:: doctype([$type = 'html5']) @@ -459,13 +363,10 @@ The following functions are available: Helps you generate document type declarations, or DTD's. HTML 5 is used by default, but many doctypes are available. - Example:: - - echo doctype(); - // + Example: - echo doctype('html4-trans'); - // + .. literalinclude:: html_helper/020.php + :lines: 2- The following is a list of the pre-defined doctype choices. These are configurable, pulled from **app/Config/DocTypes.php**, or they could be over-ridden in your **.env** configuration. diff --git a/user_guide_src/source/helpers/html_helper/001.php b/user_guide_src/source/helpers/html_helper/001.php new file mode 100644 index 000000000000..8163b563fc6e --- /dev/null +++ b/user_guide_src/source/helpers/html_helper/001.php @@ -0,0 +1,3 @@ + diff --git a/user_guide_src/source/helpers/html_helper/003.php b/user_guide_src/source/helpers/html_helper/003.php new file mode 100644 index 000000000000..1cf332ede621 --- /dev/null +++ b/user_guide_src/source/helpers/html_helper/003.php @@ -0,0 +1,4 @@ + diff --git a/user_guide_src/source/helpers/html_helper/004.php b/user_guide_src/source/helpers/html_helper/004.php new file mode 100644 index 000000000000..79769391f49f --- /dev/null +++ b/user_guide_src/source/helpers/html_helper/004.php @@ -0,0 +1,14 @@ + '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($imageProperties); +// Me, demonstrating how to eat 4 slices of pizza at one time diff --git a/user_guide_src/source/helpers/html_helper/005.php b/user_guide_src/source/helpers/html_helper/005.php new file mode 100644 index 000000000000..07c05813e74b --- /dev/null +++ b/user_guide_src/source/helpers/html_helper/005.php @@ -0,0 +1,4 @@ + diff --git a/user_guide_src/source/helpers/html_helper/008.php b/user_guide_src/source/helpers/html_helper/008.php new file mode 100644 index 000000000000..ec6741ede834 --- /dev/null +++ b/user_guide_src/source/helpers/html_helper/008.php @@ -0,0 +1,7 @@ + + +echo link_tag('feed', 'alternate', 'application/rss+xml', 'My RSS Feed'); +// diff --git a/user_guide_src/source/helpers/html_helper/009.php b/user_guide_src/source/helpers/html_helper/009.php new file mode 100644 index 000000000000..b598137dba11 --- /dev/null +++ b/user_guide_src/source/helpers/html_helper/009.php @@ -0,0 +1,11 @@ + 'css/printer.css', + 'rel' => 'stylesheet', + 'type' => 'text/css', + 'media' => 'print', +]; + +echo link_tag($link); +// diff --git a/user_guide_src/source/helpers/html_helper/010.php b/user_guide_src/source/helpers/html_helper/010.php new file mode 100644 index 000000000000..45e68400e6c9 --- /dev/null +++ b/user_guide_src/source/helpers/html_helper/010.php @@ -0,0 +1,4 @@ + diff --git a/user_guide_src/source/helpers/html_helper/011.php b/user_guide_src/source/helpers/html_helper/011.php new file mode 100644 index 000000000000..0d15fc0e6c69 --- /dev/null +++ b/user_guide_src/source/helpers/html_helper/011.php @@ -0,0 +1,6 @@ + 'js/printer.js']; + +echo script_tag($script); +// diff --git a/user_guide_src/source/helpers/html_helper/012.php b/user_guide_src/source/helpers/html_helper/012.php new file mode 100644 index 000000000000..941de51da134 --- /dev/null +++ b/user_guide_src/source/helpers/html_helper/012.php @@ -0,0 +1,15 @@ + 'boldlist', + 'id' => 'mylist', +]; + +echo ul($list, $attributes); diff --git a/user_guide_src/source/helpers/html_helper/013.php b/user_guide_src/source/helpers/html_helper/013.php new file mode 100644 index 000000000000..435ebc5535d2 --- /dev/null +++ b/user_guide_src/source/helpers/html_helper/013.php @@ -0,0 +1,38 @@ + 'boldlist', + 'id' => 'mylist', +]; + +$list = [ + 'colors' => [ + 'red', + 'blue', + 'green', + ], + 'shapes' => [ + 'round', + 'square', + 'circles' => [ + 'ellipse', + 'oval', + 'sphere', + ], + ], + 'moods' => [ + 'happy', + 'upset' => [ + 'defeated' => [ + 'dejected', + 'disheartened', + 'depressed', + ], + 'annoyed', + 'cross', + 'angry', + ] + ] +]; + +echo ul($list, $attributes); diff --git a/user_guide_src/source/helpers/html_helper/014.php b/user_guide_src/source/helpers/html_helper/014.php new file mode 100644 index 000000000000..505b771d5f1b --- /dev/null +++ b/user_guide_src/source/helpers/html_helper/014.php @@ -0,0 +1,26 @@ + diff --git a/user_guide_src/source/helpers/html_helper/016.php b/user_guide_src/source/helpers/html_helper/016.php new file mode 100644 index 000000000000..6e8c60a8dd7c --- /dev/null +++ b/user_guide_src/source/helpers/html_helper/016.php @@ -0,0 +1,4 @@ + diff --git a/user_guide_src/source/helpers/html_helper/017.php b/user_guide_src/source/helpers/html_helper/017.php new file mode 100644 index 000000000000..a0b38b79e672 --- /dev/null +++ b/user_guide_src/source/helpers/html_helper/017.php @@ -0,0 +1,13 @@ + diff --git a/user_guide_src/source/helpers/html_helper/019.php b/user_guide_src/source/helpers/html_helper/019.php new file mode 100644 index 000000000000..d073fa12df96 --- /dev/null +++ b/user_guide_src/source/helpers/html_helper/019.php @@ -0,0 +1,4 @@ + diff --git a/user_guide_src/source/helpers/html_helper/020.php b/user_guide_src/source/helpers/html_helper/020.php new file mode 100644 index 000000000000..1bd614043095 --- /dev/null +++ b/user_guide_src/source/helpers/html_helper/020.php @@ -0,0 +1,7 @@ + + +echo doctype('html4-trans'); +// diff --git a/user_guide_src/source/helpers/inflector_helper.rst b/user_guide_src/source/helpers/inflector_helper.rst index 924ee5b75559..690430ea1b63 100755 --- a/user_guide_src/source/helpers/inflector_helper.rst +++ b/user_guide_src/source/helpers/inflector_helper.rst @@ -12,9 +12,10 @@ The Inflector Helper file contains functions that permit you to change Loading this Helper =================== -This helper is loaded using the following code:: +This helper is loaded using the following code: - helper('inflector'); +.. literalinclude:: inflector_helper/001.php + :lines: 2- Available Functions =================== @@ -27,9 +28,10 @@ The following functions are available: :returns: A singular word :rtype: string - Changes a plural word to singular. Example:: + Changes a plural word to singular. Example: - echo singular('dogs'); // Prints 'dog' + .. literalinclude:: inflector_helper/002.php + :lines: 2- .. php:function:: plural($string) @@ -37,9 +39,10 @@ The following functions are available: :returns: A plural word :rtype: string - Changes a singular word to plural. Example:: + Changes a singular word to plural. Example: - echo plural('dog'); // Prints 'dogs' + .. literalinclude:: inflector_helper/003.php + :lines: 2- .. php:function:: counted($count, $string) @@ -48,9 +51,10 @@ The following functions are available: :returns: A singular or plural phrase :rtype: string - Changes a word and its count to a phrase. Example:: + Changes a word and its count to a phrase. Example: - echo counted(3, 'dog'); // Prints '3 dogs' + .. literalinclude:: inflector_helper/004.php + :lines: 2- .. php:function:: camelize($string) @@ -59,9 +63,10 @@ The following functions are available: :rtype: string Changes a string of words separated by spaces or underscores to camel - case. Example:: + case. Example: - echo camelize('my_dog_spot'); // Prints 'myDogSpot' + .. literalinclude:: inflector_helper/005.php + :lines: 2- .. php:function:: pascalize($string) @@ -70,9 +75,10 @@ The following functions are available: :rtype: string Changes a string of words separated by spaces or underscores to Pascal - case, which is camel case with the first letter capitalized. Example:: + case, which is camel case with the first letter capitalized. Example: - echo pascalize('my_dog_spot'); // Prints 'MyDogSpot' + .. literalinclude:: inflector_helper/006.php + :lines: 2- .. php:function:: underscore($string) @@ -81,9 +87,10 @@ The following functions are available: :rtype: string Takes multiple words separated by spaces and underscores them. - Example:: + Example: - echo underscore('my dog spot'); // Prints 'my_dog_spot' + .. literalinclude:: inflector_helper/007.php + :lines: 2- .. php:function:: humanize($string[, $separator = '_']) @@ -95,13 +102,15 @@ The following functions are available: Takes multiple words separated by underscores and adds spaces between them. Each word is capitalized. - Example:: + Example: - echo humanize('my_dog_spot'); // Prints 'My Dog Spot' + .. literalinclude:: inflector_helper/008.php + :lines: 2- - To use dashes instead of underscores:: + To use dashes instead of underscores: - echo humanize('my-dog-spot', '-'); // Prints 'My Dog Spot' + .. literalinclude:: inflector_helper/009.php + :lines: 2- .. php:function:: is_pluralizable($word) @@ -109,9 +118,10 @@ The following functions are available: :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_pluralizable('equipment'); // Returns false + .. literalinclude:: inflector_helper/010.php + :lines: 2- .. php:function:: dasherize($string) @@ -119,9 +129,10 @@ The following functions are available: :returns: Dasherized string :rtype: string - Replaces underscores with dashes in the string. Example:: + Replaces underscores with dashes in the string. Example: - dasherize('hello_world'); // Returns 'hello-world' + .. literalinclude:: inflector_helper/011.php + :lines: 2- .. php:function:: ordinal($integer) @@ -131,9 +142,10 @@ The following functions are available: Returns the suffix that should be added to a number to denote the position such as - 1st, 2nd, 3rd, 4th. Example:: + 1st, 2nd, 3rd, 4th. Example: - ordinal(1); // Returns 'st' + .. literalinclude:: inflector_helper/012.php + :lines: 2- .. php:function:: ordinalize($integer) @@ -143,6 +155,7 @@ The following functions are available: Turns a number into an ordinal string used to denote the position such as 1st, 2nd, 3rd, 4th. - Example:: + Example: - ordinalize(1); // Returns '1st' + .. literalinclude:: inflector_helper/013.php + :lines: 2- diff --git a/user_guide_src/source/helpers/inflector_helper/001.php b/user_guide_src/source/helpers/inflector_helper/001.php new file mode 100644 index 000000000000..985243995503 --- /dev/null +++ b/user_guide_src/source/helpers/inflector_helper/001.php @@ -0,0 +1,3 @@ +/Number.php* @@ -72,20 +67,20 @@ The following functions are available: :rtype: string Converts a number into a human-readable version, like **123.4 trillion** - for numbers up to the quadrillions. Examples:: + for numbers up to the quadrillions. Examples: - echo number_to_amount(123456); // Returns 123 thousand - echo number_to_amount(123456789); // Returns 123 million - echo number_to_amount(1234567890123, 2); // Returns 1.23 trillion - echo number_to_amount('123,456,789,012', 2); // Returns 123.46 billion + .. literalinclude:: number_helper/005.php + :lines: 2- - An optional second parameter allows you to set the precision of the result:: + An optional second parameter allows you to set the precision of the result: - echo number_to_amount(45678, 2); // Returns 45.68 thousand + .. literalinclude:: number_helper/006.php + :lines: 2- - An optional third parameter allows the locale to be specified:: + An optional third parameter allows the locale to be specified: - echo number_to_amount('123,456,789,012', 2, 'de_DE'); // Returns 123,46 billion + .. literalinclude:: number_helper/007.php + :lines: 2- .. php:function:: number_to_currency($num, $currency[, $locale = null[, $fraction = 0]]) @@ -96,12 +91,10 @@ The following functions are available: :returns: The number as the appropriate currency for the locale :rtype: string - Converts a number in common currency formats, like USD, EUR, GBP, etc:: + Converts a number in common currency formats, like USD, EUR, GBP, etc: - echo number_to_currency(1234.56, 'USD', 'en_US', 2); // Returns $1,234.56 - echo number_to_currency(1234.56, 'EUR', 'de_DE', 2); // Returns 1.234,56 € - echo number_to_currency(1234.56, 'GBP', 'en_GB', 2); // Returns £1,234.56 - echo number_to_currency(1234.56, 'YEN', 'ja_JP', 2); // Returns YEN 1,234.56 + .. literalinclude:: number_helper/008.php + :lines: 2- If you don't specify a locale, the Request locale is used. @@ -111,11 +104,10 @@ The following functions are available: :returns: The roman number converted from given parameter :rtype: string|null - Converts a number into roman:: + Converts a number into roman: - echo number_to_roman(23); // Returns XXIII - echo number_to_roman(324); // Returns CCCXXIV - echo number_to_roman(2534); // Returns MMDXXXIV + .. literalinclude:: number_helper/009.php + :lines: 2- This function only handles numbers in the range 1 through 3999. It will return null for any value outside that range. diff --git a/user_guide_src/source/helpers/number_helper/001.php b/user_guide_src/source/helpers/number_helper/001.php new file mode 100644 index 000000000000..9ff7e68b56c6 --- /dev/null +++ b/user_guide_src/source/helpers/number_helper/001.php @@ -0,0 +1,3 @@ +assertTrue($this->userHasAccess($user)); - } + .. literalinclude:: test_helper/002.php + :lines: 2- diff --git a/user_guide_src/source/helpers/test_helper/001.php b/user_guide_src/source/helpers/test_helper/001.php new file mode 100644 index 000000000000..6bbc62605b25 --- /dev/null +++ b/user_guide_src/source/helpers/test_helper/001.php @@ -0,0 +1,3 @@ +assertTrue($this->userHasAccess($user)); +} diff --git a/user_guide_src/source/helpers/text_helper.rst b/user_guide_src/source/helpers/text_helper.rst index 0c842677a001..ebc1784c305c 100755 --- a/user_guide_src/source/helpers/text_helper.rst +++ b/user_guide_src/source/helpers/text_helper.rst @@ -11,9 +11,10 @@ The Text Helper file contains functions that assist in working with Text. Loading this Helper =================== -This helper is loaded using the following code:: +This helper is loaded using the following code: - helper('text'); +.. literalinclude:: text_helper/001.php + :lines: 2- Available Functions =================== @@ -42,9 +43,10 @@ The following functions are available: - **sha1**: An encrypted random number based on ``sha1()`` (fixed length of 40). - **crypto**: A random string based on ``random_bytes()``. - Usage example:: + Usage example: - echo random_string('alnum', 16); + .. literalinclude:: text_helper/002.php + :lines: 2- .. php:function:: increment_string($str[, $separator = '_'[, $first = 1]]) @@ -58,11 +60,10 @@ The following functions are available: 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" + .. literalinclude:: text_helper/003.php + :lines: 2- .. php:function:: alternator($args) @@ -71,20 +72,16 @@ The following functions are available: :rtype: mixed Allows two or more items to be alternated between, when cycling through - a loop. Example:: + a loop. Example: - for ($i = 0; $i < 10; $i++) {      - echo alternator('string one', 'string two'); - } + .. literalinclude:: text_helper/004.php + :lines: 2- 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'); - } + .. literalinclude:: text_helper/005.php + :lines: 2- .. note:: To use multiple separate calls to this function simply call the function with no arguments to re-initialize. @@ -98,10 +95,10 @@ The following functions are available: 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" + .. literalinclude:: text_helper/006.php + :lines: 2- .. php:function:: strip_slashes($data) @@ -111,21 +108,15 @@ The following functions are available: Removes any slashes from an array of strings. - Example:: - - $str = [ - 'question' => "Is your name O\'reilly?", - 'answer' => "No, my name is O\'connor." - ]; + Example: - $str = strip_slashes($str); + .. literalinclude:: text_helper/007.php + :lines: 2- - The above will return the following array:: + The above will return the following array: - [ - 'question' => "Is your name O'reilly?", - 'answer' => "No, my name is O'connor." - ]; + .. literalinclude:: text_helper/008.php + :lines: 2- .. note:: For historical reasons, this function will also accept and handle string inputs. This however makes it just an @@ -140,16 +131,16 @@ The following functions are available: :rtype: string Reduces multiple instances of a particular character occurring directly - after each other. Example:: + after each other. Example: - $string = "Fred, Bill,, Joe, Jimmy"; - $string = reduce_multiples($string, ","); // results in "Fred, Bill, Joe, Jimmy" + .. literalinclude:: text_helper/009.php + :lines: 2- 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:: + character at the beginning and the end of the string. Example: - $string = ",Fred, Bill,, Joe, Jimmy,"; - $string = reduce_multiples($string, ", ", true); // results in "Fred, Bill, Joe, Jimmy" + .. literalinclude:: text_helper/010.php + :lines: 2- .. php:function:: quotes_to_entities($str) @@ -158,10 +149,10 @@ The following functions are available: :rtype: string Converts single and double quotes in a string to the corresponding HTML - entities. Example:: + entities. Example: - $string = "Joe's \"dinner\""; - $string = quotes_to_entities($string); //results in "Joe's "dinner"" + .. literalinclude:: text_helper/011.php + :lines: 2- .. php:function:: strip_quotes($str) @@ -169,10 +160,10 @@ The following functions are available: :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" + .. literalinclude:: text_helper/012.php + :lines: 2- .. php:function:: word_limiter($str[, $limit = 100[, $end_char = '…']]) @@ -182,11 +173,10 @@ The following functions are available: :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 + .. literalinclude:: text_helper/013.php + :lines: 2- The third parameter is an optional suffix added to the string. By default it adds an ellipsis. @@ -203,11 +193,10 @@ The following functions are available: 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 + .. literalinclude:: text_helper/014.php + :lines: 2- The third parameter is an optional suffix added to the string, if undeclared this helper uses an ellipsis. @@ -229,9 +218,10 @@ The following functions are available: but for the most part, it should correctly identify characters outside the normal range (like accented characters). - Example:: + Example: - $string = ascii_to_entities($string); + .. literalinclude:: text_helper/015.php + :lines: 2- .. php:function:: entities_to_ascii($str[, $all = true]) @@ -253,9 +243,10 @@ The following functions are available: when non-English characters need to be used where only standard ASCII characters are safely used, for instance, in URLs. - Example:: + Example: - $string = convert_accented_characters($string); + .. literalinclude:: text_helper/016.php + :lines: 2- .. note:: This function uses a companion config file **app/Config/ForeignCharacters.php** to define the to and @@ -275,10 +266,10 @@ The following functions are available: a replacement value for the words. If not specified they are replaced with pound signs: ####. - Example:: + Example: - $disallowed = ['darn', 'shucks', 'golly', 'phooey']; - $string = word_censor($string, $disallowed, 'Beep!'); + .. literalinclude:: text_helper/017.php + :lines: 2- .. php:function:: highlight_code($str) @@ -286,9 +277,10 @@ The following functions are available: :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); + .. literalinclude:: text_helper/018.php + :lines: 2- The function uses PHP's ``highlight_string()`` function, so the colors used are the ones specified in your php.ini file. @@ -307,10 +299,10 @@ The following functions are available: 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", '', ''); + .. literalinclude:: text_helper/019.php + :lines: 2- The above code prints:: @@ -336,18 +328,10 @@ The following functions are available: Wraps text at the specified *character* count while maintaining complete words. - Example:: - - $string = "Here is a simple string of text that will help us demonstrate this function."; - echo word_wrap($string, 25); + Example: - // Would produce: - // Here is a simple string - // of text that will help us - // demonstrate this - // function. - - Excessively long words will be split, but URLs will not be. + .. literalinclude:: text_helper/020.php + :lines: 2- .. php:function:: ellipsize($str, $max_length[, $position = 1[, $ellipsis = '…']]) @@ -370,10 +354,10 @@ The following functions are available: An optional fourth 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); + .. literalinclude:: text_helper/021.php + :lines: 2- Produces:: @@ -397,18 +381,10 @@ The following functions are available: passed, the excerpt will include the first $radius characters with the ellipsis at the end. - Example:: - - $text = 'Ut vel faucibus odio. Quisque quis congue libero. Etiam gravida - eros lorem, eget porttitor augue dignissim tincidunt. In eget risus eget - mauris faucibus molestie vitae ultricies odio. Vestibulum id ultricies diam. - Curabitur non mauris lectus. Phasellus eu sodales sem. Integer dictum purus - ac enim hendrerit gravida. Donec ac magna vel nunc tincidunt molestie sed - vitae nisl. Cras sed auctor mauris, non dictum tortor. Nulla vel scelerisque - arcu. Cras ac ipsum sit amet augue laoreet laoreet. Aenean a risus lacus. - Sed ut tortor diam.'; + Example: - echo excerpt($text, 'Donec'); + .. literalinclude:: text_helper/022.php + :lines: 2- Produces:: diff --git a/user_guide_src/source/helpers/text_helper/001.php b/user_guide_src/source/helpers/text_helper/001.php new file mode 100644 index 000000000000..fdf999c3d9c6 --- /dev/null +++ b/user_guide_src/source/helpers/text_helper/001.php @@ -0,0 +1,3 @@ + "Is your name O\'reilly?", + 'answer' => "No, my name is O\'connor." +]; + +$str = strip_slashes($str); diff --git a/user_guide_src/source/helpers/text_helper/008.php b/user_guide_src/source/helpers/text_helper/008.php new file mode 100644 index 000000000000..073f97ff0046 --- /dev/null +++ b/user_guide_src/source/helpers/text_helper/008.php @@ -0,0 +1,6 @@ + "Is your name O'reilly?", + 'answer' => "No, my name is O'connor." +]; diff --git a/user_guide_src/source/helpers/text_helper/009.php b/user_guide_src/source/helpers/text_helper/009.php new file mode 100644 index 000000000000..8081482f17eb --- /dev/null +++ b/user_guide_src/source/helpers/text_helper/009.php @@ -0,0 +1,4 @@ +', ''); diff --git a/user_guide_src/source/helpers/text_helper/020.php b/user_guide_src/source/helpers/text_helper/020.php new file mode 100644 index 000000000000..a6de1d0f67f0 --- /dev/null +++ b/user_guide_src/source/helpers/text_helper/020.php @@ -0,0 +1,12 @@ +My News - - echo anchor('news/local/123', 'My News', ['title' => 'The best news!']); - // Prints: My News - - echo anchor('', 'Click here'); - // Prints: Click here + .. literalinclude:: url_helper/005.php + :lines: 2- As above, you may specify an alternate configuration. You may find the alternate configuration useful if generating links for a @@ -210,20 +209,10 @@ The following functions are available: 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:: - - $atts = [ - 'width' => 800, - 'height' => 600, - 'scrollbars' => 'yes', - 'status'      => 'yes', - 'resizable'   => 'yes', - 'screenx' => 0, - 'screeny' => 0, - 'window_name' => '_blank', - ]; + Here is an example with attributes: - echo anchor_popup('news/local/123', 'Click Me!', $atts); + .. literalinclude:: url_helper/006.php + :lines: 2- As above, you may specify an alternate configuration. You may find the alternate configuration useful if generating links for a @@ -233,9 +222,10 @@ The following functions are available: .. 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:: + third parameter: - echo anchor_popup('news/local/123', 'Click Me!', []); + .. literalinclude:: url_helper/007.php + :lines: 2- .. note:: The **window_name** is not really an attribute, but an argument to the JavaScript `window.open() `_ @@ -254,15 +244,16 @@ The following functions are available: :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'); + .. literalinclude:: url_helper/008.php + :lines: 2- As with the :php:func:`anchor()` tab above, you can set attributes using the - third parameter:: + third parameter: - $attributes = ['title' => 'Mail me']; - echo mailto('me@my-site.com', 'Contact Me', $attributes); + .. literalinclude:: url_helper/009.php + :lines: 2- .. note:: Attributes passed into the mailto function are automatically escaped to protected against XSS attacks. @@ -287,27 +278,31 @@ The following functions are available: :rtype: string Automatically turns URLs and e-mail addresses contained in a string into - links. Example:: + links. Example: - $string = auto_link($string); + .. literalinclude:: url_helper/010.php + :lines: 2- The second parameter determines whether URLs and e-mails are converted or just one or the other. The default behavior is both if the parameter is not specified. E-mail links are encoded as :php:func:`safe_mailto()` as shown above. - Converts only URLs:: + Converts only URLs: - $string = auto_link($string, 'url'); + .. literalinclude:: url_helper/011.php + :lines: 2- - Converts only e-mail addresses:: + Converts only e-mail addresses: - $string = auto_link($string, 'email'); + .. literalinclude:: url_helper/012.php + :lines: 2- The third parameter determines whether links are shown in a new window. - The value can be true or false (boolean):: + The value can be true or false (boolean): - $string = auto_link($string, 'both', true); + .. literalinclude:: url_helper/013.php + :lines: 2- .. note:: The only URLs recognized are those that start with "www." or with "://". @@ -321,29 +316,26 @@ The following functions are available: 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 of your entries in the URL. Example: - $title = "What's wrong with CSS?"; - $url_title = url_title($title); - // Produces: Whats-wrong-with-CSS + .. literalinclude:: url_helper/014.php + :lines: 2- 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, '_'); - // Produces: Whats_wrong_with_CSS + .. literalinclude:: url_helper/015.php + :lines: 2- 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, '-', true); - // Produces: whats-wrong-with-css + .. literalinclude:: url_helper/016.php + :lines: 2- .. php:function:: mb_url_title($str[, $separator = '-'[, $lowercase = false]]) @@ -366,9 +358,10 @@ The following functions are available: This function will add *http://* or *https://* 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'); + .. literalinclude:: url_helper/017.php + :lines: 2- .. php:function:: url_to($controller[, ...$args]) @@ -377,14 +370,16 @@ The following functions are available: :returns: Absolute URL :rtype: string - Builds an absolute URL to a controller method in your app. Example:: + Builds an absolute URL to a controller method in your app. Example: - echo url_to('Home::index'); + .. literalinclude:: url_helper/018.php + :lines: 2- You can also add arguments to the route. - Here is an example:: + Here is an example: - echo url_to('Page::index', 'home'); + .. literalinclude:: url_helper/019.php + :lines: 2- The above example would return something like: *http://example.com/page/home* @@ -397,14 +392,16 @@ The following functions are available: :param string $path: The path to check the current URI path against. :rtype: boolean - Compares the current URL's path against the given path to see if they match. Example:: + Compares the current URL's path against the given path to see if they match. Example: - if (url_is('admin')) { ... } + .. literalinclude:: url_helper/020.php + :lines: 2- This would match ``http://example.com/admin``. You can use the ``*`` wildcard to match - any other applicable characters in the URL:: + any other applicable characters in the URL: - if (url_is('admin*')) { ... } + .. literalinclude:: url_helper/021.php + :lines: 2- This would match any of the following: diff --git a/user_guide_src/source/helpers/url_helper/001.php b/user_guide_src/source/helpers/url_helper/001.php new file mode 100644 index 000000000000..cf11aa2d2541 --- /dev/null +++ b/user_guide_src/source/helpers/url_helper/001.php @@ -0,0 +1,3 @@ +My News + +echo anchor('news/local/123', 'My News', ['title' => 'The best news!']); +// Prints: My News + +echo anchor('', 'Click here'); +// Prints: Click here diff --git a/user_guide_src/source/helpers/url_helper/006.php b/user_guide_src/source/helpers/url_helper/006.php new file mode 100644 index 000000000000..960bc6f0430e --- /dev/null +++ b/user_guide_src/source/helpers/url_helper/006.php @@ -0,0 +1,14 @@ + 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); diff --git a/user_guide_src/source/helpers/url_helper/007.php b/user_guide_src/source/helpers/url_helper/007.php new file mode 100644 index 000000000000..cb1e202af757 --- /dev/null +++ b/user_guide_src/source/helpers/url_helper/007.php @@ -0,0 +1,3 @@ + 'Mail me']; +echo mailto('me@my-site.com', 'Contact Me', $attributes); diff --git a/user_guide_src/source/helpers/url_helper/010.php b/user_guide_src/source/helpers/url_helper/010.php new file mode 100644 index 000000000000..65bf083b99cf --- /dev/null +++ b/user_guide_src/source/helpers/url_helper/010.php @@ -0,0 +1,3 @@ +Here is a paragraph & an entity ({).

    '; - $string = xml_convert($string); - echo $string; + .. literalinclude:: xml_helper/002.php + :lines: 2- outputs: diff --git a/user_guide_src/source/helpers/xml_helper/001.php b/user_guide_src/source/helpers/xml_helper/001.php new file mode 100644 index 000000000000..f92f3a7da3c2 --- /dev/null +++ b/user_guide_src/source/helpers/xml_helper/001.php @@ -0,0 +1,3 @@ +Here is a paragraph & an entity ({).

    '; +$string = xml_convert($string); +echo $string; diff --git a/user_guide_src/source/incoming/content_negotiation.rst b/user_guide_src/source/incoming/content_negotiation.rst index 8122a4a910b5..0db8e8f23c5d 100644 --- a/user_guide_src/source/incoming/content_negotiation.rst +++ b/user_guide_src/source/incoming/content_negotiation.rst @@ -13,17 +13,19 @@ can handle this for you. Loading the Class ================= -You can load an instance of the class manually through the Service class:: +You can load an instance of the class manually through the Service class: - $negotiate = \Config\Services::negotiator(); +.. literalinclude:: content_negotiation/001.php + :lines: 2- This will grab the current request instance and automatically inject it into the Negotiator class. This class does not need to be loaded on it's own. Instead, it can be accessed through this request's ``IncomingRequest`` instance. While you cannot access it directly this way, you can easily access all of methods through the ``negotiate()`` -method:: +method: - $request->negotiate('media', ['foo', 'bar']); +.. literalinclude:: content_negotiation/002.php + :lines: 2- When accessed this way, the first parameter is the type of content you're trying to find a match for, while the second is an array of supported values. @@ -47,26 +49,18 @@ from an API endpoint:: Accept: application/json The server now needs to provide a list of what type of content it can provide. In this example, the API might -be able to return data as raw HTML, JSON, or XML. This list should be provided in order of preference:: +be able to return data as raw HTML, JSON, or XML. This list should be provided in order of preference: - $supported = [ - 'application/json', - 'text/html', - 'application/xml', - ]; - - $format = $request->negotiate('media', $supported); - // or - $format = $negotiate->media($supported); +.. literalinclude:: content_negotiation/003.php + :lines: 2- In this case, both the client and the server can agree on formatting the data as JSON so 'json' is returned from the negotiate method. By default, if no match is found, the first element in the ``$supported`` array would be returned. In some cases, though, you might need to enforce the format to be a strict match. If you pass ``true`` as the -final value, it will return an empty string if no match is found:: +final value, it will return an empty string if no match is found: - $format = $request->negotiate('media', $supported, true); - // or - $format = $negotiate->media($supported, true); +.. literalinclude:: content_negotiation/004.php + :lines: 2- Language ======== @@ -80,16 +74,10 @@ header:: Accept-Language: fr; q=1.0, en; q=0.5 In this example, the browser would prefer French, with a second choice of English. If your website supports English -and German you would do something like:: - - $supported = [ - 'en', - 'de', - ]; +and German you would do something like: - $lang = $request->negotiate('language', $supported); - // or - $lang = $negotiate->language($supported); +.. literalinclude:: content_negotiation/005.php + :lines: 2- In this example, 'en' would be returned as the current language. If no match is found, it will return the first element in the ``$supported`` array, so that should always be the preferred language. @@ -103,11 +91,10 @@ specify the type of compression the client supports:: GET /foo HTTP/1.1 Accept-Encoding: compress, gzip -Your web server will define what types of compression you can use. Some, like Apache, only support **gzip**:: +Your web server will define what types of compression you can use. Some, like Apache, only support **gzip**: - $type = $request->negotiate('encoding', ['gzip']); - // or - $type = $negotiate->encoding(['gzip']); +.. literalinclude:: content_negotiation/006.php + :lines: 2- See more at `Wikipedia `_. @@ -119,8 +106,7 @@ The desired character set is passed through the ``Accept-Charset`` header:: GET /foo HTTP/1.1 Accept-Charset: utf-16, utf-8 -By default, if no matches are found, **utf-8** will be returned:: +By default, if no matches are found, **utf-8** will be returned: - $charset = $request->negotiate('charset', ['utf-8']); - // or - $charset = $negotiate->charset(['utf-8']); +.. literalinclude:: content_negotiation/007.php + :lines: 2- diff --git a/user_guide_src/source/incoming/content_negotiation/001.php b/user_guide_src/source/incoming/content_negotiation/001.php new file mode 100644 index 000000000000..3c55e788eff9 --- /dev/null +++ b/user_guide_src/source/incoming/content_negotiation/001.php @@ -0,0 +1,3 @@ +negotiate('media', ['foo', 'bar']); diff --git a/user_guide_src/source/incoming/content_negotiation/003.php b/user_guide_src/source/incoming/content_negotiation/003.php new file mode 100644 index 000000000000..262a4d74f3be --- /dev/null +++ b/user_guide_src/source/incoming/content_negotiation/003.php @@ -0,0 +1,11 @@ +negotiate('media', $supported); +// or +$format = $negotiate->media($supported); diff --git a/user_guide_src/source/incoming/content_negotiation/004.php b/user_guide_src/source/incoming/content_negotiation/004.php new file mode 100644 index 000000000000..c02b2219fb2b --- /dev/null +++ b/user_guide_src/source/incoming/content_negotiation/004.php @@ -0,0 +1,5 @@ +negotiate('media', $supported, true); +// or +$format = $negotiate->media($supported, true); diff --git a/user_guide_src/source/incoming/content_negotiation/005.php b/user_guide_src/source/incoming/content_negotiation/005.php new file mode 100644 index 000000000000..a5413d43f94d --- /dev/null +++ b/user_guide_src/source/incoming/content_negotiation/005.php @@ -0,0 +1,10 @@ +negotiate('language', $supported); +// or +$lang = $negotiate->language($supported); diff --git a/user_guide_src/source/incoming/content_negotiation/006.php b/user_guide_src/source/incoming/content_negotiation/006.php new file mode 100644 index 000000000000..3cd6d0378617 --- /dev/null +++ b/user_guide_src/source/incoming/content_negotiation/006.php @@ -0,0 +1,5 @@ +negotiate('encoding', ['gzip']); +// or +$type = $negotiate->encoding(['gzip']); diff --git a/user_guide_src/source/incoming/content_negotiation/007.php b/user_guide_src/source/incoming/content_negotiation/007.php new file mode 100644 index 000000000000..eeaf3a26c876 --- /dev/null +++ b/user_guide_src/source/incoming/content_negotiation/007.php @@ -0,0 +1,5 @@ +negotiate('charset', ['utf-8']); +// or +$charset = $negotiate->charset(['utf-8']); diff --git a/user_guide_src/source/incoming/controllers.rst b/user_guide_src/source/incoming/controllers.rst index 2fee4580dffb..6d0dbcc8e055 100644 --- a/user_guide_src/source/incoming/controllers.rst +++ b/user_guide_src/source/incoming/controllers.rst @@ -8,7 +8,6 @@ Controllers are the heart of your application, as they determine how HTTP reques :local: :depth: 2 - What is a Controller? ===================== @@ -32,19 +31,9 @@ also extend the ``CodeIgniter\Controller`` if you do not need the functionality The BaseController provides a convenient place for loading components and performing functions that are needed by all your controllers. You can extend this class in any new controller. -For security reasons be sure to declare any new utility methods as ``protected`` or ``private``.:: - - ` feature. - Here is an example based on PSR-4 Autoloader:: - - \(\)*\ + Here is an example based on PSR-4 Autoloader: - $routes->get('helloworld', '\App\Controllers\HelloWorld::index'); + .. literalinclude:: controllers/005.php + :lines: 2- Methods ======= @@ -121,24 +88,9 @@ empty. Another way to show your "Hello World" message would be this:: **The second segment of the URI determines which method in the controller gets called.** -Let's try it. Add a new method to your controller:: +Let's try it. Add a new method to your controller: - ` feature, the segments passed to your method will be the re-routed @@ -183,15 +124,17 @@ present, as will be the case when only your site root URL is requested. Let's tr with the ``Helloworld`` controller. To specify a default controller open your **app/Config/Routes.php** -file and set this variable:: +file and set this variable: - $routes->setDefaultController('Helloworld'); +.. literalinclude:: controllers/008.php + :lines: 2- Where ``Helloworld`` is the name of the controller class you want to be used. -A few lines further down **Routes.php** in the "Route Definitions" section, comment out the line:: +A few lines further down **Routes.php** in the "Route Definitions" section, comment out the line: - $routes->get('/', 'Home::index'); +.. literalinclude:: controllers/009.php + :lines: 2- If you now browse to your site without specifying any URI segments you'll see the “Hello World” message. @@ -206,12 +149,10 @@ Remapping Method Calls As noted above, the second segment of the URI typically determines which method in the controller gets called. CodeIgniter permits you to override -this behavior through the use of the ``_remap()`` method:: +this behavior through the use of the ``_remap()`` method: - public function _remap() - { - // Some code here... - } +.. literalinclude:: controllers/010.php + :lines: 2- .. important:: If your controller contains a method named ``_remap()``, it will **always** get called regardless of what your URI contains. It @@ -219,32 +160,18 @@ this behavior through the use of the ``_remap()`` method:: is called, allowing you to define your own method routing rules. The overridden method call (typically the second segment of the URI) will -be passed as a parameter to the ``_remap()`` method:: +be passed as a parameter to the ``_remap()`` method: - public function _remap($method) - { - if ($method === 'some_method') { - return $this->$method(); - } else { - return $this->default_method(); - } - } +.. literalinclude:: controllers/011.php + :lines: 2- Any extra segments after the method name are passed into ``_remap()``. These parameters can be passed to the method to emulate CodeIgniter's default behavior. -Example:: - - public function _remap($method, ...$params) - { - $method = 'process_'.$method; +Example: - if (method_exists($this, $method)) { - return $this->$method(...$params); - } - - throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound(); - } +.. literalinclude:: controllers/012.php + :lines: 2- Private methods =============== @@ -252,12 +179,10 @@ Private methods In some cases, you may want certain methods hidden from public access. To achieve this, simply declare the method as ``private`` or ``protected``. That will prevent it from being served by a URL request. For example, -if you were to define a method like this for the ``Helloworld`` controller:: +if you were to define a method like this for the ``Helloworld`` controller: - protected function utility() - { - // some code - } +.. literalinclude:: controllers/013.php + :lines: 2- then trying to access it using the following URL will not work:: @@ -295,7 +220,6 @@ your **app/Config/Routes.php** file. CodeIgniter also permits you to remap your URIs using its :doc:`URI Routing ` feature. - Included Properties =================== @@ -320,19 +244,17 @@ An instance of the :doc:`Logger <../general/logging>` class is available as a cl **forceHTTPS** A convenience method for forcing a method to be accessed via HTTPS is available within all -controllers:: +controllers: - if (! $this->request->isSecure()) { - $this->forceHTTPS(); - } +.. literalinclude:: controllers/014.php + :lines: 2- By default, and in modern browsers that support the HTTP Strict Transport Security header, this call should force the browser to convert non-HTTPS calls to HTTPS calls for one year. You can -modify this by passing the duration (in seconds) as the first parameter:: +modify this by passing the duration (in seconds) as the first parameter: - if (! $this->request->isSecure()) { - $this->forceHTTPS(31536000); // one year - } +.. literalinclude:: controllers/015.php + :lines: 2- .. note:: A number of :doc:`time-based constants ` are always available for you to use, including ``YEAR``, ``MONTH``, and more. @@ -341,14 +263,10 @@ Helpers You can define an array of helper files as a class property. Whenever the controller is loaded these helper files will be automatically loaded into memory so that you can use their methods anywhere -inside the controller:: - - namespace App\Controllers; +inside the controller: - class MyController extends BaseController - { - protected $helpers = ['url', 'form']; - } +.. literalinclude:: controllers/016.php + :lines: 2- .. _controllers-validating-data: @@ -364,35 +282,16 @@ and in the optional second parameter, an array of custom error messages to displ if the items are not valid. Internally, this uses the controller's ``$this->request`` instance to get the data to be validated. The :doc:`Validation Library docs ` have details on -rule and message array formats, as well as available rules.:: - - public function updateUser(int $userID) - { - if (! $this->validate([ - 'email' => "required|is_unique[users.email,id,{$userID}]", - 'name' => 'required|alpha_numeric_spaces' - ])) { - return view('users/update', [ - 'errors' => $this->validator->getErrors() - ]); - } - - // do something here if successful... - } +rule and message array formats, as well as available rules.: -If you find it simpler to keep the rules in the configuration file, you can replace -the ``$rules`` array with the name of the group as defined in ``Config\Validation.php``:: +.. literalinclude:: controllers/017.php + :lines: 2- - public function updateUser(int $userID) - { - if (! $this->validate('userRules')) { - return view('users/update', [ - 'errors' => $this->validator->getErrors() - ]); - } +If you find it simpler to keep the rules in the configuration file, you can replace +the ``$rules`` array with the name of the group as defined in ``Config\Validation.php``: - // do something here if successful... - } +.. literalinclude:: controllers/018.php + :lines: 2- .. note:: Validation can also be handled automatically in the model, but sometimes it's easier to do it in the controller. Where is up to you. @@ -401,25 +300,10 @@ $this->validateData() Sometimes you may want to check the controller method parameters or other custom data. In that case, you can use the ``$this->validateData()`` method. -The method accepts an array of data to validate in the first parameter:: - - public function product(int $id) - { - $data = [ - 'id' => $id, - 'name' => $this->request->getVar('name'), - ]; - $rule = [ - 'id' => 'integer', - 'name' => 'required|max_length[255]', - ]; - - if (! $this->validateData($data, $rule) { - // ... - } - - // ... - } +The method accepts an array of data to validate in the first parameter: + +.. literalinclude:: controllers/019.php + :lines: 2- That's it! ========== diff --git a/user_guide_src/source/incoming/controllers/001.php b/user_guide_src/source/incoming/controllers/001.php new file mode 100644 index 000000000000..926de1e9fbdf --- /dev/null +++ b/user_guide_src/source/incoming/controllers/001.php @@ -0,0 +1,11 @@ +(\)*\ + +$routes->get('helloworld', '\App\Controllers\HelloWorld::index'); diff --git a/user_guide_src/source/incoming/controllers/006.php b/user_guide_src/source/incoming/controllers/006.php new file mode 100644 index 000000000000..e43c3e4f2b34 --- /dev/null +++ b/user_guide_src/source/incoming/controllers/006.php @@ -0,0 +1,16 @@ +setDefaultController('Helloworld'); diff --git a/user_guide_src/source/incoming/controllers/009.php b/user_guide_src/source/incoming/controllers/009.php new file mode 100644 index 000000000000..d799d1cf0fb5 --- /dev/null +++ b/user_guide_src/source/incoming/controllers/009.php @@ -0,0 +1,3 @@ +get('/', 'Home::index'); diff --git a/user_guide_src/source/incoming/controllers/010.php b/user_guide_src/source/incoming/controllers/010.php new file mode 100644 index 000000000000..e017dcd45cdb --- /dev/null +++ b/user_guide_src/source/incoming/controllers/010.php @@ -0,0 +1,6 @@ +$method(); + } else { + return $this->default_method(); + } +} diff --git a/user_guide_src/source/incoming/controllers/012.php b/user_guide_src/source/incoming/controllers/012.php new file mode 100644 index 000000000000..25d064b859cd --- /dev/null +++ b/user_guide_src/source/incoming/controllers/012.php @@ -0,0 +1,12 @@ +$method(...$params); + } + + throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound(); +} diff --git a/user_guide_src/source/incoming/controllers/013.php b/user_guide_src/source/incoming/controllers/013.php new file mode 100644 index 000000000000..eed95b673ad2 --- /dev/null +++ b/user_guide_src/source/incoming/controllers/013.php @@ -0,0 +1,6 @@ +request->isSecure()) { + $this->forceHTTPS(); +} diff --git a/user_guide_src/source/incoming/controllers/015.php b/user_guide_src/source/incoming/controllers/015.php new file mode 100644 index 000000000000..c3309ddbf201 --- /dev/null +++ b/user_guide_src/source/incoming/controllers/015.php @@ -0,0 +1,5 @@ +request->isSecure()) { + $this->forceHTTPS(31536000); // one year +} diff --git a/user_guide_src/source/incoming/controllers/016.php b/user_guide_src/source/incoming/controllers/016.php new file mode 100644 index 000000000000..ff3ab9edfcf1 --- /dev/null +++ b/user_guide_src/source/incoming/controllers/016.php @@ -0,0 +1,8 @@ +validate([ + 'email' => "required|is_unique[users.email,id,{$userID}]", + 'name' => 'required|alpha_numeric_spaces' + ])) { + return view('users/update', [ + 'errors' => $this->validator->getErrors() + ]); + } + + // do something here if successful... +} diff --git a/user_guide_src/source/incoming/controllers/018.php b/user_guide_src/source/incoming/controllers/018.php new file mode 100644 index 000000000000..54697409827a --- /dev/null +++ b/user_guide_src/source/incoming/controllers/018.php @@ -0,0 +1,12 @@ +validate('userRules')) { + return view('users/update', [ + 'errors' => $this->validator->getErrors() + ]); + } + + // do something here if successful... +} diff --git a/user_guide_src/source/incoming/controllers/019.php b/user_guide_src/source/incoming/controllers/019.php new file mode 100644 index 000000000000..e5a96084c2c2 --- /dev/null +++ b/user_guide_src/source/incoming/controllers/019.php @@ -0,0 +1,19 @@ + $id, + 'name' => $this->request->getVar('name'), + ]; + $rule = [ + 'id' => 'integer', + 'name' => 'required|max_length[255]', + ]; + + if (! $this->validateData($data, $rule) { + // ... + } + + // ... +} \ No newline at end of file diff --git a/user_guide_src/source/incoming/filters.rst b/user_guide_src/source/incoming/filters.rst index 1b01d7c81e2e..df45851ea514 100644 --- a/user_guide_src/source/incoming/filters.rst +++ b/user_guide_src/source/incoming/filters.rst @@ -25,28 +25,9 @@ Creating a Filter Filters are simple classes that implement ``CodeIgniter\Filters\FilterInterface``. They contain two methods: ``before()`` and ``after()`` which hold the code that will run before and after the controller respectively. Your class must contain both methods -but may leave the methods empty if they are not needed. A skeleton filter class looks like:: +but may leave the methods empty if they are not needed. A skeleton filter class looks like: - isLoggedIn()) { - return redirect()->to(site_url('login')); - } - } +.. literalinclude:: filters/002.php + :lines: 2- If a ``Response`` instance is returned, the Response will be sent back to the client and script execution will stop. This can be useful for implementing rate limiting for APIs. See :doc:`Throttler ` for an @@ -102,24 +77,19 @@ $aliases ======== The ``$aliases`` array is used to associate a simple name with one or more fully-qualified class names that are the -filters to run:: +filters to run: - public $aliases = [ - 'csrf' => \CodeIgniter\Filters\CSRF::class, - ]; +.. literalinclude:: filters/003.php + :lines: 2- Aliases are mandatory and if you try to use a full class name later, the system will throw an error. Defining them in this way makes it simple to switch out the class used. Great for when you decided you need to change to a different authentication system since you only change the filter's class and you're done. -You can combine multiple filters into one alias, making complex sets of filters simple to apply:: +You can combine multiple filters into one alias, making complex sets of filters simple to apply: - public $aliases = [ - 'apiPrep' => [ - \App\Filters\Negotiate::class, - \App\Filters\ApiAuth::class, - ] - ]; +.. literalinclude:: filters/004.php + :lines: 2- You should define as many aliases as you need. @@ -128,50 +98,36 @@ $globals The second section allows you to define any filters that should be applied to every request made by the framework. You should take care with how many you use here, since it could have performance implications to have too many -run on every request. Filters can be specified by adding their alias to either the before or after array:: +run on every request. Filters can be specified by adding their alias to either the before or after array: - public $globals = [ - 'before' => [ - 'csrf', - ], - 'after' => [], - ]; +.. literalinclude:: filters/005.php + :lines: 2- There are times where you want to apply a filter to almost every request, but have a few that should be left alone. One common example is if you need to exclude a few URI's from the CSRF protection filter to allow requests from third-party websites to hit one or two specific URI's, while keeping the rest of them protected. To do this, add -an array with the 'except' key and a URI to match as the value alongside the alias:: +an array with the 'except' key and a URI to match as the value alongside the alias: - public $globals = [ - 'before' => [ - 'csrf' => ['except' => 'api/*'], - ], - 'after' => [], - ]; +.. literalinclude:: filters/006.php + :lines: 2- Any place you can use a URI in the filter settings, you can use a regular expression or, like in this example, use an asterisk for a wildcard that will match all characters after that. In this example, any URL's starting with ``api/`` would be exempted from CSRF protection, but the site's forms would all be protected. If you need to specify multiple -URI's you can use an array of URI patterns:: +URI's you can use an array of URI patterns: - public $globals = [ - 'before' => [ - 'csrf' => ['except' => ['foo/*', 'bar/*']], - ], - 'after' => [], - ]; +.. literalinclude:: filters/007.php + :lines: 2- $methods ======== You can apply filters to all requests of a certain HTTP method, like POST, GET, PUT, etc. In this array, you would specify the method name in lowercase. It's value would be an array of filters to run. Unlike the ``$globals`` or the -``$filters`` properties, these will only run as before filters:: +``$filters`` properties, these will only run as before filters: - public $methods = [ - 'post' => ['foo', 'bar'], - 'get' => ['baz'], - ] +.. literalinclude:: filters/008.php + :lines: 2- In addition to the standard HTTP methods, this also supports one special case: 'cli'. The 'cli' method would apply to all requests that were run from the command line. @@ -184,19 +140,18 @@ $filters ======== This property is an array of filter aliases. For each alias, you can specify before and after arrays that contain -a list of URI patterns that filter should apply to:: +a list of URI patterns that filter should apply to: - public filters = [ - 'foo' => ['before' => ['admin/*'], 'after' => ['users/*']], - 'bar' => ['before' => ['api/*', 'admin/*']], - ]; +.. literalinclude:: filters/009.php + :lines: 2- Filter arguments ================= -When configuring filters, additional arguments may be passed to a filter when setting up the route:: +When configuring filters, additional arguments may be passed to a filter when setting up the route: - $routes->add('users/delete/(:segment)', 'AdminController::index', ['filter' => 'admin-auth:dual,noreturn']); +.. literalinclude:: filters/010.php + :lines: 2- In this example, the array ``['dual', 'noreturn']`` will be passed in ``$arguments`` to the filter's ``before()`` and ``after()`` implementation methods. @@ -228,11 +183,9 @@ SecureHeaders This filter adds HTTP response headers that your application can use to increase the security of your application. -If you want to customize the headers, extend ``CodeIgniter\Filters\SecureHeaders`` and override the ``$headers`` property. And change the ``$aliases`` property in **app/Config/Filters.php**:: +If you want to customize the headers, extend ``CodeIgniter\Filters\SecureHeaders`` and override the ``$headers`` property. And change the ``$aliases`` property in **app/Config/Filters.php**: - public $aliases = [ - ... - 'secureheaders' => \App\Filters\SecureHeaders::class, - ]; +.. literalinclude:: filters/011.php + :lines: 2- If you want to know about secure headers, see `OWASP Secure Headers Project `_. diff --git a/user_guide_src/source/incoming/filters/001.php b/user_guide_src/source/incoming/filters/001.php new file mode 100644 index 000000000000..442cbadb89be --- /dev/null +++ b/user_guide_src/source/incoming/filters/001.php @@ -0,0 +1,20 @@ +isLoggedIn()) { + return redirect()->to(site_url('login')); + } +} diff --git a/user_guide_src/source/incoming/filters/003.php b/user_guide_src/source/incoming/filters/003.php new file mode 100644 index 000000000000..1ef6a461f3c6 --- /dev/null +++ b/user_guide_src/source/incoming/filters/003.php @@ -0,0 +1,5 @@ + \CodeIgniter\Filters\CSRF::class, +]; diff --git a/user_guide_src/source/incoming/filters/004.php b/user_guide_src/source/incoming/filters/004.php new file mode 100644 index 000000000000..a7f31363edad --- /dev/null +++ b/user_guide_src/source/incoming/filters/004.php @@ -0,0 +1,8 @@ + [ + \App\Filters\Negotiate::class, + \App\Filters\ApiAuth::class, + ] +]; diff --git a/user_guide_src/source/incoming/filters/005.php b/user_guide_src/source/incoming/filters/005.php new file mode 100644 index 000000000000..3f3801f5ce59 --- /dev/null +++ b/user_guide_src/source/incoming/filters/005.php @@ -0,0 +1,8 @@ + [ + 'csrf', + ], + 'after' => [], +]; diff --git a/user_guide_src/source/incoming/filters/006.php b/user_guide_src/source/incoming/filters/006.php new file mode 100644 index 000000000000..3706979688cd --- /dev/null +++ b/user_guide_src/source/incoming/filters/006.php @@ -0,0 +1,8 @@ + [ + 'csrf' => ['except' => 'api/*'], + ], + 'after' => [], +]; diff --git a/user_guide_src/source/incoming/filters/007.php b/user_guide_src/source/incoming/filters/007.php new file mode 100644 index 000000000000..a6790adbf9b7 --- /dev/null +++ b/user_guide_src/source/incoming/filters/007.php @@ -0,0 +1,8 @@ + [ + 'csrf' => ['except' => ['foo/*', 'bar/*']], + ], + 'after' => [], +]; diff --git a/user_guide_src/source/incoming/filters/008.php b/user_guide_src/source/incoming/filters/008.php new file mode 100644 index 000000000000..2f216281e982 --- /dev/null +++ b/user_guide_src/source/incoming/filters/008.php @@ -0,0 +1,6 @@ + ['foo', 'bar'], + 'get' => ['baz'], +] diff --git a/user_guide_src/source/incoming/filters/009.php b/user_guide_src/source/incoming/filters/009.php new file mode 100644 index 000000000000..258edd689d3c --- /dev/null +++ b/user_guide_src/source/incoming/filters/009.php @@ -0,0 +1,6 @@ + ['before' => ['admin/*'], 'after' => ['users/*']], + 'bar' => ['before' => ['api/*', 'admin/*']], +]; diff --git a/user_guide_src/source/incoming/filters/010.php b/user_guide_src/source/incoming/filters/010.php new file mode 100644 index 000000000000..7a486fb1d7c3 --- /dev/null +++ b/user_guide_src/source/incoming/filters/010.php @@ -0,0 +1,3 @@ +add('users/delete/(:segment)', 'AdminController::index', ['filter' => 'admin-auth:dual,noreturn']); diff --git a/user_guide_src/source/incoming/filters/011.php b/user_guide_src/source/incoming/filters/011.php new file mode 100644 index 000000000000..4065ef7d1743 --- /dev/null +++ b/user_guide_src/source/incoming/filters/011.php @@ -0,0 +1,6 @@ + \App\Filters\SecureHeaders::class, +]; diff --git a/user_guide_src/source/incoming/incomingrequest/001.php b/user_guide_src/source/incoming/incomingrequest/001.php new file mode 100644 index 000000000000..5513e012fb0e --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/001.php @@ -0,0 +1,15 @@ +request->isAJAX()) { + // ... + } + } +} diff --git a/user_guide_src/source/incoming/incomingrequest/002.php b/user_guide_src/source/incoming/incomingrequest/002.php new file mode 100644 index 000000000000..94d680abbdc3 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/002.php @@ -0,0 +1,3 @@ +request = $request; + } +} + +$someClass = new SomeClass(\Config\Services::request()); diff --git a/user_guide_src/source/incoming/incomingrequest/004.php b/user_guide_src/source/incoming/incomingrequest/004.php new file mode 100644 index 000000000000..9f54a85874cb --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/004.php @@ -0,0 +1,11 @@ +isAJAX()) { + // ... +} + +// Check for CLI Request +if ($request->isCLI()) { + // ... +} diff --git a/user_guide_src/source/incoming/incomingrequest/005.php b/user_guide_src/source/incoming/incomingrequest/005.php new file mode 100644 index 000000000000..3c93e74b7664 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/005.php @@ -0,0 +1,4 @@ +getMethod(); diff --git a/user_guide_src/source/incoming/incomingrequest/006.php b/user_guide_src/source/incoming/incomingrequest/006.php new file mode 100644 index 000000000000..99e269157152 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/006.php @@ -0,0 +1,4 @@ +getMethod()); diff --git a/user_guide_src/source/incoming/incomingrequest/007.php b/user_guide_src/source/incoming/incomingrequest/007.php new file mode 100644 index 000000000000..d2956fab66d4 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/007.php @@ -0,0 +1,5 @@ +isSecure()) { + force_https(); +} diff --git a/user_guide_src/source/incoming/incomingrequest/008.php b/user_guide_src/source/incoming/incomingrequest/008.php new file mode 100644 index 000000000000..1c7a14b45ed5 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/008.php @@ -0,0 +1,3 @@ +getVar('foo'); diff --git a/user_guide_src/source/incoming/incomingrequest/010.php b/user_guide_src/source/incoming/incomingrequest/010.php new file mode 100644 index 000000000000..f9c2c4a22fa1 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/010.php @@ -0,0 +1,3 @@ +getJSON(); diff --git a/user_guide_src/source/incoming/incomingrequest/011.php b/user_guide_src/source/incoming/incomingrequest/011.php new file mode 100644 index 000000000000..56f9522366b0 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/011.php @@ -0,0 +1,14 @@ +getVar('foo'); +// $data = "bar" + +$data = $request->getVar('fizz.buzz'); +// $data = "baz" diff --git a/user_guide_src/source/incoming/incomingrequest/012.php b/user_guide_src/source/incoming/incomingrequest/012.php new file mode 100644 index 000000000000..a4ca2686f6e8 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/012.php @@ -0,0 +1,8 @@ +getJsonVar('fizz'); +// $data->buzz = "baz" + +$data = $request->getJsonVar('fizz', true); +// $data = ["buzz" => "baz"] diff --git a/user_guide_src/source/incoming/incomingrequest/013.php b/user_guide_src/source/incoming/incomingrequest/013.php new file mode 100644 index 000000000000..8a46e0d01114 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/013.php @@ -0,0 +1,3 @@ +getRawInput(); diff --git a/user_guide_src/source/incoming/incomingrequest/014.php b/user_guide_src/source/incoming/incomingrequest/014.php new file mode 100644 index 000000000000..2b5ffb8498e0 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/014.php @@ -0,0 +1,8 @@ +getRawInput()); + +[ + 'Param1' => 'Value1', + 'Param2' => 'Value2' +] diff --git a/user_guide_src/source/incoming/incomingrequest/015.php b/user_guide_src/source/incoming/incomingrequest/015.php new file mode 100644 index 000000000000..564fc543143b --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/015.php @@ -0,0 +1,3 @@ +getVar('email', FILTER_SANITIZE_EMAIL); diff --git a/user_guide_src/source/incoming/incomingrequest/016.php b/user_guide_src/source/incoming/incomingrequest/016.php new file mode 100644 index 000000000000..1584967d3bd8 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/016.php @@ -0,0 +1,9 @@ +headers()); + +[ + 'Host' => CodeIgniter\HTTP\Header, + 'Cache-Control' => CodeIgniter\HTTP\Header, + 'Accept' => CodeIgniter\HTTP\Header, +] diff --git a/user_guide_src/source/incoming/incomingrequest/017.php b/user_guide_src/source/incoming/incomingrequest/017.php new file mode 100644 index 000000000000..3fd3b6d81ff2 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/017.php @@ -0,0 +1,6 @@ +header('host'); +$host = $request->header('Host'); +$host = $request->header('HOST'); diff --git a/user_guide_src/source/incoming/incomingrequest/018.php b/user_guide_src/source/incoming/incomingrequest/018.php new file mode 100644 index 000000000000..a557845e482e --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/018.php @@ -0,0 +1,5 @@ +hasHeader('DNT')) { + // Don't track something... +} diff --git a/user_guide_src/source/incoming/incomingrequest/019.php b/user_guide_src/source/incoming/incomingrequest/019.php new file mode 100644 index 000000000000..80243598d821 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/019.php @@ -0,0 +1,4 @@ +getHeaderLine('accept-encoding'); diff --git a/user_guide_src/source/incoming/incomingrequest/020.php b/user_guide_src/source/incoming/incomingrequest/020.php new file mode 100644 index 000000000000..14e917083397 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/020.php @@ -0,0 +1,3 @@ +getUri(); diff --git a/user_guide_src/source/incoming/incomingrequest/022.php b/user_guide_src/source/incoming/incomingrequest/022.php new file mode 100644 index 000000000000..672efa42b02e --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/022.php @@ -0,0 +1,14 @@ +getUri(); + +echo $uri->getScheme(); // http +echo $uri->getAuthority(); // snoopy:password@example.com:88 +echo $uri->getUserInfo(); // snoopy:password +echo $uri->getHost(); // example.com +echo $uri->getPort(); // 88 +echo $uri->getPath(); // /path/to/page +echo $uri->getQuery(); // foo=bar&bar=baz +echo $uri->getSegments(); // ['path', 'to', 'page'] +echo $uri->getSegment(1); // 'path' +echo $uri->getTotalSegments(); // 3 diff --git a/user_guide_src/source/incoming/incomingrequest/023.php b/user_guide_src/source/incoming/incomingrequest/023.php new file mode 100644 index 000000000000..55484f98a10b --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/023.php @@ -0,0 +1,11 @@ +setPath('users/list'); + $menu = new MyMenu(); + $this->assertTrue('users/list', $menu->getActiveLink()); + } +} diff --git a/user_guide_src/source/incoming/incomingrequest/024.php b/user_guide_src/source/incoming/incomingrequest/024.php new file mode 100644 index 000000000000..e29f87b9f419 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/024.php @@ -0,0 +1,18 @@ +getFiles(); + +// Grab the file by name given in HTML form +if ($files->hasFile('userfile')) { + $file = $files->getFile('userfile'); + + // Generate a new secure name + $name = $file->getRandomName(); + + // Move the file to it's new home + $file->move('/path/to/dir', $name); + + echo $file->getSize('mb'); // 1.23 + echo $file->getExtension(); // jpg + echo $file->getType(); // image/jpg +} diff --git a/user_guide_src/source/incoming/incomingrequest/025.php b/user_guide_src/source/incoming/incomingrequest/025.php new file mode 100644 index 000000000000..cfa3525255ae --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/025.php @@ -0,0 +1,3 @@ +getFile('userfile'); diff --git a/user_guide_src/source/incoming/incomingrequest/026.php b/user_guide_src/source/incoming/incomingrequest/026.php new file mode 100644 index 000000000000..912a709d2729 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/026.php @@ -0,0 +1,3 @@ +getFileMultiple('userfile'); diff --git a/user_guide_src/source/incoming/incomingrequest/027.php b/user_guide_src/source/incoming/incomingrequest/027.php new file mode 100644 index 000000000000..f5d9b96f3315 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/027.php @@ -0,0 +1,7 @@ +negotiate('language', ['en-US', 'en-GB', 'fr', 'es-mx']); +$imageType = $request->negotiate('media', ['image/png', 'image/jpg']); +$charset = $request->negotiate('charset', ['UTF-8', 'UTF-16']); +$contentType = $request->negotiate('media', ['text/html', 'text/xml']); +$encoding = $request->negotiate('encoding', ['gzip', 'compress']); diff --git a/user_guide_src/source/incoming/incomingrequest/028.php b/user_guide_src/source/incoming/incomingrequest/028.php new file mode 100644 index 000000000000..aa4f01787b4b --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/028.php @@ -0,0 +1,3 @@ +getVar('some_data'); diff --git a/user_guide_src/source/incoming/incomingrequest/029.php b/user_guide_src/source/incoming/incomingrequest/029.php new file mode 100644 index 000000000000..3bc49822b301 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/029.php @@ -0,0 +1,3 @@ +getVar('some_data', FILTER_SANITIZE_FULL_SPECIAL_CHARS); diff --git a/user_guide_src/source/incoming/incomingrequest/030.php b/user_guide_src/source/incoming/incomingrequest/030.php new file mode 100644 index 000000000000..62390522b9b6 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/030.php @@ -0,0 +1,4 @@ +getVar(null, FILTER_SANITIZE_FULL_SPECIAL_CHARS); +// returns all POST items with string sanitation diff --git a/user_guide_src/source/incoming/incomingrequest/031.php b/user_guide_src/source/incoming/incomingrequest/031.php new file mode 100644 index 000000000000..9e555a2f3143 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/031.php @@ -0,0 +1,3 @@ +getVar(['field1', 'field2']); diff --git a/user_guide_src/source/incoming/incomingrequest/032.php b/user_guide_src/source/incoming/incomingrequest/032.php new file mode 100644 index 000000000000..98c6f35e367d --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/032.php @@ -0,0 +1,3 @@ +getVar(['field1', 'field2'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); diff --git a/user_guide_src/source/incoming/incomingrequest/033.php b/user_guide_src/source/incoming/incomingrequest/033.php new file mode 100644 index 000000000000..27d669d99406 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/033.php @@ -0,0 +1,3 @@ +getPostGet('field1'); diff --git a/user_guide_src/source/incoming/incomingrequest/034.php b/user_guide_src/source/incoming/incomingrequest/034.php new file mode 100644 index 000000000000..837ca9c26b40 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/034.php @@ -0,0 +1,3 @@ +getGetPost('field1'); diff --git a/user_guide_src/source/incoming/incomingrequest/035.php b/user_guide_src/source/incoming/incomingrequest/035.php new file mode 100644 index 000000000000..befc56fd551f --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/035.php @@ -0,0 +1,4 @@ +getCookie('some_cookie'); +$request->getCookie('some_cookie', FILTER_SANITIZE_FULL_SPECIAL_CHARS); // with filter diff --git a/user_guide_src/source/incoming/incomingrequest/036.php b/user_guide_src/source/incoming/incomingrequest/036.php new file mode 100644 index 000000000000..e0c3b50803d6 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/036.php @@ -0,0 +1,3 @@ +getCookie(['some_cookie', 'some_cookie2']); diff --git a/user_guide_src/source/incoming/incomingrequest/037.php b/user_guide_src/source/incoming/incomingrequest/037.php new file mode 100644 index 000000000000..e05381317b95 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/037.php @@ -0,0 +1,3 @@ +getServer('some_data'); diff --git a/user_guide_src/source/incoming/incomingrequest/038.php b/user_guide_src/source/incoming/incomingrequest/038.php new file mode 100644 index 000000000000..0dabcaa7d528 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/038.php @@ -0,0 +1,3 @@ +getServer(['SERVER_PROTOCOL', 'REQUEST_URI']); diff --git a/user_guide_src/source/incoming/incomingrequest/039.php b/user_guide_src/source/incoming/incomingrequest/039.php new file mode 100644 index 000000000000..bbb5fcc909e7 --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/039.php @@ -0,0 +1,3 @@ +getUserAgent(); diff --git a/user_guide_src/source/incoming/message.rst b/user_guide_src/source/incoming/message.rst index e5f5a49ab4af..8333a51d7157 100644 --- a/user_guide_src/source/incoming/message.rst +++ b/user_guide_src/source/incoming/message.rst @@ -41,9 +41,10 @@ Class Reference :returns: The current message body :rtype: mixed - Returns the current message body, if any has been set. If not body exists, returns null:: + Returns the current message body, if any has been set. If not body exists, returns null: - echo $message->getBody(); + .. literalinclude:: message/001.php + :lines: 2- .. php:method:: setBody($data) @@ -88,37 +89,21 @@ Class Reference :rtype: \CodeIgniter\\HTTP\\Header|array Allows you to retrieve the current value of a single message header. ``$name`` is the case-insensitive header name. - While the header is converted internally as described above, you can access the header with any type of case:: + While the header is converted internally as described above, you can access the header with any type of case: - // These are all the same: - $message->header('HOST'); - $message->header('Host'); - $message->header('host'); + .. literalinclude:: message/002.php + :lines: 2- If the header has multiple values, ``getValue()`` will return as an array of values. You can use the ``getValueLine()`` - method to retrieve the values as a string:: + method to retrieve the values as a string: - echo $message->header('Accept-Language'); + .. literalinclude:: message/003.php + :lines: 2- - // Outputs something like: - 'Accept-Language: en,en-US' + You can filter the header by passing a filter value in as the second parameter: - echo $message->header('Accept-Language')->getValue(); - - // Outputs something like: - [ - 'en', - 'en-US' - ] - - echo $message->header('Accept-Language')->getValueLine(); - - // Outputs something like: - 'en,en-US' - - You can filter the header by passing a filter value in as the second parameter:: - - $message->header('Document-URI', FILTER_SANITIZE_URL); + .. literalinclude:: message/004.php + :lines: 2- .. php:method:: hasHeader($name) @@ -133,12 +118,10 @@ Class Reference :rtype: string Returns the value(s) of the header as a string. This method allows you to easily get a string representation - of the header values when the header has multiple values. The values are appropriately joined:: - - echo $message->getHeaderLine('Accept-Language'); + of the header values when the header has multiple values. The values are appropriately joined: - // Outputs: - en, en-US + .. literalinclude:: message/005.php + :lines: 2- .. php:method:: setHeader($name, $value) @@ -149,9 +132,10 @@ Class Reference Sets the value of a single header. ``$name`` is the case-insensitive name of the header. If the header doesn't already exist in the collection, it will be created. The ``$value`` can be either a string - or an array of strings:: + or an array of strings: - $message->setHeader('Host', 'codeigniter.com'); + .. literalinclude:: message/006.php + :lines: 2- .. php:method:: removeHeader($name) @@ -159,9 +143,10 @@ Class Reference :returns: The current message instance :rtype: CodeIgniter\\HTTP\\Message - Removes the header from the Message. ``$name`` is the case-insensitive name of the header:: + Removes the header from the Message. ``$name`` is the case-insensitive name of the header: - $message->removeHeader('Host'); + .. literalinclude:: message/007.php + :lines: 2- .. php:method:: appendHeader($name, $value) @@ -172,9 +157,9 @@ Class Reference Adds a value to an existing header. The header must already be an array of values instead of a single string. If it is a string then a LogicException will be thrown. - :: - $message->appendHeader('Accept-Language', 'en-US; q=0.8'); + .. literalinclude:: message/008.php + :lines: 2- .. php:method:: prependHeader($name, $value) @@ -185,9 +170,9 @@ Class Reference Prepends a value to an existing header. The header must already be an array of values instead of a single string. If it is a string then a LogicException will be thrown. - :: - $message->prependHeader('Accept-Language', 'en,'); + .. literalinclude:: message/009.php + :lines: 2- .. php:method:: getProtocolVersion() @@ -203,6 +188,7 @@ Class Reference :returns: The current message instance :rtype: CodeIgniter\\HTTP\\Message - Sets the HTTP protocol version this Message uses. Valid values are ``1.0``, ``1.1`` and ``2.0``:: + Sets the HTTP protocol version this Message uses. Valid values are ``1.0``, ``1.1`` and ``2.0``: - $message->setProtocolVersion('1.1'); + .. literalinclude:: message/010.php + :lines: 2- diff --git a/user_guide_src/source/incoming/message/001.php b/user_guide_src/source/incoming/message/001.php new file mode 100644 index 000000000000..a54dc3212036 --- /dev/null +++ b/user_guide_src/source/incoming/message/001.php @@ -0,0 +1,3 @@ +getBody(); diff --git a/user_guide_src/source/incoming/message/002.php b/user_guide_src/source/incoming/message/002.php new file mode 100644 index 000000000000..0a55ae7824a9 --- /dev/null +++ b/user_guide_src/source/incoming/message/002.php @@ -0,0 +1,6 @@ +header('HOST'); +$message->header('Host'); +$message->header('host'); diff --git a/user_guide_src/source/incoming/message/003.php b/user_guide_src/source/incoming/message/003.php new file mode 100644 index 000000000000..3ef7db58835a --- /dev/null +++ b/user_guide_src/source/incoming/message/003.php @@ -0,0 +1,19 @@ +header('Accept-Language'); + +// Outputs something like: +'Accept-Language: en,en-US' + +echo $message->header('Accept-Language')->getValue(); + +// Outputs something like: +[ + 'en', + 'en-US' +] + +echo $message->header('Accept-Language')->getValueLine(); + +// Outputs something like: +'en,en-US' diff --git a/user_guide_src/source/incoming/message/004.php b/user_guide_src/source/incoming/message/004.php new file mode 100644 index 000000000000..534bbcf93349 --- /dev/null +++ b/user_guide_src/source/incoming/message/004.php @@ -0,0 +1,3 @@ +header('Document-URI', FILTER_SANITIZE_URL); diff --git a/user_guide_src/source/incoming/message/005.php b/user_guide_src/source/incoming/message/005.php new file mode 100644 index 000000000000..dd643a1250e4 --- /dev/null +++ b/user_guide_src/source/incoming/message/005.php @@ -0,0 +1,6 @@ +getHeaderLine('Accept-Language'); + +// Outputs: +en, en-US diff --git a/user_guide_src/source/incoming/message/006.php b/user_guide_src/source/incoming/message/006.php new file mode 100644 index 000000000000..74f6cde18eb0 --- /dev/null +++ b/user_guide_src/source/incoming/message/006.php @@ -0,0 +1,3 @@ +setHeader('Host', 'codeigniter.com'); diff --git a/user_guide_src/source/incoming/message/007.php b/user_guide_src/source/incoming/message/007.php new file mode 100644 index 000000000000..bd7a4f9052ce --- /dev/null +++ b/user_guide_src/source/incoming/message/007.php @@ -0,0 +1,3 @@ +removeHeader('Host'); diff --git a/user_guide_src/source/incoming/message/008.php b/user_guide_src/source/incoming/message/008.php new file mode 100644 index 000000000000..e14ed62b3636 --- /dev/null +++ b/user_guide_src/source/incoming/message/008.php @@ -0,0 +1,3 @@ +appendHeader('Accept-Language', 'en-US; q=0.8'); diff --git a/user_guide_src/source/incoming/message/009.php b/user_guide_src/source/incoming/message/009.php new file mode 100644 index 000000000000..c6cdd1ca6d05 --- /dev/null +++ b/user_guide_src/source/incoming/message/009.php @@ -0,0 +1,3 @@ +prependHeader('Accept-Language', 'en,'); diff --git a/user_guide_src/source/incoming/message/010.php b/user_guide_src/source/incoming/message/010.php new file mode 100644 index 000000000000..b5e056ab447d --- /dev/null +++ b/user_guide_src/source/incoming/message/010.php @@ -0,0 +1,3 @@ +setProtocolVersion('1.1'); diff --git a/user_guide_src/source/incoming/request.rst b/user_guide_src/source/incoming/request.rst index 109c22a7bd7e..d5af007b40bd 100644 --- a/user_guide_src/source/incoming/request.rst +++ b/user_guide_src/source/incoming/request.rst @@ -22,9 +22,10 @@ Class Reference :rtype: string Returns the IP address for the current user. If the IP address is not valid, the method - will return '0.0.0.0':: + will return '0.0.0.0': - echo $request->getIPAddress(); + .. literalinclude:: request/001.php + :lines: 2- .. important:: This method takes into account the ``App->proxyIPs`` setting and will return the reported HTTP_X_FORWARDED_FOR, HTTP_CLIENT_IP, HTTP_X_CLIENT_IP, or @@ -44,13 +45,8 @@ Class Reference .. note:: The $request->getIPAddress() method above automatically validates the IP address. - :: - - if (! $request->isValidIP($ip)) { - echo 'Not Valid'; - } else { - echo 'Valid'; - } + .. literalinclude:: request/002.php + :lines: 2- Accepts an optional second string parameter of 'ipv4' or 'ipv6' to specify an IP format. The default checks for both formats. @@ -65,11 +61,9 @@ Class Reference Returns the ``$_SERVER['REQUEST_METHOD']``, with the option to set it in uppercase or lowercase. - :: - echo $request->getMethod(true); // Outputs: POST - echo $request->getMethod(false); // Outputs: post - echo $request->getMethod(); // Outputs: post + .. literalinclude:: request/003.php + :lines: 2- .. php:method:: setMethod($method) @@ -86,15 +80,16 @@ Class Reference :rtype: mixed This method is identical to the ``post()``, ``get()`` and ``cookie()`` methods from the - :doc:`IncomingRequest Class `, only it fetches server data (``$_SERVER``):: + :doc:`IncomingRequest Class `, only it fetches server data (``$_SERVER``): - $request->getServer('some_data'); + .. literalinclude:: request/004.php + :lines: 2- To return an array of multiple ``$_SERVER`` values, pass all the required keys as an array. - :: - $require->getServer(['SERVER_PROTOCOL', 'REQUEST_URI']); + .. literalinclude:: request/005.php + :lines: 2- .. php:method:: getEnv([$index = null[, $filter = null[, $flags = null]]]) @@ -105,15 +100,16 @@ Class Reference :rtype: mixed This method is identical to the ``post()``, ``get()`` and ``cookie()`` methods from the - :doc:`IncomingRequest Class `, only it fetches getEnv data (``$_ENV``):: + :doc:`IncomingRequest Class `, only it fetches getEnv data (``$_ENV``): - $request->getEnv('some_data'); + .. literalinclude:: request/006.php + :lines: 2- To return an array of multiple ``$_ENV`` values, pass all the required keys as an array. - :: - $require->getEnv(['CI_ENVIRONMENT', 'S3_BUCKET']); + .. literalinclude:: request/007.php + :lines: 2- .. php:method:: setGlobal($method, $value) diff --git a/user_guide_src/source/incoming/request/001.php b/user_guide_src/source/incoming/request/001.php new file mode 100644 index 000000000000..09c19433908f --- /dev/null +++ b/user_guide_src/source/incoming/request/001.php @@ -0,0 +1,3 @@ +getIPAddress(); diff --git a/user_guide_src/source/incoming/request/002.php b/user_guide_src/source/incoming/request/002.php new file mode 100644 index 000000000000..4b2e39489f72 --- /dev/null +++ b/user_guide_src/source/incoming/request/002.php @@ -0,0 +1,7 @@ +isValidIP($ip)) { + echo 'Not Valid'; +} else { + echo 'Valid'; +} diff --git a/user_guide_src/source/incoming/request/003.php b/user_guide_src/source/incoming/request/003.php new file mode 100644 index 000000000000..fbfda408e272 --- /dev/null +++ b/user_guide_src/source/incoming/request/003.php @@ -0,0 +1,5 @@ +getMethod(true); // Outputs: POST +echo $request->getMethod(false); // Outputs: post +echo $request->getMethod(); // Outputs: post diff --git a/user_guide_src/source/incoming/request/004.php b/user_guide_src/source/incoming/request/004.php new file mode 100644 index 000000000000..e05381317b95 --- /dev/null +++ b/user_guide_src/source/incoming/request/004.php @@ -0,0 +1,3 @@ +getServer('some_data'); diff --git a/user_guide_src/source/incoming/request/005.php b/user_guide_src/source/incoming/request/005.php new file mode 100644 index 000000000000..ba2c43023c92 --- /dev/null +++ b/user_guide_src/source/incoming/request/005.php @@ -0,0 +1,3 @@ +getServer(['SERVER_PROTOCOL', 'REQUEST_URI']); diff --git a/user_guide_src/source/incoming/request/006.php b/user_guide_src/source/incoming/request/006.php new file mode 100644 index 000000000000..b503574b79cc --- /dev/null +++ b/user_guide_src/source/incoming/request/006.php @@ -0,0 +1,3 @@ +getEnv('some_data'); diff --git a/user_guide_src/source/incoming/request/007.php b/user_guide_src/source/incoming/request/007.php new file mode 100644 index 000000000000..95952d206a44 --- /dev/null +++ b/user_guide_src/source/incoming/request/007.php @@ -0,0 +1,3 @@ +getEnv(['CI_ENVIRONMENT', 'S3_BUCKET']); diff --git a/user_guide_src/source/incoming/restful.rst b/user_guide_src/source/incoming/restful.rst index 8992221590a0..93d31a76e957 100644 --- a/user_guide_src/source/incoming/restful.rst +++ b/user_guide_src/source/incoming/restful.rst @@ -28,19 +28,10 @@ Resource Routes You can quickly create a handful of RESTful routes for a single resource with the ``resource()`` method. This creates the five most common routes needed for full CRUD of a resource: create a new resource, update an existing one, list all of that resource, show a single resource, and delete a single resource. The first parameter is the resource -name:: +name: - $routes->resource('photos'); - - // Equivalent to the following: - $routes->get('photos/new', 'Photos::new'); - $routes->post('photos', 'Photos::create'); - $routes->get('photos', 'Photos::index'); - $routes->get('photos/(:segment)', 'Photos::show/$1'); - $routes->get('photos/(:segment)/edit', 'Photos::edit/$1'); - $routes->put('photos/(:segment)', 'Photos::update/$1'); - $routes->patch('photos/(:segment)', 'Photos::update/$1'); - $routes->delete('photos/(:segment)', 'Photos::delete/$1'); +.. literalinclude:: restful/001.php + :lines: 2- .. note:: The ordering above is for clarity, whereas the actual order the routes are created in, in RouteCollection, ensures proper route resolution @@ -48,47 +39,42 @@ name:: The second parameter accepts an array of options that can be used to modify the routes that are generated. While these routes are geared toward API-usage, where more methods are allowed, you can pass in the ``websafe`` option to have it -generate update and delete methods that work with HTML forms:: - - $routes->resource('photos', ['websafe' => 1]); +generate update and delete methods that work with HTML forms: - // The following equivalent routes are created: - $routes->post('photos/(:segment)/delete', 'Photos::delete/$1'); - $routes->post('photos/(:segment)', 'Photos::update/$1'); +.. literalinclude:: restful/002.php + :lines: 2- Change the Controller Used -------------------------- You can specify the controller that should be used by passing in the ``controller`` option with the name of -the controller that should be used:: - - $routes->resource('photos', ['controller' =>'App\Gallery']); +the controller that should be used: - // Would create routes like: - $routes->get('photos', 'App\Gallery::index'); +.. literalinclude:: restful/003.php + :lines: 2- Change the Placeholder Used --------------------------- By default, the ``(:segment)`` placeholder is used when a resource ID is needed. You can change this by passing -in the ``placeholder`` option with the new string to use:: +in the ``placeholder`` option with the new string to use: - $routes->resource('photos', ['placeholder' => '(:num)']); - - // Generates routes like: - $routes->get('photos/(:num)', 'Photos::show/$1'); +.. literalinclude:: restful/004.php + :lines: 2- Limit the Routes Made --------------------- You can restrict the routes generated with the ``only`` option. This should be **an array** or **comma separated list** of method names that should -be created. Only routes that match one of these methods will be created. The rest will be ignored:: +be created. Only routes that match one of these methods will be created. The rest will be ignored: - $routes->resource('photos', ['only' => ['index', 'show']]); +.. literalinclude:: restful/005.php + :lines: 2- -Otherwise you can remove unused routes with the ``except`` option. This should also be **an array** or **comma separated list** of method names. This option run after ``only``:: +Otherwise you can remove unused routes with the ``except`` option. This should also be **an array** or **comma separated list** of method names. This option run after ``only``: - $routes->resource('photos', ['except' => 'new,edit']); +.. literalinclude:: restful/006.php + :lines: 2- Valid methods are: ``index``, ``show``, ``create``, ``update``, ``new``, ``edit`` and ``delete``. @@ -99,30 +85,14 @@ The ``ResourceController`` provides a convenient starting point for your RESTful with methods that correspond to the resource routes above. Extend it, over-riding the ``modelName`` and ``format`` properties, and then -implement those methods that you want handled.:: - - respond($this->model->findAll()); - } - - // ... - } - -The routing for this would be:: - - $routes->resource('photos'); +.. literalinclude:: restful/008.php + :lines: 2- Presenter Routes ============================================================ @@ -134,30 +104,18 @@ for your resource, or process forms submitted from those views. It is not needed, since the presentation can be handled with a conventional controller - it is a convenience. -Its usage is similar to the resource routing:: - - $routes->presenter('photos'); - - // Equivalent to the following: - $routes->get('photos/new', 'Photos::new'); - $routes->post('photos/create', 'Photos::create'); - $routes->post('photos', 'Photos::create'); // alias - $routes->get('photos', 'Photos::index'); - $routes->get('photos/show/(:segment)', 'Photos::show/$1'); - $routes->get('photos/(:segment)', 'Photos::show/$1'); // alias - $routes->get('photos/edit/(:segment)', 'Photos::edit/$1'); - $routes->post('photos/update/(:segment)', 'Photos::update/$1'); - $routes->get('photos/remove/(:segment)', 'Photos::remove/$1'); - $routes->post('photos/delete/(:segment)', 'Photos::delete/$1'); +Its usage is similar to the resource routing: + +.. literalinclude:: restful/009.php + :lines: 2- .. note:: The ordering above is for clarity, whereas the actual order the routes are created in, in RouteCollection, ensures proper route resolution You would not have routes for `photos` for both a resource and a presenter -controller. You need to distinguish them, for instance:: - - $routes->resource('api/photo'); - $routes->presenter('admin/photos'); +controller. You need to distinguish them, for instance: +.. literalinclude:: restful/010.php + :lines: 2- The second parameter accepts an array of options that can be used to modify the routes that are generated. @@ -165,35 +123,33 @@ Change the Controller Used -------------------------- You can specify the controller that should be used by passing in the ``controller`` option with the name of -the controller that should be used:: - - $routes->presenter('photos', ['controller' =>'App\Gallery']); +the controller that should be used: - // Would create routes like: - $routes->get('photos', 'App\Gallery::index'); +.. literalinclude:: restful/011.php + :lines: 2- Change the Placeholder Used --------------------------- By default, the ``(:segment)`` placeholder is used when a resource ID is needed. You can change this by passing -in the ``placeholder`` option with the new string to use:: - - $routes->presenter('photos', ['placeholder' => '(:num)']); +in the ``placeholder`` option with the new string to use: - // Generates routes like: - $routes->get('photos/(:num)', 'Photos::show/$1'); +.. literalinclude:: restful/012.php + :lines: 2- Limit the Routes Made --------------------- You can restrict the routes generated with the ``only`` option. This should be **an array** or **comma separated list** of method names that should -be created. Only routes that match one of these methods will be created. The rest will be ignored:: +be created. Only routes that match one of these methods will be created. The rest will be ignored: - $routes->presenter('photos', ['only' => ['index', 'show']]); +.. literalinclude:: restful/013.php + :lines: 2- -Otherwise you can remove unused routes with the ``except`` option. This should also be **an array** or **comma separated list** of method names. This option run after ``only``:: +Otherwise you can remove unused routes with the ``except`` option. This should also be **an array** or **comma separated list** of method names. This option run after ``only``: - $routes->presenter('photos', ['except' => 'new,edit']); +.. literalinclude:: restful/014.php + :lines: 2- Valid methods are: ``index``, ``show``, ``new``, ``create``, ``edit``, ``update``, ``remove`` and ``delete``. @@ -205,30 +161,14 @@ of your resource, and processing data from forms in those views, with methods that align to the resource routes above. Extend it, over-riding the ``modelName`` property, and then -implement those methods that you want handled.:: - - model->findAll()); - } +implement those methods that you want handled.: - // ... - } +.. literalinclude:: restful/015.php -The routing for this would be:: +The routing for this would be: - $routes->presenter('photos'); +.. literalinclude:: restful/016.php + :lines: 2- Presenter/Controller Comparison ============================================================= diff --git a/user_guide_src/source/incoming/restful/001.php b/user_guide_src/source/incoming/restful/001.php new file mode 100644 index 000000000000..4a3ee8133b7d --- /dev/null +++ b/user_guide_src/source/incoming/restful/001.php @@ -0,0 +1,13 @@ +resource('photos'); + +// Equivalent to the following: +$routes->get('photos/new', 'Photos::new'); +$routes->post('photos', 'Photos::create'); +$routes->get('photos', 'Photos::index'); +$routes->get('photos/(:segment)', 'Photos::show/$1'); +$routes->get('photos/(:segment)/edit', 'Photos::edit/$1'); +$routes->put('photos/(:segment)', 'Photos::update/$1'); +$routes->patch('photos/(:segment)', 'Photos::update/$1'); +$routes->delete('photos/(:segment)', 'Photos::delete/$1'); diff --git a/user_guide_src/source/incoming/restful/002.php b/user_guide_src/source/incoming/restful/002.php new file mode 100644 index 000000000000..cc879a2ab667 --- /dev/null +++ b/user_guide_src/source/incoming/restful/002.php @@ -0,0 +1,7 @@ +resource('photos', ['websafe' => 1]); + +// The following equivalent routes are created: +$routes->post('photos/(:segment)/delete', 'Photos::delete/$1'); +$routes->post('photos/(:segment)', 'Photos::update/$1'); diff --git a/user_guide_src/source/incoming/restful/003.php b/user_guide_src/source/incoming/restful/003.php new file mode 100644 index 000000000000..1485f3c4edea --- /dev/null +++ b/user_guide_src/source/incoming/restful/003.php @@ -0,0 +1,6 @@ +resource('photos', ['controller' =>'App\Gallery']); + +// Would create routes like: +$routes->get('photos', 'App\Gallery::index'); diff --git a/user_guide_src/source/incoming/restful/004.php b/user_guide_src/source/incoming/restful/004.php new file mode 100644 index 000000000000..540fbb84aeed --- /dev/null +++ b/user_guide_src/source/incoming/restful/004.php @@ -0,0 +1,6 @@ +resource('photos', ['placeholder' => '(:num)']); + +// Generates routes like: +$routes->get('photos/(:num)', 'Photos::show/$1'); diff --git a/user_guide_src/source/incoming/restful/005.php b/user_guide_src/source/incoming/restful/005.php new file mode 100644 index 000000000000..4ac8480f8ca2 --- /dev/null +++ b/user_guide_src/source/incoming/restful/005.php @@ -0,0 +1,3 @@ +resource('photos', ['only' => ['index', 'show']]); diff --git a/user_guide_src/source/incoming/restful/006.php b/user_guide_src/source/incoming/restful/006.php new file mode 100644 index 000000000000..a1a98809adc1 --- /dev/null +++ b/user_guide_src/source/incoming/restful/006.php @@ -0,0 +1,3 @@ +resource('photos', ['except' => 'new,edit']); diff --git a/user_guide_src/source/incoming/restful/007.php b/user_guide_src/source/incoming/restful/007.php new file mode 100644 index 000000000000..930c61f28e8c --- /dev/null +++ b/user_guide_src/source/incoming/restful/007.php @@ -0,0 +1,18 @@ +respond($this->model->findAll()); + } + + // ... +} diff --git a/user_guide_src/source/incoming/restful/008.php b/user_guide_src/source/incoming/restful/008.php new file mode 100644 index 000000000000..d1a6c08dd03c --- /dev/null +++ b/user_guide_src/source/incoming/restful/008.php @@ -0,0 +1,3 @@ +resource('photos'); diff --git a/user_guide_src/source/incoming/restful/009.php b/user_guide_src/source/incoming/restful/009.php new file mode 100644 index 000000000000..5918a044fab5 --- /dev/null +++ b/user_guide_src/source/incoming/restful/009.php @@ -0,0 +1,15 @@ +presenter('photos'); + +// Equivalent to the following: +$routes->get('photos/new', 'Photos::new'); +$routes->post('photos/create', 'Photos::create'); +$routes->post('photos', 'Photos::create'); // alias +$routes->get('photos', 'Photos::index'); +$routes->get('photos/show/(:segment)', 'Photos::show/$1'); +$routes->get('photos/(:segment)', 'Photos::show/$1'); // alias +$routes->get('photos/edit/(:segment)', 'Photos::edit/$1'); +$routes->post('photos/update/(:segment)', 'Photos::update/$1'); +$routes->get('photos/remove/(:segment)', 'Photos::remove/$1'); +$routes->post('photos/delete/(:segment)', 'Photos::delete/$1'); diff --git a/user_guide_src/source/incoming/restful/010.php b/user_guide_src/source/incoming/restful/010.php new file mode 100644 index 000000000000..b36c7ed8973e --- /dev/null +++ b/user_guide_src/source/incoming/restful/010.php @@ -0,0 +1,4 @@ +resource('api/photo'); +$routes->presenter('admin/photos'); diff --git a/user_guide_src/source/incoming/restful/011.php b/user_guide_src/source/incoming/restful/011.php new file mode 100644 index 000000000000..5c949d80cc29 --- /dev/null +++ b/user_guide_src/source/incoming/restful/011.php @@ -0,0 +1,6 @@ +presenter('photos', ['controller' =>'App\Gallery']); + +// Would create routes like: +$routes->get('photos', 'App\Gallery::index'); diff --git a/user_guide_src/source/incoming/restful/012.php b/user_guide_src/source/incoming/restful/012.php new file mode 100644 index 000000000000..0bd42b5120f0 --- /dev/null +++ b/user_guide_src/source/incoming/restful/012.php @@ -0,0 +1,6 @@ +presenter('photos', ['placeholder' => '(:num)']); + +// Generates routes like: +$routes->get('photos/(:num)', 'Photos::show/$1'); diff --git a/user_guide_src/source/incoming/restful/013.php b/user_guide_src/source/incoming/restful/013.php new file mode 100644 index 000000000000..1a3cc23a9004 --- /dev/null +++ b/user_guide_src/source/incoming/restful/013.php @@ -0,0 +1,3 @@ +presenter('photos', ['only' => ['index', 'show']]); diff --git a/user_guide_src/source/incoming/restful/014.php b/user_guide_src/source/incoming/restful/014.php new file mode 100644 index 000000000000..0d88d4ba5cdc --- /dev/null +++ b/user_guide_src/source/incoming/restful/014.php @@ -0,0 +1,3 @@ +presenter('photos', ['except' => 'new,edit']); diff --git a/user_guide_src/source/incoming/restful/015.php b/user_guide_src/source/incoming/restful/015.php new file mode 100644 index 000000000000..fc5713b20d61 --- /dev/null +++ b/user_guide_src/source/incoming/restful/015.php @@ -0,0 +1,18 @@ +model->findAll()); + } + + // ... +} diff --git a/user_guide_src/source/incoming/restful/016.php b/user_guide_src/source/incoming/restful/016.php new file mode 100644 index 000000000000..d0511180ee22 --- /dev/null +++ b/user_guide_src/source/incoming/restful/016.php @@ -0,0 +1,3 @@ +presenter('photos'); diff --git a/user_guide_src/source/incoming/routing.rst b/user_guide_src/source/incoming/routing.rst index b48c5785780b..1dbfd47c1d80 100644 --- a/user_guide_src/source/incoming/routing.rst +++ b/user_guide_src/source/incoming/routing.rst @@ -52,38 +52,37 @@ it creates an instance of the RouteCollection class (``$routes``) that permits y Routes can be specified using placeholders or Regular Expressions. When you specify a route, you choose a method to corresponding to HTTP verbs (request method). -If you expect a GET request, you use the ``get()`` method:: +If you expect a GET request, you use the ``get()`` method: - $routes->get('/', 'Home::index'); +.. literalinclude:: routing/000.php + :lines: 2- A route simply takes the URI path on the left, and maps it to the controller and method on the right, along with any parameters that should be passed to the controller. The controller and method should be listed in the same way that you would use a static method, by separating the class and its method with a double-colon, like ``Users::list``. If that method requires parameters to be -passed to it, then they would be listed after the method name, separated by forward-slashes:: +passed to it, then they would be listed after the method name, separated by forward-slashes: - // Calls $Users->list() - $routes->get('users', 'Users::list'); +.. literalinclude:: routing/001.php + :lines: 2- - // Calls $Users->list(1, 23) - $routes->get('users/1/23', 'Users::list/1/23'); +You can use any standard HTTP verb (GET, POST, PUT, DELETE, etc): -You can use any standard HTTP verb (GET, POST, PUT, DELETE, etc):: +.. literalinclude:: routing/024.php + :lines: 2- - $routes->post('products', 'Product::feature'); - $routes->put('products/1', 'Product::feature'); - $routes->delete('products/1', 'Product::feature'); +You can supply multiple verbs that a route should match by passing them in as an array to the ``match()`` method: -You can supply multiple verbs that a route should match by passing them in as an array to the ``match()`` method:: - - $routes->match(['get', 'put'], 'products', 'Product::feature'); +.. literalinclude:: routing/025.php + :lines: 2- Placeholders ============ -A typical route might look something like this:: +A typical route might look something like this: - $routes->get('product/(:num)', 'Catalog::productLookup'); +.. literalinclude:: routing/002.php + :lines: 2- In a route, the first parameter contains the URI to be matched, while the second parameter contains the destination it should be routed to. In the above example, if the literal word @@ -116,42 +115,45 @@ Examples Here are a few basic routing examples. A URL containing the word **journals** in the first segment will be remapped to the ``\App\Controllers\Blogs`` class, -and the default method, which is usually ``index()``:: +and the default method, which is usually ``index()``: - $routes->get('journals', 'Blogs'); +.. literalinclude:: routing/003.php + :lines: 2- A URL containing the segments **blog/joe** will be remapped to the ``\App\Controllers\Blogs`` class and the ``users`` method. -The ID will be set to ``34``:: +The ID will be set to ``34``: - $routes->get('blog/joe', 'Blogs::users/34'); +.. literalinclude:: routing/004.php + :lines: 2- A URL with **product** as the first segment, and anything in the second will be remapped to the ``\App\Controllers\Catalog`` class -and the ``productLookup`` method:: +and the ``productLookup`` method: - $routes->get('product/(:any)', 'Catalog::productLookup'); +.. literalinclude:: routing/005.php + :lines: 2- A URL with **product** as the first segment, and a number in the second will be remapped to the ``\App\Controllers\Catalog`` class -and the ``productLookupByID`` method passing in the match as a variable to the method:: +and the ``productLookupByID`` method passing in the match as a variable to the method: - $routes->get('product/(:num)', 'Catalog::productLookupByID/$1'); +.. literalinclude:: routing/006.php + :lines: 2- -Note that a single ``(:any)`` will match multiple segments in the URL if present. For example the route:: +Note that a single ``(:any)`` will match multiple segments in the URL if present. For example the route: - $routes->get('product/(:any)', 'Catalog::productLookup/$1'); +.. literalinclude:: routing/007.php + :lines: 2- will match **product/123**, **product/123/456**, **product/123/456/789** and so on. The implementation in the -Controller should take into account the maximum parameters:: +Controller should take into account the maximum parameters: - public function productLookup($seg1 = false, $seg2 = false, $seg3 = false) { - echo $seg1; // Will be 123 in all examples - echo $seg2; // false in first, 456 in second and third example - echo $seg3; // false in first and second, 789 in third - } +.. literalinclude:: routing/008.php + :lines: 2- If matching multiple segments is not the intended behavior, ``(:segment)`` should be used when defining the -routes. With the examples URLs from above:: +routes. With the examples URLs from above: - $routes->get('product/(:segment)', 'Catalog::productLookup/$1'); +.. literalinclude:: routing/009.php + :lines: 2- will only match **product/123** and generate 404 errors for other example. @@ -163,10 +165,10 @@ and readability. You add new placeholders with the ``addPlaceholder()`` method. The first parameter is the string to be used as the placeholder. The second parameter is the Regular Expression pattern it should be replaced with. -This must be called before you add the route:: +This must be called before you add the route: - $routes->addPlaceholder('uuid', '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'); - $routes->get('users/(:uuid)', 'Users::show/$1'); +.. literalinclude:: routing/010.php + :lines: 2- Regular Expressions =================== @@ -175,9 +177,10 @@ If you prefer you can use regular expressions to define your routing rules. Any is allowed, as are back-references. .. important:: Note: If you use back-references you must use the dollar syntax rather than the double backslash syntax. - A typical RegEx route might look something like this:: + A typical RegEx route might look something like this: - $routes->get('products/([a-z]+)/(\d+)', 'Products::show/$1/id_$2'); + .. literalinclude:: routing/011.php + :lines: 2- In the above example, a URI similar to **products/shirts/123** would instead call the ``show`` method of the ``Products`` controller class, with the original first and second segment passed as arguments to it. @@ -186,9 +189,10 @@ With regular expressions, you can also catch a segment containing a forward slas represent the delimiter between multiple segments. For example, if a user accesses a password protected area of your web application and you wish to be able to -redirect them back to the same page after they log in, you may find this example useful:: +redirect them back to the same page after they log in, you may find this example useful: - $routes->get('login/(.+)', 'Auth::login/$1'); +.. literalinclude:: routing/012.php + :lines: 2- For those of you who don’t know regular expressions and want to learn more about them, `regular-expressions.info `_ might be a good starting point. @@ -200,27 +204,20 @@ Closures You can use an anonymous function, or Closure, as the destination that a route maps to. This function will be executed when the user visits that URI. This is handy for quickly executing small tasks, or even just showing -a simple view:: - - $routes->get('feed', function () { - $rss = new RSSFeeder(); +a simple view: - return $rss->feed('general'); - }); +.. literalinclude:: routing/013.php + :lines: 2- Mapping multiple routes ======================= While the ``add()`` method is simple to use, it is often handier to work with multiple routes at once, using the ``map()`` method. Instead of calling the ``add()`` method for each route that you need to add, you can -define an array of routes and then pass it as the first parameter to the ``map()`` method:: - - $multipleRoutes = [ - 'product/(:num)' => 'Catalog::productLookupById', - 'product/(:alphanum)' => 'Catalog::productLookupByName', - ]; +define an array of routes and then pass it as the first parameter to the ``map()`` method: - $routes->map($multipleRoutes); +.. literalinclude:: routing/014.php + :lines: 2- Redirecting Routes ================== @@ -229,14 +226,10 @@ Any site that lives long enough is bound to have pages that move. You can specif to other routes with the ``addRedirect()`` method. The first parameter is the URI pattern for the old route. The second parameter is either the new URI to redirect to, or the name of a named route. The third parameter is the HTTP status code that should be sent along with the redirect. The default value is ``302`` which is a temporary -redirect and is recommended in most cases:: +redirect and is recommended in most cases: - $routes->get('users/profile', 'Users::profile', ['as' => 'profile']); - - // Redirect to a named route - $routes->addRedirect('users/about', 'profile'); - // Redirect to a URI - $routes->addRedirect('users/about', 'users/profile'); +.. literalinclude:: routing/015.php + :lines: 2- If a redirect route is matched during a page load, the user will be immediately redirected to the new page before a controller can be loaded. @@ -246,39 +239,32 @@ Grouping Routes You can group your routes under a common name with the ``group()`` method. The group name becomes a segment that appears prior to the routes defined inside of the group. This allows you to reduce the typing needed to build out an -extensive set of routes that all share the opening string, like when building an admin area:: +extensive set of routes that all share the opening string, like when building an admin area: - $routes->group('admin', function ($routes) { - $routes->get('users', 'Admin\Users::index'); - $routes->get('blog', 'Admin\Blog::index'); - }); +.. literalinclude:: routing/016.php + :lines: 2- This would prefix the **users** and **blog** URIs with **admin**, handling URLs like **admin/users** and **admin/blog**. -If you need to assign options to a group, like a :ref:`assigning-namespace`, do it before the callback:: +If you need to assign options to a group, like a :ref:`assigning-namespace`, do it before the callback: - $routes->group('api', ['namespace' => 'App\API\v1'], function ($routes) { - $routes->resource('users'); - }); +.. literalinclude:: routing/017.php + :lines: 2- This would handle a resource route to the ``App\API\v1\Users`` controller with the **api/users** URI. You can also use a specific :doc:`filter ` for a group of routes. This will always -run the filter before or after the controller. This is especially handy during authentication or api logging:: +run the filter before or after the controller. This is especially handy during authentication or api logging: - $routes->group('api', ['filter' => 'api-auth'], function ($routes) { - $routes->resource('users'); - }); +.. literalinclude:: routing/018.php + :lines: 2- The value for the filter must match one of the aliases defined within **app/Config/Filters.php**. -It is possible to nest groups within groups for finer organization if you need it:: +It is possible to nest groups within groups for finer organization if you need it: - $routes->group('admin', function ($routes) { - $routes->group('users', function ($routes) { - $routes->get('list', 'Admin\Users::list'); - }); - }); +.. literalinclude:: routing/019.php + :lines: 2- This would handle the URL at **admin/users/list**. @@ -287,13 +273,10 @@ This would handle the URL at **admin/users/list**. At some point, you may want to group routes for the purpose of applying filters or other route config options like namespace, subdomain, etc. Without necessarily needing to add a prefix to the group, you can pass an empty string in place of the prefix and the routes in the group will be routed as though the group never existed but with the -given route config options:: +given route config options: - $routes->group('', ['namespace' => 'Myth\Auth\Controllers'], static function ($routes) { - $routes->get('login', 'AuthController::login', ['as' => 'login']); - $routes->post('login', 'AuthController::attemptLogin'); - $routes->get('logout', 'AuthController::logout'); - }); +.. literalinclude:: routing/020.php + :lines: 2- Environment Restrictions ======================== @@ -301,11 +284,10 @@ Environment Restrictions You can create a set of routes that will only be viewable in a certain environment. This allows you to create tools that only the developer can use on their local machines that are not reachable on testing or production servers. This can be done with the ``environment()`` method. The first parameter is the name of the environment. Any -routes defined within this closure are only accessible from the given environment:: +routes defined within this closure are only accessible from the given environment: - $routes->environment('development', function ($routes) { - $routes->get('builder', 'Tools\Builder::index'); - }); +.. literalinclude:: routing/021.php + :lines: 2- Reverse Routing =============== @@ -317,14 +299,10 @@ to update your application code. This is typically used within views to create l For example, if you have a route to a photo gallery that you want to link to, you can use the ``route_to()`` helper function to get the current route that should be used. The first parameter is the fully qualified Controller and method, separated by a double colon (``::``), much like you would use when writing the initial route itself. Any parameters that -should be passed to the route are passed in next:: - - // The route is defined as: - $routes->get('users/(:num)/gallery(:any)', 'App\Controllers\Galleries::showUserGallery/$1/$2'); +should be passed to the route are passed in next: - // Generate the relative URL to link to user ID 15, gallery 12 - // Generates: /users/15/gallery/12 - View Gallery +.. literalinclude:: routing/022.php + :lines: 2- Using Named Routes ================== @@ -332,14 +310,10 @@ Using Named Routes You can name routes to make your application less fragile. This applies a name to a route that can be called later, and even if the route definition changes, all of the links in your application built with ``route_to()`` will still work without you having to make any changes. A route is named by passing in the ``as`` option -with the name of the route:: +with the name of the route: - // The route is defined as: - $routes->get('users/(:num)/gallery(:any)', 'Galleries::showUserGallery/$1/$2', ['as' => 'user_gallery']); - - // Generate the relative URL to link to user ID 15, gallery 12 - // Generates: /users/15/gallery/12 - View Gallery +.. literalinclude:: routing/023.php + :lines: 2- This has the added benefit of making the views more readable, too. @@ -347,9 +321,10 @@ Routes with any HTTP verbs ========================== It is possible to define a route with any HTTP verbs. -You can use the ``add()`` method:: +You can use the ``add()`` method: - $routes->add('products', 'Product::feature'); +.. literalinclude:: routing/023-2.php + :lines: 2- .. warning:: While the ``add()`` method seems to be convenient, it is recommended to always use the HTTP-verb-based routes, described above, as it is more secure. If you use the :doc:`CSRF protection `, it does not protect **GET** @@ -366,28 +341,19 @@ Command-Line only Routes You can create routes that work only from the command-line, and are inaccessible from the web browser, with the ``cli()`` method. This is great for building cron jobs or CLI-only tools. Any route created by any of the HTTP-verb-based route methods will also be inaccessible from the CLI, but routes created by the ``add()`` method will still be -available from the command line:: +available from the command line: - $routes->cli('migrate', 'App\Database::migrate'); +.. literalinclude:: routing/026.php + :lines: 2- Global Options ============== All of the methods for creating a route (add, get, post, :doc:`resource ` etc) can take an array of options that -can modify the generated routes, or further restrict them. The ``$options`` array is always the last parameter:: - - $routes->add('from', 'to', $options); - $routes->get('from', 'to', $options); - $routes->post('from', 'to', $options); - $routes->put('from', 'to', $options); - $routes->head('from', 'to', $options); - $routes->options('from', 'to', $options); - $routes->delete('from', 'to', $options); - $routes->patch('from', 'to', $options); - $routes->match(['get', 'put'], 'from', 'to', $options); - $routes->resource('photos', $options); - $routes->map($array, $options); - $routes->group('name', $options, function ()); +can modify the generated routes, or further restrict them. The ``$options`` array is always the last parameter: + +.. literalinclude:: routing/027.php + :lines: 2- .. _applying-filters: @@ -411,27 +377,31 @@ See :doc:`Controller filters ` for more information on setting up filte **Alias filter** -You specify an alias defined in **app/Config/Filters.php** for the filter value:: +You specify an alias defined in **app/Config/Filters.php** for the filter value: - $routes->get('admin',' AdminController::index', ['filter' => 'admin-auth']); +.. literalinclude:: routing/028.php + :lines: 2- -You may also supply arguments to be passed to the alias filter's ``before()`` and ``after()`` methods:: +You may also supply arguments to be passed to the alias filter's ``before()`` and ``after()`` methods: - $routes->post('users/delete/(:segment)', 'AdminController::index', ['filter' => 'admin-auth:dual,noreturn']); +.. literalinclude:: routing/029.php + :lines: 2- **Classname filter** -You specify a filter classname for the filter value:: +You specify a filter classname for the filter value: - $routes->get('admin',' AdminController::index', ['filter' => \App\Filters\SomeFilter::class]); +.. literalinclude:: routing/030.php + :lines: 2- **Multiple filters** .. important:: *Multiple filters* is disabled by default. Because it breaks backward compatibility. If you want to use it, you need to configure. See :ref:`upgrade-415-multiple-filters-for-a-route` for the details. -You specify an array for the filter value:: +You specify an array for the filter value: - $routes->get('admin',' AdminController::index', ['filter' => ['admin-auth', \App\Filters\SomeFilter::class]]); +.. literalinclude:: routing/031.php + :lines: 2- .. _assigning-namespace: @@ -440,10 +410,10 @@ Assigning Namespace While a default namespace will be prepended to the generated controllers (see below), you can also specify a different namespace to be used in any options array, with the ``namespace`` option. The value should be the -namespace you want modified:: +namespace you want modified: - // Routes to \Admin\Users::index() - $routes->get('admin/users', 'Users::index', ['namespace' => 'Admin']); +.. literalinclude:: routing/032.php + :lines: 2- The new namespace is only applied during that call for any methods that create a single route, like get, post, etc. For any methods that create multiple routes, the new namespace is attached to all routes generated by that function @@ -453,9 +423,10 @@ Limit to Hostname ----------------- You can restrict groups of routes to function only in certain domain or sub-domains of your application -by passing the "hostname" option along with the desired domain to allow it on as part of the options array:: +by passing the "hostname" option along with the desired domain to allow it on as part of the options array: - $routes->get('from', 'to', ['hostname' => 'accounts.example.com']); +.. literalinclude:: routing/033.php + :lines: 2- This example would only allow the specified hosts to work if the domain exactly matched **accounts.example.com**. It would not work under the main site at **example.com**. @@ -464,16 +435,16 @@ Limit to Subdomains ------------------- When the ``subdomain`` option is present, the system will restrict the routes to only be available on that -sub-domain. The route will only be matched if the subdomain is the one the application is being viewed through:: +sub-domain. The route will only be matched if the subdomain is the one the application is being viewed through: - // Limit to media.example.com - $routes->get('from', 'to', ['subdomain' => 'media']); +.. literalinclude:: routing/034.php + :lines: 2- You can restrict it to any subdomain by setting the value to an asterisk, (``*``). If you are viewing from a URL -that does not have any subdomain present, this will not be matched:: +that does not have any subdomain present, this will not be matched: - // Limit to any sub-domain - $routes->get('from', 'to', ['subdomain' => '*']); +.. literalinclude:: routing/035.php + :lines: 2- .. important:: The system is not perfect and should be tested for your specific domain before being used in production. Most domains should work fine but some edge case ones, especially with a period in the domain itself (not used @@ -486,12 +457,10 @@ You can offset the matched parameters in your route by any numeric value with th value being the number of segments to offset. This can be beneficial when developing API's with the first URI segment being the version number. It can also -be used when the first parameter is a language string:: - - $routes->get('users/(:num)', 'users/show/$1', ['offset' => 1]); +be used when the first parameter is a language string: - // Creates: - $routes['users/(:num)'] = 'users/show/$2'; +.. literalinclude:: routing/036.php + :lines: 2- .. _routing-priority: @@ -502,23 +471,15 @@ When working with modules, it can be a problem if the routes in the application Then the module routes will not be processed correctly. You can solve this problem by lowering the priority of route processing using the ``priority`` option. The parameter accepts positive integers and zero. The higher the number specified in the ``priority``, the lower -route priority in the processing queue:: - - // First you need to enable sorting. - $routes->setPrioritize(); - - // App\Config\Routes - $routes->get('(.*)', 'Posts::index', ['priority' => 1]); +route priority in the processing queue: - // Modules\Acme\Config\Routes - $routes->get('admin', 'Admin::index'); +.. literalinclude:: routing/037.php + :lines: 2- - // The "admin" route will now be processed before the wildcard router. +To disable this functionality, you must call the method with the parameter ``false``: - -To disable this functionality, you must call the method with the parameter ``false``:: - - $routes->setPrioritize(false); +.. literalinclude:: routing/038.php + :lines: 2- .. note:: By default, all routes have a priority of 0. Negative integers will be cast to the absolute value. @@ -539,36 +500,26 @@ When matching a controller to a route, the router will add the default namespace specified by the route. By default, this value is ``App\Controllers``. If you set the value empty string (``''``), it leaves each route to specify the fully namespaced -controller:: - - $routes->setDefaultNamespace(''); +controller: - // Controller is \Users - $routes->get('users', 'Users::index'); - - // Controller is \Admin\Users - $routes->get('users', 'Admin\Users::index'); +.. literalinclude:: routing/039.php + :lines: 2- If your controllers are not explicitly namespaced, there is no need to change this. If you namespace your controllers, -then you can change this value to save typing:: - - $routes->setDefaultNamespace('App'); +then you can change this value to save typing: - // Controller is \App\Users - $routes->get('users', 'Users::index'); - - // Controller is \App\Admin\Users - $routes->get('users', 'Admin\Users::index'); +.. literalinclude:: routing/040.php + :lines: 2- Default Controller ================== When a user visits the root of your site (i.e., example.com) the controller to use is determined by the value set by the ``setDefaultController()`` method, unless a route exists for it explicitly. The default value for this is ``Home`` -which matches the controller at **app/Controllers/Home.php**:: +which matches the controller at **app/Controllers/Home.php**: - // example.com routes to app/Controllers/Welcome.php - $routes->setDefaultController('Welcome'); +.. literalinclude:: routing/041.php + :lines: 2- The default controller is also used when no matching route has been found, and the URI would point to a directory in the controllers directory. For example, if the user visits **example.com/admin**, if a controller was found at @@ -582,18 +533,20 @@ when a controller is found that matches the URI, but no segment exists for the m ``index``. In this example, if the user were to visit **example.com/products**, and a ``Products`` controller existed, the -``Products::listAll()`` method would be executed:: +``Products::listAll()`` method would be executed: - $routes->setDefaultMethod('listAll'); +.. literalinclude:: routing/042.php + :lines: 2- Translate URI Dashes ==================== This option enables you to automatically replace dashes (``-``) with underscores in the controller and method URI segments, thus saving you additional route entries if you need to do that. This is required because the -dash isn’t a valid class or method name character and would cause a fatal error if you try to use it:: +dash isn’t a valid class or method name character and would cause a fatal error if you try to use it: - $routes->setTranslateURIDashes(true); +.. literalinclude:: routing/043.php + :lines: 2- .. _use-defined-routes-only: @@ -602,9 +555,10 @@ Use Defined Routes Only When no defined route is found that matches the URI, the system will attempt to match that URI against the controllers and methods as described above. You can disable this automatic matching, and restrict routes -to only those defined by you, by setting the ``setAutoRoute()`` option to false:: +to only those defined by you, by setting the ``setAutoRoute()`` option to false: - $routes->setAutoRoute(false); +.. literalinclude:: routing/044.php + :lines: 2- .. warning:: If you use the :doc:`CSRF protection `, it does not protect **GET** requests. If the URI is accessible by the GET method, the CSRF protection will not work. @@ -614,30 +568,20 @@ to only those defined by you, by setting the ``setAutoRoute()`` option to false: When a page is not found that matches the current URI, the system will show a generic 404 view. You can change what happens by specifying an action to happen with the ``set404Override()`` method. The value can be either -a valid class/method pair, just like you would show in any route, or a Closure:: - - // Would execute the show404 method of the App\Errors class - $routes->set404Override('App\Errors::show404'); - - // Will display a custom view - $routes->set404Override(function () - { - echo view('my_errors/not_found.html'); - }); +a valid class/method pair, just like you would show in any route, or a Closure: +.. literalinclude:: routing/045.php + :lines: 2- Route processing by priority ============================ Enables or disables processing of the routes queue by priority. Lowering the priority is defined in the route option. Disabled by default. This functionality affects all routes. -For an example use of lowering the priority see :ref:`routing-priority`:: - - // to enable - $routes->setPrioritize(); +For an example use of lowering the priority see :ref:`routing-priority`: - // to disable - $routes->setPrioritize(false); +.. literalinclude:: routing/046.php + :lines: 2- ***************** Confirming Routes @@ -675,4 +619,4 @@ But ``[/...]`` in the route of an auto route is indicates any number of segments .. note:: When auto routing is enabled, if you have the route ``home``, it can be also accessd by ``Home``, or maybe by ``hOme``, ``hoMe``, ``HOME``, etc. But the command shows only ``home``. -.. important:: The system is not perfect. If you use Custom Placeholders, *Filters* might not be correct. But the filters defined in **app/Config/Routes.php** are always displayed correctly. +.. important:: The system is not perfect. If you use Custom Placeholders, *Filters* might not be correct. But the filters defined in **app/Config/Routes.php** are always displayed correctly. \ No newline at end of file diff --git a/user_guide_src/source/incoming/routing/000.php b/user_guide_src/source/incoming/routing/000.php new file mode 100644 index 000000000000..d799d1cf0fb5 --- /dev/null +++ b/user_guide_src/source/incoming/routing/000.php @@ -0,0 +1,3 @@ +get('/', 'Home::index'); diff --git a/user_guide_src/source/incoming/routing/001.php b/user_guide_src/source/incoming/routing/001.php new file mode 100644 index 000000000000..4ddfd31abaed --- /dev/null +++ b/user_guide_src/source/incoming/routing/001.php @@ -0,0 +1,7 @@ +list() +$routes->get('users', 'Users::list'); + +// Calls $Users->list(1, 23) +$routes->get('users/1/23', 'Users::list/1/23'); \ No newline at end of file diff --git a/user_guide_src/source/incoming/routing/002.php b/user_guide_src/source/incoming/routing/002.php new file mode 100644 index 000000000000..ba4d8d98a28a --- /dev/null +++ b/user_guide_src/source/incoming/routing/002.php @@ -0,0 +1,3 @@ +get('product/(:num)', 'Catalog::productLookup'); diff --git a/user_guide_src/source/incoming/routing/003.php b/user_guide_src/source/incoming/routing/003.php new file mode 100644 index 000000000000..7a9075b57b2f --- /dev/null +++ b/user_guide_src/source/incoming/routing/003.php @@ -0,0 +1,3 @@ +get('journals', 'Blogs'); diff --git a/user_guide_src/source/incoming/routing/004.php b/user_guide_src/source/incoming/routing/004.php new file mode 100644 index 000000000000..4ee87c0af53a --- /dev/null +++ b/user_guide_src/source/incoming/routing/004.php @@ -0,0 +1,3 @@ +get('blog/joe', 'Blogs::users/34'); diff --git a/user_guide_src/source/incoming/routing/005.php b/user_guide_src/source/incoming/routing/005.php new file mode 100644 index 000000000000..d840165c7809 --- /dev/null +++ b/user_guide_src/source/incoming/routing/005.php @@ -0,0 +1,3 @@ +get('product/(:any)', 'Catalog::productLookup'); diff --git a/user_guide_src/source/incoming/routing/006.php b/user_guide_src/source/incoming/routing/006.php new file mode 100644 index 000000000000..638ed4492220 --- /dev/null +++ b/user_guide_src/source/incoming/routing/006.php @@ -0,0 +1,3 @@ +get('product/(:num)', 'Catalog::productLookupByID/$1'); diff --git a/user_guide_src/source/incoming/routing/007.php b/user_guide_src/source/incoming/routing/007.php new file mode 100644 index 000000000000..c88bc65573a3 --- /dev/null +++ b/user_guide_src/source/incoming/routing/007.php @@ -0,0 +1,3 @@ +get('product/(:any)', 'Catalog::productLookup/$1'); diff --git a/user_guide_src/source/incoming/routing/008.php b/user_guide_src/source/incoming/routing/008.php new file mode 100644 index 000000000000..11437a5881c2 --- /dev/null +++ b/user_guide_src/source/incoming/routing/008.php @@ -0,0 +1,7 @@ +get('product/(:segment)', 'Catalog::productLookup/$1'); diff --git a/user_guide_src/source/incoming/routing/010.php b/user_guide_src/source/incoming/routing/010.php new file mode 100644 index 000000000000..cb1cdda7c78c --- /dev/null +++ b/user_guide_src/source/incoming/routing/010.php @@ -0,0 +1,4 @@ +addPlaceholder('uuid', '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'); +$routes->get('users/(:uuid)', 'Users::show/$1'); diff --git a/user_guide_src/source/incoming/routing/011.php b/user_guide_src/source/incoming/routing/011.php new file mode 100644 index 000000000000..a1619a4bf080 --- /dev/null +++ b/user_guide_src/source/incoming/routing/011.php @@ -0,0 +1,3 @@ +get('products/([a-z]+)/(\d+)', 'Products::show/$1/id_$2'); diff --git a/user_guide_src/source/incoming/routing/012.php b/user_guide_src/source/incoming/routing/012.php new file mode 100644 index 000000000000..c9ddfae73610 --- /dev/null +++ b/user_guide_src/source/incoming/routing/012.php @@ -0,0 +1,3 @@ +get('login/(.+)', 'Auth::login/$1'); diff --git a/user_guide_src/source/incoming/routing/013.php b/user_guide_src/source/incoming/routing/013.php new file mode 100644 index 000000000000..2d0f48cb284e --- /dev/null +++ b/user_guide_src/source/incoming/routing/013.php @@ -0,0 +1,7 @@ +get('feed', function () { + $rss = new RSSFeeder(); + + return $rss->feed('general'); +}); diff --git a/user_guide_src/source/incoming/routing/014.php b/user_guide_src/source/incoming/routing/014.php new file mode 100644 index 000000000000..8ebc27e3f9f5 --- /dev/null +++ b/user_guide_src/source/incoming/routing/014.php @@ -0,0 +1,8 @@ + 'Catalog::productLookupById', + 'product/(:alphanum)' => 'Catalog::productLookupByName', +]; + +$routes->map($multipleRoutes); diff --git a/user_guide_src/source/incoming/routing/015.php b/user_guide_src/source/incoming/routing/015.php new file mode 100644 index 000000000000..d92d9934db5a --- /dev/null +++ b/user_guide_src/source/incoming/routing/015.php @@ -0,0 +1,8 @@ +get('users/profile', 'Users::profile', ['as' => 'profile']); + +// Redirect to a named route +$routes->addRedirect('users/about', 'profile'); +// Redirect to a URI +$routes->addRedirect('users/about', 'users/profile'); diff --git a/user_guide_src/source/incoming/routing/016.php b/user_guide_src/source/incoming/routing/016.php new file mode 100644 index 000000000000..8c770fd05f24 --- /dev/null +++ b/user_guide_src/source/incoming/routing/016.php @@ -0,0 +1,6 @@ +group('admin', function ($routes) { + $routes->get('users', 'Admin\Users::index'); + $routes->get('blog', 'Admin\Blog::index'); +}); diff --git a/user_guide_src/source/incoming/routing/017.php b/user_guide_src/source/incoming/routing/017.php new file mode 100644 index 000000000000..678e90700e74 --- /dev/null +++ b/user_guide_src/source/incoming/routing/017.php @@ -0,0 +1,5 @@ +group('api', ['namespace' => 'App\API\v1'], function ($routes) { + $routes->resource('users'); +}); diff --git a/user_guide_src/source/incoming/routing/018.php b/user_guide_src/source/incoming/routing/018.php new file mode 100644 index 000000000000..395ddfe6c8c8 --- /dev/null +++ b/user_guide_src/source/incoming/routing/018.php @@ -0,0 +1,5 @@ +group('api', ['filter' => 'api-auth'], function ($routes) { + $routes->resource('users'); +}); diff --git a/user_guide_src/source/incoming/routing/019.php b/user_guide_src/source/incoming/routing/019.php new file mode 100644 index 000000000000..08169acec275 --- /dev/null +++ b/user_guide_src/source/incoming/routing/019.php @@ -0,0 +1,7 @@ +group('admin', function ($routes) { + $routes->group('users', function ($routes) { + $routes->get('list', 'Admin\Users::list'); + }); +}); diff --git a/user_guide_src/source/incoming/routing/020.php b/user_guide_src/source/incoming/routing/020.php new file mode 100644 index 000000000000..d7624ddc6d5c --- /dev/null +++ b/user_guide_src/source/incoming/routing/020.php @@ -0,0 +1,7 @@ +group('', ['namespace' => 'Myth\Auth\Controllers'], static function ($routes) { + $routes->get('login', 'AuthController::login', ['as' => 'login']); + $routes->post('login', 'AuthController::attemptLogin'); + $routes->get('logout', 'AuthController::logout'); +}); diff --git a/user_guide_src/source/incoming/routing/021.php b/user_guide_src/source/incoming/routing/021.php new file mode 100644 index 000000000000..69a4c184ab36 --- /dev/null +++ b/user_guide_src/source/incoming/routing/021.php @@ -0,0 +1,5 @@ +environment('development', function ($routes) { + $routes->get('builder', 'Tools\Builder::index'); +}); diff --git a/user_guide_src/source/incoming/routing/022.php b/user_guide_src/source/incoming/routing/022.php new file mode 100644 index 000000000000..0af87a58c3b5 --- /dev/null +++ b/user_guide_src/source/incoming/routing/022.php @@ -0,0 +1,8 @@ +get('users/(:num)/gallery(:any)', 'App\Controllers\Galleries::showUserGallery/$1/$2'); + +// Generate the relative URL to link to user ID 15, gallery 12 +// Generates: /users/15/gallery/12 +View Gallery diff --git a/user_guide_src/source/incoming/routing/023-2.php b/user_guide_src/source/incoming/routing/023-2.php new file mode 100644 index 000000000000..e2a3784f335f --- /dev/null +++ b/user_guide_src/source/incoming/routing/023-2.php @@ -0,0 +1,3 @@ +add('products', 'Product::feature'); diff --git a/user_guide_src/source/incoming/routing/023.php b/user_guide_src/source/incoming/routing/023.php new file mode 100644 index 000000000000..5469c79db91a --- /dev/null +++ b/user_guide_src/source/incoming/routing/023.php @@ -0,0 +1,8 @@ +get('users/(:num)/gallery(:any)', 'Galleries::showUserGallery/$1/$2', ['as' => 'user_gallery']); + +// Generate the relative URL to link to user ID 15, gallery 12 +// Generates: /users/15/gallery/12 +View Gallery diff --git a/user_guide_src/source/incoming/routing/024.php b/user_guide_src/source/incoming/routing/024.php new file mode 100644 index 000000000000..7351142dea77 --- /dev/null +++ b/user_guide_src/source/incoming/routing/024.php @@ -0,0 +1,5 @@ +post('products', 'Product::feature'); +$routes->put('products/1', 'Product::feature'); +$routes->delete('products/1', 'Product::feature'); diff --git a/user_guide_src/source/incoming/routing/025.php b/user_guide_src/source/incoming/routing/025.php new file mode 100644 index 000000000000..a071f75cd156 --- /dev/null +++ b/user_guide_src/source/incoming/routing/025.php @@ -0,0 +1,3 @@ +match(['get', 'put'], 'products', 'Product::feature'); diff --git a/user_guide_src/source/incoming/routing/026.php b/user_guide_src/source/incoming/routing/026.php new file mode 100644 index 000000000000..a82d57ebc5c7 --- /dev/null +++ b/user_guide_src/source/incoming/routing/026.php @@ -0,0 +1,3 @@ +cli('migrate', 'App\Database::migrate'); diff --git a/user_guide_src/source/incoming/routing/027.php b/user_guide_src/source/incoming/routing/027.php new file mode 100644 index 000000000000..31c1dda07a70 --- /dev/null +++ b/user_guide_src/source/incoming/routing/027.php @@ -0,0 +1,14 @@ +add('from', 'to', $options); +$routes->get('from', 'to', $options); +$routes->post('from', 'to', $options); +$routes->put('from', 'to', $options); +$routes->head('from', 'to', $options); +$routes->options('from', 'to', $options); +$routes->delete('from', 'to', $options); +$routes->patch('from', 'to', $options); +$routes->match(['get', 'put'], 'from', 'to', $options); +$routes->resource('photos', $options); +$routes->map($array, $options); +$routes->group('name', $options, function ()); diff --git a/user_guide_src/source/incoming/routing/028.php b/user_guide_src/source/incoming/routing/028.php new file mode 100644 index 000000000000..ca1121e0786d --- /dev/null +++ b/user_guide_src/source/incoming/routing/028.php @@ -0,0 +1,3 @@ +get('admin',' AdminController::index', ['filter' => 'admin-auth']); diff --git a/user_guide_src/source/incoming/routing/029.php b/user_guide_src/source/incoming/routing/029.php new file mode 100644 index 000000000000..b50db49bd962 --- /dev/null +++ b/user_guide_src/source/incoming/routing/029.php @@ -0,0 +1,3 @@ +post('users/delete/(:segment)', 'AdminController::index', ['filter' => 'admin-auth:dual,noreturn']); diff --git a/user_guide_src/source/incoming/routing/030.php b/user_guide_src/source/incoming/routing/030.php new file mode 100644 index 000000000000..14d5142de2f0 --- /dev/null +++ b/user_guide_src/source/incoming/routing/030.php @@ -0,0 +1,3 @@ +get('admin',' AdminController::index', ['filter' => \App\Filters\SomeFilter::class]); diff --git a/user_guide_src/source/incoming/routing/031.php b/user_guide_src/source/incoming/routing/031.php new file mode 100644 index 000000000000..24cf6c5dbc2d --- /dev/null +++ b/user_guide_src/source/incoming/routing/031.php @@ -0,0 +1,3 @@ +get('admin',' AdminController::index', ['filter' => ['admin-auth', \App\Filters\SomeFilter::class]]); diff --git a/user_guide_src/source/incoming/routing/032.php b/user_guide_src/source/incoming/routing/032.php new file mode 100644 index 000000000000..b992deb96ecf --- /dev/null +++ b/user_guide_src/source/incoming/routing/032.php @@ -0,0 +1,4 @@ +get('admin/users', 'Users::index', ['namespace' => 'Admin']); diff --git a/user_guide_src/source/incoming/routing/033.php b/user_guide_src/source/incoming/routing/033.php new file mode 100644 index 000000000000..5b415a50138b --- /dev/null +++ b/user_guide_src/source/incoming/routing/033.php @@ -0,0 +1,3 @@ +get('from', 'to', ['hostname' => 'accounts.example.com']); diff --git a/user_guide_src/source/incoming/routing/034.php b/user_guide_src/source/incoming/routing/034.php new file mode 100644 index 000000000000..32a74934eb3a --- /dev/null +++ b/user_guide_src/source/incoming/routing/034.php @@ -0,0 +1,4 @@ +get('from', 'to', ['subdomain' => 'media']); diff --git a/user_guide_src/source/incoming/routing/035.php b/user_guide_src/source/incoming/routing/035.php new file mode 100644 index 000000000000..0d0fd0e67fb4 --- /dev/null +++ b/user_guide_src/source/incoming/routing/035.php @@ -0,0 +1,4 @@ +get('from', 'to', ['subdomain' => '*']); diff --git a/user_guide_src/source/incoming/routing/036.php b/user_guide_src/source/incoming/routing/036.php new file mode 100644 index 000000000000..ec7fa680f65e --- /dev/null +++ b/user_guide_src/source/incoming/routing/036.php @@ -0,0 +1,6 @@ +get('users/(:num)', 'users/show/$1', ['offset' => 1]); + +// Creates: +$routes['users/(:num)'] = 'users/show/$2'; diff --git a/user_guide_src/source/incoming/routing/037.php b/user_guide_src/source/incoming/routing/037.php new file mode 100644 index 000000000000..29fc83e59f17 --- /dev/null +++ b/user_guide_src/source/incoming/routing/037.php @@ -0,0 +1,12 @@ +setPrioritize(); + +// App\Config\Routes +$routes->get('(.*)', 'Posts::index', ['priority' => 1]); + +// Modules\Acme\Config\Routes +$routes->get('admin', 'Admin::index'); + +// The "admin" route will now be processed before the wildcard router. diff --git a/user_guide_src/source/incoming/routing/038.php b/user_guide_src/source/incoming/routing/038.php new file mode 100644 index 000000000000..9465f4147e2c --- /dev/null +++ b/user_guide_src/source/incoming/routing/038.php @@ -0,0 +1,3 @@ +setPrioritize(false); diff --git a/user_guide_src/source/incoming/routing/039.php b/user_guide_src/source/incoming/routing/039.php new file mode 100644 index 000000000000..98aef9276f9d --- /dev/null +++ b/user_guide_src/source/incoming/routing/039.php @@ -0,0 +1,9 @@ +setDefaultNamespace(''); + +// Controller is \Users +$routes->get('users', 'Users::index'); + +// Controller is \Admin\Users +$routes->get('users', 'Admin\Users::index'); diff --git a/user_guide_src/source/incoming/routing/040.php b/user_guide_src/source/incoming/routing/040.php new file mode 100644 index 000000000000..fbbbee2300df --- /dev/null +++ b/user_guide_src/source/incoming/routing/040.php @@ -0,0 +1,9 @@ +setDefaultNamespace('App'); + +// Controller is \App\Users +$routes->get('users', 'Users::index'); + +// Controller is \App\Admin\Users +$routes->get('users', 'Admin\Users::index'); diff --git a/user_guide_src/source/incoming/routing/041.php b/user_guide_src/source/incoming/routing/041.php new file mode 100644 index 000000000000..5d17df8130d4 --- /dev/null +++ b/user_guide_src/source/incoming/routing/041.php @@ -0,0 +1,4 @@ +setDefaultController('Welcome'); diff --git a/user_guide_src/source/incoming/routing/042.php b/user_guide_src/source/incoming/routing/042.php new file mode 100644 index 000000000000..e926e651287d --- /dev/null +++ b/user_guide_src/source/incoming/routing/042.php @@ -0,0 +1,3 @@ +setDefaultMethod('listAll'); diff --git a/user_guide_src/source/incoming/routing/043.php b/user_guide_src/source/incoming/routing/043.php new file mode 100644 index 000000000000..31d49508ab86 --- /dev/null +++ b/user_guide_src/source/incoming/routing/043.php @@ -0,0 +1,3 @@ +setTranslateURIDashes(true); diff --git a/user_guide_src/source/incoming/routing/044.php b/user_guide_src/source/incoming/routing/044.php new file mode 100644 index 000000000000..c331102cd9f4 --- /dev/null +++ b/user_guide_src/source/incoming/routing/044.php @@ -0,0 +1,3 @@ +setAutoRoute(false); diff --git a/user_guide_src/source/incoming/routing/045.php b/user_guide_src/source/incoming/routing/045.php new file mode 100644 index 000000000000..1f3758e244d4 --- /dev/null +++ b/user_guide_src/source/incoming/routing/045.php @@ -0,0 +1,10 @@ +set404Override('App\Errors::show404'); + +// Will display a custom view +$routes->set404Override(function () +{ + echo view('my_errors/not_found.html'); +}); diff --git a/user_guide_src/source/incoming/routing/046.php b/user_guide_src/source/incoming/routing/046.php new file mode 100644 index 000000000000..e3dd9f60c989 --- /dev/null +++ b/user_guide_src/source/incoming/routing/046.php @@ -0,0 +1,7 @@ +setPrioritize(); + +// to disable +$routes->setPrioritize(false); diff --git a/user_guide_src/source/index.rst b/user_guide_src/source/index.rst index 3f337e5b1f2a..7cc3b84742c4 100644 --- a/user_guide_src/source/index.rst +++ b/user_guide_src/source/index.rst @@ -75,7 +75,6 @@ Handling Databases dbmgmt/index - ******************* Libraries & Helpers ******************* diff --git a/user_guide_src/source/installation/installing_composer.rst b/user_guide_src/source/installation/installing_composer.rst index 7133e2cb80bf..ddda93bccf72 100644 --- a/user_guide_src/source/installation/installing_composer.rst +++ b/user_guide_src/source/installation/installing_composer.rst @@ -173,7 +173,6 @@ Folders in your project after set up: - app, public, writable (when using ``--prefer-source``) - vendor/codeigniter4/framework/system - Translations Installation ========================= diff --git a/user_guide_src/source/installation/installing_manual.rst b/user_guide_src/source/installation/installing_manual.rst index ebd231cdb2cf..c51f0964272e 100644 --- a/user_guide_src/source/installation/installing_manual.rst +++ b/user_guide_src/source/installation/installing_manual.rst @@ -52,7 +52,6 @@ Structure Folders in your project after set up: app, public, system, writable - Translations Installation ========================= diff --git a/user_guide_src/source/installation/troubleshooting.rst b/user_guide_src/source/installation/troubleshooting.rst index 0da650bdf07c..9ae2b5ac843a 100644 --- a/user_guide_src/source/installation/troubleshooting.rst +++ b/user_guide_src/source/installation/troubleshooting.rst @@ -34,13 +34,15 @@ first step, open your **app/Config/App.php** file and look for the URI Protocol information. It will recommend that you try a couple of alternate settings. If it still doesn't work after you've tried this you'll need to force CodeIgniter to add a question mark to your URLs. To -do this open your **app/Config/App.php** file and change this:: +do this open your **app/Config/App.php** file and change this: - public $indexPage = 'index.php'; +.. literalinclude:: troubleshooting/001.php + :lines: 2- -To this:: +To this: - public $indexPage = 'index.php?'; +.. literalinclude:: troubleshooting/002.php + :lines: 2- The tutorial gives 404 errors everywhere :( ------------------------------------------- diff --git a/user_guide_src/source/installation/troubleshooting/001.php b/user_guide_src/source/installation/troubleshooting/001.php new file mode 100644 index 000000000000..54798c261dae --- /dev/null +++ b/user_guide_src/source/installation/troubleshooting/001.php @@ -0,0 +1,3 @@ + ['csrf'], - 'post' => ['csrf'], - ]; +.. literalinclude:: upgrade_415/001.php + :lines: 2- Protecting **GET** method needs only when you use ``form_open()`` auto-generation of CSRF field. diff --git a/user_guide_src/source/installation/upgrade_415/001.php b/user_guide_src/source/installation/upgrade_415/001.php new file mode 100644 index 000000000000..e2b03e79ba25 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_415/001.php @@ -0,0 +1,6 @@ + ['csrf'], + 'post' => ['csrf'], +]; diff --git a/user_guide_src/source/installation/upgrade_configuration.rst b/user_guide_src/source/installation/upgrade_configuration.rst index fa168b2627ed..21ae6101c158 100644 --- a/user_guide_src/source/installation/upgrade_configuration.rst +++ b/user_guide_src/source/installation/upgrade_configuration.rst @@ -11,7 +11,6 @@ Documentations - `Config Documentation CodeIgniter 3.X `_ - :doc:`Configuration Documentation CodeIgniter 4.X ` - What has been changed ===================== @@ -39,28 +38,13 @@ Code Example CodeIgniter Version 3.x ------------------------ -Path: **application/config**:: - - `_ - :doc:`Working with Databases Documentation CodeIgniter 4.X ` - What has been changed ===================== - The functionality in CI3 is basically the same as in CI4. @@ -42,26 +40,17 @@ Upgrade Guide - ``$this->db->join('comments', 'comments.id = blogs.id');`` to ``$builder->join('comments', 'comments.id = blogs.id');`` - ``$this->db->having('user_id', 45);`` to ``$builder->having('user_id', 45);`` - Code Example ============ CodeIgniter Version 3.x ------------------------ -:: - $query = $this->db->select('title') - ->where('id', $id) - ->limit(10, 20) - ->get('mytable'); +.. literalinclude:: upgrade_database/001.php + :lines: 2- CodeIgniter Version 4.x ----------------------- -:: - - $builder = $db->table('mytable'); - $query = $builder->select('title') - ->where('id', $id) - ->limit(10, 20) - ->get(); +.. literalinclude:: upgrade_database/002.php + :lines: 2- diff --git a/user_guide_src/source/installation/upgrade_database/001.php b/user_guide_src/source/installation/upgrade_database/001.php new file mode 100644 index 000000000000..5dd7b11a60e7 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_database/001.php @@ -0,0 +1,6 @@ +db->select('title') + ->where('id', $id) + ->limit(10, 20) + ->get('mytable'); diff --git a/user_guide_src/source/installation/upgrade_database/002.php b/user_guide_src/source/installation/upgrade_database/002.php new file mode 100644 index 000000000000..65fdc4c24d1b --- /dev/null +++ b/user_guide_src/source/installation/upgrade_database/002.php @@ -0,0 +1,8 @@ +table('mytable'); + +$query = $builder->select('title') + ->where('id', $id) + ->limit(10, 20) + ->get(); diff --git a/user_guide_src/source/installation/upgrade_emails.rst b/user_guide_src/source/installation/upgrade_emails.rst index af5e532262aa..155562ba4a1a 100644 --- a/user_guide_src/source/installation/upgrade_emails.rst +++ b/user_guide_src/source/installation/upgrade_emails.rst @@ -5,14 +5,12 @@ Upgrade Emails :local: :depth: 2 - Documentations ============== - `Email Documentation CodeIgniter 3.X `_ - :doc:`Email Documentation CodeIgniter 4.X ` - What has been changed ===================== - Only small things like the method names and the loading of the library have changed. @@ -29,32 +27,12 @@ Code Example CodeIgniter Version 3.x ------------------------ -:: - - $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->subject('Email Test'); - $this->email->message('Testing the email class.'); - - $this->email->send(); +.. literalinclude:: upgrade_emails/001.php + :lines: 2- CodeIgniter Version 4.x ----------------------- -:: - - $email = service('email'); - - $email->setFrom('your@example.com', 'Your Name'); - $email->setTo('someone@example.com'); - $email->setCC('another@another-example.com'); - $email->setBCC('them@their-example.com'); - - $email->setSubject('Email Test'); - $email->setMessage('Testing the email class.'); - $email->send(); +.. literalinclude:: upgrade_emails/002.php + :lines: 2- diff --git a/user_guide_src/source/installation/upgrade_emails/001.php b/user_guide_src/source/installation/upgrade_emails/001.php new file mode 100644 index 000000000000..e9144bb87f6e --- /dev/null +++ b/user_guide_src/source/installation/upgrade_emails/001.php @@ -0,0 +1,13 @@ +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->subject('Email Test'); +$this->email->message('Testing the email class.'); + +$this->email->send(); diff --git a/user_guide_src/source/installation/upgrade_emails/002.php b/user_guide_src/source/installation/upgrade_emails/002.php new file mode 100644 index 000000000000..f7873714bab5 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_emails/002.php @@ -0,0 +1,13 @@ +setFrom('your@example.com', 'Your Name'); +$email->setTo('someone@example.com'); +$email->setCC('another@another-example.com'); +$email->setBCC('them@their-example.com'); + +$email->setSubject('Email Test'); +$email->setMessage('Testing the email class.'); + +$email->send(); diff --git a/user_guide_src/source/installation/upgrade_encryption.rst b/user_guide_src/source/installation/upgrade_encryption.rst index d9a29af62650..5915ca00dca1 100644 --- a/user_guide_src/source/installation/upgrade_encryption.rst +++ b/user_guide_src/source/installation/upgrade_encryption.rst @@ -5,14 +5,12 @@ Upgrade Encryption :local: :depth: 2 - Documentations ============== - `Encryption Library Documentation CodeIgniter 3.X `_ - :doc:`Encryption Service Documentation CodeIgniter 4.X ` - What has been changed ===================== - The support for ``MCrypt`` has been dropped, as that has been deprecated as of PHP 7.2. @@ -27,25 +25,12 @@ Code Example CodeIgniter Version 3.x ------------------------ -:: - - $this->load->library('encryption'); - - $plain_text = 'This is a plain-text message!'; - $ciphertext = $this->encryption->encrypt($plain_text); - - // Outputs: This is a plain-text message! - echo $this->encryption->decrypt($ciphertext); +.. literalinclude:: upgrade_encryption/001.php + :lines: 2- CodeIgniter Version 4.x ----------------------- -:: - - $encrypter = service('encrypter'); - - $plainText = 'This is a plain-text message!'; - $ciphertext = $encrypter->encrypt($plainText); - // Outputs: This is a plain-text message! - echo $encrypter->decrypt($ciphertext); +.. literalinclude:: upgrade_encryption/002.php + :lines: 2- diff --git a/user_guide_src/source/installation/upgrade_encryption/001.php b/user_guide_src/source/installation/upgrade_encryption/001.php new file mode 100644 index 000000000000..b20ba8aec855 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_encryption/001.php @@ -0,0 +1,9 @@ +load->library('encryption'); + +$plain_text = 'This is a plain-text message!'; +$ciphertext = $this->encryption->encrypt($plain_text); + +// Outputs: This is a plain-text message! +echo $this->encryption->decrypt($ciphertext); diff --git a/user_guide_src/source/installation/upgrade_encryption/002.php b/user_guide_src/source/installation/upgrade_encryption/002.php new file mode 100644 index 000000000000..91b00ee54e83 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_encryption/002.php @@ -0,0 +1,9 @@ +encrypt($plainText); + +// Outputs: This is a plain-text message! +echo $encrypter->decrypt($ciphertext); diff --git a/user_guide_src/source/installation/upgrade_file_upload.rst b/user_guide_src/source/installation/upgrade_file_upload.rst index 27bd74e19a74..f0eb3a24c405 100644 --- a/user_guide_src/source/installation/upgrade_file_upload.rst +++ b/user_guide_src/source/installation/upgrade_file_upload.rst @@ -5,7 +5,6 @@ Upgrade Working with Uploaded Files :local: :depth: 2 - Documentations ============== - `Output Class Documentation CodeIgniter 3.X `_ @@ -27,76 +26,10 @@ Code Example CodeIgniter Version 3.x ------------------------ -:: - - load->helper(array('form', 'url')); - } - - public function index() - { - $this->load->view('upload_form', array('error' => ' ' )); - } - - public function do_upload() - { - $config['upload_path'] = './uploads/'; - $config['allowed_types'] = 'png|jpg|gif'; - $config['max_size'] = 100; - $config['max_width'] = 1024; - $config['max_height'] = 768; - - $this->load->library('upload', $config); - - if (! $this->upload->do_upload('userfile')) { - $error = array('error' => $this->upload->display_errors()); - $this->load->view('upload_form', $error); - } else { - $data = array('upload_data' => $this->upload->data()); - - $this->load->view('upload_success', $data); - } - } - } +.. literalinclude:: upgrade_file_upload/001.php CodeIgniter Version 4.x ----------------------- -:: - - ' ']); - } - - public function do_upload() - { - $this->validate([ - 'userfile' => 'uploaded[userfile]|max_size[userfile,100]' - . '|mime_in[userfile,image/png,image/jpg,image/gif]' - . '|ext_in[userfile,png,jpg,gif]|max_dims[userfile,1024,768]' - ]); - - $file = $this->request->getFile('userfile'); - - if (! $path = $file->store()) { - echo view('upload_form', ['error' => "upload failed"]); - } else { - $data = ['upload_file_path' => $path]; - echo view('upload_success', $data); - } - } - } +.. literalinclude:: upgrade_file_upload/002.php diff --git a/user_guide_src/source/installation/upgrade_file_upload/001.php b/user_guide_src/source/installation/upgrade_file_upload/001.php new file mode 100644 index 000000000000..f6bb20c64de3 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_file_upload/001.php @@ -0,0 +1,36 @@ +load->helper(array('form', 'url')); + } + + public function index() + { + $this->load->view('upload_form', array('error' => ' ' )); + } + + public function do_upload() + { + $config['upload_path'] = './uploads/'; + $config['allowed_types'] = 'png|jpg|gif'; + $config['max_size'] = 100; + $config['max_width'] = 1024; + $config['max_height'] = 768; + + $this->load->library('upload', $config); + + if (! $this->upload->do_upload('userfile')) { + $error = array('error' => $this->upload->display_errors()); + + $this->load->view('upload_form', $error); + } else { + $data = array('upload_data' => $this->upload->data()); + + $this->load->view('upload_success', $data); + } + } +} diff --git a/user_guide_src/source/installation/upgrade_file_upload/002.php b/user_guide_src/source/installation/upgrade_file_upload/002.php new file mode 100644 index 000000000000..29de4bf665dc --- /dev/null +++ b/user_guide_src/source/installation/upgrade_file_upload/002.php @@ -0,0 +1,30 @@ + ' ']); + } + + public function do_upload() + { + $this->validate([ + 'userfile' => 'uploaded[userfile]|max_size[userfile,100]' + . '|mime_in[userfile,image/png,image/jpg,image/gif]' + . '|ext_in[userfile,png,jpg,gif]|max_dims[userfile,1024,768]' + ]); + + $file = $this->request->getFile('userfile'); + + if (! $path = $file->store()) { + echo view('upload_form', ['error' => "upload failed"]); + } else { + $data = ['upload_file_path' => $path]; + + echo view('upload_success', $data); + } + } +} diff --git a/user_guide_src/source/installation/upgrade_html_tables.rst b/user_guide_src/source/installation/upgrade_html_tables.rst index 1fb70790ccbc..23e6aea3526b 100644 --- a/user_guide_src/source/installation/upgrade_html_tables.rst +++ b/user_guide_src/source/installation/upgrade_html_tables.rst @@ -5,14 +5,12 @@ Upgrade HTML Tables :local: :depth: 2 - Documentations ============== - `HTML Table Documentation CodeIgniter 3.X `_ - :doc:`HTML Table Documentation CodeIgniter 4.X ` - What has been changed ===================== - Only small things like the method names and the loading of the library have changed. @@ -28,28 +26,12 @@ Code Example CodeIgniter Version 3.x ------------------------ -:: - - $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(); +.. literalinclude:: upgrade_html_tables/001.php + :lines: 2- CodeIgniter Version 4.x ----------------------- -:: - - $table = new \CodeIgniter\View\Table(); - - $table->setHeading('Name', 'Color', 'Size'); - - $table->addRow('Fred', 'Blue', 'Small'); - $table->addRow('Mary', 'Red', 'Large'); - $table->addRow('John', 'Green', 'Medium'); - echo $table->generate(); +.. literalinclude:: upgrade_html_tables/002.php + :lines: 2- diff --git a/user_guide_src/source/installation/upgrade_html_tables/001.php b/user_guide_src/source/installation/upgrade_html_tables/001.php new file mode 100644 index 000000000000..5e607318c36f --- /dev/null +++ b/user_guide_src/source/installation/upgrade_html_tables/001.php @@ -0,0 +1,11 @@ +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(); diff --git a/user_guide_src/source/installation/upgrade_html_tables/002.php b/user_guide_src/source/installation/upgrade_html_tables/002.php new file mode 100644 index 000000000000..0d0679305409 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_html_tables/002.php @@ -0,0 +1,11 @@ +setHeading('Name', 'Color', 'Size'); + +$table->addRow('Fred', 'Blue', 'Small'); +$table->addRow('Mary', 'Red', 'Large'); +$table->addRow('John', 'Green', 'Medium'); + +echo $table->generate(); diff --git a/user_guide_src/source/installation/upgrade_localization.rst b/user_guide_src/source/installation/upgrade_localization.rst index 8362b711aa3f..3fec8c15cce0 100644 --- a/user_guide_src/source/installation/upgrade_localization.rst +++ b/user_guide_src/source/installation/upgrade_localization.rst @@ -5,23 +5,22 @@ Upgrade Localization :local: :depth: 2 - Documentations ============== - `Language Documentation CodeIgniter 3.X `_ - :doc:`Localization Documentation CodeIgniter 4.X ` - What has been changed ===================== - In CI4 the language files return the language lines as array. Upgrade Guide ============= -1. Specify the default language in **Config/App.php**:: +1. Specify the default language in **Config/App.php**: - public $defaultLocale = 'en'; + .. literalinclude:: upgrade_localization/001.php + :lines: 2- 2. Now move your language files to **app/Language/**. 3. After that you have to change the syntax within the language files. Below in the Code Example you will see how the language array within the file should look like. @@ -33,34 +32,12 @@ Code Example CodeIgniter Version 3.x ------------------------ -:: - - // error.php - $lang['error_email_missing'] = 'You must submit an email address'; - $lang['error_url_missing'] = 'You must submit a URL'; - $lang['error_username_missing'] = 'You must submit a username'; - ... - - $this->lang->load('error', $lang); - echo $this->lang->line('error_email_missing'); +.. literalinclude:: upgrade_localization/002.php + :lines: 2- CodeIgniter Version 4.x ----------------------- -:: - - // Errors.php - return [ - 'errorEmailMissing' => 'You must submit an email address', - 'errorURLMissing' => 'You must submit a URL', - 'errorUsernameMissing' => 'You must submit a username', - 'nested' => [ - 'error' => [ - 'message' => 'A specific error message', - ], - ], - ]; - - ... - echo lang('Errors.errorEmailMissing'); +.. literalinclude:: upgrade_localization/003.php + :lines: 2- diff --git a/user_guide_src/source/installation/upgrade_localization/001.php b/user_guide_src/source/installation/upgrade_localization/001.php new file mode 100644 index 000000000000..c3b3de65be20 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_localization/001.php @@ -0,0 +1,3 @@ +lang->load('error', $lang); +echo $this->lang->line('error_email_missing'); diff --git a/user_guide_src/source/installation/upgrade_localization/003.php b/user_guide_src/source/installation/upgrade_localization/003.php new file mode 100644 index 000000000000..e0149516841d --- /dev/null +++ b/user_guide_src/source/installation/upgrade_localization/003.php @@ -0,0 +1,17 @@ + 'You must submit an email address', + 'errorURLMissing' => 'You must submit a URL', + 'errorUsernameMissing' => 'You must submit a username', + 'nested' => [ + 'error' => [ + 'message' => 'A specific error message', + ], + ], +]; + +... + +echo lang('Errors.errorEmailMissing'); diff --git a/user_guide_src/source/installation/upgrade_migrations.rst b/user_guide_src/source/installation/upgrade_migrations.rst index cf9b7c951511..07dc32e96675 100644 --- a/user_guide_src/source/installation/upgrade_migrations.rst +++ b/user_guide_src/source/installation/upgrade_migrations.rst @@ -51,82 +51,16 @@ Code Example CodeIgniter Version 3.x ------------------------ -Path: **application/migrations**:: - - dbforge->add_field(array( - 'blog_id' => array( - 'type' => 'INT', - 'constraint' => 5, - 'unsigned' => true, - 'auto_increment' => true, - ), - 'blog_title' => array( - 'type' => 'VARCHAR', - 'constraint' => '100', - ), - 'blog_description' => array( - 'type' => 'TEXT', - 'null' => true, - ), - )); - $this->dbforge->add_key('blog_id', true); - $this->dbforge->create_table('blog'); - } - - public function down() - { - $this->dbforge->drop_table('blog'); - } - } +Path: **application/migrations**: + +.. literalinclude:: upgrade_migrations/001.php CodeIgniter Version 4.x ----------------------- -Path: **app/Database/Migrations**:: - - forge->addField([ - 'blog_id' => [ - 'type' => 'INT', - 'constraint' => 5, - 'unsigned' => true, - 'auto_increment' => true, - ], - 'blog_title' => [ - 'type' => 'VARCHAR', - 'constraint' => '100', - ], - 'blog_description' => [ - 'type' => 'TEXT', - 'null' => true, - ], - ]); - $this->forge->addKey('blog_id', true); - $this->forge->createTable('blog'); - } - - public function down() - { - $this->forge->dropTable('blog'); - } - } +Path: **app/Database/Migrations**: + +.. literalinclude:: upgrade_migrations/002.php Search & Replace ================ diff --git a/user_guide_src/source/installation/upgrade_migrations/001.php b/user_guide_src/source/installation/upgrade_migrations/001.php new file mode 100644 index 000000000000..2437a8d5fa99 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_migrations/001.php @@ -0,0 +1,33 @@ +dbforge->add_field(array( + 'blog_id' => array( + 'type' => 'INT', + 'constraint' => 5, + 'unsigned' => true, + 'auto_increment' => true, + ), + 'blog_title' => array( + 'type' => 'VARCHAR', + 'constraint' => '100', + ), + 'blog_description' => array( + 'type' => 'TEXT', + 'null' => true, + ), + )); + $this->dbforge->add_key('blog_id', true); + $this->dbforge->create_table('blog'); + } + + public function down() + { + $this->dbforge->drop_table('blog'); + } +} diff --git a/user_guide_src/source/installation/upgrade_migrations/002.php b/user_guide_src/source/installation/upgrade_migrations/002.php new file mode 100644 index 000000000000..3f73906231f1 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_migrations/002.php @@ -0,0 +1,35 @@ +forge->addField([ + 'blog_id' => [ + 'type' => 'INT', + 'constraint' => 5, + 'unsigned' => true, + 'auto_increment' => true, + ], + 'blog_title' => [ + 'type' => 'VARCHAR', + 'constraint' => '100', + ], + 'blog_description' => [ + 'type' => 'TEXT', + 'null' => true, + ], + ]); + $this->forge->addKey('blog_id', true); + $this->forge->createTable('blog'); + } + + public function down() + { + $this->forge->dropTable('blog'); + } +} diff --git a/user_guide_src/source/installation/upgrade_models.rst b/user_guide_src/source/installation/upgrade_models.rst index dce4dd31377a..1b01819d9455 100644 --- a/user_guide_src/source/installation/upgrade_models.rst +++ b/user_guide_src/source/installation/upgrade_models.rst @@ -11,7 +11,6 @@ Documentations - `Model Documentation CodeIgniter 3.X `_ - :doc:`Model Documentation CodeIgniter 4.X ` - What has been changed ===================== @@ -41,36 +40,15 @@ Code Example CodeIgniter Version 3.x ------------------------ -Path: **application/models**:: - - db->insert('user_contacts', array( - 'name' => $name, - 'address' => $address, - 'email' => $email, - )); - } - } +.. literalinclude:: upgrade_models/001.php CodeIgniter Version 4.x ----------------------- -Path: **app/Models**:: - - insert()`` method because this method is built-in since CI4. diff --git a/user_guide_src/source/installation/upgrade_models/001.php b/user_guide_src/source/installation/upgrade_models/001.php new file mode 100644 index 000000000000..1ab3917c6a7f --- /dev/null +++ b/user_guide_src/source/installation/upgrade_models/001.php @@ -0,0 +1,13 @@ +db->insert('user_contacts', array( + 'name' => $name, + 'address' => $address, + 'email' => $email, + )); + } +} diff --git a/user_guide_src/source/installation/upgrade_models/002.php b/user_guide_src/source/installation/upgrade_models/002.php new file mode 100644 index 000000000000..0d7882ed2f52 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_models/002.php @@ -0,0 +1,10 @@ +`_ - :doc:`Pagination Documentation CodeIgniter 4.X ` - What has been changed ===================== - You have to change the views and also the controller in order to use the new pagination library. @@ -30,35 +28,17 @@ Upgrade Guide - You can use the built-in ``paginate()`` method on every Model. Have a look at the code example below to see how you setup the pagination on a specific model. - Code Example ============ CodeIgniter Version 3.x ------------------------ -:: - - $this->load->library('pagination'); - $config['base_url'] = base_url().'users/index/'; - $config['total_rows'] = $this->db->count_all('users'); - $config['per_page'] = 10; - $config['uri_segment'] = 3; - $config['attributes'] = array('class' => 'pagination-link'); - $this->pagination->initialize($config); - $data['users'] = $this->user_model->get_users(FALSE, $config['per_page'], $offset); - - $this->load->view('posts/index', $data); +.. literalinclude:: upgrade_pagination/001.php + :lines: 2- CodeIgniter Version 4.x ----------------------- -:: - - $model = new \App\Models\UserModel(); - - $data = [ - 'users' => $model->paginate(10), - 'pager' => $model->pager, - ]; - echo view('users/index', $data); +.. literalinclude:: upgrade_pagination/002.php + :lines: 2- diff --git a/user_guide_src/source/installation/upgrade_pagination/001.php b/user_guide_src/source/installation/upgrade_pagination/001.php new file mode 100644 index 000000000000..37a6f849c67c --- /dev/null +++ b/user_guide_src/source/installation/upgrade_pagination/001.php @@ -0,0 +1,13 @@ +load->library('pagination'); +$config['base_url'] = base_url().'users/index/'; +$config['total_rows'] = $this->db->count_all('users'); +$config['per_page'] = 10; +$config['uri_segment'] = 3; +$config['attributes'] = array('class' => 'pagination-link'); +$this->pagination->initialize($config); + +$data['users'] = $this->user_model->get_users(FALSE, $config['per_page'], $offset); + +$this->load->view('posts/index', $data); diff --git a/user_guide_src/source/installation/upgrade_pagination/002.php b/user_guide_src/source/installation/upgrade_pagination/002.php new file mode 100644 index 000000000000..fa1b373a5fc6 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_pagination/002.php @@ -0,0 +1,10 @@ + $model->paginate(10), + 'pager' => $model->pager, +]; + +echo view('users/index', $data); diff --git a/user_guide_src/source/installation/upgrade_responses.rst b/user_guide_src/source/installation/upgrade_responses.rst index 4518836371c9..9af660e35097 100644 --- a/user_guide_src/source/installation/upgrade_responses.rst +++ b/user_guide_src/source/installation/upgrade_responses.rst @@ -5,7 +5,6 @@ Upgrade HTTP Responses :local: :depth: 2 - Documentations ============== - `Output Class Documentation CodeIgniter 3.X `_ @@ -25,22 +24,12 @@ Code Example CodeIgniter Version 3.x ------------------------ -:: - - $this->output->set_status_header(404); - - ... - $this->output - ->set_content_type('application/json') - ->set_output(json_encode(array('foo' => 'bar'))); +.. literalinclude:: upgrade_responses/001.php + :lines: 2- CodeIgniter Version 4.x ----------------------- -:: - - $this->response->setStatusCode(404); - - ... - return $this->response->setJSON(['foo' => 'bar']); +.. literalinclude:: upgrade_responses/002.php + :lines: 2- diff --git a/user_guide_src/source/installation/upgrade_responses/001.php b/user_guide_src/source/installation/upgrade_responses/001.php new file mode 100644 index 000000000000..f837ab8b6c3b --- /dev/null +++ b/user_guide_src/source/installation/upgrade_responses/001.php @@ -0,0 +1,9 @@ +output->set_status_header(404); + +... + +$this->output + ->set_content_type('application/json') + ->set_output(json_encode(array('foo' => 'bar'))); diff --git a/user_guide_src/source/installation/upgrade_responses/002.php b/user_guide_src/source/installation/upgrade_responses/002.php new file mode 100644 index 000000000000..e84279cf273c --- /dev/null +++ b/user_guide_src/source/installation/upgrade_responses/002.php @@ -0,0 +1,7 @@ +response->setStatusCode(404); + +... + +return $this->response->setJSON(['foo' => 'bar']); diff --git a/user_guide_src/source/installation/upgrade_routing.rst b/user_guide_src/source/installation/upgrade_routing.rst index b3fe276d6fcc..533826babd29 100644 --- a/user_guide_src/source/installation/upgrade_routing.rst +++ b/user_guide_src/source/installation/upgrade_routing.rst @@ -5,14 +5,12 @@ Upgrade Routing :local: :depth: 2 - Documentations ============== - `URI Routing Documentation CodeIgniter 3.X `_ - :doc:`URI Routing Documentation CodeIgniter 4.X ` - What has been changed ===================== - In CI4 the routing is no longer configured by setting the routes as array. @@ -30,46 +28,12 @@ Code Example CodeIgniter Version 3.x ------------------------ -Path: **application/config/routes.php**:: - - add('posts/index', 'Posts::index'); - $routes->add('teams/create', 'Teams::create'); - $routes->add('teams/update', 'Teams::update'); +Path: **app/Config/Routes.php**: - $routes->add('posts/create', 'Posts::create'); - $routes->add('posts/update', 'Posts::update'); - $routes->add('drivers/create', 'Drivers::create'); - $routes->add('drivers/update', 'Drivers::update'); - $routes->add('posts/(:any)', 'Posts::view/$1'); +.. literalinclude:: upgrade_routing/002.php diff --git a/user_guide_src/source/installation/upgrade_routing/001.php b/user_guide_src/source/installation/upgrade_routing/001.php new file mode 100644 index 000000000000..31875312f013 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_routing/001.php @@ -0,0 +1,12 @@ +add('posts/index', 'Posts::index'); +$routes->add('teams/create', 'Teams::create'); +$routes->add('teams/update', 'Teams::update'); + +$routes->add('posts/create', 'Posts::create'); +$routes->add('posts/update', 'Posts::update'); +$routes->add('drivers/create', 'Drivers::create'); +$routes->add('drivers/update', 'Drivers::update'); +$routes->add('posts/(:any)', 'Posts::view/$1'); diff --git a/user_guide_src/source/installation/upgrade_security.rst b/user_guide_src/source/installation/upgrade_security.rst index ad1fc80e945b..6fbdbc2428a6 100644 --- a/user_guide_src/source/installation/upgrade_security.rst +++ b/user_guide_src/source/installation/upgrade_security.rst @@ -5,7 +5,6 @@ Upgrade Security :local: :depth: 2 - Documentations ============== @@ -21,14 +20,10 @@ What has been changed Upgrade Guide ============= -1. To enable CSRF protection in CI4 you have to enable it in **app/Config/Filters.php**:: +1. To enable CSRF protection in CI4 you have to enable it in **app/Config/Filters.php**: - public $globals = [ - 'before' => [ - //'honeypot', - 'csrf', - ] - ]; + .. literalinclude:: upgrade_security/001.php + :lines: 2- 2. Within your HTML forms you have to remove the CSRF input field which looks similar to ````. 3. Now, within your HTML forms you have to add ```` somewhere in the form body, unless you are using ``form_open()``. @@ -38,23 +33,9 @@ Code Example CodeIgniter Version 3.x ------------------------ -:: - - $csrf = array( - 'name' => $this->security->get_csrf_token_name(), - 'hash' => $this->security->get_csrf_hash() - ); - ... - -
    - - - - - - -
    +.. literalinclude:: upgrade_security/002.php + :lines: 2- CodeIgniter Version 4.x ----------------------- diff --git a/user_guide_src/source/installation/upgrade_security/001.php b/user_guide_src/source/installation/upgrade_security/001.php new file mode 100644 index 000000000000..d1bc3788b2ce --- /dev/null +++ b/user_guide_src/source/installation/upgrade_security/001.php @@ -0,0 +1,8 @@ + [ + //'honeypot', + 'csrf', + ] +]; diff --git a/user_guide_src/source/installation/upgrade_security/002.php b/user_guide_src/source/installation/upgrade_security/002.php new file mode 100644 index 000000000000..0419285423b0 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_security/002.php @@ -0,0 +1,17 @@ + $this->security->get_csrf_token_name(), + 'hash' => $this->security->get_csrf_hash() +); + +... + +
    + + + + + + +
    diff --git a/user_guide_src/source/installation/upgrade_sessions.rst b/user_guide_src/source/installation/upgrade_sessions.rst index 6785907ba061..447703854284 100644 --- a/user_guide_src/source/installation/upgrade_sessions.rst +++ b/user_guide_src/source/installation/upgrade_sessions.rst @@ -5,14 +5,12 @@ Upgrade Sessions :local: :depth: 2 - Documentations ============== - `Session Library Documentation CodeIgniter 3.X `_ - :doc:`Session Library Documentation CodeIgniter 4.X ` - What has been changed ===================== - Only small things like the method names and the loading of the library have changed. @@ -32,21 +30,12 @@ Code Example CodeIgniter Version 3.x ------------------------ -:: - $this->load->library('session'); - - $_SESSION['item']; - $this->session->item; - $this->session->userdata('item'); +.. literalinclude:: upgrade_sessions/001.php + :lines: 2- CodeIgniter Version 4.x ----------------------- -:: - - $session = session(); - $_SESSION['item']; - $session->get('item'); - $session->item; - session('item'); +.. literalinclude:: upgrade_sessions/002.php + :lines: 2- diff --git a/user_guide_src/source/installation/upgrade_sessions/001.php b/user_guide_src/source/installation/upgrade_sessions/001.php new file mode 100644 index 000000000000..73e69c5dfa9f --- /dev/null +++ b/user_guide_src/source/installation/upgrade_sessions/001.php @@ -0,0 +1,7 @@ +load->library('session'); + +$_SESSION['item']; +$this->session->item; +$this->session->userdata('item'); diff --git a/user_guide_src/source/installation/upgrade_sessions/002.php b/user_guide_src/source/installation/upgrade_sessions/002.php new file mode 100644 index 000000000000..0bfeeb7f9487 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_sessions/002.php @@ -0,0 +1,8 @@ +get('item'); +$session->item; +session('item'); diff --git a/user_guide_src/source/installation/upgrade_validations.rst b/user_guide_src/source/installation/upgrade_validations.rst index 1a71ef0b5065..54b7281d4839 100644 --- a/user_guide_src/source/installation/upgrade_validations.rst +++ b/user_guide_src/source/installation/upgrade_validations.rst @@ -5,14 +5,12 @@ Upgrade Validations :local: :depth: 2 - Documentations of Library ========================= - `Form Validation Documentation CodeIgniter 3.X `_ - :doc:`Validation Documentation CodeIgniter 4.X ` - What has been changed ===================== - If you want to change validation error display, you have to set CI4 validation View templates. @@ -33,13 +31,10 @@ Upgrade Guide - ``if ($this->form_validation->run() == FALSE)`` to ``if (! $this->validate([]))`` - ``$this->load->view('myform');`` to ``echo view('myform', ['validation' => $this->validator,]);`` -3. You have to change the validation rules. The new syntax is to set the rules as array in the controller:: +3. You have to change the validation rules. The new syntax is to set the rules as array in the controller: - $isValid = $this->validate([ - 'name' => 'required|min_length[3]', - 'email' => 'required|valid_email', - 'phone' => 'required|numeric|max_length[10]' - ]); + .. literalinclude:: upgrade_validations/001.php + :lines: 2- Code Example ============ @@ -77,27 +72,9 @@ Path: **application/views**:: -Path: **application/controllers**:: - - load->helper(array('form', 'url')); - - $this->load->library('form_validation'); +Path: **application/controllers**: - // Set validation rules - - if ($this->form_validation->run() == FALSE) { - $this->load->view('myform'); - } else { - $this->load->view('formsuccess'); - } - } - } +.. literalinclude:: upgrade_validations/002.php CodeIgniter Version 4.x ----------------------- @@ -132,28 +109,6 @@ Path: **app/Views**:: -Path: **app/Controllers**:: - - validate([ - // Validation rules - ])) { - echo view('myform', [ - 'validation' => $this->validator, - ]); - } else { - echo view('formsuccess'); - } - } - } +.. literalinclude:: upgrade_validations/003.php diff --git a/user_guide_src/source/installation/upgrade_validations/001.php b/user_guide_src/source/installation/upgrade_validations/001.php new file mode 100644 index 000000000000..f9730b8f3e3f --- /dev/null +++ b/user_guide_src/source/installation/upgrade_validations/001.php @@ -0,0 +1,7 @@ +validate([ + 'name' => 'required|min_length[3]', + 'email' => 'required|valid_email', + 'phone' => 'required|numeric|max_length[10]' +]); diff --git a/user_guide_src/source/installation/upgrade_validations/002.php b/user_guide_src/source/installation/upgrade_validations/002.php new file mode 100644 index 000000000000..3c6505455d91 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_validations/002.php @@ -0,0 +1,19 @@ +load->helper(array('form', 'url')); + + $this->load->library('form_validation'); + + // Set validation rules + + if ($this->form_validation->run() == FALSE) { + $this->load->view('myform'); + } else { + $this->load->view('formsuccess'); + } + } +} diff --git a/user_guide_src/source/installation/upgrade_validations/003.php b/user_guide_src/source/installation/upgrade_validations/003.php new file mode 100644 index 000000000000..ddbed1ede5fc --- /dev/null +++ b/user_guide_src/source/installation/upgrade_validations/003.php @@ -0,0 +1,23 @@ +validate([ + // Validation rules + ])) { + echo view('myform', [ + 'validation' => $this->validator, + ]); + } else { + echo view('formsuccess'); + } + } +} diff --git a/user_guide_src/source/installation/upgrade_view_parser.rst b/user_guide_src/source/installation/upgrade_view_parser.rst index b2c57adbf0e6..4931eb467ede 100644 --- a/user_guide_src/source/installation/upgrade_view_parser.rst +++ b/user_guide_src/source/installation/upgrade_view_parser.rst @@ -5,14 +5,12 @@ Upgrade View Parser :local: :depth: 2 - Documentations ============== - `Template Parser Documentation CodeIgniter 3.X `_ - :doc:`View Parser Documentation CodeIgniter 4.X ` - What has been changed ===================== - You have to change the implementation and loading of the Parser Library. @@ -28,28 +26,12 @@ Code Example CodeIgniter Version 3.x ------------------------ -:: - - $this->load->library('parser'); - $data = array( - 'blog_title' => 'My Blog Title', - 'blog_heading' => 'My Blog Heading' - ); - - $this->parser - ->parse('blog_template', $data); +.. literalinclude:: upgrade_view_parser/001.php + :lines: 2- CodeIgniter Version 4.x ----------------------- -:: - - $parser = service('parser'); - - $data = [ - 'blog_title' => 'My Blog Title', - 'blog_heading' => 'My Blog Heading' - ]; - echo $parser->setData($data) - ->render('blog_template'); +.. literalinclude:: upgrade_view_parser/002.php + :lines: 2- diff --git a/user_guide_src/source/installation/upgrade_view_parser/001.php b/user_guide_src/source/installation/upgrade_view_parser/001.php new file mode 100644 index 000000000000..c44e00968315 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_view_parser/001.php @@ -0,0 +1,11 @@ +load->library('parser'); + +$data = array( + 'blog_title' => 'My Blog Title', + 'blog_heading' => 'My Blog Heading' +); + +$this->parser + ->parse('blog_template', $data); diff --git a/user_guide_src/source/installation/upgrade_view_parser/002.php b/user_guide_src/source/installation/upgrade_view_parser/002.php new file mode 100644 index 000000000000..2f4607092635 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_view_parser/002.php @@ -0,0 +1,11 @@ + 'My Blog Title', + 'blog_heading' => 'My Blog Heading' +]; + +echo $parser->setData($data) + ->render('blog_template'); diff --git a/user_guide_src/source/installation/upgrade_views.rst b/user_guide_src/source/installation/upgrade_views.rst index 0aef96b113e8..773ad6541931 100644 --- a/user_guide_src/source/installation/upgrade_views.rst +++ b/user_guide_src/source/installation/upgrade_views.rst @@ -34,45 +34,13 @@ Code Example CodeIgniter Version 3.x ------------------------ -Path: **application/views**:: +Path: **application/views**: - - - <?php echo $title; ?> - - -

    - -

    My Todo List

    - -
      - -
    • - -
    - - - +.. literalinclude:: upgrade_views/001.php CodeIgniter Version 4.x ----------------------- -Path: **app/Views**:: - - - - <?= esc($title) ?> - - -

    - -

    My Todo List

    - -
      - -
    • - -
    +Path: **app/Views**: - - +.. literalinclude:: upgrade_views/002.php diff --git a/user_guide_src/source/installation/upgrade_views/001.php b/user_guide_src/source/installation/upgrade_views/001.php new file mode 100644 index 000000000000..f0b7c348666d --- /dev/null +++ b/user_guide_src/source/installation/upgrade_views/001.php @@ -0,0 +1,17 @@ + + + <?php echo $title; ?> + + +

    + +

    My Todo List

    + +
      + +
    • + +
    + + + diff --git a/user_guide_src/source/installation/upgrade_views/002.php b/user_guide_src/source/installation/upgrade_views/002.php new file mode 100644 index 000000000000..d4d043fea310 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_views/002.php @@ -0,0 +1,17 @@ + + + <?= esc($title) ?> + + +

    + +

    My Todo List

    + +
      + +
    • + +
    + + + diff --git a/user_guide_src/source/libraries/caching.rst b/user_guide_src/source/libraries/caching.rst index cc9049ee9a5d..6f4fb8071c74 100644 --- a/user_guide_src/source/libraries/caching.rst +++ b/user_guide_src/source/libraries/caching.rst @@ -17,23 +17,13 @@ Example Usage The following example shows a common usage pattern within your controllers. -:: +.. literalinclude:: caching/001.php + :lines: 2- - if (! $foo = cache('foo')) { - echo 'Saving to the cache!
    '; - $foo = 'foobarbaz!'; +You can grab an instance of the cache engine directly through the Services class: - // Save into the cache for 5 minutes - cache()->save('foo', $foo, 300); - } - - echo $foo; - -You can grab an instance of the cache engine directly through the Services class:: - - $cache = \Config\Services::cache(); - - $foo = $cache->get('foo'); +.. literalinclude:: caching/002.php + :lines: 2- ===================== Configuring the Cache @@ -94,9 +84,10 @@ Class Reference This method will attempt to fetch an item from the cache store. If the item does not exist, the method will return null. - Example:: + Example: - $foo = $cache->get('my_cached_item'); + .. literalinclude:: caching/003.php + :lines: 2- .. php:method:: remember(string $key, int $ttl, Closure $callback) @@ -121,9 +112,10 @@ Class Reference This method will save an item to the cache store. If saving fails, the method will return ``false``. - Example:: + Example: - $cache->save('cache_item_id', 'data_to_cache'); + .. literalinclude:: caching/004.php + :lines: 2- .. note:: The ``$raw`` parameter is only utilized by Memcache, in order to allow usage of ``increment()`` and ``decrement()``. @@ -137,9 +129,10 @@ Class Reference This method will delete a specific item from the cache store. If item deletion fails, the method will return false. - Example:: + Example: - $cache->delete('cache_item_id'); + .. literalinclude:: caching/005.php + :lines: 2- .. php:method:: deleteMatching($pattern): integer @@ -153,10 +146,10 @@ Class Reference .. important:: This method is only implemented for File, Redis and Predis handlers. Due to limitations, it couldn't be implemented for Memcached and Wincache handlers. - Example:: + Example: - $cache->deleteMatching('prefix_*'); // deletes all items of which keys start with "prefix_" - $cache->deleteMatching('*_suffix'); // deletes all items of which keys end with "_suffix" + .. literalinclude:: caching/006.php + :lines: 2- For more information on glob-style syntax, please see `Glob (programming) `_. @@ -170,11 +163,10 @@ Class Reference Performs atomic incrementation of a raw stored value. - Example:: + Example: - // 'iterator' has a value of 2 - $cache->increment('iterator'); // 'iterator' is now 3 - $cache->increment('iterator', 3); // 'iterator' is now 6 + .. literalinclude:: caching/007.php + :lines: 2- .. php:method:: decrement($key[, $offset = 1]): mixed @@ -185,11 +177,10 @@ Class Reference Performs atomic decrementation of a raw stored value. - Example:: + Example: - // 'iterator' has a value of 6 - $cache->decrement('iterator'); // 'iterator' is now 5 - $cache->decrement('iterator', 2); // 'iterator' is now 3 + .. literalinclude:: caching/008.php + :lines: 2- .. php:method:: clean() @@ -199,9 +190,10 @@ Class Reference This method will 'clean' the entire cache. If the deletion of the cache files fails, the method will return false. - Example:: + Example: - $cache->clean(); + .. literalinclude:: caching/009.php + :lines: 2- .. php:method:: getCacheInfo() @@ -210,9 +202,10 @@ Class Reference This method will return information on the entire cache. - Example:: + Example: - var_dump($cache->getCacheInfo()); + .. literalinclude:: caching/010.php + :lines: 2- .. note:: The information returned and the structure of the data is dependent on which adapter is being used. @@ -226,9 +219,10 @@ Class Reference This method will return detailed information on a specific item in the cache. - Example:: + Example: - var_dump($cache->getMetadata('my_cached_item')); + .. literalinclude:: caching/011.php + :lines: 2- .. note:: The information returned and the structure of the data is dependent on which adapter is being used. Some adapters (File, Memcached, Wincache) @@ -244,10 +238,10 @@ Class Reference This method is used by handler methods to check that keys are valid. It will throw an ``InvalidArgumentException`` for non-strings, invalid characters, and empty lengths. - Example:: - - $prefixedKey = BaseHandler::validateKey($key, $prefix); + Example: + .. literalinclude:: caching/012.php + :lines: 2- ******* Drivers @@ -267,14 +261,10 @@ directory to be really writable by the application. Memcached Caching ================= -Memcached servers can be specified in the cache configuration file. Available options are:: +Memcached servers can be specified in the cache configuration file. Available options are: - public $memcached = [ - 'host' => '127.0.0.1', - 'port' => 11211, - 'weight' => 1, - 'raw' => false, - ]; +.. literalinclude:: caching/013.php + :lines: 2- For more information on Memcached, please see `https://www.php.net/memcached `_. @@ -295,15 +285,10 @@ 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 `_. -Config options to connect to redis server stored in the cache configuration file. Available options are:: +Config options to connect to redis server stored in the cache configuration file. Available options are: - public $redis = [ - 'host' => '127.0.0.1', - 'password' => null, - 'port' => 6379, - 'timeout' => 0, - 'database' => 0, - ]; +.. literalinclude:: caching/014.php + :lines: 2- For more information on Redis, please see `https://redis.io `_. diff --git a/user_guide_src/source/libraries/caching/001.php b/user_guide_src/source/libraries/caching/001.php new file mode 100644 index 000000000000..491746ba14b4 --- /dev/null +++ b/user_guide_src/source/libraries/caching/001.php @@ -0,0 +1,11 @@ +'; + $foo = 'foobarbaz!'; + + // Save into the cache for 5 minutes + cache()->save('foo', $foo, 300); +} + +echo $foo; diff --git a/user_guide_src/source/libraries/caching/002.php b/user_guide_src/source/libraries/caching/002.php new file mode 100644 index 000000000000..ed453264b505 --- /dev/null +++ b/user_guide_src/source/libraries/caching/002.php @@ -0,0 +1,5 @@ +get('foo'); diff --git a/user_guide_src/source/libraries/caching/003.php b/user_guide_src/source/libraries/caching/003.php new file mode 100644 index 000000000000..4913a816e5e2 --- /dev/null +++ b/user_guide_src/source/libraries/caching/003.php @@ -0,0 +1,3 @@ +get('my_cached_item'); diff --git a/user_guide_src/source/libraries/caching/004.php b/user_guide_src/source/libraries/caching/004.php new file mode 100644 index 000000000000..f343a5bee486 --- /dev/null +++ b/user_guide_src/source/libraries/caching/004.php @@ -0,0 +1,3 @@ +save('cache_item_id', 'data_to_cache'); diff --git a/user_guide_src/source/libraries/caching/005.php b/user_guide_src/source/libraries/caching/005.php new file mode 100644 index 000000000000..1d8a3b905588 --- /dev/null +++ b/user_guide_src/source/libraries/caching/005.php @@ -0,0 +1,3 @@ +delete('cache_item_id'); diff --git a/user_guide_src/source/libraries/caching/006.php b/user_guide_src/source/libraries/caching/006.php new file mode 100644 index 000000000000..1afc08644ace --- /dev/null +++ b/user_guide_src/source/libraries/caching/006.php @@ -0,0 +1,4 @@ +deleteMatching('prefix_*'); // deletes all items of which keys start with "prefix_" +$cache->deleteMatching('*_suffix'); // deletes all items of which keys end with "_suffix" diff --git a/user_guide_src/source/libraries/caching/007.php b/user_guide_src/source/libraries/caching/007.php new file mode 100644 index 000000000000..6256d6e0e721 --- /dev/null +++ b/user_guide_src/source/libraries/caching/007.php @@ -0,0 +1,5 @@ +increment('iterator'); // 'iterator' is now 3 +$cache->increment('iterator', 3); // 'iterator' is now 6 diff --git a/user_guide_src/source/libraries/caching/008.php b/user_guide_src/source/libraries/caching/008.php new file mode 100644 index 000000000000..4e74cbb0a47f --- /dev/null +++ b/user_guide_src/source/libraries/caching/008.php @@ -0,0 +1,5 @@ +decrement('iterator'); // 'iterator' is now 5 +$cache->decrement('iterator', 2); // 'iterator' is now 3 diff --git a/user_guide_src/source/libraries/caching/009.php b/user_guide_src/source/libraries/caching/009.php new file mode 100644 index 000000000000..a5a9e5725f23 --- /dev/null +++ b/user_guide_src/source/libraries/caching/009.php @@ -0,0 +1,3 @@ +clean(); diff --git a/user_guide_src/source/libraries/caching/010.php b/user_guide_src/source/libraries/caching/010.php new file mode 100644 index 000000000000..22a5cb08b8b9 --- /dev/null +++ b/user_guide_src/source/libraries/caching/010.php @@ -0,0 +1,3 @@ +getCacheInfo()); diff --git a/user_guide_src/source/libraries/caching/011.php b/user_guide_src/source/libraries/caching/011.php new file mode 100644 index 000000000000..1fedd92c28b4 --- /dev/null +++ b/user_guide_src/source/libraries/caching/011.php @@ -0,0 +1,3 @@ +getMetadata('my_cached_item')); diff --git a/user_guide_src/source/libraries/caching/012.php b/user_guide_src/source/libraries/caching/012.php new file mode 100644 index 000000000000..90395ed77429 --- /dev/null +++ b/user_guide_src/source/libraries/caching/012.php @@ -0,0 +1,3 @@ + '127.0.0.1', + 'port' => 11211, + 'weight' => 1, + 'raw' => false, +]; diff --git a/user_guide_src/source/libraries/caching/014.php b/user_guide_src/source/libraries/caching/014.php new file mode 100644 index 000000000000..20dfb69ce9b0 --- /dev/null +++ b/user_guide_src/source/libraries/caching/014.php @@ -0,0 +1,9 @@ + '127.0.0.1', + 'password' => null, + 'port' => 6379, + 'timeout' => 0, + 'database' => 0, +]; diff --git a/user_guide_src/source/libraries/cookies.rst b/user_guide_src/source/libraries/cookies.rst index 86d36dec9a25..a5baea10ce1d 100644 --- a/user_guide_src/source/libraries/cookies.rst +++ b/user_guide_src/source/libraries/cookies.rst @@ -28,84 +28,24 @@ Creating Cookies There are currently four (4) ways to create a new ``Cookie`` value object. -:: - - use CodeIgniter\Cookie\Cookie; - use DateTime; - - // Using the constructor - $cookie = new Cookie( - 'remember_token', - 'f699c7fd18a8e082d0228932f3acd40e1ef5ef92efcedda32842a211d62f0aa6', - [ - 'expires' => new DateTime('+2 hours'), - 'prefix' => '__Secure-', - 'path' => '/', - 'domain' => '', - 'secure' => true, - 'httponly' => true, - 'raw' => false, - 'samesite' => Cookie::SAMESITE_LAX, - ] - ); - - // Supplying a Set-Cookie header string - $cookie = Cookie::fromHeaderString( - 'remember_token=f699c7fd18a8e082d0228932f3acd40e1ef5ef92efcedda32842a211d62f0aa6; Path=/; Secure; HttpOnly; SameSite=Lax', - false, // raw - ); - - // Using the fluent builder interface - $cookie = (new Cookie('remember_token')) - ->withValue('f699c7fd18a8e082d0228932f3acd40e1ef5ef92efcedda32842a211d62f0aa6') - ->withPrefix('__Secure-') - ->withExpires(new DateTime('+2 hours')) - ->withPath('/') - ->withDomain('') - ->withSecure(true) - ->withHTTPOnly(true) - ->withSameSite(Cookie::SAMESITE_LAX); - - // Using the global function `cookie` which implicitly calls `new Cookie()` - $cookie = cookie('remember_token', 'f699c7fd18a8e082d0228932f3acd40e1ef5ef92efcedda32842a211d62f0aa6'); +.. literalinclude:: cookies/001.php + :lines: 2- When constructing the ``Cookie`` object, only the ``name`` attribute is required. All other else are optional. If the optional attributes are not modified, their values will be filled up by the default values saved in the ``Cookie`` class. To override the defaults currently stored in the class, you can pass a ``Config\Cookie`` instance or an array of defaults to the static ``Cookie::setDefaults()`` method. -:: - - use CodeIgniter\Cookie\Cookie; - use Config\Cookie as CookieConfig; - - // pass in an Config\Cookie instance before constructing a Cookie class - Cookie::setDefaults(new CookieConfig()); - $cookie = new Cookie('login_token'); - - // pass in an array of defaults - $myDefaults = [ - 'expires' => 0, - 'samesite' => Cookie::SAMESITE_STRICT, - ]; - Cookie::setDefaults($myDefaults); - $cookie = new Cookie('login_token'); +.. literalinclude:: cookies/002.php + :lines: 2- Passing the ``Config\Cookie`` instance or an array to ``Cookie::setDefaults()`` will effectively overwrite your defaults and will persist until new defaults are passed. If you do not want this behavior but only want to change defaults for a limited time, you can take advantage of ``Cookie::setDefaults()`` return which returns the old defaults array. -:: - - use CodeIgniter\Cookie\Cookie; - use Config\Cookie as CookieConfig; - - $oldDefaults = Cookie::setDefaults(new CookieConfig()); - $cookie = new Cookie('my_token', 'muffins'); - - // return the old defaults - Cookie::setDefaults($oldDefaults); +.. literalinclude:: cookies/003.php + :lines: 2- ***************************** Accessing Cookie's Attributes @@ -113,48 +53,8 @@ Accessing Cookie's Attributes Once instantiated, you can easily access a ``Cookie``'s attribute by using one of its getter methods. -:: - - use CodeIgniter\Cookie\Cookie; - use DateTime; - use DateTimeZone; - - $cookie = new Cookie( - 'remember_token', - 'f699c7fd18a8e082d0228932f3acd40e1ef5ef92efcedda32842a211d62f0aa6', - [ - 'expires' => new DateTime('2025-02-14 00:00:00', new DateTimeZone('UTC')), - 'prefix' => '__Secure-', - 'path' => '/', - 'domain' => '', - 'secure' => true, - 'httponly' => true, - 'raw' => false, - 'samesite' => Cookie::SAMESITE_LAX, - ] - ); - - $cookie->getName(); // 'remember_token' - $cookie->getPrefix(); // '__Secure-' - $cookie->getPrefixedName(); // '__Secure-remember_token' - $cookie->getExpiresTimestamp(); // Unix timestamp - $cookie->getExpiresString(); // 'Fri, 14-Feb-2025 00:00:00 GMT' - $cookie->isExpired(); // false - $cookie->getMaxAge(); // the difference from time() to expires - $cookie->isRaw(); // false - $cookie->isSecure(); // true - $cookie->getPath(); // '/' - $cookie->getDomain(); // '' - $cookie->isHTTPOnly(); // true - $cookie->getSameSite(); // 'Lax' - - // additional getter - $cookie->getId(); // '__Secure-remember_token;;/' - - // when using `setcookie()`'s alternative signature on PHP 7.3+ - // you can easily use the `getOptions()` method to supply the - // $options parameter - $cookie->getOptions(); +.. literalinclude:: cookies/004.php + :lines: 2- ***************** Immutable Cookies @@ -164,18 +64,8 @@ A new ``Cookie`` instance is an immutable value object representation of an HTTP modifying any of the instance's attributes will not affect the original instance. The modification **always** returns a new instance. You need to retain this new instance in order to use it. -:: - - use CodeIgniter\Cookie\Cookie; - - $cookie = new Cookie('login_token', 'admin'); - $cookie->getName(); // 'login_token' - - $cookie->withName('remember_token'); - $cookie->getName(); // 'login_token' - - $new = $cookie->withName('remember_token'); - $new->getName(); // 'remember_token' +.. literalinclude:: cookies/005.php + :lines: 2- ******************************** Validating a Cookie's Attributes @@ -232,13 +122,8 @@ If the SameSite is set to ``None`` you need to make sure that ``Secure`` is also When writing the SameSite attribute, the ``Cookie`` class accepts any of the values case-insensitively. You can also take advantage of the class's constants to make it not a hassle. -:: - - use CodeIgniter\Cookie\Cookie; - - Cookie::SAMESITE_LAX; // 'lax' - Cookie::SAMESITE_STRICT; // 'strict' - Cookie::SAMESITE_NONE; // 'none' +.. literalinclude:: cookies/006.php + :lines: 2- ********************** Using the Cookie Store @@ -247,36 +132,13 @@ Using the Cookie Store The ``CookieStore`` class represents an immutable collection of ``Cookie`` objects. The ``CookieStore`` instance can be accessed from the current ``Response`` object. -:: - - use Config\Services; - - $cookieStore = Services::response()->getCookieStore(); +.. literalinclude:: cookies/007.php + :lines: 2- CodeIgniter provides three (3) other ways to create a new instance of the ``CookieStore``. -:: - - use CodeIgniter\Cookie\Cookie; - use CodeIgniter\Cookie\CookieStore; - - // Passing an array of `Cookie` objects in the constructor - $store = new CookieStore([ - new Cookie('login_token'), - new Cookie('remember_token'), - ]); - - // Passing an array of `Set-Cookie` header strings - $store = CookieStore::fromCookieHeaders([ - 'remember_token=me; Path=/; SameSite=Lax', - 'login_token=admin; Path=/; SameSite=Lax', - ]); - - // using the global `cookies` function - $store = cookies([new Cookie('login_token')], false); - - // retrieving the `CookieStore` instance saved in our current `Response` object - $store = cookies(); +.. literalinclude:: cookies/008.php + :lines: 2- .. note:: When using the global ``cookies()`` function, the passed ``Cookie`` array will only be considered if the second argument, ``$getGlobal``, is set to ``false``. @@ -284,79 +146,36 @@ CodeIgniter provides three (3) other ways to create a new instance of the ``Cook Checking Cookies in Store ========================= -To check whether a ``Cookie`` object exists in the ``CookieStore`` instance, you can use several ways:: - - use CodeIgniter\Cookie\Cookie; - use CodeIgniter\Cookie\CookieStore; - use Config\Services; +To check whether a ``Cookie`` object exists in the ``CookieStore`` instance, you can use several ways: - // check if cookie is in the current cookie collection - $store = new CookieStore([ - new Cookie('login_token'), - new Cookie('remember_token'), - ]); - $store->has('login_token'); - - // check if cookie is in the current Response's cookie collection - cookies()->has('login_token'); - Services::response()->hasCookie('remember_token'); - - // using the cookie helper to check the current Response - // not available to v4.1.1 and lower - helper('cookie'); - has_cookie('login_token'); +.. literalinclude:: cookies/009.php + :lines: 2- Getting Cookies in Store ======================== -Retrieving a ``Cookie`` instance in a cookie collection is very easy:: - - use CodeIgniter\Cookie\Cookie; - use CodeIgniter\Cookie\CookieStore; - use Config\Services; - - // getting cookie in the current cookie collection - $store = new CookieStore([ - new Cookie('login_token'), - new Cookie('remember_token'), - ]); - $store->get('login_token'); - - // getting cookie in the current Response's cookie collection - cookies()->get('login_token'); - Services::response()->getCookie('remember_token'); +Retrieving a ``Cookie`` instance in a cookie collection is very easy: - // using the cookie helper to get cookie from the Response's cookie collection - helper('cookie'); - get_cookie('remember_token'); +.. literalinclude:: cookies/010.php + :lines: 2- When getting a ``Cookie`` instance directly from a ``CookieStore``, an invalid name will throw a ``CookieException``. -:: - - // throws CookieException - $store->get('unknown_cookie'); +.. literalinclude:: cookies/011.php + :lines: 2- When getting a ``Cookie`` instance from the current ``Response``'s cookie collection, an invalid name will just return ``null``. -:: - - cookies()->get('unknown_cookie'); // null +.. literalinclude:: cookies/012.php + :lines: 2- If no arguments are supplied in when getting cookies from the ``Response``, all ``Cookie`` objects in store will be displayed. -:: - - cookies()->get(); // array of Cookie objects - - // alternatively, you can use the display method - cookies()->display(); - - // or even from the Response - Services::response()->getCookies(); +.. literalinclude:: cookies/013.php + :lines: 2- .. note:: The helper function ``get_cookie()`` gets the cookie from the current ``Request`` object, not from ``Response``. This function checks the `$_COOKIE` array if that cookie is set and fetches it @@ -368,22 +187,8 @@ Adding/Removing Cookies in Store As previously mentioned, ``CookieStore`` objects are immutable. You need to save the modified instance in order to work on it. The original instance is left unchanged. -:: - - use CodeIgniter\Cookie\Cookie; - use CodeIgniter\Cookie\CookieStore; - use Config\Services; - - $store = new CookieStore([ - new Cookie('login_token'), - new Cookie('remember_token'), - ]); - - // adding a new Cookie instance - $new = $store->put(new Cookie('admin_token', 'yes')); - - // removing a Cookie instance - $new = $store->remove('login_token'); +.. literalinclude:: cookies/014.php + :lines: 2- .. note:: Removing a cookie from the store **DOES NOT** delete it from the browser. If you intend to delete a cookie *from the browser*, you must put an empty value @@ -393,17 +198,8 @@ When interacting with the cookies in store in the current ``Response`` object, y cookies without worrying the immutable nature of the cookie collection. The ``Response`` object will replace the instance with the modified instance. -:: - - use Config\Services; - - Services::response()->setCookie('admin_token', 'yes'); - Services::response()->deleteCookie('login_token'); - - // using the cookie helper - helper('cookie'); - set_cookie('admin_token', 'yes'); - delete_cookie('login_token'); +.. literalinclude:: cookies/015.php + :lines: 2- Dispatching Cookies in Store ============================ @@ -413,17 +209,8 @@ for you. However, if you really need to manually send cookies, you can use the ` in sending other headers, you need to make sure the headers are not yet sent by checking the value of ``headers_sent()``. -:: - - use CodeIgniter\Cookie\Cookie; - use CodeIgniter\Cookie\CookieStore; - - $store = new CookieStore([ - new Cookie('login_token'), - new Cookie('remember_token'), - ]); - - $store->dispatch(); // After dispatch, the collection is now empty. +.. literalinclude:: cookies/016.php + :lines: 2- ********************** Cookie Personalization diff --git a/user_guide_src/source/libraries/cookies/001.php b/user_guide_src/source/libraries/cookies/001.php new file mode 100644 index 000000000000..777e74f111f5 --- /dev/null +++ b/user_guide_src/source/libraries/cookies/001.php @@ -0,0 +1,40 @@ + new DateTime('+2 hours'), + 'prefix' => '__Secure-', + 'path' => '/', + 'domain' => '', + 'secure' => true, + 'httponly' => true, + 'raw' => false, + 'samesite' => Cookie::SAMESITE_LAX, + ] +); + +// Supplying a Set-Cookie header string +$cookie = Cookie::fromHeaderString( + 'remember_token=f699c7fd18a8e082d0228932f3acd40e1ef5ef92efcedda32842a211d62f0aa6; Path=/; Secure; HttpOnly; SameSite=Lax', + false, // raw +); + +// Using the fluent builder interface +$cookie = (new Cookie('remember_token')) + ->withValue('f699c7fd18a8e082d0228932f3acd40e1ef5ef92efcedda32842a211d62f0aa6') + ->withPrefix('__Secure-') + ->withExpires(new DateTime('+2 hours')) + ->withPath('/') + ->withDomain('') + ->withSecure(true) + ->withHTTPOnly(true) + ->withSameSite(Cookie::SAMESITE_LAX); + +// Using the global function `cookie` which implicitly calls `new Cookie()` +$cookie = cookie('remember_token', 'f699c7fd18a8e082d0228932f3acd40e1ef5ef92efcedda32842a211d62f0aa6'); diff --git a/user_guide_src/source/libraries/cookies/002.php b/user_guide_src/source/libraries/cookies/002.php new file mode 100644 index 000000000000..3feb4347d330 --- /dev/null +++ b/user_guide_src/source/libraries/cookies/002.php @@ -0,0 +1,16 @@ + 0, + 'samesite' => Cookie::SAMESITE_STRICT, +]; +Cookie::setDefaults($myDefaults); +$cookie = new Cookie('login_token'); diff --git a/user_guide_src/source/libraries/cookies/003.php b/user_guide_src/source/libraries/cookies/003.php new file mode 100644 index 000000000000..2b41c1e4209f --- /dev/null +++ b/user_guide_src/source/libraries/cookies/003.php @@ -0,0 +1,10 @@ + new DateTime('2025-02-14 00:00:00', new DateTimeZone('UTC')), + 'prefix' => '__Secure-', + 'path' => '/', + 'domain' => '', + 'secure' => true, + 'httponly' => true, + 'raw' => false, + 'samesite' => Cookie::SAMESITE_LAX, + ] +); + +$cookie->getName(); // 'remember_token' +$cookie->getPrefix(); // '__Secure-' +$cookie->getPrefixedName(); // '__Secure-remember_token' +$cookie->getExpiresTimestamp(); // Unix timestamp +$cookie->getExpiresString(); // 'Fri, 14-Feb-2025 00:00:00 GMT' +$cookie->isExpired(); // false +$cookie->getMaxAge(); // the difference from time() to expires +$cookie->isRaw(); // false +$cookie->isSecure(); // true +$cookie->getPath(); // '/' +$cookie->getDomain(); // '' +$cookie->isHTTPOnly(); // true +$cookie->getSameSite(); // 'Lax' + +// additional getter +$cookie->getId(); // '__Secure-remember_token;;/' + +// when using `setcookie()`'s alternative signature on PHP 7.3+ +// you can easily use the `getOptions()` method to supply the +// $options parameter +$cookie->getOptions(); diff --git a/user_guide_src/source/libraries/cookies/005.php b/user_guide_src/source/libraries/cookies/005.php new file mode 100644 index 000000000000..264d06782104 --- /dev/null +++ b/user_guide_src/source/libraries/cookies/005.php @@ -0,0 +1,12 @@ +getName(); // 'login_token' + +$cookie->withName('remember_token'); +$cookie->getName(); // 'login_token' + +$new = $cookie->withName('remember_token'); +$new->getName(); // 'remember_token' diff --git a/user_guide_src/source/libraries/cookies/006.php b/user_guide_src/source/libraries/cookies/006.php new file mode 100644 index 000000000000..a8be634a9925 --- /dev/null +++ b/user_guide_src/source/libraries/cookies/006.php @@ -0,0 +1,7 @@ +getCookieStore(); diff --git a/user_guide_src/source/libraries/cookies/008.php b/user_guide_src/source/libraries/cookies/008.php new file mode 100644 index 000000000000..d387a507abd0 --- /dev/null +++ b/user_guide_src/source/libraries/cookies/008.php @@ -0,0 +1,22 @@ +has('login_token'); + +// check if cookie is in the current Response's cookie collection +cookies()->has('login_token'); +Services::response()->hasCookie('remember_token'); + +// using the cookie helper to check the current Response +// not available to v4.1.1 and lower +helper('cookie'); +has_cookie('login_token'); diff --git a/user_guide_src/source/libraries/cookies/010.php b/user_guide_src/source/libraries/cookies/010.php new file mode 100644 index 000000000000..8211a4a2b23e --- /dev/null +++ b/user_guide_src/source/libraries/cookies/010.php @@ -0,0 +1,20 @@ +get('login_token'); + +// getting cookie in the current Response's cookie collection +cookies()->get('login_token'); +Services::response()->getCookie('remember_token'); + +// using the cookie helper to get cookie from the Response's cookie collection +helper('cookie'); +get_cookie('remember_token'); diff --git a/user_guide_src/source/libraries/cookies/011.php b/user_guide_src/source/libraries/cookies/011.php new file mode 100644 index 000000000000..79937ad3f367 --- /dev/null +++ b/user_guide_src/source/libraries/cookies/011.php @@ -0,0 +1,4 @@ +get('unknown_cookie'); diff --git a/user_guide_src/source/libraries/cookies/012.php b/user_guide_src/source/libraries/cookies/012.php new file mode 100644 index 000000000000..cde062c20bd0 --- /dev/null +++ b/user_guide_src/source/libraries/cookies/012.php @@ -0,0 +1,3 @@ +get('unknown_cookie'); // null diff --git a/user_guide_src/source/libraries/cookies/013.php b/user_guide_src/source/libraries/cookies/013.php new file mode 100644 index 000000000000..e9c09b49052a --- /dev/null +++ b/user_guide_src/source/libraries/cookies/013.php @@ -0,0 +1,9 @@ +get(); // array of Cookie objects + +// alternatively, you can use the display method +cookies()->display(); + +// or even from the Response +Services::response()->getCookies(); diff --git a/user_guide_src/source/libraries/cookies/014.php b/user_guide_src/source/libraries/cookies/014.php new file mode 100644 index 000000000000..0e6ae6772146 --- /dev/null +++ b/user_guide_src/source/libraries/cookies/014.php @@ -0,0 +1,16 @@ +put(new Cookie('admin_token', 'yes')); + +// removing a Cookie instance +$new = $store->remove('login_token'); diff --git a/user_guide_src/source/libraries/cookies/015.php b/user_guide_src/source/libraries/cookies/015.php new file mode 100644 index 000000000000..040a2f8a9882 --- /dev/null +++ b/user_guide_src/source/libraries/cookies/015.php @@ -0,0 +1,11 @@ +setCookie('admin_token', 'yes'); +Services::response()->deleteCookie('login_token'); + +// using the cookie helper +helper('cookie'); +set_cookie('admin_token', 'yes'); +delete_cookie('login_token'); diff --git a/user_guide_src/source/libraries/cookies/016.php b/user_guide_src/source/libraries/cookies/016.php new file mode 100644 index 000000000000..ec04f12f1cb7 --- /dev/null +++ b/user_guide_src/source/libraries/cookies/016.php @@ -0,0 +1,11 @@ +dispatch(); // After dispatch, the collection is now empty. diff --git a/user_guide_src/source/libraries/curlrequest.rst b/user_guide_src/source/libraries/curlrequest.rst index 62e6ebbaa0c8..0d2789816953 100644 --- a/user_guide_src/source/libraries/curlrequest.rst +++ b/user_guide_src/source/libraries/curlrequest.rst @@ -30,9 +30,10 @@ Due to historical reasons, by default, the CURLRequest shares all the options be If you send more than one request with an instance of the class, this behavior may cause an error request with unnecessary headers. -You can change the behavior by editing the following config parameter value in **app/Config/CURLRequest.php** to ``false``:: +You can change the behavior by editing the following config parameter value in **app/Config/CURLRequest.php** to ``false``: - public $shareOptions = false; +.. literalinclude:: curlrequest/001.php + :lines: 2- ******************* Loading the Library @@ -40,31 +41,25 @@ Loading the Library The library can be loaded either manually or through the :doc:`Services class `. -To load with the Services class call the ``curlrequest()`` method:: +To load with the Services class call the ``curlrequest()`` method: - $client = \Config\Services::curlrequest(); +.. literalinclude:: curlrequest/002.php + :lines: 2- You can pass in an array of default options as the first parameter to modify how cURL will handle the request. -The options are described later in this document:: +The options are described later in this document: - $options = [ - 'baseURI' => 'http://example.com/api/v1/', - 'timeout' => 3, - ]; - $client = \Config\Services::curlrequest($options); +.. literalinclude:: curlrequest/003.php + :lines: 2- .. note:: When ``$shareOptions`` is false, the default options passed to the class constructor will be used for all requests. Other options will be reset after sending a request. When creating the class manually, you need to pass a few dependencies in. The first parameter is an instance of the ``Config\App`` class. The second parameter is a URI instance. The third -parameter is a Response object. The fourth parameter is the optional default ``$options`` array:: +parameter is a Response object. The fourth parameter is the optional default ``$options`` array: - $client = new \CodeIgniter\HTTP\CURLRequest( - new \Config\App(), - new \CodeIgniter\HTTP\URI(), - new \CodeIgniter\HTTP\Response(new \Config\App()), - $options - ); +.. literalinclude:: curlrequest/004.php + :lines: 2- ************************ Working with the Library @@ -79,51 +74,33 @@ Making Requests Most communication is done through the ``request()`` method, which fires off the request, and then returns a Response instance to you. This takes the HTTP method, the url and an array of options as the parameters. -:: - $client = \Config\Services::curlrequest(); - - $response = $client->request('GET', 'https://api.github.com/user', [ - 'auth' => ['user', 'pass'], - ]); +.. literalinclude:: curlrequest/005.php + :lines: 2- .. note:: When ``$shareOptions`` is false, the options passed to the method will be used for the request. After sending the request, they will be cleared. If you want to use the options to all requests, pass the options in the constructor. Since the response is an instance of ``CodeIgniter\HTTP\Response`` you have all of the normal information -available to you:: +available to you: - echo $response->getStatusCode(); - echo $response->getBody(); - echo $response->getHeader('Content-Type'); - $language = $response->negotiateLanguage(['en', 'fr']); +.. literalinclude:: curlrequest/006.php + :lines: 2- While the ``request()`` method is the most flexible, you can also use the following shortcut methods. They -each take the URL as the first parameter and an array of options as the second:: +each take the URL as the first parameter and an array of options as the second: - $client->get('http://example.com'); - $client->delete('http://example.com'); - $client->head('http://example.com'); - $client->options('http://example.com'); - $client->patch('http://example.com'); - $client->put('http://example.com'); - $client->post('http://example.com'); +.. literalinclude:: curlrequest/007.php + :lines: 2- Base URI -------- A ``baseURI`` can be set as one of the options during the instantiation of the class. This allows you to set a base URI, and then make all requests with that client using relative URLs. This is especially handy -when working with APIs:: - - $client = \Config\Services::curlrequest([ - 'baseURI' => 'https://example.com/api/v1/', - ]); +when working with APIs: - // GET http:example.com/api/v1/photos - $client->get('photos'); - - // GET http:example.com/api/v1/photos/13 - $client->delete('photos/13'); +.. literalinclude:: curlrequest/008.php + :lines: 2- When a relative URI is provided to the ``request()`` method or any of the shortcut methods, it will be combined with the baseURI according to the rules described by @@ -147,31 +124,26 @@ Using Responses Each ``request()`` call returns a Response object that contains a lot of useful information and some helpful methods. The most commonly used methods let you determine the response itself. -You can get the status code and reason phrase of the response:: - - $code = $response->getStatusCode(); // 200 - $reason = $response->getReason(); // OK +You can get the status code and reason phrase of the response: -You can retrieve headers from the response:: +.. literalinclude:: curlrequest/009.php + :lines: 2- - // Get a header line - echo $response->getHeaderLine('Content-Type'); +You can retrieve headers from the response: - // Get all headers - foreach ($response->getHeaders() as $name => $value) { - echo $name .': '. $response->getHeaderLine($name) ."\n"; - } +.. literalinclude:: curlrequest/010.php + :lines: 2- -The body can be retrieved using the ``getBody()`` method:: +The body can be retrieved using the ``getBody()`` method: - $body = $response->getBody(); +.. literalinclude:: curlrequest/011.php + :lines: 2- The body is the raw body provided by the remote server. If the content type requires formatting, you will need -to ensure that your script handles that:: +to ensure that your script handles that: - if (strpos($response->getHeader('content-type'), 'application/json') !== false) { - $body = json_decode($body); - } +.. literalinclude:: curlrequest/012.php + :lines: 2- *************** Request Options @@ -186,25 +158,20 @@ allow_redirects By default, cURL will follow all "Location:" headers the remote servers send back. The ``allow_redirects`` option allows you to modify how that works. -If you set the value to ``false``, then it will not follow any redirects at all:: +If you set the value to ``false``, then it will not follow any redirects at all: - $client->request('GET', 'http://example.com', ['allow_redirects' => false]); +.. literalinclude:: curlrequest/013.php + :lines: 2- -Setting it to ``true`` will apply the default settings to the request:: +Setting it to ``true`` will apply the default settings to the request: - $client->request('GET', 'http://example.com', ['allow_redirects' => true]); +.. literalinclude:: curlrequest/014.php + :lines: 2- - // Sets the following defaults: - 'max' => 5, // Maximum number of redirects to follow before stopping - 'strict' => true, // Ensure POST requests stay POST requests through redirects - 'protocols' => ['http', 'https'] // Restrict redirects to one or more protocols +You can pass in array as the value of the ``allow_redirects`` option to specify new settings in place of the defaults: -You can pass in array as the value of the ``allow_redirects`` option to specify new settings in place of the defaults:: - - $client->request('GET', 'http://example.com', ['allow_redirects' => [ - 'max' => 10, - 'protocols' => ['https'] // Force HTTPS domains only. - ]]); +.. literalinclude:: curlrequest/015.php + :lines: 2- .. note:: Following redirects does not work when PHP is in safe_mode or open_basedir is enabled. @@ -215,49 +182,55 @@ Allows you to provide Authentication details for `HTTP Basic `_ and authentication. Your script may have to do extra to support Digest authentication - this simply passes the username and password along for you. The value must be an array where the first element is the username, and the second is the password. The third parameter should be -the type of authentication to use, either ``basic`` or ``digest``:: +the type of authentication to use, either ``basic`` or ``digest``: - $client->request('GET', 'http://example.com', ['auth' => ['username', 'password', 'digest']]); +.. literalinclude:: curlrequest/016.php + :lines: 2- body ==== There are two ways to set the body of the request for request types that support them, like PUT, OR POST. -The first way is to use the ``setBody()`` method:: +The first way is to use the ``setBody()`` method: - $client->setBody($body) ->request('put', 'http://example.com'); +.. literalinclude:: curlrequest/017.php + :lines: 2- The second method is by passing a ``body`` option in. This is provided to maintain Guzzle API compatibility, -and functions the exact same way as the previous example. The value must be a string:: +and functions the exact same way as the previous example. The value must be a string: - $client->request('put', 'http://example.com', ['body' => $body]); +.. literalinclude:: curlrequest/018.php + :lines: 2- cert ==== To specify the location of a PEM formatted client-side certificate, pass a string with the full path to the file as the ``cert`` option. If a password is required, set the value to an array with the first element -as the path to the certificate, and the second as the password:: +as the path to the certificate, and the second as the password: - $client->request('get', '/', ['cert' => ['/path/server.pem', 'password']); +.. literalinclude:: curlrequest/019.php + :lines: 2- connect_timeout =============== By default, CodeIgniter does not impose a limit for cURL to attempt to connect to a website. If you need to modify this value, you can do so by passing the amount of time in seconds with the ``connect_timeout`` option. -You can pass 0 to wait indefinitely:: +You can pass 0 to wait indefinitely: - $response->request('GET', 'http://example.com', ['connect_timeout' => 0]); +.. literalinclude:: curlrequest/020.php + :lines: 2- cookie ====== This specifies the filename that CURL should use to read cookie values from, and to save cookie values to. This is done using the CURL_COOKIEJAR and CURL_COOKIEFILE options. -An example:: +An example: - $response->request('GET', 'http://example.com', ['cookie' => WRITEPATH . 'CookieSaver.txt']); +.. literalinclude:: curlrequest/021.php + :lines: 2- debug ===== @@ -269,31 +242,28 @@ the server's error log. $response->request('GET', 'http://example.com', ['debug' => true]); -You can pass a filename as the value for debug to have the output written to a file:: +You can pass a filename as the value for debug to have the output written to a file: - $response->request('GET', 'http://example.com', ['debug' => '/usr/local/curl_log.txt']); +.. literalinclude:: curlrequest/022.php + :lines: 2- delay ===== -Allows you to pause a number of milliseconds before sending the request:: +Allows you to pause a number of milliseconds before sending the request: - // Delay for 2 seconds - $response->request('GET', 'http://example.com', ['delay' => 2000]); +.. literalinclude:: curlrequest/023.php + :lines: 2- form_params =========== You can send form data in an application/x-www-form-urlencoded POST request by passing an associative array in the ``form_params`` option. This will set the ``Content-Type`` header to ``application/x-www-form-urlencoded`` -if it's not already set:: +if it's not already set: - $client->request('POST', '/post', [ - 'form_params' => [ - 'foo' => 'bar', - 'baz' => ['hi', 'there'], - ], - ]); +.. literalinclude:: curlrequest/024.php + :lines: 2- .. note:: ``form_params`` cannot be used with the ``multipart`` option. You will need to use one or the other. Use ``form_params`` for ``application/x-www-form-urlencoded`` request, and ``multipart`` for ``multipart/form-data`` @@ -306,15 +276,10 @@ headers While you can set any headers this request needs by using the ``setHeader()`` method, you can also pass an associative array of headers in as an option. Each key is the name of a header, and each value is a string or array of strings -representing the header field values:: +representing the header field values: - $client->request('get', '/', [ - 'headers' => [ - 'User-Agent' => 'testing/1.0', - 'Accept' => 'application/json', - 'X-Foo' => ['Bar', 'Baz'], - ], - ]); +.. literalinclude:: curlrequest/025.php + :lines: 2- If headers are passed into the constructor they are treated as default values that will be overridden later by any further headers arrays or calls to ``setHeader()``. @@ -323,23 +288,20 @@ http_errors =========== By default, CURLRequest will fail if the HTTP code returned is greater than or equal to 400. You can set -``http_errors`` to ``false`` to return the content instead:: - - $client->request('GET', '/status/500'); - // Will fail verbosely +``http_errors`` to ``false`` to return the content instead: - $res = $client->request('GET', '/status/500', ['http_errors' => false]); - echo $res->getStatusCode(); - // 500 +.. literalinclude:: curlrequest/026.php + :lines: 2- json ==== The ``json`` option is used to easily upload JSON encoded data as the body of a request. A Content-Type header of ``application/json`` is added, overwriting any Content-Type that might be already set. The data provided to -this option can be any value that ``json_encode()`` accepts:: +this option can be any value that ``json_encode()`` accepts: - $response = $client->request('PUT', '/put', ['json' => ['foo' => 'bar']]); +.. literalinclude:: curlrequest/027.php + :lines: 2- .. note:: This option does not allow for any customization of the ``json_encode()`` function, or the Content-Type header. If you need that ability, you will need to encode the data manually, passing it through the ``setBody()`` @@ -351,12 +313,10 @@ multipart When you need to send files and other data via a POST request, you can use the ``multipart`` option, along with the `CURLFile Class `_. The values should be an associative array of POST data to send. For safer usage, the legacy method of uploading files by prefixing their name with an `@` -has been disabled. Any files that you want to send must be passed as instances of CURLFile:: +has been disabled. Any files that you want to send must be passed as instances of CURLFile: - $post_data = [ - 'foo' => 'bar', - 'userfile' => new \CURLFile('/path/to/file.txt'), - ]; +.. literalinclude:: curlrequest/028.php + :lines: 2- .. note:: ``multipart`` cannot be used with the ``form_params`` option. You can only use one or the other. Use ``form_params`` for ``application/x-www-form-urlencoded`` requests, and ``multipart`` for ``multipart/form-data`` @@ -365,25 +325,27 @@ has been disabled. Any files that you want to send must be passed as instances o query ===== -You can pass along data to send as query string variables by passing an associative array as the ``query`` option:: +You can pass along data to send as query string variables by passing an associative array as the ``query`` option: - // Send a GET request to /get?foo=bar - $client->request('GET', '/get', ['query' => ['foo' => 'bar']]); +.. literalinclude:: curlrequest/029.php + :lines: 2- timeout ======= By default, cURL functions are allowed to run as long as they take, with no time limit. You can modify this with the ``timeout`` -option. The value should be the number of seconds you want the functions to execute for. Use 0 to wait indefinitely:: +option. The value should be the number of seconds you want the functions to execute for. Use 0 to wait indefinitely: - $response->request('GET', 'http://example.com', ['timeout' => 5]); +.. literalinclude:: curlrequest/030.php + :lines: 2- user_agent ========== -Allows specifying the User Agent for requests:: +Allows specifying the User Agent for requests: - $response->request('GET', 'http://example.com', ['user_agent' => 'CodeIgniter Framework v4']); +.. literalinclude:: curlrequest/031.php + :lines: 2- verify ====== @@ -392,22 +354,16 @@ This option describes the SSL certificate verification behavior. If the ``verify SSL certificate verification and uses the default CA bundle provided by the operating system. If set to ``false`` it will disable the certificate verification (this is insecure, and allows man-in-the-middle attacks!). You can set it to a string that contains the path to a CA bundle to enable verification with a custom certificate. The default value -is true:: - - // Use the system's CA bundle (this is the default setting) - $client->request('GET', '/', ['verify' => true]); - - // Use a custom SSL certificate on disk. - $client->request('GET', '/', ['verify' => '/path/to/cert.pem']); +is true: - // Disable validation entirely. (Insecure!) - $client->request('GET', '/', ['verify' => false]); +.. literalinclude:: curlrequest/032.php + :lines: 2- version ======= To set the HTTP protocol to use, you can pass a string or float with the version number (typically either 1.0 -or 1.1, 2.0 is currently unsupported.):: +or 1.1, 2.0 is currently unsupported.): - // Force HTTP/1.0 - $client->request('GET', '/', ['version' => 1.0]); +.. literalinclude:: curlrequest/033.php + :lines: 2- diff --git a/user_guide_src/source/libraries/curlrequest/001.php b/user_guide_src/source/libraries/curlrequest/001.php new file mode 100644 index 000000000000..43e1f74bc943 --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/001.php @@ -0,0 +1,3 @@ + 'http://example.com/api/v1/', + 'timeout' => 3, +]; +$client = \Config\Services::curlrequest($options); diff --git a/user_guide_src/source/libraries/curlrequest/004.php b/user_guide_src/source/libraries/curlrequest/004.php new file mode 100644 index 000000000000..4d6a14fadbb0 --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/004.php @@ -0,0 +1,8 @@ +request('GET', 'https://api.github.com/user', [ + 'auth' => ['user', 'pass'], +]); diff --git a/user_guide_src/source/libraries/curlrequest/006.php b/user_guide_src/source/libraries/curlrequest/006.php new file mode 100644 index 000000000000..114b14e2251d --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/006.php @@ -0,0 +1,6 @@ +getStatusCode(); +echo $response->getBody(); +echo $response->getHeader('Content-Type'); +$language = $response->negotiateLanguage(['en', 'fr']); diff --git a/user_guide_src/source/libraries/curlrequest/007.php b/user_guide_src/source/libraries/curlrequest/007.php new file mode 100644 index 000000000000..d509f3e3fa29 --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/007.php @@ -0,0 +1,9 @@ +get('http://example.com'); +$client->delete('http://example.com'); +$client->head('http://example.com'); +$client->options('http://example.com'); +$client->patch('http://example.com'); +$client->put('http://example.com'); +$client->post('http://example.com'); diff --git a/user_guide_src/source/libraries/curlrequest/008.php b/user_guide_src/source/libraries/curlrequest/008.php new file mode 100644 index 000000000000..611909c2df7d --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/008.php @@ -0,0 +1,11 @@ + 'https://example.com/api/v1/', +]); + +// GET http:example.com/api/v1/photos +$client->get('photos'); + +// GET http:example.com/api/v1/photos/13 +$client->delete('photos/13'); diff --git a/user_guide_src/source/libraries/curlrequest/009.php b/user_guide_src/source/libraries/curlrequest/009.php new file mode 100644 index 000000000000..49eaa5ec7562 --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/009.php @@ -0,0 +1,4 @@ +getStatusCode(); // 200 +$reason = $response->getReason(); // OK diff --git a/user_guide_src/source/libraries/curlrequest/010.php b/user_guide_src/source/libraries/curlrequest/010.php new file mode 100644 index 000000000000..e13fa1c5e7e3 --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/010.php @@ -0,0 +1,9 @@ +getHeaderLine('Content-Type'); + +// Get all headers +foreach ($response->getHeaders() as $name => $value) { + echo $name .': '. $response->getHeaderLine($name) ."\n"; +} diff --git a/user_guide_src/source/libraries/curlrequest/011.php b/user_guide_src/source/libraries/curlrequest/011.php new file mode 100644 index 000000000000..ee93e3dac0e9 --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/011.php @@ -0,0 +1,3 @@ +getBody(); diff --git a/user_guide_src/source/libraries/curlrequest/012.php b/user_guide_src/source/libraries/curlrequest/012.php new file mode 100644 index 000000000000..2dc0eea65d0d --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/012.php @@ -0,0 +1,5 @@ +getHeader('content-type'), 'application/json') !== false) { + $body = json_decode($body); +} diff --git a/user_guide_src/source/libraries/curlrequest/013.php b/user_guide_src/source/libraries/curlrequest/013.php new file mode 100644 index 000000000000..342b6af55ea7 --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/013.php @@ -0,0 +1,3 @@ +request('GET', 'http://example.com', ['allow_redirects' => false]); diff --git a/user_guide_src/source/libraries/curlrequest/014.php b/user_guide_src/source/libraries/curlrequest/014.php new file mode 100644 index 000000000000..452f30dd45ed --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/014.php @@ -0,0 +1,8 @@ +request('GET', 'http://example.com', ['allow_redirects' => true]); + +// Sets the following defaults: +'max' => 5, // Maximum number of redirects to follow before stopping +'strict' => true, // Ensure POST requests stay POST requests through redirects +'protocols' => ['http', 'https'] // Restrict redirects to one or more protocols diff --git a/user_guide_src/source/libraries/curlrequest/015.php b/user_guide_src/source/libraries/curlrequest/015.php new file mode 100644 index 000000000000..c8c85ee7f116 --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/015.php @@ -0,0 +1,6 @@ +request('GET', 'http://example.com', ['allow_redirects' => [ + 'max' => 10, + 'protocols' => ['https'] // Force HTTPS domains only. +]]); diff --git a/user_guide_src/source/libraries/curlrequest/016.php b/user_guide_src/source/libraries/curlrequest/016.php new file mode 100644 index 000000000000..3c3fa945f535 --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/016.php @@ -0,0 +1,3 @@ +request('GET', 'http://example.com', ['auth' => ['username', 'password', 'digest']]); diff --git a/user_guide_src/source/libraries/curlrequest/017.php b/user_guide_src/source/libraries/curlrequest/017.php new file mode 100644 index 000000000000..fbc6302a68ec --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/017.php @@ -0,0 +1,3 @@ +setBody($body) ->request('put', 'http://example.com'); diff --git a/user_guide_src/source/libraries/curlrequest/018.php b/user_guide_src/source/libraries/curlrequest/018.php new file mode 100644 index 000000000000..16fba53e2e8b --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/018.php @@ -0,0 +1,3 @@ +request('put', 'http://example.com', ['body' => $body]); diff --git a/user_guide_src/source/libraries/curlrequest/019.php b/user_guide_src/source/libraries/curlrequest/019.php new file mode 100644 index 000000000000..96f86c9ea6a2 --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/019.php @@ -0,0 +1,3 @@ +request('get', '/', ['cert' => ['/path/server.pem', 'password']); diff --git a/user_guide_src/source/libraries/curlrequest/020.php b/user_guide_src/source/libraries/curlrequest/020.php new file mode 100644 index 000000000000..6e0b1e3726a7 --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/020.php @@ -0,0 +1,3 @@ +request('GET', 'http://example.com', ['connect_timeout' => 0]); diff --git a/user_guide_src/source/libraries/curlrequest/021.php b/user_guide_src/source/libraries/curlrequest/021.php new file mode 100644 index 000000000000..4acf82aa9e0b --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/021.php @@ -0,0 +1,3 @@ +request('GET', 'http://example.com', ['cookie' => WRITEPATH . 'CookieSaver.txt']); diff --git a/user_guide_src/source/libraries/curlrequest/022.php b/user_guide_src/source/libraries/curlrequest/022.php new file mode 100644 index 000000000000..6acbcf0a7784 --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/022.php @@ -0,0 +1,3 @@ +request('GET', 'http://example.com', ['debug' => '/usr/local/curl_log.txt']); diff --git a/user_guide_src/source/libraries/curlrequest/023.php b/user_guide_src/source/libraries/curlrequest/023.php new file mode 100644 index 000000000000..b6846257ad83 --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/023.php @@ -0,0 +1,4 @@ +request('GET', 'http://example.com', ['delay' => 2000]); diff --git a/user_guide_src/source/libraries/curlrequest/024.php b/user_guide_src/source/libraries/curlrequest/024.php new file mode 100644 index 000000000000..bbc6285e0eec --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/024.php @@ -0,0 +1,8 @@ +request('POST', '/post', [ + 'form_params' => [ + 'foo' => 'bar', + 'baz' => ['hi', 'there'], + ], +]); diff --git a/user_guide_src/source/libraries/curlrequest/025.php b/user_guide_src/source/libraries/curlrequest/025.php new file mode 100644 index 000000000000..acc8b40002ef --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/025.php @@ -0,0 +1,9 @@ +request('get', '/', [ + 'headers' => [ + 'User-Agent' => 'testing/1.0', + 'Accept' => 'application/json', + 'X-Foo' => ['Bar', 'Baz'], + ], +]); diff --git a/user_guide_src/source/libraries/curlrequest/026.php b/user_guide_src/source/libraries/curlrequest/026.php new file mode 100644 index 000000000000..36ea74cb9293 --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/026.php @@ -0,0 +1,8 @@ +request('GET', '/status/500'); +// Will fail verbosely + +$res = $client->request('GET', '/status/500', ['http_errors' => false]); +echo $res->getStatusCode(); +// 500 diff --git a/user_guide_src/source/libraries/curlrequest/027.php b/user_guide_src/source/libraries/curlrequest/027.php new file mode 100644 index 000000000000..bd91655f3dbe --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/027.php @@ -0,0 +1,3 @@ +request('PUT', '/put', ['json' => ['foo' => 'bar']]); diff --git a/user_guide_src/source/libraries/curlrequest/028.php b/user_guide_src/source/libraries/curlrequest/028.php new file mode 100644 index 000000000000..fcce227c1d9a --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/028.php @@ -0,0 +1,6 @@ + 'bar', + 'userfile' => new \CURLFile('/path/to/file.txt'), +]; diff --git a/user_guide_src/source/libraries/curlrequest/029.php b/user_guide_src/source/libraries/curlrequest/029.php new file mode 100644 index 000000000000..7a19976bd0a2 --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/029.php @@ -0,0 +1,4 @@ +request('GET', '/get', ['query' => ['foo' => 'bar']]); diff --git a/user_guide_src/source/libraries/curlrequest/030.php b/user_guide_src/source/libraries/curlrequest/030.php new file mode 100644 index 000000000000..83bf718e33e4 --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/030.php @@ -0,0 +1,3 @@ +request('GET', 'http://example.com', ['timeout' => 5]); diff --git a/user_guide_src/source/libraries/curlrequest/031.php b/user_guide_src/source/libraries/curlrequest/031.php new file mode 100644 index 000000000000..1709d6d90b9c --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/031.php @@ -0,0 +1,3 @@ +request('GET', 'http://example.com', ['user_agent' => 'CodeIgniter Framework v4']); diff --git a/user_guide_src/source/libraries/curlrequest/032.php b/user_guide_src/source/libraries/curlrequest/032.php new file mode 100644 index 000000000000..13e2fba21f04 --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/032.php @@ -0,0 +1,10 @@ +request('GET', '/', ['verify' => true]); + +// Use a custom SSL certificate on disk. +$client->request('GET', '/', ['verify' => '/path/to/cert.pem']); + +// Disable validation entirely. (Insecure!) +$client->request('GET', '/', ['verify' => false]); diff --git a/user_guide_src/source/libraries/curlrequest/033.php b/user_guide_src/source/libraries/curlrequest/033.php new file mode 100644 index 000000000000..a7a8df45589c --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/033.php @@ -0,0 +1,4 @@ +request('GET', '/', ['version' => 1.0]); diff --git a/user_guide_src/source/libraries/email.rst b/user_guide_src/source/libraries/email.rst index e56af313b005..800816ed4bbd 100644 --- a/user_guide_src/source/libraries/email.rst +++ b/user_guide_src/source/libraries/email.rst @@ -30,19 +30,10 @@ Sending Email Sending email is not only simple, but you can configure it on the fly or set your preferences in the **app/Config/Email.php** file. -Here is a basic example demonstrating how you might send email:: +Here is a basic example demonstrating how you might send email: - $email = \Config\Services::email(); - - $email->setFrom('your@example.com', 'Your Name'); - $email->setTo('someone@example.com'); - $email->setCC('another@another-example.com'); - $email->setBCC('them@their-example.com'); - - $email->setSubject('Email Test'); - $email->setMessage('Testing the email class.'); - - $email->send(); +.. literalinclude:: email/001.php + :lines: 2- .. _setting-email-preferences: @@ -56,14 +47,10 @@ below: Preferences are set by passing an array of preference values to the email initialize method. Here is an example of how you might set some -preferences:: +preferences: - $config['protocol'] = 'sendmail'; - $config['mailPath'] = '/usr/sbin/sendmail'; - $config['charset'] = 'iso-8859-1'; - $config['wordWrap'] = true; - - $email->initialize($config); +.. literalinclude:: email/002.php + :lines: 2- .. note:: Most of the preferences have default values that will be used if you do not set them. @@ -167,7 +154,6 @@ message like this:: More text that will be wrapped normally. - Place the item you do not want word-wrapped between: {unwrap} {/unwrap} *************** @@ -184,13 +170,15 @@ Class Reference :returns: CodeIgniter\\Email\\Email instance (method chaining) :rtype: CodeIgniter\\Email\\Email - Sets the email address and name of the person sending the email:: + Sets the email address and name of the person sending the email: - $email->setFrom('you@example.com', 'Your Name'); + .. literalinclude:: email/003.php + :lines: 2- - You can also set a Return-Path, to help redirect undelivered mail:: + You can also set a Return-Path, to help redirect undelivered mail: - $email->setFrom('you@example.com', 'Your Name', 'returned_emails@example.com'); + .. literalinclude:: email/004.php + :lines: 2- .. note:: Return-Path can't be used if you've configured 'smtp' as your protocol. @@ -203,9 +191,10 @@ Class Reference :rtype: CodeIgniter\\Email\\Email Sets the reply-to address. If the information is not provided the - information in the `setFrom <#setFrom>`_ method is used. Example:: + information in the `setFrom <#setFrom>`_ method is used. Example: - $email->setReplyTo('you@example.com', 'Your Name'); + .. literalinclude:: email/005.php + :lines: 2- .. php:method:: setTo($to) @@ -214,17 +203,16 @@ Class Reference :rtype: CodeIgniter\\Email\\Email Sets the email address(s) of the recipient(s). Can be a single e-mail, - a comma-delimited list or an array:: - - $email->setTo('someone@example.com'); + a comma-delimited list or an array: - :: + .. literalinclude:: email/006.php + :lines: 2- - $email->setTo('one@example.com, two@example.com, three@example.com'); + .. literalinclude:: email/007.php + :lines: 2- - :: - - $email->setTo(['one@example.com', 'two@example.com', 'three@example.com']); + .. literalinclude:: email/008.php + :lines: 2- .. php:method:: setCC($cc) @@ -255,9 +243,10 @@ Class Reference :returns: CodeIgniter\\Email\\Email instance (method chaining) :rtype: CodeIgniter\\Email\\Email - Sets the email subject:: + Sets the email subject: - $email->setSubject('This is my subject'); + .. literalinclude:: email/009.php + :lines: 2- .. php:method:: setMessage($body) @@ -265,9 +254,10 @@ Class Reference :returns: CodeIgniter\\Email\\Email instance (method chaining) :rtype: CodeIgniter\\Email\\Email - Sets the e-mail message body:: + Sets the e-mail message body: - $email->setMessage('This is my message'); + .. literalinclude:: email/010.php + :lines: 2- .. php:method:: setAltMessage($str) @@ -275,9 +265,10 @@ Class Reference :returns: CodeIgniter\\Email\\Email instance (method chaining) :rtype: CodeIgniter\\Email\\Email - Sets the alternative e-mail message body:: + Sets the alternative e-mail message body: - $email->setAltMessage('This is the alternative message'); + .. literalinclude:: email/011.php + :lines: 2- This is an optional message string which can be used if you send HTML formatted email. It lets you specify an alternative message @@ -294,10 +285,10 @@ Class Reference :returns: CodeIgniter\\Email\\Email instance (method chaining) :rtype: CodeIgniter\\Email\\Email - Appends additional headers to the e-mail:: + Appends additional headers to the e-mail: - $email->setHeader('Header1', 'Value1'); - $email->setHeader('Header2', 'Value2'); + .. literalinclude:: email/012.php + :lines: 2- .. php:method:: clear($clearAttachments = false) @@ -309,23 +300,14 @@ Class Reference is intended for use if you run the email sending method in a loop, permitting the data to be reset between cycles. - :: - - foreach ($list as $name => $address) - { - $email->clear(); - - $email->setTo($address); - $email->setFrom('your@example.com'); - $email->setSubject('Here is your info '.$name); - $email->setMessage('Hi ' . $name . ' Here is the info you requested.'); - $email->send(); - } + .. literalinclude:: email/013.php + :lines: 2- If you set the parameter to true any attachments will be cleared as - well:: + well: - $email->clear(true); + .. literalinclude:: email/014.php + :lines: 2- .. php:method:: send($autoClear = true) @@ -334,18 +316,16 @@ Class Reference :rtype: bool The e-mail sending method. Returns boolean true or false based on - success or failure, enabling it to be used conditionally:: + success or failure, enabling it to be used conditionally: - if (! $email->send()) { - // Generate error - } + .. literalinclude:: email/015.php + :lines: 2- This method will automatically clear all parameters if the request was - successful. To stop this behaviour pass false:: + successful. To stop this behaviour pass false: - if ($email->send(false)) { - // Parameters won't be cleared - } + .. literalinclude:: email/016.php + :lines: 2- .. note:: In order to use the ``printDebugger()`` method, you need to avoid clearing the email parameters. @@ -367,30 +347,33 @@ Class Reference 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:: + For example: - $email->attach('/path/to/photo1.jpg'); - $email->attach('/path/to/photo2.jpg'); - $email->attach('/path/to/photo3.jpg'); + .. literalinclude:: email/017.php + :lines: 2- To use the default disposition (attachment), leave the second parameter blank, - otherwise use a custom disposition:: + otherwise use a custom disposition: - $email->attach('image.jpg', 'inline'); + .. literalinclude:: email/018.php + :lines: 2- - You can also use a URL:: + You can also use a URL: - $email->attach('http://example.com/filename.pdf'); + .. literalinclude:: email/019.php + :lines: 2- - If you'd like to use a custom file name, you can use the third parameter:: + If you'd like to use a custom file name, you can use the third parameter: - $email->attach('filename.pdf', 'attachment', 'report.pdf'); + .. literalinclude:: email/020.php + :lines: 2- 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:: + parameter as mime-type: - $email->attach($buffer, 'attachment', 'report.pdf', 'application/pdf'); + .. literalinclude:: email/021.php + :lines: 2- .. php:method:: setAttachmentCID($filename) @@ -400,17 +383,9 @@ Class Reference 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'; - $email->attach($filename); - - foreach ($list as $address) { - $email->setTo($address); - $cid = $email->setAttachmentCID($filename); - $email->setMessage('photo1'); - $email->send(); - } + .. literalinclude:: email/022.php + :lines: 2- .. note:: Content-ID for each e-mail must be re-created for it to be unique. @@ -426,14 +401,9 @@ Class Reference 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, printDebugger() would have - // nothing to output. - $email->send(false); + Example: - // Will only print the email headers, excluding the message subject and body - $email->printDebugger(['headers']); + .. literalinclude:: email/023.php + :lines: 2- .. note:: By default, all of the raw data will be printed. diff --git a/user_guide_src/source/libraries/email/001.php b/user_guide_src/source/libraries/email/001.php new file mode 100644 index 000000000000..914193c15203 --- /dev/null +++ b/user_guide_src/source/libraries/email/001.php @@ -0,0 +1,13 @@ +setFrom('your@example.com', 'Your Name'); +$email->setTo('someone@example.com'); +$email->setCC('another@another-example.com'); +$email->setBCC('them@their-example.com'); + +$email->setSubject('Email Test'); +$email->setMessage('Testing the email class.'); + +$email->send(); diff --git a/user_guide_src/source/libraries/email/002.php b/user_guide_src/source/libraries/email/002.php new file mode 100644 index 000000000000..02268ee6079d --- /dev/null +++ b/user_guide_src/source/libraries/email/002.php @@ -0,0 +1,8 @@ +initialize($config); diff --git a/user_guide_src/source/libraries/email/003.php b/user_guide_src/source/libraries/email/003.php new file mode 100644 index 000000000000..b2ade5bab56b --- /dev/null +++ b/user_guide_src/source/libraries/email/003.php @@ -0,0 +1,3 @@ +setFrom('you@example.com', 'Your Name'); diff --git a/user_guide_src/source/libraries/email/004.php b/user_guide_src/source/libraries/email/004.php new file mode 100644 index 000000000000..9d8195de4ea5 --- /dev/null +++ b/user_guide_src/source/libraries/email/004.php @@ -0,0 +1,3 @@ +setFrom('you@example.com', 'Your Name', 'returned_emails@example.com'); diff --git a/user_guide_src/source/libraries/email/005.php b/user_guide_src/source/libraries/email/005.php new file mode 100644 index 000000000000..ba6033c281c0 --- /dev/null +++ b/user_guide_src/source/libraries/email/005.php @@ -0,0 +1,3 @@ +setReplyTo('you@example.com', 'Your Name'); diff --git a/user_guide_src/source/libraries/email/006.php b/user_guide_src/source/libraries/email/006.php new file mode 100644 index 000000000000..1998618a5b5f --- /dev/null +++ b/user_guide_src/source/libraries/email/006.php @@ -0,0 +1,3 @@ +setTo('someone@example.com'); diff --git a/user_guide_src/source/libraries/email/007.php b/user_guide_src/source/libraries/email/007.php new file mode 100644 index 000000000000..b0622d0ac56f --- /dev/null +++ b/user_guide_src/source/libraries/email/007.php @@ -0,0 +1,3 @@ +setTo('one@example.com, two@example.com, three@example.com'); diff --git a/user_guide_src/source/libraries/email/008.php b/user_guide_src/source/libraries/email/008.php new file mode 100644 index 000000000000..d3ac20661d04 --- /dev/null +++ b/user_guide_src/source/libraries/email/008.php @@ -0,0 +1,3 @@ +setTo(['one@example.com', 'two@example.com', 'three@example.com']); diff --git a/user_guide_src/source/libraries/email/009.php b/user_guide_src/source/libraries/email/009.php new file mode 100644 index 000000000000..566736474df4 --- /dev/null +++ b/user_guide_src/source/libraries/email/009.php @@ -0,0 +1,3 @@ +setSubject('This is my subject'); diff --git a/user_guide_src/source/libraries/email/010.php b/user_guide_src/source/libraries/email/010.php new file mode 100644 index 000000000000..6383ac2e112d --- /dev/null +++ b/user_guide_src/source/libraries/email/010.php @@ -0,0 +1,3 @@ +setMessage('This is my message'); diff --git a/user_guide_src/source/libraries/email/011.php b/user_guide_src/source/libraries/email/011.php new file mode 100644 index 000000000000..75f8fe87587d --- /dev/null +++ b/user_guide_src/source/libraries/email/011.php @@ -0,0 +1,3 @@ +setAltMessage('This is the alternative message'); diff --git a/user_guide_src/source/libraries/email/012.php b/user_guide_src/source/libraries/email/012.php new file mode 100644 index 000000000000..b5fdc3f86ddd --- /dev/null +++ b/user_guide_src/source/libraries/email/012.php @@ -0,0 +1,4 @@ +setHeader('Header1', 'Value1'); +$email->setHeader('Header2', 'Value2'); diff --git a/user_guide_src/source/libraries/email/013.php b/user_guide_src/source/libraries/email/013.php new file mode 100644 index 000000000000..744360f49cc1 --- /dev/null +++ b/user_guide_src/source/libraries/email/013.php @@ -0,0 +1,12 @@ + $address) +{ + $email->clear(); + + $email->setTo($address); + $email->setFrom('your@example.com'); + $email->setSubject('Here is your info '.$name); + $email->setMessage('Hi ' . $name . ' Here is the info you requested.'); + $email->send(); +} diff --git a/user_guide_src/source/libraries/email/014.php b/user_guide_src/source/libraries/email/014.php new file mode 100644 index 000000000000..01bf56c01116 --- /dev/null +++ b/user_guide_src/source/libraries/email/014.php @@ -0,0 +1,3 @@ +clear(true); diff --git a/user_guide_src/source/libraries/email/015.php b/user_guide_src/source/libraries/email/015.php new file mode 100644 index 000000000000..60512f6b6416 --- /dev/null +++ b/user_guide_src/source/libraries/email/015.php @@ -0,0 +1,5 @@ +send()) { + // Generate error +} diff --git a/user_guide_src/source/libraries/email/016.php b/user_guide_src/source/libraries/email/016.php new file mode 100644 index 000000000000..2eb092b49787 --- /dev/null +++ b/user_guide_src/source/libraries/email/016.php @@ -0,0 +1,5 @@ +send(false)) { + // Parameters won't be cleared +} diff --git a/user_guide_src/source/libraries/email/017.php b/user_guide_src/source/libraries/email/017.php new file mode 100644 index 000000000000..391cd43214c8 --- /dev/null +++ b/user_guide_src/source/libraries/email/017.php @@ -0,0 +1,5 @@ +attach('/path/to/photo1.jpg'); +$email->attach('/path/to/photo2.jpg'); +$email->attach('/path/to/photo3.jpg'); diff --git a/user_guide_src/source/libraries/email/018.php b/user_guide_src/source/libraries/email/018.php new file mode 100644 index 000000000000..5f17f0aae311 --- /dev/null +++ b/user_guide_src/source/libraries/email/018.php @@ -0,0 +1,3 @@ +attach('image.jpg', 'inline'); diff --git a/user_guide_src/source/libraries/email/019.php b/user_guide_src/source/libraries/email/019.php new file mode 100644 index 000000000000..d5fc39267e3c --- /dev/null +++ b/user_guide_src/source/libraries/email/019.php @@ -0,0 +1,3 @@ +attach('http://example.com/filename.pdf'); diff --git a/user_guide_src/source/libraries/email/020.php b/user_guide_src/source/libraries/email/020.php new file mode 100644 index 000000000000..e14badb97d6b --- /dev/null +++ b/user_guide_src/source/libraries/email/020.php @@ -0,0 +1,3 @@ +attach('filename.pdf', 'attachment', 'report.pdf'); diff --git a/user_guide_src/source/libraries/email/021.php b/user_guide_src/source/libraries/email/021.php new file mode 100644 index 000000000000..103d8bc02c45 --- /dev/null +++ b/user_guide_src/source/libraries/email/021.php @@ -0,0 +1,3 @@ +attach($buffer, 'attachment', 'report.pdf', 'application/pdf'); diff --git a/user_guide_src/source/libraries/email/022.php b/user_guide_src/source/libraries/email/022.php new file mode 100644 index 000000000000..a6d9bfadeb70 --- /dev/null +++ b/user_guide_src/source/libraries/email/022.php @@ -0,0 +1,11 @@ +attach($filename); + +foreach ($list as $address) { + $email->setTo($address); + $cid = $email->setAttachmentCID($filename); + $email->setMessage('photo1'); + $email->send(); +} diff --git a/user_guide_src/source/libraries/email/023.php b/user_guide_src/source/libraries/email/023.php new file mode 100644 index 000000000000..82813787c1c9 --- /dev/null +++ b/user_guide_src/source/libraries/email/023.php @@ -0,0 +1,9 @@ +send(false); + +// Will only print the email headers, excluding the message subject and body +$email->printDebugger(['headers']); diff --git a/user_guide_src/source/libraries/encryption.rst b/user_guide_src/source/libraries/encryption.rst index 1a8bf834d94c..f14d433641b6 100644 --- a/user_guide_src/source/libraries/encryption.rst +++ b/user_guide_src/source/libraries/encryption.rst @@ -40,19 +40,17 @@ A more comprehensive package like `Halite ` Using the Encryption Library **************************** -Like all services in CodeIgniter, it can be loaded via ``Config\Services``:: +Like all services in CodeIgniter, it can be loaded via ``Config\Services``: - $encrypter = \Config\Services::encrypter(); +.. literalinclude:: encryption/001.php + :lines: 2- Assuming you have set your starting key (see :ref:`configuration`), encrypting and decrypting data is simple - pass the appropriate string to ``encrypt()`` -and/or ``decrypt()`` methods:: +and/or ``decrypt()`` methods: - $plainText = 'This is a plain-text message!'; - $ciphertext = $encrypter->encrypt($plainText); - - // Outputs: This is a plain-text message! - echo $encrypter->decrypt($ciphertext); +.. literalinclude:: encryption/002.php + :lines: 2- And that's it! The Encryption library will do everything necessary for the whole process to be cryptographically secure out-of-the-box. @@ -77,13 +75,9 @@ digest Message digest algorithm (``SHA512``) You can replace the config file's settings by passing a configuration object of your own to the ``Services`` call. The ``$config`` variable must be an instance of the ``Config\Encryption`` class. -:: - - $config = new \Config\Encryption(); - $config->key = 'aBigsecret_ofAtleast32Characters'; - $config->driver = 'OpenSSL'; - $encrypter = \Config\Services::encrypter($config); +.. literalinclude:: encryption/003.php + :lines: 2- Default Behavior ================ @@ -100,22 +94,18 @@ For AES-256, that's 256 bits or 32 bytes (characters) long. The key should be as random as possible, and it **must not** be a regular text string, nor the output of a hashing function, etc. To create a proper key, you can use the Encryption library's ``createKey()`` method. -:: - - // $key will be assigned a 32-byte (256-bit) random key - $key = \CodeIgniter\Encryption\Encryption::createKey(); - // for the SodiumHandler, you can use either: - $key = sodium_crypto_secretbox_keygen(); - $key = \CodeIgniter\Encryption\Encryption::createKey(SODIUM_CRYPTO_SECRETBOX_KEYBYTES); +.. literalinclude:: encryption/004.php + :lines: 2- The key can be stored in **app/Config/Encryption.php**, or you can design a storage mechanism of your own and pass the key dynamically when encrypting/decrypting. To save your key to your **app/Config/Encryption.php**, open the file -and set:: +and set: - public $key = 'YOUR KEY'; +.. literalinclude:: encryption/005.php + :lines: 2- Encoding Keys or Results ------------------------ @@ -123,20 +113,16 @@ Encoding Keys or Results You'll notice that the ``createKey()`` method outputs binary data, which is hard to deal with (i.e., a copy-paste may damage it), so you may use ``bin2hex()``, or ``base64_encode`` to work with the key in -a more friendly manner. For example:: - - // Get a hex-encoded representation of the key: - $encoded = bin2hex(\CodeIgniter\Encryption\Encryption::createKey(32)); +a more friendly manner. For example: - // Put the same value with hex2bin(), - // so that it is still passed as binary to the library: - $key = hex2bin('your-hex-encoded-key'); +.. literalinclude:: encryption/006.php + :lines: 2- You might find the same technique useful for the results -of encryption:: +of encryption: - // Encrypt some text & make the results text - $encoded = base64_encode($encrypter->encrypt($plaintext)); +.. literalinclude:: encryption/007.php + :lines: 2- Using Prefixes in Storing Keys ------------------------------ @@ -146,13 +132,9 @@ encryption keys: ``hex2bin:`` and ``base64:``. When these prefixes immediately precede the value of your key, ``Encryption`` will intelligently parse the key and still pass a binary string to the library. -:: - - // In Encryption, you may use - public $key = 'hex2bin:' - // or - public $key = 'base64:' +.. literalinclude:: encryption/008.php + :lines: 2- Similarly, you can use these prefixes in your **.env** file, too! :: @@ -231,13 +213,9 @@ Using the Encryption Service Directly Instead of (or in addition to) using ``Services`` as described in :ref:`usage`, you can create an "Encrypter" directly, or change the settings of an existing instance. -:: - - // create an Encryption instance - $encryption = new \CodeIgniter\Encryption\Encryption(); - // reconfigure an instance with different settings - $encrypter = $encryption->initialize($config); +.. literalinclude:: encryption/009.php + :lines: 2- Remember, that ``$config`` must be an instance of ``Config\Encryption`` class. @@ -265,9 +243,10 @@ Class Reference Initializes (configures) the library to use different settings. - Example:: + Example: - $encrypter = $encryption->initialize(['cipher' => '3des']); + .. literalinclude:: encryption/010.php + :lines: 2- Please refer to the :ref:`configuration` section for detailed info. @@ -290,13 +269,10 @@ Class Reference If you are using the SodiumHandler and want to pass a different ``blockSize`` on runtime, pass the ``blockSize`` key in the ``$params`` array. - Examples:: + Examples: - $ciphertext = $encrypter->encrypt('My secret message'); - $ciphertext = $encrypter->encrypt('My secret message', ['key' => 'New secret key']); - $ciphertext = $encrypter->encrypt('My secret message', ['key' => 'New secret key', 'blockSize' => 32]); - $ciphertext = $encrypter->encrypt('My secret message', 'New secret key'); - $ciphertext = $encrypter->encrypt('My secret message', ['blockSize' => 32]); + .. literalinclude:: encryption/011.php + :lines: 2- .. php:method:: decrypt($data[, $params = null]) @@ -315,10 +291,7 @@ Class Reference If you are using the SodiumHandler and want to pass a different ``blockSize`` on runtime, pass the ``blockSize`` key in the ``$params`` array. - Examples:: + Examples: - echo $encrypter->decrypt($ciphertext); - echo $encrypter->decrypt($ciphertext, ['key' => 'New secret key']); - echo $encrypter->decrypt($ciphertext, ['key' => 'New secret key', 'blockSize' => 32]); - echo $encrypter->decrypt($ciphertext, 'New secret key'); - echo $encrypter->decrypt($ciphertext, ['blockSize' => 32]); + .. literalinclude:: encryption/012.php + :lines: 2- diff --git a/user_guide_src/source/libraries/encryption/001.php b/user_guide_src/source/libraries/encryption/001.php new file mode 100644 index 000000000000..8f840be59245 --- /dev/null +++ b/user_guide_src/source/libraries/encryption/001.php @@ -0,0 +1,3 @@ +encrypt($plainText); + +// Outputs: This is a plain-text message! +echo $encrypter->decrypt($ciphertext); diff --git a/user_guide_src/source/libraries/encryption/003.php b/user_guide_src/source/libraries/encryption/003.php new file mode 100644 index 000000000000..772a2172417f --- /dev/null +++ b/user_guide_src/source/libraries/encryption/003.php @@ -0,0 +1,7 @@ +key = 'aBigsecret_ofAtleast32Characters'; +$config->driver = 'OpenSSL'; + +$encrypter = \Config\Services::encrypter($config); diff --git a/user_guide_src/source/libraries/encryption/004.php b/user_guide_src/source/libraries/encryption/004.php new file mode 100644 index 000000000000..30d861e74a40 --- /dev/null +++ b/user_guide_src/source/libraries/encryption/004.php @@ -0,0 +1,8 @@ +encrypt($plaintext)); diff --git a/user_guide_src/source/libraries/encryption/008.php b/user_guide_src/source/libraries/encryption/008.php new file mode 100644 index 000000000000..3e5899ec4cdf --- /dev/null +++ b/user_guide_src/source/libraries/encryption/008.php @@ -0,0 +1,7 @@ +' + +// or +public $key = 'base64:' diff --git a/user_guide_src/source/libraries/encryption/009.php b/user_guide_src/source/libraries/encryption/009.php new file mode 100644 index 000000000000..ec40cae6127c --- /dev/null +++ b/user_guide_src/source/libraries/encryption/009.php @@ -0,0 +1,7 @@ +initialize($config); diff --git a/user_guide_src/source/libraries/encryption/010.php b/user_guide_src/source/libraries/encryption/010.php new file mode 100644 index 000000000000..1bc9ebbbb2a5 --- /dev/null +++ b/user_guide_src/source/libraries/encryption/010.php @@ -0,0 +1,3 @@ +initialize(['cipher' => '3des']); diff --git a/user_guide_src/source/libraries/encryption/011.php b/user_guide_src/source/libraries/encryption/011.php new file mode 100644 index 000000000000..8b675de0f16f --- /dev/null +++ b/user_guide_src/source/libraries/encryption/011.php @@ -0,0 +1,7 @@ +encrypt('My secret message'); +$ciphertext = $encrypter->encrypt('My secret message', ['key' => 'New secret key']); +$ciphertext = $encrypter->encrypt('My secret message', ['key' => 'New secret key', 'blockSize' => 32]); +$ciphertext = $encrypter->encrypt('My secret message', 'New secret key'); +$ciphertext = $encrypter->encrypt('My secret message', ['blockSize' => 32]); diff --git a/user_guide_src/source/libraries/encryption/012.php b/user_guide_src/source/libraries/encryption/012.php new file mode 100644 index 000000000000..491e16f876e4 --- /dev/null +++ b/user_guide_src/source/libraries/encryption/012.php @@ -0,0 +1,7 @@ +decrypt($ciphertext); +echo $encrypter->decrypt($ciphertext, ['key' => 'New secret key']); +echo $encrypter->decrypt($ciphertext, ['key' => 'New secret key', 'blockSize' => 32]); +echo $encrypter->decrypt($ciphertext, 'New secret key'); +echo $encrypter->decrypt($ciphertext, ['blockSize' => 32]); diff --git a/user_guide_src/source/libraries/files.rst b/user_guide_src/source/libraries/files.rst index 6734e98d5fda..0cc766937028 100644 --- a/user_guide_src/source/libraries/files.rst +++ b/user_guide_src/source/libraries/files.rst @@ -17,32 +17,16 @@ You create a new File instance by passing in the path to the file in the constru By default, the file does not need to exist. However, you can pass an additional argument of "true" to check that the file exists and throw ``FileNotFoundException()`` if it does not. -:: - - $file = new \CodeIgniter\Files\File($path); +.. literalinclude:: files/001.php + :lines: 2- Taking Advantage of Spl ======================= -Once you have an instance, you have the full power of the SplFileInfo class at the ready, including:: - - // Get the file's basename - echo $file->getBasename(); - // Get last modified time - echo $file->getMTime(); - // Get the true real path - echo $file->getRealPath(); - // Get the file permissions - echo $file->getPerms(); +Once you have an instance, you have the full power of the SplFileInfo class at the ready, including: - // Write CSV rows to it. - if ($file->isWritable()) { - $csv = $file->openFile('w'); - - foreach ($rows as $row) { - $csv->fputcsv($row); - } - } +.. literalinclude:: files/002.php + :lines: 2- New Features ============ @@ -52,61 +36,62 @@ In addition to all of the methods in the SplFileInfo class, you get some new too **getRandomName()** You can generate a cryptographically secure random filename, with the current timestamp prepended, with the ``getRandomName()`` -method. This is especially useful to rename files when moving it so that the filename is unguessable:: +method. This is especially useful to rename files when moving it so that the filename is unguessable: - // Generates something like: 1465965676_385e33f741.jpg - $newName = $file->getRandomName(); +.. literalinclude:: files/003.php + :lines: 2- **getSize()** -Returns the size of the uploaded file in bytes:: +Returns the size of the uploaded file in bytes: - $size = $file->getSize(); // 256901 +.. literalinclude:: files/004.php + :lines: 2- **getSizeByUnit()** Returns the size of the uploaded file default in bytes. You can pass in either 'kb' or 'mb' as the first parameter to get -the results in kilobytes or megabytes, respectively:: +the results in kilobytes or megabytes, respectively: - $bytes = $file->getSizeByUnit(); // 256901 - $kilobytes = $file->getSizeByUnit('kb'); // 250.880 - $megabytes = $file->getSizeByUnit('mb'); // 0.245 +.. literalinclude:: files/005.php + :lines: 2- **getMimeType()** Retrieve the media type (mime type) of the file. Uses methods that are considered as secure as possible when determining -the type of file:: - - $type = $file->getMimeType(); +the type of file: - echo $type; // image/png +.. literalinclude:: files/006.php + :lines: 2- **guessExtension()** Attempts to determine the file extension based on the trusted ``getMimeType()`` method. If the mime type is unknown, will return null. This is often a more trusted source than simply using the extension provided by the filename. Uses -the values in **app/Config/Mimes.php** to determine extension:: +the values in **app/Config/Mimes.php** to determine extension: - // Returns 'jpg' (WITHOUT the period) - $ext = $file->guessExtension(); +.. literalinclude:: files/007.php + :lines: 2- Moving Files ------------ Each file can be moved to its new location with the aptly named ``move()`` method. This takes the directory to move -the file to as the first parameter:: +the file to as the first parameter: - $file->move(WRITEPATH . 'uploads'); +.. literalinclude:: files/008.php + :lines: 2- -By default, the original filename was used. You can specify a new filename by passing it as the second parameter:: +By default, the original filename was used. You can specify a new filename by passing it as the second parameter: - $newName = $file->getRandomName(); - $file->move(WRITEPATH . 'uploads', $newName); +.. literalinclude:: files/009.php + :lines: 2- The move() method returns a new File instance that for the relocated file, so you must capture the result if the -resulting location is needed:: +resulting location is needed: - $file = $file->move(WRITEPATH . 'uploads'); +.. literalinclude:: files/010.php + :lines: 2- **************** File Collections @@ -114,32 +99,22 @@ File Collections Working with groups of files can be cumbersome, so the framework supplies the ``FileCollection`` class to facilitate locating and working with groups of files across the filesystem. At its most basic, ``FileCollection`` is an index -of files you set or build:: +of files you set or build: - $files = new FileCollection([ - FCPATH . 'index.php', - ROOTPATH . 'spark', - ]); - $files->addDirectory(APPPATH . 'Filters'); +.. literalinclude:: files/011.php + :lines: 2- After you have input the files you would like to work with you may remove files or use the filtering commands to remove -or retain files matching a certain regex or glob-style pattern:: +or retain files matching a certain regex or glob-style pattern: - $files->removeFile(APPPATH . 'Filters/DevelopToolbar'); - - $files->removePattern('#\.gitkeep#'); - $files->retainPattern('*.php'); +.. literalinclude:: files/012.php + :lines: 2- When your collection is complete, you can use ``get()`` to retrieve the final list of file paths, or take advantage of -``FileCollection`` being countable and iterable to work directly with each ``File``:: - - echo 'My files: ' . implode(PHP_EOL, $files->get()); - echo 'I have ' . count($files) . ' files!'; +``FileCollection`` being countable and iterable to work directly with each ``File``: - foreach ($files as $file) { - echo 'Moving ' . $file->getBasename() . ', ' . $file->getSizeByUnit('mb'); - $file->move(WRITABLE . $file->getRandomName()); - } +.. literalinclude:: files/013.php + :lines: 2- Below are the specific methods for working with a ``FileCollection``. @@ -154,15 +129,10 @@ The constructor accepts an optional array of file paths to use as the initial co **define()** Allows child classes to define their own initial files. This method is called by the constructor and allows -predefined collections without having to use their methods. Example:: +predefined collections without having to use their methods. Example: - class ConfigCollection extends \CodeIgniter\Files\FileCollection - { - protected function define(): void - { - $this->add(APPPATH . 'Config', true)->retainPattern('*.php'); - } - } +.. literalinclude:: files/014.php + :lines: 2- Now you may use the ``ConfigCollection`` anywhere in your project to access all App Config files without having to re-call the collection methods every time. @@ -208,16 +178,10 @@ to ``glob()`` (like ``*.css``). If a ``$scope`` is provided then only files in or under that directory will be considered (i.e. files outside of ``$scope`` are always retained). When no scope is provided then all files are subject. -Examples:: - - $files = new FileCollection(); - $files->add(APPPATH . 'Config', true); // Adds all Config files and directories - - $files->removePattern('*tion.php'); // Would remove Encryption.php, Validation.php, and boot/production.php - $files->removePattern('*tion.php', APPPATH . 'Config/boot'); // Would only remove boot/production.php +Examples: - $files->retainPattern('#A.+php$#'); // Would keep only Autoload.php - $files->retainPattern('#d.+php$#', APPPATH . 'Config/boot'); // Would keep everything but boot/production.php and boot/testing.php +.. literalinclude:: files/015.php + :lines: 2- Retrieving Files ================ diff --git a/user_guide_src/source/libraries/files/001.php b/user_guide_src/source/libraries/files/001.php new file mode 100644 index 000000000000..643758d14ca8 --- /dev/null +++ b/user_guide_src/source/libraries/files/001.php @@ -0,0 +1,3 @@ +getBasename(); +// Get last modified time +echo $file->getMTime(); +// Get the true real path +echo $file->getRealPath(); +// Get the file permissions +echo $file->getPerms(); + +// Write CSV rows to it. +if ($file->isWritable()) { + $csv = $file->openFile('w'); + + foreach ($rows as $row) { + $csv->fputcsv($row); + } +} diff --git a/user_guide_src/source/libraries/files/003.php b/user_guide_src/source/libraries/files/003.php new file mode 100644 index 000000000000..53327d59bd0f --- /dev/null +++ b/user_guide_src/source/libraries/files/003.php @@ -0,0 +1,4 @@ +getRandomName(); diff --git a/user_guide_src/source/libraries/files/004.php b/user_guide_src/source/libraries/files/004.php new file mode 100644 index 000000000000..e73de3b6cd74 --- /dev/null +++ b/user_guide_src/source/libraries/files/004.php @@ -0,0 +1,3 @@ +getSize(); // 256901 diff --git a/user_guide_src/source/libraries/files/005.php b/user_guide_src/source/libraries/files/005.php new file mode 100644 index 000000000000..ee9043ff92a6 --- /dev/null +++ b/user_guide_src/source/libraries/files/005.php @@ -0,0 +1,5 @@ +getSizeByUnit(); // 256901 +$kilobytes = $file->getSizeByUnit('kb'); // 250.880 +$megabytes = $file->getSizeByUnit('mb'); // 0.245 diff --git a/user_guide_src/source/libraries/files/006.php b/user_guide_src/source/libraries/files/006.php new file mode 100644 index 000000000000..5c8ae9a08945 --- /dev/null +++ b/user_guide_src/source/libraries/files/006.php @@ -0,0 +1,5 @@ +getMimeType(); + +echo $type; // image/png diff --git a/user_guide_src/source/libraries/files/007.php b/user_guide_src/source/libraries/files/007.php new file mode 100644 index 000000000000..26be30a2c7bc --- /dev/null +++ b/user_guide_src/source/libraries/files/007.php @@ -0,0 +1,4 @@ +guessExtension(); diff --git a/user_guide_src/source/libraries/files/008.php b/user_guide_src/source/libraries/files/008.php new file mode 100644 index 000000000000..12499a3ca1ba --- /dev/null +++ b/user_guide_src/source/libraries/files/008.php @@ -0,0 +1,3 @@ +move(WRITEPATH . 'uploads'); diff --git a/user_guide_src/source/libraries/files/009.php b/user_guide_src/source/libraries/files/009.php new file mode 100644 index 000000000000..2e6b39645a4b --- /dev/null +++ b/user_guide_src/source/libraries/files/009.php @@ -0,0 +1,4 @@ +getRandomName(); +$file->move(WRITEPATH . 'uploads', $newName); diff --git a/user_guide_src/source/libraries/files/010.php b/user_guide_src/source/libraries/files/010.php new file mode 100644 index 000000000000..2a3fcab40957 --- /dev/null +++ b/user_guide_src/source/libraries/files/010.php @@ -0,0 +1,3 @@ +move(WRITEPATH . 'uploads'); diff --git a/user_guide_src/source/libraries/files/011.php b/user_guide_src/source/libraries/files/011.php new file mode 100644 index 000000000000..fb15a5ca6cbd --- /dev/null +++ b/user_guide_src/source/libraries/files/011.php @@ -0,0 +1,7 @@ +addDirectory(APPPATH . 'Filters'); diff --git a/user_guide_src/source/libraries/files/012.php b/user_guide_src/source/libraries/files/012.php new file mode 100644 index 000000000000..db0f881014c0 --- /dev/null +++ b/user_guide_src/source/libraries/files/012.php @@ -0,0 +1,6 @@ +removeFile(APPPATH . 'Filters/DevelopToolbar'); + +$files->removePattern('#\.gitkeep#'); +$files->retainPattern('*.php'); diff --git a/user_guide_src/source/libraries/files/013.php b/user_guide_src/source/libraries/files/013.php new file mode 100644 index 000000000000..a529fd0bcd6c --- /dev/null +++ b/user_guide_src/source/libraries/files/013.php @@ -0,0 +1,9 @@ +get()); +echo 'I have ' . count($files) . ' files!'; + +foreach ($files as $file) { + echo 'Moving ' . $file->getBasename() . ', ' . $file->getSizeByUnit('mb'); + $file->move(WRITABLE . $file->getRandomName()); +} diff --git a/user_guide_src/source/libraries/files/014.php b/user_guide_src/source/libraries/files/014.php new file mode 100644 index 000000000000..a768829427f3 --- /dev/null +++ b/user_guide_src/source/libraries/files/014.php @@ -0,0 +1,9 @@ +add(APPPATH . 'Config', true)->retainPattern('*.php'); + } +} diff --git a/user_guide_src/source/libraries/files/015.php b/user_guide_src/source/libraries/files/015.php new file mode 100644 index 000000000000..7e5c65e9a3d6 --- /dev/null +++ b/user_guide_src/source/libraries/files/015.php @@ -0,0 +1,10 @@ +add(APPPATH . 'Config', true); // Adds all Config files and directories + +$files->removePattern('*tion.php'); // Would remove Encryption.php, Validation.php, and boot/production.php +$files->removePattern('*tion.php', APPPATH . 'Config/boot'); // Would only remove boot/production.php + +$files->retainPattern('#A.+php$#'); // Would keep only Autoload.php +$files->retainPattern('#d.+php$#', APPPATH . 'Config/boot'); // Would keep everything but boot/production.php and boot/testing.php diff --git a/user_guide_src/source/libraries/honeypot.rst b/user_guide_src/source/libraries/honeypot.rst index 0b9114456cf0..69c23e47ca03 100644 --- a/user_guide_src/source/libraries/honeypot.rst +++ b/user_guide_src/source/libraries/honeypot.rst @@ -15,18 +15,10 @@ Enabling Honeypot ===================== To enable a Honeypot, changes have to be made to the **app/Config/Filters.php**. Just uncomment honeypot -from the ``$globals`` array, like...:: - - public $globals = [ - 'before' => [ - 'honeypot' - // 'csrf', - ], - 'after' => [ - 'toolbar', - 'honeypot', - ], - ]; +from the ``$globals`` array, like...: + +.. literalinclude:: honeypot/001.php + :lines: 2- A sample Honeypot filter is bundled, as ``system/Filters/Honeypot.php``. If it is not suitable, make your own at ``app/Filters/Honeypot.php``, diff --git a/user_guide_src/source/libraries/honeypot/001.php b/user_guide_src/source/libraries/honeypot/001.php new file mode 100644 index 000000000000..1ed16460a9a4 --- /dev/null +++ b/user_guide_src/source/libraries/honeypot/001.php @@ -0,0 +1,12 @@ + [ + 'honeypot' + // 'csrf', + ], + 'after' => [ + 'toolbar', + 'honeypot', + ], +]; diff --git a/user_guide_src/source/libraries/images.rst b/user_guide_src/source/libraries/images.rst index bd71be9657f2..029c534cacbe 100644 --- a/user_guide_src/source/libraries/images.rst +++ b/user_guide_src/source/libraries/images.rst @@ -22,14 +22,16 @@ Initializing the Class ********************** Like most other classes in CodeIgniter, the image class is initialized -in your controller by calling the Services class:: +in your controller by calling the Services class: - $image = \Config\Services::image(); +.. literalinclude:: images/001.php + :lines: 2- You can pass the alias for the image library you wish to use into the -Service function:: +Service function: - $image = Config\Services::image('imagick'); +.. literalinclude:: images/002.php + :lines: 2- The available Handlers are as follows: @@ -50,12 +52,10 @@ Regardless of the type of processing you would like to perform (resizing, cropping, rotation, or watermarking), the general process is identical. You will set some preferences corresponding to the action you intend to perform, then call one of the available processing functions. -For example, to create an image thumbnail you'll do this:: +For example, to create an image thumbnail you'll do this: - $image = \Config\Services::image() - ->withFile('/path/to/image/mypic.jpg') - ->fit(100, 100, 'center') - ->save('/path/to/image/mypic_thumb.jpg'); +.. literalinclude:: images/003.php + :lines: 2- The above code tells the library to look for an image called *mypic.jpg* located in the source_image folder, then create a @@ -67,14 +67,10 @@ desired aspect ratio, and then crop and resize the result. An image can be processed through as many of the available methods as needed before saving. The original image is left untouched, and a new image is used and passed through each method, applying the results on top of the -previous results:: +previous results: - $image = \Config\Services::image() - ->withFile('/path/to/image/mypic.jpg') - ->reorient() - ->rotate(90) - ->crop(100, 100, 0, 0) - ->save('/path/to/image/mypic_thumb.jpg'); +.. literalinclude:: images/004.php + :lines: 2- This example would take the same image and first fix any mobile phone orientation issues, rotate the image by 90 degrees, and then crop the result into a 100x100 pixel image, @@ -94,22 +90,18 @@ Image Quality ``save()`` can take an additional parameter ``$quality`` to alter the resulting image quality. Values range from 0 to 100 with 90 being the framework default. This parameter -only applies to JPEG images and will be ignored otherwise:: +only applies to JPEG images and will be ignored otherwise: - $image = \Config\Services::image() - ->withFile('/path/to/image/mypic.jpg') - // processing methods - ->save('/path/to/image/my_low_quality_pic.jpg', 10); +.. literalinclude:: images/005.php + :lines: 2- .. note:: Higher quality will result in larger file sizes. See also https://www.php.net/manual/en/function.imagejpeg.php If you are only interested in changing the image quality without doing any processing. -You will need to include the image resource or you will end up with an exact copy:: +You will need to include the image resource or you will end up with an exact copy: - $image = \Config\Services::image() - ->withFile('/path/to/image/mypic.jpg') - ->withResource() - ->save('/path/to/image/my_low_quality_pic.jpg', 10); +.. literalinclude:: images/006.php + :lines: 2- Processing Methods ================== @@ -128,16 +120,10 @@ There are seven available processing methods: These methods return the class instance so they can be chained together, as shown above. If they fail they will throw a ``CodeIgniter\Images\ImageException`` that contains the error message. A good practice is to catch the exceptions, showing an -error upon failure, like this:: +error upon failure, like this: - try { - $image = \Config\Services::image() - ->withFile('/path/to/image/mypic.jpg') - ->fit(100, 100, 'center') - ->save('/path/to/image/mypic_thumb.jpg'); - } catch (CodeIgniter\Images\ImageException $e) { - echo $e->getMessage(); - } +.. literalinclude:: images/007.php + :lines: 2- Cropping Images --------------- @@ -155,20 +141,10 @@ thumbnail images that should match a certain size/aspect ratio. This is handled - **$masterDim** specifies which dimension should be left untouched when $maintainRatio is true. Values can be: 'width', 'height', or 'auto'. To take a 50x50 pixel square out of the center of an image, you would need to first calculate the appropriate x and y -offset values:: +offset values: - $info = \Config\Services::image('imagick') - ->withFile('/path/to/image/mypic.jpg') - ->getFile() - ->getProperties(true); - - $xOffset = ($info['width'] / 2) - 25; - $yOffset = ($info['height'] / 2) - 25; - - \Config\Services::image('imagick') - ->withFile('/path/to/image/mypic.jpg') - ->crop(50, 50, $xOffset, $yOffset) - ->save('/path/to/new/image.jpg'); +.. literalinclude:: images/008.php + :lines: 2- Converting Images ----------------- @@ -177,12 +153,10 @@ The ``convert()`` method changes the library's internal indicator for the desire convert(int $imageType) -- **$imageType** is one of PHP's image type constants (see for example https://www.php.net/manual/en/function.image-type-to-mime-type.php):: +- **$imageType** is one of PHP's image type constants (see for example https://www.php.net/manual/en/function.image-type-to-mime-type.php): - \Config\Services::image() - ->withFile('/path/to/image/mypic.jpg') - ->convert(IMAGETYPE_PNG) - ->save('/path/to/new/image.png'); + .. literalinclude:: images/009.php + :lines: 2- .. note:: ImageMagick already saves files in the type indicated by their extension, ignoring **$imageType** @@ -204,12 +178,10 @@ The ``fit()`` method aims to help simplify cropping a portion of an image in a " - **$height** is the desired final height of the image. - **$position** determines the portion of the image to crop out. Allowed positions: 'top-left', 'top', 'top-right', 'left', 'center', 'right', 'bottom-left', 'bottom', 'bottom-right'. -This provides a much simpler way to crop that will always maintain the aspect ratio:: +This provides a much simpler way to crop that will always maintain the aspect ratio: - \Config\Services::image('imagick') - ->withFile('/path/to/image/mypic.jpg') - ->fit(100, 150, 'left') - ->save('/path/to/new/image.jpg'); +.. literalinclude:: images/010.php + :lines: 2- Flattening Images ----------------- @@ -226,17 +198,8 @@ The ``flatten()`` method aims to add a background color behind transparent image - **$green** is the green value of the background. - **$blue** is the blue value of the background. -:: - - \Config\Services::image('imagick') - ->withFile('/path/to/image/mypic.png') - ->flatten() - ->save('/path/to/new/image.jpg'); - - \Config\Services::image('imagick') - ->withFile('/path/to/image/mypic.png') - ->flatten(25,25,112) - ->save('/path/to/new/image.jpg'); +.. literalinclude:: images/011.php + :lines: 2- Flipping Images --------------- @@ -247,12 +210,8 @@ Images can be flipped along either their horizontal or vertical axis:: - **$dir** specifies the axis to flip along. Can be either 'vertical' or 'horizontal'. -:: - - \Config\Services::image('imagick') - ->withFile('/path/to/image/mypic.jpg') - ->flip('horizontal') - ->save('/path/to/new/image.jpg'); +.. literalinclude:: images/012.php + :lines: 2- Resizing Images --------------- @@ -270,12 +229,8 @@ When resizing images you can choose whether to maintain the ratio of the origina image to fit the desired dimensions. If $maintainRatio is true, the dimension specified by $masterDim will stay the same, while the other dimension will be altered to match the original image's aspect ratio. -:: - - \Config\Services::image('imagick') - ->withFile('/path/to/image/mypic.jpg') - ->resize(200, 100, true, 'height') - ->save('/path/to/new/image.jpg'); +.. literalinclude:: images/013.php + :lines: 2- Rotating Images --------------- @@ -301,19 +256,10 @@ products. text(string $text, array $options = []) The first parameter is the string of text that you wish to display. The second parameter is an array of options -that allow you to specify how the text should be displayed:: - - \Config\Services::image('imagick') - ->withFile('/path/to/image/mypic.jpg') - ->text('Copyright 2017 My Photo Co', [ - 'color' => '#fff', - 'opacity' => 0.5, - 'withShadow' => true, - 'hAlign' => 'center', - 'vAlign' => 'bottom', - 'fontSize' => 20 - ]) - ->save('/path/to/new/image.jpg'); +that allow you to specify how the text should be displayed: + +.. literalinclude:: images/014.php + :lines: 2- The possible options that are recognized are as follows: diff --git a/user_guide_src/source/libraries/images/001.php b/user_guide_src/source/libraries/images/001.php new file mode 100644 index 000000000000..780bb37b3a4d --- /dev/null +++ b/user_guide_src/source/libraries/images/001.php @@ -0,0 +1,3 @@ +withFile('/path/to/image/mypic.jpg') + ->fit(100, 100, 'center') + ->save('/path/to/image/mypic_thumb.jpg'); diff --git a/user_guide_src/source/libraries/images/004.php b/user_guide_src/source/libraries/images/004.php new file mode 100644 index 000000000000..ec6026592341 --- /dev/null +++ b/user_guide_src/source/libraries/images/004.php @@ -0,0 +1,8 @@ +withFile('/path/to/image/mypic.jpg') + ->reorient() + ->rotate(90) + ->crop(100, 100, 0, 0) + ->save('/path/to/image/mypic_thumb.jpg'); diff --git a/user_guide_src/source/libraries/images/005.php b/user_guide_src/source/libraries/images/005.php new file mode 100644 index 000000000000..3f7470ee82ac --- /dev/null +++ b/user_guide_src/source/libraries/images/005.php @@ -0,0 +1,6 @@ +withFile('/path/to/image/mypic.jpg') + // processing methods + ->save('/path/to/image/my_low_quality_pic.jpg', 10); diff --git a/user_guide_src/source/libraries/images/006.php b/user_guide_src/source/libraries/images/006.php new file mode 100644 index 000000000000..9bfcb18b3b7e --- /dev/null +++ b/user_guide_src/source/libraries/images/006.php @@ -0,0 +1,6 @@ +withFile('/path/to/image/mypic.jpg') + ->withResource() + ->save('/path/to/image/my_low_quality_pic.jpg', 10); diff --git a/user_guide_src/source/libraries/images/007.php b/user_guide_src/source/libraries/images/007.php new file mode 100644 index 000000000000..503c038cf81c --- /dev/null +++ b/user_guide_src/source/libraries/images/007.php @@ -0,0 +1,10 @@ +withFile('/path/to/image/mypic.jpg') + ->fit(100, 100, 'center') + ->save('/path/to/image/mypic_thumb.jpg'); +} catch (CodeIgniter\Images\ImageException $e) { + echo $e->getMessage(); +} diff --git a/user_guide_src/source/libraries/images/008.php b/user_guide_src/source/libraries/images/008.php new file mode 100644 index 000000000000..01406733d31b --- /dev/null +++ b/user_guide_src/source/libraries/images/008.php @@ -0,0 +1,14 @@ +withFile('/path/to/image/mypic.jpg') + ->getFile() + ->getProperties(true); + +$xOffset = ($info['width'] / 2) - 25; +$yOffset = ($info['height'] / 2) - 25; + +\Config\Services::image('imagick') + ->withFile('/path/to/image/mypic.jpg') + ->crop(50, 50, $xOffset, $yOffset) + ->save('/path/to/new/image.jpg'); diff --git a/user_guide_src/source/libraries/images/009.php b/user_guide_src/source/libraries/images/009.php new file mode 100644 index 000000000000..6314181ef435 --- /dev/null +++ b/user_guide_src/source/libraries/images/009.php @@ -0,0 +1,6 @@ +withFile('/path/to/image/mypic.jpg') + ->convert(IMAGETYPE_PNG) + ->save('/path/to/new/image.png'); diff --git a/user_guide_src/source/libraries/images/010.php b/user_guide_src/source/libraries/images/010.php new file mode 100644 index 000000000000..b70b179815cd --- /dev/null +++ b/user_guide_src/source/libraries/images/010.php @@ -0,0 +1,6 @@ +withFile('/path/to/image/mypic.jpg') + ->fit(100, 150, 'left') + ->save('/path/to/new/image.jpg'); diff --git a/user_guide_src/source/libraries/images/011.php b/user_guide_src/source/libraries/images/011.php new file mode 100644 index 000000000000..c72932893af8 --- /dev/null +++ b/user_guide_src/source/libraries/images/011.php @@ -0,0 +1,11 @@ +withFile('/path/to/image/mypic.png') + ->flatten() + ->save('/path/to/new/image.jpg'); + +\Config\Services::image('imagick') + ->withFile('/path/to/image/mypic.png') + ->flatten(25,25,112) + ->save('/path/to/new/image.jpg'); diff --git a/user_guide_src/source/libraries/images/012.php b/user_guide_src/source/libraries/images/012.php new file mode 100644 index 000000000000..581a984238bd --- /dev/null +++ b/user_guide_src/source/libraries/images/012.php @@ -0,0 +1,6 @@ +withFile('/path/to/image/mypic.jpg') + ->flip('horizontal') + ->save('/path/to/new/image.jpg'); diff --git a/user_guide_src/source/libraries/images/013.php b/user_guide_src/source/libraries/images/013.php new file mode 100644 index 000000000000..c51a7126be8d --- /dev/null +++ b/user_guide_src/source/libraries/images/013.php @@ -0,0 +1,6 @@ +withFile('/path/to/image/mypic.jpg') + ->resize(200, 100, true, 'height') + ->save('/path/to/new/image.jpg'); diff --git a/user_guide_src/source/libraries/images/014.php b/user_guide_src/source/libraries/images/014.php new file mode 100644 index 000000000000..4afd1e12d420 --- /dev/null +++ b/user_guide_src/source/libraries/images/014.php @@ -0,0 +1,13 @@ +withFile('/path/to/image/mypic.jpg') + ->text('Copyright 2017 My Photo Co', [ + 'color' => '#fff', + 'opacity' => 0.5, + 'withShadow' => true, + 'hAlign' => 'center', + 'vAlign' => 'bottom', + 'fontSize' => 20 + ]) + ->save('/path/to/new/image.jpg'); diff --git a/user_guide_src/source/libraries/pagination.rst b/user_guide_src/source/libraries/pagination.rst index dfab3b6c80f4..8a79531326d6 100644 --- a/user_guide_src/source/libraries/pagination.rst +++ b/user_guide_src/source/libraries/pagination.rst @@ -14,9 +14,10 @@ Loading the Library ******************* Like all services in CodeIgniter, it can be loaded via ``Config\Services``, though you usually will not need -to load it manually:: +to load it manually: - $pager = \Config\Services::pager(); +.. literalinclude:: pagination/001.php + :lines: 2- *************************** Paginating Database Results @@ -27,28 +28,9 @@ When using the :doc:`Model ` class, you can use its built-in ``pa retrieve the current batch of results, as well as set up the Pager library so it's ready to use in your controllers. It even reads the current page it should display from the current URL via a ``page=X`` query variable. -To provide a paginated list of users in your application, your controller's method would look something like:: +To provide a paginated list of users in your application, your controller's method would look something like: - $model->paginate(10), - 'pager' => $model->pager, - ]; - - echo view('users/index', $data); - } - } +.. literalinclude:: pagination/002.php In this example, we first create a new instance of our ``UserModel``. Then we populate the data to send to the view. The first element is the results from the database, **users**, which is retrieved for the correct page, returning @@ -60,28 +42,10 @@ that and assign it to the ``$pager`` variable in the view. Therefore, trying to use ``$db->query()`` and Model::paginate() **will not work** because ``$db->query()`` executes the query immediately and is not associated with a QueryBuilder. -To define conditions for pagination in a model, you can:: +To define conditions for pagination in a model, you can: - // You can specify conditions directly. - $model = new \App\Models\UserModel(); - - $data = [ - 'users' => $model->where('ban', 1)->paginate(10), - 'pager' => $model->pager, - ]; - - // You can move the conditions to a separate method. - // Model method - public function banned() - { - $this->builder()->where('ban', 1); - return $this; // This will allow the call chain to be used. - } - - $data = [ - 'users' => $model->banned()->paginate(10), - 'pager' => $model->pager, - ]; +.. literalinclude:: pagination/003.php + :lines: 2- Within the view, we then need to tell it where to display the resulting links:: @@ -106,26 +70,10 @@ Paginating Multiple Results =========================== If you need to provide links from two different result sets, you can pass group names to most of the pagination -methods to keep the data separate:: - - // In the Controller - public function index() - { - $userModel = new \App\Models\UserModel(); - $pageModel = new \App\Models\PageModel(); - - $data = [ - 'users' => $userModel->paginate(10, 'group1'), - 'pages' => $pageModel->paginate(15, 'group2'), - 'pager' => $userModel->pager, - ]; +methods to keep the data separate: - echo view('users/index', $data); - } - - // In the views: - links('group1') ?> - simpleLinks('group2') ?> +.. literalinclude:: pagination/004.php + :lines: 2- Setting Page Manually ===================== @@ -133,12 +81,8 @@ Setting Page Manually If you need to specify which page of results to return you can specify the page as the 3rd argument. This can be handy when you have a different manner than the default ``$_GET`` varibable to control which page to show. -:: - - $userModel = new \App\Models\UserModel(); - $page = 3; - - $users = $userModel->paginate(10, 'group1', $page); +.. literalinclude:: pagination/005.php + :lines: 2- Specifying the URI Segment for Page =================================== @@ -147,9 +91,8 @@ It is also possible to use a URI segment for the page number, instead of the pag segment number to use as the fourth argument. URIs generated by the pager would then look like **https://domain.tld/foo/bar/[pageNumber]** instead of **https://domain.tld/foo/bar?page=[pageNumber]**. -:: - - $users = $userModel->paginate(10, 'group1', null, $segment); +.. literalinclude:: pagination/006.php + :lines: 2- Please note: ``$segment`` value cannot be greater than the number of URI segments plus 1. @@ -179,11 +122,10 @@ the previous section. Specify the segment number to use as the fifth parameter t Please note: ``$segment`` value cannot be greater than the number of URI segments plus 1. -If you in need to show many pagers on one page then additional parameter which will define a group could be helpful:: +If you in need to show many pagers on one page then additional parameter which will define a group could be helpful: - $pager = service('pager'); - $pager->setPath('path/for/my-group', 'my-group'); // Additionally you could define path for every group. - $pager->makeLinks($page, $perPage, $total, 'template_name', $segment, 'my-group'); +.. literalinclude:: pagination/007.php + :lines: 2- Pagination library uses **page** query parameter for HTTP queries by default (if no group or ``default`` group name given) or ``page_[groupName]`` for custom group names. @@ -192,15 +134,15 @@ Paginating with Only Expected Queries By default, all GET queries are shown in the pagination links. -For example, when accessing the URL **https://domain.tld?search=foo&order=asc&hello=i+am+here&page=2**, the page 3 link can be generated, along with the other links, as follows:: +For example, when accessing the URL **https://domain.tld?search=foo&order=asc&hello=i+am+here&page=2**, the page 3 link can be generated, along with the other links, as follows: - echo $pager->links(); - // Page 3 link: https://domain.tld?search=foo&order=asc&hello=i+am+here&page=3 +.. literalinclude:: pagination/008.php + :lines: 2- -The ``only()`` method allows you to limit this just to queries already expected:: +The ``only()`` method allows you to limit this just to queries already expected: - echo $pager->only(['search', 'order'])->links(); - // Page 3 link: https://domain.tld?search=foo&order=asc&page=3 +.. literalinclude:: pagination/009.php + :lines: 2- The *page* query is enabled by default. And ``only()`` acts in all pagination links. @@ -212,12 +154,10 @@ View Configuration ================== When the links are rendered out to the page, they use a view file to describe the HTML. You can easily change the view -that is used by editing **app/Config/Pager.php**:: +that is used by editing **app/Config/Pager.php**: - public $templates = [ - 'default_full' => 'CodeIgniter\Pager\Views\default_full', - 'default_simple' => 'CodeIgniter\Pager\Views\default_simple', - ]; +.. literalinclude:: pagination/010.php + :lines: 2- This setting stores the alias and :doc:`namespaced view paths ` for the view that should be used. The ``default_full`` and ``default_simple`` views are used for the ``links()`` and ``simpleLinks()`` @@ -226,25 +166,23 @@ methods, respectively. To change the way those are displayed application-wide, y For example, say you create a new view file that works with the Foundation CSS framework, and you place that file at **app/Views/Pagers/foundation_full.php**. Since the **application** directory is namespaced as ``App``, and all directories underneath it map directly to segments of the namespace, you can locate -the view file through it's namespace:: +the view file through it's namespace: - 'default_full' => 'App\Views\Pagers\foundation_full', +.. literalinclude:: pagination/011.php + :lines: 2- Since it is under the standard **app/Views** directory, though, you do not need to namespace it since the -``view()`` method can locate it by filename. In that case, you can simply give the sub-directory and file name:: +``view()`` method can locate it by filename. In that case, you can simply give the sub-directory and file name: - 'default_full' => 'Pagers/foundation_full', +.. literalinclude:: pagination/012.php + :lines: 2- Once you have created the view and set it in the configuration, it will automatically be used. You don't have to replace the existing templates. You can create as many additional templates as you need in the configuration file. A common situation would be needing different styles for the frontend and the backend of your application. -:: - public $templates = [ - 'default_full' => 'CodeIgniter\Pager\Views\default_full', - 'default_simple' => 'CodeIgniter\Pager\Views\default_simple', - 'front_full' => 'App\Views\Pagers\foundation_full', - ]; +.. literalinclude:: pagination/013.php + :lines: 2- Once configured, you can specify it as a the last parameter in the ``links()``, ``simpleLinks()``, and ``makeLinks()`` methods:: @@ -258,47 +196,9 @@ Creating the View When you create a new view, you only need to create the code that is needed for creating the pagination links themselves. You should not create unnecessary wrapping divs since it might be used in multiple places and you only limit their -usefulness. It is easiest to demonstrate creating a new view by showing you the existing ``default_full`` template:: - - setSurroundCount(2) ?> - - +usefulness. It is easiest to demonstrate creating a new view by showing you the existing ``default_full`` template: + +.. literalinclude:: pagination/014.php **setSurroundCount()** @@ -326,57 +226,18 @@ result set. **links()** Returns an array of data about all of the numbered links. Each link's array contains the uri for the link, the -title, which is just the number, and a boolean that tells whether the link is the current/active link or not:: +title, which is just the number, and a boolean that tells whether the link is the current/active link or not: - $link = [ - 'active' => false, - 'uri' => 'https://example.com/foo?page=2', - 'title' => 1, - ]; +.. literalinclude:: pagination/015.php + :lines: 2- In the code presented for the standard pagination structure, the methods ``getPrevious()`` and ``getNext()`` are used to obtain the links to the previous and next pagination groups respectively. If you want to use the pagination structure where prev and next will be links to the previous and next pages based on the current page, just replace the ``getPrevious()`` and ``getNext()`` methods with ``getPreviousPage()`` and ``getNextPage()``, and the methods ``hasPrevious()`` and ``hasNext()`` by ``hasPreviousPage()`` and ``hasNextPage()`` respectively. -See following an example with these changes:: - - +See following an example with these changes: + +.. literalinclude:: pagination/016.php **hasPreviousPage()** & **hasNextPage()** diff --git a/user_guide_src/source/libraries/pagination/001.php b/user_guide_src/source/libraries/pagination/001.php new file mode 100644 index 000000000000..ec86f0e73490 --- /dev/null +++ b/user_guide_src/source/libraries/pagination/001.php @@ -0,0 +1,3 @@ + $model->paginate(10), + 'pager' => $model->pager, + ]; + + echo view('users/index', $data); + } +} diff --git a/user_guide_src/source/libraries/pagination/003.php b/user_guide_src/source/libraries/pagination/003.php new file mode 100644 index 000000000000..f0ea0d90ed76 --- /dev/null +++ b/user_guide_src/source/libraries/pagination/003.php @@ -0,0 +1,22 @@ + $model->where('ban', 1)->paginate(10), + 'pager' => $model->pager, +]; + +// You can move the conditions to a separate method. +// Model method +public function banned() +{ + $this->builder()->where('ban', 1); + return $this; // This will allow the call chain to be used. +} + +$data = [ + 'users' => $model->banned()->paginate(10), + 'pager' => $model->pager, +]; diff --git a/user_guide_src/source/libraries/pagination/004.php b/user_guide_src/source/libraries/pagination/004.php new file mode 100644 index 000000000000..a61b3c3bad2a --- /dev/null +++ b/user_guide_src/source/libraries/pagination/004.php @@ -0,0 +1,20 @@ + $userModel->paginate(10, 'group1'), + 'pages' => $pageModel->paginate(15, 'group2'), + 'pager' => $userModel->pager, + ]; + + echo view('users/index', $data); +} + +// In the views: +links('group1') ?> +simpleLinks('group2') ?> diff --git a/user_guide_src/source/libraries/pagination/005.php b/user_guide_src/source/libraries/pagination/005.php new file mode 100644 index 000000000000..149f369b321c --- /dev/null +++ b/user_guide_src/source/libraries/pagination/005.php @@ -0,0 +1,6 @@ +paginate(10, 'group1', $page); diff --git a/user_guide_src/source/libraries/pagination/006.php b/user_guide_src/source/libraries/pagination/006.php new file mode 100644 index 000000000000..9d754431ce58 --- /dev/null +++ b/user_guide_src/source/libraries/pagination/006.php @@ -0,0 +1,3 @@ +paginate(10, 'group1', null, $segment); diff --git a/user_guide_src/source/libraries/pagination/007.php b/user_guide_src/source/libraries/pagination/007.php new file mode 100644 index 000000000000..be726a996116 --- /dev/null +++ b/user_guide_src/source/libraries/pagination/007.php @@ -0,0 +1,5 @@ +setPath('path/for/my-group', 'my-group'); // Additionally you could define path for every group. +$pager->makeLinks($page, $perPage, $total, 'template_name', $segment, 'my-group'); diff --git a/user_guide_src/source/libraries/pagination/008.php b/user_guide_src/source/libraries/pagination/008.php new file mode 100644 index 000000000000..0b8219ff43e3 --- /dev/null +++ b/user_guide_src/source/libraries/pagination/008.php @@ -0,0 +1,4 @@ +links(); +// Page 3 link: https://domain.tld?search=foo&order=asc&hello=i+am+here&page=3 diff --git a/user_guide_src/source/libraries/pagination/009.php b/user_guide_src/source/libraries/pagination/009.php new file mode 100644 index 000000000000..6f309ca10552 --- /dev/null +++ b/user_guide_src/source/libraries/pagination/009.php @@ -0,0 +1,4 @@ +only(['search', 'order'])->links(); +// Page 3 link: https://domain.tld?search=foo&order=asc&page=3 diff --git a/user_guide_src/source/libraries/pagination/010.php b/user_guide_src/source/libraries/pagination/010.php new file mode 100644 index 000000000000..95d27f8e4e3c --- /dev/null +++ b/user_guide_src/source/libraries/pagination/010.php @@ -0,0 +1,6 @@ + 'CodeIgniter\Pager\Views\default_full', + 'default_simple' => 'CodeIgniter\Pager\Views\default_simple', +]; diff --git a/user_guide_src/source/libraries/pagination/011.php b/user_guide_src/source/libraries/pagination/011.php new file mode 100644 index 000000000000..86c5e0bcd8b5 --- /dev/null +++ b/user_guide_src/source/libraries/pagination/011.php @@ -0,0 +1,3 @@ + 'App\Views\Pagers\foundation_full', diff --git a/user_guide_src/source/libraries/pagination/012.php b/user_guide_src/source/libraries/pagination/012.php new file mode 100644 index 000000000000..841118b57ae1 --- /dev/null +++ b/user_guide_src/source/libraries/pagination/012.php @@ -0,0 +1,3 @@ + 'Pagers/foundation_full', diff --git a/user_guide_src/source/libraries/pagination/013.php b/user_guide_src/source/libraries/pagination/013.php new file mode 100644 index 000000000000..fa59edbacf9b --- /dev/null +++ b/user_guide_src/source/libraries/pagination/013.php @@ -0,0 +1,7 @@ + 'CodeIgniter\Pager\Views\default_full', + 'default_simple' => 'CodeIgniter\Pager\Views\default_simple', + 'front_full' => 'App\Views\Pagers\foundation_full', +]; diff --git a/user_guide_src/source/libraries/pagination/014.php b/user_guide_src/source/libraries/pagination/014.php new file mode 100644 index 000000000000..00bdee764c7f --- /dev/null +++ b/user_guide_src/source/libraries/pagination/014.php @@ -0,0 +1,39 @@ +setSurroundCount(2) ?> + + diff --git a/user_guide_src/source/libraries/pagination/015.php b/user_guide_src/source/libraries/pagination/015.php new file mode 100644 index 000000000000..43a8f2624d64 --- /dev/null +++ b/user_guide_src/source/libraries/pagination/015.php @@ -0,0 +1,7 @@ + false, + 'uri' => 'https://example.com/foo?page=2', + 'title' => 1, +]; diff --git a/user_guide_src/source/libraries/pagination/016.php b/user_guide_src/source/libraries/pagination/016.php new file mode 100644 index 000000000000..e827bd15a457 --- /dev/null +++ b/user_guide_src/source/libraries/pagination/016.php @@ -0,0 +1,37 @@ + diff --git a/user_guide_src/source/libraries/publisher.rst b/user_guide_src/source/libraries/publisher.rst index 895d74bee7b3..3657a124317c 100644 --- a/user_guide_src/source/libraries/publisher.rst +++ b/user_guide_src/source/libraries/publisher.rst @@ -13,9 +13,10 @@ Loading the Library ******************* Because Publisher instances are specific to their source and destination this library is not available -through ``Services`` but should be instantiated or extended directly. E.g.:: +through ``Services`` but should be instantiated or extended directly. E.g.: - $publisher = new \CodeIgniter\Publisher\Publisher(); +.. literalinclude:: publisher/001.php + :lines: 2- ***************** Concept and Usage @@ -36,43 +37,23 @@ the class and leveraging its discovery with ``spark publish``. On Demand ========= -Access ``Publisher`` directly by instantiating a new instance of the class:: +Access ``Publisher`` directly by instantiating a new instance of the class: - $publisher = new \CodeIgniter\Publisher\Publisher(); +.. literalinclude:: publisher/001.php + :lines: 2- By default the source and destination will be set to ``ROOTPATH`` and ``FCPATH`` respectively, giving ``Publisher`` easy access to take any file from your project and make it web-accessible. Alternatively you may pass a new source -or source and destination into the constructor:: +or source and destination into the constructor: - use CodeIgniter\Publisher\Publisher; - - $vendorPublisher = new Publisher(ROOTPATH . 'vendor'); - $filterPublisher = new Publisher('/path/to/module/Filters', APPPATH . 'Filters'); - - // Once the source and destination are set you may start adding relative input files - $frameworkPublisher = new Publisher(ROOTPATH . 'vendor/codeigniter4/codeigniter4'); - - // All "path" commands are relative to $source - $frameworkPublisher->addPath('app/Config/Cookie.php'); - - // You may also add from outside the source, but the files will not be merged into subdirectories - $frameworkPublisher->addFiles([ - '/opt/mail/susan', - '/opt/mail/ubuntu', - ]); - $frameworkPublisher->addDirectory(SUPPORTPATH . 'Images'); +.. literalinclude:: publisher/003.php + :lines: 2- Once all the files are staged use one of the output commands (**copy()** or **merge()**) to process the staged files -to their destination(s):: - - // Place all files into $destination - $frameworkPublisher->copy(); +to their destination(s): - // Place all files into $destination, overwriting existing files - $frameworkPublisher->copy(true); - - // Place files into their relative $destination directories, overwriting and saving the boolean result - $result = $frameworkPublisher->merge(true); +.. literalinclude:: publisher/004.php + :lines: 2- See the :ref:`reference` for a full description of available methods. @@ -80,24 +61,16 @@ Automation and Discovery ======================== You may have regular publication tasks embedded as part of your application deployment or upkeep. ``Publisher`` leverages -the powerful ``Autoloader`` to locate any child classes primed for publication:: - - use CodeIgniter\CLI\CLI; - use CodeIgniter\Publisher\Publisher; - - foreach (Publisher::discover() as $publisher) - { - $result = $publisher->publish(); +the powerful ``Autoloader`` to locate any child classes primed for publication: - if ($result === false) { - CLI::error(get_class($publisher) . ' failed to publish!', 'red'); - } - } +.. literalinclude:: publisher/005.php + :lines: 2- By default ``discover()`` will search for the "Publishers" directory across all namespaces, but you may specify a -different directory and it will return any child classes found:: +different directory and it will return any child classes found: - $memePublishers = Publisher::discover('CatGIFs'); +.. literalinclude:: publisher/006.php + :lines: 2- Most of the time you will not need to handle your own discovery, just use the provided "publish" command:: @@ -131,92 +104,25 @@ File Sync Example You want to display a "photo of the day" image on your homepage. You have a feed for daily photos but you need to get the actual file into a browsable location in your project at **public/images/daily_photo.jpg**. -You can set up :doc:`Custom Command ` to run daily that will handle this for you:: - - ` to run daily that will handle this for you: - use CodeIgniter\CLI\BaseCommand; - use CodeIgniter\Publisher\Publisher; - use Throwable; - - class DailyPhoto extends BaseCommand - { - protected $group = 'Publication'; - protected $name = 'publish:daily'; - protected $description = 'Publishes the latest daily photo to the homepage.'; - - public function run(array $params) - { - $publisher = new Publisher('/path/to/photos/', FCPATH . 'assets/images'); - - try { - $publisher->addPath('daily_photo.jpg')->copy(true); // `true` to enable overwrites - } catch (Throwable $e) { - $this->showError($e); - } - } - } +.. literalinclude:: publisher/007.php Now running ``spark publish:daily`` will keep your homepage's image up-to-date. What if the photo is coming from an external API? You can use ``addUri()`` in place of ``addPath()`` to download the remote -resource and publish it out instead:: +resource and publish it out instead: - $publisher->addUri('https://example.com/feeds/daily_photo.jpg')->copy(true); +.. literalinclude:: publisher/008.php + :lines: 2- Asset Dependencies Example ========================== You want to integrate the frontend library "Bootstrap" into your project, but the frequent updates makes it a hassle to keep up with. You can create a publication definition in your project to sync frontend assets by extending -``Publisher`` in your project. So **app/Publishers/BootstrapPublisher.php** might look like this:: - - addPath('dist') - - // Indicate we only want the minimized versions - ->retainPattern('*.min.*') - - // Merge-and-replace to retain the original directory structure - ->merge(true); - } - } +``Publisher`` in your project. So **app/Publishers/BootstrapPublisher.php** might look like this: + +.. literalinclude:: publisher/009.php Now add the dependency via Composer and call ``spark publish`` to run the publication:: @@ -254,50 +160,9 @@ Module Deployment Example You want to allow developers using your popular authentication module the ability to expand on the default behavior of your Migration, Controller, and Model. You can create your own module "publish" command to inject these components -into an application for use:: - - getNamespace('Math\\Auth'); - - $publisher = new Publisher($source, APPATH); - - try { - // Add only the desired components - $publisher->addPaths([ - 'Controllers', - 'Database/Migrations', - 'Models', - ])->merge(false); // Be careful not to overwrite anything - } catch (Throwable $e) { - $this->showError($e); - return; - } - - // If publication succeeded then update namespaces - foreach ($publisher->getPublished() as $file) { - // Replace the namespace - $contents = file_get_contents($file); - $contents = str_replace('namespace Math\\Auth', 'namespace ' . APP_NAMESPACE, $contents); - file_put_contents($file, $contents); - } - } - } +into an application for use: + +.. literalinclude:: publisher/010.php Now when your module users run ``php spark auth:publish`` they will have the following added to their project:: @@ -370,16 +235,10 @@ Copies all files into the ``$destination``. This does not recreate the directory from the current list will end up in the same destination directory. Using ``$replace`` will cause files to overwrite when there is already an existing file. Returns success or failure, use ``getPublished()`` and ``getErrors()`` to troubleshoot failures. -Be mindful of duplicate basename collisions, for example:: - - $publisher = new Publisher('/home/source', '/home/destination'); - $publisher->addPaths([ - 'pencil/lead.png', - 'metal/lead.png', - ]); +Be mindful of duplicate basename collisions, for example: - // This is bad! Only one file will remain at /home/destination/lead.png - $publisher->copy(true); +.. literalinclude:: publisher/011.php + :lines: 2- **merge(bool $replace = true): bool** @@ -390,13 +249,7 @@ to overwrite when there is already an existing file; since directories are merge affect other files in the destination. Returns success or failure, use ``getPublished()`` and ``getErrors()`` to troubleshoot failures. -Example:: - - $publisher = new Publisher('/home/source', '/home/destination'); - $publisher->addPaths([ - 'pencil/lead.png', - 'metal/lead.png', - ]); +Example: - // Results in "/home/destination/pencil/lead.png" and "/home/destination/metal/lead.png" - $publisher->merge(); +.. literalinclude:: publisher/012.php + :lines: 2- diff --git a/user_guide_src/source/libraries/publisher/001.php b/user_guide_src/source/libraries/publisher/001.php new file mode 100644 index 000000000000..6312e0d034f4 --- /dev/null +++ b/user_guide_src/source/libraries/publisher/001.php @@ -0,0 +1,3 @@ +addPath('app/Config/Cookie.php'); + +// You may also add from outside the source, but the files will not be merged into subdirectories +$frameworkPublisher->addFiles([ + '/opt/mail/susan', + '/opt/mail/ubuntu', +]); +$frameworkPublisher->addDirectory(SUPPORTPATH . 'Images'); diff --git a/user_guide_src/source/libraries/publisher/004.php b/user_guide_src/source/libraries/publisher/004.php new file mode 100644 index 000000000000..f516a8cab4aa --- /dev/null +++ b/user_guide_src/source/libraries/publisher/004.php @@ -0,0 +1,10 @@ +copy(); + +// Place all files into $destination, overwriting existing files +$frameworkPublisher->copy(true); + +// Place files into their relative $destination directories, overwriting and saving the boolean result +$result = $frameworkPublisher->merge(true); diff --git a/user_guide_src/source/libraries/publisher/005.php b/user_guide_src/source/libraries/publisher/005.php new file mode 100644 index 000000000000..5d598c3f7d1c --- /dev/null +++ b/user_guide_src/source/libraries/publisher/005.php @@ -0,0 +1,13 @@ +publish(); + + if ($result === false) { + CLI::error(get_class($publisher) . ' failed to publish!', 'red'); + } +} diff --git a/user_guide_src/source/libraries/publisher/006.php b/user_guide_src/source/libraries/publisher/006.php new file mode 100644 index 000000000000..9ec20cc403e2 --- /dev/null +++ b/user_guide_src/source/libraries/publisher/006.php @@ -0,0 +1,3 @@ +addPath('daily_photo.jpg')->copy(true); // `true` to enable overwrites + } catch (Throwable $e) { + $this->showError($e); + } + } +} diff --git a/user_guide_src/source/libraries/publisher/008.php b/user_guide_src/source/libraries/publisher/008.php new file mode 100644 index 000000000000..23467e5b28bf --- /dev/null +++ b/user_guide_src/source/libraries/publisher/008.php @@ -0,0 +1,3 @@ +addUri('https://example.com/feeds/daily_photo.jpg')->copy(true); diff --git a/user_guide_src/source/libraries/publisher/009.php b/user_guide_src/source/libraries/publisher/009.php new file mode 100644 index 000000000000..4756956740bd --- /dev/null +++ b/user_guide_src/source/libraries/publisher/009.php @@ -0,0 +1,45 @@ +addPath('dist') + + // Indicate we only want the minimized versions + ->retainPattern('*.min.*') + + // Merge-and-replace to retain the original directory structure + ->merge(true); + } +} diff --git a/user_guide_src/source/libraries/publisher/010.php b/user_guide_src/source/libraries/publisher/010.php new file mode 100644 index 000000000000..3ea9c40e24b6 --- /dev/null +++ b/user_guide_src/source/libraries/publisher/010.php @@ -0,0 +1,42 @@ +getNamespace('Math\\Auth'); + + $publisher = new Publisher($source, APPATH); + + try { + // Add only the desired components + $publisher->addPaths([ + 'Controllers', + 'Database/Migrations', + 'Models', + ])->merge(false); // Be careful not to overwrite anything + } catch (Throwable $e) { + $this->showError($e); + return; + } + + // If publication succeeded then update namespaces + foreach ($publisher->getPublished() as $file) { + // Replace the namespace + $contents = file_get_contents($file); + $contents = str_replace('namespace Math\\Auth', 'namespace ' . APP_NAMESPACE, $contents); + file_put_contents($file, $contents); + } + } +} diff --git a/user_guide_src/source/libraries/publisher/011.php b/user_guide_src/source/libraries/publisher/011.php new file mode 100644 index 000000000000..b48e43282de1 --- /dev/null +++ b/user_guide_src/source/libraries/publisher/011.php @@ -0,0 +1,10 @@ +addPaths([ + 'pencil/lead.png', + 'metal/lead.png', +]); + +// This is bad! Only one file will remain at /home/destination/lead.png +$publisher->copy(true); diff --git a/user_guide_src/source/libraries/publisher/012.php b/user_guide_src/source/libraries/publisher/012.php new file mode 100644 index 000000000000..32ec11f13b33 --- /dev/null +++ b/user_guide_src/source/libraries/publisher/012.php @@ -0,0 +1,10 @@ +addPaths([ + 'pencil/lead.png', + 'metal/lead.png', +]); + +// Results in "/home/destination/pencil/lead.png" and "/home/destination/metal/lead.png" +$publisher->merge(); diff --git a/user_guide_src/source/libraries/security.rst b/user_guide_src/source/libraries/security.rst index 08c23d4ff337..d3a2b6cc0785 100644 --- a/user_guide_src/source/libraries/security.rst +++ b/user_guide_src/source/libraries/security.rst @@ -15,9 +15,10 @@ Loading the Library If your only interest in loading the library is to handle CSRF protection, then you will never need to load it, as it runs as a filter and has no manual interaction. -If you find a case where you do need direct access though, you may load it through the Services file:: +If you find a case where you do need direct access though, you may load it through the Services file: - $security = \Config\Services::security(); +.. literalinclude:: security/001.php + :lines: 2- .. _cross-site-request-forgery: @@ -44,9 +45,10 @@ You can also use Session based CSRF Protection. It is `Synchronizer Token Pattern `_. You can set to use the Session based CSRF protection by editing the following config parameter value in -**app/Config/Security.php**:: +**app/Config/Security.php**: - public $csrfProtection = 'session'; +.. literalinclude:: security/002.php + :lines: 2- Token Randomization ------------------- @@ -58,9 +60,10 @@ If you enable it, a random mask is added to the token and used to scramble it. .. _`BREACH`: https://en.wikipedia.org/wiki/BREACH You can enable it by editing the following config parameter value in -**app/Config/Security.php**:: +**app/Config/Security.php**: - public $tokenRandomize = true; +.. literalinclude:: security/003.php + :lines: 2- Token Regeneration ------------------ @@ -71,9 +74,10 @@ regeneration of tokens provides stricter security, but may result in usability concerns as other tokens become invalid (back/forward navigation, multiple tabs/windows, asynchronous actions, etc). You may alter this behavior by editing the following config parameter value in -**app/Config/Security.php**:: +**app/Config/Security.php**: - public $regenerate = true; +.. literalinclude:: security/004.php + :lines: 2- Redirection on Failure ---------------------- @@ -85,9 +89,10 @@ setting an ``error`` flash message that you can display to the end user with the This provides a nicer experience than simply crashing. This can be turned off by editing the following config parameter value in -**app/Config/Security.php**:: +**app/Config/Security.php**: - public $redirect = false; +.. literalinclude:: security/005.php + :lines: 2- Even when the redirect value is ``true``, AJAX calls will not redirect, but will throw an error. @@ -95,39 +100,27 @@ Enable CSRF Protection ====================== You can enable CSRF protection by altering your **app/Config/Filters.php** -and enabling the `csrf` filter globally:: +and enabling the `csrf` filter globally: - public $globals = [ - 'before' => [ - // 'honeypot', - 'csrf', - ], - ]; +.. literalinclude:: security/006.php + :lines: 2- Select URIs can be whitelisted from CSRF protection (for example API endpoints expecting externally POSTed content). You can add these URIs -by adding them as exceptions in the filter:: +by adding them as exceptions in the filter: - public $globals = [ - 'before' => [ - 'csrf' => ['except' => ['api/record/save']], - ], - ]; +.. literalinclude:: security/007.php + :lines: 2- -Regular expressions are also supported (case-insensitive):: +Regular expressions are also supported (case-insensitive): - public $globals = [ - 'before' => [ - 'csrf' => ['except' => ['api/record/[0-9]+']], - ], - ]; +.. literalinclude:: security/008.php + :lines: 2- -It is also possible to enable the CSRF filter only for specific methods:: +It is also possible to enable the CSRF filter only for specific methods: - public $methods = [ - 'get' => ['csrf'], - 'post' => ['csrf'], - ]; +.. literalinclude:: security/009.php + :lines: 2- .. Warning:: If you use ``$methods`` filters, you should :ref:`disable auto-routing ` because auto-routing permits any HTTP method to access a controller. @@ -188,6 +181,6 @@ particularly useful for files that were supplied via user input. The first param 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, ``$relativePath`` to ``true``. -:: - $path = $security->sanitizeFilename($request->getVar('filepath')); +.. literalinclude:: security/010.php + :lines: 2- diff --git a/user_guide_src/source/libraries/security/001.php b/user_guide_src/source/libraries/security/001.php new file mode 100644 index 000000000000..fe504ef35a8e --- /dev/null +++ b/user_guide_src/source/libraries/security/001.php @@ -0,0 +1,3 @@ + [ + // 'honeypot', + 'csrf', + ], +]; diff --git a/user_guide_src/source/libraries/security/007.php b/user_guide_src/source/libraries/security/007.php new file mode 100644 index 000000000000..d647d1b8c120 --- /dev/null +++ b/user_guide_src/source/libraries/security/007.php @@ -0,0 +1,7 @@ + [ + 'csrf' => ['except' => ['api/record/save']], + ], +]; diff --git a/user_guide_src/source/libraries/security/008.php b/user_guide_src/source/libraries/security/008.php new file mode 100644 index 000000000000..c78d18937b08 --- /dev/null +++ b/user_guide_src/source/libraries/security/008.php @@ -0,0 +1,7 @@ + [ + 'csrf' => ['except' => ['api/record/[0-9]+']], + ], +]; diff --git a/user_guide_src/source/libraries/security/009.php b/user_guide_src/source/libraries/security/009.php new file mode 100644 index 000000000000..e2b03e79ba25 --- /dev/null +++ b/user_guide_src/source/libraries/security/009.php @@ -0,0 +1,6 @@ + ['csrf'], + 'post' => ['csrf'], +]; diff --git a/user_guide_src/source/libraries/security/010.php b/user_guide_src/source/libraries/security/010.php new file mode 100644 index 000000000000..228df8107fda --- /dev/null +++ b/user_guide_src/source/libraries/security/010.php @@ -0,0 +1,3 @@ +sanitizeFilename($request->getVar('filepath')); diff --git a/user_guide_src/source/libraries/sessions.rst b/user_guide_src/source/libraries/sessions.rst index cb6e78c25330..889ad559d8bb 100644 --- a/user_guide_src/source/libraries/sessions.rst +++ b/user_guide_src/source/libraries/sessions.rst @@ -21,24 +21,26 @@ Initializing a Session Sessions will typically run globally with each page load, so the Session class should be magically initialized. -To access and initialize the session:: +To access and initialize the session: - $session = \Config\Services::session($config); +.. literalinclude:: sessions/001.php + :lines: 2- The ``$config`` parameter is optional - your application configuration. If not provided, the services register will instantiate your default one. -Once loaded, the Sessions library object will be available using:: +Once loaded, the Sessions library object will be available using: - $session +.. literalinclude:: sessions/002.php + :lines: 2- Alternatively, you can use the helper function that will use the default configuration options. This version is a little friendlier to read, but does not take any configuration options. -:: - $session = session(); +.. literalinclude:: sessions/003.php + :lines: 2- How do Sessions work? ===================== @@ -89,9 +91,9 @@ Locking is not the issue, it is a solution. Your issue is that you still have the session open, while you've already processed it and therefore no longer need it. So, what you need is to close the session for the current request after you no longer need it. -:: - session_write_close(); +.. literalinclude:: sessions/004.php + :lines: 2- What is Session Data? ===================== @@ -115,47 +117,41 @@ Retrieving Session Data ======================= Any piece of information from the session array is available through the -``$_SESSION`` superglobal:: +``$_SESSION`` superglobal: - $_SESSION['item'] +.. literalinclude:: sessions/005.php + :lines: 2- -Or through the conventional accessor method:: +Or through the conventional accessor method: - $session->get('item'); +.. literalinclude:: sessions/006.php + :lines: 2- -Or through the magic getter:: +Or through the magic getter: - $session->item +.. literalinclude:: sessions/007.php + :lines: 2- -Or even through the session helper method:: +Or even through the session helper method: - session('item'); +.. literalinclude:: sessions/008.php + :lines: 2- Where ``item`` is the array key corresponding to the item you wish to fetch. For example, to assign a previously stored 'name' item to the ``$name`` -variable, you will do this:: - - $name = $_SESSION['name']; - - // or: - - $name = $session->name +variable, you will do this: - // or: - - $name = $session->get('name'); +.. literalinclude:: sessions/009.php + :lines: 2- .. note:: The ``get()`` method 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 (magic getter only works for single property values):: - - $_SESSION +omit the item key (magic getter only works for single property values): - // or: - - $session->get(); +.. literalinclude:: sessions/010.php + :lines: 2- Adding Session Data =================== @@ -170,71 +166,64 @@ variable. Or as a property of ``$session``. The former userdata method is deprecated, but you can pass an array containing your new session data to the -``set()`` method:: +``set()`` method: - $session->set($array); +.. literalinclude:: sessions/011.php + :lines: 2- Where ``$array`` is an associative array containing your new data. Here's -an example:: - - $newdata = [ - 'username' => 'johndoe', - 'email' => 'johndoe@some-site.com', - 'logged_in' => true, - ]; +an example: - $session->set($newdata); +.. literalinclude:: sessions/012.php + :lines: 2- If you want to add session data one value at a time, ``set()`` also -supports this syntax:: +supports this syntax: - $session->set('some_name', 'some_value'); +.. literalinclude:: sessions/013.php + :lines: 2- If you want to verify that a session value exists, simply check with -``isset()``:: +``isset()``: - // returns false if the 'some_name' item doesn't exist or is null, - // true otherwise: - isset($_SESSION['some_name']) +.. literalinclude:: sessions/014.php + :lines: 2- -Or you can call ``has()``:: +Or you can call ``has()``: - $session->has('some_name'); +.. literalinclude:: sessions/015.php + :lines: 2- Pushing new value to session data ================================= The push method is used to push a new value onto a session value that is an array. -For instance, if the 'hobbies' key contains an array of hobbies, you can add a new value onto the array like so:: +For instance, if the 'hobbies' key contains an array of hobbies, you can add a new value onto the array like so: -$session->push('hobbies', ['sport'=>'tennis']); +.. literalinclude:: sessions/016.php + :lines: 2- Removing Session Data ===================== Just as with any other variable, unsetting a value in ``$_SESSION`` can be -done through ``unset()``:: +done through ``unset()``: - unset($_SESSION['some_name']); - - // or multiple values: - - unset( - $_SESSION['some_name'], - $_SESSION['another_name'] - ); +.. literalinclude:: sessions/017.php + :lines: 2- Also, just as ``set()`` can be used to add information to a session, ``remove()`` can be used to remove it, by passing the session key. For example, if you wanted to remove 'some_name' from your -session data array:: +session data array: - $session->remove('some_name'); +.. literalinclude:: sessions/018.php + :lines: 2- -This method also accepts an array of item keys to unset:: +This method also accepts an array of item keys to unset: - $array_items = ['username', 'email']; - $session->remove($array_items); +.. literalinclude:: sessions/019.php + :lines: 2- Flashdata ========= @@ -248,44 +237,50 @@ status messages (for example: "Record 2 deleted"). It should be noted that flashdata variables are regular session variables, managed inside the CodeIgniter session handler. -To mark an existing item as "flashdata":: +To mark an existing item as "flashdata": - $session->markAsFlashdata('item'); +.. literalinclude:: sessions/020.php + :lines: 2- If you want to mark multiple items as flashdata, simply pass the keys as an -array:: +array: - $session->markAsFlashdata(['item', 'item2']); +.. literalinclude:: sessions/021.php + :lines: 2- -To add flashdata:: +To add flashdata: - $_SESSION['item'] = 'value'; - $session->markAsFlashdata('item'); +.. literalinclude:: sessions/022.php + :lines: 2- -Or alternatively, using the ``setFlashdata()`` method:: +Or alternatively, using the ``setFlashdata()`` method: - $session->setFlashdata('item', 'value'); +.. literalinclude:: sessions/023.php + :lines: 2- You can also pass an array to ``setFlashdata()``, in the same manner as ``set()``. Reading flashdata variables is the same as reading regular session data -through ``$_SESSION``:: +through ``$_SESSION``: - $_SESSION['item'] +.. literalinclude:: sessions/005.php + :lines: 2- .. important:: The ``get()`` method WILL return flashdata items when retrieving a single item by key. It will not return flashdata when grabbing all userdata from the session, however. However, if you want to be sure that you're reading "flashdata" (and not -any other kind), you can also use the ``getFlashdata()`` method:: +any other kind), you can also use the ``getFlashdata()`` method: - $session->getFlashdata('item'); +.. literalinclude:: sessions/025.php + :lines: 2- -Or to get an array with all flashdata, simply omit the key parameter:: +Or to get an array with all flashdata, simply omit the key parameter: - $session->getFlashdata(); +.. literalinclude:: sessions/026.php + :lines: 2- .. note:: The ``getFlashdata()`` method returns null if the item cannot be found. @@ -294,10 +289,8 @@ If you find that you need to preserve a flashdata variable through an additional request, you can do so using the ``keepFlashdata()`` method. You can either pass a single item or an array of flashdata items to keep. -:: - - $session->keepFlashdata('item'); - $session->keepFlashdata(['item1', 'item2', 'item3']); +.. literalinclude:: sessions/027.php + :lines: 2- Tempdata ======== @@ -310,73 +303,72 @@ Similarly to flashdata, tempdata variables are managed internally by the CodeIgniter session handler. To mark an existing item as "tempdata", simply pass its key and expiry time -(in seconds!) to the ``markAsTempdata()`` method:: +(in seconds!) to the ``markAsTempdata()`` method: - // 'item' will be erased after 300 seconds - $session->markAsTempdata('item', 300); +.. literalinclude:: sessions/028.php + :lines: 2- You can mark multiple items as tempdata in two ways, depending on whether -you want them all to have the same expiry time or not:: +you want them all to have the same expiry time or not: - // Both 'item' and 'item2' will expire after 300 seconds - $session->markAsTempdata(['item', 'item2'], 300); +.. literalinclude:: sessions/029.php + :lines: 2- - // 'item' will be erased after 300 seconds, while 'item2' - // will do so after only 240 seconds - $session->markAsTempdata([ - 'item' => 300, - 'item2' => 240, - ]); +To add tempdata: -To add tempdata:: +.. literalinclude:: sessions/030.php + :lines: 2- - $_SESSION['item'] = 'value'; - $session->markAsTempdata('item', 300); // Expire in 5 minutes +Or alternatively, using the ``setTempdata()`` method: -Or alternatively, using the ``setTempdata()`` method:: +.. literalinclude:: sessions/031.php + :lines: 2- - $session->setTempdata('item', 'value', 300); +You can also pass an array to ``setTempdata()``: -You can also pass an array to ``setTempdata()``:: - - $tempdata = ['newuser' => true, 'message' => 'Thanks for joining!']; - $session->setTempdata($tempdata, null, $expire); +.. literalinclude:: sessions/032.php + :lines: 2- .. note:: If the expiration is omitted or set to 0, the default time-to-live value of 300 seconds (or 5 minutes) will be used. To read a tempdata variable, again you can just access it through the -``$_SESSION`` superglobal array:: +``$_SESSION`` superglobal array: - $_SESSION['item'] +.. literalinclude:: sessions/005.php + :lines: 2- .. important:: The ``get()`` method WILL return tempdata items when retrieving a single item by key. It will not return tempdata when grabbing all userdata from the session, however. Or if you want to be sure that you're reading "tempdata" (and not any -other kind), you can also use the ``getTempdata()`` method:: +other kind), you can also use the ``getTempdata()`` method: - $session->getTempdata('item'); +.. literalinclude:: sessions/034.php + :lines: 2- -And of course, if you want to retrieve all existing tempdata:: +And of course, if you want to retrieve all existing tempdata: - $session->getTempdata(); +.. literalinclude:: sessions/035.php + :lines: 2- .. note:: The ``getTempdata()`` method returns null if the item cannot be found. If you need to remove a tempdata value before it expires, you can directly -unset it from the ``$_SESSION`` array:: +unset it from the ``$_SESSION`` array: - unset($_SESSION['item']); +.. literalinclude:: sessions/036.php + :lines: 2- However, this won't remove the marker that makes this specific item to be tempdata (it will be invalidated on the next HTTP request), so if you intend to reuse that same key in the same request, you'd want to use -``removeTempdata()``:: +``removeTempdata()``: - $session->removeTempdata('item'); +.. literalinclude:: sessions/037.php + :lines: 2- Destroying a Session ==================== @@ -384,13 +376,10 @@ Destroying a Session To clear the current session (for example, during a logout), you may simply use either PHP's `session_destroy() `_ function, or the library's ``destroy()`` method. Both will work in exactly the -same way:: - - session_destroy(); +same way: - // or - - $session->destroy(); +.. literalinclude:: sessions/038.php + :lines: 2- .. note:: This must be the last session-related operation that you do during the same request. All session data (including flashdata and @@ -399,9 +388,10 @@ same way:: You may also use the ``stop()`` method to completely kill the session by removing the old session_id, destroying all data, and destroying -the cookie that contained the session id:: +the cookie that contained the session id: - $session->stop(); +.. literalinclude:: sessions/039.php + :lines: 2- Accessing session metadata ========================== @@ -463,7 +453,6 @@ Preference Default Opti (often the default value of ``1440``). This needs to be changed in ``php.ini`` or via ``ini_set()`` as needed. - In addition to the values above, the cookie and native drivers apply the following configuration values shared by the :doc:`IncomingRequest ` and :doc:`Security ` classes: @@ -575,10 +564,10 @@ In order to use the 'DatabaseHandler' session driver, you must also create this table that we already mentioned and then set it as your ``$sessionSavePath`` value. For example, if you would like to use 'ci_sessions' as your table name, -you would do this:: +you would do this: - public $sessionDriver = 'CodeIgniter\Session\Handlers\DatabaseHandler'; - public $sessionSavePath = 'ci_sessions'; +.. literalinclude:: sessions/040.php + :lines: 2- And then of course, create the database table ... @@ -616,9 +605,10 @@ setting**. The examples below work both on MySQL and PostgreSQL:: ALTER TABLE ci_sessions DROP PRIMARY KEY; You can choose the Database group to use by adding a new line to the -**app/Config/App.php** file with the name of the group to use:: +**app/Config/App.php** file with the name of the group to use: - public $sessionDBGroup = 'groupName'; +.. literalinclude:: sessions/041.php + :lines: 2- If you'd rather not do all of this by hand, you can use the ``session:migration`` command from the cli to generate a migration file for you:: @@ -669,10 +659,10 @@ link you to it: the link above. For the most common case however, a simple ``host:port`` pair should be -sufficient:: +sufficient: - public $sessionDiver = 'CodeIgniter\Session\Handlers\RedisHandler'; - public $sessionSavePath = 'tcp://localhost:6379'; +.. literalinclude:: sessions/042.php + :lines: 2- MemcachedHandler Driver ======================= @@ -697,10 +687,10 @@ expire earlier than that time). This happens very rarely, but should be considered as it may result in loss of sessions. The ``$sessionSavePath`` format is fairly straightforward here, -being just a ``host:port`` pair:: +being just a ``host:port`` pair: - public $sessionDriver = 'CodeIgniter\Session\Handlers\MemcachedHandler'; - public $sessionSavePath = 'localhost:11211'; +.. literalinclude:: sessions/043.php + :lines: 2- Bonus Tip --------- @@ -710,8 +700,7 @@ third colon-separated (``:weight``) value is also supported, but we have to note that we haven't tested if that is reliable. If you want to experiment with this feature (on your own risk), simply -separate the multiple server paths with commas:: +separate the multiple server paths with commas: - // localhost will be given higher priority (5) here, - // compared to 192.0.2.1 with a weight of 1. - public $sessionSavePath = 'localhost:11211:5,192.0.2.1:11211:1'; +.. literalinclude:: sessions/044.php + :lines: 2- diff --git a/user_guide_src/source/libraries/sessions/001.php b/user_guide_src/source/libraries/sessions/001.php new file mode 100644 index 000000000000..b1fa9aac3530 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/001.php @@ -0,0 +1,3 @@ +get('item'); diff --git a/user_guide_src/source/libraries/sessions/007.php b/user_guide_src/source/libraries/sessions/007.php new file mode 100644 index 000000000000..d3d4aaf2aaf8 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/007.php @@ -0,0 +1,3 @@ +item diff --git a/user_guide_src/source/libraries/sessions/008.php b/user_guide_src/source/libraries/sessions/008.php new file mode 100644 index 000000000000..ebe59d510994 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/008.php @@ -0,0 +1,3 @@ +name + +// or: + +$name = $session->get('name'); diff --git a/user_guide_src/source/libraries/sessions/010.php b/user_guide_src/source/libraries/sessions/010.php new file mode 100644 index 000000000000..e723f1b13ddd --- /dev/null +++ b/user_guide_src/source/libraries/sessions/010.php @@ -0,0 +1,7 @@ +get(); diff --git a/user_guide_src/source/libraries/sessions/011.php b/user_guide_src/source/libraries/sessions/011.php new file mode 100644 index 000000000000..b8b949797d22 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/011.php @@ -0,0 +1,3 @@ +set($array); diff --git a/user_guide_src/source/libraries/sessions/012.php b/user_guide_src/source/libraries/sessions/012.php new file mode 100644 index 000000000000..01bbbe1670b0 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/012.php @@ -0,0 +1,9 @@ + 'johndoe', + 'email' => 'johndoe@some-site.com', + 'logged_in' => true, +]; + +$session->set($newdata); diff --git a/user_guide_src/source/libraries/sessions/013.php b/user_guide_src/source/libraries/sessions/013.php new file mode 100644 index 000000000000..0d9c4699281a --- /dev/null +++ b/user_guide_src/source/libraries/sessions/013.php @@ -0,0 +1,3 @@ +set('some_name', 'some_value'); diff --git a/user_guide_src/source/libraries/sessions/014.php b/user_guide_src/source/libraries/sessions/014.php new file mode 100644 index 000000000000..4cab41e404aa --- /dev/null +++ b/user_guide_src/source/libraries/sessions/014.php @@ -0,0 +1,5 @@ +has('some_name'); diff --git a/user_guide_src/source/libraries/sessions/016.php b/user_guide_src/source/libraries/sessions/016.php new file mode 100644 index 000000000000..ef48af6552cc --- /dev/null +++ b/user_guide_src/source/libraries/sessions/016.php @@ -0,0 +1,3 @@ +push('hobbies', ['sport'=>'tennis']); diff --git a/user_guide_src/source/libraries/sessions/017.php b/user_guide_src/source/libraries/sessions/017.php new file mode 100644 index 000000000000..66a5f8662b39 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/017.php @@ -0,0 +1,10 @@ +remove('some_name'); diff --git a/user_guide_src/source/libraries/sessions/019.php b/user_guide_src/source/libraries/sessions/019.php new file mode 100644 index 000000000000..2ebd4f8a4e5f --- /dev/null +++ b/user_guide_src/source/libraries/sessions/019.php @@ -0,0 +1,4 @@ +remove($array_items); diff --git a/user_guide_src/source/libraries/sessions/020.php b/user_guide_src/source/libraries/sessions/020.php new file mode 100644 index 000000000000..471c5c5fef96 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/020.php @@ -0,0 +1,3 @@ +markAsFlashdata('item'); diff --git a/user_guide_src/source/libraries/sessions/021.php b/user_guide_src/source/libraries/sessions/021.php new file mode 100644 index 000000000000..4be42e7f3a62 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/021.php @@ -0,0 +1,3 @@ +markAsFlashdata(['item', 'item2']); diff --git a/user_guide_src/source/libraries/sessions/022.php b/user_guide_src/source/libraries/sessions/022.php new file mode 100644 index 000000000000..d87dd8763d34 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/022.php @@ -0,0 +1,4 @@ +markAsFlashdata('item'); diff --git a/user_guide_src/source/libraries/sessions/023.php b/user_guide_src/source/libraries/sessions/023.php new file mode 100644 index 000000000000..f22af522ab61 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/023.php @@ -0,0 +1,3 @@ +setFlashdata('item', 'value'); diff --git a/user_guide_src/source/libraries/sessions/024.php b/user_guide_src/source/libraries/sessions/024.php new file mode 100644 index 000000000000..4f09358d5fc8 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/024.php @@ -0,0 +1,3 @@ +getFlashdata('item'); diff --git a/user_guide_src/source/libraries/sessions/026.php b/user_guide_src/source/libraries/sessions/026.php new file mode 100644 index 000000000000..7c387b5a4fa2 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/026.php @@ -0,0 +1,3 @@ +getFlashdata(); diff --git a/user_guide_src/source/libraries/sessions/027.php b/user_guide_src/source/libraries/sessions/027.php new file mode 100644 index 000000000000..94a299006a5d --- /dev/null +++ b/user_guide_src/source/libraries/sessions/027.php @@ -0,0 +1,4 @@ +keepFlashdata('item'); +$session->keepFlashdata(['item1', 'item2', 'item3']); diff --git a/user_guide_src/source/libraries/sessions/028.php b/user_guide_src/source/libraries/sessions/028.php new file mode 100644 index 000000000000..d2ed461826c0 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/028.php @@ -0,0 +1,4 @@ +markAsTempdata('item', 300); diff --git a/user_guide_src/source/libraries/sessions/029.php b/user_guide_src/source/libraries/sessions/029.php new file mode 100644 index 000000000000..978341190b52 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/029.php @@ -0,0 +1,11 @@ +markAsTempdata(['item', 'item2'], 300); + +// 'item' will be erased after 300 seconds, while 'item2' +// will do so after only 240 seconds +$session->markAsTempdata([ + 'item' => 300, + 'item2' => 240, +]); diff --git a/user_guide_src/source/libraries/sessions/030.php b/user_guide_src/source/libraries/sessions/030.php new file mode 100644 index 000000000000..d4e8941b5d34 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/030.php @@ -0,0 +1,4 @@ +markAsTempdata('item', 300); // Expire in 5 minutes diff --git a/user_guide_src/source/libraries/sessions/031.php b/user_guide_src/source/libraries/sessions/031.php new file mode 100644 index 000000000000..444c045adae9 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/031.php @@ -0,0 +1,3 @@ +setTempdata('item', 'value', 300); diff --git a/user_guide_src/source/libraries/sessions/032.php b/user_guide_src/source/libraries/sessions/032.php new file mode 100644 index 000000000000..f7099d76289a --- /dev/null +++ b/user_guide_src/source/libraries/sessions/032.php @@ -0,0 +1,4 @@ + true, 'message' => 'Thanks for joining!']; +$session->setTempdata($tempdata, null, $expire); diff --git a/user_guide_src/source/libraries/sessions/033.php b/user_guide_src/source/libraries/sessions/033.php new file mode 100644 index 000000000000..4f09358d5fc8 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/033.php @@ -0,0 +1,3 @@ +getTempdata('item'); diff --git a/user_guide_src/source/libraries/sessions/035.php b/user_guide_src/source/libraries/sessions/035.php new file mode 100644 index 000000000000..f44b959eee81 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/035.php @@ -0,0 +1,3 @@ +getTempdata(); diff --git a/user_guide_src/source/libraries/sessions/036.php b/user_guide_src/source/libraries/sessions/036.php new file mode 100644 index 000000000000..f063fa2907f4 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/036.php @@ -0,0 +1,3 @@ +removeTempdata('item'); diff --git a/user_guide_src/source/libraries/sessions/038.php b/user_guide_src/source/libraries/sessions/038.php new file mode 100644 index 000000000000..72c7d5d07602 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/038.php @@ -0,0 +1,7 @@ +destroy(); diff --git a/user_guide_src/source/libraries/sessions/039.php b/user_guide_src/source/libraries/sessions/039.php new file mode 100644 index 000000000000..7b43795e71e4 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/039.php @@ -0,0 +1,3 @@ +stop(); diff --git a/user_guide_src/source/libraries/sessions/040.php b/user_guide_src/source/libraries/sessions/040.php new file mode 100644 index 000000000000..a3724620886d --- /dev/null +++ b/user_guide_src/source/libraries/sessions/040.php @@ -0,0 +1,4 @@ +check($name, 60, MINUTE); +.. literalinclude:: throttler/001.php + :lines: 2- Here we're using one of the :doc:`global constants ` for the time, to make it a little more readable. This says that the bucket allows 60 actions every minute, or 1 action every second. @@ -50,50 +50,9 @@ The Code ======== You could make your own Throttler filter, at **app/Filters/Throttle.php**, -along the lines of:: - - check(md5($request->getIPAddress()), 60, MINUTE) === false) { - return Services::response()->setStatusCode(429); - } - } - - /** - * We don't have anything to do here. - * - * @param array|null $arguments - * - * @return mixed - */ - public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) - { - // ... - } - } +along the lines of: + +.. literalinclude:: throttler/002.php When run, this method first grabs an instance of the throttler. Next, it uses the IP address as the bucket name, and sets things to limit them to one request per second. If the throttler rejects the check, returning false, @@ -107,18 +66,15 @@ Applying the Filter We don't necessarily need to throttle every page on the site. For many web applications, this makes the most sense to apply only to POST requests, though API's might want to limit every request made by a user. In order to apply this to incoming requests, you need to edit **/app/Config/Filters.php** and first add an alias to the -filter:: +filter: - public $aliases = [ - ... - 'throttle' => \App\Filters\Throttle::class, - ]; +.. literalinclude:: throttler/003.php + :lines: 2- -Next, we assign it to all POST requests made on the site:: +Next, we assign it to all POST requests made on the site: - public $methods = [ - 'post' => ['throttle'], - ]; +.. literalinclude:: throttler/004.php + :lines: 2- .. Warning:: If you use ``$methods`` filters, you should :ref:`disable auto-routing ` because auto-routing permits any HTTP method to access a controller. diff --git a/user_guide_src/source/libraries/throttler/001.php b/user_guide_src/source/libraries/throttler/001.php new file mode 100644 index 000000000000..20086d3fc60a --- /dev/null +++ b/user_guide_src/source/libraries/throttler/001.php @@ -0,0 +1,4 @@ +check($name, 60, MINUTE); diff --git a/user_guide_src/source/libraries/throttler/002.php b/user_guide_src/source/libraries/throttler/002.php new file mode 100644 index 000000000000..91c89ca83d97 --- /dev/null +++ b/user_guide_src/source/libraries/throttler/002.php @@ -0,0 +1,42 @@ +check(md5($request->getIPAddress()), 60, MINUTE) === false) { + return Services::response()->setStatusCode(429); + } + } + + /** + * We don't have anything to do here. + * + * @param array|null $arguments + * + * @return mixed + */ + public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) + { + // ... + } +} diff --git a/user_guide_src/source/libraries/throttler/003.php b/user_guide_src/source/libraries/throttler/003.php new file mode 100644 index 000000000000..af756092e30d --- /dev/null +++ b/user_guide_src/source/libraries/throttler/003.php @@ -0,0 +1,6 @@ + \App\Filters\Throttle::class, +]; diff --git a/user_guide_src/source/libraries/throttler/004.php b/user_guide_src/source/libraries/throttler/004.php new file mode 100644 index 000000000000..455874cd5730 --- /dev/null +++ b/user_guide_src/source/libraries/throttler/004.php @@ -0,0 +1,5 @@ + ['throttle'], +]; diff --git a/user_guide_src/source/libraries/time.rst b/user_guide_src/source/libraries/time.rst index 6e55cf87aed3..b8788eee17b7 100644 --- a/user_guide_src/source/libraries/time.rst +++ b/user_guide_src/source/libraries/time.rst @@ -19,21 +19,18 @@ Instantiating There are several ways that a new Time instance can be created. The first is simply to create a new instance like any other class. When you do it this way, you can pass in a string representing the desired time. This can -be any string that PHP's strtotime function can parse:: +be any string that PHP's strtotime function can parse: - use CodeIgniter\I18n\Time; - - $myTime = new Time('+3 week'); - $myTime = new Time('now'); +.. literalinclude:: time/001.php + :lines: 2- You can pass in strings representing the timezone and the locale in the second and parameters, respectively. Timezones can be any supported by PHP's `DateTimeZone `__ class. The locale can be any supported by PHP's `Locale `__ class. If no locale or timezone is provided, the application defaults will be used. -:: - - $myTime = new Time('now', 'America/Chicago', 'en_US'); +.. literalinclude:: time/002.php + :lines: 2- now() ----- @@ -42,106 +39,111 @@ The Time class has several helper methods to instantiate the class. The first of that returns a new instance set to the current time. You can pass in strings representing the timezone and the locale in the second and parameters, respectively. If no locale or timezone is provided, the application defaults will be used. -:: - - $myTime = Time::now('America/Chicago', 'en_US'); +.. literalinclude:: time/003.php + :lines: 2- parse() ------- This helper method is a static version of the default constructor. It takes a string acceptable as DateTime's -constructor as the first parameter, a timezone as the second parameter, and the locale as the third parameter.:: +constructor as the first parameter, a timezone as the second parameter, and the locale as the third parameter.: - $myTime = Time::parse('next Tuesday', 'America/Chicago', 'en_US'); +.. literalinclude:: time/004.php + :lines: 2- today() ------- Returns a new instance with the date set to the current date, and the time set to midnight. It accepts strings -for the timezone and locale in the first and second parameters:: +for the timezone and locale in the first and second parameters: - $myTime = Time::today('America/Chicago', 'en_US'); +.. literalinclude:: time/005.php + :lines: 2- yesterday() ----------- Returns a new instance with the date set to the yesterday's date and the time set to midnight. It accepts strings -for the timezone and locale in the first and second parameters:: +for the timezone and locale in the first and second parameters: - $myTime = Time::yesterday('America/Chicago', 'en_US'); +.. literalinclude:: time/006.php + :lines: 2- tomorrow() ----------- Returns a new instance with the date set to tomorrow's date and the time set to midnight. It accepts strings -for the timezone and locale in the first and second parameters:: +for the timezone and locale in the first and second parameters: - $myTime = Time::tomorrow('America/Chicago', 'en_US'); +.. literalinclude:: time/007.php + :lines: 2- createFromDate() ---------------- Given separate inputs for **year**, **month**, and **day**, will return a new instance. If any of these parameters are not provided, it will use the current value to fill it in. Accepts strings for the timezone and locale in the -fourth and fifth parameters:: +fourth and fifth parameters: - $today = Time::createFromDate(); // Uses current year, month, and day - $anniversary = Time::createFromDate(2018); // Uses current month and day - $date = Time::createFromDate(2018, 3, 15, 'America/Chicago', 'en_US'); +.. literalinclude:: time/008.php + :lines: 2- createFromTime() ---------------- Like ``createFromDate()`` except it is only concerned with the **hours**, **minutes**, and **seconds**. Uses the current day for the date portion of the Time instance. Accepts strings for the timezone and locale in the -fourth and fifth parameters:: +fourth and fifth parameters: - $lunch = Time::createFromTime(11, 30); // 11:30 am today - $dinner = Time::createFromTime(18, 00, 00); // 6:00 pm today - $time = Time::createFromTime($hour, $minutes, $seconds, $timezone, $locale); +.. literalinclude:: time/009.php + :lines: 2- create() -------- A combination of the previous two methods, takes **year**, **month**, **day**, **hour**, **minutes**, and **seconds** as separate parameters. Any value not provided will use the current date and time to determine. Accepts strings for the -timezone and locale in the fourth and fifth parameters:: +timezone and locale in the fourth and fifth parameters: - $time = Time::create($year, $month, $day, $hour, $minutes, $seconds, $timezone, $locale); +.. literalinclude:: time/010.php + :lines: 2- createFromFormat() ------------------ This is a replacement for DateTime's method of the same name. This allows the timezone to be set at the same time, -and returns a ``Time`` instance, instead of DateTime:: +and returns a ``Time`` instance, instead of DateTime: - $time = Time::createFromFormat('j-M-Y', '15-Feb-2009', 'America/Chicago'); +.. literalinclude:: time/011.php + :lines: 2- createFromTimestamp() --------------------- -This method takes a UNIX timestamp and, optionally, the timezone and locale, to create a new Time instance:: +This method takes a UNIX timestamp and, optionally, the timezone and locale, to create a new Time instance: - $time = Time::createFromTimestamp(1501821586, 'America/Chicago', 'en_US'); +.. literalinclude:: time/012.php + :lines: 2- createFromInstance() -------------------- When working with other libraries that provide a DateTime instance, you can use this method to convert that to a Time instance, optionally setting the locale. The timezone will be automatically determined from the DateTime -instance passed in:: +instance passed in: - $dt = new DateTime('now'); - $time = Time::createFromInstance($dt, 'en_US'); +.. literalinclude:: time/013.php + :lines: 2- toDateTime() ------------ While not an instantiator, this method is the opposite of the **instance** method, allowing you to convert a Time instance into a DateTime instance. This preserves the timezone setting, but loses the locale, since DateTime is -not aware of locales:: +not aware of locales: - $datetime = Time::toDateTime(); +.. literalinclude:: time/014.php + :lines: 2- ==================== Displaying the Value @@ -157,47 +159,44 @@ toLocalizedString() This is the localized version of DateTime's ``format()`` method. Instead of using the values you might be familiar with, though, you must use values acceptable to the `IntlDateFormatter `__ class. A full listing of values can be found `here `__. -:: - $time = Time::parse('March 9, 2016 12:00:00', 'America/Chicago'); - echo $time->toLocalizedString('MMM d, yyyy'); // March 9, 2016 +.. literalinclude:: time/015.php + :lines: 2- toDateTimeString() ------------------ This is the first of three helper methods to work with the IntlDateFormatter without having to remember their values. -This will return a string formatted as you would commonly use for datetime columns in a database (Y-m-d H:i:s):: +This will return a string formatted as you would commonly use for datetime columns in a database (Y-m-d H:i:s): - $time = Time::parse('March 9, 2016 12:00:00', 'America/Chicago'); - echo $time->toDateTimeString(); // 2016-03-09 12:00:00 +.. literalinclude:: time/016.php + :lines: 2- toDateString() -------------- -Displays just the date portion of the Time:: +Displays just the date portion of the Time: - $time = Time::parse('March 9, 2016 12:00:00', 'America/Chicago'); - echo $time->toDateString(); // 2016-03-09 +.. literalinclude:: time/017.php + :lines: 2- toTimeString() -------------- -Displays just the time portion of the value:: +Displays just the time portion of the value: - $time = Time::parse('March 9, 2016 12:00:00', 'America/Chicago'); - echo $time->toTimeString(); // 12:00:00 +.. literalinclude:: time/018.php + :lines: 2- humanize() ---------- This methods returns a string that displays the difference between the current date/time and the instance in a human readable format that is geared towards being easily understood. It can create strings like '3 hours ago', -'in 1 month', etc:: - - // Assume current time is: March 10, 2017 (America/Chicago) - $time = Time::parse('March 9, 2016 12:00:00', 'America/Chicago'); +'in 1 month', etc: - echo $time->humanize(); // 1 year ago +.. literalinclude:: time/019.php + :lines: 2- The exact time displayed is determined in the following manner: @@ -230,96 +229,65 @@ like ``getYear()`` can also be accessed through ``$time->year``, and so on. Getters ------- -The following basic getters exist:: - - $time = Time::parse('August 12, 2016 4:15:23pm'); - - echo $time->getYear(); // 2016 - echo $time->getMonth(); // 8 - echo $time->getDay(); // 12 - echo $time->getHour(); // 16 - echo $time->getMinute(); // 15 - echo $time->getSecond(); // 23 - - echo $time->year; // 2016 - echo $time->month; // 8 - echo $time->day; // 12 - echo $time->hour; // 16 - echo $time->minute; // 15 - echo $time->second; // 23 +The following basic getters exist: -In addition to these, a number of methods exist to provide additional information about the date:: +.. literalinclude:: time/020.php + :lines: 2- - $time = Time::parse('August 12, 2016 4:15:23pm'); +In addition to these, a number of methods exist to provide additional information about the date: - echo $time->getDayOfWeek(); // 6 - but may vary based on locale's starting day of the week - echo $time->getDayOfYear(); // 225 - echo $time->getWeekOfMonth(); // 2 - echo $time->getWeekOfYear(); // 33 - echo $time->getTimestamp(); // 1471018523 - UNIX timestamp - echo $time->getQuarter(); // 3 - - echo $time->dayOfWeek; // 6 - echo $time->dayOfYear; // 225 - echo $time->weekOfMonth; // 2 - echo $time->weekOfYear; // 33 - echo $time->timestamp; // 1471018523 - echo $time->quarter; // 3 +.. literalinclude:: time/021.php + :lines: 2- getAge() -------- Returns the age, in years, of between the Time's instance and the current time. Perfect for checking -the age of someone based on their birthday:: - - $time = Time::parse('5 years ago'); +the age of someone based on their birthday: - echo $time->getAge(); // 5 - echo $time->age; // 5 +.. literalinclude:: time/022.php + :lines: 2- getDST() -------- -Returns boolean true/false based on whether the Time instance is currently observing Daylight Savings Time:: +Returns boolean true/false based on whether the Time instance is currently observing Daylight Savings Time: - echo Time::createFromDate(2012, 1, 1)->getDst(); // false - echo Time::createFromDate(2012, 9, 1)->dst; // true +.. literalinclude:: time/023.php + :lines: 2- getLocal() ---------- -Returns boolean true if the Time instance is in the same timezone as the application is currently running in:: +Returns boolean true if the Time instance is in the same timezone as the application is currently running in: - echo Time::now()->getLocal(); // true - echo Time::now('Europe/London'); // false +.. literalinclude:: time/024.php + :lines: 2- getUtc() -------- -Returns boolean true if the Time instance is in UTC time:: +Returns boolean true if the Time instance is in UTC time: - echo Time::now('America/Chicago')->getUtc(); // false - echo Time::now('UTC')->utc; // true +.. literalinclude:: time/025.php + :lines: 2- getTimezone() ------------- Returns a new `DateTimeZone `__ object set the timezone of the Time -instance:: - - $tz = Time::now()->getTimezone(); - $tz = Time::now()->timezone; +instance: - echo $tz->getName(); - echo $tz->getOffset(); +.. literalinclude:: time/026.php + :lines: 2- getTimezoneName() ----------------- -Returns the full `timezone string `__ of the Time instance:: +Returns the full `timezone string `__ of the Time instance: - echo Time::now('America/Chicago')->getTimezoneName(); // America/Chicago - echo Time::now('Europe/London')->timezoneName; // Europe/London +.. literalinclude:: time/027.php + :lines: 2- Setters ======= @@ -331,41 +299,24 @@ thrown. .. note:: All setters will throw an InvalidArgumentException if the value is out of range. -:: - - $time = $time->setYear(2017); - $time = $time->setMonth(4); // April - $time = $time->setMonth('April'); - $time = $time->setMonth('Feb'); // February - $time = $time->setDay(25); - $time = $time->setHour(14); // 2:00 pm - $time = $time->setMinute(30); - $time = $time->setSecond(54); +.. literalinclude:: time/028.php + :lines: 2- setTimezone() ------------- -Converts the time from it's current timezone into the new one:: - - $time = Time::parse('13 May 2020 10:00', 'America/Chicago'); - $time2 = $time->setTimezone('Europe/London'); // Returns new instance converted to new timezone - - echo $time->getTimezoneName(); // American/Chicago - echo $time2->getTimezoneName(); // Europe/London +Converts the time from it's current timezone into the new one: - echo $time->toDateTimeString(); // 2020-05-13 10:00:00 - echo $time2->toDateTimeString(); // 2020-05-13 18:00:00 +.. literalinclude:: time/029.php + :lines: 2- setTimestamp() -------------- -Returns a new instance with the date set to the new timestamp:: +Returns a new instance with the date set to the new timestamp: - $time = Time::parse('May 10, 2017', 'America/Chicago'); - $time2 = $time->setTimestamp(strtotime('April 1, 2017')); - - echo $time->toDateTimeString(); // 2017-05-10 00:00:00 - echo $time2->toDateTimeString(); // 2017-04-01 00:00:00 +.. literalinclude:: time/030.php + :lines: 2- Modifying the Value =================== @@ -373,21 +324,8 @@ Modifying the Value The following methods allow you to modify the date by adding or subtracting values to the current Time. This will not modify the existing Time instance, but will return a new instance. -:: - - $time = $time->addSeconds(23); - $time = $time->addMinutes(15); - $time = $time->addHours(12); - $time = $time->addDays(21); - $time = $time->addMonths(14); - $time = $time->addYears(5); - - $time = $time->subSeconds(23); - $time = $time->subMinutes(15); - $time = $time->subHours(12); - $time = $time->subDays(21); - $time = $time->subMonths(14); - $time = $time->subYears(5); +.. literalinclude:: time/031.php + :lines: 2- Comparing Two Times =================== @@ -400,113 +338,82 @@ equals() Determines if the datetime passed in is equal to the current instance. Equal in this case means that they represent the same moment in time, and are not required to be in the same timezone, as both times are converted to UTC and compared -that way:: +that way: - $time1 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago'); - $time2 = Time::parse('January 11, 2017 03:50:00', 'Europe/London'); - - $time1->equals($time2); // true +.. literalinclude:: time/032.php + :lines: 2- The value being tested against can be a Time instance, a DateTime instance, or a string with the full date time in a manner that a new DateTime instance can understand. When passing a string as the first parameter, you can pass -a timezone string in as the second parameter. If no timezone is given, the system default will be used:: +a timezone string in as the second parameter. If no timezone is given, the system default will be used: - $time1->equals('January 11, 2017 03:50:00', 'Europe/London'); // true +.. literalinclude:: time/033.php + :lines: 2- sameAs() -------- This is identical to the ``equals()`` method, except that it only returns true when the date, time, AND timezone are -all identical:: - - $time1 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago'); - $time2 = Time::parse('January 11, 2017 03:50:00', 'Europe/London'); +all identical: - $time1->sameAs($time2); // false - $time2->sameAs('January 10, 2017 21:50:00', 'America/Chicago'); // true +.. literalinclude:: time/034.php + :lines: 2- isBefore() ---------- Checks if the passed in time is before the current instance. The comparison is done against the UTC versions of -both times:: - - $time1 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago'); - $time2 = Time::parse('January 11, 2017 03:50:00', 'America/Chicago'); +both times: - $time1->isBefore($time2); // true - $time2->isBefore($time1); // false +.. literalinclude:: time/035.php + :lines: 2- The value being tested against can be a Time instance, a DateTime instance, or a string with the full date time in a manner that a new DateTime instance can understand. When passing a string as the first parameter, you can pass -a timezone string in as the second parameter. If no timezone is given, the system default will be used:: +a timezone string in as the second parameter. If no timezone is given, the system default will be used: - $time1->isBefore('March 15, 2013', 'America/Chicago'); // false +.. literalinclude:: time/036.php + :lines: 2- isAfter() --------- -Works exactly the same as ``isBefore()`` except checks if the time is after the time passed in:: +Works exactly the same as ``isBefore()`` except checks if the time is after the time passed in: - $time1 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago'); - $time2 = Time::parse('January 11, 2017 03:50:00', 'America/Chicago'); - - $time1->isAfter($time2); // false - $time2->isAfter($time1); // true +.. literalinclude:: time/037.php + :lines: 2- Viewing Differences =================== To compare two Times directly, you would use the ``difference()`` method, which returns a ``CodeIgniter\I18n\TimeDifference`` instance. The first parameter is either a Time instance, a DateTime instance, or a string with the date/time. If -a string is passed in the first parameter, the second parameter can be a timezone string:: - - $time = Time::parse('March 10, 2017', 'America/Chicago'); +a string is passed in the first parameter, the second parameter can be a timezone string: - $diff = $time->difference(Time::now()); - $diff = $time->difference(new DateTime('July 4, 1975', 'America/Chicago'); - $diff = $time->difference('July 4, 1975 13:32:05', 'America/Chicago'); +.. literalinclude:: time/038.php + :lines: 2- Once you have the TimeDifference instance, you have several methods you can use to find information about the difference between the two times. The value returned will be negative if it was in the past, or positive if in the future from -the original time:: - - $current = Time::parse('March 10, 2017', 'America/Chicago'); - $test = Time::parse('March 10, 2010', 'America/Chicago'); +the original time: - $diff = $current->difference($test); +.. literalinclude:: time/039.php + :lines: 2- - echo $diff->getYears(); // -7 - echo $diff->getMonths(); // -84 - echo $diff->getWeeks(); // -365 - echo $diff->getDays(); // -2557 - echo $diff->getHours(); // -61368 - echo $diff->getMinutes(); // -3682080 - echo $diff->getSeconds(); // -220924800 +You can use either ``getX()`` methods, or access the calculate values as if they were properties: -You can use either ``getX()`` methods, or access the calculate values as if they were properties:: - - echo $diff->years; // -7 - echo $diff->months; // -84 - echo $diff->weeks; // -365 - echo $diff->days; // -2557 - echo $diff->hours; // -61368 - echo $diff->minutes; // -3682080 - echo $diff->seconds; // -220924800 +.. literalinclude:: time/040.php + :lines: 2- humanize() ---------- Much like Time's ``humanize()`` method, this returns a string that displays the difference between the times in a human readable format that is geared towards being easily understood. It can create strings like '3 hours ago', -'in 1 month', etc. The biggest differences are in how very recent dates are handled:: - - $current = Time::parse('March 10, 2017', 'America/Chicago') - $test = Time::parse('March 9, 2016 12:00:00', 'America/Chicago'); - - $diff = $current->difference($test) +'in 1 month', etc. The biggest differences are in how very recent dates are handled: - echo $diff->humanize(); // 1 year ago +.. literalinclude:: time/041.php + :lines: 2- The exact time displayed is determined in the following manner: diff --git a/user_guide_src/source/libraries/time/001.php b/user_guide_src/source/libraries/time/001.php new file mode 100644 index 000000000000..ba7e4d3b36bc --- /dev/null +++ b/user_guide_src/source/libraries/time/001.php @@ -0,0 +1,6 @@ +toLocalizedString('MMM d, yyyy'); // March 9, 2016 diff --git a/user_guide_src/source/libraries/time/016.php b/user_guide_src/source/libraries/time/016.php new file mode 100644 index 000000000000..32fa8a8fe83f --- /dev/null +++ b/user_guide_src/source/libraries/time/016.php @@ -0,0 +1,4 @@ +toDateTimeString(); // 2016-03-09 12:00:00 diff --git a/user_guide_src/source/libraries/time/017.php b/user_guide_src/source/libraries/time/017.php new file mode 100644 index 000000000000..5ff0734c8add --- /dev/null +++ b/user_guide_src/source/libraries/time/017.php @@ -0,0 +1,4 @@ +toDateString(); // 2016-03-09 diff --git a/user_guide_src/source/libraries/time/018.php b/user_guide_src/source/libraries/time/018.php new file mode 100644 index 000000000000..4d0fcaf8c216 --- /dev/null +++ b/user_guide_src/source/libraries/time/018.php @@ -0,0 +1,4 @@ +toTimeString(); // 12:00:00 diff --git a/user_guide_src/source/libraries/time/019.php b/user_guide_src/source/libraries/time/019.php new file mode 100644 index 000000000000..50088537061c --- /dev/null +++ b/user_guide_src/source/libraries/time/019.php @@ -0,0 +1,6 @@ +humanize(); // 1 year ago diff --git a/user_guide_src/source/libraries/time/020.php b/user_guide_src/source/libraries/time/020.php new file mode 100644 index 000000000000..8d83bcaf5747 --- /dev/null +++ b/user_guide_src/source/libraries/time/020.php @@ -0,0 +1,17 @@ +getYear(); // 2016 +echo $time->getMonth(); // 8 +echo $time->getDay(); // 12 +echo $time->getHour(); // 16 +echo $time->getMinute(); // 15 +echo $time->getSecond(); // 23 + +echo $time->year; // 2016 +echo $time->month; // 8 +echo $time->day; // 12 +echo $time->hour; // 16 +echo $time->minute; // 15 +echo $time->second; // 23 diff --git a/user_guide_src/source/libraries/time/021.php b/user_guide_src/source/libraries/time/021.php new file mode 100644 index 000000000000..a3e0f128c5d7 --- /dev/null +++ b/user_guide_src/source/libraries/time/021.php @@ -0,0 +1,17 @@ +getDayOfWeek(); // 6 - but may vary based on locale's starting day of the week +echo $time->getDayOfYear(); // 225 +echo $time->getWeekOfMonth(); // 2 +echo $time->getWeekOfYear(); // 33 +echo $time->getTimestamp(); // 1471018523 - UNIX timestamp +echo $time->getQuarter(); // 3 + +echo $time->dayOfWeek; // 6 +echo $time->dayOfYear; // 225 +echo $time->weekOfMonth; // 2 +echo $time->weekOfYear; // 33 +echo $time->timestamp; // 1471018523 +echo $time->quarter; // 3 diff --git a/user_guide_src/source/libraries/time/022.php b/user_guide_src/source/libraries/time/022.php new file mode 100644 index 000000000000..facfdc5a9d02 --- /dev/null +++ b/user_guide_src/source/libraries/time/022.php @@ -0,0 +1,6 @@ +getAge(); // 5 +echo $time->age; // 5 diff --git a/user_guide_src/source/libraries/time/023.php b/user_guide_src/source/libraries/time/023.php new file mode 100644 index 000000000000..970aaad45d76 --- /dev/null +++ b/user_guide_src/source/libraries/time/023.php @@ -0,0 +1,4 @@ +getDst(); // false +echo Time::createFromDate(2012, 9, 1)->dst; // true diff --git a/user_guide_src/source/libraries/time/024.php b/user_guide_src/source/libraries/time/024.php new file mode 100644 index 000000000000..1919e1d097cf --- /dev/null +++ b/user_guide_src/source/libraries/time/024.php @@ -0,0 +1,4 @@ +getLocal(); // true +echo Time::now('Europe/London'); // false diff --git a/user_guide_src/source/libraries/time/025.php b/user_guide_src/source/libraries/time/025.php new file mode 100644 index 000000000000..b25d5de4aef9 --- /dev/null +++ b/user_guide_src/source/libraries/time/025.php @@ -0,0 +1,4 @@ +getUtc(); // false +echo Time::now('UTC')->utc; // true diff --git a/user_guide_src/source/libraries/time/026.php b/user_guide_src/source/libraries/time/026.php new file mode 100644 index 000000000000..030102f72d70 --- /dev/null +++ b/user_guide_src/source/libraries/time/026.php @@ -0,0 +1,7 @@ +getTimezone(); +$tz = Time::now()->timezone; + +echo $tz->getName(); +echo $tz->getOffset(); diff --git a/user_guide_src/source/libraries/time/027.php b/user_guide_src/source/libraries/time/027.php new file mode 100644 index 000000000000..dde3a39bec92 --- /dev/null +++ b/user_guide_src/source/libraries/time/027.php @@ -0,0 +1,4 @@ +getTimezoneName(); // America/Chicago +echo Time::now('Europe/London')->timezoneName; // Europe/London diff --git a/user_guide_src/source/libraries/time/028.php b/user_guide_src/source/libraries/time/028.php new file mode 100644 index 000000000000..97a3c26764d3 --- /dev/null +++ b/user_guide_src/source/libraries/time/028.php @@ -0,0 +1,10 @@ +setYear(2017); +$time = $time->setMonth(4); // April +$time = $time->setMonth('April'); +$time = $time->setMonth('Feb'); // February +$time = $time->setDay(25); +$time = $time->setHour(14); // 2:00 pm +$time = $time->setMinute(30); +$time = $time->setSecond(54); diff --git a/user_guide_src/source/libraries/time/029.php b/user_guide_src/source/libraries/time/029.php new file mode 100644 index 000000000000..d65f408fe05d --- /dev/null +++ b/user_guide_src/source/libraries/time/029.php @@ -0,0 +1,10 @@ +setTimezone('Europe/London'); // Returns new instance converted to new timezone + +echo $time->getTimezoneName(); // American/Chicago +echo $time2->getTimezoneName(); // Europe/London + +echo $time->toDateTimeString(); // 2020-05-13 10:00:00 +echo $time2->toDateTimeString(); // 2020-05-13 18:00:00 diff --git a/user_guide_src/source/libraries/time/030.php b/user_guide_src/source/libraries/time/030.php new file mode 100644 index 000000000000..929a9f272e28 --- /dev/null +++ b/user_guide_src/source/libraries/time/030.php @@ -0,0 +1,7 @@ +setTimestamp(strtotime('April 1, 2017')); + +echo $time->toDateTimeString(); // 2017-05-10 00:00:00 +echo $time2->toDateTimeString(); // 2017-04-01 00:00:00 diff --git a/user_guide_src/source/libraries/time/031.php b/user_guide_src/source/libraries/time/031.php new file mode 100644 index 000000000000..3737ae67a3c1 --- /dev/null +++ b/user_guide_src/source/libraries/time/031.php @@ -0,0 +1,15 @@ +addSeconds(23); +$time = $time->addMinutes(15); +$time = $time->addHours(12); +$time = $time->addDays(21); +$time = $time->addMonths(14); +$time = $time->addYears(5); + +$time = $time->subSeconds(23); +$time = $time->subMinutes(15); +$time = $time->subHours(12); +$time = $time->subDays(21); +$time = $time->subMonths(14); +$time = $time->subYears(5); diff --git a/user_guide_src/source/libraries/time/032.php b/user_guide_src/source/libraries/time/032.php new file mode 100644 index 000000000000..9207945c5242 --- /dev/null +++ b/user_guide_src/source/libraries/time/032.php @@ -0,0 +1,6 @@ +equals($time2); // true diff --git a/user_guide_src/source/libraries/time/033.php b/user_guide_src/source/libraries/time/033.php new file mode 100644 index 000000000000..73962921a299 --- /dev/null +++ b/user_guide_src/source/libraries/time/033.php @@ -0,0 +1,3 @@ +equals('January 11, 2017 03:50:00', 'Europe/London'); // true diff --git a/user_guide_src/source/libraries/time/034.php b/user_guide_src/source/libraries/time/034.php new file mode 100644 index 000000000000..229dfe82c094 --- /dev/null +++ b/user_guide_src/source/libraries/time/034.php @@ -0,0 +1,7 @@ +sameAs($time2); // false +$time2->sameAs('January 10, 2017 21:50:00', 'America/Chicago'); // true diff --git a/user_guide_src/source/libraries/time/035.php b/user_guide_src/source/libraries/time/035.php new file mode 100644 index 000000000000..e21714c2f2ef --- /dev/null +++ b/user_guide_src/source/libraries/time/035.php @@ -0,0 +1,7 @@ +isBefore($time2); // true +$time2->isBefore($time1); // false diff --git a/user_guide_src/source/libraries/time/036.php b/user_guide_src/source/libraries/time/036.php new file mode 100644 index 000000000000..817f31e4dce8 --- /dev/null +++ b/user_guide_src/source/libraries/time/036.php @@ -0,0 +1,3 @@ +isBefore('March 15, 2013', 'America/Chicago'); // false diff --git a/user_guide_src/source/libraries/time/037.php b/user_guide_src/source/libraries/time/037.php new file mode 100644 index 000000000000..103d228e1bc3 --- /dev/null +++ b/user_guide_src/source/libraries/time/037.php @@ -0,0 +1,7 @@ +isAfter($time2); // false +$time2->isAfter($time1); // true diff --git a/user_guide_src/source/libraries/time/038.php b/user_guide_src/source/libraries/time/038.php new file mode 100644 index 000000000000..5284ee5d5828 --- /dev/null +++ b/user_guide_src/source/libraries/time/038.php @@ -0,0 +1,7 @@ +difference(Time::now()); +$diff = $time->difference(new DateTime('July 4, 1975', 'America/Chicago'); +$diff = $time->difference('July 4, 1975 13:32:05', 'America/Chicago'); diff --git a/user_guide_src/source/libraries/time/039.php b/user_guide_src/source/libraries/time/039.php new file mode 100644 index 000000000000..12cc3d638f2c --- /dev/null +++ b/user_guide_src/source/libraries/time/039.php @@ -0,0 +1,14 @@ +difference($test); + +echo $diff->getYears(); // -7 +echo $diff->getMonths(); // -84 +echo $diff->getWeeks(); // -365 +echo $diff->getDays(); // -2557 +echo $diff->getHours(); // -61368 +echo $diff->getMinutes(); // -3682080 +echo $diff->getSeconds(); // -220924800 diff --git a/user_guide_src/source/libraries/time/040.php b/user_guide_src/source/libraries/time/040.php new file mode 100644 index 000000000000..1af52b88fd75 --- /dev/null +++ b/user_guide_src/source/libraries/time/040.php @@ -0,0 +1,9 @@ +years; // -7 +echo $diff->months; // -84 +echo $diff->weeks; // -365 +echo $diff->days; // -2557 +echo $diff->hours; // -61368 +echo $diff->minutes; // -3682080 +echo $diff->seconds; // -220924800 diff --git a/user_guide_src/source/libraries/time/041.php b/user_guide_src/source/libraries/time/041.php new file mode 100644 index 000000000000..98a67ecf7998 --- /dev/null +++ b/user_guide_src/source/libraries/time/041.php @@ -0,0 +1,8 @@ +difference($test) + +echo $diff->humanize(); // 1 year ago diff --git a/user_guide_src/source/libraries/typography.rst b/user_guide_src/source/libraries/typography.rst index 0a4ded63a898..adbb868ae902 100644 --- a/user_guide_src/source/libraries/typography.rst +++ b/user_guide_src/source/libraries/typography.rst @@ -14,9 +14,10 @@ Loading the Library ******************* Like all services in CodeIgniter, it can be loaded via ``Config\Services``, though you usually will not need -to load it manually:: +to load it manually: - $typography = \Config\Services::typography(); +.. literalinclude:: typography/001.php + :lines: 2- ************************** Available static functions @@ -34,9 +35,10 @@ The following functions are available: Formats text so that it is semantically and typographically correct HTML. - Usage example:: + Usage example: - $string = $typography->autoTypography($string); + .. literalinclude:: typography/002.php + :lines: 2- .. note:: Typographic formatting can be processor intensive, particularly if you have a lot of content being formatted. If you choose to use this @@ -53,9 +55,10 @@ The following functions are available: to curly entities, but it also converts em-dashes, double spaces, and ampersands. - Usage example:: + Usage example: - $string = $typography->formatCharacters($string); + .. literalinclude:: typography/003.php + :lines: 2- .. php:function:: nl2brExceptPre($str) @@ -67,6 +70,7 @@ The following functions are available: This function is identical to the native PHP ``nl2br()`` function, except that it ignores ``
    `` tags.
     
    -    Usage example::
    +    Usage example:
     
    -        $string = $typography->nl2brExceptPre($string);
    +    .. literalinclude:: typography/004.php
    +       :lines: 2-
    diff --git a/user_guide_src/source/libraries/typography/001.php b/user_guide_src/source/libraries/typography/001.php
    new file mode 100644
    index 000000000000..0c82ed0e95fa
    --- /dev/null
    +++ b/user_guide_src/source/libraries/typography/001.php
    @@ -0,0 +1,3 @@
    +autoTypography($string);
    diff --git a/user_guide_src/source/libraries/typography/003.php b/user_guide_src/source/libraries/typography/003.php
    new file mode 100644
    index 000000000000..1c2d51a9afdd
    --- /dev/null
    +++ b/user_guide_src/source/libraries/typography/003.php
    @@ -0,0 +1,3 @@
    +formatCharacters($string);
    diff --git a/user_guide_src/source/libraries/typography/004.php b/user_guide_src/source/libraries/typography/004.php
    new file mode 100644
    index 000000000000..3d5b4347aafc
    --- /dev/null
    +++ b/user_guide_src/source/libraries/typography/004.php
    @@ -0,0 +1,3 @@
    +nl2brExceptPre($string);
    diff --git a/user_guide_src/source/libraries/uploaded_files.rst b/user_guide_src/source/libraries/uploaded_files.rst
    index 9640809ba99b..b2117f37c37a 100644
    --- a/user_guide_src/source/libraries/uploaded_files.rst
    +++ b/user_guide_src/source/libraries/uploaded_files.rst
    @@ -33,31 +33,9 @@ Creating the Upload Form
     ========================
     
     Using a text editor, create a form called upload_form.php. In it, place
    -this code and save it to your **app/Views/** directory::
    +this code and save it to your **app/Views/** directory:
     
    -    
    -    
    -    
    -        Upload Form
    -    
    -    
    -
    -    
    -        
  • - - - - - - -

    - - - - - - - +.. literalinclude:: uploaded_files/000.php You'll notice we are using a form helper to create the opening form tag. File uploads require a multipart form, so the helper creates the proper @@ -95,56 +73,9 @@ The Controller ============== Using a text editor, create a controller called Upload.php. In it, place -this code and save it to your **app/Controllers/** directory:: - - []]); - } - - public function upload() - { - $validationRule = [ - 'userfile' => [ - 'label' => 'Image File', - 'rules' => 'uploaded[userfile]' - . '|is_image[userfile]' - . '|mime_in[userfile,image/jpg,image/jpeg,image/gif,image/png,image/webp]' - . '|max_size[userfile,100]' - . '|max_dims[userfile,1024,768]', - ], - ]; - if (! $this->validate($validationRule)) { - $data = ['errors' => $this->validator->getErrors()]; +this code and save it to your **app/Controllers/** directory: - return view('upload_form', $data); - } - - $img = $this->request->getFile('userfile'); - - if (! $img->hasMoved()) { - $filepath = WRITEPATH . 'uploads/' . $img->store(); - - $data = ['uploaded_flleinfo' => new File($filepath)]; - - return view('upload_success', $data); - } else { - $data = ['errors' => 'The file has already been moved.']; - - return view('upload_form', $data); - } - } - } +.. literalinclude:: uploaded_files/001.php .. note:: Since the value of a file upload HTML field doesn't exist, and is stored in the ``$_FILES`` global, only :ref:`rules-for-file-uploads` can be used to validate upload file with :doc:`validation`. @@ -181,20 +112,20 @@ are not aware of. CodeIgniter helps with both of these situations by standardizi common interface. Files are accessed through the current ``IncomingRequest`` instance. To retrieve all files that were uploaded with this -request, use ``getFiles()``. This will return an array of files represented by instances of ``CodeIgniter\HTTP\Files\UploadedFile``:: +request, use ``getFiles()``. This will return an array of files represented by instances of ``CodeIgniter\HTTP\Files\UploadedFile``: - $files = $this->request->getFiles(); +.. literalinclude:: uploaded_files/002.php + :lines: 2- Of course, there are multiple ways to name the file input, and anything but the simplest can create strange results. The array returns in a manner that you would expect. With the simplest usage, a single file might be submitted like:: -Which would return a simple array like:: +Which would return a simple array like: - [ - 'avatar' => // UploadedFile instance - ] +.. literalinclude:: uploaded_files/003.php + :lines: 2- .. note:: The UploadedFile instance corresponds to ``$_FILES``. Even if a user just clicks the submit button and does not upload any file, the instance will still exist. You can check that the file was actually uploaded by the ``isValid()`` method in UploadedFile. See :ref:`verify-a-file`. @@ -202,32 +133,20 @@ If you used an array notation for the name, the input would look something like: -The array returned by ``getFiles()`` would look more like this:: +The array returned by ``getFiles()`` would look more like this: - [ - 'my-form' => [ - 'details' => [ - 'avatar' => // UploadedFile instance - ] - ] - ] +.. literalinclude:: uploaded_files/004.php + :lines: 2- In some cases, you may specify an array of files to upload:: Upload an avatar: Upload an avatar: -In this case, the returned array of files would be more like:: +In this case, the returned array of files would be more like: - [ - 'my-form' => [ - 'details' => [ - 'avatar' => [ - 0 => /* UploadedFile instance */, - 1 => /* UploadedFile instance */ - ] - ] - ] +.. literalinclude:: uploaded_files/005.php + :lines: 2- Single File =========== @@ -241,9 +160,10 @@ With the simplest usage, a single file might be submitted like:: -Which would return a simple file instance like:: +Which would return a simple file instance like: - $file = $this->request->getFile('userfile'); +.. literalinclude:: uploaded_files/006.php + :lines: 2- Array notation -------------- @@ -252,9 +172,10 @@ If you used an array notation for the name, the input would look something like: -For get the file instance:: +For get the file instance: - $file = $this->request->getFile('my-form.details.avatar'); +.. literalinclude:: uploaded_files/007.php + :lines: 2- Multiple files ============== @@ -263,40 +184,34 @@ Multiple files -In controller:: +In controller: - if ($imagefile = $this->request->getFiles()) { - foreach($imagefile['images'] as $img) { - if ($img->isValid() && ! $img->hasMoved()) { - $newName = $img->getRandomName(); - $img->move(WRITEPATH . 'uploads', $newName); - } - } - } +.. literalinclude:: uploaded_files/008.php + :lines: 2- where the ``images`` is a loop from the form field name. If there are multiple files with the same name you can use ``getFile()`` to retrieve every file individually. -In controller:: - - $file1 = $this->request->getFile('images.0'); - $file2 = $this->request->getFile('images.1'); +In controller: -You might find it easier to use ``getFileMultiple()``, to get an array of uploaded files with the same name:: +.. literalinclude:: uploaded_files/009.php + :lines: 2- - $files = $this->request->getFileMultiple('images'); +You might find it easier to use ``getFileMultiple()``, to get an array of uploaded files with the same name: +.. literalinclude:: uploaded_files/010.php + :lines: 2- Another example:: Upload an avatar: Upload an avatar: -In controller:: +In controller: - $file1 = $this->request->getFile('my-form.details.avatars.0'); - $file2 = $this->request->getFile('my-form.details.avatars.1'); +.. literalinclude:: uploaded_files/011.php + :lines: 2- .. note:: Using ``getFiles()`` is more appropriate. @@ -312,11 +227,10 @@ move the file to a new location. Verify a File ============= -You can check that a file was actually uploaded via HTTP with no errors by calling the ``isValid()`` method:: +You can check that a file was actually uploaded via HTTP with no errors by calling the ``isValid()`` method: - if (! $file->isValid()) { - throw new \RuntimeException($file->getErrorString() . '(' . $file->getError() . ')'); - } +.. literalinclude:: uploaded_files/012.php + :lines: 2- As seen in this example, if a file had an upload error, you can retrieve the error code (an integer) and the error message with the ``getError()`` and ``getErrorString()`` methods. The following errors can be discovered through @@ -337,61 +251,64 @@ File Names You can retrieve the original filename provided by the client with the ``getName()`` method. This will typically be the filename sent by the client, and should not be trusted. If the file has been moved, this will return the final name of -the moved file:: +the moved file: - $name = $file->getName(); +.. literalinclude:: uploaded_files/013.php + :lines: 2- **getClientName()** -Always returns the original name of the uploaded file as sent by the client, even if the file has been moved:: +Always returns the original name of the uploaded file as sent by the client, even if the file has been moved: - $originalName = $file->getClientName(); +.. literalinclude:: uploaded_files/014.php + :lines: 2- **getTempName()** -To get the full path of the temp file that was created during the upload, you can use the ``getTempName()`` method:: +To get the full path of the temp file that was created during the upload, you can use the ``getTempName()`` method: - $tempfile = $file->getTempName(); +.. literalinclude:: uploaded_files/015.php + :lines: 2- Other File Info =============== **getClientExtension()** -Returns the original file extension, based on the file name that was uploaded:: +Returns the original file extension, based on the file name that was uploaded: - $ext = $file->getClientExtension(); +.. literalinclude:: uploaded_files/016.php + :lines: 2- .. warning:: This is NOT a trusted source. For a trusted version, use ``guessExtension()`` instead. **getClientMimeType()** Returns the mime type (mime type) of the file as provided by the client. This is NOT a trusted value. For a trusted -version, use ``getMimeType()`` instead:: - - $type = $file->getClientMimeType(); +version, use ``getMimeType()`` instead: - echo $type; // image/png +.. literalinclude:: uploaded_files/017.php + :lines: 2- Moving Files ============ Each file can be moved to its new location with the aptly named ``move()`` method. This takes the directory to move -the file to as the first parameter:: +the file to as the first parameter: - $file->move(WRITEPATH . 'uploads'); +.. literalinclude:: uploaded_files/018.php + :lines: 2- -By default, the original filename was used. You can specify a new filename by passing it as the second parameter:: +By default, the original filename was used. You can specify a new filename by passing it as the second parameter: - $newName = $file->getRandomName(); - $file->move(WRITEPATH . 'uploads', $newName); +.. literalinclude:: uploaded_files/019.php + :lines: 2- Once the file has been removed the temporary file is deleted. You can check if a file has been moved already with -the ``hasMoved()`` method, which returns a boolean:: +the ``hasMoved()`` method, which returns a boolean: - if ($file->isValid() && ! $file->hasMoved()) { - $file->move($path); - } +.. literalinclude:: uploaded_files/020.php + :lines: 2- Moving an uploaded file can fail, with an HTTPException, under several circumstances: @@ -409,14 +326,16 @@ With the simplest usage, a single file might be submitted like:: By default, upload files are saved in **writable/uploads** directory. The **YYYYMMDD** folder -and random file name will be created. Returns a file path:: +and random file name will be created. Returns a file path: - $path = $this->request->getFile('userfile')->store(); +.. literalinclude:: uploaded_files/021.php + :lines: 2- You can specify a directory to move the file to as the first parameter. A new filename by -passing it as the second parameter:: +passing it as the second parameter: - $path = $this->request->getFile('userfile')->store('head_img/', 'user_name.jpg'); +.. literalinclude:: uploaded_files/022.php + :lines: 2- Moving an uploaded file can fail, with an ``HTTPException``, under several circumstances: diff --git a/user_guide_src/source/libraries/uploaded_files/000.php b/user_guide_src/source/libraries/uploaded_files/000.php new file mode 100644 index 000000000000..d58b7664d28b --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/000.php @@ -0,0 +1,23 @@ + + + + Upload Form + + + + +
  • + + + + + + +

    + + + + + + + diff --git a/user_guide_src/source/libraries/uploaded_files/001.php b/user_guide_src/source/libraries/uploaded_files/001.php new file mode 100644 index 000000000000..f186d517fd96 --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/001.php @@ -0,0 +1,48 @@ + []]); + } + + public function upload() + { + $validationRule = [ + 'userfile' => [ + 'label' => 'Image File', + 'rules' => 'uploaded[userfile]' + . '|is_image[userfile]' + . '|mime_in[userfile,image/jpg,image/jpeg,image/gif,image/png,image/webp]' + . '|max_size[userfile,100]' + . '|max_dims[userfile,1024,768]', + ], + ]; + if (! $this->validate($validationRule)) { + $data = ['errors' => $this->validator->getErrors()]; + + return view('upload_form', $data); + } + + $img = $this->request->getFile('userfile'); + + if (! $img->hasMoved()) { + $filepath = WRITEPATH . 'uploads/' . $img->store(); + + $data = ['uploaded_flleinfo' => new File($filepath)]; + + return view('upload_success', $data); + } else { + $data = ['errors' => 'The file has already been moved.']; + + return view('upload_form', $data); + } + } +} diff --git a/user_guide_src/source/libraries/uploaded_files/002.php b/user_guide_src/source/libraries/uploaded_files/002.php new file mode 100644 index 000000000000..17141efbdde8 --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/002.php @@ -0,0 +1,3 @@ +request->getFiles(); diff --git a/user_guide_src/source/libraries/uploaded_files/003.php b/user_guide_src/source/libraries/uploaded_files/003.php new file mode 100644 index 000000000000..368facf4f7ab --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/003.php @@ -0,0 +1,5 @@ + // UploadedFile instance +] diff --git a/user_guide_src/source/libraries/uploaded_files/004.php b/user_guide_src/source/libraries/uploaded_files/004.php new file mode 100644 index 000000000000..bf31373e57bd --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/004.php @@ -0,0 +1,9 @@ + [ + 'details' => [ + 'avatar' => // UploadedFile instance + ] + ] +] diff --git a/user_guide_src/source/libraries/uploaded_files/005.php b/user_guide_src/source/libraries/uploaded_files/005.php new file mode 100644 index 000000000000..c53d82a298fc --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/005.php @@ -0,0 +1,11 @@ + [ + 'details' => [ + 'avatar' => [ + 0 => /* UploadedFile instance */, + 1 => /* UploadedFile instance */ + ] + ] +] diff --git a/user_guide_src/source/libraries/uploaded_files/006.php b/user_guide_src/source/libraries/uploaded_files/006.php new file mode 100644 index 000000000000..e5f6440d96fb --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/006.php @@ -0,0 +1,3 @@ +request->getFile('userfile'); diff --git a/user_guide_src/source/libraries/uploaded_files/007.php b/user_guide_src/source/libraries/uploaded_files/007.php new file mode 100644 index 000000000000..ad71bd5575fb --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/007.php @@ -0,0 +1,3 @@ +request->getFile('my-form.details.avatar'); diff --git a/user_guide_src/source/libraries/uploaded_files/008.php b/user_guide_src/source/libraries/uploaded_files/008.php new file mode 100644 index 000000000000..f37491c04821 --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/008.php @@ -0,0 +1,10 @@ +request->getFiles()) { + foreach($imagefile['images'] as $img) { + if ($img->isValid() && ! $img->hasMoved()) { + $newName = $img->getRandomName(); + $img->move(WRITEPATH . 'uploads', $newName); + } + } +} diff --git a/user_guide_src/source/libraries/uploaded_files/009.php b/user_guide_src/source/libraries/uploaded_files/009.php new file mode 100644 index 000000000000..da51d17dbd15 --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/009.php @@ -0,0 +1,4 @@ +request->getFile('images.0'); +$file2 = $this->request->getFile('images.1'); diff --git a/user_guide_src/source/libraries/uploaded_files/010.php b/user_guide_src/source/libraries/uploaded_files/010.php new file mode 100644 index 000000000000..646e6bb0b8b9 --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/010.php @@ -0,0 +1,3 @@ +request->getFileMultiple('images'); diff --git a/user_guide_src/source/libraries/uploaded_files/011.php b/user_guide_src/source/libraries/uploaded_files/011.php new file mode 100644 index 000000000000..d18a755ba234 --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/011.php @@ -0,0 +1,4 @@ +request->getFile('my-form.details.avatars.0'); +$file2 = $this->request->getFile('my-form.details.avatars.1'); diff --git a/user_guide_src/source/libraries/uploaded_files/012.php b/user_guide_src/source/libraries/uploaded_files/012.php new file mode 100644 index 000000000000..094ea73c1064 --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/012.php @@ -0,0 +1,5 @@ +isValid()) { + throw new \RuntimeException($file->getErrorString() . '(' . $file->getError() . ')'); +} diff --git a/user_guide_src/source/libraries/uploaded_files/013.php b/user_guide_src/source/libraries/uploaded_files/013.php new file mode 100644 index 000000000000..057a56b3e9a0 --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/013.php @@ -0,0 +1,3 @@ +getName(); diff --git a/user_guide_src/source/libraries/uploaded_files/014.php b/user_guide_src/source/libraries/uploaded_files/014.php new file mode 100644 index 000000000000..4fb0cae0ad12 --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/014.php @@ -0,0 +1,3 @@ +getClientName(); diff --git a/user_guide_src/source/libraries/uploaded_files/015.php b/user_guide_src/source/libraries/uploaded_files/015.php new file mode 100644 index 000000000000..c9e4774a4bbf --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/015.php @@ -0,0 +1,3 @@ +getTempName(); diff --git a/user_guide_src/source/libraries/uploaded_files/016.php b/user_guide_src/source/libraries/uploaded_files/016.php new file mode 100644 index 000000000000..867877238c76 --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/016.php @@ -0,0 +1,3 @@ +getClientExtension(); diff --git a/user_guide_src/source/libraries/uploaded_files/017.php b/user_guide_src/source/libraries/uploaded_files/017.php new file mode 100644 index 000000000000..dd1288e441c3 --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/017.php @@ -0,0 +1,5 @@ +getClientMimeType(); + +echo $type; // image/png diff --git a/user_guide_src/source/libraries/uploaded_files/018.php b/user_guide_src/source/libraries/uploaded_files/018.php new file mode 100644 index 000000000000..12499a3ca1ba --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/018.php @@ -0,0 +1,3 @@ +move(WRITEPATH . 'uploads'); diff --git a/user_guide_src/source/libraries/uploaded_files/019.php b/user_guide_src/source/libraries/uploaded_files/019.php new file mode 100644 index 000000000000..2e6b39645a4b --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/019.php @@ -0,0 +1,4 @@ +getRandomName(); +$file->move(WRITEPATH . 'uploads', $newName); diff --git a/user_guide_src/source/libraries/uploaded_files/020.php b/user_guide_src/source/libraries/uploaded_files/020.php new file mode 100644 index 000000000000..7f49d1f5232e --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/020.php @@ -0,0 +1,5 @@ +isValid() && ! $file->hasMoved()) { + $file->move($path); +} diff --git a/user_guide_src/source/libraries/uploaded_files/021.php b/user_guide_src/source/libraries/uploaded_files/021.php new file mode 100644 index 000000000000..90f9495eaf7b --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/021.php @@ -0,0 +1,3 @@ +request->getFile('userfile')->store(); diff --git a/user_guide_src/source/libraries/uploaded_files/022.php b/user_guide_src/source/libraries/uploaded_files/022.php new file mode 100644 index 000000000000..0e552f417d52 --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/022.php @@ -0,0 +1,3 @@ +request->getFile('userfile')->store('head_img/', 'user_name.jpg'); diff --git a/user_guide_src/source/libraries/uri.rst b/user_guide_src/source/libraries/uri.rst index 4f5e9dda6fb6..25e7c92566b0 100644 --- a/user_guide_src/source/libraries/uri.rst +++ b/user_guide_src/source/libraries/uri.rst @@ -14,58 +14,59 @@ relative URI to an existing one and have it resolved safely and correctly. Creating URI instances ====================== -Creating a URI instance is as simple as creating a new class instance:: +Creating a URI instance is as simple as creating a new class instance: - $uri = new \CodeIgniter\HTTP\URI(); +.. literalinclude:: uri/001.php + :lines: 2- -Alternatively, you can use the ``service()`` function to return an instance for you:: +Alternatively, you can use the ``service()`` function to return an instance for you: - $uri = service('uri'); +.. literalinclude:: uri/002.php + :lines: 2- When you create the new instance, you can pass a full or partial URL in the constructor and it will be parsed -into its appropriate sections:: +into its appropriate sections: - $uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path'); - $uri = service('uri', 'http://www.example.com/some/path'); +.. literalinclude:: uri/003.php + :lines: 2- The Current URI --------------- Many times, all you really want is an object representing the current URL of this request. -You can use one of the functions available in the **url_helper**:: +You can use one of the functions available in the **url_helper**: - $uri = current_url(true); +.. literalinclude:: uri/004.php + :lines: 2- You must pass ``true`` as the first parameter, otherwise, it will return the string representation of the current URL. This URI is based on the path (relative to your ``baseURL``) as determined by the current request object and your settings in ``Config\App`` (baseURL, indexPage, and forceGlobalSecureRequests). -Assuming that you're in a controller that extends ``CodeIgniter\Controller`` you can get this relative path:: +Assuming that you're in a controller that extends ``CodeIgniter\Controller`` you can get this relative path: - $path = $this->request->getPath(); +.. literalinclude:: uri/005.php + :lines: 2- =========== URI Strings =========== Many times, all you really want is to get a string representation of a URI. This is easy to do by simply casting -the URI as a string:: +the URI as a string: - $uri = current_url(true); - echo (string) $uri; // http://example.com/index.php +.. literalinclude:: uri/006.php + :lines: 2- If you know the pieces of the URI and just want to ensure it's all formatted correctly, you can generate a string -using the URI class' static ``createURIString()`` method:: +using the URI class' static ``createURIString()`` method: - $uriString = URI::createURIString($scheme, $authority, $path, $query, $fragment); - - // Creates: http://exmample.com/some/path?foo=bar#first-heading - echo URI::createURIString('http', 'example.com', 'some/path', 'foo=bar', 'first-heading'); +.. literalinclude:: uri/007.php + :lines: 2- .. important:: When ``URI`` is cast to a string, it will attempt to adjust project URLs to the settings defined in ``Config\App``. If you need the exact, unaltered string representation then use ``URI::createURIString()`` instead. - ============= The URI Parts ============= @@ -77,12 +78,9 @@ Scheme ------ The scheme is frequently 'http' or 'https', but any scheme is supported, including 'file', 'mailto', etc. -:: - - $uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path'); - echo $uri->getScheme(); // 'http' - $uri->setScheme('https'); +.. literalinclude:: uri/008.php + :lines: 2- Authority --------- @@ -90,25 +88,21 @@ Authority Many URIs contain several elements that are collectively known as the 'authority'. This includes any user info, the host and the port number. You can retrieve all of these pieces as one single string with the ``getAuthority()`` method, or you can manipulate the individual parts. -:: - $uri = new \CodeIgniter\HTTP\URI('ftp://user:password@example.com:21/some/path'); - - echo $uri->getAuthority(); // user@example.com:21 +.. literalinclude:: uri/009.php + :lines: 2- By default, this will not display the password portion since you wouldn't want to show that to anyone. If you want to show the password, you can use the ``showPassword()`` method. This URI instance will continue to show that password -until you turn it off again, so always make sure that you turn it off as soon as you are finished with it:: - - echo $uri->getAuthority(); // user@example.com:21 - echo $uri->showPassword()->getAuthority(); // user:password@example.com:21 +until you turn it off again, so always make sure that you turn it off as soon as you are finished with it: - // Turn password display off again. - $uri->showPassword(false); +.. literalinclude:: uri/010.php + :lines: 2- -If you do not want to display the port, pass in ``true`` as the only parameter:: +If you do not want to display the port, pass in ``true`` as the only parameter: - echo $uri->getAuthority(true); // user@example.com +.. literalinclude:: uri/011.php + :lines: 2- .. note:: If the current port is the default port for the scheme it will never be displayed. @@ -116,36 +110,32 @@ Userinfo -------- The userinfo section is simply the username and password that you might see with an FTP URI. While you can get -this as part of the Authority, you can also retrieve it yourself:: +this as part of the Authority, you can also retrieve it yourself: - echo $uri->getUserInfo(); // user +.. literalinclude:: uri/012.php + :lines: 2- -By default, it will not display the password, but you can override that with the ``showPassword()`` method:: +By default, it will not display the password, but you can override that with the ``showPassword()`` method: - echo $uri->showPassword()->getUserInfo(); // user:password - $uri->showPassword(false); +.. literalinclude:: uri/013.php + :lines: 2- Host ---- The host portion of the URI is typically the domain name of the URL. This can be easily set and retrieved with the -``getHost()`` and ``setHost()`` methods:: +``getHost()`` and ``setHost()`` methods: - $uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path'); - - echo $uri->getHost(); // www.example.com - echo $uri->setHost('anotherexample.com')->getHost(); // anotherexample.com +.. literalinclude:: uri/014.php + :lines: 2- Port ---- The port is an integer number between 0 and 65535. Each sheme has a default value associated with it. -:: - - $uri = new \CodeIgniter\HTTP\URI('ftp://user:password@example.com:21/some/path'); - echo $uri->getPort(); // 21 - echo $uri->setPort(2201)->getPort(); // 2201 +.. literalinclude:: uri/015.php + :lines: 2- When using the ``setPort()`` method, the port will be checked that it is within the valid range and assigned. @@ -153,12 +143,10 @@ Path ---- The path are all of the segments within the site itself. As expected, the ``getPath()`` and ``setPath()`` methods -can be used to manipulate it:: +can be used to manipulate it: - $uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path'); - - echo $uri->getPath(); // 'some/path' - echo $uri->setPath('another/path')->getPath(); // 'another/path' +.. literalinclude:: uri/016.php + :lines: 2- .. note:: When setting the path this way, or any other way the class allows, it is sanitized to encode any dangerous characters, and remove dot segments for safety. @@ -168,48 +156,37 @@ Query The query variables can be manipulated through the class using simple string representations. Query values can only be set as a string currently. -:: - - $uri = new \CodeIgniter\HTTP\URI('http://www.example.com?foo=bar'); - echo $uri->getQuery(); // 'foo=bar' - $uri->setQuery('foo=bar&bar=baz'); +.. literalinclude:: uri/017.php + :lines: 2- .. note:: Query values cannot contain fragments. An InvalidArgumentException will be thrown if it does. -You can set query values using an array:: +You can set query values using an array: - $uri->setQueryArray(['foo' => 'bar', 'bar' => 'baz']); +.. literalinclude:: uri/018.php + :lines: 2- The ``setQuery()`` and ``setQueryArray()`` methods overwrite any existing query variables. You can add a value to the query variables collection without destroying the existing query variables with the ``addQuery()`` method. The first -parameter is the name of the variable, and the second parameter is the value:: +parameter is the name of the variable, and the second parameter is the value: - $uri->addQuery('foo', 'bar'); +.. literalinclude:: uri/019.php + :lines: 2- **Filtering Query Values** You can filter the query values returned by passing an options array to the ``getQuery()`` method, with either an -*only* or an *except* key:: +*only* or an *except* key: - $uri = new \CodeIgniter\HTTP\URI('http://www.example.com?foo=bar&bar=baz&baz=foz'); - - // Returns 'foo=bar' - echo $uri->getQuery(['only' => ['foo']); - - // Returns 'foo=bar&baz=foz' - echo $uri->getQuery(['except' => ['bar']]); +.. literalinclude:: uri/020.php + :lines: 2- This only changes the values returned during this one call. If you need to modify the URI's query values more permanently, -you can use the ``stripQuery()`` and ``keepQuery()`` methods to change the actual object's query variable collection:: - - $uri = new \CodeIgniter\HTTP\URI('http://www.example.com?foo=bar&bar=baz&baz=foz'); +you can use the ``stripQuery()`` and ``keepQuery()`` methods to change the actual object's query variable collection: - // Leaves just the 'baz' variable - $uri->stripQuery('foo', 'bar'); - - // Leaves just the 'foo' variable - $uri->keepQuery('foo'); +.. literalinclude:: uri/021.php + :lines: 2- .. note:: By default ``setQuery()`` and ``setQueryArray()`` methods uses native ``parse_str()`` function to prepare data. If you want to use more liberal rules (which allow key names to contain dots), you can use a special method @@ -220,12 +197,9 @@ Fragment Fragments are the portion at the end of the URL, preceded by the pound-sign (#). In HTML URL's these are links to an on-page anchor. Media URI's can make use of them in various other ways. -:: - - $uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path#first-heading'); - echo $uri->getFragment(); // 'first-heading' - echo $uri->setFragment('second-heading')->getFragment(); // 'second-heading' +.. literalinclude:: uri/022.php + :lines: 2- ============ URI Segments @@ -233,45 +207,24 @@ URI Segments Each section of the path between the slashes is a single segment. The URI class provides a simple way to determine what the values of the segments are. The segments start at 1 being the furthest left of the path. -:: - // URI = http://example.com/users/15/profile - - // Prints '15' - if ($uri->getSegment(1) == 'users') { - echo $uri->getSegment(2); - } +.. literalinclude:: uri/023.php + :lines: 2- You can also set a different default value for a particular segment by using the second parameter of the ``getSegment()`` method. The default is empty string. -:: - - // URI = http://example.com/users/15/profile - // will print 'profile' - echo $uri->getSegment(3, 'foo'); - // will print 'bar' - echo $uri->getSegment(4, 'bar'); - // will throw an exception - echo $uri->getSegment(5, 'baz'); - // will print 'baz' - echo $uri->setSilent()->getSegment(5, 'baz'); - // will print '' (empty string) - echo $uri->setSilent()->getSegment(5); +.. literalinclude:: uri/024.php + :lines: 2- -You can get a count of the total segments:: +You can get a count of the total segments: - $total = $uri->getTotalSegments(); // 3 +.. literalinclude:: uri/025.php + :lines: 2- -Finally, you can retrieve an array of all of the segments:: +Finally, you can retrieve an array of all of the segments: - $segments = $uri->getSegments(); - - // $segments = - [ - 0 => 'users', - 1 => '15', - 2 => 'profile' - ] +.. literalinclude:: uri/026.php + :lines: 2- =========================== Disable Throwing Exceptions @@ -279,10 +232,6 @@ Disable Throwing Exceptions By default, some methods of this class may throw an exception. If you want to disable it, you can set a special flag that will prevent throwing exceptions. -:: - - // Disable throwing exceptions - $uri->setSilent(); - // Enable throwing exceptions (default) - $uri->setSilent(false); +.. literalinclude:: uri/027.php + :lines: 2- diff --git a/user_guide_src/source/libraries/uri/001.php b/user_guide_src/source/libraries/uri/001.php new file mode 100644 index 000000000000..524e67669110 --- /dev/null +++ b/user_guide_src/source/libraries/uri/001.php @@ -0,0 +1,3 @@ +request->getPath(); diff --git a/user_guide_src/source/libraries/uri/006.php b/user_guide_src/source/libraries/uri/006.php new file mode 100644 index 000000000000..3cdabe4db4e8 --- /dev/null +++ b/user_guide_src/source/libraries/uri/006.php @@ -0,0 +1,4 @@ +getScheme(); // 'http' +$uri->setScheme('https'); diff --git a/user_guide_src/source/libraries/uri/009.php b/user_guide_src/source/libraries/uri/009.php new file mode 100644 index 000000000000..44043fbe63d0 --- /dev/null +++ b/user_guide_src/source/libraries/uri/009.php @@ -0,0 +1,5 @@ +getAuthority(); // user@example.com:21 diff --git a/user_guide_src/source/libraries/uri/010.php b/user_guide_src/source/libraries/uri/010.php new file mode 100644 index 000000000000..7b723837fd7f --- /dev/null +++ b/user_guide_src/source/libraries/uri/010.php @@ -0,0 +1,7 @@ +getAuthority(); // user@example.com:21 +echo $uri->showPassword()->getAuthority(); // user:password@example.com:21 + +// Turn password display off again. +$uri->showPassword(false); diff --git a/user_guide_src/source/libraries/uri/011.php b/user_guide_src/source/libraries/uri/011.php new file mode 100644 index 000000000000..ac1297380583 --- /dev/null +++ b/user_guide_src/source/libraries/uri/011.php @@ -0,0 +1,3 @@ +getAuthority(true); // user@example.com diff --git a/user_guide_src/source/libraries/uri/012.php b/user_guide_src/source/libraries/uri/012.php new file mode 100644 index 000000000000..0f733222f408 --- /dev/null +++ b/user_guide_src/source/libraries/uri/012.php @@ -0,0 +1,3 @@ +getUserInfo(); // user diff --git a/user_guide_src/source/libraries/uri/013.php b/user_guide_src/source/libraries/uri/013.php new file mode 100644 index 000000000000..65836aa97865 --- /dev/null +++ b/user_guide_src/source/libraries/uri/013.php @@ -0,0 +1,4 @@ +showPassword()->getUserInfo(); // user:password +$uri->showPassword(false); diff --git a/user_guide_src/source/libraries/uri/014.php b/user_guide_src/source/libraries/uri/014.php new file mode 100644 index 000000000000..79192a56955d --- /dev/null +++ b/user_guide_src/source/libraries/uri/014.php @@ -0,0 +1,6 @@ +getHost(); // www.example.com +echo $uri->setHost('anotherexample.com')->getHost(); // anotherexample.com diff --git a/user_guide_src/source/libraries/uri/015.php b/user_guide_src/source/libraries/uri/015.php new file mode 100644 index 000000000000..f5b43c3a65d0 --- /dev/null +++ b/user_guide_src/source/libraries/uri/015.php @@ -0,0 +1,6 @@ +getPort(); // 21 +echo $uri->setPort(2201)->getPort(); // 2201 diff --git a/user_guide_src/source/libraries/uri/016.php b/user_guide_src/source/libraries/uri/016.php new file mode 100644 index 000000000000..a9e680ac38de --- /dev/null +++ b/user_guide_src/source/libraries/uri/016.php @@ -0,0 +1,6 @@ +getPath(); // 'some/path' +echo $uri->setPath('another/path')->getPath(); // 'another/path' diff --git a/user_guide_src/source/libraries/uri/017.php b/user_guide_src/source/libraries/uri/017.php new file mode 100644 index 000000000000..dd45fb157f4b --- /dev/null +++ b/user_guide_src/source/libraries/uri/017.php @@ -0,0 +1,6 @@ +getQuery(); // 'foo=bar' +$uri->setQuery('foo=bar&bar=baz'); diff --git a/user_guide_src/source/libraries/uri/018.php b/user_guide_src/source/libraries/uri/018.php new file mode 100644 index 000000000000..64d5ab6f359c --- /dev/null +++ b/user_guide_src/source/libraries/uri/018.php @@ -0,0 +1,3 @@ +setQueryArray(['foo' => 'bar', 'bar' => 'baz']); diff --git a/user_guide_src/source/libraries/uri/019.php b/user_guide_src/source/libraries/uri/019.php new file mode 100644 index 000000000000..076fbf4652c1 --- /dev/null +++ b/user_guide_src/source/libraries/uri/019.php @@ -0,0 +1,3 @@ +addQuery('foo', 'bar'); diff --git a/user_guide_src/source/libraries/uri/020.php b/user_guide_src/source/libraries/uri/020.php new file mode 100644 index 000000000000..ab991a826cff --- /dev/null +++ b/user_guide_src/source/libraries/uri/020.php @@ -0,0 +1,9 @@ +getQuery(['only' => ['foo']); + +// Returns 'foo=bar&baz=foz' +echo $uri->getQuery(['except' => ['bar']]); diff --git a/user_guide_src/source/libraries/uri/021.php b/user_guide_src/source/libraries/uri/021.php new file mode 100644 index 000000000000..ed2976e6e1d3 --- /dev/null +++ b/user_guide_src/source/libraries/uri/021.php @@ -0,0 +1,9 @@ +stripQuery('foo', 'bar'); + +// Leaves just the 'foo' variable +$uri->keepQuery('foo'); diff --git a/user_guide_src/source/libraries/uri/022.php b/user_guide_src/source/libraries/uri/022.php new file mode 100644 index 000000000000..e2df019dcb87 --- /dev/null +++ b/user_guide_src/source/libraries/uri/022.php @@ -0,0 +1,6 @@ +getFragment(); // 'first-heading' +echo $uri->setFragment('second-heading')->getFragment(); // 'second-heading' diff --git a/user_guide_src/source/libraries/uri/023.php b/user_guide_src/source/libraries/uri/023.php new file mode 100644 index 000000000000..8c611f066c28 --- /dev/null +++ b/user_guide_src/source/libraries/uri/023.php @@ -0,0 +1,8 @@ +getSegment(1) == 'users') { + echo $uri->getSegment(2); +} diff --git a/user_guide_src/source/libraries/uri/024.php b/user_guide_src/source/libraries/uri/024.php new file mode 100644 index 000000000000..61a951db93c3 --- /dev/null +++ b/user_guide_src/source/libraries/uri/024.php @@ -0,0 +1,14 @@ +getSegment(3, 'foo'); +// will print 'bar' +echo $uri->getSegment(4, 'bar'); +// will throw an exception +echo $uri->getSegment(5, 'baz'); +// will print 'baz' +echo $uri->setSilent()->getSegment(5, 'baz'); +// will print '' (empty string) +echo $uri->setSilent()->getSegment(5); diff --git a/user_guide_src/source/libraries/uri/025.php b/user_guide_src/source/libraries/uri/025.php new file mode 100644 index 000000000000..ce130a2c6f8b --- /dev/null +++ b/user_guide_src/source/libraries/uri/025.php @@ -0,0 +1,3 @@ +getTotalSegments(); // 3 diff --git a/user_guide_src/source/libraries/uri/026.php b/user_guide_src/source/libraries/uri/026.php new file mode 100644 index 000000000000..c5be0f68c2ff --- /dev/null +++ b/user_guide_src/source/libraries/uri/026.php @@ -0,0 +1,10 @@ +getSegments(); + +// $segments = +[ + 0 => 'users', + 1 => '15', + 2 => 'profile' +] diff --git a/user_guide_src/source/libraries/uri/027.php b/user_guide_src/source/libraries/uri/027.php new file mode 100644 index 000000000000..8ad2f883ffe4 --- /dev/null +++ b/user_guide_src/source/libraries/uri/027.php @@ -0,0 +1,7 @@ +setSilent(); + +// Enable throwing exceptions (default) +$uri->setSilent(false); diff --git a/user_guide_src/source/libraries/user_agent.rst b/user_guide_src/source/libraries/user_agent.rst index 576798bf4b2a..fad24a91d403 100644 --- a/user_guide_src/source/libraries/user_agent.rst +++ b/user_guide_src/source/libraries/user_agent.rst @@ -18,9 +18,10 @@ Initializing the Class The User Agent class is always available directly from the current :doc:`IncomingRequest ` instance. By default, you will have a request instance in your controller that you can retrieve the -User Agent class from:: +User Agent class from: - $agent = $this->request->getUserAgent(); +.. literalinclude:: user_agent/001.php + :lines: 2- User Agent Definitions ====================== @@ -35,23 +36,10 @@ Example When the User Agent class is initialized it will attempt to determine whether the user agent browsing your site is a web browser, a mobile device, or a robot. It will also gather the platform information if it -is available:: +is available: - $agent = $this->request->getUserAgent(); - - if ($agent->isBrowser()) { - $currentAgent = $agent->getBrowser() . ' ' . $agent->getVersion(); - } elseif ($agent->isRobot()) { - $currentAgent = $agent->getRobot(); - } elseif ($agent->isMobile()) { - $currentAgent = $agent->getMobile(); - } else { - $currentAgent = 'Unidentified User Agent'; - } - - echo $currentAgent; - - echo $agent->getPlatform(); // Platform info (Windows, Linux, Mac, etc.) +.. literalinclude:: user_agent/002.php + :lines: 2- *************** Class Reference @@ -66,13 +54,9 @@ Class Reference :rtype: bool Returns true/false (boolean) if the user agent is a known web browser. - :: - if ($agent->isBrowser('Safari')) { - echo 'You are using Safari.'; - } elseif ($agent->isBrowser()) { - echo 'You are using a browser.'; - } + .. literalinclude:: user_agent/003.php + :lines: 2- .. note:: The string "Safari" in this example is an array key in the list of browser definitions. You can find this list in **app/Config/UserAgents.php** if you want to add new @@ -85,15 +69,9 @@ Class Reference :rtype: bool Returns true/false (boolean) if the user agent is a known mobile device. - :: - if ($agent->isMobile('iphone')) { - echo view('iphone/home'); - } elseif ($agent->isMobile()) { - echo view('mobile/home'); - } else { - echo view('web/home'); - } + .. literalinclude:: user_agent/004.php + :lines: 2- .. php:method:: isRobot([$key = null]) @@ -155,11 +133,10 @@ Class Reference :returns: Detected referrer 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:: + The referrer, if the user agent was referred from another site. Typically you'll test for this as follows: - if ($agent->isReferral()) { - echo $agent->referrer(); - } + .. literalinclude:: user_agent/005.php + :lines: 2- .. php:method:: getAgentString() diff --git a/user_guide_src/source/libraries/user_agent/001.php b/user_guide_src/source/libraries/user_agent/001.php new file mode 100644 index 000000000000..f8af7f7cfaee --- /dev/null +++ b/user_guide_src/source/libraries/user_agent/001.php @@ -0,0 +1,3 @@ +request->getUserAgent(); diff --git a/user_guide_src/source/libraries/user_agent/002.php b/user_guide_src/source/libraries/user_agent/002.php new file mode 100644 index 000000000000..0a92a06bc2f7 --- /dev/null +++ b/user_guide_src/source/libraries/user_agent/002.php @@ -0,0 +1,17 @@ +request->getUserAgent(); + +if ($agent->isBrowser()) { + $currentAgent = $agent->getBrowser() . ' ' . $agent->getVersion(); +} elseif ($agent->isRobot()) { + $currentAgent = $agent->getRobot(); +} elseif ($agent->isMobile()) { + $currentAgent = $agent->getMobile(); +} else { + $currentAgent = 'Unidentified User Agent'; +} + +echo $currentAgent; + +echo $agent->getPlatform(); // Platform info (Windows, Linux, Mac, etc.) diff --git a/user_guide_src/source/libraries/user_agent/003.php b/user_guide_src/source/libraries/user_agent/003.php new file mode 100644 index 000000000000..0abfbf22d7d8 --- /dev/null +++ b/user_guide_src/source/libraries/user_agent/003.php @@ -0,0 +1,7 @@ +isBrowser('Safari')) { + echo 'You are using Safari.'; +} elseif ($agent->isBrowser()) { + echo 'You are using a browser.'; +} diff --git a/user_guide_src/source/libraries/user_agent/004.php b/user_guide_src/source/libraries/user_agent/004.php new file mode 100644 index 000000000000..80405bff519d --- /dev/null +++ b/user_guide_src/source/libraries/user_agent/004.php @@ -0,0 +1,9 @@ +isMobile('iphone')) { + echo view('iphone/home'); +} elseif ($agent->isMobile()) { + echo view('mobile/home'); +} else { + echo view('web/home'); +} diff --git a/user_guide_src/source/libraries/user_agent/005.php b/user_guide_src/source/libraries/user_agent/005.php new file mode 100644 index 000000000000..944c70975971 --- /dev/null +++ b/user_guide_src/source/libraries/user_agent/005.php @@ -0,0 +1,5 @@ +isReferral()) { + echo $agent->referrer(); +} diff --git a/user_guide_src/source/libraries/validation.rst b/user_guide_src/source/libraries/validation.rst index 89eb4740179d..0f43f911a506 100644 --- a/user_guide_src/source/libraries/validation.rst +++ b/user_guide_src/source/libraries/validation.rst @@ -117,29 +117,9 @@ The Controller ================================================ Using a text editor, create a controller called **Form.php**. In it, place -this code and save it to your **app/Controllers/** folder:: +this code and save it to your **app/Controllers/** folder: - validate([])) { - echo view('Signup', [ - 'validation' => $this->validator, - ]); - } else { - echo view('Success'); - } - } - } +.. literalinclude:: validation/001.php Try it! ================================================ @@ -188,16 +168,10 @@ form or the success page. Add Validation Rules ================================================ -Then add validation rules in the controller (**Form.php**):: +Then add validation rules in the controller (**Form.php**): - if (! $this->validate([ - 'username' => 'required', - 'password' => 'required|min_length[10]', - 'passconf' => 'required|matches[password]', - 'email' => 'required|valid_email', - ])) { - ... - } +.. literalinclude:: validation/002.php + :lines: 2- If you submit the form you should see the success page or the form with error messages. @@ -228,21 +202,18 @@ The **Strict Rules** don't use implicit type conversion. Using Strict Rules ------------------ -If you want to use these rules, you need to change the rule classes in **app/Config/Validation.php**:: +If you want to use these rules, you need to change the rule classes in **app/Config/Validation.php**: - public $ruleSets = [ - \CodeIgniter\Validation\StrictRules\CreditCardRules::class, - \CodeIgniter\Validation\StrictRules\FileRules::class, - \CodeIgniter\Validation\StrictRules\FormatRules::class, - \CodeIgniter\Validation\StrictRules\Rules::class, - ]; +.. literalinclude:: validation/003.php + :lines: 2- Loading the Library ************************************************ -The library is loaded as a service named **validation**:: +The library is loaded as a service named **validation**: - $validation = \Config\Services::validation(); +.. literalinclude:: validation/004.php + :lines: 2- This automatically loads the ``Config\Validation`` file which contains settings for including multiple Rulesets, and collections of rules that can be easily reused. @@ -265,10 +236,10 @@ This method sets a single rule. It has the method signature:: setRule(string $field, ?string $label, array|string $rules[, array $errors = []]) -The ``$rules`` either takes in a pipe-delimited list of rules or an array collection of rules:: +The ``$rules`` either takes in a pipe-delimited list of rules or an array collection of rules: - $validation->setRule('username', 'Username', 'required|min_length[3]'); - $validation->setRule('password', 'Password', ['required', 'min_length[8]', 'alpha_numeric_punct']); +.. literalinclude:: validation/005.php + :lines: 2- The value you pass to ``$field`` must match the key of any data array that is sent in. If the data is taken directly from ``$_POST``, then it must be an exact match for @@ -282,19 +253,15 @@ the form input name. setRules() ========== -Like ``setRule()``, but accepts an array of field names and their rules:: +Like ``setRule()``, but accepts an array of field names and their rules: - $validation->setRules([ - 'username' => 'required', - 'password' => 'required|min_length[10]', - ]); +.. literalinclude:: validation/006.php + :lines: 2- -To give a labeled error message you can set up as:: +To give a labeled error message you can set up as: - $validation->setRules([ - 'username' => ['label' => 'Username', 'rules' => 'required'], - 'password' => ['label' => 'Password', 'rules' => 'required|min_length[10]'], - ]); +.. literalinclude:: validation/007.php + :lines: 2- withRequest() ============= @@ -302,9 +269,10 @@ withRequest() One of the most common times you will use the validation library is when validating data that was input from an HTTP Request. If desired, you can pass an instance of the current Request object and it will take all of the input data and set it as the -data to be validated:: +data to be validated: - $validation->withRequest($this->request)->run(); +.. literalinclude:: validation/008.php + :lines: 2- Working with Validation ************************************************ @@ -313,58 +281,29 @@ Validating Keys that are Arrays ================================================ If your data is in a nested associative array, you can use "dot array syntax" to -easily validate your data:: +easily validate your data: - // The data to test: - 'contacts' => [ - 'name' => 'Joe Smith', - 'friends' => [ - [ - 'name' => 'Fred Flinstone', - ], - [ - 'name' => 'Wilma', - ], - ] - ] +.. literalinclude:: validation/009.php + :lines: 2- - // Joe Smith - $validation->setRules([ - 'contacts.name' => 'required', - ]); - - // Fred Flintsone & Wilma - $validation->setRules([ - 'contacts.friends.name' => 'required', - ]); +You can use the '*' wildcard symbol to match any one level of the array: -You can use the '*' wildcard symbol to match any one level of the array:: - - // Fred Flintsone & Wilma - $validation->setRules([ - 'contacts.*.name' => 'required', - ]); +.. literalinclude:: validation/010.php + :lines: 2- "dot array syntax" can also be useful when you have single dimension array data. -For example, data returned by multi select dropdown:: +For example, data returned by multi select dropdown: - // The data to test: - 'user_ids' => [ - 1, - 2, - 3, - ] - // Rule - $validation->setRules([ - 'user_ids.*' => 'required', - ]); +.. literalinclude:: validation/011.php + :lines: 2- Validate 1 Value ================================================ -Validate one value against a rule:: +Validate one value against a rule: - $validation->check($value, 'required'); +.. literalinclude:: validation/012.php + :lines: 2- Saving Sets of Validation Rules to the Config File ======================================================= @@ -381,64 +320,27 @@ How to save your rules To store your validation rules, simply create a new public property in the ``Config\Validation`` class with the name of your group. This element will hold an array with your validation -rules. As shown earlier, the validation array will have this prototype:: +rules. As shown earlier, the validation array will have this prototype: - class Validation - { - public $signup = [ - 'username' => 'required', - 'password' => 'required', - 'pass_confirm' => 'required|matches[password]', - 'email' => 'required|valid_email', - ]; - } +.. literalinclude:: validation/013.php + :lines: 2- -You can specify the group to use when you call the ``run()`` method:: +You can specify the group to use when you call the ``run()`` method: - $validation->run($data, 'signup'); +.. literalinclude:: validation/014.php + :lines: 2- You can also store custom error messages in this configuration file by naming the property the same as the group, and appended with ``_errors``. These will automatically -be used for any errors when this group is used:: - - class Validation - { - public $signup = [ - 'username' => 'required', - 'password' => 'required', - 'pass_confirm' => 'required|matches[password]', - 'email' => 'required|valid_email', - ]; - - public $signup_errors = [ - 'username' => [ - 'required' => 'You must choose a username.', - ], - 'email' => [ - 'valid_email' => 'Please check the Email field. It does not appear to be valid.', - ], - ]; - } - -Or pass all settings in an array:: - - class Validation - { - public $signup = [ - 'username' => [ - 'rules' => 'required', - 'errors' => [ - 'required' => 'You must choose a Username.', - ], - ], - 'email' => [ - 'rules' => 'required|valid_email', - 'errors' => [ - 'valid_email' => 'Please check the Email field. It does not appear to be valid.', - ], - ], - ]; - } +be used for any errors when this group is used: + +.. literalinclude:: validation/015.php + :lines: 2- + +Or pass all settings in an array: + +.. literalinclude:: validation/016.php + :lines: 2- See below for details on the formatting of the array. @@ -447,15 +349,17 @@ Getting & Setting Rule Groups **Get Rule Group** -This method gets a rule group from the validation configuration:: +This method gets a rule group from the validation configuration: - $validation->getRuleGroup('signup'); +.. literalinclude:: validation/017.php + :lines: 2- **Set Rule Group** -This method sets a rule group from the validation configuration to the validation service:: +This method sets a rule group from the validation configuration to the validation service: - $validation->setRuleGroup('signup'); +.. literalinclude:: validation/018.php + :lines: 2- Running Multiple Validations ======================================================= @@ -467,16 +371,10 @@ Running Multiple Validations If you intend to run multiple validations, for instance on different data sets or with different rules after one another, you might need to call ``$validation->reset()`` before each run to get rid of errors from previous run. Be aware that ``reset()`` will invalidate any data, rule or custom error -you previously set, so ``setRules()``, ``setRuleGroup()`` etc. need to be repeated:: +you previously set, so ``setRules()``, ``setRuleGroup()`` etc. need to be repeated: - foreach ($userAccounts as $user) { - $validation->reset(); - $validation->setRules($userAccountRules); - - if (! $validation->run($user)) { - // handle validation errors - } - } +.. literalinclude:: validation/019.php + :lines: 2- Validation Placeholders ======================================================= @@ -484,25 +382,21 @@ Validation Placeholders The Validation class provides a simple method to replace parts of your rules based on data that's being passed into it. This sounds fairly obscure but can be especially handy with the ``is_unique`` validation rule. Placeholders are simply the name of the field (or array key) that was passed in as ``$data`` surrounded by curly brackets. It will be -replaced by the **value** of the matched incoming field. An example should clarify this:: +replaced by the **value** of the matched incoming field. An example should clarify this: - $validation->setRules([ - 'email' => 'required|valid_email|is_unique[users.email,id,{id}]', - ]); +.. literalinclude:: validation/020.php + :lines: 2- In this set of rules, it states that the email address should be unique in the database, except for the row -that has an id matching the placeholder's value. Assuming that the form POST data had the following:: +that has an id matching the placeholder's value. Assuming that the form POST data had the following: - $_POST = [ - 'id' => 4, - 'email' => 'foo@example.com', - ]; +.. literalinclude:: validation/021.php + :lines: 2- -then the ``{id}`` placeholder would be replaced with the number **4**, giving this revised rule:: +then the ``{id}`` placeholder would be replaced with the number **4**, giving this revised rule: - $validation->setRules([ - 'email' => 'required|valid_email|is_unique[users.email,id,4]', - ]); +.. literalinclude:: validation/022.php + :lines: 2- So it will ignore the row in the database that has ``id=4`` when it verifies the email is unique. @@ -530,46 +424,21 @@ instance. If not custom error message is provided, the default value will be use These are two ways to provide custom error messages. -As the last parameter:: +As the last parameter: - $validation->setRules([ - 'username' => 'required|is_unique[users.username]', - 'password' => 'required|min_length[10]' - ], - [ // Errors - 'username' => [ - 'required' => 'All accounts must have usernames provided', - ], - 'password' => [ - 'min_length' => 'Your password is too short. You want to get hacked?', - ], - ] - ); +.. literalinclude:: validation/023.php + :lines: 2- -Or as a labeled style:: +Or as a labeled style: - $validation->setRules([ - 'username' => [ - 'label' => 'Username', - 'rules' => 'required|is_unique[users.username]', - 'errors' => [ - 'required' => 'All accounts must have {field} provided', - ], - ], - 'password' => [ - 'label' => 'Password', - 'rules' => 'required|min_length[10]', - 'errors' => [ - 'min_length' => 'Your {field} is too short. You want to get hacked?', - ], - ] - ] - ); +.. literalinclude:: validation/024.php + :lines: 2- If you’d like to include a field’s “human” name, or the optional parameter some rules allow for (such as max_length), -or the value that was validated you can add the ``{field}``, ``{param}`` and ``{value}`` tags to your message, respectively:: +or the value that was validated you can add the ``{field}``, ``{param}`` and ``{value}`` tags to your message, respectively: - 'min_length' => 'Supplied value ({value}) for {field} must have at least {param} characters.' +.. literalinclude:: validation/025.php + :lines: 2- On a field with the human name Username and a rule of ``min_length[6]`` with a value of “Pizza”, an error would display: “Supplied value (Pizza) for Username must have at least 6 characters.” @@ -583,40 +452,20 @@ Translation Of Messages And Validation Labels To use translated strings from language files, we can simply use the dot syntax. Let's say we have a file with translations located here: ``app/Languages/en/Rules.php``. -We can simply use the language lines defined in this file, like this:: - - $validation->setRules([ - 'username' => [ - 'label' => 'Rules.username', - 'rules' => 'required|is_unique[users.username]', - 'errors' => [ - 'required' => 'Rules.username.required', - ], - ], - 'password' => [ - 'label' => 'Rules.password', - 'rules' => 'required|min_length[10]', - 'errors' => [ - 'min_length' => 'Rules.password.min_length', - ], - ], - ] - ); +We can simply use the language lines defined in this file, like this: + +.. literalinclude:: validation/026.php + :lines: 2- .. _validation-getting-all-errors: Getting All Errors ================== -If you need to retrieve all error messages for failed fields, you can use the ``getErrors()`` method:: - - $errors = $validation->getErrors(); +If you need to retrieve all error messages for failed fields, you can use the ``getErrors()`` method: - // Returns: - [ - 'field1' => 'error message', - 'field2' => 'error message', - ] +.. literalinclude:: validation/027.php + :lines: 2- If no errors exist, an empty array will be returned. @@ -644,9 +493,10 @@ Getting a Single Error ====================== You can retrieve the error for a single field with the ``getError()`` method. The only parameter is the field -name:: +name: - $error = $validation->getError('username'); +.. literalinclude:: validation/028.php + :lines: 2- If no error exists, an empty string will be returned. @@ -655,11 +505,10 @@ If no error exists, an empty string will be returned. Check If Error Exists ===================== -You can check to see if an error exists with the ``hasError()`` method. The only parameter is the field name:: +You can check to see if an error exists with the ``hasError()`` method. The only parameter is the field name: - if ($validation->hasError('username')) { - echo $validation->getError('username'); - } +.. literalinclude:: validation/029.php + :lines: 2- When specifying a field with a wildcard, all errors matching the mask will be checked.:: @@ -683,23 +532,15 @@ Creating the Views The first step is to create custom views. These can be placed anywhere that the ``view()`` method can locate them, which means the standard View directory, or any namespaced View folder will work. For example, you could create -a new view at **/app/Views/_errors_list.php**:: +a new view at **/app/Views/_errors_list.php**: - +.. literalinclude:: validation/029-2.php An array named ``$errors`` is available within the view that contains a list of the errors, where the key is -the name of the field that had the error, and the value is the error message, like this:: +the name of the field that had the error, and the value is the error message, like this: - $errors = [ - 'username' => 'The username field must be unique.', - 'email' => 'You must provide a valid email address.' - ]; +.. literalinclude:: validation/030.php + :lines: 2- There are actually two types of views that you can create. The first has an array of all of the errors, and is what we just looked at. The other type is simpler, and only contains a single variable, ``$error`` that contains the @@ -712,13 +553,10 @@ Configuration Once you have your views created, you need to let the Validation library know about them. Open ``Config/Validation.php``. Inside, you'll find the ``$templates`` property where you can list as many custom views as you want, and provide an -short alias they can be referenced by. If we were to add our example file from above, it would look something like:: +short alias they can be referenced by. If we were to add our example file from above, it would look something like: - public $templates = [ - 'list' => 'CodeIgniter\Validation\Views\list', - 'single' => 'CodeIgniter\Validation\Views\single', - 'my_list' => '_errors_list', - ]; +.. literalinclude:: validation/031.php + :lines: 2- Specifying the Template ======================= @@ -737,94 +575,41 @@ Creating Custom Rules Rules are stored within simple, namespaced classes. They can be stored any location you would like, as long as the autoloader can find it. These files are called RuleSets. To add a new RuleSet, edit **Config/Validation.php** and -add the new file to the ``$ruleSets`` array:: - - use CodeIgniter\Validation\CreditCardRules; - use CodeIgniter\Validation\FileRules; - use CodeIgniter\Validation\FormatRules; - use CodeIgniter\Validation\Rules; +add the new file to the ``$ruleSets`` array: - public $ruleSets = [ - Rules::class, - FormatRules::class, - FileRules::class, - CreditCardRules::class, - ]; +.. literalinclude:: validation/032.php + :lines: 2- You can add it as either a simple string with the fully qualified class name, or using the ``::class`` suffix as shown above. The primary benefit here is that it provides some extra navigation capabilities in more advanced IDEs. Within the file itself, each method is a rule and must accept a string as the first parameter, and must return -a boolean true or false value signifying true if it passed the test or false if it did not:: +a boolean true or false value signifying true if it passed the test or false if it did not: - class MyRules - { - public function even(string $str): bool - { - return (int) $str % 2 == 0; - } - } +.. literalinclude:: validation/033.php + :lines: 2- By default, the system will look within ``CodeIgniter\Language\en\Validation.php`` for the language strings used within errors. In custom rules, you may provide error messages by accepting a ``$error`` variable by reference in the -second parameter:: +second parameter: - public function even(string $str, string &$error = null): bool - { - if ((int) $str % 2 !== 0) { - $error = lang('myerrors.evenError'); +.. literalinclude:: validation/034.php + :lines: 2- - return false; - } +Your new custom rule could now be used just like any other rule: - return true; - } - -Your new custom rule could now be used just like any other rule:: - - $this->validate($request, [ - 'foo' => 'required|even', - ]); +.. literalinclude:: validation/035.php + :lines: 2- Allowing Parameters =================== If your method needs to work with parameters, the function will need a minimum of three parameters: the string to validate, the parameter string, and an array with all of the data that was submitted the form. The ``$data`` array is especially handy -for rules like ``require_with`` that needs to check the value of another submitted field to base its result on:: - - public function required_with($str, string $fields, array $data): bool - { - $fields = explode(',', $fields); - - // If the field is present we can safely assume that - // the field is here, no matter whether the corresponding - // search field is present or not. - $present = $this->required($str ?? ''); +for rules like ``require_with`` that needs to check the value of another submitted field to base its result on: - if ($present) { - return true; - } - - // Still here? Then we fail this test if - // any of the fields are present in $data - // as $fields is the lis - $requiredFields = []; - - foreach ($fields as $field) { - if (array_key_exists($field, $data)) { - $requiredFields[] = $field; - } - } - - // Remove any keys with empty values since, that means they - // weren't truly there, as far as this is concerned. - $requiredFields = array_filter($requiredFields, function ($item) use ($data) { - return ! empty($data[$item]); - }); - - return empty($requiredFields); - } +.. literalinclude:: validation/036.php + :lines: 2- Custom errors can be returned as the fourth parameter, just as described above. @@ -836,16 +621,8 @@ The following is a list of all the native rules that are available to use: .. note:: Rule is a string; there must be **no spaces** between the parameters, especially the ``is_unique`` rule. There can be no spaces before and after ``ignore_value``. -:: - - // is_unique[table.field,ignore_field,ignore_value] - - $validation->setRules([ - 'name' => "is_unique[supplier.name,uuid, $uuid]", // is not ok - 'name' => "is_unique[supplier.name,uuid,$uuid ]", // is not ok - 'name' => "is_unique[supplier.name,uuid,$uuid]", // is ok - 'name' => "is_unique[supplier.name,uuid,{uuid}]", // is ok - see "Validation Placeholders" - ]); +.. literalinclude:: validation/037.php + :lines: 2- ======================= ========== ============================================= =================================================== Rule Parameter Description Example diff --git a/user_guide_src/source/libraries/validation/001.php b/user_guide_src/source/libraries/validation/001.php new file mode 100644 index 000000000000..e52362c46cea --- /dev/null +++ b/user_guide_src/source/libraries/validation/001.php @@ -0,0 +1,21 @@ +validate([])) { + echo view('Signup', [ + 'validation' => $this->validator, + ]); + } else { + echo view('Success'); + } + } +} diff --git a/user_guide_src/source/libraries/validation/002.php b/user_guide_src/source/libraries/validation/002.php new file mode 100644 index 000000000000..46322fe586bd --- /dev/null +++ b/user_guide_src/source/libraries/validation/002.php @@ -0,0 +1,10 @@ +validate([ + 'username' => 'required', + 'password' => 'required|min_length[10]', + 'passconf' => 'required|matches[password]', + 'email' => 'required|valid_email', +])) { + ... +} diff --git a/user_guide_src/source/libraries/validation/003.php b/user_guide_src/source/libraries/validation/003.php new file mode 100644 index 000000000000..a6ae3a4a6fff --- /dev/null +++ b/user_guide_src/source/libraries/validation/003.php @@ -0,0 +1,8 @@ +setRule('username', 'Username', 'required|min_length[3]'); +$validation->setRule('password', 'Password', ['required', 'min_length[8]', 'alpha_numeric_punct']); diff --git a/user_guide_src/source/libraries/validation/006.php b/user_guide_src/source/libraries/validation/006.php new file mode 100644 index 000000000000..24a771f70e31 --- /dev/null +++ b/user_guide_src/source/libraries/validation/006.php @@ -0,0 +1,6 @@ +setRules([ + 'username' => 'required', + 'password' => 'required|min_length[10]', +]); diff --git a/user_guide_src/source/libraries/validation/007.php b/user_guide_src/source/libraries/validation/007.php new file mode 100644 index 000000000000..b211d9c1cec5 --- /dev/null +++ b/user_guide_src/source/libraries/validation/007.php @@ -0,0 +1,6 @@ +setRules([ + 'username' => ['label' => 'Username', 'rules' => 'required'], + 'password' => ['label' => 'Password', 'rules' => 'required|min_length[10]'], +]); diff --git a/user_guide_src/source/libraries/validation/008.php b/user_guide_src/source/libraries/validation/008.php new file mode 100644 index 000000000000..1b570f1aad82 --- /dev/null +++ b/user_guide_src/source/libraries/validation/008.php @@ -0,0 +1,3 @@ +withRequest($this->request)->run(); diff --git a/user_guide_src/source/libraries/validation/009.php b/user_guide_src/source/libraries/validation/009.php new file mode 100644 index 000000000000..1678d5530f27 --- /dev/null +++ b/user_guide_src/source/libraries/validation/009.php @@ -0,0 +1,24 @@ + [ + 'name' => 'Joe Smith', + 'friends' => [ + [ + 'name' => 'Fred Flinstone', + ], + [ + 'name' => 'Wilma', + ], + ] +] + +// Joe Smith +$validation->setRules([ + 'contacts.name' => 'required', +]); + +// Fred Flintsone & Wilma +$validation->setRules([ + 'contacts.friends.name' => 'required', +]); diff --git a/user_guide_src/source/libraries/validation/010.php b/user_guide_src/source/libraries/validation/010.php new file mode 100644 index 000000000000..94c6919311d5 --- /dev/null +++ b/user_guide_src/source/libraries/validation/010.php @@ -0,0 +1,6 @@ +setRules([ + 'contacts.*.name' => 'required', +]); diff --git a/user_guide_src/source/libraries/validation/011.php b/user_guide_src/source/libraries/validation/011.php new file mode 100644 index 000000000000..023712f4315e --- /dev/null +++ b/user_guide_src/source/libraries/validation/011.php @@ -0,0 +1,12 @@ + [ + 1, + 2, + 3, +] +// Rule +$validation->setRules([ + 'user_ids.*' => 'required', +]); diff --git a/user_guide_src/source/libraries/validation/012.php b/user_guide_src/source/libraries/validation/012.php new file mode 100644 index 000000000000..a43f9ab1a498 --- /dev/null +++ b/user_guide_src/source/libraries/validation/012.php @@ -0,0 +1,3 @@ +check($value, 'required'); diff --git a/user_guide_src/source/libraries/validation/013.php b/user_guide_src/source/libraries/validation/013.php new file mode 100644 index 000000000000..f90dfc0ba5fc --- /dev/null +++ b/user_guide_src/source/libraries/validation/013.php @@ -0,0 +1,11 @@ + 'required', + 'password' => 'required', + 'pass_confirm' => 'required|matches[password]', + 'email' => 'required|valid_email', + ]; +} diff --git a/user_guide_src/source/libraries/validation/014.php b/user_guide_src/source/libraries/validation/014.php new file mode 100644 index 000000000000..1aa5b7f521c0 --- /dev/null +++ b/user_guide_src/source/libraries/validation/014.php @@ -0,0 +1,3 @@ +run($data, 'signup'); diff --git a/user_guide_src/source/libraries/validation/015.php b/user_guide_src/source/libraries/validation/015.php new file mode 100644 index 000000000000..31cf681b92a7 --- /dev/null +++ b/user_guide_src/source/libraries/validation/015.php @@ -0,0 +1,20 @@ + 'required', + 'password' => 'required', + 'pass_confirm' => 'required|matches[password]', + 'email' => 'required|valid_email', + ]; + + public $signup_errors = [ + 'username' => [ + 'required' => 'You must choose a username.', + ], + 'email' => [ + 'valid_email' => 'Please check the Email field. It does not appear to be valid.', + ], + ]; +} diff --git a/user_guide_src/source/libraries/validation/016.php b/user_guide_src/source/libraries/validation/016.php new file mode 100644 index 000000000000..55d9f6985cf9 --- /dev/null +++ b/user_guide_src/source/libraries/validation/016.php @@ -0,0 +1,19 @@ + [ + 'rules' => 'required', + 'errors' => [ + 'required' => 'You must choose a Username.', + ], + ], + 'email' => [ + 'rules' => 'required|valid_email', + 'errors' => [ + 'valid_email' => 'Please check the Email field. It does not appear to be valid.', + ], + ], + ]; +} diff --git a/user_guide_src/source/libraries/validation/017.php b/user_guide_src/source/libraries/validation/017.php new file mode 100644 index 000000000000..f84561eb5375 --- /dev/null +++ b/user_guide_src/source/libraries/validation/017.php @@ -0,0 +1,3 @@ +getRuleGroup('signup'); diff --git a/user_guide_src/source/libraries/validation/018.php b/user_guide_src/source/libraries/validation/018.php new file mode 100644 index 000000000000..245c4b6932cf --- /dev/null +++ b/user_guide_src/source/libraries/validation/018.php @@ -0,0 +1,3 @@ +setRuleGroup('signup'); diff --git a/user_guide_src/source/libraries/validation/019.php b/user_guide_src/source/libraries/validation/019.php new file mode 100644 index 000000000000..bf158323f638 --- /dev/null +++ b/user_guide_src/source/libraries/validation/019.php @@ -0,0 +1,10 @@ +reset(); + $validation->setRules($userAccountRules); + + if (! $validation->run($user)) { + // handle validation errors + } +} diff --git a/user_guide_src/source/libraries/validation/020.php b/user_guide_src/source/libraries/validation/020.php new file mode 100644 index 000000000000..d9ab8f75fcdc --- /dev/null +++ b/user_guide_src/source/libraries/validation/020.php @@ -0,0 +1,5 @@ +setRules([ + 'email' => 'required|valid_email|is_unique[users.email,id,{id}]', +]); diff --git a/user_guide_src/source/libraries/validation/021.php b/user_guide_src/source/libraries/validation/021.php new file mode 100644 index 000000000000..ab70fa937a5d --- /dev/null +++ b/user_guide_src/source/libraries/validation/021.php @@ -0,0 +1,6 @@ + 4, + 'email' => 'foo@example.com', +]; diff --git a/user_guide_src/source/libraries/validation/022.php b/user_guide_src/source/libraries/validation/022.php new file mode 100644 index 000000000000..9c0f3ab7410d --- /dev/null +++ b/user_guide_src/source/libraries/validation/022.php @@ -0,0 +1,5 @@ +setRules([ + 'email' => 'required|valid_email|is_unique[users.email,id,4]', +]); diff --git a/user_guide_src/source/libraries/validation/023.php b/user_guide_src/source/libraries/validation/023.php new file mode 100644 index 000000000000..5d0618b338ee --- /dev/null +++ b/user_guide_src/source/libraries/validation/023.php @@ -0,0 +1,15 @@ +setRules([ + 'username' => 'required|is_unique[users.username]', + 'password' => 'required|min_length[10]' + ], + [ // Errors + 'username' => [ + 'required' => 'All accounts must have usernames provided', + ], + 'password' => [ + 'min_length' => 'Your password is too short. You want to get hacked?', + ], + ] +); diff --git a/user_guide_src/source/libraries/validation/024.php b/user_guide_src/source/libraries/validation/024.php new file mode 100644 index 000000000000..b6b7c7464a5d --- /dev/null +++ b/user_guide_src/source/libraries/validation/024.php @@ -0,0 +1,19 @@ +setRules([ + 'username' => [ + 'label' => 'Username', + 'rules' => 'required|is_unique[users.username]', + 'errors' => [ + 'required' => 'All accounts must have {field} provided', + ], + ], + 'password' => [ + 'label' => 'Password', + 'rules' => 'required|min_length[10]', + 'errors' => [ + 'min_length' => 'Your {field} is too short. You want to get hacked?', + ], + ] + ] +); diff --git a/user_guide_src/source/libraries/validation/025.php b/user_guide_src/source/libraries/validation/025.php new file mode 100644 index 000000000000..0531b84be47c --- /dev/null +++ b/user_guide_src/source/libraries/validation/025.php @@ -0,0 +1,3 @@ + 'Supplied value ({value}) for {field} must have at least {param} characters.' diff --git a/user_guide_src/source/libraries/validation/026.php b/user_guide_src/source/libraries/validation/026.php new file mode 100644 index 000000000000..50bd0147aaf2 --- /dev/null +++ b/user_guide_src/source/libraries/validation/026.php @@ -0,0 +1,19 @@ +setRules([ + 'username' => [ + 'label' => 'Rules.username', + 'rules' => 'required|is_unique[users.username]', + 'errors' => [ + 'required' => 'Rules.username.required', + ], + ], + 'password' => [ + 'label' => 'Rules.password', + 'rules' => 'required|min_length[10]', + 'errors' => [ + 'min_length' => 'Rules.password.min_length', + ], + ], + ] +); diff --git a/user_guide_src/source/libraries/validation/027.php b/user_guide_src/source/libraries/validation/027.php new file mode 100644 index 000000000000..57aa5a31cb84 --- /dev/null +++ b/user_guide_src/source/libraries/validation/027.php @@ -0,0 +1,9 @@ +getErrors(); + +// Returns: +[ + 'field1' => 'error message', + 'field2' => 'error message', +] diff --git a/user_guide_src/source/libraries/validation/028.php b/user_guide_src/source/libraries/validation/028.php new file mode 100644 index 000000000000..2a3cffba88fc --- /dev/null +++ b/user_guide_src/source/libraries/validation/028.php @@ -0,0 +1,3 @@ +getError('username'); diff --git a/user_guide_src/source/libraries/validation/029-2.php b/user_guide_src/source/libraries/validation/029-2.php new file mode 100644 index 000000000000..f7c69eb42e99 --- /dev/null +++ b/user_guide_src/source/libraries/validation/029-2.php @@ -0,0 +1,7 @@ + diff --git a/user_guide_src/source/libraries/validation/029.php b/user_guide_src/source/libraries/validation/029.php new file mode 100644 index 000000000000..2334c3c00f50 --- /dev/null +++ b/user_guide_src/source/libraries/validation/029.php @@ -0,0 +1,5 @@ +hasError('username')) { + echo $validation->getError('username'); +} diff --git a/user_guide_src/source/libraries/validation/030.php b/user_guide_src/source/libraries/validation/030.php new file mode 100644 index 000000000000..0da86ca2d054 --- /dev/null +++ b/user_guide_src/source/libraries/validation/030.php @@ -0,0 +1,6 @@ + 'The username field must be unique.', + 'email' => 'You must provide a valid email address.' +]; diff --git a/user_guide_src/source/libraries/validation/031.php b/user_guide_src/source/libraries/validation/031.php new file mode 100644 index 000000000000..110b159a41cc --- /dev/null +++ b/user_guide_src/source/libraries/validation/031.php @@ -0,0 +1,7 @@ + 'CodeIgniter\Validation\Views\list', + 'single' => 'CodeIgniter\Validation\Views\single', + 'my_list' => '_errors_list', +]; diff --git a/user_guide_src/source/libraries/validation/032.php b/user_guide_src/source/libraries/validation/032.php new file mode 100644 index 000000000000..ccee27b08ad7 --- /dev/null +++ b/user_guide_src/source/libraries/validation/032.php @@ -0,0 +1,13 @@ +validate($request, [ + 'foo' => 'required|even', +]); diff --git a/user_guide_src/source/libraries/validation/036.php b/user_guide_src/source/libraries/validation/036.php new file mode 100644 index 000000000000..9511380c04f5 --- /dev/null +++ b/user_guide_src/source/libraries/validation/036.php @@ -0,0 +1,34 @@ +required($str ?? ''); + + if ($present) { + return true; + } + + // Still here? Then we fail this test if + // any of the fields are present in $data + // as $fields is the lis + $requiredFields = []; + + foreach ($fields as $field) { + if (array_key_exists($field, $data)) { + $requiredFields[] = $field; + } + } + + // Remove any keys with empty values since, that means they + // weren't truly there, as far as this is concerned. + $requiredFields = array_filter($requiredFields, function ($item) use ($data) { + return ! empty($data[$item]); + }); + + return empty($requiredFields); +} diff --git a/user_guide_src/source/libraries/validation/037.php b/user_guide_src/source/libraries/validation/037.php new file mode 100644 index 000000000000..089b0eeaf465 --- /dev/null +++ b/user_guide_src/source/libraries/validation/037.php @@ -0,0 +1,10 @@ +setRules([ + 'name' => "is_unique[supplier.name,uuid, $uuid]", // is not ok + 'name' => "is_unique[supplier.name,uuid,$uuid ]", // is not ok + 'name' => "is_unique[supplier.name,uuid,$uuid]", // is ok + 'name' => "is_unique[supplier.name,uuid,{uuid}]", // is ok - see "Validation Placeholders" +]); diff --git a/user_guide_src/source/models/entities.rst b/user_guide_src/source/models/entities.rst index dda716209451..3a9d9b705bc2 100644 --- a/user_guide_src/source/models/entities.rst +++ b/user_guide_src/source/models/entities.rst @@ -38,41 +38,16 @@ Now create a new Entity class. Since there's no default location to store these in with the existing directory structure, create a new directory at **app/Entities**. Create the Entity itself at **app/Entities/User.php**. -:: - - find($id); - - // Display - echo $user->username; - echo $user->email; +Now that all of the pieces are in place, you would work with the Entity class as you would any other class: - // Updating - unset($user->username); - - if (! isset($user->username) { - $user->username = 'something new'; - } - - $userModel->save($user); - - // Create - $user = new \App\Entities\User(); - $user->username = 'foo'; - $user->email = 'foo@example.com'; - $userModel->save($user); +.. literalinclude:: entities/003.php + :lines: 2- You may have noticed that the ``User`` class has not set any properties for the columns, but you can still access them as if they were public properties. The base class, ``CodeIgniter\Entity\Entity``, takes care of this for you, as @@ -128,22 +85,13 @@ and populate the class properties. Any property in the array will be set on the the model, only the fields in ``$allowedFields`` will actually be saved to the database, so you can store additional data on your entities without worrying much about stray fields getting saved incorrectly. -:: - - $data = $this->request->getPost(); - - $user = new \App\Entities\User(); - $user->fill($data); - $userModel->save($user); +.. literalinclude:: entities/004.php + :lines: 2- You can also pass the data in the constructor and the data will be passed through the ``fill()`` method during instantiation. -:: - - $data = $this->request->getPost(); - - $user = new \App\Entities\User($data); - $userModel->save($user); +.. literalinclude:: entities/005.php + :lines: 2- Bulk Accessing Properties ------------------------- @@ -160,43 +108,9 @@ While the examples above are convenient, they don't help enforce any business lo some smart ``__get()`` and ``__set()`` methods that will check for special methods and use those instead of using the attributes directly, allowing you to enforce any business logic or data conversion that you need. -Here's an updated User entity to provide some examples of how this could be used:: - - attributes['password'] = password_hash($pass, PASSWORD_BCRYPT); - - return $this; - } - - public function setCreatedAt(string $dateString) - { - $this->attributes['created_at'] = new Time($dateString, 'UTC'); - - return $this; - } - - public function getCreatedAt(string $format = 'Y-m-d H:i:s') - { - // Convert to CodeIgniter\I18n\Time object - $this->attributes['created_at'] = $this->mutateDate($this->attributes['created_at']); - - $timezone = $this->timezone ?? app_timezone(); - - $this->attributes['created_at']->setTimezone($timezone); - - return $this->attributes['created_at']->format($format); - } - } +.. literalinclude:: entities/006.php The first thing to notice is the name of the methods we've added. For each one, the class expects the snake_case column name to be converted into PascalCase, and prefixed with either ``set`` or ``get``. These methods will then @@ -216,11 +130,8 @@ a formatted string in the application's current timezone. While fairly simple, these examples show that using Entity classes can provide a very flexible way to enforce business logic and create objects that are pleasant to use. -:: - - // Auto-hash the password - both do the same thing - $user->password = 'my great password'; - $user->setPassword('my great password'); +.. literalinclude:: entities/007.php + :lines: 2- Data Mapping ============ @@ -230,25 +141,9 @@ original column names in the database no longer make sense. Or you find that you class properties, but your database schema required snake_case names. These situations can be easily handled with the Entity class' data mapping features. -As an example, imagine you have the simplified User Entity that is used throughout your application:: - - null, - 'name' => null, // Represents a username - 'email' => null, - 'password' => null, - 'created_at' => null, - 'updated_at' => null, - ]; - } +.. literalinclude:: entities/008.php Your boss comes to you and says that no one uses usernames anymore, so you're switching to just use emails for login. But they do want to personalize the application a bit, so they want you to change the name field to represent a user's @@ -257,29 +152,9 @@ in the database you whip up a migration to rename the `name` field to `full_name Ignoring how contrived this example is, we now have two choices on how to fix the User class. We could modify the class property from ``$name`` to ``$full_name``, but that would require changes throughout the application. Instead, we can -simply map the ``full_name`` column in the database to the ``$name`` property, and be done with the Entity changes:: - - null, - 'full_name' => null, // In the $attributes, the key is the column name - 'email' => null, - 'password' => null, - 'created_at' => null, - 'updated_at' => null, - ]; +simply map the ``full_name`` column in the database to the ``$name`` property, and be done with the Entity changes: - protected $datamap = [ - 'name' => 'full_name', - ]; - } +.. literalinclude:: entities/009.php By adding our new database name to the ``$datamap`` array, we can tell the class what class property the database column should be accessible through. The key of the array is class property to map it to, where the value in the array is the @@ -301,30 +176,15 @@ By default, the Entity class will convert fields named `created_at`, `updated_at :doc:`Time ` instances whenever they are set or retrieved. The Time class provides a large number of helpful methods in an immutable, localized way. -You can define which properties are automatically converted by adding the name to the ``$dates`` property:: +You can define which properties are automatically converted by adding the name to the ``$dates`` property: - created_at = 'April 15, 2017 10:30:00'; +current timezone, as set in **app/Config/App.php**: - // Can now use any Time methods: - echo $user->created_at->humanize(); - echo $user->created_at->setTimezone('Europe/London')->toDateString(); +.. literalinclude:: entities/011.php + :lines: 2- Property Casting ---------------- @@ -336,21 +196,9 @@ either the entity or the database. Properties can be cast to any of the followin **integer**, **float**, **double**, **string**, **boolean**, **object**, **array**, **datetime**, **timestamp**, and **uri**. Add a question mark at the beginning of type to mark property as nullable, i.e., **?string**, **?integer**. -For example, if you had a User entity with an ``is_banned`` property, you can cast it as a boolean:: +For example, if you had a User entity with an ``is_banned`` property, you can cast it as a boolean: - 'boolean', - 'is_banned_nullable' => '?boolean', - ]; - } +.. literalinclude:: entities/012.php Array/Json Casting ------------------ @@ -367,32 +215,12 @@ Unlike the rest of the data types that you can cast properties into, the: * **array** cast type will serialize, * **json** and **json-array** cast will use json_encode function on -the value whenever the property is set:: - - 'array', - 'options_object' => 'json', - 'options_array' => 'json-array', - ]; - } - -:: - - $user = $userModel->find(15); - $options = $user->options; - - $options['foo'] = 'bar'; - - $user->options = $options; - $userModel->save($user); +.. literalinclude:: entities/014.php + :lines: 2- CSV Casting ----------- @@ -400,24 +228,14 @@ CSV Casting If you know you have a flat array of simple values, encoding them as a serialized or JSON string may be more complex than the original structure. Casting as Comma-Separated Values (CSV) is a simpler alternative will result in a string that uses less space and is more easily read -by humans:: - - 'csv', - ]; - } +.. literalinclude:: entities/015.php -Stored in the database as "red,yellow,green":: +Stored in the database as "red,yellow,green": - $widget->colors = ['red', 'yellow', 'green']; +.. literalinclude:: entities/016.php + :lines: 2- .. note:: Casting as CSV uses PHP's internal ``implode`` and ``explode`` methods and assumes all values are string-safe and free of commas. For more complex data casts try ``array`` or ``json``. @@ -427,67 +245,18 @@ Custom casting You can define your own conversion types for getting and setting data. At first you need to create a handler class for your type. -Let's say the class will be located in the **app/Entities/Cast** directory:: +Let's say the class will be located in the **app/Entities/Cast** directory: - 'base64', - ]; - - // Bind the type to the handler - protected $castHandlers = [ - 'base64' => \App\Entities\Cast\CastBase64::class, - ]; - } - - // ... - - $entity->key = 'test'; // dGVzdA== - echo $entity->key; // test - - -If you don't need to change values when getting or setting a value. Then just don't implement the appropriate method:: - - use CodeIgniter\Entity\Cast\BaseCast; - - class CastBase64 extends BaseCast - { - public static function get($value, array $params = []) - { - return base64_decode($value); - } - } +If you don't need to change values when getting or setting a value. Then just don't implement the appropriate method: +.. literalinclude:: entities/019.php + :lines: 2- **Parameters** @@ -496,55 +265,26 @@ Additional parameters are indicated in square brackets and listed with a comma. **type[param1, param2]** -:: - - // Defining a type with parameters - protected $casts = [ - 'some_attribute' => 'class[App\SomeClass, param2, param3]', - ]; - - // Bind the type to the handler - protected $castHandlers = [ - 'class' => 'SomeHandler', - ]; - -:: - - use CodeIgniter\Entity\Cast\BaseCast; - - class SomeHandler extends BaseCast - { - public static function get($value, array $params = []) - { - var_dump($params); - // array(3) { - // [0]=> - // string(13) "App\SomeClass" - // [1]=> - // string(6) "param2" - // [2]=> - // string(6) "param3" - // } - } - } +.. literalinclude:: entities/020.php + :lines: 2- + +.. literalinclude:: entities/021.php + :lines: 2- .. note:: If the casting type is marked as nullable ``?bool`` and the passed value is not null, then the parameter with the value ``nullable`` will be passed to the casting type handler. If casting type has predefined parameters, then ``nullable`` will be added to the end of the list. - Checking for Changed Attributes =============================== You can check if an Entity attribute has changed since it was created. The only parameter is the name of the -attribute to check:: - - $user = new \App\Entities\User(); - $user->hasChanged('name'); // false +attribute to check: - $user->name = 'Fred'; - $user->hasChanged('name'); // true +.. literalinclude:: entities/022.php + :lines: 2- -Or to check the whole entity for changed values omit the parameter:: +Or to check the whole entity for changed values omit the parameter: - $user->hasChanged(); // true +.. literalinclude:: entities/023.php + :lines: 2- diff --git a/user_guide_src/source/models/entities/001.php b/user_guide_src/source/models/entities/001.php new file mode 100644 index 000000000000..2da022b25edd --- /dev/null +++ b/user_guide_src/source/models/entities/001.php @@ -0,0 +1,10 @@ +find($id); + +// Display +echo $user->username; +echo $user->email; + +// Updating +unset($user->username); + +if (! isset($user->username) { + $user->username = 'something new'; +} + +$userModel->save($user); + +// Create +$user = new \App\Entities\User(); +$user->username = 'foo'; +$user->email = 'foo@example.com'; +$userModel->save($user); diff --git a/user_guide_src/source/models/entities/004.php b/user_guide_src/source/models/entities/004.php new file mode 100644 index 000000000000..e5307d38b1a2 --- /dev/null +++ b/user_guide_src/source/models/entities/004.php @@ -0,0 +1,7 @@ +request->getPost(); + +$user = new \App\Entities\User(); +$user->fill($data); +$userModel->save($user); diff --git a/user_guide_src/source/models/entities/005.php b/user_guide_src/source/models/entities/005.php new file mode 100644 index 000000000000..5dd5d47af1f5 --- /dev/null +++ b/user_guide_src/source/models/entities/005.php @@ -0,0 +1,6 @@ +request->getPost(); + +$user = new \App\Entities\User($data); +$userModel->save($user); diff --git a/user_guide_src/source/models/entities/006.php b/user_guide_src/source/models/entities/006.php new file mode 100644 index 000000000000..0a271a37a73d --- /dev/null +++ b/user_guide_src/source/models/entities/006.php @@ -0,0 +1,35 @@ +attributes['password'] = password_hash($pass, PASSWORD_BCRYPT); + + return $this; + } + + public function setCreatedAt(string $dateString) + { + $this->attributes['created_at'] = new Time($dateString, 'UTC'); + + return $this; + } + + public function getCreatedAt(string $format = 'Y-m-d H:i:s') + { + // Convert to CodeIgniter\I18n\Time object + $this->attributes['created_at'] = $this->mutateDate($this->attributes['created_at']); + + $timezone = $this->timezone ?? app_timezone(); + + $this->attributes['created_at']->setTimezone($timezone); + + return $this->attributes['created_at']->format($format); + } +} diff --git a/user_guide_src/source/models/entities/007.php b/user_guide_src/source/models/entities/007.php new file mode 100644 index 000000000000..36a39a017e43 --- /dev/null +++ b/user_guide_src/source/models/entities/007.php @@ -0,0 +1,5 @@ +password = 'my great password'; +$user->setPassword('my great password'); diff --git a/user_guide_src/source/models/entities/008.php b/user_guide_src/source/models/entities/008.php new file mode 100644 index 000000000000..f0612ce0e4b9 --- /dev/null +++ b/user_guide_src/source/models/entities/008.php @@ -0,0 +1,17 @@ + null, + 'name' => null, // Represents a username + 'email' => null, + 'password' => null, + 'created_at' => null, + 'updated_at' => null, + ]; +} diff --git a/user_guide_src/source/models/entities/009.php b/user_guide_src/source/models/entities/009.php new file mode 100644 index 000000000000..411961833749 --- /dev/null +++ b/user_guide_src/source/models/entities/009.php @@ -0,0 +1,21 @@ + null, + 'full_name' => null, // In the $attributes, the key is the column name + 'email' => null, + 'password' => null, + 'created_at' => null, + 'updated_at' => null, + ]; + + protected $datamap = [ + 'name' => 'full_name', + ]; +} diff --git a/user_guide_src/source/models/entities/010.php b/user_guide_src/source/models/entities/010.php new file mode 100644 index 000000000000..e8636fa0fbcc --- /dev/null +++ b/user_guide_src/source/models/entities/010.php @@ -0,0 +1,10 @@ +created_at = 'April 15, 2017 10:30:00'; + +// Can now use any Time methods: +echo $user->created_at->humanize(); +echo $user->created_at->setTimezone('Europe/London')->toDateString(); diff --git a/user_guide_src/source/models/entities/012.php b/user_guide_src/source/models/entities/012.php new file mode 100644 index 000000000000..0c14d2f822c6 --- /dev/null +++ b/user_guide_src/source/models/entities/012.php @@ -0,0 +1,13 @@ + 'boolean', + 'is_banned_nullable' => '?boolean', + ]; +} diff --git a/user_guide_src/source/models/entities/013.php b/user_guide_src/source/models/entities/013.php new file mode 100644 index 000000000000..460f42435304 --- /dev/null +++ b/user_guide_src/source/models/entities/013.php @@ -0,0 +1,14 @@ + 'array', + 'options_object' => 'json', + 'options_array' => 'json-array', + ]; +} diff --git a/user_guide_src/source/models/entities/014.php b/user_guide_src/source/models/entities/014.php new file mode 100644 index 000000000000..0a6523818e5c --- /dev/null +++ b/user_guide_src/source/models/entities/014.php @@ -0,0 +1,9 @@ +find(15); +$options = $user->options; + +$options['foo'] = 'bar'; + +$user->options = $options; +$userModel->save($user); diff --git a/user_guide_src/source/models/entities/015.php b/user_guide_src/source/models/entities/015.php new file mode 100644 index 000000000000..079797096bec --- /dev/null +++ b/user_guide_src/source/models/entities/015.php @@ -0,0 +1,12 @@ + 'csv', + ]; +} diff --git a/user_guide_src/source/models/entities/016.php b/user_guide_src/source/models/entities/016.php new file mode 100644 index 000000000000..739ab9f3237a --- /dev/null +++ b/user_guide_src/source/models/entities/016.php @@ -0,0 +1,3 @@ +colors = ['red', 'yellow', 'green']; diff --git a/user_guide_src/source/models/entities/017.php b/user_guide_src/source/models/entities/017.php new file mode 100644 index 000000000000..422a28cd1c37 --- /dev/null +++ b/user_guide_src/source/models/entities/017.php @@ -0,0 +1,19 @@ + 'base64', + ]; + + // Bind the type to the handler + protected $castHandlers = [ + 'base64' => \App\Entities\Cast\CastBase64::class, + ]; +} + +// ... + +$entity->key = 'test'; // dGVzdA== +echo $entity->key; // test diff --git a/user_guide_src/source/models/entities/019.php b/user_guide_src/source/models/entities/019.php new file mode 100644 index 000000000000..7d3744cc037c --- /dev/null +++ b/user_guide_src/source/models/entities/019.php @@ -0,0 +1,11 @@ + 'class[App\SomeClass, param2, param3]', +]; + +// Bind the type to the handler +protected $castHandlers = [ + 'class' => 'SomeHandler', +]; diff --git a/user_guide_src/source/models/entities/021.php b/user_guide_src/source/models/entities/021.php new file mode 100644 index 000000000000..12a805850827 --- /dev/null +++ b/user_guide_src/source/models/entities/021.php @@ -0,0 +1,19 @@ + + // string(13) "App\SomeClass" + // [1]=> + // string(6) "param2" + // [2]=> + // string(6) "param3" + // } + } +} diff --git a/user_guide_src/source/models/entities/022.php b/user_guide_src/source/models/entities/022.php new file mode 100644 index 000000000000..07dc560038a3 --- /dev/null +++ b/user_guide_src/source/models/entities/022.php @@ -0,0 +1,7 @@ +hasChanged('name'); // false + +$user->name = 'Fred'; +$user->hasChanged('name'); // true diff --git a/user_guide_src/source/models/entities/023.php b/user_guide_src/source/models/entities/023.php new file mode 100644 index 000000000000..1e336bcf9d3c --- /dev/null +++ b/user_guide_src/source/models/entities/023.php @@ -0,0 +1,3 @@ +hasChanged(); // true diff --git a/user_guide_src/source/models/model.rst b/user_guide_src/source/models/model.rst index 707491b2cb37..abf096b90857 100644 --- a/user_guide_src/source/models/model.rst +++ b/user_guide_src/source/models/model.rst @@ -24,23 +24,8 @@ location within the directory, like ``namespace App\Models``. You can access models within your classes by creating a new instance or using the ``model()`` helper function. -:: - - // Create a new class manually - $userModel = new \App\Models\UserModel(); - - // Create a new class with the model function - $userModel = model('App\Models\UserModel', false); - - // Create a shared instance of the model - $userModel = model('App\Models\UserModel'); - - // Create shared instance with a supplied database connection - // When no namespace is given, it will search through all namespaces - // the system knows about and attempt to located the UserModel class. - $db = db_connect('custom'); - $userModel = model('UserModel', true, $db); - +.. literalinclude:: model/001.php + :lines: 2- CodeIgniter's Model =================== @@ -60,43 +45,18 @@ Creating Your Model =================== To take advantage of CodeIgniter's model, you would simply create a new model class -that extends ``CodeIgniter\Model``:: - - allowedFields[] = 'middlename'; - } - } +.. literalinclude:: model/003.php Connecting to the Database -------------------------- @@ -106,18 +66,8 @@ it will automatically connect to the default database group, as set in the confi modify which group is used on a per-model basis by adding the ``$DBGroup`` property to your class. This ensures that within the model any references to ``$this->db`` are made through the appropriate connection. -:: - - find($user_id); +.. literalinclude:: model/006.php + :lines: 2- The value is returned in the format specified in ``$returnType``. You can specify more than one row to return by passing an array of primaryKey values instead -of just one:: +of just one: - $users = $userModel->find([1,2,3]); +.. literalinclude:: model/007.php + :lines: 2- If no parameters are passed in, will return all rows in that model's table, effectively acting like ``findAll()``, though less explicit. **findColumn()** -Returns null or an indexed array of column values:: +Returns null or an indexed array of column values: - $user = $userModel->findColumn($column_name); +.. literalinclude:: model/008.php + :lines: 2- ``$column_name`` should be a name of single column else you will get the DataException. **findAll()** -Returns all results:: +Returns all results: - $users = $userModel->findAll(); +.. literalinclude:: model/009.php + :lines: 2- -This query may be modified by interjecting Query Builder commands as needed prior to calling this method:: +This query may be modified by interjecting Query Builder commands as needed prior to calling this method: - $users = $userModel->where('active', 1) - ->findAll(); +.. literalinclude:: model/010.php + :lines: 2- You can pass in a limit and offset values as the first and second -parameters, respectively:: +parameters, respectively: - $users = $userModel->findAll($limit, $offset); +.. literalinclude:: model/011.php + :lines: 2- **first()** Returns the first row in the result set. This is best used in combination with the query builder. -:: - $user = $userModel->where('deleted', 0) - ->first(); +.. literalinclude:: model/012.php + :lines: 2- **withDeleted()** If ``$useSoftDeletes`` is true, then the **find*()** methods will not return any rows where 'deleted_at IS NOT NULL'. To temporarily override this, you can use the ``withDeleted()`` method prior to calling the **find*()** method. -:: - - // Only gets non-deleted rows (deleted = 0) - $activeUsers = $userModel->findAll(); - // Gets all rows - $allUsers = $userModel->withDeleted()->findAll(); +.. literalinclude:: model/013.php + :lines: 2- **onlyDeleted()** Whereas ``withDeleted()`` will return both deleted and not-deleted rows, this method modifies -the next **find*()** methods to return only soft deleted rows:: +the next **find*()** methods to return only soft deleted rows: - $deletedUsers = $userModel->onlyDeleted()->findAll(); +.. literalinclude:: model/014.php + :lines: 2- Saving Data ----------- @@ -348,67 +273,38 @@ Saving Data An associative array of data is passed into this method as the only parameter to create a new row of data in the database. The array's keys must match the name of the columns in a ``$table``, while -the array's values are the values to save for that key:: - - $data = [ - 'username' => 'darth', - 'email' => 'd.vader@theempire.com', - ]; +the array's values are the values to save for that key: - $userModel->insert($data); +.. literalinclude:: model/015.php + :lines: 2- **update()** Updates an existing record in the database. The first parameter is the ``$primaryKey`` of the record to update. An associative array of data is passed into this method as the second parameter. The array's keys must match the name -of the columns in a ``$table``, while the array's values are the values to save for that key:: +of the columns in a ``$table``, while the array's values are the values to save for that key: - $data = [ - 'username' => 'darth', - 'email' => 'd.vader@theempire.com', - ]; +.. literalinclude:: model/016.php + :lines: 2- - $userModel->update($id, $data); +Multiple records may be updated with a single call by passing an array of primary keys as the first parameter: -Multiple records may be updated with a single call by passing an array of primary keys as the first parameter:: - - $data = [ - 'active' => 1, - ]; - - $userModel->update([1, 2, 3], $data); +.. literalinclude:: model/017.php + :lines: 2- When you need a more flexible solution, you can leave the parameters empty and it functions like the Query Builder's -update command, with the added benefit of validation, events, etc:: +update command, with the added benefit of validation, events, etc: - $userModel - ->whereIn('id', [1,2,3]) - ->set(['active' => 1]) - ->update(); +.. literalinclude:: model/018.php + :lines: 2- **save()** This is a wrapper around the ``insert()`` and ``update()`` methods that handle inserting or updating the record -automatically, based on whether it finds an array key matching the **primary key** value:: - - // Defined as a model property - $primaryKey = 'id'; +automatically, based on whether it finds an array key matching the **primary key** value: - // Does an insert() - $data = [ - 'username' => 'darth', - 'email' => 'd.vader@theempire.com', - ]; - - $userModel->save($data); - - // Performs an update, since the primary key, 'id', is found. - $data = [ - 'id' => 3, - 'username' => 'darth', - 'email' => 'd.vader@theempire.com', - ]; - $userModel->save($data); +.. literalinclude:: model/019.php + :lines: 2- The save method also can make working with custom class result objects much simpler by recognizing a non-simple object and grabbing its public and protected values into an array, which is then passed to the appropriate @@ -416,56 +312,22 @@ insert or update method. This allows you to work with Entity classes in a very c simple classes that represent a single instance of an object type, like a user, a blog post, job, etc. This class is responsible for maintaining the business logic surrounding the object itself, like formatting elements in a certain way, etc. They shouldn't have any idea about how they are saved to the database. At their -simplest, they might look like this:: - - namespace App\Entities; - - class Job - { - protected $id; - protected $name; - protected $description; - - public function __get($key) - { - if (property_exists($this, $key)) { - return $this->$key; - } - } - - public function __set($key, $value) - { - if (property_exists($this, $key)) { - $this->$key = $value; - } - } - } - -A very simple model to work with this might look like:: - - use CodeIgniter\Model; - - class JobModel extends Model - { - protected $table = 'jobs'; - protected $returnType = '\App\Entities\Job'; - protected $allowedFields = [ - 'name', 'description' - ]; - } +simplest, they might look like this: -This model works with data from the ``jobs`` table, and returns all results as an instance of ``App\Entities\Job``. -When you need to persist that record to the database, you will need to either write custom methods, or use the -model's ``save()`` method to inspect the class, grab any public and private properties, and save them to the database:: +.. literalinclude:: model/020.php + :lines: 2- + +A very simple model to work with this might look like: - // Retrieve a Job instance - $job = $model->find(15); +.. literalinclude:: model/021.php + :lines: 2- - // Make some changes - $job->name = "Foobar"; +This model works with data from the ``jobs`` table, and returns all results as an instance of ``App\Entities\Job``. +When you need to persist that record to the database, you will need to either write custom methods, or use the +model's ``save()`` method to inspect the class, grab any public and private properties, and save them to the database: - // Save the changes - $model->save($job); +.. literalinclude:: model/022.php + :lines: 2- .. note:: If you find yourself working with Entities a lot, CodeIgniter provides a built-in :doc:`Entity class ` that provides several handy features that make developing Entities simpler. @@ -475,27 +337,31 @@ Deleting Data **delete()** -Takes a primary key value as the first parameter and deletes the matching record from the model's table:: +Takes a primary key value as the first parameter and deletes the matching record from the model's table: - $userModel->delete(12); +.. literalinclude:: model/023.php + :lines: 2- If the model's ``$useSoftDeletes`` value is true, this will update the row to set ``deleted_at`` to the current date and time. You can force a permanent delete by setting the second parameter as true. -An array of primary keys can be passed in as the first parameter to delete multiple records at once:: +An array of primary keys can be passed in as the first parameter to delete multiple records at once: - $userModel->delete([1,2,3]); +.. literalinclude:: model/024.php + :lines: 2- If no parameters are passed in, will act like the Query Builder's delete method, requiring a where call -previously:: +previously: - $userModel->where('id', 12)->delete(); +.. literalinclude:: model/025.php + :lines: 2- **purgeDeleted()** -Cleans out the database table by permanently removing all rows that have 'deleted_at IS NOT NULL'. :: +Cleans out the database table by permanently removing all rows that have 'deleted_at IS NOT NULL'. - $userModel->purgeDeleted(); +.. literalinclude:: model/026.php + :lines: 2- Validating Data --------------- @@ -505,23 +371,10 @@ standard, without duplicating code. The Model class provides a way to automatica prior to saving to the database with the ``insert()``, ``update()``, or ``save()`` methods. The first step is to fill out the ``$validationRules`` class property with the fields and rules that should -be applied. If you have custom error message that you want to use, place them in the ``$validationMessages`` array:: - - class UserModel extends Model - { - protected $validationRules = [ - 'username' => 'required|alpha_numeric_space|min_length[3]', - 'email' => 'required|valid_email|is_unique[users.email]', - 'password' => 'required|min_length[8]', - 'pass_confirm' => 'required_with[password]|matches[password]', - ]; - - protected $validationMessages = [ - 'email' => [ - 'is_unique' => 'Sorry. That email has already been taken. Please choose another.', - ], - ]; - } +be applied. If you have custom error message that you want to use, place them in the ``$validationMessages`` array: + +.. literalinclude:: model/027.php + :lines: 2- The other way to set the validation rules to fields by functions, @@ -532,12 +385,10 @@ The other way to set the validation rules to fields by functions, This function will set the field validation rules. - Usage example:: - - $fieldName = 'username'; - $fieldRules = 'required|alpha_numeric_space|min_length[3]'; + Usage example: - $model->setValidationRule($fieldName, $fieldRules); + .. literalinclude:: model/028.php + :lines: 2- .. php:function:: setValidationRules($validationRules) @@ -545,18 +396,10 @@ The other way to set the validation rules to fields by functions, This function will set the validation rules. - Usage example:: + Usage example: - $validationRules = [ - 'username' => 'required|alpha_numeric_space|min_length[3]', - 'email' => [ - 'rules' => 'required|valid_email|is_unique[users.email]', - 'errors' => [ - 'required' => 'We really need your email.', - ], - ], - ]; - $model->setValidationRules($validationRules); + .. literalinclude:: model/029.php + :lines: 2- The other way to set the validation message to fields by functions, @@ -567,13 +410,10 @@ The other way to set the validation message to fields by functions, This function will set the field wise error messages. - Usage example:: + Usage example: - $fieldName = 'name'; - $fieldValidationMessage = [ - 'required' => 'Your name is required here', - ]; - $model->setValidationMessage($fieldName, $fieldValidationMessage); + .. literalinclude:: model/030.php + :lines: 2- .. php:function:: setValidationMessages($fieldMessages) @@ -581,63 +421,49 @@ The other way to set the validation message to fields by functions, This function will set the field messages. - Usage example:: + Usage example: - $fieldValidationMessage = [ - 'name' => [ - 'required' => 'Your baby name is missing.', - 'min_length' => 'Too short, man!', - ], - ]; - $model->setValidationMessages($fieldValidationMessage); + .. literalinclude:: model/031.php + :lines: 2- Now, whenever you call the ``insert()``, ``update()``, or ``save()`` methods, the data will be validated. If it fails, -the model will return boolean **false**. You can use the ``errors()`` method to retrieve the validation errors:: +the model will return boolean **false**. You can use the ``errors()`` method to retrieve the validation errors: - if ($model->save($data) === false) { - return view('updateUser', ['errors' => $model->errors()]); - } +.. literalinclude:: model/032.php + :lines: 2- This returns an array with the field names and their associated errors that can be used to either show all of the -errors at the top of the form, or to display them individually:: +errors at the top of the form, or to display them individually: - -
    - $error): ?> -

    - -
    - +.. literalinclude:: model/033.php If you'd rather organize your rules and error messages within the Validation configuration file, you can do that -and simply set ``$validationRules`` to the name of the validation rule group you created:: +and simply set ``$validationRules`` to the name of the validation rule group you created: - class UserModel extends Model - { - protected $validationRules = 'users'; - } +.. literalinclude:: model/034.php + :lines: 2- Retrieving Validation Rules --------------------------- You can retrieve a model's validation rules by accessing its ``validationRules`` -property:: +property: - $rules = $model->validationRules; +.. literalinclude:: model/035.php + :lines: 2- You can also retrieve just a subset of those rules by calling the accessor -method directly, with options:: +method directly, with options: - $rules = $model->getValidationRules($options); +.. literalinclude:: model/036.php + :lines: 2- The ``$options`` parameter is an associative array with one element, whose key is either ``'except'`` or ``'only'``, and which has as its -value an array of fieldnames of interest.:: +value an array of fieldnames of interest.: - // get the rules for all but the "username" field - $rules = $model->getValidationRules(['except' => ['username']]); - // get the rules for only the "city" and "state" fields - $rules = $model->getValidationRules(['only' => ['city', 'state']]); +.. literalinclude:: model/037.php + :lines: 2- Validation Placeholders ----------------------- @@ -645,25 +471,21 @@ Validation Placeholders The model provides a simple method to replace parts of your rules based on data that's being passed into it. This sounds fairly obscure but can be especially handy with the ``is_unique`` validation rule. Placeholders are simply the name of the field (or array key) that was passed in as ``$data`` surrounded by curly brackets. It will be -replaced by the **value** of the matched incoming field. An example should clarify this:: +replaced by the **value** of the matched incoming field. An example should clarify this: - protected $validationRules = [ - 'email' => 'required|valid_email|is_unique[users.email,id,{id}]' - ]; +.. literalinclude:: model/038.php + :lines: 2- In this set of rules, it states that the email address should be unique in the database, except for the row -that has an id matching the placeholder's value. Assuming that the form POST data had the following:: +that has an id matching the placeholder's value. Assuming that the form POST data had the following: - $_POST = [ - 'id' => 4, - 'email' => 'foo@example.com' - ]; +.. literalinclude:: model/039.php + :lines: 2- -then the ``{id}`` placeholder would be replaced with the number **4**, giving this revised rule:: +then the ``{id}`` placeholder would be replaced with the number **4**, giving this revised rule: - protected $validationRules = [ - 'email' => 'required|valid_email|is_unique[users.email,id,4]' - ]; +.. literalinclude:: model/040.php + :lines: 2- So it will ignore the row in the database that has ``id=4`` when it verifies the email is unique. @@ -677,45 +499,46 @@ To help protect against Mass Assignment Attacks, the Model class **requires** th that can be changed during inserts and updates in the ``$allowedFields`` class property. Any data provided in addition to these will be removed prior to hitting the database. This is great for ensuring that timestamps, or primary keys do not get changed. -:: - protected $allowedFields = ['name', 'email', 'address']; +.. literalinclude:: model/041.php + :lines: 2- Occasionally, you will find times where you need to be able to change these elements. This is often during -testing, migrations, or seeds. In these cases, you can turn the protection on or off:: +testing, migrations, or seeds. In these cases, you can turn the protection on or off: - $model->protect(false) - ->insert($data) - ->protect(true); +.. literalinclude:: model/042.php + :lines: 2- Working With Query Builder -------------------------- You can get access to a shared instance of the Query Builder for that model's database connection any time you -need it:: +need it: - $builder = $userModel->builder(); +.. literalinclude:: model/043.php + :lines: 2- This builder is already set up with the model's ``$table``. If you need access to another table -you can pass it in as a parameter, but be aware that this will not return a shared instance:: +you can pass it in as a parameter, but be aware that this will not return a shared instance: - $groupBuilder = $userModel->builder('groups'); +.. literalinclude:: model/044.php + :lines: 2- You can also use Query Builder methods and the Model's CRUD methods in the same chained call, allowing for -very elegant use:: +very elegant use: - $users = $userModel->where('status', 'active') - ->orderBy('last_login', 'asc') - ->findAll(); +.. literalinclude:: model/045.php + :lines: 2- .. important:: The Model does not provide a perfect interface to the Query Builder. The Model and the Query Builder are separate classes with different purposes. They should not be expected to return the same data. For example, if you need to get the compiledInsert you should do so directly on the builder instance. -.. note:: You can also access the model's database connection seamlessly:: +.. note:: You can also access the model's database connection seamlessly: - $user_name = $userModel->escape($name); + .. literalinclude:: model/046.php + :lines: 2- Runtime Return Type Changes ---------------------------- @@ -729,19 +552,17 @@ provides methods that allow you to do just that. **asArray()** -Returns data from the next **find*()** method as associative arrays:: +Returns data from the next **find*()** method as associative arrays: - $users = $userModel->asArray()->where('status', 'active')->findAll(); +.. literalinclude:: model/047.php + :lines: 2- **asObject()** -Returns data from the next **find*()** method as standard objects or custom class intances:: +Returns data from the next **find*()** method as standard objects or custom class intances: - // Return as standard objects - $users = $userModel->asObject()->where('status', 'active')->findAll(); - - // Return as custom class instances - $users = $userModel->asObject('User')->where('status', 'active')->findAll(); +.. literalinclude:: model/048.php + :lines: 2- Processing Large Amounts of Data -------------------------------- @@ -752,12 +573,9 @@ do your work on. The first parameter is the number of rows to retrieve in a sing parameter is a Closure that will be called for each row of data. This is best used during cronjobs, data exports, or other large tasks. -:: - $userModel->chunk(100, function ($data) { - // do something. - // $data is a single row of data. - }); +.. literalinclude:: model/049.php + :lines: 2- Model Events ============ @@ -777,38 +595,28 @@ of the insert* or update* methods, that will be the key/value pairs that are bei main array will also contain the other values passed to the method, and be detailed later. The callback method must return the original $data array so other callbacks have the full information. -:: - - protected function hashPassword(array $data) - { - if (! isset($data['data']['password'])) { - return $data; - } - - $data['data']['password_hash'] = password_hash($data['data']['password'], PASSWORD_DEFAULT); - unset($data['data']['password']); - - return $data; - } +.. literalinclude:: model/050.php + :lines: 2- Specifying Callbacks To Run --------------------------- You specify when to run the callbacks by adding the method name to the appropriate class property (``$beforeInsert``, ``$afterUpdate``, etc). Multiple callbacks can be added to a single event and they will be processed one after the other. You can -use the same callback in multiple events:: +use the same callback in multiple events: - protected $beforeInsert = ['hashPassword']; - protected $beforeUpdate = ['hashPassword']; +.. literalinclude:: model/051.php + :lines: 2- -Additionally, each model may allow (default) or deny callbacks class-wide by setting its ``$allowCallbacks`` property:: +Additionally, each model may allow (default) or deny callbacks class-wide by setting its ``$allowCallbacks`` property: - protected $allowCallbacks = false; +.. literalinclude:: model/052.php + :lines: 2- -You may also change this setting temporarily for a single model call sing the ``allowCallbacks()`` method:: +You may also change this setting temporarily for a single model call sing the ``allowCallbacks()`` method: - $model->allowCallbacks(false)->find(1); // No callbacks triggered - $model->find(1); // Callbacks subject to original property value +.. literalinclude:: model/053.php + :lines: 2- Event Parameters ---------------- @@ -851,22 +659,10 @@ Modifying Find* Data The ``beforeFind`` and ``afterFind`` methods can both return a modified set of data to override the normal response from the model. For ``afterFind`` any changes made to ``data`` in the return array will automatically be passed back to the calling context. In order for ``beforeFind`` to intercept the find workflow it must also return an additional -boolean, ``returnData``:: - - protected $beforeFind = ['checkCache']; - // ... - protected function checkCache(array $data) - { - // Check if the requested item is already in our cache - if (isset($data['id']) && $item = $this->getCachedItem($data['id']])) { - $data['data'] = $item; - $data['returnData'] = true; - - return $data; - } +boolean, ``returnData``: - // ... - } +.. literalinclude:: model/054.php + :lines: 2- Manual Model Creation ===================== @@ -875,20 +671,4 @@ You do not need to extend any special class to create a model for your applicati instance of the database connection and you're good to go. This allows you to bypass the features CodeIgniter's Model gives you out of the box, and create a fully custom experience. -:: - - db = &$db; - } - } +.. literalinclude:: model/055.php diff --git a/user_guide_src/source/models/model/001.php b/user_guide_src/source/models/model/001.php new file mode 100644 index 000000000000..ac8ede5c3dec --- /dev/null +++ b/user_guide_src/source/models/model/001.php @@ -0,0 +1,16 @@ +allowedFields[] = 'middlename'; + } +} diff --git a/user_guide_src/source/models/model/004.php b/user_guide_src/source/models/model/004.php new file mode 100644 index 000000000000..1ae028acbf7a --- /dev/null +++ b/user_guide_src/source/models/model/004.php @@ -0,0 +1,10 @@ +find($user_id); diff --git a/user_guide_src/source/models/model/007.php b/user_guide_src/source/models/model/007.php new file mode 100644 index 000000000000..1c5d65b7d93e --- /dev/null +++ b/user_guide_src/source/models/model/007.php @@ -0,0 +1,3 @@ +find([1,2,3]); diff --git a/user_guide_src/source/models/model/008.php b/user_guide_src/source/models/model/008.php new file mode 100644 index 000000000000..981f887120e3 --- /dev/null +++ b/user_guide_src/source/models/model/008.php @@ -0,0 +1,3 @@ +findColumn($column_name); diff --git a/user_guide_src/source/models/model/009.php b/user_guide_src/source/models/model/009.php new file mode 100644 index 000000000000..881962a52c3b --- /dev/null +++ b/user_guide_src/source/models/model/009.php @@ -0,0 +1,3 @@ +findAll(); diff --git a/user_guide_src/source/models/model/010.php b/user_guide_src/source/models/model/010.php new file mode 100644 index 000000000000..bc654f2703c9 --- /dev/null +++ b/user_guide_src/source/models/model/010.php @@ -0,0 +1,4 @@ +where('active', 1) + ->findAll(); diff --git a/user_guide_src/source/models/model/011.php b/user_guide_src/source/models/model/011.php new file mode 100644 index 000000000000..a906bda6142e --- /dev/null +++ b/user_guide_src/source/models/model/011.php @@ -0,0 +1,3 @@ +findAll($limit, $offset); diff --git a/user_guide_src/source/models/model/012.php b/user_guide_src/source/models/model/012.php new file mode 100644 index 000000000000..117771f78ca8 --- /dev/null +++ b/user_guide_src/source/models/model/012.php @@ -0,0 +1,4 @@ +where('deleted', 0) + ->first(); diff --git a/user_guide_src/source/models/model/013.php b/user_guide_src/source/models/model/013.php new file mode 100644 index 000000000000..1abc1e3be49b --- /dev/null +++ b/user_guide_src/source/models/model/013.php @@ -0,0 +1,7 @@ +findAll(); + +// Gets all rows +$allUsers = $userModel->withDeleted()->findAll(); diff --git a/user_guide_src/source/models/model/014.php b/user_guide_src/source/models/model/014.php new file mode 100644 index 000000000000..f12fc5e0cb6a --- /dev/null +++ b/user_guide_src/source/models/model/014.php @@ -0,0 +1,3 @@ +onlyDeleted()->findAll(); diff --git a/user_guide_src/source/models/model/015.php b/user_guide_src/source/models/model/015.php new file mode 100644 index 000000000000..23414a8c9a01 --- /dev/null +++ b/user_guide_src/source/models/model/015.php @@ -0,0 +1,8 @@ + 'darth', + 'email' => 'd.vader@theempire.com', +]; + +$userModel->insert($data); diff --git a/user_guide_src/source/models/model/016.php b/user_guide_src/source/models/model/016.php new file mode 100644 index 000000000000..efecefe6ba81 --- /dev/null +++ b/user_guide_src/source/models/model/016.php @@ -0,0 +1,8 @@ + 'darth', + 'email' => 'd.vader@theempire.com', +]; + +$userModel->update($id, $data); diff --git a/user_guide_src/source/models/model/017.php b/user_guide_src/source/models/model/017.php new file mode 100644 index 000000000000..5032c34a4613 --- /dev/null +++ b/user_guide_src/source/models/model/017.php @@ -0,0 +1,7 @@ + 1, +]; + +$userModel->update([1, 2, 3], $data); diff --git a/user_guide_src/source/models/model/018.php b/user_guide_src/source/models/model/018.php new file mode 100644 index 000000000000..8c13a5a85e2a --- /dev/null +++ b/user_guide_src/source/models/model/018.php @@ -0,0 +1,6 @@ +whereIn('id', [1,2,3]) + ->set(['active' => 1]) + ->update(); diff --git a/user_guide_src/source/models/model/019.php b/user_guide_src/source/models/model/019.php new file mode 100644 index 000000000000..789218001968 --- /dev/null +++ b/user_guide_src/source/models/model/019.php @@ -0,0 +1,20 @@ + 'darth', + 'email' => 'd.vader@theempire.com', +]; + +$userModel->save($data); + +// Performs an update, since the primary key, 'id', is found. +$data = [ + 'id' => 3, + 'username' => 'darth', + 'email' => 'd.vader@theempire.com', +]; +$userModel->save($data); diff --git a/user_guide_src/source/models/model/020.php b/user_guide_src/source/models/model/020.php new file mode 100644 index 000000000000..ebc37ee608c1 --- /dev/null +++ b/user_guide_src/source/models/model/020.php @@ -0,0 +1,24 @@ +$key; + } + } + + public function __set($key, $value) + { + if (property_exists($this, $key)) { + $this->$key = $value; + } + } +} diff --git a/user_guide_src/source/models/model/021.php b/user_guide_src/source/models/model/021.php new file mode 100644 index 000000000000..a49cfe210163 --- /dev/null +++ b/user_guide_src/source/models/model/021.php @@ -0,0 +1,12 @@ +find(15); + +// Make some changes +$job->name = "Foobar"; + +// Save the changes +$model->save($job); diff --git a/user_guide_src/source/models/model/023.php b/user_guide_src/source/models/model/023.php new file mode 100644 index 000000000000..c1045eecbbb2 --- /dev/null +++ b/user_guide_src/source/models/model/023.php @@ -0,0 +1,3 @@ +delete(12); diff --git a/user_guide_src/source/models/model/024.php b/user_guide_src/source/models/model/024.php new file mode 100644 index 000000000000..f6769f061142 --- /dev/null +++ b/user_guide_src/source/models/model/024.php @@ -0,0 +1,3 @@ +delete([1,2,3]); diff --git a/user_guide_src/source/models/model/025.php b/user_guide_src/source/models/model/025.php new file mode 100644 index 000000000000..dc520c882d8e --- /dev/null +++ b/user_guide_src/source/models/model/025.php @@ -0,0 +1,3 @@ +where('id', 12)->delete(); diff --git a/user_guide_src/source/models/model/026.php b/user_guide_src/source/models/model/026.php new file mode 100644 index 000000000000..c06642313a0c --- /dev/null +++ b/user_guide_src/source/models/model/026.php @@ -0,0 +1,3 @@ +purgeDeleted(); diff --git a/user_guide_src/source/models/model/027.php b/user_guide_src/source/models/model/027.php new file mode 100644 index 000000000000..b0d19738c5c0 --- /dev/null +++ b/user_guide_src/source/models/model/027.php @@ -0,0 +1,17 @@ + 'required|alpha_numeric_space|min_length[3]', + 'email' => 'required|valid_email|is_unique[users.email]', + 'password' => 'required|min_length[8]', + 'pass_confirm' => 'required_with[password]|matches[password]', + ]; + + protected $validationMessages = [ + 'email' => [ + 'is_unique' => 'Sorry. That email has already been taken. Please choose another.', + ], + ]; +} diff --git a/user_guide_src/source/models/model/028.php b/user_guide_src/source/models/model/028.php new file mode 100644 index 000000000000..c9bea660de81 --- /dev/null +++ b/user_guide_src/source/models/model/028.php @@ -0,0 +1,6 @@ +setValidationRule($fieldName, $fieldRules); diff --git a/user_guide_src/source/models/model/029.php b/user_guide_src/source/models/model/029.php new file mode 100644 index 000000000000..15221f2505a6 --- /dev/null +++ b/user_guide_src/source/models/model/029.php @@ -0,0 +1,12 @@ + 'required|alpha_numeric_space|min_length[3]', + 'email' => [ + 'rules' => 'required|valid_email|is_unique[users.email]', + 'errors' => [ + 'required' => 'We really need your email.', + ], + ], +]; +$model->setValidationRules($validationRules); diff --git a/user_guide_src/source/models/model/030.php b/user_guide_src/source/models/model/030.php new file mode 100644 index 000000000000..deca0d44f722 --- /dev/null +++ b/user_guide_src/source/models/model/030.php @@ -0,0 +1,7 @@ + 'Your name is required here', +]; +$model->setValidationMessage($fieldName, $fieldValidationMessage); diff --git a/user_guide_src/source/models/model/031.php b/user_guide_src/source/models/model/031.php new file mode 100644 index 000000000000..902cea408f1f --- /dev/null +++ b/user_guide_src/source/models/model/031.php @@ -0,0 +1,9 @@ + [ + 'required' => 'Your baby name is missing.', + 'min_length' => 'Too short, man!', + ], +]; +$model->setValidationMessages($fieldValidationMessage); diff --git a/user_guide_src/source/models/model/032.php b/user_guide_src/source/models/model/032.php new file mode 100644 index 000000000000..0e93993557b4 --- /dev/null +++ b/user_guide_src/source/models/model/032.php @@ -0,0 +1,5 @@ +save($data) === false) { + return view('updateUser', ['errors' => $model->errors()]); +} diff --git a/user_guide_src/source/models/model/033.php b/user_guide_src/source/models/model/033.php new file mode 100644 index 000000000000..32005c35b635 --- /dev/null +++ b/user_guide_src/source/models/model/033.php @@ -0,0 +1,7 @@ + +
    + $error): ?> +

    + +
    + diff --git a/user_guide_src/source/models/model/034.php b/user_guide_src/source/models/model/034.php new file mode 100644 index 000000000000..8de746bec4cd --- /dev/null +++ b/user_guide_src/source/models/model/034.php @@ -0,0 +1,6 @@ +validationRules; diff --git a/user_guide_src/source/models/model/036.php b/user_guide_src/source/models/model/036.php new file mode 100644 index 000000000000..af5a3eef010e --- /dev/null +++ b/user_guide_src/source/models/model/036.php @@ -0,0 +1,3 @@ +getValidationRules($options); diff --git a/user_guide_src/source/models/model/037.php b/user_guide_src/source/models/model/037.php new file mode 100644 index 000000000000..ff15de70d9c5 --- /dev/null +++ b/user_guide_src/source/models/model/037.php @@ -0,0 +1,6 @@ +getValidationRules(['except' => ['username']]); +// get the rules for only the "city" and "state" fields +$rules = $model->getValidationRules(['only' => ['city', 'state']]); diff --git a/user_guide_src/source/models/model/038.php b/user_guide_src/source/models/model/038.php new file mode 100644 index 000000000000..0a0dffd7dba5 --- /dev/null +++ b/user_guide_src/source/models/model/038.php @@ -0,0 +1,5 @@ + 'required|valid_email|is_unique[users.email,id,{id}]' +]; diff --git a/user_guide_src/source/models/model/039.php b/user_guide_src/source/models/model/039.php new file mode 100644 index 000000000000..00ab7df2a766 --- /dev/null +++ b/user_guide_src/source/models/model/039.php @@ -0,0 +1,6 @@ + 4, + 'email' => 'foo@example.com' +]; diff --git a/user_guide_src/source/models/model/040.php b/user_guide_src/source/models/model/040.php new file mode 100644 index 000000000000..68f9c5c13143 --- /dev/null +++ b/user_guide_src/source/models/model/040.php @@ -0,0 +1,5 @@ + 'required|valid_email|is_unique[users.email,id,4]' +]; diff --git a/user_guide_src/source/models/model/041.php b/user_guide_src/source/models/model/041.php new file mode 100644 index 000000000000..8aaa151c61a1 --- /dev/null +++ b/user_guide_src/source/models/model/041.php @@ -0,0 +1,3 @@ +protect(false) + ->insert($data) + ->protect(true); diff --git a/user_guide_src/source/models/model/043.php b/user_guide_src/source/models/model/043.php new file mode 100644 index 000000000000..44a962a082f8 --- /dev/null +++ b/user_guide_src/source/models/model/043.php @@ -0,0 +1,3 @@ +builder(); diff --git a/user_guide_src/source/models/model/044.php b/user_guide_src/source/models/model/044.php new file mode 100644 index 000000000000..229af898adcb --- /dev/null +++ b/user_guide_src/source/models/model/044.php @@ -0,0 +1,3 @@ +builder('groups'); diff --git a/user_guide_src/source/models/model/045.php b/user_guide_src/source/models/model/045.php new file mode 100644 index 000000000000..9b064dd4fbff --- /dev/null +++ b/user_guide_src/source/models/model/045.php @@ -0,0 +1,5 @@ +where('status', 'active') + ->orderBy('last_login', 'asc') + ->findAll(); diff --git a/user_guide_src/source/models/model/046.php b/user_guide_src/source/models/model/046.php new file mode 100644 index 000000000000..13b84dc5d71c --- /dev/null +++ b/user_guide_src/source/models/model/046.php @@ -0,0 +1,3 @@ +escape($name); diff --git a/user_guide_src/source/models/model/047.php b/user_guide_src/source/models/model/047.php new file mode 100644 index 000000000000..ab2dfdecc85b --- /dev/null +++ b/user_guide_src/source/models/model/047.php @@ -0,0 +1,3 @@ +asArray()->where('status', 'active')->findAll(); diff --git a/user_guide_src/source/models/model/048.php b/user_guide_src/source/models/model/048.php new file mode 100644 index 000000000000..799e88726d93 --- /dev/null +++ b/user_guide_src/source/models/model/048.php @@ -0,0 +1,7 @@ +asObject()->where('status', 'active')->findAll(); + +// Return as custom class instances +$users = $userModel->asObject('User')->where('status', 'active')->findAll(); diff --git a/user_guide_src/source/models/model/049.php b/user_guide_src/source/models/model/049.php new file mode 100644 index 000000000000..0aace6d0fc28 --- /dev/null +++ b/user_guide_src/source/models/model/049.php @@ -0,0 +1,6 @@ +chunk(100, function ($data) { + // do something. + // $data is a single row of data. +}); diff --git a/user_guide_src/source/models/model/050.php b/user_guide_src/source/models/model/050.php new file mode 100644 index 000000000000..a933f49d5f3e --- /dev/null +++ b/user_guide_src/source/models/model/050.php @@ -0,0 +1,13 @@ +allowCallbacks(false)->find(1); // No callbacks triggered +$model->find(1); // Callbacks subject to original property value diff --git a/user_guide_src/source/models/model/054.php b/user_guide_src/source/models/model/054.php new file mode 100644 index 000000000000..dd8bb573b5dd --- /dev/null +++ b/user_guide_src/source/models/model/054.php @@ -0,0 +1,16 @@ +getCachedItem($data['id']])) { + $data['data'] = $item; + $data['returnData'] = true; + + return $data; + } + + // ... +} diff --git a/user_guide_src/source/models/model/055.php b/user_guide_src/source/models/model/055.php new file mode 100644 index 000000000000..1d62c54ba058 --- /dev/null +++ b/user_guide_src/source/models/model/055.php @@ -0,0 +1,15 @@ +db = &$db; + } +} diff --git a/user_guide_src/source/outgoing/alternative_php.rst b/user_guide_src/source/outgoing/alternative_php.rst index 369808874413..b4a2b10257e5 100644 --- a/user_guide_src/source/outgoing/alternative_php.rst +++ b/user_guide_src/source/outgoing/alternative_php.rst @@ -25,17 +25,9 @@ Alternative Control Structures ============================== Controls structures, like if, for, foreach, and while can be written in -a simplified format as well. Here is an example using ``foreach``:: +a simplified format as well. Here is an example using ``foreach``: -
      - - - -
    • - - - -
    +.. literalinclude:: alternative_php/001.php Notice that there are no braces. Instead, the end brace is replaced with ``endforeach``. Each of the control structures listed above has a similar @@ -44,18 +36,6 @@ closing syntax: ``endif``, ``endfor``, ``endforeach``, and ``endwhile`` Also notice that instead of using a semicolon after each structure (except the last one), there is a colon. This is important! -Here is another example, using ``if``/``elseif``/``else``. Notice the colons:: - - - -

    Hi Sally

    - - - -

    Hi Joe

    - - - -

    Hi unknown user

    +Here is another example, using ``if``/``elseif``/``else``. Notice the colons: - +.. literalinclude:: alternative_php/002.php diff --git a/user_guide_src/source/outgoing/alternative_php/001.php b/user_guide_src/source/outgoing/alternative_php/001.php new file mode 100644 index 000000000000..9158fe27dccc --- /dev/null +++ b/user_guide_src/source/outgoing/alternative_php/001.php @@ -0,0 +1,9 @@ +
      + + + +
    • + + + +
    diff --git a/user_guide_src/source/outgoing/alternative_php/002.php b/user_guide_src/source/outgoing/alternative_php/002.php new file mode 100644 index 000000000000..47c5afcfb95a --- /dev/null +++ b/user_guide_src/source/outgoing/alternative_php/002.php @@ -0,0 +1,13 @@ + + +

    Hi Sally

    + + + +

    Hi Joe

    + + + +

    Hi unknown user

    + + diff --git a/user_guide_src/source/outgoing/api_responses.rst b/user_guide_src/source/outgoing/api_responses.rst index 92eaa066f36f..1e6e2bba735f 100644 --- a/user_guide_src/source/outgoing/api_responses.rst +++ b/user_guide_src/source/outgoing/api_responses.rst @@ -17,66 +17,13 @@ Example Usage The following example shows a common usage pattern within your controllers. -:: - - save($this->request->getPost()); - - // Respond with 201 status code - return $this->respondCreated(); - } - } +.. literalinclude:: api_responses/001.php In this example, an HTTP status code of 201 is returned, with the generic status message, 'Created'. Methods -exist for the most common use cases:: - - // Generic response method - $this->respond($data, 200); - - // Generic failure response - $this->fail($errors, 400); - - // Item created response - $this->respondCreated($data); - - // Item successfully deleted - $this->respondDeleted($data); - - // Command executed by no response required - $this->respondNoContent($message); - - // Client isn't authorized - $this->failUnauthorized($description); - - // Forbidden action - $this->failForbidden($description); - - // Resource Not Found - $this->failNotFound($description); - - // Data did not validate - $this->failValidationError($description); +exist for the most common use cases: - // Resource already exists - $this->failResourceExists($description); - - // Resource previously deleted - $this->failResourceGone($description); - - // Client made too many requests - $this->failTooManyRequests($description); +.. literalinclude:: api_responses/002.php + :lines: 2- *********************** Handling Response Types @@ -92,12 +39,10 @@ the following criteria: To define the formatter that is used, edit **Config/Format.php**. The ``$supportedResponseFormats`` contains a list of mime types that your application can automatically format the response for. By default, the system knows how to -format both XML and JSON responses:: +format both XML and JSON responses: - public $supportedResponseFormats = [ - 'application/json', - 'application/xml', - ]; +.. literalinclude:: api_responses/003.php + :lines: 2- This is the array that is used during :doc:`Content Negotiation ` to determine which type of response to return. If no matches are found between what the client requested and what you support, the first @@ -105,12 +50,10 @@ format in this array is what will be returned. Next, you need to define the class that is used to format the array of data. This must be a fully qualified class name, and the class must implement ``CodeIgniter\Format\FormatterInterface``. Formatters come out of the box that -support both JSON and XML:: +support both JSON and XML: - public $formatters = [ - 'application/json' => \CodeIgniter\Format\JSONFormatter::class, - 'application/xml' => \CodeIgniter\Format\XMLFormatter::class, - ]; +.. literalinclude:: api_responses/004.php + :lines: 2- So, if your request asks for JSON formatted data in an **Accept** header, the data array you pass any of the ``respond*`` or ``fail*`` methods will be formatted by the ``CodeIgniter\Format\JSONFormatter`` class. The resulting @@ -125,10 +68,8 @@ Class Reference This defines the format to be used when formatting arrays in responses. If you provide a ``null`` value for ``$format``, it will be automatically determined through content negotiation. -:: - - return $this->setResponseFormat('json')->respond(['error' => false]); - +.. literalinclude:: api_responses/005.php + :lines: 2- .. php:method:: respond($data[, $statusCode = 200[, $message = '']]) @@ -171,16 +112,10 @@ Class Reference that match the status code. The response is an array with two elements: ``error`` and ``messages``. The ``error`` element contains the status - code of the error. The ``messages`` element contains an array of error messages. It would look something like:: + code of the error. The ``messages`` element contains an array of error messages. It would look something like: - $response = [ - 'status' => 400, - 'code' => '321a', - 'messages' => [ - 'Error message 1', - 'Error message 2', - ], - ]; + .. literalinclude:: api_responses/006.php + :lines: 2- .. php:method:: respondCreated($data = null[, string $message = '']) @@ -188,10 +123,10 @@ Class Reference :param string $message: A custom "reason" message to return. :returns: The value of the Response object's send() method. - Sets the appropriate status code to use when a new resource was created, typically 201.:: + Sets the appropriate status code to use when a new resource was created, typically 201.: - $user = $userModel->insert($data); - return $this->respondCreated($user); + .. literalinclude:: api_responses/007.php + :lines: 2- .. php:method:: respondDeleted($data = null[, string $message = '']) @@ -201,10 +136,8 @@ Class Reference Sets the appropriate status code to use when a new resource was deleted as the result of this API call, typically 200. - :: - - $user = $userModel->delete($id); - return $this->respondDeleted(['id' => $id]); + .. literalinclude:: api_responses/008.php + :lines: 2- .. php:method:: respondNoContent(string $message = 'No Content') @@ -214,10 +147,8 @@ Class Reference Sets the appropriate status code to use when a command was successfully executed by the server but there is no meaningful reply to send back to the client, typically 204. - :: - - sleep(1); - return $this->respondNoContent(); + .. literalinclude:: api_responses/009.php + :lines: 2- .. php:method:: failUnauthorized(string $description = 'Unauthorized'[, string $code = null[, string $message = '']]) @@ -229,9 +160,8 @@ Class Reference Sets the appropriate status code to use when the user either has not been authorized, or has incorrect authorization. Status code is 401. - :: - - return $this->failUnauthorized('Invalid Auth token'); + .. literalinclude:: api_responses/010.php + :lines: 2- .. php:method:: failForbidden(string $description = 'Forbidden'[, string $code=null[, string $message = '']]) @@ -244,9 +174,8 @@ Class Reference Unauthorized implies the client is encouraged to try again with different credentials. Forbidden means the client should not try again because it won't help. Status code is 403. - :: - - return $this->failForbidden('Invalid API endpoint.'); + .. literalinclude:: api_responses/011.php + :lines: 2- .. php:method:: failNotFound(string $description = 'Not Found'[, string $code=null[, string $message = '']]) @@ -257,9 +186,8 @@ Class Reference Sets the appropriate status code to use when the requested resource cannot be found. Status code is 404. - :: - - return $this->failNotFound('User 13 cannot be found.'); + .. literalinclude:: api_responses/012.php + :lines: 2- .. php:method:: failValidationErrors($errors[, string $code=null[, string $message = '']]) @@ -270,9 +198,8 @@ Class Reference Sets the appropriate status code to use when data the client sent did not pass validation rules. Status code is typically 400. - :: - - return $this->failValidationErrors($validation->getErrors()); + .. literalinclude:: api_responses/013.php + :lines: 2- .. php:method:: failResourceExists(string $description = 'Conflict'[, string $code=null[, string $message = '']]) @@ -284,9 +211,8 @@ Class Reference Sets the appropriate status code to use when the resource the client is trying to create already exists. Status code is typically 409. - :: - - return $this->failResourceExists('A user already exists with that email.'); + .. literalinclude:: api_responses/014.php + :lines: 2- .. php:method:: failResourceGone(string $description = 'Gone'[, string $code=null[, string $message = '']]) @@ -298,9 +224,8 @@ Class Reference Sets the appropriate status code to use when the requested resource was previously deleted and is no longer available. Status code is typically 410. - :: - - return $this->failResourceGone('That user has been previously deleted.'); + .. literalinclude:: api_responses/015.php + :lines: 2- .. php:method:: failTooManyRequests(string $description = 'Too Many Requests'[, string $code=null[, string $message = '']]) @@ -312,9 +237,8 @@ Class Reference Sets the appropriate status code to use when the client has called an API endpoint too many times. This might be due to some form of throttling or rate limiting. Status code is typically 400. - :: - - return $this->failTooManyRequests('You must wait 15 seconds before making another request.'); + .. literalinclude:: api_responses/016.php + :lines: 2- .. php:method:: failServerError(string $description = 'Internal Server Error'[, string $code = null[, string $message = '']]) @@ -325,6 +249,5 @@ Class Reference Sets the appropriate status code to use when there is a server error. - :: - - return $this->failServerError('Server error.'); + .. literalinclude:: api_responses/017.php + :lines: 2- diff --git a/user_guide_src/source/outgoing/api_responses/001.php b/user_guide_src/source/outgoing/api_responses/001.php new file mode 100644 index 000000000000..c2a196482b58 --- /dev/null +++ b/user_guide_src/source/outgoing/api_responses/001.php @@ -0,0 +1,19 @@ +save($this->request->getPost()); + + // Respond with 201 status code + return $this->respondCreated(); + } +} diff --git a/user_guide_src/source/outgoing/api_responses/002.php b/user_guide_src/source/outgoing/api_responses/002.php new file mode 100644 index 000000000000..e383ddc3c09f --- /dev/null +++ b/user_guide_src/source/outgoing/api_responses/002.php @@ -0,0 +1,37 @@ +respond($data, 200); + +// Generic failure response +$this->fail($errors, 400); + +// Item created response +$this->respondCreated($data); + +// Item successfully deleted +$this->respondDeleted($data); + +// Command executed by no response required +$this->respondNoContent($message); + +// Client isn't authorized +$this->failUnauthorized($description); + +// Forbidden action +$this->failForbidden($description); + +// Resource Not Found +$this->failNotFound($description); + +// Data did not validate +$this->failValidationError($description); + +// Resource already exists +$this->failResourceExists($description); + +// Resource previously deleted +$this->failResourceGone($description); + +// Client made too many requests +$this->failTooManyRequests($description); diff --git a/user_guide_src/source/outgoing/api_responses/003.php b/user_guide_src/source/outgoing/api_responses/003.php new file mode 100644 index 000000000000..ab1db7ccdc45 --- /dev/null +++ b/user_guide_src/source/outgoing/api_responses/003.php @@ -0,0 +1,6 @@ + \CodeIgniter\Format\JSONFormatter::class, + 'application/xml' => \CodeIgniter\Format\XMLFormatter::class, +]; diff --git a/user_guide_src/source/outgoing/api_responses/005.php b/user_guide_src/source/outgoing/api_responses/005.php new file mode 100644 index 000000000000..dbe887df0b63 --- /dev/null +++ b/user_guide_src/source/outgoing/api_responses/005.php @@ -0,0 +1,3 @@ +setResponseFormat('json')->respond(['error' => false]); diff --git a/user_guide_src/source/outgoing/api_responses/006.php b/user_guide_src/source/outgoing/api_responses/006.php new file mode 100644 index 000000000000..3c910d6566b5 --- /dev/null +++ b/user_guide_src/source/outgoing/api_responses/006.php @@ -0,0 +1,10 @@ + 400, + 'code' => '321a', + 'messages' => [ + 'Error message 1', + 'Error message 2', + ], +]; diff --git a/user_guide_src/source/outgoing/api_responses/007.php b/user_guide_src/source/outgoing/api_responses/007.php new file mode 100644 index 000000000000..568075938d3a --- /dev/null +++ b/user_guide_src/source/outgoing/api_responses/007.php @@ -0,0 +1,4 @@ +insert($data); +return $this->respondCreated($user); diff --git a/user_guide_src/source/outgoing/api_responses/008.php b/user_guide_src/source/outgoing/api_responses/008.php new file mode 100644 index 000000000000..5c1fe47efb65 --- /dev/null +++ b/user_guide_src/source/outgoing/api_responses/008.php @@ -0,0 +1,4 @@ +delete($id); +return $this->respondDeleted(['id' => $id]); diff --git a/user_guide_src/source/outgoing/api_responses/009.php b/user_guide_src/source/outgoing/api_responses/009.php new file mode 100644 index 000000000000..e7672d94a610 --- /dev/null +++ b/user_guide_src/source/outgoing/api_responses/009.php @@ -0,0 +1,4 @@ +respondNoContent(); diff --git a/user_guide_src/source/outgoing/api_responses/010.php b/user_guide_src/source/outgoing/api_responses/010.php new file mode 100644 index 000000000000..3de055d94cba --- /dev/null +++ b/user_guide_src/source/outgoing/api_responses/010.php @@ -0,0 +1,3 @@ +failUnauthorized('Invalid Auth token'); diff --git a/user_guide_src/source/outgoing/api_responses/011.php b/user_guide_src/source/outgoing/api_responses/011.php new file mode 100644 index 000000000000..44f3c4eeb23e --- /dev/null +++ b/user_guide_src/source/outgoing/api_responses/011.php @@ -0,0 +1,3 @@ +failForbidden('Invalid API endpoint.'); diff --git a/user_guide_src/source/outgoing/api_responses/012.php b/user_guide_src/source/outgoing/api_responses/012.php new file mode 100644 index 000000000000..2c8d8b29175a --- /dev/null +++ b/user_guide_src/source/outgoing/api_responses/012.php @@ -0,0 +1,3 @@ +failNotFound('User 13 cannot be found.'); diff --git a/user_guide_src/source/outgoing/api_responses/013.php b/user_guide_src/source/outgoing/api_responses/013.php new file mode 100644 index 000000000000..d470b1079d3b --- /dev/null +++ b/user_guide_src/source/outgoing/api_responses/013.php @@ -0,0 +1,3 @@ +failValidationErrors($validation->getErrors()); diff --git a/user_guide_src/source/outgoing/api_responses/014.php b/user_guide_src/source/outgoing/api_responses/014.php new file mode 100644 index 000000000000..d0772239c43e --- /dev/null +++ b/user_guide_src/source/outgoing/api_responses/014.php @@ -0,0 +1,3 @@ +failResourceExists('A user already exists with that email.'); diff --git a/user_guide_src/source/outgoing/api_responses/015.php b/user_guide_src/source/outgoing/api_responses/015.php new file mode 100644 index 000000000000..a8ce10dc9ff6 --- /dev/null +++ b/user_guide_src/source/outgoing/api_responses/015.php @@ -0,0 +1,3 @@ +failResourceGone('That user has been previously deleted.'); diff --git a/user_guide_src/source/outgoing/api_responses/016.php b/user_guide_src/source/outgoing/api_responses/016.php new file mode 100644 index 000000000000..197376fe271f --- /dev/null +++ b/user_guide_src/source/outgoing/api_responses/016.php @@ -0,0 +1,3 @@ +failTooManyRequests('You must wait 15 seconds before making another request.'); diff --git a/user_guide_src/source/outgoing/api_responses/017.php b/user_guide_src/source/outgoing/api_responses/017.php new file mode 100644 index 000000000000..5bb665f3dd60 --- /dev/null +++ b/user_guide_src/source/outgoing/api_responses/017.php @@ -0,0 +1,3 @@ +failServerError('Server error.'); diff --git a/user_guide_src/source/outgoing/localization.rst b/user_guide_src/source/outgoing/localization.rst index 58b24c48524f..cb87e8717f1a 100644 --- a/user_guide_src/source/outgoing/localization.rst +++ b/user_guide_src/source/outgoing/localization.rst @@ -30,9 +30,10 @@ supported language:: Configuring the Locale ====================== -Every site will have a default language/locale they operate in. This can be set in **Config/App.php**:: +Every site will have a default language/locale they operate in. This can be set in **Config/App.php**: - public $defaultLocale = 'en'; +.. literalinclude:: localization/001.php + :lines: 2- The value can be any string that your application uses to manage text strings and other formats. It is recommended that a `BCP 47 `_ language code is used. This results in @@ -58,25 +59,28 @@ Content Negotiation ------------------- You can set up content negotiation to happen automatically by setting two additional settings in Config/App. -The first value tells the Request class that we do want to negotiate a locale, so simply set it to true:: +The first value tells the Request class that we do want to negotiate a locale, so simply set it to true: - public $negotiateLocale = true; +.. literalinclude:: localization/002.php + :lines: 2- Once this is enabled, the system will automatically negotiate the correct language based upon an array of locales that you have defined in ``$supportLocales``. If no match is found between the languages that you support, and the requested language, the first item in $supportedLocales will be used. In -the following example, the **en** locale would be used if no match is found:: +the following example, the **en** locale would be used if no match is found: - public $supportedLocales = ['en', 'es', 'fr-FR']; +.. literalinclude:: localization/003.php + :lines: 2- In Routes --------- The second method uses a custom placeholder to detect the desired locale and set it on the Request. The placeholder ``{locale}`` can be placed as a segment in your route. If present, the contents of the matching -segment will be your locale:: +segment will be your locale: - $routes->get('{locale}/books', 'App\Books::index'); +.. literalinclude:: localization/004.php + :lines: 2- In this example, if the user tried to visit ``http://example.com/fr/books``, then the locale would be set to ``fr``, assuming it was configured as a valid locale. @@ -88,23 +92,14 @@ Retrieving the Current Locale ============================= The current locale can always be retrieved from the IncomingRequest object, through the ``getLocale()`` method. -If your controller is extending ``CodeIgniter\Controller``, this will be available through ``$this->request``:: +If your controller is extending ``CodeIgniter\Controller``, this will be available through ``$this->request``: - ` to retrieve the current request: - class UserController extends \CodeIgniter\Controller - { - public function index() - { - $locale = $this->request->getLocale(); - } - } - -Alternatively, you can use the :doc:`Services class ` to retrieve the current request:: - - $locale = service('request')->getLocale(); +.. literalinclude:: localization/006.php + :lines: 2- ********************* Language Localization @@ -117,43 +112,33 @@ Languages do not have any specific naming convention that are required. The file describe the type of content it holds. For example, let's say you want to create a file containing error messages. You might name it simply: **Errors.php**. -Within the file, you would return an array, where each element in the array has a language key and can have string to return:: +Within the file, you would return an array, where each element in the array has a language key and can have string to return: - 'languageKey' => 'The actual message to be shown.' +.. literalinclude:: localization/007.php + :lines: 2- -It also support nested definition:: +It also support nested definition: - 'languageKey' => [ - 'nested' => [ - 'key' => 'The actual message to be shown.', - ], - ], +.. literalinclude:: localization/008.php + :lines: 2- -:: - - return [ - 'errorEmailMissing' => 'You must submit an email address', - 'errorURLMissing' => 'You must submit a URL', - 'errorUsernameMissing' => 'You must submit a username', - 'nested' => [ - 'error' => [ - 'message' => 'A specific error message', - ], - ], - ]; +.. literalinclude:: localization/009.php + :lines: 2- Basic Usage =========== You can use the ``lang()`` helper function to retrieve text from any of the language files, by passing the filename and the language key as the first parameter, separated by a period (.). For example, to load the -``errorEmailMissing`` string from the ``Errors`` language file, you would do the following:: +``errorEmailMissing`` string from the ``Errors`` language file, you would do the following: - echo lang('Errors.errorEmailMissing'); +.. literalinclude:: localization/010.php + :lines: 2- -For nested definition, you would do the following:: +For nested definition, you would do the following: - echo lang('Errors.nested.error.message'); +.. literalinclude:: localization/011.php + :lines: 2- If the requested language key doesn't exist in the file for the current locale, the string will be passed back, unchanged. In this example, it would return 'Errors.errorEmailMissing' or 'Errors.nested.error.message' if it didn't exist. @@ -166,27 +151,20 @@ Replacing Parameters A great overview can be found over at `Sitepoint `_. You can pass an array of values to replace placeholders in the language string as the second parameter to the -``lang()`` function. This allows for very simple number translations and formatting:: - - // The language file, Tests.php: - return [ - 'apples' => 'I have {0, number} apples.', - 'men' => 'The top {1, number} men out-performed the remaining {0, number}', - 'namedApples' => 'I have {number_apples, number, integer} apples.', - ]; +``lang()`` function. This allows for very simple number translations and formatting: - // Displays "I have 3 apples." - echo lang('Tests.apples', [ 3 ]); +.. literalinclude:: localization/012.php + :lines: 2- -The first item in the placeholder corresponds to the index of the item in the array, if it's numerical:: +The first item in the placeholder corresponds to the index of the item in the array, if it's numerical: - // Displays "The top 23 men out-performed the remaining 20" - echo lang('Tests.men', [20, 23]); +.. literalinclude:: localization/013.php + :lines: 2- -You can also use named keys to make it easier to keep things straight, if you'd like:: +You can also use named keys to make it easier to keep things straight, if you'd like: - // Displays "I have 3 apples." - echo lang('Tests.namedApples', ['number_apples' => 3]); +.. literalinclude:: localization/014.php + :lines: 2- Obviously, you can do more than just number replacement. According to the `official ICU docs `_ for the underlying @@ -199,46 +177,10 @@ library, the following types of data can be replaced: * ordinal * duration -Here are a few examples:: - - // The language file, Tests.php - return [ - 'shortTime' => 'The time is now {0, time, short}.', - 'mediumTime' => 'The time is now {0, time, medium}.', - 'longTime' => 'The time is now {0, time, long}.', - 'fullTime' => 'The time is now {0, time, full}.', - 'shortDate' => 'The date is now {0, date, short}.', - 'mediumDate' => 'The date is now {0, date, medium}.', - 'longDate' => 'The date is now {0, date, long}.', - 'fullDate' => 'The date is now {0, date, full}.', - 'spelledOut' => '34 is {0, spellout}', - 'ordinal' => 'The ordinal is {0, ordinal}', - 'duration' => 'It has been {0, duration}', - ]; - - // Displays "The time is now 11:18 PM" - echo lang('Tests.shortTime', [time()]); - // Displays "The time is now 11:18:50 PM" - echo lang('Tests.mediumTime', [time()]); - // Displays "The time is now 11:19:09 PM CDT" - echo lang('Tests.longTime', [time()]); - // Displays "The time is now 11:19:26 PM Central Daylight Time" - echo lang('Tests.fullTime', [time()]); - - // Displays "The date is now 8/14/16" - echo lang('Tests.shortDate', [time()]); - // Displays "The date is now Aug 14, 2016" - echo lang('Tests.mediumDate', [time()]); - // Displays "The date is now August 14, 2016" - echo lang('Tests.longDate', [time()]); - // Displays "The date is now Sunday, August 14, 2016" - echo lang('Tests.fullDate', [time()]); - - // Displays "34 is thirty-four" - echo lang('Tests.spelledOut', [34]); - - // Displays "It has been 408,676:24:35" - echo lang('Tests.ordinal', [time()]); +Here are a few examples: + +.. literalinclude:: localization/015.php + :lines: 2- You should be sure to read up on the MessageFormatter class and the underlying ICU formatting to get a better idea on what capabilities it has, like performing the conditional replacement, pluralization, and more. Both of the links provided @@ -249,37 +191,17 @@ Specifying Locale To specify a different locale to be used when replacing parameters, you can pass the locale in as the third parameter to the ``lang()`` method. -:: - - // Displays "The time is now 23:21:28 GMT-5" - echo lang('Test.longTime', [time()], 'ru-RU'); - // Displays "£7.41" - echo lang('{price, number, currency}', ['price' => 7.41], 'en-GB'); - // Displays "$7.41" - echo lang('{price, number, currency}', ['price' => 7.41], 'en-US'); +.. literalinclude:: localization/016.php + :lines: 2- Nested Arrays ------------- Language files also allow nested arrays to make working with lists, etc... easier. -:: - - // Language/en/Fruit.php - - return [ - 'list' => [ - 'Apples', - 'Bananas', - 'Grapes', - 'Lemons', - 'Oranges', - 'Strawberries', - ], - ]; - - // Displays "Apples, Bananas, Grapes, Lemons, Oranges, Strawberries" - echo implode(', ', lang('Fruit.list')); + +.. literalinclude:: localization/017.php + :lines: 2- Language Fallback ================= diff --git a/user_guide_src/source/outgoing/localization/001.php b/user_guide_src/source/outgoing/localization/001.php new file mode 100644 index 000000000000..c3b3de65be20 --- /dev/null +++ b/user_guide_src/source/outgoing/localization/001.php @@ -0,0 +1,3 @@ +get('{locale}/books', 'App\Books::index'); diff --git a/user_guide_src/source/outgoing/localization/005.php b/user_guide_src/source/outgoing/localization/005.php new file mode 100644 index 000000000000..09d2d5cae03d --- /dev/null +++ b/user_guide_src/source/outgoing/localization/005.php @@ -0,0 +1,11 @@ +request->getLocale(); + } +} diff --git a/user_guide_src/source/outgoing/localization/006.php b/user_guide_src/source/outgoing/localization/006.php new file mode 100644 index 000000000000..06eee03102b5 --- /dev/null +++ b/user_guide_src/source/outgoing/localization/006.php @@ -0,0 +1,3 @@ +getLocale(); diff --git a/user_guide_src/source/outgoing/localization/007.php b/user_guide_src/source/outgoing/localization/007.php new file mode 100644 index 000000000000..48dc3e455282 --- /dev/null +++ b/user_guide_src/source/outgoing/localization/007.php @@ -0,0 +1,3 @@ + 'The actual message to be shown.' diff --git a/user_guide_src/source/outgoing/localization/008.php b/user_guide_src/source/outgoing/localization/008.php new file mode 100644 index 000000000000..b8975a521320 --- /dev/null +++ b/user_guide_src/source/outgoing/localization/008.php @@ -0,0 +1,7 @@ + [ + 'nested' => [ + 'key' => 'The actual message to be shown.', + ], +], diff --git a/user_guide_src/source/outgoing/localization/009.php b/user_guide_src/source/outgoing/localization/009.php new file mode 100644 index 000000000000..07e6924dcdab --- /dev/null +++ b/user_guide_src/source/outgoing/localization/009.php @@ -0,0 +1,12 @@ + 'You must submit an email address', + 'errorURLMissing' => 'You must submit a URL', + 'errorUsernameMissing' => 'You must submit a username', + 'nested' => [ + 'error' => [ + 'message' => 'A specific error message', + ], + ], +]; diff --git a/user_guide_src/source/outgoing/localization/010.php b/user_guide_src/source/outgoing/localization/010.php new file mode 100644 index 000000000000..7631da71f069 --- /dev/null +++ b/user_guide_src/source/outgoing/localization/010.php @@ -0,0 +1,3 @@ + 'I have {0, number} apples.', + 'men' => 'The top {1, number} men out-performed the remaining {0, number}', + 'namedApples' => 'I have {number_apples, number, integer} apples.', +]; + +// Displays "I have 3 apples." +echo lang('Tests.apples', [ 3 ]); diff --git a/user_guide_src/source/outgoing/localization/013.php b/user_guide_src/source/outgoing/localization/013.php new file mode 100644 index 000000000000..c74a8f868f6e --- /dev/null +++ b/user_guide_src/source/outgoing/localization/013.php @@ -0,0 +1,4 @@ + 3]); diff --git a/user_guide_src/source/outgoing/localization/015.php b/user_guide_src/source/outgoing/localization/015.php new file mode 100644 index 000000000000..04e15f558f69 --- /dev/null +++ b/user_guide_src/source/outgoing/localization/015.php @@ -0,0 +1,40 @@ + 'The time is now {0, time, short}.', + 'mediumTime' => 'The time is now {0, time, medium}.', + 'longTime' => 'The time is now {0, time, long}.', + 'fullTime' => 'The time is now {0, time, full}.', + 'shortDate' => 'The date is now {0, date, short}.', + 'mediumDate' => 'The date is now {0, date, medium}.', + 'longDate' => 'The date is now {0, date, long}.', + 'fullDate' => 'The date is now {0, date, full}.', + 'spelledOut' => '34 is {0, spellout}', + 'ordinal' => 'The ordinal is {0, ordinal}', + 'duration' => 'It has been {0, duration}', +]; + +// Displays "The time is now 11:18 PM" +echo lang('Tests.shortTime', [time()]); +// Displays "The time is now 11:18:50 PM" +echo lang('Tests.mediumTime', [time()]); +// Displays "The time is now 11:19:09 PM CDT" +echo lang('Tests.longTime', [time()]); +// Displays "The time is now 11:19:26 PM Central Daylight Time" +echo lang('Tests.fullTime', [time()]); + +// Displays "The date is now 8/14/16" +echo lang('Tests.shortDate', [time()]); +// Displays "The date is now Aug 14, 2016" +echo lang('Tests.mediumDate', [time()]); +// Displays "The date is now August 14, 2016" +echo lang('Tests.longDate', [time()]); +// Displays "The date is now Sunday, August 14, 2016" +echo lang('Tests.fullDate', [time()]); + +// Displays "34 is thirty-four" +echo lang('Tests.spelledOut', [34]); + +// Displays "It has been 408,676:24:35" +echo lang('Tests.ordinal', [time()]); diff --git a/user_guide_src/source/outgoing/localization/016.php b/user_guide_src/source/outgoing/localization/016.php new file mode 100644 index 000000000000..93b709a73e99 --- /dev/null +++ b/user_guide_src/source/outgoing/localization/016.php @@ -0,0 +1,9 @@ + 7.41], 'en-GB'); +// Displays "$7.41" +echo lang('{price, number, currency}', ['price' => 7.41], 'en-US'); diff --git a/user_guide_src/source/outgoing/localization/017.php b/user_guide_src/source/outgoing/localization/017.php new file mode 100644 index 000000000000..bd6218e927b5 --- /dev/null +++ b/user_guide_src/source/outgoing/localization/017.php @@ -0,0 +1,17 @@ + [ + 'Apples', + 'Bananas', + 'Grapes', + 'Lemons', + 'Oranges', + 'Strawberries', + ], +]; + +// Displays "Apples, Bananas, Grapes, Lemons, Oranges, Strawberries" +echo implode(', ', lang('Fruit.list')); diff --git a/user_guide_src/source/outgoing/response.rst b/user_guide_src/source/outgoing/response.rst index a573710ad8c8..6a1fcd81b85c 100644 --- a/user_guide_src/source/outgoing/response.rst +++ b/user_guide_src/source/outgoing/response.rst @@ -23,26 +23,22 @@ Setting the Output When you need to set the output of the script directly, and not rely on CodeIgniter to automatically get it, you do it manually with the ``setBody`` method. This is usually used in conjunction with setting the status code of -the response:: +the response: - $this->response->setStatusCode(404)->setBody($body); +.. literalinclude:: response/001.php + :lines: 2- The reason phrase ('OK', 'Created', 'Moved Permanently') will be automatically added, but you can add custom reasons -as the second parameter of the ``setStatusCode()`` method:: +as the second parameter of the ``setStatusCode()`` method: - $this->response->setStatusCode(404, 'Nope. Not here.'); +.. literalinclude:: response/002.php + :lines: 2- You can set format an array into either JSON or XML and set the content type header to the appropriate mime with the -``setJSON`` and ``setXML`` methods. Typically, you will send an array of data to be converted:: +``setJSON`` and ``setXML`` methods. Typically, you will send an array of data to be converted: - $data = [ - 'success' => true, - 'id' => 123, - ]; - - return $this->response->setJSON($data); - // or - return $this->response->setXML($data); +.. literalinclude:: response/003.php + :lines: 2- Setting Headers --------------- @@ -52,24 +48,22 @@ with the ``setHeader()`` method. The first parameter is the name of the header. which can be either a string or an array of values that will be combined correctly when sent to the client. Using these functions instead of using the native PHP functions allows you to ensure that no headers are sent prematurely, causing errors, and makes testing possible. -:: - $response->setHeader('Location', 'http://example.com') - ->setHeader('WWW-Authenticate', 'Negotiate'); +.. literalinclude:: response/004.php + :lines: 2- If the header exists and can have more than one value, you may use the ``appendHeader()`` and ``prependHeader()`` methods to add the value to the end or beginning of the values list, respectively. The first parameter is the name of the header, while the second is the value to append or prepend. -:: - $response->setHeader('Cache-Control', 'no-cache') - ->appendHeader('Cache-Control', 'must-revalidate'); +.. literalinclude:: response/005.php + :lines: 2- Headers can be removed from the response with the ``removeHeader()`` method, which takes the header name as the only parameter. This is not case-sensitive. -:: - $response->removeHeader('Location'); +.. literalinclude:: response/006.php + :lines: 2- Force File Download =================== @@ -87,21 +81,21 @@ 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'; - return $response->download($name, $data); +.. literalinclude:: response/007.php + :lines: 2- If you want to download an existing file from your server you'll need to -pass ``null`` explicitly for the second parameter:: +pass ``null`` explicitly for the second parameter: - // Contents of photo.jpg will be automatically read - return $response->download('/path/to/photo.jpg', null); +.. literalinclude:: response/008.php + :lines: 2- -Use the optional ``setFileName()`` method to change the filename as it is sent to the client's browser:: +Use the optional ``setFileName()`` method to change the filename as it is sent to the client's browser: - return $response->download('awkwardEncryptedFileName.fakeExt', null)->setFileName('expenses.csv'); +.. literalinclude:: response/009.php + :lines: 2- .. note:: The response object MUST be returned for the download to be sent to the client. This allows the response to be passed through all **after** filters before being sent to the client. @@ -119,14 +113,10 @@ introduction to all of the cache headers power, but you can get a good understan By default, all response objects sent through CodeIgniter have HTTP caching turned off. The options and exact circumstances are too varied for us to be able to create a good default other than turning it off. It's simple -to set the Cache values to what you need, through the ``setCache()`` method:: +to set the Cache values to what you need, through the ``setCache()`` method: - $options = [ - 'max-age' => 300, - 's-maxage' => 900, - 'etag' => 'abcde' - ]; - $this->response->setCache($options); +.. literalinclude:: response/010.php + :lines: 2- The ``$options`` array simply takes an array of key/value pairs that are, with a couple of exceptions, assigned to the ``Cache-Control`` header. You are free to set all of the options exactly as you need for your specific @@ -159,9 +149,10 @@ Turning CSP On -------------- By default, support for this is off. To enable support in your application, edit the ``CSPEnabled`` value in -**app/Config/App.php**:: +**app/Config/App.php**: - public $CSPEnabled = true; +.. literalinclude:: response/011.php + :lines: 2- When enabled, the response object will contain an instance of ``CodeIgniter\HTTP\ContentSecurityPolicy``. The values set in **app/Config/ContentSecurityPolicy.php** are applied to that instance, and if no changes are @@ -184,48 +175,20 @@ Runtime Configuration If your application needs to make changes at run-time, you can access the instance at ``$response->CSP``. The class holds a number of methods that map pretty clearly to the appropriate header value that you need to set. Examples are shown below, with different combinations of parameters, though all accept either a directive -name or an array of them.:: - - // specify the default directive treatment - $response->CSP->reportOnly(false); - - // specify the origin to use if none provided for a directive - $response->CSP->setDefaultSrc('cdn.example.com'); - - // specify the URL that "report-only" reports get sent to - $response->CSP->setReportURI('http://example.com/csp/reports'); - - // specify that HTTP requests be upgraded to HTTPS - $response->CSP->upgradeInsecureRequests(true); - - // add types or origins to CSP directives - // assuming that the default treatment is to block rather than just report - $response->CSP->addBaseURI('example.com', true); // report only - $response->CSP->addChildSrc('https://youtube.com'); // blocked - $response->CSP->addConnectSrc('https://*.facebook.com', false); // blocked - $response->CSP->addFontSrc('fonts.example.com'); - $response->CSP->addFormAction('self'); - $response->CSP->addFrameAncestor('none', true); // report this one - $response->CSP->addImageSrc('cdn.example.com'); - $response->CSP->addMediaSrc('cdn.example.com'); - $response->CSP->addManifestSrc('cdn.example.com'); - $response->CSP->addObjectSrc('cdn.example.com', false); // reject from here - $response->CSP->addPluginType('application/pdf', false); // reject this media type - $response->CSP->addScriptSrc('scripts.example.com', true); // allow but report requests from here - $response->CSP->addStyleSrc('css.example.com'); - $response->CSP->addSandbox(['allow-forms', 'allow-scripts']); +name or an array of them.: + +.. literalinclude:: response/012.php + :lines: 2- The first parameter to each of the "add" methods is an appropriate string value, or an array of them. The ``reportOnly`` method allows you to specify the default reporting treatment for subsequent sources, unless over-ridden. For instance, you could specify -that youtube.com was allowed, and then provide several allowed but reported sources:: +that youtube.com was allowed, and then provide several allowed but reported sources: - $response->addChildSrc('https://youtube.com'); // allowed - $response->reportOnly(true); - $response->addChildSrc('https://metube.com'); // allowed but reported - $response->addChildSrc('https://ourtube.com',false); // allowed +.. literalinclude:: response/013.php + :lines: 2- Inline Content -------------- @@ -305,9 +268,10 @@ The methods provided by the parent class that are available are: :rtype: int Returns the currently status code for this response. If no status code has been set, a BadMethodCallException - will be thrown:: + will be thrown: - echo $response->getStatusCode(); + .. literalinclude:: response/014.php + :lines: 2- .. php:method:: setStatusCode($code[, $reason='']) @@ -316,23 +280,26 @@ The methods provided by the parent class that are available are: :returns: The current Response instance :rtype: ``CodeIgniter\HTTP\Response`` - Sets the HTTP status code that should be sent with this response:: + Sets the HTTP status code that should be sent with this response: - $response->setStatusCode(404); + .. literalinclude:: response/015.php + :lines: 2- The reason phrase will be automatically generated based upon the official lists. If you need to set your own - for a custom status code, you can pass the reason phrase as the second parameter:: + for a custom status code, you can pass the reason phrase as the second parameter: - $response->setStatusCode(230, "Tardis initiated"); + .. literalinclude:: response/016.php + :lines: 2- .. php:method:: getReasonPhrase() :returns: The current reason phrase. :rtype: string - Returns the current status code for this response. If not status has been set, will return an empty string:: + Returns the current status code for this response. If not status has been set, will return an empty string: - echo $response->getReasonPhrase(); + .. literalinclude:: response/017.php + :lines: 2- .. php:method:: setDate($date) @@ -340,10 +307,10 @@ The methods provided by the parent class that are available are: :returns: The current response instance. :rtype: ``CodeIgniter\HTTP\Response`` - Sets the date used for this response. The ``$date`` argument must be an instance of ``DateTime``:: + Sets the date used for this response. The ``$date`` argument must be an instance of ``DateTime``: - $date = DateTime::createFromFormat('j-M-Y', '15-Feb-2016'); - $response->setDate($date); + .. literalinclude:: response/018.php + :lines: 2- .. php:method:: setContentType($mime[, $charset='UTF-8']) @@ -352,16 +319,16 @@ The methods provided by the parent class that are available are: :returns: The current response instance. :rtype: ``CodeIgniter\HTTP\Response`` - Sets the content type this response represents:: + Sets the content type this response represents: - $response->setContentType('text/plain'); - $response->setContentType('text/html'); - $response->setContentType('application/json'); + .. literalinclude:: response/019.php + :lines: 2- By default, the method sets the character set to ``UTF-8``. If you need to change this, you can - pass the character set as the second parameter:: + pass the character set as the second parameter: - $response->setContentType('text/plain', 'x-pig-latin'); + .. literalinclude:: response/020.php + :lines: 2- .. php:method:: noCache() @@ -369,12 +336,10 @@ The methods provided by the parent class that are available are: :rtype: ``CodeIgniter\HTTP\Response`` Sets the ``Cache-Control`` header to turn off all HTTP caching. This is the default setting - of all response messages:: + of all response messages: - $response->noCache(); - - // Sets the following header: - Cache-Control: no-store, max-age=0, no-cache + .. literalinclude:: response/021.php + :lines: 2- .. php:method:: setCache($options) @@ -403,10 +368,10 @@ The methods provided by the parent class that are available are: :rtype: ``CodeIgniter\HTTP\Response`` Sets the ``Last-Modified`` header. The ``$date`` object can be either a string or a ``DateTime`` - instance:: + instance: - $response->setLastModified(date('D, d M Y H:i:s')); - $response->setLastModified(DateTime::createFromFormat('u', $time)); + .. literalinclude:: response/022.php + :lines: 2- .. php:method:: send(): Response @@ -437,21 +402,10 @@ The methods provided by the parent class that are available are: **Array Method** Using this method, an associative array is passed as the first - parameter:: - - $cookie = [ - 'name' => 'The Cookie Name', - 'value' => 'The Value', - 'expire' => '86500', - 'domain' => '.some-domain.com', - 'path' => '/', - 'prefix' => 'myprefix_', - 'secure' => true, - 'httponly' => false, - 'samesite' => 'Lax' - ]; - - $response->setCookie($cookie); + parameter: + + .. literalinclude:: response/023.php + :lines: 2- **Notes** @@ -482,9 +436,10 @@ The methods provided by the parent class that are available are: **Discrete Parameters** If you prefer, you can set the cookie by passing data using individual - parameters:: + parameters: - $response->setCookie($name, $value, $expire, $domain, $path, $prefix, $secure, $httponly, $samesite); + .. literalinclude:: response/024.php + :lines: 2- .. php:method:: deleteCookie($name = ''[, $domain = ''[, $path = '/'[, $prefix = '']]]) @@ -510,9 +465,10 @@ The methods provided by the parent class that are available are: If any of the optional parameters are empty, then the same-named cookie will be deleted across all that apply. - Example:: + Example: - $response->deleteCookie($name); + .. literalinclude:: response/025.php + :lines: 2- .. php:method:: hasCookie($name = ''[, $value = null[, $prefix = '']]) @@ -531,9 +487,10 @@ The methods provided by the parent class that are available are: If a value is given, then the method checks that the cookie exists, and that it has the prescribed value. - Example:: + Example: - if ($response->hasCookie($name)) ... + .. literalinclude:: response/026.php + :lines: 2- .. php:method:: getCookie($name = ''[, $prefix = '']) @@ -544,9 +501,10 @@ The methods provided by the parent class that are available are: Returns the named cookie, if found, or ``null``. If no name is given, returns the array of ``Cookie`` objects. - Example:: + Example: - $cookie = $response->getCookie($name); + .. literalinclude:: response/027.php + :lines: 2- .. php:method:: getCookies() diff --git a/user_guide_src/source/outgoing/response/001.php b/user_guide_src/source/outgoing/response/001.php new file mode 100644 index 000000000000..9815f6f1475d --- /dev/null +++ b/user_guide_src/source/outgoing/response/001.php @@ -0,0 +1,3 @@ +response->setStatusCode(404)->setBody($body); diff --git a/user_guide_src/source/outgoing/response/002.php b/user_guide_src/source/outgoing/response/002.php new file mode 100644 index 000000000000..d5ed0fd87d96 --- /dev/null +++ b/user_guide_src/source/outgoing/response/002.php @@ -0,0 +1,3 @@ +response->setStatusCode(404, 'Nope. Not here.'); diff --git a/user_guide_src/source/outgoing/response/003.php b/user_guide_src/source/outgoing/response/003.php new file mode 100644 index 000000000000..e8d671f81739 --- /dev/null +++ b/user_guide_src/source/outgoing/response/003.php @@ -0,0 +1,10 @@ + true, + 'id' => 123, +]; + +return $this->response->setJSON($data); +// or +return $this->response->setXML($data); diff --git a/user_guide_src/source/outgoing/response/004.php b/user_guide_src/source/outgoing/response/004.php new file mode 100644 index 000000000000..2777aea2795b --- /dev/null +++ b/user_guide_src/source/outgoing/response/004.php @@ -0,0 +1,4 @@ +setHeader('Location', 'http://example.com') + ->setHeader('WWW-Authenticate', 'Negotiate'); diff --git a/user_guide_src/source/outgoing/response/005.php b/user_guide_src/source/outgoing/response/005.php new file mode 100644 index 000000000000..acc3254fa49a --- /dev/null +++ b/user_guide_src/source/outgoing/response/005.php @@ -0,0 +1,4 @@ +setHeader('Cache-Control', 'no-cache') + ->appendHeader('Cache-Control', 'must-revalidate'); diff --git a/user_guide_src/source/outgoing/response/006.php b/user_guide_src/source/outgoing/response/006.php new file mode 100644 index 000000000000..a2fdee1e9ed5 --- /dev/null +++ b/user_guide_src/source/outgoing/response/006.php @@ -0,0 +1,3 @@ +removeHeader('Location'); diff --git a/user_guide_src/source/outgoing/response/007.php b/user_guide_src/source/outgoing/response/007.php new file mode 100644 index 000000000000..c8e545831e00 --- /dev/null +++ b/user_guide_src/source/outgoing/response/007.php @@ -0,0 +1,5 @@ +download($name, $data); diff --git a/user_guide_src/source/outgoing/response/008.php b/user_guide_src/source/outgoing/response/008.php new file mode 100644 index 000000000000..832d75fc0616 --- /dev/null +++ b/user_guide_src/source/outgoing/response/008.php @@ -0,0 +1,4 @@ +download('/path/to/photo.jpg', null); diff --git a/user_guide_src/source/outgoing/response/009.php b/user_guide_src/source/outgoing/response/009.php new file mode 100644 index 000000000000..e75c386647cb --- /dev/null +++ b/user_guide_src/source/outgoing/response/009.php @@ -0,0 +1,3 @@ +download('awkwardEncryptedFileName.fakeExt', null)->setFileName('expenses.csv'); diff --git a/user_guide_src/source/outgoing/response/010.php b/user_guide_src/source/outgoing/response/010.php new file mode 100644 index 000000000000..724c1fb213a1 --- /dev/null +++ b/user_guide_src/source/outgoing/response/010.php @@ -0,0 +1,8 @@ + 300, + 's-maxage' => 900, + 'etag' => 'abcde' +]; +$this->response->setCache($options); diff --git a/user_guide_src/source/outgoing/response/011.php b/user_guide_src/source/outgoing/response/011.php new file mode 100644 index 000000000000..37d2234a5527 --- /dev/null +++ b/user_guide_src/source/outgoing/response/011.php @@ -0,0 +1,3 @@ +CSP->reportOnly(false); + +// specify the origin to use if none provided for a directive +$response->CSP->setDefaultSrc('cdn.example.com'); + +// specify the URL that "report-only" reports get sent to +$response->CSP->setReportURI('http://example.com/csp/reports'); + +// specify that HTTP requests be upgraded to HTTPS +$response->CSP->upgradeInsecureRequests(true); + +// add types or origins to CSP directives +// assuming that the default treatment is to block rather than just report +$response->CSP->addBaseURI('example.com', true); // report only +$response->CSP->addChildSrc('https://youtube.com'); // blocked +$response->CSP->addConnectSrc('https://*.facebook.com', false); // blocked +$response->CSP->addFontSrc('fonts.example.com'); +$response->CSP->addFormAction('self'); +$response->CSP->addFrameAncestor('none', true); // report this one +$response->CSP->addImageSrc('cdn.example.com'); +$response->CSP->addMediaSrc('cdn.example.com'); +$response->CSP->addManifestSrc('cdn.example.com'); +$response->CSP->addObjectSrc('cdn.example.com', false); // reject from here +$response->CSP->addPluginType('application/pdf', false); // reject this media type +$response->CSP->addScriptSrc('scripts.example.com', true); // allow but report requests from here +$response->CSP->addStyleSrc('css.example.com'); +$response->CSP->addSandbox(['allow-forms', 'allow-scripts']); diff --git a/user_guide_src/source/outgoing/response/013.php b/user_guide_src/source/outgoing/response/013.php new file mode 100644 index 000000000000..8cebd2451096 --- /dev/null +++ b/user_guide_src/source/outgoing/response/013.php @@ -0,0 +1,6 @@ +addChildSrc('https://youtube.com'); // allowed +$response->reportOnly(true); +$response->addChildSrc('https://metube.com'); // allowed but reported +$response->addChildSrc('https://ourtube.com',false); // allowed diff --git a/user_guide_src/source/outgoing/response/014.php b/user_guide_src/source/outgoing/response/014.php new file mode 100644 index 000000000000..c05ef6fbe606 --- /dev/null +++ b/user_guide_src/source/outgoing/response/014.php @@ -0,0 +1,3 @@ +getStatusCode(); diff --git a/user_guide_src/source/outgoing/response/015.php b/user_guide_src/source/outgoing/response/015.php new file mode 100644 index 000000000000..3fbc71bc6371 --- /dev/null +++ b/user_guide_src/source/outgoing/response/015.php @@ -0,0 +1,3 @@ +setStatusCode(404); diff --git a/user_guide_src/source/outgoing/response/016.php b/user_guide_src/source/outgoing/response/016.php new file mode 100644 index 000000000000..38d6a8e3b690 --- /dev/null +++ b/user_guide_src/source/outgoing/response/016.php @@ -0,0 +1,3 @@ +setStatusCode(230, "Tardis initiated"); diff --git a/user_guide_src/source/outgoing/response/017.php b/user_guide_src/source/outgoing/response/017.php new file mode 100644 index 000000000000..78ce30be95bb --- /dev/null +++ b/user_guide_src/source/outgoing/response/017.php @@ -0,0 +1,3 @@ +getReasonPhrase(); diff --git a/user_guide_src/source/outgoing/response/018.php b/user_guide_src/source/outgoing/response/018.php new file mode 100644 index 000000000000..606424af8f79 --- /dev/null +++ b/user_guide_src/source/outgoing/response/018.php @@ -0,0 +1,4 @@ +setDate($date); diff --git a/user_guide_src/source/outgoing/response/019.php b/user_guide_src/source/outgoing/response/019.php new file mode 100644 index 000000000000..f74953ae772d --- /dev/null +++ b/user_guide_src/source/outgoing/response/019.php @@ -0,0 +1,5 @@ +setContentType('text/plain'); +$response->setContentType('text/html'); +$response->setContentType('application/json'); diff --git a/user_guide_src/source/outgoing/response/020.php b/user_guide_src/source/outgoing/response/020.php new file mode 100644 index 000000000000..fdbc546b6fad --- /dev/null +++ b/user_guide_src/source/outgoing/response/020.php @@ -0,0 +1,3 @@ +setContentType('text/plain', 'x-pig-latin'); diff --git a/user_guide_src/source/outgoing/response/021.php b/user_guide_src/source/outgoing/response/021.php new file mode 100644 index 000000000000..41745631aaac --- /dev/null +++ b/user_guide_src/source/outgoing/response/021.php @@ -0,0 +1,6 @@ +noCache(); + +// Sets the following header: +Cache-Control: no-store, max-age=0, no-cache diff --git a/user_guide_src/source/outgoing/response/022.php b/user_guide_src/source/outgoing/response/022.php new file mode 100644 index 000000000000..5a841f28d2ce --- /dev/null +++ b/user_guide_src/source/outgoing/response/022.php @@ -0,0 +1,4 @@ +setLastModified(date('D, d M Y H:i:s')); +$response->setLastModified(DateTime::createFromFormat('u', $time)); diff --git a/user_guide_src/source/outgoing/response/023.php b/user_guide_src/source/outgoing/response/023.php new file mode 100644 index 000000000000..35d072f354d9 --- /dev/null +++ b/user_guide_src/source/outgoing/response/023.php @@ -0,0 +1,15 @@ + 'The Cookie Name', + 'value' => 'The Value', + 'expire' => '86500', + 'domain' => '.some-domain.com', + 'path' => '/', + 'prefix' => 'myprefix_', + 'secure' => true, + 'httponly' => false, + 'samesite' => 'Lax' +]; + +$response->setCookie($cookie); diff --git a/user_guide_src/source/outgoing/response/024.php b/user_guide_src/source/outgoing/response/024.php new file mode 100644 index 000000000000..3b75c4004362 --- /dev/null +++ b/user_guide_src/source/outgoing/response/024.php @@ -0,0 +1,3 @@ +setCookie($name, $value, $expire, $domain, $path, $prefix, $secure, $httponly, $samesite); diff --git a/user_guide_src/source/outgoing/response/025.php b/user_guide_src/source/outgoing/response/025.php new file mode 100644 index 000000000000..a2343928babe --- /dev/null +++ b/user_guide_src/source/outgoing/response/025.php @@ -0,0 +1,3 @@ +deleteCookie($name); diff --git a/user_guide_src/source/outgoing/response/026.php b/user_guide_src/source/outgoing/response/026.php new file mode 100644 index 000000000000..55149496da87 --- /dev/null +++ b/user_guide_src/source/outgoing/response/026.php @@ -0,0 +1,3 @@ +hasCookie($name)) ... diff --git a/user_guide_src/source/outgoing/response/027.php b/user_guide_src/source/outgoing/response/027.php new file mode 100644 index 000000000000..1d76679940c8 --- /dev/null +++ b/user_guide_src/source/outgoing/response/027.php @@ -0,0 +1,3 @@ +getCookie($name); diff --git a/user_guide_src/source/outgoing/table.rst b/user_guide_src/source/outgoing/table.rst index 01b7dabe5cef..9890a18acbe4 100644 --- a/user_guide_src/source/outgoing/table.rst +++ b/user_guide_src/source/outgoing/table.rst @@ -17,9 +17,10 @@ Initializing the Class ====================== The Table class is not provided as a service, and should be instantiated -"normally", for instance:: +"normally", for instance: - $table = new \CodeIgniter\View\Table(); +.. literalinclude:: table/001.php + :lines: 2- Examples ======== @@ -29,100 +30,37 @@ multi-dimensional array. Note that the first array index will become the table heading (or you can set your own headings using the ``setHeading()`` method described in the function reference below). -:: - - $table = new \CodeIgniter\View\Table(); - - $data = [ - ['Name', 'Color', 'Size'], - ['Fred', 'Blue', 'Small'], - ['Mary', 'Red', 'Large'], - ['John', 'Green', 'Medium'], - ]; - - echo $table->generate($data); +.. literalinclude:: table/002.php + :lines: 2- 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 ``setHeading()`` method described in the class reference below). -:: - - $table = new \CodeIgniter\View\Table(); - - $query = $db->query('SELECT * FROM my_table'); - - echo $table->generate($query); +.. literalinclude:: table/003.php + :lines: 2- Here is an example showing how you might create a table using discrete -parameters:: +parameters: - $table = new \CodeIgniter\View\Table(); - - $table->setHeading('Name', 'Color', 'Size'); - - $table->addRow('Fred', 'Blue', 'Small'); - $table->addRow('Mary', 'Red', 'Large'); - $table->addRow('John', 'Green', 'Medium'); - - echo $table->generate(); +.. literalinclude:: table/004.php + :lines: 2- Here is the same example, except instead of individual parameters, -arrays are used:: - - $table = new \CodeIgniter\View\Table(); - - $table->setHeading(array('Name', 'Color', 'Size')); +arrays are used: - $table->addRow(['Fred', 'Blue', 'Small']); - $table->addRow(['Mary', 'Red', 'Large']); - $table->addRow(['John', 'Green', 'Medium']); - - echo $table->generate(); +.. literalinclude:: table/005.php + :lines: 2- 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:: - - $template = [ - 'table_open' => '', - - 'thead_open' => '', - 'thead_close' => '', - - 'heading_row_start' => '', - 'heading_row_end' => '', - 'heading_cell_start' => '', - - 'tfoot_open' => '', - 'tfoot_close' => '', - - 'footing_row_start' => '', - 'footing_row_end' => '', - 'footing_cell_start' => '', - - 'tbody_open' => '', - 'tbody_close' => '', - - 'row_start' => '', - 'row_end' => '', - 'cell_start' => '', - - 'row_alt_start' => '', - 'row_alt_end' => '', - 'cell_alt_start' => '', - - 'table_close' => '
    ', - 'heading_cell_end' => '
    ', - 'footing_cell_end' => '
    ', - 'cell_end' => '
    ', - 'cell_alt_end' => '
    ' - ]; +specify the design of your layout. Here is the template prototype: - $table->setTemplate($template); +.. literalinclude:: table/006.php + :lines: 2- .. note:: You'll notice there are two sets of "row" blocks in the template. These permit you to create alternating row colors or design @@ -130,23 +68,16 @@ specify the design of your layout. Here is the template prototype:: 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:: +example, only the table opening tag is being changed: - $template = [ - 'table_open' => '' - ]; - - $table->setTemplate($template); +.. literalinclude:: table/007.php + :lines: 2- You can also set defaults for these by passing an array of template settings -to the Table constructor.:: - - $customSettings = [ - 'table_open' => '
    ' - ]; - - $table = new \CodeIgniter\View\Table($customSettings); +to the Table constructor.: +.. literalinclude:: table/008.php + :lines: 2- *************** Class Reference @@ -157,15 +88,9 @@ Class Reference .. attribute:: $function = null Allows you to specify a native PHP function or a valid function array object to be applied to all cell data. - :: - - $table = new \CodeIgniter\View\Table(); - - $table->setHeading('Name', 'Color', 'Size'); - $table->addRow('Fred', 'Blue', 'Small'); - $table->function = 'htmlspecialchars'; - echo $table->generate(); + .. literalinclude:: table/009.php + :lines: 2- In the above example, all cell data would be run through PHP's :php:func:`htmlspecialchars()` function, resulting in:: @@ -186,9 +111,9 @@ Class Reference :rtype: Table Permits you to add a caption to the table. - :: - $table->setCaption('Colors'); + .. literalinclude:: table/010.php + :lines: 2- .. php:method:: setHeading([$args = [] [, ...]]) @@ -196,11 +121,10 @@ Class Reference :returns: Table instance (method chaining) :rtype: Table - Permits you to set the table heading. You can submit an array or discrete params:: + Permits you to set the table heading. You can submit an array or discrete params: - $table->setHeading('Name', 'Color', 'Size'); // or - - $table->setHeading(['Name', 'Color', 'Size']); + .. literalinclude:: table/011.php + :lines: 2- .. php:method:: setFooting([$args = [] [, ...]]) @@ -208,11 +132,10 @@ Class Reference :returns: Table instance (method chaining) :rtype: Table - Permits you to set the table footing. You can submit an array or discrete params:: - - $table->setFooting('Subtotal', $subtotal, $notes); // or + Permits you to set the table footing. You can submit an array or discrete params: - $table->setFooting(['Subtotal', $subtotal, $notes]); + .. literalinclude:: table/012.php + :lines: 2- .. php:method:: addRow([$args = [] [, ...]]) @@ -220,20 +143,16 @@ Class Reference :returns: Table instance (method chaining) :rtype: Table - Permits you to add a row to your table. You can submit an array or discrete params:: - - $table->addRow('Blue', 'Red', 'Green'); // or + Permits you to add a row to your table. You can submit an array or discrete params: - $table->addRow(['Blue', 'Red', 'Green']); + .. literalinclude:: table/013.php + :lines: 2- 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:: + The associative key **data** defines the cell's data. Any other key => val pairs are added as key='val' attributes to the tag: - $cell = ['data' => 'Blue', 'class' => 'highlight', 'colspan' => 2]; - $table->addRow($cell, 'Red', 'Green'); - - // generates - // + .. literalinclude:: table/014.php + :lines: 2- .. php:method:: makeColumns([$array = [] [, $columnLimit = 0]]) @@ -243,27 +162,10 @@ Class Reference :rtype: array 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:: - - $list = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve']; - - $newList = $table->makeColumns($list, 3); - - $table->generate($newList); - - // Generates a table with this prototype - -
    BlueRedGreen
    - - - - - - - - -
    onetwothree
    fourfivesix
    seveneightnine
    teneleventwelve
    + This allows a single array with many elements to be displayed in a table that has a fixed column count. Consider this example: + .. literalinclude:: table/015.php + :lines: 2- .. php:method:: setTemplate($template) @@ -272,13 +174,9 @@ Class Reference :rtype: bool Permits you to set your template. You can submit a full or partial template. - :: - - $template = [ - 'table_open' => '' - ]; - $table->setTemplate($template); + .. literalinclude:: table/016.php + :lines: 2- .. php:method:: setEmpty($value) @@ -287,9 +185,10 @@ Class Reference :rtype: Table Lets you set a default value for use in any table cells that are empty. - You might, for example, set a non-breaking space:: + You might, for example, set a non-breaking space: - $table->setEmpty(" "); + .. literalinclude:: table/017.php + :lines: 2- .. php:method:: clear() @@ -301,24 +200,7 @@ Class Reference should to call this method after each table has been generated to clear the previous table information. - Example :: - - $table = new \CodeIgniter\View\Table(); - - $table->setCaption('Preferences') - ->setHeading('Name', 'Color', 'Size') - ->addRow('Fred', 'Blue', 'Small') - ->addRow('Mary', 'Red', 'Large') - ->addRow('John', 'Green', 'Medium'); - - echo $table->generate(); - - $table->clear(); - - $table->setCaption('Shipping') - ->setHeading('Name', 'Day', 'Delivery') - ->addRow('Fred', 'Wednesday', 'Express') - ->addRow('Mary', 'Monday', 'Air') - ->addRow('John', 'Saturday', 'Overnight'); + Example - echo $table->generate(); + .. literalinclude:: table/018.php + :lines: 2- diff --git a/user_guide_src/source/outgoing/table/001.php b/user_guide_src/source/outgoing/table/001.php new file mode 100644 index 000000000000..dbd5ba323335 --- /dev/null +++ b/user_guide_src/source/outgoing/table/001.php @@ -0,0 +1,3 @@ +generate($data); diff --git a/user_guide_src/source/outgoing/table/003.php b/user_guide_src/source/outgoing/table/003.php new file mode 100644 index 000000000000..91218de3f143 --- /dev/null +++ b/user_guide_src/source/outgoing/table/003.php @@ -0,0 +1,7 @@ +query('SELECT * FROM my_table'); + +echo $table->generate($query); diff --git a/user_guide_src/source/outgoing/table/004.php b/user_guide_src/source/outgoing/table/004.php new file mode 100644 index 000000000000..0d0679305409 --- /dev/null +++ b/user_guide_src/source/outgoing/table/004.php @@ -0,0 +1,11 @@ +setHeading('Name', 'Color', 'Size'); + +$table->addRow('Fred', 'Blue', 'Small'); +$table->addRow('Mary', 'Red', 'Large'); +$table->addRow('John', 'Green', 'Medium'); + +echo $table->generate(); diff --git a/user_guide_src/source/outgoing/table/005.php b/user_guide_src/source/outgoing/table/005.php new file mode 100644 index 000000000000..06eaf75d9f8d --- /dev/null +++ b/user_guide_src/source/outgoing/table/005.php @@ -0,0 +1,11 @@ +setHeading(array('Name', 'Color', 'Size')); + +$table->addRow(['Fred', 'Blue', 'Small']); +$table->addRow(['Mary', 'Red', 'Large']); +$table->addRow(['John', 'Green', 'Medium']); + +echo $table->generate(); diff --git a/user_guide_src/source/outgoing/table/006.php b/user_guide_src/source/outgoing/table/006.php new file mode 100644 index 000000000000..2bc38b546950 --- /dev/null +++ b/user_guide_src/source/outgoing/table/006.php @@ -0,0 +1,38 @@ + '
    ', + + 'thead_open' => '', + 'thead_close' => '', + + 'heading_row_start' => '', + 'heading_row_end' => '', + 'heading_cell_start' => '', + + 'tfoot_open' => '', + 'tfoot_close' => '', + + 'footing_row_start' => '', + 'footing_row_end' => '', + 'footing_cell_start' => '', + + 'tbody_open' => '', + 'tbody_close' => '', + + 'row_start' => '', + 'row_end' => '', + 'cell_start' => '', + + 'row_alt_start' => '', + 'row_alt_end' => '', + 'cell_alt_start' => '', + + 'table_close' => '
    ', + 'heading_cell_end' => '
    ', + 'footing_cell_end' => '
    ', + 'cell_end' => '
    ', + 'cell_alt_end' => '
    ' +]; + +$table->setTemplate($template); diff --git a/user_guide_src/source/outgoing/table/007.php b/user_guide_src/source/outgoing/table/007.php new file mode 100644 index 000000000000..307d2e9a6c26 --- /dev/null +++ b/user_guide_src/source/outgoing/table/007.php @@ -0,0 +1,7 @@ + '' +]; + +$table->setTemplate($template); diff --git a/user_guide_src/source/outgoing/table/008.php b/user_guide_src/source/outgoing/table/008.php new file mode 100644 index 000000000000..9d6dbddd40c6 --- /dev/null +++ b/user_guide_src/source/outgoing/table/008.php @@ -0,0 +1,7 @@ + '
    ' +]; + +$table = new \CodeIgniter\View\Table($customSettings); diff --git a/user_guide_src/source/outgoing/table/009.php b/user_guide_src/source/outgoing/table/009.php new file mode 100644 index 000000000000..c08af5b1fa9a --- /dev/null +++ b/user_guide_src/source/outgoing/table/009.php @@ -0,0 +1,9 @@ +setHeading('Name', 'Color', 'Size'); +$table->addRow('Fred', 'Blue', 'Small'); + +$table->function = 'htmlspecialchars'; +echo $table->generate(); diff --git a/user_guide_src/source/outgoing/table/010.php b/user_guide_src/source/outgoing/table/010.php new file mode 100644 index 000000000000..0c6a74ea5b35 --- /dev/null +++ b/user_guide_src/source/outgoing/table/010.php @@ -0,0 +1,3 @@ +setCaption('Colors'); diff --git a/user_guide_src/source/outgoing/table/011.php b/user_guide_src/source/outgoing/table/011.php new file mode 100644 index 000000000000..a6657c8690e4 --- /dev/null +++ b/user_guide_src/source/outgoing/table/011.php @@ -0,0 +1,5 @@ +setHeading('Name', 'Color', 'Size'); // or + +$table->setHeading(['Name', 'Color', 'Size']); diff --git a/user_guide_src/source/outgoing/table/012.php b/user_guide_src/source/outgoing/table/012.php new file mode 100644 index 000000000000..01a26b237908 --- /dev/null +++ b/user_guide_src/source/outgoing/table/012.php @@ -0,0 +1,5 @@ +setFooting('Subtotal', $subtotal, $notes); // or + +$table->setFooting(['Subtotal', $subtotal, $notes]); diff --git a/user_guide_src/source/outgoing/table/013.php b/user_guide_src/source/outgoing/table/013.php new file mode 100644 index 000000000000..1229bd01d7cd --- /dev/null +++ b/user_guide_src/source/outgoing/table/013.php @@ -0,0 +1,5 @@ +addRow('Blue', 'Red', 'Green'); // or + +$table->addRow(['Blue', 'Red', 'Green']); diff --git a/user_guide_src/source/outgoing/table/014.php b/user_guide_src/source/outgoing/table/014.php new file mode 100644 index 000000000000..eb2e3d729a8c --- /dev/null +++ b/user_guide_src/source/outgoing/table/014.php @@ -0,0 +1,7 @@ + 'Blue', 'class' => 'highlight', 'colspan' => 2]; +$table->addRow($cell, 'Red', 'Green'); + +// generates +// diff --git a/user_guide_src/source/outgoing/table/015.php b/user_guide_src/source/outgoing/table/015.php new file mode 100644 index 000000000000..4f4349ec66b4 --- /dev/null +++ b/user_guide_src/source/outgoing/table/015.php @@ -0,0 +1,20 @@ +makeColumns($list, 3); + +$table->generate($newList); + +// Generates a table with this prototype + +
    BlueRedGreen
    + + + + + + + + +
    onetwothree
    fourfivesix
    seveneightnine
    teneleventwelve
    diff --git a/user_guide_src/source/outgoing/table/016.php b/user_guide_src/source/outgoing/table/016.php new file mode 100644 index 000000000000..307d2e9a6c26 --- /dev/null +++ b/user_guide_src/source/outgoing/table/016.php @@ -0,0 +1,7 @@ + '' +]; + +$table->setTemplate($template); diff --git a/user_guide_src/source/outgoing/table/017.php b/user_guide_src/source/outgoing/table/017.php new file mode 100644 index 000000000000..41ecff5926c7 --- /dev/null +++ b/user_guide_src/source/outgoing/table/017.php @@ -0,0 +1,3 @@ +setEmpty(" "); diff --git a/user_guide_src/source/outgoing/table/018.php b/user_guide_src/source/outgoing/table/018.php new file mode 100644 index 000000000000..c67c746bde9b --- /dev/null +++ b/user_guide_src/source/outgoing/table/018.php @@ -0,0 +1,21 @@ +setCaption('Preferences') + ->setHeading('Name', 'Color', 'Size') + ->addRow('Fred', 'Blue', 'Small') + ->addRow('Mary', 'Red', 'Large') + ->addRow('John', 'Green', 'Medium'); + +echo $table->generate(); + +$table->clear(); + +$table->setCaption('Shipping') + ->setHeading('Name', 'Day', 'Delivery') + ->addRow('Fred', 'Wednesday', 'Express') + ->addRow('Mary', 'Monday', 'Air') + ->addRow('John', 'Saturday', 'Overnight'); + +echo $table->generate(); diff --git a/user_guide_src/source/outgoing/view_decorators.rst b/user_guide_src/source/outgoing/view_decorators.rst index 513e9c1a3f0a..1620446785b0 100644 --- a/user_guide_src/source/outgoing/view_decorators.rst +++ b/user_guide_src/source/outgoing/view_decorators.rst @@ -13,29 +13,12 @@ Creating your own view decorators requires creating a new class that implements This requires a single method that takes the generated HTML string, performs any modifications on it, and returns the resulting HTML. -:: +.. literalinclude:: view_decorators/001.php - endSection() ?> endSection() ?> - ****************** Rendering the View ****************** -Rendering the view and it's layout is done exactly as any other view would be displayed within a controller:: +Rendering the view and it's layout is done exactly as any other view would be displayed within a controller: - public function index() - { - echo view('some_view'); - } +.. literalinclude:: view_layouts/001.php + :lines: 2- It renders the View **app/Views/some_view.php** and if it extends ``default``, the Layout **app/Views/default.php** is also used automatically. diff --git a/user_guide_src/source/outgoing/view_layouts/001.php b/user_guide_src/source/outgoing/view_layouts/001.php new file mode 100644 index 000000000000..5c6136bfe9ee --- /dev/null +++ b/user_guide_src/source/outgoing/view_layouts/001.php @@ -0,0 +1,6 @@ + 'My Blog Title', - 'blog_heading' => 'My Blog Heading', - ]; - - echo $parser->setData($data) - ->render('blog_template'); +.. literalinclude:: view_parser/003.php + :lines: 2- View parameters are passed to ``setData()`` as an associative array of data to be replaced in the template. In the above example, the @@ -116,12 +113,8 @@ Several options can be passed to the ``render()`` or ``renderString()`` methods. - ``cascadeData`` - true if pseudo-variable settings should be passed on to nested substitutions; default is **true** -:: - - echo $parser->render('blog_template', [ - 'cache' => HOUR, - 'cache_name' => 'something_unique', - ]); +.. literalinclude:: view_parser/004.php + :lines: 2- *********************** Substitution Variations @@ -132,14 +125,10 @@ Substitutions are performed in the same sequence that pseudo-variables were adde The **simple substitution** performed by the parser is a one-to-one replacement of pseudo-variables where the corresponding data parameter -has either a scalar or string value, as in this example:: - - $template = '{blog_title}'; - $data = ['blog_title' => 'My ramblings']; - - echo $parser->setData($data)->renderString($template); +has either a scalar or string value, as in this example: - // Result: My ramblings +.. literalinclude:: view_parser/005.php + :lines: 2- The ``Parser`` takes substitution a lot further with "variable pairs", used for nested substitutions or looping, and with some advanced @@ -184,22 +173,10 @@ the number of rows in the "blog_entries" element of the parameters array. Parsing variable pairs is done using the identical code shown above to parse single variables, except, you will add a multi-dimensional array -corresponding to your variable pair data. Consider this example:: +corresponding to your variable pair data. Consider this example: - $data = [ - 'blog_title' => 'My Blog Title', - 'blog_heading' => 'My Blog Heading', - 'blog_entries' => [ - ['title' => 'Title 1', 'body' => 'Body 1'], - ['title' => 'Title 2', 'body' => 'Body 2'], - ['title' => 'Title 3', 'body' => 'Body 3'], - ['title' => 'Title 4', 'body' => 'Body 4'], - ['title' => 'Title 5', 'body' => 'Body 5'], - ], - ]; - - echo $parser->setData($data) - ->render('blog_template'); +.. literalinclude:: view_parser/006.php + :lines: 2- The value for the pseudo-variable ``blog_entries`` is a sequential array of associative arrays. The outer level does not have keys associated @@ -207,18 +184,10 @@ with each of the nested "rows". If your "pair" data is coming from a database result, which is already a multi-dimensional array, you can simply use the database ``getResultArray()`` -method:: - - $query = $db->query("SELECT * FROM blog"); - - $data = [ - 'blog_title' => 'My Blog Title', - 'blog_heading' => 'My Blog Heading', - 'blog_entries' => $query->getResultArray(), - ]; +method: - echo $parser->setData($data) - ->render('blog_template'); +.. literalinclude:: view_parser/007.php + :lines: 2- If the array you are trying to loop over contains objects instead of arrays, the parser will first look for an ``asArray()`` method on the object. If it exists, @@ -234,19 +203,10 @@ Nested Substitutions ==================== A nested substitution happens when the value for a pseudo-variable is -an associative array of values, like a record from a database:: - - $data = [ - 'blog_title' => 'My Blog Title', - 'blog_heading' => 'My Blog Heading', - 'blog_entry' => [ - 'title' => 'Title 1', - 'body' => 'Body 1', - ], - ]; +an associative array of values, like a record from a database: - echo $parser->setData($data) - ->render('blog_template'); +.. literalinclude:: view_parser/008.php + :lines: 2- The value for the pseudo-variable ``blog_entry`` is an associative array. The key/value pairs defined inside it will be exposed inside @@ -287,32 +247,15 @@ Cascading Data With both a nested and a loop substitution, you have the option of cascading data pairs into the inner substitution. -The following example is not impacted by cascading:: - - $template = '{name} lives in {location}{city} on {planet}{/location}.'; - - $data = [ - 'name' => 'George', - 'location' => ['city' => 'Red City', 'planet' => 'Mars'], - ]; - - echo $parser->setData($data)->renderString($template); - // Result: George lives in Red City on Mars. - -This example gives different results, depending on cascading:: - - $template = '{location}{name} lives in {city} on {planet}{/location}.'; +The following example is not impacted by cascading: - $data = [ - 'name' => 'George', - 'location' => ['city' => 'Red City', 'planet' => 'Mars'], - ]; +.. literalinclude:: view_parser/009.php + :lines: 2- - echo $parser->setData($data)->renderString($template, ['cascadeData'=>false]); - // Result: {name} lives in Red City on Mars. +This example gives different results, depending on cascading: - echo $parser->setData($data)->renderString($template, ['cascadeData'=>true]); - // Result: George lives in Red City on Mars. +.. literalinclude:: view_parser/010.php + :lines: 2- Preventing Parsing ================== @@ -336,11 +279,9 @@ blocks must be closed with an ``endif`` tag::

    Welcome, Admin!

    {endif} -This simple block is converted to the following during parsing:: +This simple block is converted to the following during parsing: - -

    Welcome, Admin!

    - +.. literalinclude:: view_parser/010-2.php All variables used within if statements must have been previously set with the same name. Other than that, it is treated exactly like a standard PHP conditional, and all standard PHP rules would apply here. You can use any @@ -470,23 +411,20 @@ Custom Filters You can easily create your own filters by editing **app/Config/View.php** and adding new entries to the ``$filters`` array. Each key is the name of the filter is called by in the view, and its value is any valid PHP -callable:: +callable: - public $filters = [ - 'abs' => '\CodeIgniter\View\Filters::abs', - 'capitalize' => '\CodeIgniter\View\Filters::capitalize', - ]; +.. literalinclude:: view_parser/011.php + :lines: 2- PHP Native functions as Filters ------------------------------- You can use native php function as filters by editing **app/Config/View.php** and adding new entries to the ``$filters`` array.Each key is the name of the native PHP function is called by in the view, and its value is any valid native PHP -function prefixed with:: +function prefixed with: - public $filters = [ - 'str_repeat' => '\str_repeat', - ]; +.. literalinclude:: view_parser/012.php + :lines: 2- Parser Plugins ============== @@ -541,100 +479,50 @@ Registering a Plugin At its simplest, all you need to do to register a new plugin and make it ready for use is to add it to the **app/Config/View.php**, under the **$plugins** array. The key is the name of the plugin that is -used within the template file. The value is any valid PHP callable, including static class methods, and closures:: - - public $plugins = [ - 'foo' => '\Some\Class::methodName', - 'bar' => function ($str, array $params=[]) { - return $str; - }, - ]; - -Any closures that are being used must be defined in the config file's constructor:: +used within the template file. The value is any valid PHP callable, including static class methods, and closures: - class View extends \CodeIgniter\Config\View - { - public $plugins = []; +.. literalinclude:: view_parser/013.php + :lines: 2- - public function __construct() - { - $this->plugins['bar'] = function (array $params=[]) { - return $params[0] ?? ''; - }; +Any closures that are being used must be defined in the config file's constructor: - parent::__construct(); - } - } +.. literalinclude:: view_parser/014.php + :lines: 2- If the callable is on its own, it is treated as a single tag, not a open/close one. It will be replaced by -the return value from the plugin:: +the return value from the plugin: - public $plugins = [ - 'foo' => '\Some\Class::methodName' - ]; - - // Tag is replaced by the return value of Some\Class::methodName static function. - {+ foo +} +.. literalinclude:: view_parser/015.php + :lines: 2- If the callable is wrapped in an array, it is treated as an open/close tag pair that can operate on any of -the content between its tags:: - - public $plugins = [ - 'foo' => ['\Some\Class::methodName'] - ]; +the content between its tags: - {+ foo +} inner content {+ /foo +} +.. literalinclude:: view_parser/016.php + :lines: 2- *********** Usage Notes *********** If you include substitution parameters that are not referenced in your -template, they are ignored:: - - $template = 'Hello, {firstname} {lastname}'; - $data = [ - 'title' => 'Mr', - 'firstname' => 'John', - 'lastname' => 'Doe' - ]; - echo $parser->setData($data) - ->renderString($template); +template, they are ignored: - // Result: Hello, John Doe +.. literalinclude:: view_parser/017.php + :lines: 2- If you do not include a substitution parameter that is referenced in your -template, the original pseudo-variable is shown in the result:: +template, the original pseudo-variable is shown in the result: - $template = 'Hello, {firstname} {initials} {lastname}'; - $data = [ - 'title' => 'Mr', - 'firstname' => 'John', - 'lastname' => 'Doe', - ]; - echo $parser->setData($data) - ->renderString($template); - - // Result: Hello, John {initials} Doe +.. literalinclude:: view_parser/018.php + :lines: 2- If you provide a string substitution parameter when an array is expected, i.e., for a variable pair, the substitution is done for the opening variable -pair tag, but the closing variable pair tag is not rendered properly:: +pair tag, but the closing variable pair tag is not rendered properly: - $template = 'Hello, {firstname} {lastname} ({degrees}{degree} {/degrees})'; - $data = [ - 'degrees' => 'Mr', - 'firstname' => 'John', - 'lastname' => 'Doe', - 'titles' => [ - ['degree' => 'BSc'], - ['degree' => 'PhD'], - ], - ]; - echo $parser->setData($data) - ->renderString($template); - - // Result: Hello, John Doe (Mr{degree} {/degrees}) +.. literalinclude:: view_parser/019.php + :lines: 2- View Fragments ============== @@ -667,25 +555,10 @@ Result:: An example with the iteration controlled in the controller, -using a view fragment:: - - $temp = ''; - $template1 = '
  • {title}
  • '; - $data1 = [ - ['title' => 'First Link', 'link' => '/first'], - ['title' => 'Second Link', 'link' => '/second'], - ]; - - foreach ($data1 as $menuItem),{ - $temp .= $parser->setData($menuItem)->renderString($template1); - } +using a view fragment: - $template2 = '
      {menuitems}
    '; - $data = [ - 'menuitems' => $temp, - ]; - echo $parser->setData($data) - ->renderString($template2); +.. literalinclude:: view_parser/020.php + :lines: 2- Result:: @@ -708,9 +581,10 @@ Class Reference :returns: The rendered text for the chosen view :rtype: string - Builds the output based upon a file name and any data that has already been set:: + Builds the output based upon a file name and any data that has already been set: - echo $parser->render('myview'); + .. literalinclude:: view_parser/021.php + :lines: 2- Options supported: @@ -732,9 +606,10 @@ Class Reference :returns: The rendered text for the chosen view :rtype: string - Builds the output based upon a provided template source and any data that has already been set:: + Builds the output based upon a provided template source and any data that has already been set: - echo $parser->render('myview'); + .. literalinclude:: view_parser/021.php + :lines: 2- Options supported, and behavior, as above. @@ -745,9 +620,10 @@ Class Reference :returns: The Renderer, for method chaining :rtype: CodeIgniter\\View\\RendererInterface. - Sets several pieces of view data at once:: + Sets several pieces of view data at once: - $renderer->setData(['name' => 'George', 'position' => 'Boss']); + .. literalinclude:: view_parser/023.php + :lines: 2- Supported escape contexts: html, css, js, url, or attr or raw. If 'raw', no escaping will happen. @@ -760,9 +636,10 @@ Class Reference :returns: The Renderer, for method chaining :rtype: CodeIgniter\\View\\RendererInterface. - Sets a single piece of view data:: + Sets a single piece of view data: - $renderer->setVar('name','Joe','html'); + .. literalinclude:: view_parser/024.php + :lines: 2- Supported escape contexts: html, css, js, url, attr or raw. If 'raw', no escaping will happen. @@ -774,6 +651,7 @@ Class Reference :returns: The Renderer, for method chaining :rtype: CodeIgniter\\View\\RendererInterface. - Override the substitution field delimiters:: + Override the substitution field delimiters: - $renderer->setDelimiters('[',']'); + .. literalinclude:: view_parser/025.php + :lines: 2- diff --git a/user_guide_src/source/outgoing/view_parser/001.php b/user_guide_src/source/outgoing/view_parser/001.php new file mode 100644 index 000000000000..56f7f51e4a07 --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/001.php @@ -0,0 +1,3 @@ + 'My Blog Title', + 'blog_heading' => 'My Blog Heading', +]; + +echo $parser->setData($data) + ->render('blog_template'); diff --git a/user_guide_src/source/outgoing/view_parser/004.php b/user_guide_src/source/outgoing/view_parser/004.php new file mode 100644 index 000000000000..70862b585adc --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/004.php @@ -0,0 +1,6 @@ +render('blog_template', [ + 'cache' => HOUR, + 'cache_name' => 'something_unique', +]); diff --git a/user_guide_src/source/outgoing/view_parser/005.php b/user_guide_src/source/outgoing/view_parser/005.php new file mode 100644 index 000000000000..6681b588d74e --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/005.php @@ -0,0 +1,8 @@ +{blog_title}'; +$data = ['blog_title' => 'My ramblings']; + +echo $parser->setData($data)->renderString($template); + +// Result: My ramblings diff --git a/user_guide_src/source/outgoing/view_parser/006.php b/user_guide_src/source/outgoing/view_parser/006.php new file mode 100644 index 000000000000..1bedecc07c0a --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/006.php @@ -0,0 +1,16 @@ + 'My Blog Title', + 'blog_heading' => 'My Blog Heading', + 'blog_entries' => [ + ['title' => 'Title 1', 'body' => 'Body 1'], + ['title' => 'Title 2', 'body' => 'Body 2'], + ['title' => 'Title 3', 'body' => 'Body 3'], + ['title' => 'Title 4', 'body' => 'Body 4'], + ['title' => 'Title 5', 'body' => 'Body 5'], + ], +]; + +echo $parser->setData($data) + ->render('blog_template'); diff --git a/user_guide_src/source/outgoing/view_parser/007.php b/user_guide_src/source/outgoing/view_parser/007.php new file mode 100644 index 000000000000..8932712a7835 --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/007.php @@ -0,0 +1,12 @@ +query("SELECT * FROM blog"); + +$data = [ + 'blog_title' => 'My Blog Title', + 'blog_heading' => 'My Blog Heading', + 'blog_entries' => $query->getResultArray(), +]; + +echo $parser->setData($data) + ->render('blog_template'); diff --git a/user_guide_src/source/outgoing/view_parser/008.php b/user_guide_src/source/outgoing/view_parser/008.php new file mode 100644 index 000000000000..ef502cf5e3af --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/008.php @@ -0,0 +1,13 @@ + 'My Blog Title', + 'blog_heading' => 'My Blog Heading', + 'blog_entry' => [ + 'title' => 'Title 1', + 'body' => 'Body 1', + ], +]; + +echo $parser->setData($data) + ->render('blog_template'); diff --git a/user_guide_src/source/outgoing/view_parser/009.php b/user_guide_src/source/outgoing/view_parser/009.php new file mode 100644 index 000000000000..6b112fdd6829 --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/009.php @@ -0,0 +1,11 @@ + 'George', + 'location' => ['city' => 'Red City', 'planet' => 'Mars'], +]; + +echo $parser->setData($data)->renderString($template); +// Result: George lives in Red City on Mars. diff --git a/user_guide_src/source/outgoing/view_parser/010-2.php b/user_guide_src/source/outgoing/view_parser/010-2.php new file mode 100644 index 000000000000..8030f44e8883 --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/010-2.php @@ -0,0 +1,3 @@ + +

    Welcome, Admin!

    + diff --git a/user_guide_src/source/outgoing/view_parser/010.php b/user_guide_src/source/outgoing/view_parser/010.php new file mode 100644 index 000000000000..33439f861407 --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/010.php @@ -0,0 +1,14 @@ + 'George', + 'location' => ['city' => 'Red City', 'planet' => 'Mars'], +]; + +echo $parser->setData($data)->renderString($template, ['cascadeData'=>false]); +// Result: {name} lives in Red City on Mars. + +echo $parser->setData($data)->renderString($template, ['cascadeData'=>true]); +// Result: George lives in Red City on Mars. diff --git a/user_guide_src/source/outgoing/view_parser/011.php b/user_guide_src/source/outgoing/view_parser/011.php new file mode 100644 index 000000000000..39eae3da0177 --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/011.php @@ -0,0 +1,6 @@ + '\CodeIgniter\View\Filters::abs', + 'capitalize' => '\CodeIgniter\View\Filters::capitalize', +]; diff --git a/user_guide_src/source/outgoing/view_parser/012.php b/user_guide_src/source/outgoing/view_parser/012.php new file mode 100644 index 000000000000..dbb096b416fb --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/012.php @@ -0,0 +1,5 @@ + '\str_repeat', +]; diff --git a/user_guide_src/source/outgoing/view_parser/013.php b/user_guide_src/source/outgoing/view_parser/013.php new file mode 100644 index 000000000000..d959d153d415 --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/013.php @@ -0,0 +1,8 @@ + '\Some\Class::methodName', + 'bar' => function ($str, array $params=[]) { + return $str; + }, +]; diff --git a/user_guide_src/source/outgoing/view_parser/014.php b/user_guide_src/source/outgoing/view_parser/014.php new file mode 100644 index 000000000000..bac6137888f1 --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/014.php @@ -0,0 +1,15 @@ +plugins['bar'] = function (array $params=[]) { + return $params[0] ?? ''; + }; + + parent::__construct(); + } +} diff --git a/user_guide_src/source/outgoing/view_parser/015.php b/user_guide_src/source/outgoing/view_parser/015.php new file mode 100644 index 000000000000..74a18943365c --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/015.php @@ -0,0 +1,8 @@ + '\Some\Class::methodName' +]; + +// Tag is replaced by the return value of Some\Class::methodName static function. +{+ foo +} diff --git a/user_guide_src/source/outgoing/view_parser/016.php b/user_guide_src/source/outgoing/view_parser/016.php new file mode 100644 index 000000000000..30d72b247059 --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/016.php @@ -0,0 +1,7 @@ + ['\Some\Class::methodName'] +]; + +{+ foo +} inner content {+ /foo +} diff --git a/user_guide_src/source/outgoing/view_parser/017.php b/user_guide_src/source/outgoing/view_parser/017.php new file mode 100644 index 000000000000..cd9ca09109b9 --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/017.php @@ -0,0 +1,12 @@ + 'Mr', + 'firstname' => 'John', + 'lastname' => 'Doe' +]; +echo $parser->setData($data) + ->renderString($template); + +// Result: Hello, John Doe diff --git a/user_guide_src/source/outgoing/view_parser/018.php b/user_guide_src/source/outgoing/view_parser/018.php new file mode 100644 index 000000000000..dfce0c26ccb4 --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/018.php @@ -0,0 +1,12 @@ + 'Mr', + 'firstname' => 'John', + 'lastname' => 'Doe', +]; +echo $parser->setData($data) + ->renderString($template); + +// Result: Hello, John {initials} Doe diff --git a/user_guide_src/source/outgoing/view_parser/019.php b/user_guide_src/source/outgoing/view_parser/019.php new file mode 100644 index 000000000000..371fa9a21f14 --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/019.php @@ -0,0 +1,16 @@ + 'Mr', + 'firstname' => 'John', + 'lastname' => 'Doe', + 'titles' => [ + ['degree' => 'BSc'], + ['degree' => 'PhD'], + ], +]; +echo $parser->setData($data) + ->renderString($template); + +// Result: Hello, John Doe (Mr{degree} {/degrees}) diff --git a/user_guide_src/source/outgoing/view_parser/020.php b/user_guide_src/source/outgoing/view_parser/020.php new file mode 100644 index 000000000000..cf7b31fa7e30 --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/020.php @@ -0,0 +1,19 @@ +{title}'; +$data1 = [ + ['title' => 'First Link', 'link' => '/first'], + ['title' => 'Second Link', 'link' => '/second'], +]; + +foreach ($data1 as $menuItem),{ + $temp .= $parser->setData($menuItem)->renderString($template1); +} + +$template2 = '
      {menuitems}
    '; +$data = [ + 'menuitems' => $temp, +]; +echo $parser->setData($data) + ->renderString($template2); diff --git a/user_guide_src/source/outgoing/view_parser/021.php b/user_guide_src/source/outgoing/view_parser/021.php new file mode 100644 index 000000000000..022450bb6fd6 --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/021.php @@ -0,0 +1,3 @@ +render('myview'); diff --git a/user_guide_src/source/outgoing/view_parser/022.php b/user_guide_src/source/outgoing/view_parser/022.php new file mode 100644 index 000000000000..022450bb6fd6 --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/022.php @@ -0,0 +1,3 @@ +render('myview'); diff --git a/user_guide_src/source/outgoing/view_parser/023.php b/user_guide_src/source/outgoing/view_parser/023.php new file mode 100644 index 000000000000..42ddfa949331 --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/023.php @@ -0,0 +1,3 @@ +setData(['name' => 'George', 'position' => 'Boss']); diff --git a/user_guide_src/source/outgoing/view_parser/024.php b/user_guide_src/source/outgoing/view_parser/024.php new file mode 100644 index 000000000000..76ba0b537f96 --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/024.php @@ -0,0 +1,3 @@ +setVar('name','Joe','html'); diff --git a/user_guide_src/source/outgoing/view_parser/025.php b/user_guide_src/source/outgoing/view_parser/025.php new file mode 100644 index 000000000000..a8633d5717c7 --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/025.php @@ -0,0 +1,3 @@ +setDelimiters('[',']'); diff --git a/user_guide_src/source/outgoing/view_renderer.rst b/user_guide_src/source/outgoing/view_renderer.rst index 7da85b6f9546..bf1570cede9c 100644 --- a/user_guide_src/source/outgoing/view_renderer.rst +++ b/user_guide_src/source/outgoing/view_renderer.rst @@ -12,14 +12,16 @@ Using the View Renderer The ``view()`` function is a convenience function that grabs an instance of the ``renderer`` service, sets the data, and renders the view. While this is often exactly what you want, you may find times where you want to work with it more directly. -In that case you can access the View service directly:: +In that case you can access the View service directly: - $view = \Config\Services::renderer(); +.. literalinclude:: view_renderer/001.php + :lines: 2- Alternately, if you are not using the ``View`` class as your default renderer, you -can instantiate it directly:: +can instantiate it directly: - $view = new \CodeIgniter\View\View(); +.. literalinclude:: view_renderer/002.php + :lines: 2- .. important:: You should create services only within controllers. If you need access to the View class from a library, you should set that as a dependency @@ -49,11 +51,10 @@ Method Chaining =============== The ``setVar()`` and ``setData()`` methods are chainable, allowing you to combine a -number of different calls together in a chain:: +number of different calls together in a chain: - $view->setVar('one', $one) - ->setVar('two', $two) - ->render('myView'); +.. literalinclude:: view_renderer/003.php + :lines: 2- Escaping Data ============= @@ -62,9 +63,10 @@ When you pass data to the ``setVar()`` and ``setData()`` functions you have the against cross-site scripting attacks. As the last parameter in either method, you can pass the desired context to escape the data for. See below for context descriptions. -If you don't want the data to be escaped, you can pass ``null`` or ``'raw'`` as the final parameter to each function:: +If you don't want the data to be escaped, you can pass ``null`` or ``'raw'`` as the final parameter to each function: - $view->setVar('one', $one, 'raw'); +.. literalinclude:: view_renderer/004.php + :lines: 2- If you choose not to escape data, or you are passing in an object instance, you can manually escape the data within the view with the ``esc()`` function. The first parameter is the string to escape. The second parameter is the @@ -118,9 +120,10 @@ Class Reference :returns: The rendered text for the chosen view :rtype: string - Builds the output based upon a file name and any data that has already been set:: + Builds the output based upon a file name and any data that has already been set: - echo $view->render('myview'); + .. literalinclude:: view_renderer/005.php + :lines: 2- .. php:method:: renderString($view[, $options[, $saveData = false]]) :noindex: @@ -131,9 +134,10 @@ Class Reference :returns: The rendered text for the chosen view :rtype: string - Builds the output based upon a view fragment and any data that has already been set:: + Builds the output based upon a view fragment and any data that has already been set: - echo $view->renderString('
    My Sharona
    '); + .. literalinclude:: view_renderer/006.php + :lines: 2- .. warning:: This could be used for displaying content that might have been stored in a database, but you need to be aware that this is a potential security vulnerability, @@ -148,9 +152,10 @@ Class Reference :returns: The Renderer, for method chaining :rtype: CodeIgniter\\View\\RendererInterface. - Sets several pieces of view data at once:: + Sets several pieces of view data at once: - $view->setData(['name'=>'George', 'position'=>'Boss']); + .. literalinclude:: view_renderer/007.php + :lines: 2- Supported escape contexts: ``html``, ``css``, ``js``, ``url``, or ``attr`` or ``raw``. If ``'raw'``, no escaping will happen. @@ -167,9 +172,10 @@ Class Reference :returns: The Renderer, for method chaining :rtype: CodeIgniter\\View\\RendererInterface. - Sets a single piece of view data:: + Sets a single piece of view data: - $view->setVar('name','Joe','html'); + .. literalinclude:: view_renderer/008.php + :lines: 2- Supported escape contexts: ``html``, ``css``, ``js``, ``url``, ``attr`` or ``raw``. If ``'raw'``, no escaping will happen. diff --git a/user_guide_src/source/outgoing/view_renderer/001.php b/user_guide_src/source/outgoing/view_renderer/001.php new file mode 100644 index 000000000000..2772e22cad0d --- /dev/null +++ b/user_guide_src/source/outgoing/view_renderer/001.php @@ -0,0 +1,3 @@ +setVar('one', $one) + ->setVar('two', $two) + ->render('myView'); diff --git a/user_guide_src/source/outgoing/view_renderer/004.php b/user_guide_src/source/outgoing/view_renderer/004.php new file mode 100644 index 000000000000..b690f3478c82 --- /dev/null +++ b/user_guide_src/source/outgoing/view_renderer/004.php @@ -0,0 +1,3 @@ +setVar('one', $one, 'raw'); diff --git a/user_guide_src/source/outgoing/view_renderer/005.php b/user_guide_src/source/outgoing/view_renderer/005.php new file mode 100644 index 000000000000..9bb35502f352 --- /dev/null +++ b/user_guide_src/source/outgoing/view_renderer/005.php @@ -0,0 +1,3 @@ +render('myview'); diff --git a/user_guide_src/source/outgoing/view_renderer/006.php b/user_guide_src/source/outgoing/view_renderer/006.php new file mode 100644 index 000000000000..8f3c21abd99d --- /dev/null +++ b/user_guide_src/source/outgoing/view_renderer/006.php @@ -0,0 +1,3 @@ +renderString('
    My Sharona
    '); diff --git a/user_guide_src/source/outgoing/view_renderer/007.php b/user_guide_src/source/outgoing/view_renderer/007.php new file mode 100644 index 000000000000..1b45fef3dca5 --- /dev/null +++ b/user_guide_src/source/outgoing/view_renderer/007.php @@ -0,0 +1,3 @@ +setData(['name'=>'George', 'position'=>'Boss']); diff --git a/user_guide_src/source/outgoing/view_renderer/008.php b/user_guide_src/source/outgoing/view_renderer/008.php new file mode 100644 index 000000000000..284b58caf6be --- /dev/null +++ b/user_guide_src/source/outgoing/view_renderer/008.php @@ -0,0 +1,3 @@ +setVar('name','Joe','html'); diff --git a/user_guide_src/source/outgoing/views.rst b/user_guide_src/source/outgoing/views.rst index 96e350216ce7..9c386f3feb7c 100644 --- a/user_guide_src/source/outgoing/views.rst +++ b/user_guide_src/source/outgoing/views.rst @@ -35,27 +35,18 @@ Then save the file in your **app/Views** directory. Displaying a View ================= -To load and display a particular view file you will use the following function:: +To load and display a particular view file you will use the following function: - echo view('name'); +.. literalinclude:: views/001.php + :lines: 2- Where *name* is the name of your view file. .. important:: If the file extension is omitted, then the views are expected to end with the .php extension. -Now, open the controller file you made earlier called ``Blog.php``, and replace the echo statement with the view function:: +Now, open the controller file you made earlier called ``Blog.php``, and replace the echo statement with the view function: - 'Your title', - ]; +content view, and a footer view. That might look something like this: - echo view('header'); - echo view('menu'); - echo view('content', $data); - echo view('footer'); - } - } +.. literalinclude:: views/003.php In the example above, we are using "dynamically added data", which you will see below. @@ -96,9 +70,10 @@ Storing Views within Sub-directories ==================================== Your view files can also be stored within sub-directories if you prefer that type of organization. -When doing so you will need to include the directory name loading the view. Example:: +When doing so you will need to include the directory name loading the view. Example: - echo view('directory_name/file_name'); +.. literalinclude:: views/004.php + :lines: 2- Namespaced Views ================ @@ -109,9 +84,10 @@ to package your views together in a module-like fashion for easy re-use or distr If you have ``example/blog`` directory that has a PSR-4 mapping set up in the :doc:`Autoloader ` living under the namespace ``Example\Blog``, you could retrieve view files as if they were namespaced also. Following this -example, you could load the **blog_view.php** file from **example/blog/Views** by prepending the namespace to the view name:: +example, you could load the **blog_view.php** file from **example/blog/Views** by prepending the namespace to the view name: - echo view('Example\Blog\Views\blog_view'); +.. literalinclude:: views/005.php + :lines: 2- .. _caching-views: @@ -119,47 +95,29 @@ Caching Views ============= You can cache a view with the ``view`` command by passing a ``cache`` option with the number of seconds to cache -the view for, in the third parameter:: +the view for, in the third parameter: - // Cache the view for 60 seconds - echo view('file_name', $data, ['cache' => 60]); +.. literalinclude:: views/006.php + :lines: 2- By default, the view will be cached using the same name as the view file itself. You can customize this by passing -along ``cache_name`` and the cache ID you wish to use:: +along ``cache_name`` and the cache ID you wish to use: - // Cache the view for 60 seconds - echo view('file_name', $data, ['cache' => 60, 'cache_name' => 'my_cached_view']); +.. literalinclude:: views/007.php + :lines: 2- Adding Dynamic Data to the View =============================== Data is passed from the controller to the view by way of an array in the second parameter of the view function. -Here's an example:: +Here's an example: - $data = [ - 'title' => 'My title', - 'heading' => 'My Heading', - 'message' => 'My Message', - ]; +.. literalinclude:: views/008.php + :lines: 2- - echo view('blog_view', $data); +Let's try it with your controller file. Open it and add this code: -Let's try it with your controller file. Open it and add this code:: - - 'My title', - 'heading' => 'My Heading', - 'message' => 'My Message', - ]; - echo view('blog_view', $data, ['saveData' => true]); +.. literalinclude:: views/010.php + :lines: 2- Additionally, if you would like the default functionality of the view function to be that it does save the data between calls, you can set ``$saveData`` to **true** in **app/Config/Views.php**. @@ -198,44 +150,10 @@ The data array you pass to your view files is not limited to simple variables. Y arrays, which can be looped to generate multiple rows. For example, if you pull data from your database it will typically be in the form of a multi-dimensional array. -Here’s a simple example. Add this to your controller:: +Here’s a simple example. Add this to your controller: - ['Clean House', 'Call Mom', 'Run Errands'], - 'title' => 'My Real Title', - 'heading' => 'My Real Heading', - ]; - - echo view('blog_view', $data); - } - } - -Now open your view file and create a loop:: - - - - <?= esc($title) ?> - - -

    - -

    My Todo List

    - -
      - - -
    • - - -
    - - - +.. literalinclude:: views/012.php diff --git a/user_guide_src/source/outgoing/views/001.php b/user_guide_src/source/outgoing/views/001.php new file mode 100644 index 000000000000..90c817235bf5 --- /dev/null +++ b/user_guide_src/source/outgoing/views/001.php @@ -0,0 +1,3 @@ + 'Your title', + ]; + + echo view('header'); + echo view('menu'); + echo view('content', $data); + echo view('footer'); + } +} diff --git a/user_guide_src/source/outgoing/views/004.php b/user_guide_src/source/outgoing/views/004.php new file mode 100644 index 000000000000..d77e328657f3 --- /dev/null +++ b/user_guide_src/source/outgoing/views/004.php @@ -0,0 +1,3 @@ + 60]); diff --git a/user_guide_src/source/outgoing/views/007.php b/user_guide_src/source/outgoing/views/007.php new file mode 100644 index 000000000000..b1d22eb55260 --- /dev/null +++ b/user_guide_src/source/outgoing/views/007.php @@ -0,0 +1,4 @@ + 60, 'cache_name' => 'my_cached_view']); diff --git a/user_guide_src/source/outgoing/views/008.php b/user_guide_src/source/outgoing/views/008.php new file mode 100644 index 000000000000..c9b2ab2f5bbd --- /dev/null +++ b/user_guide_src/source/outgoing/views/008.php @@ -0,0 +1,9 @@ + 'My title', + 'heading' => 'My Heading', + 'message' => 'My Message', +]; + +echo view('blog_view', $data); diff --git a/user_guide_src/source/outgoing/views/009.php b/user_guide_src/source/outgoing/views/009.php new file mode 100644 index 000000000000..02ce288dd6c8 --- /dev/null +++ b/user_guide_src/source/outgoing/views/009.php @@ -0,0 +1,14 @@ + 'My title', + 'heading' => 'My Heading', + 'message' => 'My Message', +]; + +echo view('blog_view', $data, ['saveData' => true]); diff --git a/user_guide_src/source/outgoing/views/011.php b/user_guide_src/source/outgoing/views/011.php new file mode 100644 index 000000000000..2f3cb13c2989 --- /dev/null +++ b/user_guide_src/source/outgoing/views/011.php @@ -0,0 +1,17 @@ + ['Clean House', 'Call Mom', 'Run Errands'], + 'title' => 'My Real Title', + 'heading' => 'My Real Heading', + ]; + + echo view('blog_view', $data); + } +} diff --git a/user_guide_src/source/outgoing/views/012.php b/user_guide_src/source/outgoing/views/012.php new file mode 100644 index 000000000000..5a3781fe6720 --- /dev/null +++ b/user_guide_src/source/outgoing/views/012.php @@ -0,0 +1,19 @@ + + + <?= esc($title) ?> + + +

    + +

    My Todo List

    + +
      + + +
    • + + +
    + + + diff --git a/user_guide_src/source/testing/benchmark.rst b/user_guide_src/source/testing/benchmark.rst index 780dcfe8ac08..33fe7c200be9 100644 --- a/user_guide_src/source/testing/benchmark.rst +++ b/user_guide_src/source/testing/benchmark.rst @@ -23,48 +23,39 @@ it simple to measure the performance of different aspects of your application. A the ``start()`` and ``stop()`` methods. The ``start()`` methods takes a single parameter: the name of this timer. You can use any string as the name -of the timer. It is only used for you to reference later to know which measurement is which:: +of the timer. It is only used for you to reference later to know which measurement is which: - $benchmark = \Config\Services::timer(); - $benchmark->start('render view'); +.. literalinclude:: benchmark/001.php + :lines: 2- -The ``stop()`` method takes the name of the timer that you want to stop as the only parameter, also:: +The ``stop()`` method takes the name of the timer that you want to stop as the only parameter, also: - $benchmark->stop('render view'); +.. literalinclude:: benchmark/002.php + :lines: 2- The name is not case-sensitive, but otherwise must match the name you gave it when you started the timer. Alternatively, you can use the :doc:`global function ` ``timer()`` to start -and stop timers:: +and stop timers: - // Start the timer - timer('render view'); - // Stop a running timer, - // if one of this name has been started - timer('render view'); +.. literalinclude:: benchmark/003.php + :lines: 2- Viewing Your Benchmark Points ============================= When your application runs, all of the timers that you have set are collected by the Timer class. It does not automatically display them, though. You can retrieve all of your timers by calling the ``getTimers()`` method. -This returns an array of benchmark information, including start, end, and duration:: +This returns an array of benchmark information, including start, end, and duration: - $timers = $benchmark->getTimers(); - - // Timers = - [ - 'render view' => [ - 'start' => 1234567890, - 'end' => 1345678920, - 'duration' => 15.4315, // number of seconds - ] - ] +.. literalinclude:: benchmark/004.php + :lines: 2- You can change the precision of the calculated duration by passing in the number of decimal places you want to be shown as -the only parameter. The default value is 4 numbers behind the decimal point:: +the only parameter. The default value is 4 numbers behind the decimal point: - $timers = $benchmark->getTimers(6); +.. literalinclude:: benchmark/005.php + :lines: 2- The timers are automatically displayed in the :doc:`Debub Toolbar `. @@ -73,10 +64,10 @@ Displaying Execution Time While the ``getTimers()`` method will give you the raw data for all of the timers in your project, you can retrieve the duration of a single timer, in seconds, with the `getElapsedTime()` method. The first parameter is the name of -the timer to display. The second is the number of decimal places to display. This defaults to 4:: +the timer to display. The second is the number of decimal places to display. This defaults to 4: - echo timer()->getElapsedTime('render view'); - // Displays: 0.0234 +.. literalinclude:: benchmark/006.php + :lines: 2- ================== Using the Iterator @@ -92,32 +83,23 @@ Creating Tasks To Run Tasks are defined within Closures. Any output the task creates will be discarded automatically. They are added to the Iterator class through the `add()` method. The first parameter is a name you want to refer to -this test by. The second parameter is the Closure, itself:: - - $iterator = new \CodeIgniter\Benchmark\Iterator(); - - // Add a new task - $iterator->add('single_concat', function () { - $str = 'Some basic'.'little'.'string concatenation test.'; - }); +this test by. The second parameter is the Closure, itself: - // Add another task - $iterator->add('double', function ($a = 'little') { - $str = "Some basic {$little} string test."; - }); +.. literalinclude:: benchmark/007.php + :lines: 2- Running the Tasks ================= Once you've added the tasks to run, you can use the ``run()`` method to loop over the tasks many times. By default, it will run each task 1000 times. This is probably sufficient for most simple tests. If you need -to run the tests more times than that, you can pass the number as the first parameter:: +to run the tests more times than that, you can pass the number as the first parameter: - // Run the tests 3000 times. - $iterator->run(3000); +.. literalinclude:: benchmark/008.php + :lines: 2- Once it has run, it will return an HTML table with the results of the test. If you don't want the results -displayed, you can pass in `false` as the second parameter:: +displayed, you can pass in `false` as the second parameter: - // Don't display the results. - $iterator->run(1000, false); +.. literalinclude:: benchmark/009.php + :lines: 2- diff --git a/user_guide_src/source/testing/benchmark/001.php b/user_guide_src/source/testing/benchmark/001.php new file mode 100644 index 000000000000..ce3bd09ac87f --- /dev/null +++ b/user_guide_src/source/testing/benchmark/001.php @@ -0,0 +1,4 @@ +start('render view'); diff --git a/user_guide_src/source/testing/benchmark/002.php b/user_guide_src/source/testing/benchmark/002.php new file mode 100644 index 000000000000..003d1cc18cf7 --- /dev/null +++ b/user_guide_src/source/testing/benchmark/002.php @@ -0,0 +1,3 @@ +stop('render view'); diff --git a/user_guide_src/source/testing/benchmark/003.php b/user_guide_src/source/testing/benchmark/003.php new file mode 100644 index 000000000000..861dbd8232a5 --- /dev/null +++ b/user_guide_src/source/testing/benchmark/003.php @@ -0,0 +1,7 @@ +getTimers(); + +// Timers = +[ + 'render view' => [ + 'start' => 1234567890, + 'end' => 1345678920, + 'duration' => 15.4315, // number of seconds + ] +] diff --git a/user_guide_src/source/testing/benchmark/005.php b/user_guide_src/source/testing/benchmark/005.php new file mode 100644 index 000000000000..309c02f92a9b --- /dev/null +++ b/user_guide_src/source/testing/benchmark/005.php @@ -0,0 +1,3 @@ +getTimers(6); diff --git a/user_guide_src/source/testing/benchmark/006.php b/user_guide_src/source/testing/benchmark/006.php new file mode 100644 index 000000000000..a5f93a20fbf9 --- /dev/null +++ b/user_guide_src/source/testing/benchmark/006.php @@ -0,0 +1,4 @@ +getElapsedTime('render view'); +// Displays: 0.0234 diff --git a/user_guide_src/source/testing/benchmark/007.php b/user_guide_src/source/testing/benchmark/007.php new file mode 100644 index 000000000000..c126ed4a9670 --- /dev/null +++ b/user_guide_src/source/testing/benchmark/007.php @@ -0,0 +1,13 @@ +add('single_concat', function () { + $str = 'Some basic'.'little'.'string concatenation test.'; +}); + +// Add another task +$iterator->add('double', function ($a = 'little') { + $str = "Some basic {$little} string test."; +}); diff --git a/user_guide_src/source/testing/benchmark/008.php b/user_guide_src/source/testing/benchmark/008.php new file mode 100644 index 000000000000..da0f6a83b5fa --- /dev/null +++ b/user_guide_src/source/testing/benchmark/008.php @@ -0,0 +1,4 @@ +run(3000); diff --git a/user_guide_src/source/testing/benchmark/009.php b/user_guide_src/source/testing/benchmark/009.php new file mode 100644 index 000000000000..1f30692559b2 --- /dev/null +++ b/user_guide_src/source/testing/benchmark/009.php @@ -0,0 +1,4 @@ +run(1000, false); diff --git a/user_guide_src/source/testing/controllers.rst b/user_guide_src/source/testing/controllers.rst index d5dd2d379b8b..590e491ed687 100644 --- a/user_guide_src/source/testing/controllers.rst +++ b/user_guide_src/source/testing/controllers.rst @@ -17,47 +17,16 @@ case you need it. The Helper Trait ================ -To enable Controller Testing you need to use the ``ControllerTestTrait`` trait within your tests:: +To enable Controller Testing you need to use the ``ControllerTestTrait`` trait within your tests: - withURI('http://example.com/categories') - ->controller(\App\Controllers\ForumController::class) - ->execute('showCategories'); - - $this->assertTrue($result->isOK()); - } - } +.. literalinclude:: controllers/002.php Helper Methods ============== @@ -65,16 +34,17 @@ Helper Methods **controller($class)** Specifies the class name of the controller to test. The first parameter must be a fully qualified class name -(i.e., include the namespace):: +(i.e., include the namespace): - $this->controller(\App\Controllers\ForumController::class); +.. literalinclude:: controllers/003.php + :lines: 2- **execute(string $method, ...$params)** -Executes the specified method within the controller. The first parameter is the name of the method to run:: +Executes the specified method within the controller. The first parameter is the name of the method to run: - $results = $this->controller(\App\Controllers\ForumController::class) - ->execute('showCategories'); +.. literalinclude:: controllers/004.php + :lines: 2- By specifying the second and subsequent parameters, you can pass them to the controller method. @@ -83,54 +53,39 @@ for details. **withConfig($config)** -Allows you to pass in a modified version of **Config\App.php** to test with different settings:: +Allows you to pass in a modified version of **Config\App.php** to test with different settings: - $config = new Config\App(); - $config->appTimezone = 'America/Chicago'; - - $results = $this->withConfig($config) - ->controller(\App\Controllers\ForumController::class) - ->execute('showCategories'); +.. literalinclude:: controllers/005.php + :lines: 2- If you do not provide one, the application's App config file will be used. **withRequest($request)** -Allows you to provide an **IncomingRequest** instance tailored to your testing needs:: - - $request = new \CodeIgniter\HTTP\IncomingRequest(new \Config\App(), new URI('http://example.com')); - $request->setLocale($locale); +Allows you to provide an **IncomingRequest** instance tailored to your testing needs: - $results = $this->withRequest($request) - ->controller(\App\Controllers\ForumController::class) - ->execute('showCategories'); +.. literalinclude:: controllers/006.php + :lines: 2- If you do not provide one, a new IncomingRequest instance with the default application values will be passed into your controller. **withResponse($response)** -Allows you to provide a **Response** instance:: +Allows you to provide a **Response** instance: - $response = new \CodeIgniter\HTTP\Response(new \Config\App()); - - $results = $this->withResponse($response) - ->controller(\App\Controllers\ForumController::class) - ->execute('showCategories'); +.. literalinclude:: controllers/007.php + :lines: 2- If you do not provide one, a new Response instance with the default application values will be passed into your controller. **withLogger($logger)** -Allows you to provide a **Logger** instance:: - - $logger = new \CodeIgniter\Log\Handlers\FileHandler(); +Allows you to provide a **Logger** instance: - $results = $this->withResponse($response) - ->withLogger($logger) - ->controller(\App\Controllers\ForumController::class) - ->execute('showCategories'); +.. literalinclude:: controllers/008.php + :lines: 2- If you do not provide one, a new Logger instance with the default configuration values will be passed into your controller. @@ -139,24 +94,20 @@ into your controller. Allows you to provide a new URI that simulates the URL the client was visiting when this controller was run. This is helpful if you need to check URI segments within your controller. The only parameter is a string -representing a valid URI:: +representing a valid URI: - $results = $this->withURI('http://example.com/forums/categories') - ->controller(\App\Controllers\ForumController::class) - ->execute('showCategories'); +.. literalinclude:: controllers/009.php + :lines: 2- It is a good practice to always provide the URI during testing to avoid surprises. **withBody($body)** Allows you to provide a custom body for the request. This can be helpful when testing API controllers where -you need to set a JSON value as the body. The only parameter is a string that represents the body of the request:: - - $body = json_encode(['foo' => 'bar']); +you need to set a JSON value as the body. The only parameter is a string that represents the body of the request: - $results = $this->withBody($body) - ->controller(\App\Controllers\ForumController::class) - ->execute('showCategories'); +.. literalinclude:: controllers/010.php + :lines: 2- Checking the Response ===================== @@ -174,19 +125,9 @@ The Helper Trait ---------------- Just like with the Controller Tester you need to include the ``FilterTestTrait`` in your test -cases to enable these features:: - - filtersConfig->globals['before'] = ['admin-only-filter']; - - $this->assertHasFilters('unfiltered/route', 'before'); - } - ... +.. literalinclude:: controllers/012.php + :lines: 2- Checking Routes --------------- @@ -234,9 +166,10 @@ a large performance advantage over Controller and HTTP Testing. :returns: Aliases for each filter that would have run :rtype: string[] - Usage example:: + Usage example: - $result = $this->getFiltersForRoute('/', 'after'); // ['toolbar'] + .. literalinclude:: controllers/013.php + :lines: 2- Calling Filter Methods ---------------------- @@ -252,15 +185,10 @@ method using these properties to test your Filter code safely and check the resu :returns: A callable method to run the simulated Filter event :rtype: Closure - Usage example:: - - protected function testUnauthorizedAccessRedirects() - { - $caller = $this->getFilterCaller('permission', 'before'); - $result = $caller('MayEditWidgets'); + Usage example: - $this->assertInstanceOf('CodeIgniter\HTTP\RedirectResponse', $result); - } + .. literalinclude:: controllers/014.php + :lines: 2- Notice how the ``Closure`` can take input parameters which are passed to your filter method. @@ -270,22 +198,22 @@ Assertions In addition to the helper methods above ``FilterTestTrait`` also comes with some assertions to streamline your test methods. -The **assertFilter()** method checks that the given route at position uses the filter (by its alias):: +The **assertFilter()** method checks that the given route at position uses the filter (by its alias): - // Make sure users are logged in before checking their account - $this->assertFilter('users/account', 'before', 'login'); +.. literalinclude:: controllers/015.php + :lines: 2- -The **assertNotFilter()** method checks that the given route at position does not use the filter (by its alias):: +The **assertNotFilter()** method checks that the given route at position does not use the filter (by its alias): - // Make sure API calls do not try to use the Debug Toolbar - $this->assertNotFilter('api/v1/widgets', 'after', 'toolbar'); +.. literalinclude:: controllers/016.php + :lines: 2- -The **assertHasFilters()** method checks that the given route at position has at least one filter set:: +The **assertHasFilters()** method checks that the given route at position has at least one filter set: - // Make sure that filters are enabled - $this->assertHasFilters('filtered/route', 'after'); +.. literalinclude:: controllers/017.php + :lines: 2- -The **assertNotHasFilters()** method checks that the given route at position has no filters set:: +The **assertNotHasFilters()** method checks that the given route at position has no filters set: - // Make sure no filters run for our static pages - $this->assertNotHasFilters('about/contact', 'before'); +.. literalinclude:: controllers/018.php + :lines: 2- diff --git a/user_guide_src/source/testing/controllers/001.php b/user_guide_src/source/testing/controllers/001.php new file mode 100644 index 000000000000..9c31d5b62d00 --- /dev/null +++ b/user_guide_src/source/testing/controllers/001.php @@ -0,0 +1,12 @@ +withURI('http://example.com/categories') + ->controller(\App\Controllers\ForumController::class) + ->execute('showCategories'); + + $this->assertTrue($result->isOK()); + } +} diff --git a/user_guide_src/source/testing/controllers/003.php b/user_guide_src/source/testing/controllers/003.php new file mode 100644 index 000000000000..51e810538e87 --- /dev/null +++ b/user_guide_src/source/testing/controllers/003.php @@ -0,0 +1,3 @@ +controller(\App\Controllers\ForumController::class); diff --git a/user_guide_src/source/testing/controllers/004.php b/user_guide_src/source/testing/controllers/004.php new file mode 100644 index 000000000000..d06bb51768c3 --- /dev/null +++ b/user_guide_src/source/testing/controllers/004.php @@ -0,0 +1,4 @@ +controller(\App\Controllers\ForumController::class) + ->execute('showCategories'); diff --git a/user_guide_src/source/testing/controllers/005.php b/user_guide_src/source/testing/controllers/005.php new file mode 100644 index 000000000000..bffc4c9c8f95 --- /dev/null +++ b/user_guide_src/source/testing/controllers/005.php @@ -0,0 +1,8 @@ +appTimezone = 'America/Chicago'; + +$results = $this->withConfig($config) + ->controller(\App\Controllers\ForumController::class) + ->execute('showCategories'); diff --git a/user_guide_src/source/testing/controllers/006.php b/user_guide_src/source/testing/controllers/006.php new file mode 100644 index 000000000000..aef7e41e071e --- /dev/null +++ b/user_guide_src/source/testing/controllers/006.php @@ -0,0 +1,8 @@ +setLocale($locale); + +$results = $this->withRequest($request) + ->controller(\App\Controllers\ForumController::class) + ->execute('showCategories'); diff --git a/user_guide_src/source/testing/controllers/007.php b/user_guide_src/source/testing/controllers/007.php new file mode 100644 index 000000000000..73b1d4e122c2 --- /dev/null +++ b/user_guide_src/source/testing/controllers/007.php @@ -0,0 +1,7 @@ +withResponse($response) + ->controller(\App\Controllers\ForumController::class) + ->execute('showCategories'); diff --git a/user_guide_src/source/testing/controllers/008.php b/user_guide_src/source/testing/controllers/008.php new file mode 100644 index 000000000000..4ea1c84dee20 --- /dev/null +++ b/user_guide_src/source/testing/controllers/008.php @@ -0,0 +1,8 @@ +withResponse($response) + ->withLogger($logger) + ->controller(\App\Controllers\ForumController::class) + ->execute('showCategories'); diff --git a/user_guide_src/source/testing/controllers/009.php b/user_guide_src/source/testing/controllers/009.php new file mode 100644 index 000000000000..4559dd8f4711 --- /dev/null +++ b/user_guide_src/source/testing/controllers/009.php @@ -0,0 +1,5 @@ +withURI('http://example.com/forums/categories') + ->controller(\App\Controllers\ForumController::class) + ->execute('showCategories'); diff --git a/user_guide_src/source/testing/controllers/010.php b/user_guide_src/source/testing/controllers/010.php new file mode 100644 index 000000000000..2cf6d9919c31 --- /dev/null +++ b/user_guide_src/source/testing/controllers/010.php @@ -0,0 +1,7 @@ + 'bar']); + +$results = $this->withBody($body) + ->controller(\App\Controllers\ForumController::class) + ->execute('showCategories'); diff --git a/user_guide_src/source/testing/controllers/011.php b/user_guide_src/source/testing/controllers/011.php new file mode 100644 index 000000000000..f2ab558b8da2 --- /dev/null +++ b/user_guide_src/source/testing/controllers/011.php @@ -0,0 +1,11 @@ +filtersConfig->globals['before'] = ['admin-only-filter']; + + $this->assertHasFilters('unfiltered/route', 'before'); + } +... diff --git a/user_guide_src/source/testing/controllers/013.php b/user_guide_src/source/testing/controllers/013.php new file mode 100644 index 000000000000..e205f0f4ea54 --- /dev/null +++ b/user_guide_src/source/testing/controllers/013.php @@ -0,0 +1,3 @@ +getFiltersForRoute('/', 'after'); // ['toolbar'] diff --git a/user_guide_src/source/testing/controllers/014.php b/user_guide_src/source/testing/controllers/014.php new file mode 100644 index 000000000000..19f2310392fa --- /dev/null +++ b/user_guide_src/source/testing/controllers/014.php @@ -0,0 +1,9 @@ +getFilterCaller('permission', 'before'); + $result = $caller('MayEditWidgets'); + + $this->assertInstanceOf('CodeIgniter\HTTP\RedirectResponse', $result); +} diff --git a/user_guide_src/source/testing/controllers/015.php b/user_guide_src/source/testing/controllers/015.php new file mode 100644 index 000000000000..866d2e80ce43 --- /dev/null +++ b/user_guide_src/source/testing/controllers/015.php @@ -0,0 +1,4 @@ +assertFilter('users/account', 'before', 'login'); diff --git a/user_guide_src/source/testing/controllers/016.php b/user_guide_src/source/testing/controllers/016.php new file mode 100644 index 000000000000..cdbf08ccc36b --- /dev/null +++ b/user_guide_src/source/testing/controllers/016.php @@ -0,0 +1,4 @@ +assertNotFilter('api/v1/widgets', 'after', 'toolbar'); diff --git a/user_guide_src/source/testing/controllers/017.php b/user_guide_src/source/testing/controllers/017.php new file mode 100644 index 000000000000..15db694e5419 --- /dev/null +++ b/user_guide_src/source/testing/controllers/017.php @@ -0,0 +1,4 @@ +assertHasFilters('filtered/route', 'after'); diff --git a/user_guide_src/source/testing/controllers/018.php b/user_guide_src/source/testing/controllers/018.php new file mode 100644 index 000000000000..33606c0e122e --- /dev/null +++ b/user_guide_src/source/testing/controllers/018.php @@ -0,0 +1,4 @@ +assertNotHasFilters('about/contact', 'before'); diff --git a/user_guide_src/source/testing/database.rst b/user_guide_src/source/testing/database.rst index 86b91537917e..614099449e29 100644 --- a/user_guide_src/source/testing/database.rst +++ b/user_guide_src/source/testing/database.rst @@ -10,51 +10,15 @@ The Test Class ============== In order to take advantage of the built-in database tools that CodeIgniter provides for testing, your -tests must extend ``CIUnitTestCase`` and use the ``DatabaseTestTrait``:: +tests must extend ``CIUnitTestCase`` and use the ``DatabaseTestTrait``: - 'joe@example.com', - 'active' => 1, - ]; - $this->dontSeeInDatabase('users', $criteria); +.. literalinclude:: database/004.php + :lines: 2- **seeInDatabase($table, $criteria)** Asserts that a row with criteria matching the key/value pairs in ``$criteria`` DOES exist in the database. -:: - $criteria = [ - 'email' => 'joe@example.com', - 'active' => 1, - ]; - $this->seeInDatabase('users', $criteria); +.. literalinclude:: database/005.php + :lines: 2- **grabFromDatabase($table, $column, $criteria)** Returns the value of ``$column`` from the specified table where the row matches ``$criteria``. If more than one row is found, it will only test against the first one. -:: - $username = $this->grabFromDatabase('users', 'username', ['email' => 'joe@example.com']); +.. literalinclude:: database/006.php + :lines: 2- **hasInDatabase($table, $data)** Inserts a new row into the database. This row is removed after the current test runs. ``$data`` is an associative array with the data to insert into the table. -:: - $data = [ - 'email' => 'joe@example.com', - 'name' => 'Joe Cool', - ]; - $this->hasInDatabase('users', $data); +.. literalinclude:: database/007.php + :lines: 2- **seeNumRecords($expected, $table, $criteria)** Asserts that a number of matching rows are found in the database that match ``$criteria``. -:: - $criteria = [ - 'active' => 1, - ]; - $this->seeNumRecords(2, 'users', $criteria); +.. literalinclude:: database/008.php + :lines: 2- diff --git a/user_guide_src/source/testing/database/001.php b/user_guide_src/source/testing/database/001.php new file mode 100644 index 000000000000..809cd59d8c0f --- /dev/null +++ b/user_guide_src/source/testing/database/001.php @@ -0,0 +1,13 @@ + 'joe@example.com', + 'active' => 1, +]; +$this->dontSeeInDatabase('users', $criteria); diff --git a/user_guide_src/source/testing/database/005.php b/user_guide_src/source/testing/database/005.php new file mode 100644 index 000000000000..960ba5e5b91e --- /dev/null +++ b/user_guide_src/source/testing/database/005.php @@ -0,0 +1,7 @@ + 'joe@example.com', + 'active' => 1, +]; +$this->seeInDatabase('users', $criteria); diff --git a/user_guide_src/source/testing/database/006.php b/user_guide_src/source/testing/database/006.php new file mode 100644 index 000000000000..951736b95611 --- /dev/null +++ b/user_guide_src/source/testing/database/006.php @@ -0,0 +1,3 @@ +grabFromDatabase('users', 'username', ['email' => 'joe@example.com']); diff --git a/user_guide_src/source/testing/database/007.php b/user_guide_src/source/testing/database/007.php new file mode 100644 index 000000000000..46ebb8fbe695 --- /dev/null +++ b/user_guide_src/source/testing/database/007.php @@ -0,0 +1,7 @@ + 'joe@example.com', + 'name' => 'Joe Cool', +]; +$this->hasInDatabase('users', $data); diff --git a/user_guide_src/source/testing/database/008.php b/user_guide_src/source/testing/database/008.php new file mode 100644 index 000000000000..9a60e154d331 --- /dev/null +++ b/user_guide_src/source/testing/database/008.php @@ -0,0 +1,6 @@ + 1, +]; +$this->seeNumRecords(2, 'users', $criteria); diff --git a/user_guide_src/source/testing/debugging.rst b/user_guide_src/source/testing/debugging.rst index 22c77141e116..0b841517846e 100644 --- a/user_guide_src/source/testing/debugging.rst +++ b/user_guide_src/source/testing/debugging.rst @@ -29,9 +29,10 @@ Using Kint **d()** The ``d()`` method dumps all of the data it knows about the contents passed as the only parameter to the screen, and -allows the script to continue executing:: +allows the script to continue executing: - d($_SERVER); +.. literalinclude:: debugging/001.php + :lines: 2- **dd()** @@ -39,9 +40,10 @@ This method is identical to ``d()``, except that it also ``dies()`` and no furth **trace()** -This provides a backtrace to the current execution point, with Kint's own unique spin:: +This provides a backtrace to the current execution point, with Kint's own unique spin: - trace(); +.. literalinclude:: debugging/002.php + :lines: 2- For more information, see `Kint's page `_. @@ -74,18 +76,10 @@ Choosing What to Show CodeIgniter ships with several Collectors that, as the name implies, collect data to display on the toolbar. You can easily make your own to customize the toolbar. To determine which collectors are shown, again head over to -the **app/Config/Toolbar.php** configuration file:: - - public $collectors = [ - \CodeIgniter\Debug\Toolbar\Collectors\Timers::class, - \CodeIgniter\Debug\Toolbar\Collectors\Database::class, - \CodeIgniter\Debug\Toolbar\Collectors\Logs::class, - \CodeIgniter\Debug\Toolbar\Collectors\Views::class, - \CodeIgniter\Debug\Toolbar\Collectors\Cache::class, - \CodeIgniter\Debug\Toolbar\Collectors\Files::class, - \CodeIgniter\Debug\Toolbar\Collectors\Routes::class, - \CodeIgniter\Debug\Toolbar\Collectors\Events::class, - ]; +the **app/Config/Toolbar.php** configuration file: + +.. literalinclude:: debugging/003.php + :lines: 2- Comment out any collectors that you do not want to show. Add custom Collectors here by providing the fully-qualified class name. The exact collectors that appear here will affect which tabs are shown, as well as what information is @@ -119,24 +113,8 @@ Creating custom collectors is a straightforward task. You create a new class, fu can locate it, that extends ``CodeIgniter\Debug\Toolbar\Collectors\BaseCollector``. This provides a number of methods that you can override, and has four required class properties that you must correctly set depending on how you want the Collector to work -:: - - '', // Name displayed on the left of the timeline - 'component' => '', // Name of the Component listed in the middle of timeline - 'start' => 0.00, // start time, like microtime(true) - 'duration' => 0.00, // duration, like mircrotime(true) - microtime(true) - ]; +.. literalinclude:: debugging/005.php + :lines: 2- Providing Vars -------------- @@ -196,15 +170,7 @@ To add data to the Vars tab you must: 2. Implement ``getVarData()`` method. The ``getVarData()`` method should return an array containing arrays of key/value pairs to display. The name of the -outer array's key is the name of the section on the Vars tab:: - - $data = [ - 'section 1' => [ - 'foo' => 'bar', - 'bar' => 'baz', - ], - 'section 2' => [ - 'foo' => 'bar', - 'bar' => 'baz', - ], - ]; +outer array's key is the name of the section on the Vars tab: + +.. literalinclude:: debugging/006.php + :lines: 2- diff --git a/user_guide_src/source/testing/debugging/001.php b/user_guide_src/source/testing/debugging/001.php new file mode 100644 index 000000000000..f54b4701f98e --- /dev/null +++ b/user_guide_src/source/testing/debugging/001.php @@ -0,0 +1,3 @@ + '', // Name displayed on the left of the timeline + 'component' => '', // Name of the Component listed in the middle of timeline + 'start' => 0.00, // start time, like microtime(true) + 'duration' => 0.00, // duration, like mircrotime(true) - microtime(true) +]; diff --git a/user_guide_src/source/testing/debugging/006.php b/user_guide_src/source/testing/debugging/006.php new file mode 100644 index 000000000000..3140ea7e4a81 --- /dev/null +++ b/user_guide_src/source/testing/debugging/006.php @@ -0,0 +1,12 @@ + [ + 'foo' => 'bar', + 'bar' => 'baz', + ], + 'section 2' => [ + 'foo' => 'bar', + 'bar' => 'baz', + ], + ]; diff --git a/user_guide_src/source/testing/fabricator.rst b/user_guide_src/source/testing/fabricator.rst index abd68d8af86b..3e419353ef07 100644 --- a/user_guide_src/source/testing/fabricator.rst +++ b/user_guide_src/source/testing/fabricator.rst @@ -14,27 +14,25 @@ Supported Models ================ ``Fabricator`` supports any model that extends the framework's core model, ``CodeIgniter\Model``. -You may use your own custom models by ensuring they implement ``CodeIgniter\Test\Interfaces\FabricatorModel``:: +You may use your own custom models by ensuring they implement ``CodeIgniter\Test\Interfaces\FabricatorModel``: - class MyModel implements CodeIgniter\Test\Interfaces\FabricatorModel +.. literalinclude:: fabricator/001.php + :lines: 2- .. note:: In addition to methods, the interface outlines some necessary properties for the target model. Please see the interface code for details. Loading Fabricators =================== -At its most basic a fabricator takes the model to act on:: +At its most basic a fabricator takes the model to act on: - use App\Models\UserModel; - use CodeIgniter\Test\Fabricator; +.. literalinclude:: fabricator/002.php + :lines: 2- - $fabricator = new Fabricator(UserModel::class); +The parameter can be a string specifying the name of the model, or an instance of the model itself: -The parameter can be a string specifying the name of the model, or an instance of the model itself:: - - $model = new UserModel($testDbConnection); - - $fabricator = new Fabricator($model); +.. literalinclude:: fabricator/003.php + :lines: 2- Defining Formatters =================== @@ -43,16 +41,10 @@ Faker generates data by requesting it from a formatter. With no formatters defin attempt to guess at the most appropriate fit based on the field name and properties of the model it represents, falling back on ``$fabricator->defaultFormatter``. This may be fine if your field names correspond with common formatters, or if you don't care much about the content of the fields, but most -of the time you will want to specify the formatters to use as the second parameter to the constructor:: - - $formatters = [ - 'first' => 'firstName', - 'email' => 'email', - 'phone' => 'phoneNumber', - 'avatar' => 'imageUrl', - ]; +of the time you will want to specify the formatters to use as the second parameter to the constructor: - $fabricator = new Fabricator(UserModel::class, $formatters); +.. literalinclude:: fabricator/004.php + :lines: 2- You can also change the formatters after a fabricator is initialized by using the ``setFormatters()`` method. @@ -60,41 +52,28 @@ You can also change the formatters after a fabricator is initialized by using th Sometimes the default return of a formatter is not enough. Faker providers allow parameters to most formatters to further limit the scope of random data. A fabricator will check its representative model for the ``fake()`` -method where you can define exactly what the faked data should look like:: - - class UserModel - { - public function fake(Generator &$faker) - { - return [ - 'first' => $faker->firstName, - 'email' => $faker->email, - 'phone' => $faker->phoneNumber, - 'avatar' => Faker\Provider\Image::imageUrl(800, 400), - 'login' => config('Auth')->allowRemembering ? date('Y-m-d') : null, - ]; - } +method where you can define exactly what the faked data should look like: + +.. literalinclude:: fabricator/005.php + :lines: 2- Notice in this example how the first three values are equivalent to the formatters from before. However for ``avatar`` we have requested an image size other than the default and ``login`` uses a conditional based on app configuration, neither of which are possible using the ``$formatters`` parameter. You may want to keep your test data separate from your production models, so it is a good practice to define -a child class in your test support folder:: - - namespace Tests\Support\Models; +a child class in your test support folder: - class UserFabricator extends \App\Models\UserModel - { - public function fake(&$faker) - { +.. literalinclude:: fabricator/006.php + :lines: 2- Localization ============ Faker supports a lot of different locales. Check their documentation to determine which providers -support your locale. Specify a locale in the third parameter while initiating a fabricator:: +support your locale. Specify a locale in the third parameter while initiating a fabricator: - $fabricator = new Fabricator(UserModel::class, null, 'fr_FR'); +.. literalinclude:: fabricator/007.php + :lines: 2- If no locale is specified it will use the one defined in **app/Config/App.php** as ``defaultLocale``. You can check the locale of an existing fabricator using its ``getLocale()`` method. @@ -102,114 +81,72 @@ You can check the locale of an existing fabricator using its ``getLocale()`` met Faking the Data =============== -Once you have a properly-initialized fabricator it is easy to generate test data with the ``make()`` command:: +Once you have a properly-initialized fabricator it is easy to generate test data with the ``make()`` command: - $fabricator = new Fabricator(UserFabricator::class); - $testUser = $fabricator->make(); - print_r($testUser); +.. literalinclude:: fabricator/008.php + :lines: 2- -You might get back something like this:: +You might get back something like this: - array( - 'first' => "Maynard", - 'email' => "king.alford@example.org", - 'phone' => "201-886-0269 x3767", - 'avatar' => "http://lorempixel.com/800/400/", - 'login' => null, - ) +.. literalinclude:: fabricator/009.php + :lines: 2- -You can also get a lot of them back by supplying a count:: +You can also get a lot of them back by supplying a count: - $users = $fabricator->make(10); +.. literalinclude:: fabricator/010.php + :lines: 2- The return type of ``make()`` mimics what is defined in the representative model, but you can -force a type using the methods directly:: +force a type using the methods directly: - $userArray = $fabricator->makeArray(); - $userObject = $fabricator->makeObject(); - $userEntity = $fabricator->makeObject('App\Entities\User'); +.. literalinclude:: fabricator/011.php + :lines: 2- The return from ``make()`` is ready to be used in tests or inserted into the database. Alternatively ``Fabricator`` includes the ``create()`` command to insert it for you, and return the result. Due to model callbacks, database formatting, and special keys like primary and timestamps the return -from ``create()`` can differ from ``make()``. You might get back something like this:: +from ``create()`` can differ from ``make()``. You might get back something like this: - array( - 'id' => 1, - 'first' => "Rachel", - 'email' => "bradley72@gmail.com", - 'phone' => "741-241-2356", - 'avatar' => "http://lorempixel.com/800/400/", - 'login' => null, - 'created_at' => "2020-05-08 14:52:10", - 'updated_at' => "2020-05-08 14:52:10", - ) +.. literalinclude:: fabricator/012.php + :lines: 2- -Similar to ``make()`` you can supply a count to insert and return an array of objects:: +Similar to ``make()`` you can supply a count to insert and return an array of objects: - $users = $fabricator->create(100); +.. literalinclude:: fabricator/013.php + :lines: 2- Finally, there may be times you want to test with the full database object but you are not actually using a database. ``create()`` takes a second parameter to allowing mocking the object, returning -the object with extra database fields above without actually touching the database:: - - $user = $fabricator(null, true); +the object with extra database fields above without actually touching the database: - $this->assertIsNumeric($user->id); - $this->dontSeeInDatabase('user', ['id' => $user->id]); +.. literalinclude:: fabricator/014.php + :lines: 2- Specifying Test Data ==================== Generated data is great, but sometimes you may want to supply a specific field for a test without compromising your formatters configuration. Rather then creating a new fabricator for each variant -you can use ``setOverrides()`` to specify the value for any fields:: +you can use ``setOverrides()`` to specify the value for any fields: - $fabricator->setOverrides(['first' => 'Bobby']); - $bobbyUser = $fabricator->make(); +.. literalinclude:: fabricator/015.php + :lines: 2- -Now any data generated with ``make()`` or ``create()`` will always use "Bobby" for the ``first`` field:: +Now any data generated with ``make()`` or ``create()`` will always use "Bobby" for the ``first`` field: - array( - 'first' => "Bobby", - 'email' => "latta.kindel@company.org", - 'phone' => "251-806-2169", - 'avatar' => "http://lorempixel.com/800/400/", - 'login' => null, - ) - - array( - 'first' => "Bobby", - 'email' => "melissa.strike@fabricon.us", - 'phone' => "525-214-2656 x23546", - 'avatar' => "http://lorempixel.com/800/400/", - 'login' => null, - ) +.. literalinclude:: fabricator/016.php + :lines: 2- ``setOverrides()`` can take a second parameter to indicate whether this should be a persistent -override or only for a single action:: - - $fabricator->setOverrides(['first' => 'Bobby'], $persist = false); - $bobbyUser = $fabricator->make(); - $bobbyUser = $fabricator->make(); - -Notice after the first return the fabricator stops using the overrides:: - - array( - 'first' => "Bobby", - 'email' => "belingadon142@example.org", - 'phone' => "741-857-1933 x1351", - 'avatar' => "http://lorempixel.com/800/400/", - 'login' => null, - ) - - array( - 'first' => "Hans", - 'email' => "hoppifur@metraxalon.com", - 'phone' => "487-235-7006", - 'avatar' => "http://lorempixel.com/800/400/", - 'login' => null, - ) +override or only for a single action: + +.. literalinclude:: fabricator/017.php + :lines: 2- + +Notice after the first return the fabricator stops using the overrides: + +.. literalinclude:: fabricator/018.php + :lines: 2- If no second parameter is supplied then passed values will persist by default. @@ -217,16 +154,15 @@ Test Helper =========== Often all you will need is a one-and-done fake object for testing. The Test Helper provides -the ``fake($model, $overrides, $persist = true)`` function to do just this:: +the ``fake($model, $overrides, $persist = true)`` function to do just this: - helper('test'); - $user = fake('App\Models\UserModel', ['name' => 'Gerry']); +.. literalinclude:: fabricator/019.php + :lines: 2- -This is equivalent to:: +This is equivalent to: - $fabricator = new Fabricator('App\Models\UserModel'); - $fabricator->setOverrides(['name' => 'Gerry']); - $user = $fabricator->create(); +.. literalinclude:: fabricator/020.php + :lines: 2- If you just need a fake object without saving it to the database you can pass false into the persist parameter. @@ -240,20 +176,10 @@ example: Your project has users and groups. In your test case you want to create various scenarios with groups of different sizes, so you use ``Fabricator`` to create a bunch of groups. Now you want to create fake users but don't want to assign them to a non-existant group ID. -Your model's fake method could look like this:: - - class UserModel - { - protected $table = 'users'; - - public function fake(Generator &$faker) - { - return [ - 'first' => $faker->firstName, - 'email' => $faker->email, - 'group_id' => rand(1, Fabricator::getCount('groups')), - ]; - } +Your model's fake method could look like this: + +.. literalinclude:: fabricator/021.php + :lines: 2- Now creating a new user will ensure it is a part of a valid group: ``$user = fake(UserModel::class);`` diff --git a/user_guide_src/source/testing/fabricator/001.php b/user_guide_src/source/testing/fabricator/001.php new file mode 100644 index 000000000000..f5f2e33ff455 --- /dev/null +++ b/user_guide_src/source/testing/fabricator/001.php @@ -0,0 +1,3 @@ + 'firstName', + 'email' => 'email', + 'phone' => 'phoneNumber', + 'avatar' => 'imageUrl', +]; + +$fabricator = new Fabricator(UserModel::class, $formatters); diff --git a/user_guide_src/source/testing/fabricator/005.php b/user_guide_src/source/testing/fabricator/005.php new file mode 100644 index 000000000000..d5dc3ab38932 --- /dev/null +++ b/user_guide_src/source/testing/fabricator/005.php @@ -0,0 +1,14 @@ + $faker->firstName, + 'email' => $faker->email, + 'phone' => $faker->phoneNumber, + 'avatar' => Faker\Provider\Image::imageUrl(800, 400), + 'login' => config('Auth')->allowRemembering ? date('Y-m-d') : null, + ]; + } diff --git a/user_guide_src/source/testing/fabricator/006.php b/user_guide_src/source/testing/fabricator/006.php new file mode 100644 index 000000000000..587a0697d1fa --- /dev/null +++ b/user_guide_src/source/testing/fabricator/006.php @@ -0,0 +1,8 @@ +make(); +print_r($testUser); diff --git a/user_guide_src/source/testing/fabricator/009.php b/user_guide_src/source/testing/fabricator/009.php new file mode 100644 index 000000000000..3a7507430265 --- /dev/null +++ b/user_guide_src/source/testing/fabricator/009.php @@ -0,0 +1,9 @@ + "Maynard", + 'email' => "king.alford@example.org", + 'phone' => "201-886-0269 x3767", + 'avatar' => "http://lorempixel.com/800/400/", + 'login' => null, +) diff --git a/user_guide_src/source/testing/fabricator/010.php b/user_guide_src/source/testing/fabricator/010.php new file mode 100644 index 000000000000..54b795ee2f72 --- /dev/null +++ b/user_guide_src/source/testing/fabricator/010.php @@ -0,0 +1,3 @@ +make(10); diff --git a/user_guide_src/source/testing/fabricator/011.php b/user_guide_src/source/testing/fabricator/011.php new file mode 100644 index 000000000000..9b9f62fd84ee --- /dev/null +++ b/user_guide_src/source/testing/fabricator/011.php @@ -0,0 +1,5 @@ +makeArray(); +$userObject = $fabricator->makeObject(); +$userEntity = $fabricator->makeObject('App\Entities\User'); diff --git a/user_guide_src/source/testing/fabricator/012.php b/user_guide_src/source/testing/fabricator/012.php new file mode 100644 index 000000000000..782c58f8917f --- /dev/null +++ b/user_guide_src/source/testing/fabricator/012.php @@ -0,0 +1,12 @@ + 1, + 'first' => "Rachel", + 'email' => "bradley72@gmail.com", + 'phone' => "741-241-2356", + 'avatar' => "http://lorempixel.com/800/400/", + 'login' => null, + 'created_at' => "2020-05-08 14:52:10", + 'updated_at' => "2020-05-08 14:52:10", +) diff --git a/user_guide_src/source/testing/fabricator/013.php b/user_guide_src/source/testing/fabricator/013.php new file mode 100644 index 000000000000..6e89dd774eb9 --- /dev/null +++ b/user_guide_src/source/testing/fabricator/013.php @@ -0,0 +1,3 @@ +create(100); diff --git a/user_guide_src/source/testing/fabricator/014.php b/user_guide_src/source/testing/fabricator/014.php new file mode 100644 index 000000000000..60f0161b795f --- /dev/null +++ b/user_guide_src/source/testing/fabricator/014.php @@ -0,0 +1,6 @@ +assertIsNumeric($user->id); +$this->dontSeeInDatabase('user', ['id' => $user->id]); diff --git a/user_guide_src/source/testing/fabricator/015.php b/user_guide_src/source/testing/fabricator/015.php new file mode 100644 index 000000000000..277c32fa370b --- /dev/null +++ b/user_guide_src/source/testing/fabricator/015.php @@ -0,0 +1,4 @@ +setOverrides(['first' => 'Bobby']); +$bobbyUser = $fabricator->make(); diff --git a/user_guide_src/source/testing/fabricator/016.php b/user_guide_src/source/testing/fabricator/016.php new file mode 100644 index 000000000000..72f2b946366e --- /dev/null +++ b/user_guide_src/source/testing/fabricator/016.php @@ -0,0 +1,17 @@ + "Bobby", + 'email' => "latta.kindel@company.org", + 'phone' => "251-806-2169", + 'avatar' => "http://lorempixel.com/800/400/", + 'login' => null, +) + +array( + 'first' => "Bobby", + 'email' => "melissa.strike@fabricon.us", + 'phone' => "525-214-2656 x23546", + 'avatar' => "http://lorempixel.com/800/400/", + 'login' => null, +) diff --git a/user_guide_src/source/testing/fabricator/017.php b/user_guide_src/source/testing/fabricator/017.php new file mode 100644 index 000000000000..ee79ea6f8d03 --- /dev/null +++ b/user_guide_src/source/testing/fabricator/017.php @@ -0,0 +1,5 @@ +setOverrides(['first' => 'Bobby'], $persist = false); +$bobbyUser = $fabricator->make(); +$bobbyUser = $fabricator->make(); diff --git a/user_guide_src/source/testing/fabricator/018.php b/user_guide_src/source/testing/fabricator/018.php new file mode 100644 index 000000000000..73a3b932052e --- /dev/null +++ b/user_guide_src/source/testing/fabricator/018.php @@ -0,0 +1,17 @@ + "Bobby", + 'email' => "belingadon142@example.org", + 'phone' => "741-857-1933 x1351", + 'avatar' => "http://lorempixel.com/800/400/", + 'login' => null, +) + +array( + 'first' => "Hans", + 'email' => "hoppifur@metraxalon.com", + 'phone' => "487-235-7006", + 'avatar' => "http://lorempixel.com/800/400/", + 'login' => null, +) diff --git a/user_guide_src/source/testing/fabricator/019.php b/user_guide_src/source/testing/fabricator/019.php new file mode 100644 index 000000000000..4c1de5f23dd2 --- /dev/null +++ b/user_guide_src/source/testing/fabricator/019.php @@ -0,0 +1,4 @@ + 'Gerry']); diff --git a/user_guide_src/source/testing/fabricator/020.php b/user_guide_src/source/testing/fabricator/020.php new file mode 100644 index 000000000000..385646b2ea2c --- /dev/null +++ b/user_guide_src/source/testing/fabricator/020.php @@ -0,0 +1,5 @@ +setOverrides(['name' => 'Gerry']); +$user = $fabricator->create(); diff --git a/user_guide_src/source/testing/fabricator/021.php b/user_guide_src/source/testing/fabricator/021.php new file mode 100644 index 000000000000..a1b0111e0903 --- /dev/null +++ b/user_guide_src/source/testing/fabricator/021.php @@ -0,0 +1,14 @@ + $faker->firstName, + 'email' => $faker->email, + 'group_id' => rand(1, Fabricator::getCount('groups')), + ]; + } diff --git a/user_guide_src/source/testing/feature.rst b/user_guide_src/source/testing/feature.rst index 2a9eb96a348a..54cb6035a804 100644 --- a/user_guide_src/source/testing/feature.rst +++ b/user_guide_src/source/testing/feature.rst @@ -18,33 +18,8 @@ Feature testing requires that all of your test classes use the ``CodeIgniter\Tes and ``CodeIgniter\Test\FeatureTestTrait`` traits. Since these testing tools rely on proper database staging you must always ensure that ``parent::setUp()`` and ``parent::tearDown()`` are called if you implement your own methods. -:: - myClassMethod(); - } - - protected function tearDown(): void - { - parent::tearDown(); - - $this->anotherClassMethod(); - } - } +.. literalinclude:: feature/001.php Requesting A Page ================= @@ -54,25 +29,14 @@ to do this, you use the ``call()`` method. The first parameter is the HTTP metho The second parameter is the path on your site to test. The third parameter accepts an array that is used to populate the superglobal variables for the HTTP verb you are using. So, a method of **GET** would have the **$_GET** variable populated, while a **post** request would have the **$_POST** array populated. -:: - - // Get a simple page - $result = $this->call('get', '/'); - // Submit a form - $result = $this->call('post', 'contact'), [ - 'name' => 'Fred Flintstone', - 'email' => 'flintyfred@example.com' - ]); +.. literalinclude:: feature/002.php + :lines: 2- -Shorthand methods for each of the HTTP verbs exist to ease typing and make things clearer:: +Shorthand methods for each of the HTTP verbs exist to ease typing and make things clearer: - $this->get($path, $params); - $this->post($path, $params); - $this->put($path, $params); - $this->patch($path, $params); - $this->delete($path, $params); - $this->options($path, $params); +.. literalinclude:: feature/003.php + :lines: 2- .. note:: The ``$params`` array does not make sense for every HTTP verb, but is included for consistency. @@ -80,57 +44,41 @@ Setting Different Routes ------------------------ You can use a custom collection of routes by passing an array of "routes" into the ``withRoutes()`` method. This will -override any existing routes in the system:: +override any existing routes in the system: - $routes = [ - ['get', 'users', 'UserController::list'], - ]; - - $result = $this->withRoutes($routes)->get('users'); +.. literalinclude:: feature/004.php + :lines: 2- Each of the "routes" is a 3 element array containing the HTTP verb (or "add" for all), the URI to match, and the routing destination. - Setting Session Values ---------------------- You can set custom session values to use during a single test with the ``withSession()`` method. This takes an array of key/value pairs that should exist within the ``$_SESSION`` variable when this request is made, or ``null`` to indicate that the current values of ``$_SESSION`` should be used. This is handy for testing authentication and more. -:: - - $values = [ - 'logged_in' => 123, - ]; - - $result = $this->withSession($values)->get('admin'); - // Or... - - $_SESSION['logged_in'] = 123; - - $result = $this->withSession()->get('admin'); +.. literalinclude:: feature/005.php + :lines: 2- Setting Headers --------------- You can set header values with the ``withHeaders()`` method. This takes an array of key/value pairs that would be -passed as a header into the call.:: +passed as a header into the call.: - $headers = [ - 'CONTENT_TYPE' => 'application/json', - ]; - - $result = $this->withHeaders($headers)->post('users'); +.. literalinclude:: feature/006.php + :lines: 2- Bypassing Events ---------------- Events are handy to use in your application, but can be problematic during testing. Especially events that are used -to send out emails. You can tell the system to skip any event handling with the ``skipEvents()`` method:: +to send out emails. You can tell the system to skip any event handling with the ``skipEvents()`` method: - $result = $this->skipEvents()->post('users', $userInfo); +.. literalinclude:: feature/007.php + :lines: 2- Formatting The Request ----------------------- @@ -139,13 +87,9 @@ You can set the format of your request's body using the ``withBodyFormat()`` met `json` or `xml`. This will take the parameters passed into ``call()``, ``post()``, ``get()``... and assign them to the body of the request in the given format. This will also set the `Content-Type` header for your request accordingly. This is useful when testing JSON or XML API's so that you can set the request in the form that the controller will expect. -:: - - // If your feature test contains this: - $result = $this->withBodyFormat('json')->post('users', $userInfo); - // Your controller can then get the parameters passed in with: - $userInfo = $this->request->getJson(); +.. literalinclude:: feature/008.php + :lines: 2- Setting the Body ---------------- diff --git a/user_guide_src/source/testing/feature/001.php b/user_guide_src/source/testing/feature/001.php new file mode 100644 index 000000000000..5449332fe266 --- /dev/null +++ b/user_guide_src/source/testing/feature/001.php @@ -0,0 +1,25 @@ +myClassMethod(); + } + + protected function tearDown(): void + { + parent::tearDown(); + + $this->anotherClassMethod(); + } +} diff --git a/user_guide_src/source/testing/feature/002.php b/user_guide_src/source/testing/feature/002.php new file mode 100644 index 000000000000..c5f67f42b36c --- /dev/null +++ b/user_guide_src/source/testing/feature/002.php @@ -0,0 +1,10 @@ +call('get', '/'); + +// Submit a form +$result = $this->call('post', 'contact'), [ + 'name' => 'Fred Flintstone', + 'email' => 'flintyfred@example.com' +]); diff --git a/user_guide_src/source/testing/feature/003.php b/user_guide_src/source/testing/feature/003.php new file mode 100644 index 000000000000..1905a2dcf110 --- /dev/null +++ b/user_guide_src/source/testing/feature/003.php @@ -0,0 +1,8 @@ +get($path, $params); +$this->post($path, $params); +$this->put($path, $params); +$this->patch($path, $params); +$this->delete($path, $params); +$this->options($path, $params); diff --git a/user_guide_src/source/testing/feature/004.php b/user_guide_src/source/testing/feature/004.php new file mode 100644 index 000000000000..4f98ced2f8d6 --- /dev/null +++ b/user_guide_src/source/testing/feature/004.php @@ -0,0 +1,7 @@ +withRoutes($routes)->get('users'); diff --git a/user_guide_src/source/testing/feature/005.php b/user_guide_src/source/testing/feature/005.php new file mode 100644 index 000000000000..448e68800a4e --- /dev/null +++ b/user_guide_src/source/testing/feature/005.php @@ -0,0 +1,13 @@ + 123, +]; + +$result = $this->withSession($values)->get('admin'); + +// Or... + +$_SESSION['logged_in'] = 123; + +$result = $this->withSession()->get('admin'); diff --git a/user_guide_src/source/testing/feature/006.php b/user_guide_src/source/testing/feature/006.php new file mode 100644 index 000000000000..e3cf72b69b47 --- /dev/null +++ b/user_guide_src/source/testing/feature/006.php @@ -0,0 +1,7 @@ + 'application/json', +]; + +$result = $this->withHeaders($headers)->post('users'); diff --git a/user_guide_src/source/testing/feature/007.php b/user_guide_src/source/testing/feature/007.php new file mode 100644 index 000000000000..f44369c79865 --- /dev/null +++ b/user_guide_src/source/testing/feature/007.php @@ -0,0 +1,3 @@ +skipEvents()->post('users', $userInfo); diff --git a/user_guide_src/source/testing/feature/008.php b/user_guide_src/source/testing/feature/008.php new file mode 100644 index 000000000000..f5118ea42091 --- /dev/null +++ b/user_guide_src/source/testing/feature/008.php @@ -0,0 +1,7 @@ +withBodyFormat('json')->post('users', $userInfo); + +// Your controller can then get the parameters passed in with: +$userInfo = $this->request->getJson(); diff --git a/user_guide_src/source/testing/mocking.rst b/user_guide_src/source/testing/mocking.rst index 972ad1a40f96..8c4b8b54d222 100644 --- a/user_guide_src/source/testing/mocking.rst +++ b/user_guide_src/source/testing/mocking.rst @@ -15,9 +15,9 @@ Cache ===== You can mock the cache with the ``mock()`` method, using the ``CacheFactory`` as its only parameter. -:: - $mock = mock(\CodeIgniter\Cache\CacheFactory::class); +.. literalinclude:: mocking/001.php + :lines: 2- While this returns an instance of ``CodeIgniter\Test\Mock\MockCache`` that you can use directly, it also inserts the mock into the Service class, so any calls within your code to ``service('cache')`` or ``Config\Services::cache()`` will @@ -31,23 +31,14 @@ Additional Methods You can instruct the mocked cache handler to never do any caching with the ``bypass()`` method. This will emulate using the dummy handler and ensures that your test does not rely on cached data for your tests. -:: - $mock = mock(\CodeIgniter\Cache\CacheFactory::class); - // Never cache any items during this test. - $mock->bypass(); +.. literalinclude:: mocking/002.php + :lines: 2- Available Assertions -------------------- The following new assertions are available on the mocked class for using during testing: -:: - $mock = mock(\CodeIgniter\Cache\CacheFactory::class); - - // Assert that a cached item named $key exists - $mock->assertHas($key); - // Assert that a cached item named $key exists with a value of $value - $mock->assertHasValue($key, $value); - // Assert that a cached item named $key does NOT exist - $mock->assertMissing($key); +.. literalinclude:: mocking/003.php + :lines: 2- diff --git a/user_guide_src/source/testing/mocking/001.php b/user_guide_src/source/testing/mocking/001.php new file mode 100644 index 000000000000..69e69239049d --- /dev/null +++ b/user_guide_src/source/testing/mocking/001.php @@ -0,0 +1,3 @@ +bypass(); diff --git a/user_guide_src/source/testing/mocking/003.php b/user_guide_src/source/testing/mocking/003.php new file mode 100644 index 000000000000..4a3babddaf54 --- /dev/null +++ b/user_guide_src/source/testing/mocking/003.php @@ -0,0 +1,10 @@ +assertHas($key); +// Assert that a cached item named $key exists with a value of $value +$mock->assertHasValue($key, $value); +// Assert that a cached item named $key does NOT exist +$mock->assertMissing($key); diff --git a/user_guide_src/source/testing/overview.rst b/user_guide_src/source/testing/overview.rst index 4b4cdce7beed..9c3fec194ab4 100644 --- a/user_guide_src/source/testing/overview.rst +++ b/user_guide_src/source/testing/overview.rst @@ -43,7 +43,6 @@ Phar The other option is to download the .phar file from the `PHPUnit `__ site. This is a standalone file that should be placed within your project root. - ************************ Testing Your Application ************************ @@ -64,38 +63,13 @@ The Test Class In order to take advantage of the additional tools provided, your tests must extend ``CIUnitTestCase``. All tests are expected to be located in the **tests/app** directory by default. -To test a new library, **Foo**, you would create a new file at **tests/app/Libraries/FooTest.php**:: - - model->purgeDeleted() - } +.. literalinclude:: overview/006.php + :lines: 2- Traits ------ @@ -157,22 +114,10 @@ A common way to enhance your tests is by using traits to consolidate staging acr test cases. ``CIUnitTestCase`` will detect any class traits and look for staging methods to run named for the trait itself. For example, if you needed to add authentication to some of your test cases you could create an authentication trait with a set up method to fake a -logged in user:: - - trait AuthTrait - { - protected setUpAuthTrait() - { - $user = $this->createFakeUser(); - $this->logInUser($user); - } - ... - - class AuthenticationFeatureTest - { - use AuthTrait; - ... +logged in user: +.. literalinclude:: overview/007.php + :lines: 2- Additional Assertions --------------------- @@ -181,54 +126,34 @@ Additional Assertions **assertLogged($level, $expectedMessage)** -Ensure that something you expected to be logged actually was:: +Ensure that something you expected to be logged actually was: - $config = new LoggerConfig(); - $logger = new Logger($config); - - ... do something that you expect a log entry from - $logger->log('error', "That's no moon"); - - $this->assertLogged('error', "That's no moon"); +.. literalinclude:: overview/008.php + :lines: 2- **assertEventTriggered($eventName)** -Ensure that an event you expected to be triggered actually was:: - - Events::on('foo', function ($arg) use(&$result) { - $result = $arg; - }); - - Events::trigger('foo', 'bar'); +Ensure that an event you expected to be triggered actually was: - $this->assertEventTriggered('foo'); +.. literalinclude:: overview/009.php + :lines: 2- **assertHeaderEmitted($header, $ignoreCase = false)** -Ensure that a header or cookie was actually emitted:: +Ensure that a header or cookie was actually emitted: - $response->setCookie('foo', 'bar'); - - ob_start(); - $this->response->send(); - $output = ob_get_clean(); // in case you want to check the actual body - - $this->assertHeaderEmitted("Set-Cookie: foo=bar"); +.. literalinclude:: overview/010.php + :lines: 2- Note: the test case with this should be `run as a separate process in PHPunit `_. **assertHeaderNotEmitted($header, $ignoreCase = false)** -Ensure that a header or cookie was not emitted:: - - $response->setCookie('foo', 'bar'); - - ob_start(); - $this->response->send(); - $output = ob_get_clean(); // in case you want to check the actual body +Ensure that a header or cookie was not emitted: - $this->assertHeaderNotEmitted("Set-Cookie: banana"); +.. literalinclude:: overview/011.php + :lines: 2- Note: the test case with this should be `run as a separate process in PHPunit `_. @@ -236,26 +161,23 @@ in PHPunit start('longjohn', strtotime('-11 minutes')); - $this->assertCloseEnough(11 * 60, $timer->getElapsedTime('longjohn')); +.. literalinclude:: overview/012.php + :lines: 2- The above test will allow the actual time to be either 660 or 661 seconds. **assertCloseEnoughString($expected, $actual, $message = '', $tolerance = 1)** For extended execution time testing, tests that the absolute difference -between expected and actual time, formatted as strings, is within the prescribed tolerance.:: +between expected and actual time, formatted as strings, is within the prescribed tolerance.: - $timer = new Timer(); - $timer->start('longjohn', strtotime('-11 minutes')); - $this->assertCloseEnoughString(11 * 60, $timer->getElapsedTime('longjohn')); +.. literalinclude:: overview/013.php + :lines: 2- The above test will allow the actual time to be either 660 or 661 seconds. - Accessing Protected/Private Properties -------------------------------------- @@ -267,42 +189,24 @@ properties in the classes that you are testing. Enables you to call private methods from outside the class. This returns a function that can be called. The first parameter is an instance of the class to test. The second parameter is the name of the method you want to call. -:: - - // Create an instance of the class to test - $obj = new Foo(); - - // Get the invoker for the 'privateMethod' method. - $method = $this->getPrivateMethodInvoker($obj, 'privateMethod'); - - // Test the results - $this->assertEquals('bar', $method('param1', 'param2')); +.. literalinclude:: overview/014.php + :lines: 2- **getPrivateProperty($instance, $property)** Retrieves the value of a private/protected class property from an instance of a class. The first parameter is an instance of the class to test. The second parameter is the name of the property. -:: - - // Create an instance of the class to test - $obj = new Foo(); - - // Test the value - $this->assertEquals('bar', $this->getPrivateProperty($obj, 'baz')); +.. literalinclude:: overview/015.php + :lines: 2- **setPrivateProperty($instance, $property, $value)** Set a protected value within a class instance. The first parameter is an instance of the class to test. The second -parameter is the name of the property to set the value of. The third parameter is the value to set it to:: - - // Create an instance of the class to test - $obj = new Foo(); - - // Set the value - $this->setPrivateProperty($obj, 'baz', 'oops!'); +parameter is the name of the property to set the value of. The third parameter is the value to set it to: - // Do normal testing... +.. literalinclude:: overview/016.php + :lines: 2- Mocking Services ================ @@ -316,17 +220,9 @@ to simplify this. This method allows you to define the exact instance that will be returned by the Services class. You can use this to set properties of a service so that it behaves in a certain way, or replace a service with a mocked class. -:: - public function testSomething() - { - $curlrequest = $this->getMockBuilder('CodeIgniter\HTTP\CURLRequest') - ->setMethods(['request']) - ->getMock(); - Services::injectMock('curlrequest', $curlrequest); - - // Do normal testing here.... - } +.. literalinclude:: overview/017.php + :lines: 2- The first parameter is the service that you are replacing. The name must match the function name in the Services class exactly. The second parameter is the instance to replace it with. @@ -347,15 +243,10 @@ Mocking Factory Instances Similar to Services, you may find yourself needing to supply a pre-configured class instance during testing that will be used with ``Factories``. Use the same ``injectMock()`` and ``reset()`` static methods like **Services**, but they take an additional preceding parameter for the -component name:: - - protected function setUp() - { - parent::setUp(); +component name: - $model = new MockUserModel(); - Factories::injectMock('models', 'App\Models\UserModel', $model); - } +.. literalinclude:: overview/018.php + :lines: 2- .. note:: All component Factories are reset by default between each test. Modify your test case's ``$setUpMethods`` if you need instances to persist. @@ -367,22 +258,7 @@ Stream Filters You may need to test things that are difficult to test. Sometimes, capturing a stream, like PHP's own STDOUT, or STDERR, might be helpful. The ``CITestStreamFilter`` helps you capture the output from the stream of your choice. -An example demonstrating this inside one of your test cases:: - - public function setUp() - { - CITestStreamFilter::$buffer = ''; - $this->stream_filter = stream_filter_append(STDOUT, 'CITestStreamFilter'); - } - - public function tearDown() - { - stream_filter_remove($this->stream_filter); - } - - public function testSomeOutput() - { - CLI::write('first.'); - $expected = "first.\n"; - $this->assertSame($expected, CITestStreamFilter::$buffer); - } +An example demonstrating this inside one of your test cases: + +.. literalinclude:: overview/019.php + :lines: 2- diff --git a/user_guide_src/source/testing/overview/001.php b/user_guide_src/source/testing/overview/001.php new file mode 100644 index 000000000000..6dac95d2b671 --- /dev/null +++ b/user_guide_src/source/testing/overview/001.php @@ -0,0 +1,13 @@ +model->purgeDeleted() + } diff --git a/user_guide_src/source/testing/overview/007.php b/user_guide_src/source/testing/overview/007.php new file mode 100644 index 000000000000..74bbb533de38 --- /dev/null +++ b/user_guide_src/source/testing/overview/007.php @@ -0,0 +1,15 @@ +createFakeUser(); + $this->logInUser($user); + } +... + +class AuthenticationFeatureTest +{ + use AuthTrait; +... diff --git a/user_guide_src/source/testing/overview/008.php b/user_guide_src/source/testing/overview/008.php new file mode 100644 index 000000000000..9d84f888c1d4 --- /dev/null +++ b/user_guide_src/source/testing/overview/008.php @@ -0,0 +1,9 @@ +log('error', "That's no moon"); + +$this->assertLogged('error', "That's no moon"); diff --git a/user_guide_src/source/testing/overview/009.php b/user_guide_src/source/testing/overview/009.php new file mode 100644 index 000000000000..115cf6bda9e4 --- /dev/null +++ b/user_guide_src/source/testing/overview/009.php @@ -0,0 +1,9 @@ +assertEventTriggered('foo'); diff --git a/user_guide_src/source/testing/overview/010.php b/user_guide_src/source/testing/overview/010.php new file mode 100644 index 000000000000..4884f9a4a9f2 --- /dev/null +++ b/user_guide_src/source/testing/overview/010.php @@ -0,0 +1,9 @@ +setCookie('foo', 'bar'); + +ob_start(); +$this->response->send(); +$output = ob_get_clean(); // in case you want to check the actual body + +$this->assertHeaderEmitted("Set-Cookie: foo=bar"); diff --git a/user_guide_src/source/testing/overview/011.php b/user_guide_src/source/testing/overview/011.php new file mode 100644 index 000000000000..a2aa11c7bb64 --- /dev/null +++ b/user_guide_src/source/testing/overview/011.php @@ -0,0 +1,9 @@ +setCookie('foo', 'bar'); + +ob_start(); +$this->response->send(); +$output = ob_get_clean(); // in case you want to check the actual body + +$this->assertHeaderNotEmitted("Set-Cookie: banana"); diff --git a/user_guide_src/source/testing/overview/012.php b/user_guide_src/source/testing/overview/012.php new file mode 100644 index 000000000000..c9b85aef7f87 --- /dev/null +++ b/user_guide_src/source/testing/overview/012.php @@ -0,0 +1,5 @@ +start('longjohn', strtotime('-11 minutes')); +$this->assertCloseEnough(11 * 60, $timer->getElapsedTime('longjohn')); diff --git a/user_guide_src/source/testing/overview/013.php b/user_guide_src/source/testing/overview/013.php new file mode 100644 index 000000000000..1c03733868e4 --- /dev/null +++ b/user_guide_src/source/testing/overview/013.php @@ -0,0 +1,5 @@ +start('longjohn', strtotime('-11 minutes')); +$this->assertCloseEnoughString(11 * 60, $timer->getElapsedTime('longjohn')); diff --git a/user_guide_src/source/testing/overview/014.php b/user_guide_src/source/testing/overview/014.php new file mode 100644 index 000000000000..f228dcf28963 --- /dev/null +++ b/user_guide_src/source/testing/overview/014.php @@ -0,0 +1,10 @@ +getPrivateMethodInvoker($obj, 'privateMethod'); + +// Test the results +$this->assertEquals('bar', $method('param1', 'param2')); diff --git a/user_guide_src/source/testing/overview/015.php b/user_guide_src/source/testing/overview/015.php new file mode 100644 index 000000000000..1befb710253e --- /dev/null +++ b/user_guide_src/source/testing/overview/015.php @@ -0,0 +1,7 @@ +assertEquals('bar', $this->getPrivateProperty($obj, 'baz')); diff --git a/user_guide_src/source/testing/overview/016.php b/user_guide_src/source/testing/overview/016.php new file mode 100644 index 000000000000..c2e815953dd9 --- /dev/null +++ b/user_guide_src/source/testing/overview/016.php @@ -0,0 +1,9 @@ +setPrivateProperty($obj, 'baz', 'oops!'); + +// Do normal testing... diff --git a/user_guide_src/source/testing/overview/017.php b/user_guide_src/source/testing/overview/017.php new file mode 100644 index 000000000000..653c7d0947ba --- /dev/null +++ b/user_guide_src/source/testing/overview/017.php @@ -0,0 +1,11 @@ +getMockBuilder('CodeIgniter\HTTP\CURLRequest') + ->setMethods(['request']) + ->getMock(); + Services::injectMock('curlrequest', $curlrequest); + + // Do normal testing here.... +} diff --git a/user_guide_src/source/testing/overview/018.php b/user_guide_src/source/testing/overview/018.php new file mode 100644 index 000000000000..743074117d9e --- /dev/null +++ b/user_guide_src/source/testing/overview/018.php @@ -0,0 +1,9 @@ +stream_filter = stream_filter_append(STDOUT, 'CITestStreamFilter'); +} + +public function tearDown() +{ + stream_filter_remove($this->stream_filter); +} + +public function testSomeOutput() +{ + CLI::write('first.'); + $expected = "first.\n"; + $this->assertSame($expected, CITestStreamFilter::$buffer); +} diff --git a/user_guide_src/source/testing/response.rst b/user_guide_src/source/testing/response.rst index 6c22e7e9cbdb..e695064825fe 100644 --- a/user_guide_src/source/testing/response.rst +++ b/user_guide_src/source/testing/response.rst @@ -5,10 +5,10 @@ Testing Responses The ``TestResponse`` class provides a number of helpful functions for parsing and testing responses from your test cases. Usually a ``TestResponse`` will be provided for you as a result of your :doc:`Controller Tests ` or :doc:`HTTP Feature Tests `, but you can always -create your own directly using any ``ResponseInterface``:: +create your own directly using any ``ResponseInterface``: - $result = new \CodeIgniter\Test\TestResponse($response); - $result->assertOK(); +.. literalinclude:: response/001.php + :lines: 2- .. contents:: :local: @@ -25,15 +25,17 @@ Accessing Request/Response **request()** -You can access directly the Request object, if it was set during testing:: +You can access directly the Request object, if it was set during testing: - $request = $results->request(); +.. literalinclude:: response/002.php + :lines: 2- **response()** -This allows you direct access to the response object:: +This allows you direct access to the response object: - $response = $results->response(); +.. literalinclude:: response/003.php + :lines: 2- Checking Response Status ------------------------ @@ -42,58 +44,52 @@ Checking Response Status Returns a boolean true/false based on whether the response is perceived to be "ok". This is primarily determined by a response status code in the 200 or 300's. An empty body is not considered valid, unless in redirects. -:: - if ($result->isOK()) { - ... - } +.. literalinclude:: response/004.php + :lines: 2- **assertOK()** This assertion simply uses the **isOK()** method to test a response. **assertNotOK** is the inverse of this assertion. -:: - $result->assertOK(); +.. literalinclude:: response/005.php + :lines: 2- **isRedirect()** Returns a boolean true/false based on whether the response is a redirected response. -:: - if ($result->isRedirect()) { - ... - } +.. literalinclude:: response/006.php + :lines: 2- **assertRedirect()** Asserts that the Response is an instance of RedirectResponse. **assertNotRedirect** is the inverse of this assertion. -:: - $result->assertRedirect(); +.. literalinclude:: response/007.php + :lines: 2- **assertRedirectTo()** Asserts that the Response is an instance of RedirectResponse and the destination matches the uri given. -:: - $result->assertRedirectTo('foo/bar'); +.. literalinclude:: response/008.php + :lines: 2- **getRedirectUrl()** Returns the URL set for a RedirectResponse, or null for failure. -:: - $url = $result->getRedirectUrl(); - $this->assertEquals(site_url('foo/bar'), $url); +.. literalinclude:: response/009.php + :lines: 2- **assertStatus(int $code)** Asserts that the HTTP status code returned matches $code. -:: - - $result->assertStatus(403); +.. literalinclude:: response/010.php + :lines: 2- Session Assertions ------------------ @@ -102,17 +98,16 @@ Session Assertions Asserts that a value exists in the resulting session. If $value is passed, will also assert that the variable's value matches what was specified. -:: - $result->assertSessionHas('logged_in', 123); +.. literalinclude:: response/011.php + :lines: 2- **assertSessionMissing(string $key)** Asserts that the resulting session does not include the specified $key. -:: - - $result->assertSessionMissin('logged_in'); +.. literalinclude:: response/012.php + :lines: 2- Header Assertions ----------------- @@ -121,17 +116,16 @@ Header Assertions Asserts that a header named **$key** exists in the response. If **$value** is not empty, will also assert that the values match. -:: - $result->assertHeader('Content-Type', 'text/html'); +.. literalinclude:: response/013.php + :lines: 2- **assertHeaderMissing(string $key)** Asserts that a header name **$key** does not exist in the response. -:: - - $result->assertHeader('Accepts'); +.. literalinclude:: response/014.php + :lines: 2- Cookie Assertions ----------------- @@ -140,24 +134,24 @@ Cookie Assertions Asserts that a cookie named **$key** exists in the response. If **$value** is not empty, will also assert that the values match. You can set the cookie prefix, if needed, by passing it in as the third parameter. -:: - $result->assertCookie('foo', 'bar'); +.. literalinclude:: response/015.php + :lines: 2- **assertCookieMissing(string $key)** Asserts that a cookie named **$key** does not exist in the response. -:: - $result->assertCookieMissing('ci_session'); +.. literalinclude:: response/016.php + :lines: 2- **assertCookieExpired(string $key, string $prefix = '')** Asserts that a cookie named **$key** exists, but has expired. You can set the cookie prefix, if needed, by passing it in as the second parameter. -:: - $result->assertCookieExpired('foo'); +.. literalinclude:: response/017.php + :lines: 2- DOM Helpers ----------- @@ -166,54 +160,36 @@ The response you get back contains a number of helper methods to inspect the HTM are useful for using within assertions in your tests. The **see()** method checks the text on the page to see if it exists either by itself, or more specifically within -a tag, as specified by type, class, or id:: +a tag, as specified by type, class, or id: - // Check that "Hello World" is on the page - $results->see('Hello World'); - // Check that "Hello World" is within an h1 tag - $results->see('Hello World', 'h1'); - // Check that "Hello World" is within an element with the "notice" class - $results->see('Hello World', '.notice'); - // Check that "Hello World" is within an element with id of "title" - $results->see('Hellow World', '#title'); +.. literalinclude:: response/018.php + :lines: 2- -The **dontSee()** method is the exact opposite:: +The **dontSee()** method is the exact opposite: - // Checks that "Hello World" does NOT exist on the page - $results->dontSee('Hello World'); - // Checks that "Hellow World" does NOT exist within any h1 tag - $results->dontSee('Hello World', 'h1'); +.. literalinclude:: response/019.php + :lines: 2- The **seeElement()** and **dontSeeElement()** are very similar to the previous methods, but do not look at the -values of the elements. Instead, they simply check that the elements exist on the page:: +values of the elements. Instead, they simply check that the elements exist on the page: - // Check that an element with class 'notice' exists - $results->seeElement('.notice'); - // Check that an element with id 'title' exists - $results->seeElement('#title') - // Verify that an element with id 'title' does NOT exist - $results->dontSeeElement('#title'); +.. literalinclude:: response/020.php + :lines: 2- -You can use **seeLink()** to ensure that a link appears on the page with the specified text:: +You can use **seeLink()** to ensure that a link appears on the page with the specified text: - // Check that a link exists with 'Upgrade Account' as the text:: - $results->seeLink('Upgrade Account'); - // Check that a link exists with 'Upgrade Account' as the text, AND a class of 'upsell' - $results->seeLink('Upgrade Account', '.upsell'); +.. literalinclude:: response/021.php + :lines: 2- -The **seeInField()** method checks for any input tags exist with the name and value:: +The **seeInField()** method checks for any input tags exist with the name and value: - // Check that an input exists named 'user' with the value 'John Snow' - $results->seeInField('user', 'John Snow'); - // Check a multi-dimensional input - $results->seeInField('user[name]', 'John Snow'); +.. literalinclude:: response/022.php + :lines: 2- -Finally, you can check if a checkbox exists and is checked with the **seeCheckboxIsChecked()** method:: +Finally, you can check if a checkbox exists and is checked with the **seeCheckboxIsChecked()** method: - // Check if checkbox is checked with class of 'foo' - $results->seeCheckboxIsChecked('.foo'); - // Check if checkbox with id of 'bar' is checked - $results->seeCheckboxIsChecked('#bar'); +.. literalinclude:: response/023.php + :lines: 2- DOM Assertions -------------- @@ -224,62 +200,46 @@ assertions. **assertSee(string $search = null, string $element = null)** Asserts that text/HTML is on the page, either by itself or - more specifically - within -a tag, as specified by type, class, or id:: - - // Check that "Hello World" is on the page - $result->assertSee('Hello World'); - // Check that "Hello World" is within an h1 tag - $result->assertSee('Hello World', 'h1'); - // Check that "Hello World" is within an element with the "notice" class - $result->assertSee('Hello World', '.notice'); - // Check that "Hello World" is within an element with id of "title" - $result->assertSee('Hellow World', '#title'); +a tag, as specified by type, class, or id: +.. literalinclude:: response/024.php + :lines: 2- **assertDontSee(string $search = null, string $element = null)** -Asserts the exact opposite of the **assertSee()** method:: +Asserts the exact opposite of the **assertSee()** method: - // Checks that "Hello World" does NOT exist on the page - $results->dontSee('Hello World'); - // Checks that "Hello World" does NOT exist within any h1 tag - $results->dontSee('Hello World', 'h1'); +.. literalinclude:: response/025.php + :lines: 2- **assertSeeElement(string $search)** -Similar to **assertSee()**, however this only checks for an existing element. It does not check for specific text:: +Similar to **assertSee()**, however this only checks for an existing element. It does not check for specific text: - // Check that an element with class 'notice' exists - $results->seeElement('.notice'); - // Check that an element with id 'title' exists - $results->seeElement('#title') +.. literalinclude:: response/026.php + :lines: 2- **assertDontSeeElement(string $search)** Similar to **assertSee()**, however this only checks for an existing element that is missing. It does not check for -specific text:: +specific text: - // Verify that an element with id 'title' does NOT exist - $results->dontSeeElement('#title'); +.. literalinclude:: response/027.php + :lines: 2- **assertSeeLink(string $text, string $details=null)** -Asserts that an anchor tag is found with matching **$text** as the body of the tag:: +Asserts that an anchor tag is found with matching **$text** as the body of the tag: - // Check that a link exists with 'Upgrade Account' as the text:: - $results->seeLink('Upgrade Account'); - // Check that a link exists with 'Upgrade Account' as the text, AND a class of 'upsell' - $results->seeLink('Upgrade Account', '.upsell'); +.. literalinclude:: response/021.php + :lines: 2- **assertSeeInField(string $field, string $value=null)** -Asserts that an input tag exists with the name and value:: - - // Check that an input exists named 'user' with the value 'John Snow' - $results->assertSeeInField('user', 'John Snow'); - // Check a multi-dimensional input - $results->assertSeeInField('user[name]', 'John Snow'); +Asserts that an input tag exists with the name and value: +.. literalinclude:: response/029.php + :lines: 2- Working With JSON ----------------- @@ -289,22 +249,15 @@ can help to test the responses. **getJSON()** -This method will return the body of the response as a JSON string:: +This method will return the body of the response as a JSON string: - // Response body is this: - ['foo' => 'bar'] +.. literalinclude:: response/030.php + :lines: 2- - $json = $result->getJSON(); +You can use this method to determine if ``$response`` actually holds JSON content: - // $json is this: - { - "foo": "bar" - } - -You can use this method to determine if ``$response`` actually holds JSON content:: - - // Verify the response is JSON - $this->assertTrue($result->getJSON() !== false) +.. literalinclude:: response/031.php + :lines: 2- .. note:: Be aware that the JSON string will be pretty-printed in the result. @@ -312,21 +265,13 @@ You can use this method to determine if ``$response`` actually holds JSON conten Asserts that $fragment is found within the JSON response. It does not need to match the entire JSON value. -:: - - // Response body is this: - [ - 'config' => ['key-a', 'key-b'], - ] - - // Is true - $result->assertJSONFragment(['config' => ['key-a']]); +.. literalinclude:: response/032.php + :lines: 2- **assertJSONExact($test)** Similar to **assertJSONFragment()**, but checks the entire JSON response to ensure exact matches. - Working With XML ---------------- diff --git a/user_guide_src/source/testing/response/001.php b/user_guide_src/source/testing/response/001.php new file mode 100644 index 000000000000..0e37cfec37ba --- /dev/null +++ b/user_guide_src/source/testing/response/001.php @@ -0,0 +1,4 @@ +assertOK(); diff --git a/user_guide_src/source/testing/response/002.php b/user_guide_src/source/testing/response/002.php new file mode 100644 index 000000000000..a835659904db --- /dev/null +++ b/user_guide_src/source/testing/response/002.php @@ -0,0 +1,3 @@ +request(); diff --git a/user_guide_src/source/testing/response/003.php b/user_guide_src/source/testing/response/003.php new file mode 100644 index 000000000000..c0cb73899f30 --- /dev/null +++ b/user_guide_src/source/testing/response/003.php @@ -0,0 +1,3 @@ +response(); diff --git a/user_guide_src/source/testing/response/004.php b/user_guide_src/source/testing/response/004.php new file mode 100644 index 000000000000..3cb56ea74b8f --- /dev/null +++ b/user_guide_src/source/testing/response/004.php @@ -0,0 +1,5 @@ +isOK()) { + ... +} diff --git a/user_guide_src/source/testing/response/005.php b/user_guide_src/source/testing/response/005.php new file mode 100644 index 000000000000..9c01964bc050 --- /dev/null +++ b/user_guide_src/source/testing/response/005.php @@ -0,0 +1,3 @@ +assertOK(); diff --git a/user_guide_src/source/testing/response/006.php b/user_guide_src/source/testing/response/006.php new file mode 100644 index 000000000000..90da5662c383 --- /dev/null +++ b/user_guide_src/source/testing/response/006.php @@ -0,0 +1,5 @@ +isRedirect()) { + ... +} diff --git a/user_guide_src/source/testing/response/007.php b/user_guide_src/source/testing/response/007.php new file mode 100644 index 000000000000..38b43a99b200 --- /dev/null +++ b/user_guide_src/source/testing/response/007.php @@ -0,0 +1,3 @@ +assertRedirect(); diff --git a/user_guide_src/source/testing/response/008.php b/user_guide_src/source/testing/response/008.php new file mode 100644 index 000000000000..62b8da3db6af --- /dev/null +++ b/user_guide_src/source/testing/response/008.php @@ -0,0 +1,3 @@ +assertRedirectTo('foo/bar'); diff --git a/user_guide_src/source/testing/response/009.php b/user_guide_src/source/testing/response/009.php new file mode 100644 index 000000000000..ba58bc23bb9e --- /dev/null +++ b/user_guide_src/source/testing/response/009.php @@ -0,0 +1,4 @@ +getRedirectUrl(); +$this->assertEquals(site_url('foo/bar'), $url); diff --git a/user_guide_src/source/testing/response/010.php b/user_guide_src/source/testing/response/010.php new file mode 100644 index 000000000000..70faf34078e1 --- /dev/null +++ b/user_guide_src/source/testing/response/010.php @@ -0,0 +1,3 @@ +assertStatus(403); diff --git a/user_guide_src/source/testing/response/011.php b/user_guide_src/source/testing/response/011.php new file mode 100644 index 000000000000..e9fccd725002 --- /dev/null +++ b/user_guide_src/source/testing/response/011.php @@ -0,0 +1,3 @@ +assertSessionHas('logged_in', 123); diff --git a/user_guide_src/source/testing/response/012.php b/user_guide_src/source/testing/response/012.php new file mode 100644 index 000000000000..671330ac32a4 --- /dev/null +++ b/user_guide_src/source/testing/response/012.php @@ -0,0 +1,3 @@ +assertSessionMissin('logged_in'); diff --git a/user_guide_src/source/testing/response/013.php b/user_guide_src/source/testing/response/013.php new file mode 100644 index 000000000000..761b39943842 --- /dev/null +++ b/user_guide_src/source/testing/response/013.php @@ -0,0 +1,3 @@ +assertHeader('Content-Type', 'text/html'); diff --git a/user_guide_src/source/testing/response/014.php b/user_guide_src/source/testing/response/014.php new file mode 100644 index 000000000000..109ce46d1097 --- /dev/null +++ b/user_guide_src/source/testing/response/014.php @@ -0,0 +1,3 @@ +assertHeader('Accepts'); diff --git a/user_guide_src/source/testing/response/015.php b/user_guide_src/source/testing/response/015.php new file mode 100644 index 000000000000..ded077e66a9b --- /dev/null +++ b/user_guide_src/source/testing/response/015.php @@ -0,0 +1,3 @@ +assertCookie('foo', 'bar'); diff --git a/user_guide_src/source/testing/response/016.php b/user_guide_src/source/testing/response/016.php new file mode 100644 index 000000000000..3aa73f14899a --- /dev/null +++ b/user_guide_src/source/testing/response/016.php @@ -0,0 +1,3 @@ +assertCookieMissing('ci_session'); diff --git a/user_guide_src/source/testing/response/017.php b/user_guide_src/source/testing/response/017.php new file mode 100644 index 000000000000..5ce2b3e2ab9f --- /dev/null +++ b/user_guide_src/source/testing/response/017.php @@ -0,0 +1,3 @@ +assertCookieExpired('foo'); diff --git a/user_guide_src/source/testing/response/018.php b/user_guide_src/source/testing/response/018.php new file mode 100644 index 000000000000..e6860f412e08 --- /dev/null +++ b/user_guide_src/source/testing/response/018.php @@ -0,0 +1,10 @@ +see('Hello World'); +// Check that "Hello World" is within an h1 tag +$results->see('Hello World', 'h1'); +// Check that "Hello World" is within an element with the "notice" class +$results->see('Hello World', '.notice'); +// Check that "Hello World" is within an element with id of "title" +$results->see('Hellow World', '#title'); diff --git a/user_guide_src/source/testing/response/019.php b/user_guide_src/source/testing/response/019.php new file mode 100644 index 000000000000..f96493b52e91 --- /dev/null +++ b/user_guide_src/source/testing/response/019.php @@ -0,0 +1,6 @@ +dontSee('Hello World'); +// Checks that "Hellow World" does NOT exist within any h1 tag +$results->dontSee('Hello World', 'h1'); diff --git a/user_guide_src/source/testing/response/020.php b/user_guide_src/source/testing/response/020.php new file mode 100644 index 000000000000..cb490d8a98ff --- /dev/null +++ b/user_guide_src/source/testing/response/020.php @@ -0,0 +1,8 @@ +seeElement('.notice'); +// Check that an element with id 'title' exists +$results->seeElement('#title') +// Verify that an element with id 'title' does NOT exist +$results->dontSeeElement('#title'); diff --git a/user_guide_src/source/testing/response/021.php b/user_guide_src/source/testing/response/021.php new file mode 100644 index 000000000000..bc74e3ad9124 --- /dev/null +++ b/user_guide_src/source/testing/response/021.php @@ -0,0 +1,6 @@ +seeLink('Upgrade Account'); +// Check that a link exists with 'Upgrade Account' as the text, AND a class of 'upsell' +$results->seeLink('Upgrade Account', '.upsell'); diff --git a/user_guide_src/source/testing/response/022.php b/user_guide_src/source/testing/response/022.php new file mode 100644 index 000000000000..9bb549c9db5f --- /dev/null +++ b/user_guide_src/source/testing/response/022.php @@ -0,0 +1,6 @@ +seeInField('user', 'John Snow'); +// Check a multi-dimensional input +$results->seeInField('user[name]', 'John Snow'); diff --git a/user_guide_src/source/testing/response/023.php b/user_guide_src/source/testing/response/023.php new file mode 100644 index 000000000000..3378144f6eb7 --- /dev/null +++ b/user_guide_src/source/testing/response/023.php @@ -0,0 +1,6 @@ +seeCheckboxIsChecked('.foo'); +// Check if checkbox with id of 'bar' is checked +$results->seeCheckboxIsChecked('#bar'); diff --git a/user_guide_src/source/testing/response/024.php b/user_guide_src/source/testing/response/024.php new file mode 100644 index 000000000000..021910b4e3f7 --- /dev/null +++ b/user_guide_src/source/testing/response/024.php @@ -0,0 +1,10 @@ +assertSee('Hello World'); +// Check that "Hello World" is within an h1 tag +$result->assertSee('Hello World', 'h1'); +// Check that "Hello World" is within an element with the "notice" class +$result->assertSee('Hello World', '.notice'); +// Check that "Hello World" is within an element with id of "title" +$result->assertSee('Hellow World', '#title'); diff --git a/user_guide_src/source/testing/response/025.php b/user_guide_src/source/testing/response/025.php new file mode 100644 index 000000000000..b255f4155ac5 --- /dev/null +++ b/user_guide_src/source/testing/response/025.php @@ -0,0 +1,6 @@ +dontSee('Hello World'); +// Checks that "Hello World" does NOT exist within any h1 tag +$results->dontSee('Hello World', 'h1'); diff --git a/user_guide_src/source/testing/response/026.php b/user_guide_src/source/testing/response/026.php new file mode 100644 index 000000000000..773b7dd04833 --- /dev/null +++ b/user_guide_src/source/testing/response/026.php @@ -0,0 +1,6 @@ +seeElement('.notice'); +// Check that an element with id 'title' exists +$results->seeElement('#title') diff --git a/user_guide_src/source/testing/response/027.php b/user_guide_src/source/testing/response/027.php new file mode 100644 index 000000000000..9780489133ee --- /dev/null +++ b/user_guide_src/source/testing/response/027.php @@ -0,0 +1,4 @@ +dontSeeElement('#title'); diff --git a/user_guide_src/source/testing/response/028.php b/user_guide_src/source/testing/response/028.php new file mode 100644 index 000000000000..bc74e3ad9124 --- /dev/null +++ b/user_guide_src/source/testing/response/028.php @@ -0,0 +1,6 @@ +seeLink('Upgrade Account'); +// Check that a link exists with 'Upgrade Account' as the text, AND a class of 'upsell' +$results->seeLink('Upgrade Account', '.upsell'); diff --git a/user_guide_src/source/testing/response/029.php b/user_guide_src/source/testing/response/029.php new file mode 100644 index 000000000000..1ae7910e9776 --- /dev/null +++ b/user_guide_src/source/testing/response/029.php @@ -0,0 +1,6 @@ +assertSeeInField('user', 'John Snow'); +// Check a multi-dimensional input +$results->assertSeeInField('user[name]', 'John Snow'); diff --git a/user_guide_src/source/testing/response/030.php b/user_guide_src/source/testing/response/030.php new file mode 100644 index 000000000000..e6417035e73f --- /dev/null +++ b/user_guide_src/source/testing/response/030.php @@ -0,0 +1,11 @@ + 'bar'] + +$json = $result->getJSON(); + +// $json is this: +{ + "foo": "bar" +} diff --git a/user_guide_src/source/testing/response/031.php b/user_guide_src/source/testing/response/031.php new file mode 100644 index 000000000000..0c9ded88a7f5 --- /dev/null +++ b/user_guide_src/source/testing/response/031.php @@ -0,0 +1,4 @@ +assertTrue($result->getJSON() !== false) diff --git a/user_guide_src/source/testing/response/032.php b/user_guide_src/source/testing/response/032.php new file mode 100644 index 000000000000..e808ca1a43dd --- /dev/null +++ b/user_guide_src/source/testing/response/032.php @@ -0,0 +1,9 @@ + ['key-a', 'key-b'], +] + +// Is true +$result->assertJSONFragment(['config' => ['key-a']]); diff --git a/user_guide_src/source/tutorial/create_news_items.rst b/user_guide_src/source/tutorial/create_news_items.rst index 81a84e71f927..acf04e52d0f6 100644 --- a/user_guide_src/source/tutorial/create_news_items.rst +++ b/user_guide_src/source/tutorial/create_news_items.rst @@ -11,11 +11,10 @@ Enable CSRF Filter Before creating a form, let's enable the CSRF protection. -Open the **app/Config/Filters.php** file and update the ``$methods`` property like the following:: +Open the **app/Config/Filters.php** file and update the ``$methods`` property like the following: - public $methods = [ - 'post' => ['csrf'], - ]; +.. literalinclude:: create_news_items/001.php + :lines: 2- It configures the CSRF filter to be enabled for all **POST** requests. You can read more about the CSRF protection in :doc:`Security ` library. @@ -67,29 +66,8 @@ check whether the form was submitted and whether the submitted data passed the validation rules. You'll use the :doc:`form validation <../libraries/validation>` library to do this. -:: - - public function create() - { - $model = model(NewsModel::class); - - if ($this->request->getMethod() === 'post' && $this->validate([ - 'title' => 'required|min_length[3]|max_length[255]', - 'body' => 'required', - ])) { - $model->save([ - 'title' => $this->request->getPost('title'), - 'slug' => url_title($this->request->getPost('title'), '-', true), - 'body' => $this->request->getPost('body'), - ]); - - echo view('news/success'); - } else { - echo view('templates/header', ['title' => 'Create a news item']); - echo view('news/create'); - echo view('templates/footer'); - } - } +.. literalinclude:: create_news_items/002.php + :lines: 2- The code above adds a lot of functionality. First we load the NewsModel. After that, we check if we deal with the **POST** request and then @@ -134,20 +112,7 @@ not actually save any data because it doesn't know what fields are safe to be updated. Edit the **NewsModel** to provide it a list of updatable fields in the ``$allowedFields`` property. -:: - - `. -:: - - $routes->match(['get', 'post'], 'news/create', 'News::create'); - $routes->get('news/(:segment)', 'News::view/$1'); - $routes->get('news', 'News::index'); - $routes->get('(:any)', 'Pages::view/$1'); +.. literalinclude:: create_news_items/004.php + :lines: 2- Now point your browser to your local development environment where you installed CodeIgniter and add ``/news/create`` to the URL. diff --git a/user_guide_src/source/tutorial/create_news_items/001.php b/user_guide_src/source/tutorial/create_news_items/001.php new file mode 100644 index 000000000000..80d86db34633 --- /dev/null +++ b/user_guide_src/source/tutorial/create_news_items/001.php @@ -0,0 +1,5 @@ + ['csrf'], +]; diff --git a/user_guide_src/source/tutorial/create_news_items/002.php b/user_guide_src/source/tutorial/create_news_items/002.php new file mode 100644 index 000000000000..2dc230c3a720 --- /dev/null +++ b/user_guide_src/source/tutorial/create_news_items/002.php @@ -0,0 +1,23 @@ +request->getMethod() === 'post' && $this->validate([ + 'title' => 'required|min_length[3]|max_length[255]', + 'body' => 'required', + ])) { + $model->save([ + 'title' => $this->request->getPost('title'), + 'slug' => url_title($this->request->getPost('title'), '-', true), + 'body' => $this->request->getPost('body'), + ]); + + echo view('news/success'); + } else { + echo view('templates/header', ['title' => 'Create a news item']); + echo view('news/create'); + echo view('templates/footer'); + } +} diff --git a/user_guide_src/source/tutorial/create_news_items/003.php b/user_guide_src/source/tutorial/create_news_items/003.php new file mode 100644 index 000000000000..83e03f18eb2b --- /dev/null +++ b/user_guide_src/source/tutorial/create_news_items/003.php @@ -0,0 +1,12 @@ +match(['get', 'post'], 'news/create', 'News::create'); +$routes->get('news/(:segment)', 'News::view/$1'); +$routes->get('news', 'News::index'); +$routes->get('(:any)', 'Pages::view/$1'); diff --git a/user_guide_src/source/tutorial/index.rst b/user_guide_src/source/tutorial/index.rst index 798341a6ce96..35cb5ba9ba7f 100644 --- a/user_guide_src/source/tutorial/index.rst +++ b/user_guide_src/source/tutorial/index.rst @@ -84,7 +84,6 @@ command line from the root of your project:: > php spark serve - The Welcome Page **************** @@ -127,6 +126,5 @@ There are a couple of things to note here: Everything else should be clear when you see it. - Now that we know how to get started and how to debug a little, let's get started building this small news application. diff --git a/user_guide_src/source/tutorial/news_section.rst b/user_guide_src/source/tutorial/news_section.rst index 396c74255962..3e5c7b0dd631 100644 --- a/user_guide_src/source/tutorial/news_section.rst +++ b/user_guide_src/source/tutorial/news_section.rst @@ -75,18 +75,7 @@ You can read more about it :doc:`here `. Open up the **app/Models/** directory and create a new file called **NewsModel.php** and add the following code. -:: - - findAll(); - } - - return $this->where(['slug' => $slug])->first(); - } +.. literalinclude:: news_section/002.php + :lines: 2- With this code, you can perform two different queries. You can get all news records, or get a news item by its slug. You might have @@ -135,30 +116,7 @@ in our ``Pages`` controller created earlier, but for the sake of clarity, a new ``News`` controller is defined. Create the new controller at **app/Controllers/News.php**. -:: - - getNews(); - } - - public function view($slug = null) - { - $model = model(NewsModel::class); - - $data['news'] = $model->getNews($slug); - } - } +.. literalinclude:: news_section/003.php Looking at the code, you may see some similarity with the files we created earlier. First, it extends a core CodeIgniter class, ``Controller``, @@ -179,21 +137,10 @@ news item to be returned. Now the data is retrieved by the controller through our model, but nothing is displayed yet. The next thing to do is, passing this data to -the views. Modify the ``index()`` method to look like this:: - - public function index() - { - $model = model(NewsModel::class); - - $data = [ - 'news' => $model->getNews(), - 'title' => 'News archive', - ]; +the views. Modify the ``index()`` method to look like this: - echo view('templates/header', $data); - echo view('news/overview', $data); - echo view('templates/footer', $data); - } +.. literalinclude:: news_section/004.php + :lines: 2- The code above gets all news records from the model and assigns it to a variable. The value for the title is also assigned to the ``$data['title']`` @@ -201,31 +148,7 @@ element and all data is passed to the views. You now need to create a view to render the news items. Create **app/Views/news/overview.php** and add the next piece of code. -:: - -

    - - - - - -

    - -
    - -
    -

    View article

    - - - - - -

    No News

    - -

    Unable to find any news for you.

    - - - +.. literalinclude:: news_section/005.php .. note:: We are again using using ``esc()`` to help prevent XSS attacks. But this time we also passed "url" as a second parameter. That's because @@ -243,34 +166,15 @@ a way that it can easily be used for this functionality. You only need to add some code to the controller and create a new view. Go back to the ``News`` controller and update the ``view()`` method with the following: -:: - - public function view($slug = null) - { - $model = model(NewsModel::class); - - $data['news'] = $model->getNews($slug); - - if (empty($data['news'])) { - throw new \CodeIgniter\Exceptions\PageNotFoundException('Cannot find the news item: ' . $slug); - } - - $data['title'] = $data['news']['title']; - - echo view('templates/header', $data); - echo view('news/view', $data); - echo view('templates/footer', $data); - } +.. literalinclude:: news_section/006.php + :lines: 2- Instead of calling the ``getNews()`` method without a parameter, the ``$slug`` variable is passed, so it will return the specific news item. The only thing left to do is create the corresponding view at **app/Views/news/view.php**. Put the following code in this file. -:: - -

    -

    +.. literalinclude:: news_section/007.php Routing ------------------------------------------------------- @@ -282,11 +186,8 @@ This makes sure the requests reach the ``News`` controller instead of going directly to the ``Pages`` controller. The first line routes URI's with a slug to the ``view()`` method in the ``News`` controller. -:: - - $routes->get('news/(:segment)', 'News::view/$1'); - $routes->get('news', 'News::index'); - $routes->get('(:any)', 'Pages::view/$1'); +.. literalinclude:: news_section/008.php + :lines: 2- Point your browser to your "news" page, i.e., ``localhost:8080/news``, you should see a list of the news items, each of which has a link diff --git a/user_guide_src/source/tutorial/news_section/001.php b/user_guide_src/source/tutorial/news_section/001.php new file mode 100644 index 000000000000..b565d4a82f25 --- /dev/null +++ b/user_guide_src/source/tutorial/news_section/001.php @@ -0,0 +1,10 @@ +findAll(); + } + + return $this->where(['slug' => $slug])->first(); +} diff --git a/user_guide_src/source/tutorial/news_section/003.php b/user_guide_src/source/tutorial/news_section/003.php new file mode 100644 index 000000000000..13c3b7263db6 --- /dev/null +++ b/user_guide_src/source/tutorial/news_section/003.php @@ -0,0 +1,22 @@ +getNews(); + } + + public function view($slug = null) + { + $model = model(NewsModel::class); + + $data['news'] = $model->getNews($slug); + } +} diff --git a/user_guide_src/source/tutorial/news_section/004.php b/user_guide_src/source/tutorial/news_section/004.php new file mode 100644 index 000000000000..0fac31909775 --- /dev/null +++ b/user_guide_src/source/tutorial/news_section/004.php @@ -0,0 +1,15 @@ + $model->getNews(), + 'title' => 'News archive', + ]; + + echo view('templates/header', $data); + echo view('news/overview', $data); + echo view('templates/footer', $data); +} diff --git a/user_guide_src/source/tutorial/news_section/005.php b/user_guide_src/source/tutorial/news_section/005.php new file mode 100644 index 000000000000..39db0a4319f7 --- /dev/null +++ b/user_guide_src/source/tutorial/news_section/005.php @@ -0,0 +1,22 @@ +

    + + + + + +

    + +
    + +
    +

    View article

    + + + + + +

    No News

    + +

    Unable to find any news for you.

    + + diff --git a/user_guide_src/source/tutorial/news_section/006.php b/user_guide_src/source/tutorial/news_section/006.php new file mode 100644 index 000000000000..ea7331dbf77f --- /dev/null +++ b/user_guide_src/source/tutorial/news_section/006.php @@ -0,0 +1,18 @@ +getNews($slug); + + if (empty($data['news'])) { + throw new \CodeIgniter\Exceptions\PageNotFoundException('Cannot find the news item: ' . $slug); + } + + $data['title'] = $data['news']['title']; + + echo view('templates/header', $data); + echo view('news/view', $data); + echo view('templates/footer', $data); +} diff --git a/user_guide_src/source/tutorial/news_section/007.php b/user_guide_src/source/tutorial/news_section/007.php new file mode 100644 index 000000000000..9975baad0cbb --- /dev/null +++ b/user_guide_src/source/tutorial/news_section/007.php @@ -0,0 +1,2 @@ +

    +

    diff --git a/user_guide_src/source/tutorial/news_section/008.php b/user_guide_src/source/tutorial/news_section/008.php new file mode 100644 index 000000000000..8943925258bd --- /dev/null +++ b/user_guide_src/source/tutorial/news_section/008.php @@ -0,0 +1,5 @@ +get('news/(:segment)', 'News::view/$1'); +$routes->get('news', 'News::index'); +$routes->get('(:any)', 'Pages::view/$1'); diff --git a/user_guide_src/source/tutorial/static_pages.rst b/user_guide_src/source/tutorial/static_pages.rst index ecf6e87e03c5..0b64ca40baba 100644 --- a/user_guide_src/source/tutorial/static_pages.rst +++ b/user_guide_src/source/tutorial/static_pages.rst @@ -33,25 +33,7 @@ Let's make our first controller Create a file at **app/Controllers/Pages.php** with the following code. -:: - - @@ -95,9 +75,7 @@ The header contains the basic HTML code that you'll want to display before loading the main view, together with a heading. It will also output the ``$title`` variable, which we'll define later in the controller. Now, create a footer at **app/Views/templates/footer.php** that -includes the following code: - -:: +includes the following code:: © 2021 @@ -123,21 +101,8 @@ In order to load those pages, you'll have to check whether the requested page actually exists. This will be the body of the ``view()`` method in the ``Pages`` controller created above: -:: - - public function view($page = 'home') - { - if (! is_file(APPPATH . 'Views/pages/' . $page . '.php')) { - // Whoops, we don't have a page for that! - throw new \CodeIgniter\Exceptions\PageNotFoundException($page); - } - - $data['title'] = ucfirst($page); // Capitalize the first letter - - echo view('templates/header', $data); - echo view('pages/' . $page, $data); - echo view('templates/footer', $data); - } +.. literalinclude:: static_pages/002.php + :lines: 2- Now, when the requested page does exist, it is loaded, including the header and footer, and displayed to the user. If the requested page doesn't exist, a "404 @@ -212,7 +177,6 @@ controller you made above produces... | | `app/Views/pages/shop.php` | +---------------------------------+-----------------------------------------------------------------+ - Routing ------------------------------------------------------- @@ -231,18 +195,16 @@ section of the configuration file. The only uncommented line there to start with should be: -:: - - $routes->get('/', 'Home::index'); +.. literalinclude:: static_pages/003.php + :lines: 2- This directive says that any incoming request without any content specified should be handled by the ``index()`` method inside the ``Home`` controller. Add the following line, **after** the route directive for '/'. -:: - - $routes->get('(:any)', 'Pages::view/$1'); +.. literalinclude:: static_pages/004.php + :lines: 2- CodeIgniter reads its routing rules from top to bottom and routes the request to the first matching rule. Each rule is a regular expression diff --git a/user_guide_src/source/tutorial/static_pages/001.php b/user_guide_src/source/tutorial/static_pages/001.php new file mode 100644 index 000000000000..0cedb8e44906 --- /dev/null +++ b/user_guide_src/source/tutorial/static_pages/001.php @@ -0,0 +1,16 @@ +get('/', 'Home::index'); diff --git a/user_guide_src/source/tutorial/static_pages/004.php b/user_guide_src/source/tutorial/static_pages/004.php new file mode 100644 index 000000000000..f998b89762fd --- /dev/null +++ b/user_guide_src/source/tutorial/static_pages/004.php @@ -0,0 +1,3 @@ +get('(:any)', 'Pages::view/$1'); From c18c392c01d009a6fb068871e4f8fdf714ad42f1 Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Sun, 20 Feb 2022 00:04:17 +0100 Subject: [PATCH 0523/1246] Segregate duplicates. --- user_guide_src/source/libraries/publisher.rst | 2 +- user_guide_src/source/libraries/sessions.rst | 4 ++-- user_guide_src/source/libraries/sessions/005-1.php | 3 +++ user_guide_src/source/libraries/sessions/005-2.php | 3 +++ user_guide_src/source/outgoing/view_parser.rst | 2 +- user_guide_src/source/outgoing/view_parser/021-1.php | 3 +++ user_guide_src/source/testing/response.rst | 2 +- user_guide_src/source/testing/response/021-2.php | 6 ++++++ 8 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 user_guide_src/source/libraries/sessions/005-1.php create mode 100644 user_guide_src/source/libraries/sessions/005-2.php create mode 100644 user_guide_src/source/outgoing/view_parser/021-1.php create mode 100644 user_guide_src/source/testing/response/021-2.php diff --git a/user_guide_src/source/libraries/publisher.rst b/user_guide_src/source/libraries/publisher.rst index 3657a124317c..ebe0716d2bcb 100644 --- a/user_guide_src/source/libraries/publisher.rst +++ b/user_guide_src/source/libraries/publisher.rst @@ -39,7 +39,7 @@ On Demand Access ``Publisher`` directly by instantiating a new instance of the class: -.. literalinclude:: publisher/001.php +.. literalinclude:: publisher/002.php :lines: 2- By default the source and destination will be set to ``ROOTPATH`` and ``FCPATH`` respectively, giving ``Publisher`` diff --git a/user_guide_src/source/libraries/sessions.rst b/user_guide_src/source/libraries/sessions.rst index 889ad559d8bb..fcab322aa3d9 100644 --- a/user_guide_src/source/libraries/sessions.rst +++ b/user_guide_src/source/libraries/sessions.rst @@ -119,7 +119,7 @@ Retrieving Session Data Any piece of information from the session array is available through the ``$_SESSION`` superglobal: -.. literalinclude:: sessions/005.php +.. literalinclude:: sessions/005-2.php :lines: 2- Or through the conventional accessor method: @@ -335,7 +335,7 @@ You can also pass an array to ``setTempdata()``: To read a tempdata variable, again you can just access it through the ``$_SESSION`` superglobal array: -.. literalinclude:: sessions/005.php +.. literalinclude:: sessions/005-1.php :lines: 2- .. important:: The ``get()`` method WILL return tempdata items when diff --git a/user_guide_src/source/libraries/sessions/005-1.php b/user_guide_src/source/libraries/sessions/005-1.php new file mode 100644 index 000000000000..4f09358d5fc8 --- /dev/null +++ b/user_guide_src/source/libraries/sessions/005-1.php @@ -0,0 +1,3 @@ +render('myview'); diff --git a/user_guide_src/source/testing/response.rst b/user_guide_src/source/testing/response.rst index e695064825fe..ae6eb2deb97e 100644 --- a/user_guide_src/source/testing/response.rst +++ b/user_guide_src/source/testing/response.rst @@ -178,7 +178,7 @@ values of the elements. Instead, they simply check that the elements exist on th You can use **seeLink()** to ensure that a link appears on the page with the specified text: -.. literalinclude:: response/021.php +.. literalinclude:: response/021-2.php :lines: 2- The **seeInField()** method checks for any input tags exist with the name and value: diff --git a/user_guide_src/source/testing/response/021-2.php b/user_guide_src/source/testing/response/021-2.php new file mode 100644 index 000000000000..bc74e3ad9124 --- /dev/null +++ b/user_guide_src/source/testing/response/021-2.php @@ -0,0 +1,6 @@ +seeLink('Upgrade Account'); +// Check that a link exists with 'Upgrade Account' as the text, AND a class of 'upsell' +$results->seeLink('Upgrade Account', '.upsell'); From a85a2e843ef01971af68e9068c27e1c8c60676db Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Sun, 20 Feb 2022 09:04:37 +0100 Subject: [PATCH 0524/1246] Renumerate examples. --- user_guide_src/source/helpers/url_helper.rst | 44 ++++----- .../source/helpers/url_helper/002-2.php | 3 - .../source/helpers/url_helper/002-3.php | 3 - .../source/helpers/url_helper/002-4.php | 3 - .../source/helpers/url_helper/003.php | 2 +- .../source/helpers/url_helper/004.php | 2 +- .../source/helpers/url_helper/005.php | 9 +- .../source/helpers/url_helper/006.php | 13 +-- .../source/helpers/url_helper/007.php | 2 +- .../source/helpers/url_helper/008.php | 9 +- .../source/helpers/url_helper/009.php | 14 ++- .../source/helpers/url_helper/010.php | 2 +- .../source/helpers/url_helper/011.php | 2 +- .../source/helpers/url_helper/012.php | 3 +- .../source/helpers/url_helper/013.php | 2 +- .../source/helpers/url_helper/014.php | 4 +- .../source/helpers/url_helper/015.php | 4 +- .../source/helpers/url_helper/016.php | 4 +- .../source/helpers/url_helper/017.php | 4 +- .../source/helpers/url_helper/018.php | 4 +- .../source/helpers/url_helper/019.php | 4 +- .../source/helpers/url_helper/020.php | 2 +- .../source/helpers/url_helper/021.php | 2 +- .../source/helpers/url_helper/022.php | 3 + .../source/helpers/url_helper/023.php | 3 + .../source/helpers/url_helper/024.php | 3 + user_guide_src/source/incoming/routing.rst | 96 +++++++++---------- .../source/incoming/routing/000.php | 3 - .../source/incoming/routing/001.php | 6 +- .../source/incoming/routing/002.php | 6 +- .../source/incoming/routing/003.php | 4 +- .../source/incoming/routing/004.php | 2 +- .../source/incoming/routing/005.php | 2 +- .../source/incoming/routing/006.php | 2 +- .../source/incoming/routing/007.php | 2 +- .../source/incoming/routing/008.php | 6 +- .../source/incoming/routing/009.php | 2 +- .../source/incoming/routing/010.php | 3 +- .../source/incoming/routing/011.php | 6 +- .../source/incoming/routing/012.php | 2 +- .../source/incoming/routing/013.php | 7 +- .../source/incoming/routing/014.php | 7 +- .../source/incoming/routing/015.php | 7 +- .../source/incoming/routing/016.php | 7 +- .../source/incoming/routing/017.php | 9 +- .../source/incoming/routing/018.php | 9 +- .../source/incoming/routing/019.php | 5 +- .../source/incoming/routing/020.php | 6 +- .../source/incoming/routing/021.php | 4 +- .../source/incoming/routing/022.php | 11 +-- .../source/incoming/routing/023-2.php | 3 - .../source/incoming/routing/023.php | 11 +-- .../source/incoming/routing/024.php | 6 +- .../source/incoming/routing/025.php | 7 +- .../source/incoming/routing/026.php | 7 +- .../source/incoming/routing/027.php | 13 +-- .../source/incoming/routing/028.php | 2 +- .../source/incoming/routing/029.php | 13 ++- .../source/incoming/routing/030.php | 2 +- .../source/incoming/routing/031.php | 2 +- .../source/incoming/routing/032.php | 3 +- .../source/incoming/routing/033.php | 2 +- .../source/incoming/routing/034.php | 4 +- .../source/incoming/routing/035.php | 3 +- .../source/incoming/routing/036.php | 6 +- .../source/incoming/routing/037.php | 12 +-- .../source/incoming/routing/038.php | 5 +- .../source/incoming/routing/039.php | 13 ++- .../source/incoming/routing/040.php | 8 +- .../source/incoming/routing/041.php | 9 +- .../source/incoming/routing/042.php | 8 +- .../source/incoming/routing/043.php | 3 +- .../source/incoming/routing/044.php | 2 +- .../source/incoming/routing/045.php | 9 +- .../source/incoming/routing/046.php | 6 +- .../source/incoming/routing/047.php | 10 ++ .../source/incoming/routing/048.php | 7 ++ user_guide_src/source/libraries/sessions.rst | 6 +- .../source/libraries/sessions/005-1.php | 3 - .../source/libraries/sessions/005-2.php | 3 - .../source/libraries/uploaded_files.rst | 46 ++++----- .../source/libraries/uploaded_files/000.php | 23 ----- .../source/libraries/uploaded_files/001.php | 57 ++++------- .../source/libraries/uploaded_files/002.php | 47 ++++++++- .../source/libraries/uploaded_files/003.php | 4 +- .../source/libraries/uploaded_files/004.php | 6 +- .../source/libraries/uploaded_files/005.php | 4 +- .../source/libraries/uploaded_files/006.php | 10 +- .../source/libraries/uploaded_files/007.php | 2 +- .../source/libraries/uploaded_files/008.php | 9 +- .../source/libraries/uploaded_files/009.php | 10 +- .../source/libraries/uploaded_files/010.php | 3 +- .../source/libraries/uploaded_files/011.php | 3 +- .../source/libraries/uploaded_files/012.php | 5 +- .../source/libraries/uploaded_files/013.php | 4 +- .../source/libraries/uploaded_files/014.php | 2 +- .../source/libraries/uploaded_files/015.php | 2 +- .../source/libraries/uploaded_files/016.php | 2 +- .../source/libraries/uploaded_files/017.php | 4 +- .../source/libraries/uploaded_files/018.php | 4 +- .../source/libraries/uploaded_files/019.php | 3 +- .../source/libraries/uploaded_files/020.php | 5 +- .../source/libraries/uploaded_files/021.php | 4 +- .../source/libraries/uploaded_files/022.php | 2 +- .../source/libraries/uploaded_files/023.php | 3 + .../source/libraries/validation.rst | 18 ++-- .../source/libraries/validation/029-2.php | 7 -- .../source/libraries/validation/030.php | 13 +-- .../source/libraries/validation/031.php | 7 +- .../source/libraries/validation/032.php | 14 +-- .../source/libraries/validation/033.php | 18 ++-- .../source/libraries/validation/034.php | 11 +-- .../source/libraries/validation/035.php | 13 ++- .../source/libraries/validation/036.php | 35 +------ .../source/libraries/validation/037.php | 40 ++++++-- .../source/libraries/validation/038.php | 10 ++ .../source/outgoing/view_parser.rst | 32 +++---- .../source/outgoing/view_parser/010-2.php | 3 - .../source/outgoing/view_parser/011.php | 9 +- .../source/outgoing/view_parser/012.php | 3 +- .../source/outgoing/view_parser/013.php | 7 +- .../source/outgoing/view_parser/014.php | 19 ++-- .../source/outgoing/view_parser/015.php | 17 +++- .../source/outgoing/view_parser/016.php | 5 +- .../source/outgoing/view_parser/017.php | 11 +-- .../source/outgoing/view_parser/018.php | 6 +- .../source/outgoing/view_parser/019.php | 10 +- .../source/outgoing/view_parser/020.php | 25 +++-- .../source/outgoing/view_parser/021-1.php | 3 - .../source/outgoing/view_parser/021.php | 18 +++- .../source/outgoing/view_parser/023.php | 2 +- .../source/outgoing/view_parser/024.php | 2 +- .../source/outgoing/view_parser/025.php | 2 +- .../source/outgoing/view_parser/026.php | 3 + user_guide_src/source/testing/response.rst | 4 +- .../source/testing/response/021-2.php | 6 -- 136 files changed, 587 insertions(+), 602 deletions(-) delete mode 100644 user_guide_src/source/helpers/url_helper/002-2.php delete mode 100644 user_guide_src/source/helpers/url_helper/002-3.php delete mode 100644 user_guide_src/source/helpers/url_helper/002-4.php create mode 100644 user_guide_src/source/helpers/url_helper/022.php create mode 100644 user_guide_src/source/helpers/url_helper/023.php create mode 100644 user_guide_src/source/helpers/url_helper/024.php delete mode 100644 user_guide_src/source/incoming/routing/000.php delete mode 100644 user_guide_src/source/incoming/routing/023-2.php create mode 100644 user_guide_src/source/incoming/routing/047.php create mode 100644 user_guide_src/source/incoming/routing/048.php delete mode 100644 user_guide_src/source/libraries/sessions/005-1.php delete mode 100644 user_guide_src/source/libraries/sessions/005-2.php delete mode 100644 user_guide_src/source/libraries/uploaded_files/000.php create mode 100644 user_guide_src/source/libraries/uploaded_files/023.php delete mode 100644 user_guide_src/source/libraries/validation/029-2.php create mode 100644 user_guide_src/source/libraries/validation/038.php delete mode 100644 user_guide_src/source/outgoing/view_parser/010-2.php delete mode 100644 user_guide_src/source/outgoing/view_parser/021-1.php create mode 100644 user_guide_src/source/outgoing/view_parser/026.php delete mode 100644 user_guide_src/source/testing/response/021-2.php diff --git a/user_guide_src/source/helpers/url_helper.rst b/user_guide_src/source/helpers/url_helper.rst index 5ce922578e45..0713a770b5f7 100644 --- a/user_guide_src/source/helpers/url_helper.rst +++ b/user_guide_src/source/helpers/url_helper.rst @@ -62,7 +62,7 @@ The following functions are available: Returns your site base URL, as specified in your config file. Example: - .. literalinclude:: url_helper/002-2.php + .. literalinclude:: url_helper/003.php :lines: 2- This function returns the same thing as :php:func:`site_url()`, without @@ -71,7 +71,7 @@ The following functions are available: Also like :php:func:`site_url()`, you can supply segments as a string or an array. Here is a string example: - .. literalinclude:: url_helper/002-3.php + .. literalinclude:: url_helper/004.php :lines: 2- The above example would return something like: @@ -80,7 +80,7 @@ The following functions are available: 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: - .. literalinclude:: url_helper/002-4.php + .. literalinclude:: url_helper/005.php :lines: 2- This would give you something like: @@ -98,7 +98,7 @@ The following functions are available: .. note:: Calling this function is the same as doing this: - .. literalinclude:: url_helper/003.php + .. literalinclude:: url_helper/006.php :lines: 2- .. important:: Prior to **4.1.2** this function had a bug causing it to ignore the configuration on ``App::$indexPage``. @@ -147,7 +147,7 @@ The following functions are available: Returns your site **indexPage**, as specified in your config file. Example: - .. literalinclude:: url_helper/004.php + .. literalinclude:: url_helper/007.php :lines: 2- As with :php:func:`site_url()`, you may specify an alternate configuration. @@ -184,7 +184,7 @@ The following functions are available: Here are some examples: - .. literalinclude:: url_helper/005.php + .. literalinclude:: url_helper/008.php :lines: 2- As above, you may specify an alternate configuration. @@ -211,7 +211,7 @@ The following functions are available: Here is an example with attributes: - .. literalinclude:: url_helper/006.php + .. literalinclude:: url_helper/009.php :lines: 2- As above, you may specify an alternate configuration. @@ -224,7 +224,7 @@ The following functions are available: function to use all of its defaults simply pass an empty array in the third parameter: - .. literalinclude:: url_helper/007.php + .. literalinclude:: url_helper/010.php :lines: 2- .. note:: The **window_name** is not really an attribute, but an argument to @@ -246,13 +246,13 @@ The following functions are available: Creates a standard HTML e-mail link. Usage example: - .. literalinclude:: url_helper/008.php + .. literalinclude:: url_helper/011.php :lines: 2- As with the :php:func:`anchor()` tab above, you can set attributes using the third parameter: - .. literalinclude:: url_helper/009.php + .. literalinclude:: url_helper/012.php :lines: 2- .. note:: Attributes passed into the mailto function are automatically escaped to protected against XSS attacks. @@ -280,7 +280,7 @@ The following functions are available: Automatically turns URLs and e-mail addresses contained in a string into links. Example: - .. literalinclude:: url_helper/010.php + .. literalinclude:: url_helper/013.php :lines: 2- The second parameter determines whether URLs and e-mails are converted or @@ -290,18 +290,18 @@ The following functions are available: Converts only URLs: - .. literalinclude:: url_helper/011.php + .. literalinclude:: url_helper/014.php :lines: 2- Converts only e-mail addresses: - .. literalinclude:: url_helper/012.php + .. literalinclude:: url_helper/015.php :lines: 2- The third parameter determines whether links are shown in a new window. The value can be true or false (boolean): - .. literalinclude:: url_helper/013.php + .. literalinclude:: url_helper/016.php :lines: 2- .. note:: The only URLs recognized are those that start with "www." or with "://". @@ -318,7 +318,7 @@ The following functions are available: useful if, for example, you have a blog in which you'd like to use the title of your entries in the URL. Example: - .. literalinclude:: url_helper/014.php + .. literalinclude:: url_helper/017.php :lines: 2- The second parameter determines the word delimiter. By default dashes @@ -326,7 +326,7 @@ The following functions are available: Example: - .. literalinclude:: url_helper/015.php + .. literalinclude:: url_helper/018.php :lines: 2- The third parameter determines whether or not lowercase characters are @@ -334,7 +334,7 @@ The following functions are available: Example: - .. literalinclude:: url_helper/016.php + .. literalinclude:: url_helper/019.php :lines: 2- .. php:function:: mb_url_title($str[, $separator = '-'[, $lowercase = false]]) @@ -360,7 +360,7 @@ The following functions are available: Pass the URL string to the function like this: - .. literalinclude:: url_helper/017.php + .. literalinclude:: url_helper/020.php :lines: 2- .. php:function:: url_to($controller[, ...$args]) @@ -372,13 +372,13 @@ The following functions are available: Builds an absolute URL to a controller method in your app. Example: - .. literalinclude:: url_helper/018.php + .. literalinclude:: url_helper/021.php :lines: 2- You can also add arguments to the route. Here is an example: - .. literalinclude:: url_helper/019.php + .. literalinclude:: url_helper/022.php :lines: 2- The above example would return something like: @@ -394,13 +394,13 @@ The following functions are available: Compares the current URL's path against the given path to see if they match. Example: - .. literalinclude:: url_helper/020.php + .. literalinclude:: url_helper/023.php :lines: 2- This would match ``http://example.com/admin``. You can use the ``*`` wildcard to match any other applicable characters in the URL: - .. literalinclude:: url_helper/021.php + .. literalinclude:: url_helper/024.php :lines: 2- This would match any of the following: diff --git a/user_guide_src/source/helpers/url_helper/002-2.php b/user_guide_src/source/helpers/url_helper/002-2.php deleted file mode 100644 index fc388607fec6..000000000000 --- a/user_guide_src/source/helpers/url_helper/002-2.php +++ /dev/null @@ -1,3 +0,0 @@ -My News - -echo anchor('news/local/123', 'My News', ['title' => 'The best news!']); -// Prints: My News - -echo anchor('', 'Click here'); -// Prints: Click here +echo base_url('images/icons/edit.png'); diff --git a/user_guide_src/source/helpers/url_helper/006.php b/user_guide_src/source/helpers/url_helper/006.php index 960bc6f0430e..e6bd1a239fcd 100644 --- a/user_guide_src/source/helpers/url_helper/006.php +++ b/user_guide_src/source/helpers/url_helper/006.php @@ -1,14 +1,3 @@ 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); +site_url(uri_string()); diff --git a/user_guide_src/source/helpers/url_helper/007.php b/user_guide_src/source/helpers/url_helper/007.php index cb1e202af757..35ae47978306 100644 --- a/user_guide_src/source/helpers/url_helper/007.php +++ b/user_guide_src/source/helpers/url_helper/007.php @@ -1,3 +1,3 @@ My News + +echo anchor('news/local/123', 'My News', ['title' => 'The best news!']); +// Prints: My News + +echo anchor('', 'Click here'); +// Prints: Click here diff --git a/user_guide_src/source/helpers/url_helper/009.php b/user_guide_src/source/helpers/url_helper/009.php index dcd65cd2bfcf..960bc6f0430e 100644 --- a/user_guide_src/source/helpers/url_helper/009.php +++ b/user_guide_src/source/helpers/url_helper/009.php @@ -1,4 +1,14 @@ 'Mail me']; -echo mailto('me@my-site.com', 'Contact Me', $attributes); +$atts = [ + '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); diff --git a/user_guide_src/source/helpers/url_helper/010.php b/user_guide_src/source/helpers/url_helper/010.php index 65bf083b99cf..cb1e202af757 100644 --- a/user_guide_src/source/helpers/url_helper/010.php +++ b/user_guide_src/source/helpers/url_helper/010.php @@ -1,3 +1,3 @@ 'Mail me']; +echo mailto('me@my-site.com', 'Contact Me', $attributes); diff --git a/user_guide_src/source/helpers/url_helper/013.php b/user_guide_src/source/helpers/url_helper/013.php index 4ee151df4b12..65bf083b99cf 100644 --- a/user_guide_src/source/helpers/url_helper/013.php +++ b/user_guide_src/source/helpers/url_helper/013.php @@ -1,3 +1,3 @@ ` for a group of routes. This will always run the filter before or after the controller. This is especially handy during authentication or api logging: -.. literalinclude:: routing/018.php +.. literalinclude:: routing/021.php :lines: 2- The value for the filter must match one of the aliases defined within **app/Config/Filters.php**. It is possible to nest groups within groups for finer organization if you need it: -.. literalinclude:: routing/019.php +.. literalinclude:: routing/022.php :lines: 2- This would handle the URL at **admin/users/list**. @@ -275,7 +275,7 @@ config options like namespace, subdomain, etc. Without necessarily needing to ad an empty string in place of the prefix and the routes in the group will be routed as though the group never existed but with the given route config options: -.. literalinclude:: routing/020.php +.. literalinclude:: routing/023.php :lines: 2- Environment Restrictions @@ -286,7 +286,7 @@ tools that only the developer can use on their local machines that are not reach This can be done with the ``environment()`` method. The first parameter is the name of the environment. Any routes defined within this closure are only accessible from the given environment: -.. literalinclude:: routing/021.php +.. literalinclude:: routing/024.php :lines: 2- Reverse Routing @@ -301,7 +301,7 @@ function to get the current route that should be used. The first parameter is th separated by a double colon (``::``), much like you would use when writing the initial route itself. Any parameters that should be passed to the route are passed in next: -.. literalinclude:: routing/022.php +.. literalinclude:: routing/025.php :lines: 2- Using Named Routes @@ -312,7 +312,7 @@ later, and even if the route definition changes, all of the links in your applic will still work without you having to make any changes. A route is named by passing in the ``as`` option with the name of the route: -.. literalinclude:: routing/023.php +.. literalinclude:: routing/026.php :lines: 2- This has the added benefit of making the views more readable, too. @@ -323,7 +323,7 @@ Routes with any HTTP verbs It is possible to define a route with any HTTP verbs. You can use the ``add()`` method: -.. literalinclude:: routing/023-2.php +.. literalinclude:: routing/027.php :lines: 2- .. warning:: While the ``add()`` method seems to be convenient, it is recommended to always use the HTTP-verb-based @@ -343,7 +343,7 @@ You can create routes that work only from the command-line, and are inaccessible route methods will also be inaccessible from the CLI, but routes created by the ``add()`` method will still be available from the command line: -.. literalinclude:: routing/026.php +.. literalinclude:: routing/028.php :lines: 2- Global Options @@ -352,7 +352,7 @@ Global Options All of the methods for creating a route (add, get, post, :doc:`resource ` etc) can take an array of options that can modify the generated routes, or further restrict them. The ``$options`` array is always the last parameter: -.. literalinclude:: routing/027.php +.. literalinclude:: routing/029.php :lines: 2- .. _applying-filters: @@ -379,19 +379,19 @@ See :doc:`Controller filters ` for more information on setting up filte You specify an alias defined in **app/Config/Filters.php** for the filter value: -.. literalinclude:: routing/028.php +.. literalinclude:: routing/030.php :lines: 2- You may also supply arguments to be passed to the alias filter's ``before()`` and ``after()`` methods: -.. literalinclude:: routing/029.php +.. literalinclude:: routing/031.php :lines: 2- **Classname filter** You specify a filter classname for the filter value: -.. literalinclude:: routing/030.php +.. literalinclude:: routing/032.php :lines: 2- **Multiple filters** @@ -400,7 +400,7 @@ You specify a filter classname for the filter value: You specify an array for the filter value: -.. literalinclude:: routing/031.php +.. literalinclude:: routing/033.php :lines: 2- .. _assigning-namespace: @@ -412,7 +412,7 @@ While a default namespace will be prepended to the generated controllers (see be a different namespace to be used in any options array, with the ``namespace`` option. The value should be the namespace you want modified: -.. literalinclude:: routing/032.php +.. literalinclude:: routing/034.php :lines: 2- The new namespace is only applied during that call for any methods that create a single route, like get, post, etc. @@ -425,7 +425,7 @@ Limit to Hostname You can restrict groups of routes to function only in certain domain or sub-domains of your application by passing the "hostname" option along with the desired domain to allow it on as part of the options array: -.. literalinclude:: routing/033.php +.. literalinclude:: routing/035.php :lines: 2- This example would only allow the specified hosts to work if the domain exactly matched **accounts.example.com**. @@ -437,13 +437,13 @@ Limit to Subdomains When the ``subdomain`` option is present, the system will restrict the routes to only be available on that sub-domain. The route will only be matched if the subdomain is the one the application is being viewed through: -.. literalinclude:: routing/034.php +.. literalinclude:: routing/036.php :lines: 2- You can restrict it to any subdomain by setting the value to an asterisk, (``*``). If you are viewing from a URL that does not have any subdomain present, this will not be matched: -.. literalinclude:: routing/035.php +.. literalinclude:: routing/037.php :lines: 2- .. important:: The system is not perfect and should be tested for your specific domain before being used in production. @@ -459,7 +459,7 @@ value being the number of segments to offset. This can be beneficial when developing API's with the first URI segment being the version number. It can also be used when the first parameter is a language string: -.. literalinclude:: routing/036.php +.. literalinclude:: routing/038.php :lines: 2- .. _routing-priority: @@ -473,12 +473,12 @@ You can solve this problem by lowering the priority of route processing using th accepts positive integers and zero. The higher the number specified in the ``priority``, the lower route priority in the processing queue: -.. literalinclude:: routing/037.php +.. literalinclude:: routing/039.php :lines: 2- To disable this functionality, you must call the method with the parameter ``false``: -.. literalinclude:: routing/038.php +.. literalinclude:: routing/040.php :lines: 2- .. note:: By default, all routes have a priority of 0. @@ -502,13 +502,13 @@ specified by the route. By default, this value is ``App\Controllers``. If you set the value empty string (``''``), it leaves each route to specify the fully namespaced controller: -.. literalinclude:: routing/039.php +.. literalinclude:: routing/041.php :lines: 2- If your controllers are not explicitly namespaced, there is no need to change this. If you namespace your controllers, then you can change this value to save typing: -.. literalinclude:: routing/040.php +.. literalinclude:: routing/042.php :lines: 2- Default Controller @@ -518,7 +518,7 @@ When a user visits the root of your site (i.e., example.com) the controller to u the ``setDefaultController()`` method, unless a route exists for it explicitly. The default value for this is ``Home`` which matches the controller at **app/Controllers/Home.php**: -.. literalinclude:: routing/041.php +.. literalinclude:: routing/043.php :lines: 2- The default controller is also used when no matching route has been found, and the URI would point to a directory @@ -535,7 +535,7 @@ when a controller is found that matches the URI, but no segment exists for the m In this example, if the user were to visit **example.com/products**, and a ``Products`` controller existed, the ``Products::listAll()`` method would be executed: -.. literalinclude:: routing/042.php +.. literalinclude:: routing/044.php :lines: 2- Translate URI Dashes @@ -545,7 +545,7 @@ This option enables you to automatically replace dashes (``-``) with underscores URI segments, thus saving you additional route entries if you need to do that. This is required because the dash isn’t a valid class or method name character and would cause a fatal error if you try to use it: -.. literalinclude:: routing/043.php +.. literalinclude:: routing/045.php :lines: 2- .. _use-defined-routes-only: @@ -557,7 +557,7 @@ When no defined route is found that matches the URI, the system will attempt to controllers and methods as described above. You can disable this automatic matching, and restrict routes to only those defined by you, by setting the ``setAutoRoute()`` option to false: -.. literalinclude:: routing/044.php +.. literalinclude:: routing/046.php :lines: 2- .. warning:: If you use the :doc:`CSRF protection `, it does not protect **GET** @@ -570,7 +570,7 @@ When a page is not found that matches the current URI, the system will show a ge what happens by specifying an action to happen with the ``set404Override()`` method. The value can be either a valid class/method pair, just like you would show in any route, or a Closure: -.. literalinclude:: routing/045.php +.. literalinclude:: routing/047.php :lines: 2- Route processing by priority @@ -580,7 +580,7 @@ Enables or disables processing of the routes queue by priority. Lowering the pri Disabled by default. This functionality affects all routes. For an example use of lowering the priority see :ref:`routing-priority`: -.. literalinclude:: routing/046.php +.. literalinclude:: routing/048.php :lines: 2- ***************** diff --git a/user_guide_src/source/incoming/routing/000.php b/user_guide_src/source/incoming/routing/000.php deleted file mode 100644 index d799d1cf0fb5..000000000000 --- a/user_guide_src/source/incoming/routing/000.php +++ /dev/null @@ -1,3 +0,0 @@ -get('/', 'Home::index'); diff --git a/user_guide_src/source/incoming/routing/001.php b/user_guide_src/source/incoming/routing/001.php index 4ddfd31abaed..d799d1cf0fb5 100644 --- a/user_guide_src/source/incoming/routing/001.php +++ b/user_guide_src/source/incoming/routing/001.php @@ -1,7 +1,3 @@ list() -$routes->get('users', 'Users::list'); - -// Calls $Users->list(1, 23) -$routes->get('users/1/23', 'Users::list/1/23'); \ No newline at end of file +$routes->get('/', 'Home::index'); diff --git a/user_guide_src/source/incoming/routing/002.php b/user_guide_src/source/incoming/routing/002.php index ba4d8d98a28a..4ddfd31abaed 100644 --- a/user_guide_src/source/incoming/routing/002.php +++ b/user_guide_src/source/incoming/routing/002.php @@ -1,3 +1,7 @@ get('product/(:num)', 'Catalog::productLookup'); +// Calls $Users->list() +$routes->get('users', 'Users::list'); + +// Calls $Users->list(1, 23) +$routes->get('users/1/23', 'Users::list/1/23'); \ No newline at end of file diff --git a/user_guide_src/source/incoming/routing/003.php b/user_guide_src/source/incoming/routing/003.php index 7a9075b57b2f..7351142dea77 100644 --- a/user_guide_src/source/incoming/routing/003.php +++ b/user_guide_src/source/incoming/routing/003.php @@ -1,3 +1,5 @@ get('journals', 'Blogs'); +$routes->post('products', 'Product::feature'); +$routes->put('products/1', 'Product::feature'); +$routes->delete('products/1', 'Product::feature'); diff --git a/user_guide_src/source/incoming/routing/004.php b/user_guide_src/source/incoming/routing/004.php index 4ee87c0af53a..a071f75cd156 100644 --- a/user_guide_src/source/incoming/routing/004.php +++ b/user_guide_src/source/incoming/routing/004.php @@ -1,3 +1,3 @@ get('blog/joe', 'Blogs::users/34'); +$routes->match(['get', 'put'], 'products', 'Product::feature'); diff --git a/user_guide_src/source/incoming/routing/005.php b/user_guide_src/source/incoming/routing/005.php index d840165c7809..ba4d8d98a28a 100644 --- a/user_guide_src/source/incoming/routing/005.php +++ b/user_guide_src/source/incoming/routing/005.php @@ -1,3 +1,3 @@ get('product/(:any)', 'Catalog::productLookup'); +$routes->get('product/(:num)', 'Catalog::productLookup'); diff --git a/user_guide_src/source/incoming/routing/006.php b/user_guide_src/source/incoming/routing/006.php index 638ed4492220..7a9075b57b2f 100644 --- a/user_guide_src/source/incoming/routing/006.php +++ b/user_guide_src/source/incoming/routing/006.php @@ -1,3 +1,3 @@ get('product/(:num)', 'Catalog::productLookupByID/$1'); +$routes->get('journals', 'Blogs'); diff --git a/user_guide_src/source/incoming/routing/007.php b/user_guide_src/source/incoming/routing/007.php index c88bc65573a3..4ee87c0af53a 100644 --- a/user_guide_src/source/incoming/routing/007.php +++ b/user_guide_src/source/incoming/routing/007.php @@ -1,3 +1,3 @@ get('product/(:any)', 'Catalog::productLookup/$1'); +$routes->get('blog/joe', 'Blogs::users/34'); diff --git a/user_guide_src/source/incoming/routing/008.php b/user_guide_src/source/incoming/routing/008.php index 11437a5881c2..d840165c7809 100644 --- a/user_guide_src/source/incoming/routing/008.php +++ b/user_guide_src/source/incoming/routing/008.php @@ -1,7 +1,3 @@ get('product/(:any)', 'Catalog::productLookup'); diff --git a/user_guide_src/source/incoming/routing/009.php b/user_guide_src/source/incoming/routing/009.php index cee3785eb0d8..638ed4492220 100644 --- a/user_guide_src/source/incoming/routing/009.php +++ b/user_guide_src/source/incoming/routing/009.php @@ -1,3 +1,3 @@ get('product/(:segment)', 'Catalog::productLookup/$1'); +$routes->get('product/(:num)', 'Catalog::productLookupByID/$1'); diff --git a/user_guide_src/source/incoming/routing/010.php b/user_guide_src/source/incoming/routing/010.php index cb1cdda7c78c..c88bc65573a3 100644 --- a/user_guide_src/source/incoming/routing/010.php +++ b/user_guide_src/source/incoming/routing/010.php @@ -1,4 +1,3 @@ addPlaceholder('uuid', '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'); -$routes->get('users/(:uuid)', 'Users::show/$1'); +$routes->get('product/(:any)', 'Catalog::productLookup/$1'); diff --git a/user_guide_src/source/incoming/routing/011.php b/user_guide_src/source/incoming/routing/011.php index a1619a4bf080..11437a5881c2 100644 --- a/user_guide_src/source/incoming/routing/011.php +++ b/user_guide_src/source/incoming/routing/011.php @@ -1,3 +1,7 @@ get('products/([a-z]+)/(\d+)', 'Products::show/$1/id_$2'); +public function productLookup($seg1 = false, $seg2 = false, $seg3 = false) { + echo $seg1; // Will be 123 in all examples + echo $seg2; // false in first, 456 in second and third example + echo $seg3; // false in first and second, 789 in third +} diff --git a/user_guide_src/source/incoming/routing/012.php b/user_guide_src/source/incoming/routing/012.php index c9ddfae73610..cee3785eb0d8 100644 --- a/user_guide_src/source/incoming/routing/012.php +++ b/user_guide_src/source/incoming/routing/012.php @@ -1,3 +1,3 @@ get('login/(.+)', 'Auth::login/$1'); +$routes->get('product/(:segment)', 'Catalog::productLookup/$1'); diff --git a/user_guide_src/source/incoming/routing/013.php b/user_guide_src/source/incoming/routing/013.php index 2d0f48cb284e..cb1cdda7c78c 100644 --- a/user_guide_src/source/incoming/routing/013.php +++ b/user_guide_src/source/incoming/routing/013.php @@ -1,7 +1,4 @@ get('feed', function () { - $rss = new RSSFeeder(); - - return $rss->feed('general'); -}); +$routes->addPlaceholder('uuid', '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'); +$routes->get('users/(:uuid)', 'Users::show/$1'); diff --git a/user_guide_src/source/incoming/routing/014.php b/user_guide_src/source/incoming/routing/014.php index 8ebc27e3f9f5..a1619a4bf080 100644 --- a/user_guide_src/source/incoming/routing/014.php +++ b/user_guide_src/source/incoming/routing/014.php @@ -1,8 +1,3 @@ 'Catalog::productLookupById', - 'product/(:alphanum)' => 'Catalog::productLookupByName', -]; - -$routes->map($multipleRoutes); +$routes->get('products/([a-z]+)/(\d+)', 'Products::show/$1/id_$2'); diff --git a/user_guide_src/source/incoming/routing/015.php b/user_guide_src/source/incoming/routing/015.php index d92d9934db5a..c9ddfae73610 100644 --- a/user_guide_src/source/incoming/routing/015.php +++ b/user_guide_src/source/incoming/routing/015.php @@ -1,8 +1,3 @@ get('users/profile', 'Users::profile', ['as' => 'profile']); - -// Redirect to a named route -$routes->addRedirect('users/about', 'profile'); -// Redirect to a URI -$routes->addRedirect('users/about', 'users/profile'); +$routes->get('login/(.+)', 'Auth::login/$1'); diff --git a/user_guide_src/source/incoming/routing/016.php b/user_guide_src/source/incoming/routing/016.php index 8c770fd05f24..2d0f48cb284e 100644 --- a/user_guide_src/source/incoming/routing/016.php +++ b/user_guide_src/source/incoming/routing/016.php @@ -1,6 +1,7 @@ group('admin', function ($routes) { - $routes->get('users', 'Admin\Users::index'); - $routes->get('blog', 'Admin\Blog::index'); +$routes->get('feed', function () { + $rss = new RSSFeeder(); + + return $rss->feed('general'); }); diff --git a/user_guide_src/source/incoming/routing/017.php b/user_guide_src/source/incoming/routing/017.php index 678e90700e74..8ebc27e3f9f5 100644 --- a/user_guide_src/source/incoming/routing/017.php +++ b/user_guide_src/source/incoming/routing/017.php @@ -1,5 +1,8 @@ group('api', ['namespace' => 'App\API\v1'], function ($routes) { - $routes->resource('users'); -}); +$multipleRoutes = [ + 'product/(:num)' => 'Catalog::productLookupById', + 'product/(:alphanum)' => 'Catalog::productLookupByName', +]; + +$routes->map($multipleRoutes); diff --git a/user_guide_src/source/incoming/routing/018.php b/user_guide_src/source/incoming/routing/018.php index 395ddfe6c8c8..d92d9934db5a 100644 --- a/user_guide_src/source/incoming/routing/018.php +++ b/user_guide_src/source/incoming/routing/018.php @@ -1,5 +1,8 @@ group('api', ['filter' => 'api-auth'], function ($routes) { - $routes->resource('users'); -}); +$routes->get('users/profile', 'Users::profile', ['as' => 'profile']); + +// Redirect to a named route +$routes->addRedirect('users/about', 'profile'); +// Redirect to a URI +$routes->addRedirect('users/about', 'users/profile'); diff --git a/user_guide_src/source/incoming/routing/019.php b/user_guide_src/source/incoming/routing/019.php index 08169acec275..8c770fd05f24 100644 --- a/user_guide_src/source/incoming/routing/019.php +++ b/user_guide_src/source/incoming/routing/019.php @@ -1,7 +1,6 @@ group('admin', function ($routes) { - $routes->group('users', function ($routes) { - $routes->get('list', 'Admin\Users::list'); - }); + $routes->get('users', 'Admin\Users::index'); + $routes->get('blog', 'Admin\Blog::index'); }); diff --git a/user_guide_src/source/incoming/routing/020.php b/user_guide_src/source/incoming/routing/020.php index d7624ddc6d5c..678e90700e74 100644 --- a/user_guide_src/source/incoming/routing/020.php +++ b/user_guide_src/source/incoming/routing/020.php @@ -1,7 +1,5 @@ group('', ['namespace' => 'Myth\Auth\Controllers'], static function ($routes) { - $routes->get('login', 'AuthController::login', ['as' => 'login']); - $routes->post('login', 'AuthController::attemptLogin'); - $routes->get('logout', 'AuthController::logout'); +$routes->group('api', ['namespace' => 'App\API\v1'], function ($routes) { + $routes->resource('users'); }); diff --git a/user_guide_src/source/incoming/routing/021.php b/user_guide_src/source/incoming/routing/021.php index 69a4c184ab36..395ddfe6c8c8 100644 --- a/user_guide_src/source/incoming/routing/021.php +++ b/user_guide_src/source/incoming/routing/021.php @@ -1,5 +1,5 @@ environment('development', function ($routes) { - $routes->get('builder', 'Tools\Builder::index'); +$routes->group('api', ['filter' => 'api-auth'], function ($routes) { + $routes->resource('users'); }); diff --git a/user_guide_src/source/incoming/routing/022.php b/user_guide_src/source/incoming/routing/022.php index 0af87a58c3b5..08169acec275 100644 --- a/user_guide_src/source/incoming/routing/022.php +++ b/user_guide_src/source/incoming/routing/022.php @@ -1,8 +1,7 @@ get('users/(:num)/gallery(:any)', 'App\Controllers\Galleries::showUserGallery/$1/$2'); - -// Generate the relative URL to link to user ID 15, gallery 12 -// Generates: /users/15/gallery/12 -View Gallery +$routes->group('admin', function ($routes) { + $routes->group('users', function ($routes) { + $routes->get('list', 'Admin\Users::list'); + }); +}); diff --git a/user_guide_src/source/incoming/routing/023-2.php b/user_guide_src/source/incoming/routing/023-2.php deleted file mode 100644 index e2a3784f335f..000000000000 --- a/user_guide_src/source/incoming/routing/023-2.php +++ /dev/null @@ -1,3 +0,0 @@ -add('products', 'Product::feature'); diff --git a/user_guide_src/source/incoming/routing/023.php b/user_guide_src/source/incoming/routing/023.php index 5469c79db91a..d7624ddc6d5c 100644 --- a/user_guide_src/source/incoming/routing/023.php +++ b/user_guide_src/source/incoming/routing/023.php @@ -1,8 +1,7 @@ get('users/(:num)/gallery(:any)', 'Galleries::showUserGallery/$1/$2', ['as' => 'user_gallery']); - -// Generate the relative URL to link to user ID 15, gallery 12 -// Generates: /users/15/gallery/12 -View Gallery +$routes->group('', ['namespace' => 'Myth\Auth\Controllers'], static function ($routes) { + $routes->get('login', 'AuthController::login', ['as' => 'login']); + $routes->post('login', 'AuthController::attemptLogin'); + $routes->get('logout', 'AuthController::logout'); +}); diff --git a/user_guide_src/source/incoming/routing/024.php b/user_guide_src/source/incoming/routing/024.php index 7351142dea77..69a4c184ab36 100644 --- a/user_guide_src/source/incoming/routing/024.php +++ b/user_guide_src/source/incoming/routing/024.php @@ -1,5 +1,5 @@ post('products', 'Product::feature'); -$routes->put('products/1', 'Product::feature'); -$routes->delete('products/1', 'Product::feature'); +$routes->environment('development', function ($routes) { + $routes->get('builder', 'Tools\Builder::index'); +}); diff --git a/user_guide_src/source/incoming/routing/025.php b/user_guide_src/source/incoming/routing/025.php index a071f75cd156..0af87a58c3b5 100644 --- a/user_guide_src/source/incoming/routing/025.php +++ b/user_guide_src/source/incoming/routing/025.php @@ -1,3 +1,8 @@ match(['get', 'put'], 'products', 'Product::feature'); +// The route is defined as: +$routes->get('users/(:num)/gallery(:any)', 'App\Controllers\Galleries::showUserGallery/$1/$2'); + +// Generate the relative URL to link to user ID 15, gallery 12 +// Generates: /users/15/gallery/12 +View Gallery diff --git a/user_guide_src/source/incoming/routing/026.php b/user_guide_src/source/incoming/routing/026.php index a82d57ebc5c7..5469c79db91a 100644 --- a/user_guide_src/source/incoming/routing/026.php +++ b/user_guide_src/source/incoming/routing/026.php @@ -1,3 +1,8 @@ cli('migrate', 'App\Database::migrate'); +// The route is defined as: +$routes->get('users/(:num)/gallery(:any)', 'Galleries::showUserGallery/$1/$2', ['as' => 'user_gallery']); + +// Generate the relative URL to link to user ID 15, gallery 12 +// Generates: /users/15/gallery/12 +View Gallery diff --git a/user_guide_src/source/incoming/routing/027.php b/user_guide_src/source/incoming/routing/027.php index 31c1dda07a70..e2a3784f335f 100644 --- a/user_guide_src/source/incoming/routing/027.php +++ b/user_guide_src/source/incoming/routing/027.php @@ -1,14 +1,3 @@ add('from', 'to', $options); -$routes->get('from', 'to', $options); -$routes->post('from', 'to', $options); -$routes->put('from', 'to', $options); -$routes->head('from', 'to', $options); -$routes->options('from', 'to', $options); -$routes->delete('from', 'to', $options); -$routes->patch('from', 'to', $options); -$routes->match(['get', 'put'], 'from', 'to', $options); -$routes->resource('photos', $options); -$routes->map($array, $options); -$routes->group('name', $options, function ()); +$routes->add('products', 'Product::feature'); diff --git a/user_guide_src/source/incoming/routing/028.php b/user_guide_src/source/incoming/routing/028.php index ca1121e0786d..a82d57ebc5c7 100644 --- a/user_guide_src/source/incoming/routing/028.php +++ b/user_guide_src/source/incoming/routing/028.php @@ -1,3 +1,3 @@ get('admin',' AdminController::index', ['filter' => 'admin-auth']); +$routes->cli('migrate', 'App\Database::migrate'); diff --git a/user_guide_src/source/incoming/routing/029.php b/user_guide_src/source/incoming/routing/029.php index b50db49bd962..31c1dda07a70 100644 --- a/user_guide_src/source/incoming/routing/029.php +++ b/user_guide_src/source/incoming/routing/029.php @@ -1,3 +1,14 @@ post('users/delete/(:segment)', 'AdminController::index', ['filter' => 'admin-auth:dual,noreturn']); +$routes->add('from', 'to', $options); +$routes->get('from', 'to', $options); +$routes->post('from', 'to', $options); +$routes->put('from', 'to', $options); +$routes->head('from', 'to', $options); +$routes->options('from', 'to', $options); +$routes->delete('from', 'to', $options); +$routes->patch('from', 'to', $options); +$routes->match(['get', 'put'], 'from', 'to', $options); +$routes->resource('photos', $options); +$routes->map($array, $options); +$routes->group('name', $options, function ()); diff --git a/user_guide_src/source/incoming/routing/030.php b/user_guide_src/source/incoming/routing/030.php index 14d5142de2f0..ca1121e0786d 100644 --- a/user_guide_src/source/incoming/routing/030.php +++ b/user_guide_src/source/incoming/routing/030.php @@ -1,3 +1,3 @@ get('admin',' AdminController::index', ['filter' => \App\Filters\SomeFilter::class]); +$routes->get('admin',' AdminController::index', ['filter' => 'admin-auth']); diff --git a/user_guide_src/source/incoming/routing/031.php b/user_guide_src/source/incoming/routing/031.php index 24cf6c5dbc2d..b50db49bd962 100644 --- a/user_guide_src/source/incoming/routing/031.php +++ b/user_guide_src/source/incoming/routing/031.php @@ -1,3 +1,3 @@ get('admin',' AdminController::index', ['filter' => ['admin-auth', \App\Filters\SomeFilter::class]]); +$routes->post('users/delete/(:segment)', 'AdminController::index', ['filter' => 'admin-auth:dual,noreturn']); diff --git a/user_guide_src/source/incoming/routing/032.php b/user_guide_src/source/incoming/routing/032.php index b992deb96ecf..14d5142de2f0 100644 --- a/user_guide_src/source/incoming/routing/032.php +++ b/user_guide_src/source/incoming/routing/032.php @@ -1,4 +1,3 @@ get('admin/users', 'Users::index', ['namespace' => 'Admin']); +$routes->get('admin',' AdminController::index', ['filter' => \App\Filters\SomeFilter::class]); diff --git a/user_guide_src/source/incoming/routing/033.php b/user_guide_src/source/incoming/routing/033.php index 5b415a50138b..24cf6c5dbc2d 100644 --- a/user_guide_src/source/incoming/routing/033.php +++ b/user_guide_src/source/incoming/routing/033.php @@ -1,3 +1,3 @@ get('from', 'to', ['hostname' => 'accounts.example.com']); +$routes->get('admin',' AdminController::index', ['filter' => ['admin-auth', \App\Filters\SomeFilter::class]]); diff --git a/user_guide_src/source/incoming/routing/034.php b/user_guide_src/source/incoming/routing/034.php index 32a74934eb3a..b992deb96ecf 100644 --- a/user_guide_src/source/incoming/routing/034.php +++ b/user_guide_src/source/incoming/routing/034.php @@ -1,4 +1,4 @@ get('from', 'to', ['subdomain' => 'media']); +// Routes to \Admin\Users::index() +$routes->get('admin/users', 'Users::index', ['namespace' => 'Admin']); diff --git a/user_guide_src/source/incoming/routing/035.php b/user_guide_src/source/incoming/routing/035.php index 0d0fd0e67fb4..5b415a50138b 100644 --- a/user_guide_src/source/incoming/routing/035.php +++ b/user_guide_src/source/incoming/routing/035.php @@ -1,4 +1,3 @@ get('from', 'to', ['subdomain' => '*']); +$routes->get('from', 'to', ['hostname' => 'accounts.example.com']); diff --git a/user_guide_src/source/incoming/routing/036.php b/user_guide_src/source/incoming/routing/036.php index ec7fa680f65e..32a74934eb3a 100644 --- a/user_guide_src/source/incoming/routing/036.php +++ b/user_guide_src/source/incoming/routing/036.php @@ -1,6 +1,4 @@ get('users/(:num)', 'users/show/$1', ['offset' => 1]); - -// Creates: -$routes['users/(:num)'] = 'users/show/$2'; +// Limit to media.example.com +$routes->get('from', 'to', ['subdomain' => 'media']); diff --git a/user_guide_src/source/incoming/routing/037.php b/user_guide_src/source/incoming/routing/037.php index 29fc83e59f17..0d0fd0e67fb4 100644 --- a/user_guide_src/source/incoming/routing/037.php +++ b/user_guide_src/source/incoming/routing/037.php @@ -1,12 +1,4 @@ setPrioritize(); - -// App\Config\Routes -$routes->get('(.*)', 'Posts::index', ['priority' => 1]); - -// Modules\Acme\Config\Routes -$routes->get('admin', 'Admin::index'); - -// The "admin" route will now be processed before the wildcard router. +// Limit to any sub-domain +$routes->get('from', 'to', ['subdomain' => '*']); diff --git a/user_guide_src/source/incoming/routing/038.php b/user_guide_src/source/incoming/routing/038.php index 9465f4147e2c..ec7fa680f65e 100644 --- a/user_guide_src/source/incoming/routing/038.php +++ b/user_guide_src/source/incoming/routing/038.php @@ -1,3 +1,6 @@ setPrioritize(false); +$routes->get('users/(:num)', 'users/show/$1', ['offset' => 1]); + +// Creates: +$routes['users/(:num)'] = 'users/show/$2'; diff --git a/user_guide_src/source/incoming/routing/039.php b/user_guide_src/source/incoming/routing/039.php index 98aef9276f9d..29fc83e59f17 100644 --- a/user_guide_src/source/incoming/routing/039.php +++ b/user_guide_src/source/incoming/routing/039.php @@ -1,9 +1,12 @@ setDefaultNamespace(''); +// First you need to enable sorting. +$routes->setPrioritize(); -// Controller is \Users -$routes->get('users', 'Users::index'); +// App\Config\Routes +$routes->get('(.*)', 'Posts::index', ['priority' => 1]); -// Controller is \Admin\Users -$routes->get('users', 'Admin\Users::index'); +// Modules\Acme\Config\Routes +$routes->get('admin', 'Admin::index'); + +// The "admin" route will now be processed before the wildcard router. diff --git a/user_guide_src/source/incoming/routing/040.php b/user_guide_src/source/incoming/routing/040.php index fbbbee2300df..9465f4147e2c 100644 --- a/user_guide_src/source/incoming/routing/040.php +++ b/user_guide_src/source/incoming/routing/040.php @@ -1,9 +1,3 @@ setDefaultNamespace('App'); - -// Controller is \App\Users -$routes->get('users', 'Users::index'); - -// Controller is \App\Admin\Users -$routes->get('users', 'Admin\Users::index'); +$routes->setPrioritize(false); diff --git a/user_guide_src/source/incoming/routing/041.php b/user_guide_src/source/incoming/routing/041.php index 5d17df8130d4..98aef9276f9d 100644 --- a/user_guide_src/source/incoming/routing/041.php +++ b/user_guide_src/source/incoming/routing/041.php @@ -1,4 +1,9 @@ setDefaultController('Welcome'); +$routes->setDefaultNamespace(''); + +// Controller is \Users +$routes->get('users', 'Users::index'); + +// Controller is \Admin\Users +$routes->get('users', 'Admin\Users::index'); diff --git a/user_guide_src/source/incoming/routing/042.php b/user_guide_src/source/incoming/routing/042.php index e926e651287d..fbbbee2300df 100644 --- a/user_guide_src/source/incoming/routing/042.php +++ b/user_guide_src/source/incoming/routing/042.php @@ -1,3 +1,9 @@ setDefaultMethod('listAll'); +$routes->setDefaultNamespace('App'); + +// Controller is \App\Users +$routes->get('users', 'Users::index'); + +// Controller is \App\Admin\Users +$routes->get('users', 'Admin\Users::index'); diff --git a/user_guide_src/source/incoming/routing/043.php b/user_guide_src/source/incoming/routing/043.php index 31d49508ab86..5d17df8130d4 100644 --- a/user_guide_src/source/incoming/routing/043.php +++ b/user_guide_src/source/incoming/routing/043.php @@ -1,3 +1,4 @@ setTranslateURIDashes(true); +// example.com routes to app/Controllers/Welcome.php +$routes->setDefaultController('Welcome'); diff --git a/user_guide_src/source/incoming/routing/044.php b/user_guide_src/source/incoming/routing/044.php index c331102cd9f4..e926e651287d 100644 --- a/user_guide_src/source/incoming/routing/044.php +++ b/user_guide_src/source/incoming/routing/044.php @@ -1,3 +1,3 @@ setAutoRoute(false); +$routes->setDefaultMethod('listAll'); diff --git a/user_guide_src/source/incoming/routing/045.php b/user_guide_src/source/incoming/routing/045.php index 1f3758e244d4..31d49508ab86 100644 --- a/user_guide_src/source/incoming/routing/045.php +++ b/user_guide_src/source/incoming/routing/045.php @@ -1,10 +1,3 @@ set404Override('App\Errors::show404'); - -// Will display a custom view -$routes->set404Override(function () -{ - echo view('my_errors/not_found.html'); -}); +$routes->setTranslateURIDashes(true); diff --git a/user_guide_src/source/incoming/routing/046.php b/user_guide_src/source/incoming/routing/046.php index e3dd9f60c989..c331102cd9f4 100644 --- a/user_guide_src/source/incoming/routing/046.php +++ b/user_guide_src/source/incoming/routing/046.php @@ -1,7 +1,3 @@ setPrioritize(); - -// to disable -$routes->setPrioritize(false); +$routes->setAutoRoute(false); diff --git a/user_guide_src/source/incoming/routing/047.php b/user_guide_src/source/incoming/routing/047.php new file mode 100644 index 000000000000..1f3758e244d4 --- /dev/null +++ b/user_guide_src/source/incoming/routing/047.php @@ -0,0 +1,10 @@ +set404Override('App\Errors::show404'); + +// Will display a custom view +$routes->set404Override(function () +{ + echo view('my_errors/not_found.html'); +}); diff --git a/user_guide_src/source/incoming/routing/048.php b/user_guide_src/source/incoming/routing/048.php new file mode 100644 index 000000000000..e3dd9f60c989 --- /dev/null +++ b/user_guide_src/source/incoming/routing/048.php @@ -0,0 +1,7 @@ +setPrioritize(); + +// to disable +$routes->setPrioritize(false); diff --git a/user_guide_src/source/libraries/sessions.rst b/user_guide_src/source/libraries/sessions.rst index fcab322aa3d9..ad45f9fea4f3 100644 --- a/user_guide_src/source/libraries/sessions.rst +++ b/user_guide_src/source/libraries/sessions.rst @@ -119,7 +119,7 @@ Retrieving Session Data Any piece of information from the session array is available through the ``$_SESSION`` superglobal: -.. literalinclude:: sessions/005-2.php +.. literalinclude:: sessions/005.php :lines: 2- Or through the conventional accessor method: @@ -264,7 +264,7 @@ You can also pass an array to ``setFlashdata()``, in the same manner as Reading flashdata variables is the same as reading regular session data through ``$_SESSION``: -.. literalinclude:: sessions/005.php +.. literalinclude:: sessions/024.php :lines: 2- .. important:: The ``get()`` method WILL return flashdata items when @@ -335,7 +335,7 @@ You can also pass an array to ``setTempdata()``: To read a tempdata variable, again you can just access it through the ``$_SESSION`` superglobal array: -.. literalinclude:: sessions/005-1.php +.. literalinclude:: sessions/033.php :lines: 2- .. important:: The ``get()`` method WILL return tempdata items when diff --git a/user_guide_src/source/libraries/sessions/005-1.php b/user_guide_src/source/libraries/sessions/005-1.php deleted file mode 100644 index 4f09358d5fc8..000000000000 --- a/user_guide_src/source/libraries/sessions/005-1.php +++ /dev/null @@ -1,3 +0,0 @@ - - - - Upload Form - - - - -
  • - - - - - - -

    - - - - - - - diff --git a/user_guide_src/source/libraries/uploaded_files/001.php b/user_guide_src/source/libraries/uploaded_files/001.php index f186d517fd96..d58b7664d28b 100644 --- a/user_guide_src/source/libraries/uploaded_files/001.php +++ b/user_guide_src/source/libraries/uploaded_files/001.php @@ -1,48 +1,23 @@ - + + + Upload Form + + -namespace App\Controllers; + +
  • + -use CodeIgniter\Files\File; + -class Upload extends BaseController -{ - protected $helpers = ['form']; + - public function index() - { - return view('upload_form', ['errors' => []]); - } +

    - public function upload() - { - $validationRule = [ - 'userfile' => [ - 'label' => 'Image File', - 'rules' => 'uploaded[userfile]' - . '|is_image[userfile]' - . '|mime_in[userfile,image/jpg,image/jpeg,image/gif,image/png,image/webp]' - . '|max_size[userfile,100]' - . '|max_dims[userfile,1024,768]', - ], - ]; - if (! $this->validate($validationRule)) { - $data = ['errors' => $this->validator->getErrors()]; + - return view('upload_form', $data); - } + - $img = $this->request->getFile('userfile'); - - if (! $img->hasMoved()) { - $filepath = WRITEPATH . 'uploads/' . $img->store(); - - $data = ['uploaded_flleinfo' => new File($filepath)]; - - return view('upload_success', $data); - } else { - $data = ['errors' => 'The file has already been moved.']; - - return view('upload_form', $data); - } - } -} + + diff --git a/user_guide_src/source/libraries/uploaded_files/002.php b/user_guide_src/source/libraries/uploaded_files/002.php index 17141efbdde8..f186d517fd96 100644 --- a/user_guide_src/source/libraries/uploaded_files/002.php +++ b/user_guide_src/source/libraries/uploaded_files/002.php @@ -1,3 +1,48 @@ request->getFiles(); +namespace App\Controllers; + +use CodeIgniter\Files\File; + +class Upload extends BaseController +{ + protected $helpers = ['form']; + + public function index() + { + return view('upload_form', ['errors' => []]); + } + + public function upload() + { + $validationRule = [ + 'userfile' => [ + 'label' => 'Image File', + 'rules' => 'uploaded[userfile]' + . '|is_image[userfile]' + . '|mime_in[userfile,image/jpg,image/jpeg,image/gif,image/png,image/webp]' + . '|max_size[userfile,100]' + . '|max_dims[userfile,1024,768]', + ], + ]; + if (! $this->validate($validationRule)) { + $data = ['errors' => $this->validator->getErrors()]; + + return view('upload_form', $data); + } + + $img = $this->request->getFile('userfile'); + + if (! $img->hasMoved()) { + $filepath = WRITEPATH . 'uploads/' . $img->store(); + + $data = ['uploaded_flleinfo' => new File($filepath)]; + + return view('upload_success', $data); + } else { + $data = ['errors' => 'The file has already been moved.']; + + return view('upload_form', $data); + } + } +} diff --git a/user_guide_src/source/libraries/uploaded_files/003.php b/user_guide_src/source/libraries/uploaded_files/003.php index 368facf4f7ab..17141efbdde8 100644 --- a/user_guide_src/source/libraries/uploaded_files/003.php +++ b/user_guide_src/source/libraries/uploaded_files/003.php @@ -1,5 +1,3 @@ // UploadedFile instance -] +$files = $this->request->getFiles(); diff --git a/user_guide_src/source/libraries/uploaded_files/004.php b/user_guide_src/source/libraries/uploaded_files/004.php index bf31373e57bd..368facf4f7ab 100644 --- a/user_guide_src/source/libraries/uploaded_files/004.php +++ b/user_guide_src/source/libraries/uploaded_files/004.php @@ -1,9 +1,5 @@ [ - 'details' => [ - 'avatar' => // UploadedFile instance - ] - ] + 'avatar' => // UploadedFile instance ] diff --git a/user_guide_src/source/libraries/uploaded_files/005.php b/user_guide_src/source/libraries/uploaded_files/005.php index c53d82a298fc..bf31373e57bd 100644 --- a/user_guide_src/source/libraries/uploaded_files/005.php +++ b/user_guide_src/source/libraries/uploaded_files/005.php @@ -3,9 +3,7 @@ [ 'my-form' => [ 'details' => [ - 'avatar' => [ - 0 => /* UploadedFile instance */, - 1 => /* UploadedFile instance */ + 'avatar' => // UploadedFile instance ] ] ] diff --git a/user_guide_src/source/libraries/uploaded_files/006.php b/user_guide_src/source/libraries/uploaded_files/006.php index e5f6440d96fb..c53d82a298fc 100644 --- a/user_guide_src/source/libraries/uploaded_files/006.php +++ b/user_guide_src/source/libraries/uploaded_files/006.php @@ -1,3 +1,11 @@ request->getFile('userfile'); +[ + 'my-form' => [ + 'details' => [ + 'avatar' => [ + 0 => /* UploadedFile instance */, + 1 => /* UploadedFile instance */ + ] + ] +] diff --git a/user_guide_src/source/libraries/uploaded_files/007.php b/user_guide_src/source/libraries/uploaded_files/007.php index ad71bd5575fb..e5f6440d96fb 100644 --- a/user_guide_src/source/libraries/uploaded_files/007.php +++ b/user_guide_src/source/libraries/uploaded_files/007.php @@ -1,3 +1,3 @@ request->getFile('my-form.details.avatar'); +$file = $this->request->getFile('userfile'); diff --git a/user_guide_src/source/libraries/uploaded_files/008.php b/user_guide_src/source/libraries/uploaded_files/008.php index f37491c04821..ad71bd5575fb 100644 --- a/user_guide_src/source/libraries/uploaded_files/008.php +++ b/user_guide_src/source/libraries/uploaded_files/008.php @@ -1,10 +1,3 @@ request->getFiles()) { - foreach($imagefile['images'] as $img) { - if ($img->isValid() && ! $img->hasMoved()) { - $newName = $img->getRandomName(); - $img->move(WRITEPATH . 'uploads', $newName); - } - } -} +$file = $this->request->getFile('my-form.details.avatar'); diff --git a/user_guide_src/source/libraries/uploaded_files/009.php b/user_guide_src/source/libraries/uploaded_files/009.php index da51d17dbd15..f37491c04821 100644 --- a/user_guide_src/source/libraries/uploaded_files/009.php +++ b/user_guide_src/source/libraries/uploaded_files/009.php @@ -1,4 +1,10 @@ request->getFile('images.0'); -$file2 = $this->request->getFile('images.1'); +if ($imagefile = $this->request->getFiles()) { + foreach($imagefile['images'] as $img) { + if ($img->isValid() && ! $img->hasMoved()) { + $newName = $img->getRandomName(); + $img->move(WRITEPATH . 'uploads', $newName); + } + } +} diff --git a/user_guide_src/source/libraries/uploaded_files/010.php b/user_guide_src/source/libraries/uploaded_files/010.php index 646e6bb0b8b9..da51d17dbd15 100644 --- a/user_guide_src/source/libraries/uploaded_files/010.php +++ b/user_guide_src/source/libraries/uploaded_files/010.php @@ -1,3 +1,4 @@ request->getFileMultiple('images'); +$file1 = $this->request->getFile('images.0'); +$file2 = $this->request->getFile('images.1'); diff --git a/user_guide_src/source/libraries/uploaded_files/011.php b/user_guide_src/source/libraries/uploaded_files/011.php index d18a755ba234..646e6bb0b8b9 100644 --- a/user_guide_src/source/libraries/uploaded_files/011.php +++ b/user_guide_src/source/libraries/uploaded_files/011.php @@ -1,4 +1,3 @@ request->getFile('my-form.details.avatars.0'); -$file2 = $this->request->getFile('my-form.details.avatars.1'); +$files = $this->request->getFileMultiple('images'); diff --git a/user_guide_src/source/libraries/uploaded_files/012.php b/user_guide_src/source/libraries/uploaded_files/012.php index 094ea73c1064..d18a755ba234 100644 --- a/user_guide_src/source/libraries/uploaded_files/012.php +++ b/user_guide_src/source/libraries/uploaded_files/012.php @@ -1,5 +1,4 @@ isValid()) { - throw new \RuntimeException($file->getErrorString() . '(' . $file->getError() . ')'); -} +$file1 = $this->request->getFile('my-form.details.avatars.0'); +$file2 = $this->request->getFile('my-form.details.avatars.1'); diff --git a/user_guide_src/source/libraries/uploaded_files/013.php b/user_guide_src/source/libraries/uploaded_files/013.php index 057a56b3e9a0..094ea73c1064 100644 --- a/user_guide_src/source/libraries/uploaded_files/013.php +++ b/user_guide_src/source/libraries/uploaded_files/013.php @@ -1,3 +1,5 @@ getName(); +if (! $file->isValid()) { + throw new \RuntimeException($file->getErrorString() . '(' . $file->getError() . ')'); +} diff --git a/user_guide_src/source/libraries/uploaded_files/014.php b/user_guide_src/source/libraries/uploaded_files/014.php index 4fb0cae0ad12..057a56b3e9a0 100644 --- a/user_guide_src/source/libraries/uploaded_files/014.php +++ b/user_guide_src/source/libraries/uploaded_files/014.php @@ -1,3 +1,3 @@ getClientName(); +$name = $file->getName(); diff --git a/user_guide_src/source/libraries/uploaded_files/015.php b/user_guide_src/source/libraries/uploaded_files/015.php index c9e4774a4bbf..4fb0cae0ad12 100644 --- a/user_guide_src/source/libraries/uploaded_files/015.php +++ b/user_guide_src/source/libraries/uploaded_files/015.php @@ -1,3 +1,3 @@ getTempName(); +$originalName = $file->getClientName(); diff --git a/user_guide_src/source/libraries/uploaded_files/016.php b/user_guide_src/source/libraries/uploaded_files/016.php index 867877238c76..c9e4774a4bbf 100644 --- a/user_guide_src/source/libraries/uploaded_files/016.php +++ b/user_guide_src/source/libraries/uploaded_files/016.php @@ -1,3 +1,3 @@ getClientExtension(); +$tempfile = $file->getTempName(); diff --git a/user_guide_src/source/libraries/uploaded_files/017.php b/user_guide_src/source/libraries/uploaded_files/017.php index dd1288e441c3..867877238c76 100644 --- a/user_guide_src/source/libraries/uploaded_files/017.php +++ b/user_guide_src/source/libraries/uploaded_files/017.php @@ -1,5 +1,3 @@ getClientMimeType(); - -echo $type; // image/png +$ext = $file->getClientExtension(); diff --git a/user_guide_src/source/libraries/uploaded_files/018.php b/user_guide_src/source/libraries/uploaded_files/018.php index 12499a3ca1ba..dd1288e441c3 100644 --- a/user_guide_src/source/libraries/uploaded_files/018.php +++ b/user_guide_src/source/libraries/uploaded_files/018.php @@ -1,3 +1,5 @@ move(WRITEPATH . 'uploads'); +$type = $file->getClientMimeType(); + +echo $type; // image/png diff --git a/user_guide_src/source/libraries/uploaded_files/019.php b/user_guide_src/source/libraries/uploaded_files/019.php index 2e6b39645a4b..12499a3ca1ba 100644 --- a/user_guide_src/source/libraries/uploaded_files/019.php +++ b/user_guide_src/source/libraries/uploaded_files/019.php @@ -1,4 +1,3 @@ getRandomName(); -$file->move(WRITEPATH . 'uploads', $newName); +$file->move(WRITEPATH . 'uploads'); diff --git a/user_guide_src/source/libraries/uploaded_files/020.php b/user_guide_src/source/libraries/uploaded_files/020.php index 7f49d1f5232e..2e6b39645a4b 100644 --- a/user_guide_src/source/libraries/uploaded_files/020.php +++ b/user_guide_src/source/libraries/uploaded_files/020.php @@ -1,5 +1,4 @@ isValid() && ! $file->hasMoved()) { - $file->move($path); -} +$newName = $file->getRandomName(); +$file->move(WRITEPATH . 'uploads', $newName); diff --git a/user_guide_src/source/libraries/uploaded_files/021.php b/user_guide_src/source/libraries/uploaded_files/021.php index 90f9495eaf7b..7f49d1f5232e 100644 --- a/user_guide_src/source/libraries/uploaded_files/021.php +++ b/user_guide_src/source/libraries/uploaded_files/021.php @@ -1,3 +1,5 @@ request->getFile('userfile')->store(); +if ($file->isValid() && ! $file->hasMoved()) { + $file->move($path); +} diff --git a/user_guide_src/source/libraries/uploaded_files/022.php b/user_guide_src/source/libraries/uploaded_files/022.php index 0e552f417d52..90f9495eaf7b 100644 --- a/user_guide_src/source/libraries/uploaded_files/022.php +++ b/user_guide_src/source/libraries/uploaded_files/022.php @@ -1,3 +1,3 @@ request->getFile('userfile')->store('head_img/', 'user_name.jpg'); +$path = $this->request->getFile('userfile')->store(); diff --git a/user_guide_src/source/libraries/uploaded_files/023.php b/user_guide_src/source/libraries/uploaded_files/023.php new file mode 100644 index 000000000000..0e552f417d52 --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/023.php @@ -0,0 +1,3 @@ +request->getFile('userfile')->store('head_img/', 'user_name.jpg'); diff --git a/user_guide_src/source/libraries/validation.rst b/user_guide_src/source/libraries/validation.rst index 0f43f911a506..a74bca7904d8 100644 --- a/user_guide_src/source/libraries/validation.rst +++ b/user_guide_src/source/libraries/validation.rst @@ -534,12 +534,12 @@ The first step is to create custom views. These can be placed anywhere that the which means the standard View directory, or any namespaced View folder will work. For example, you could create a new view at **/app/Views/_errors_list.php**: -.. literalinclude:: validation/029-2.php +.. literalinclude:: validation/030.php An array named ``$errors`` is available within the view that contains a list of the errors, where the key is the name of the field that had the error, and the value is the error message, like this: -.. literalinclude:: validation/030.php +.. literalinclude:: validation/031.php :lines: 2- There are actually two types of views that you can create. The first has an array of all of the errors, and is what @@ -555,7 +555,7 @@ Once you have your views created, you need to let the Validation library know ab Inside, you'll find the ``$templates`` property where you can list as many custom views as you want, and provide an short alias they can be referenced by. If we were to add our example file from above, it would look something like: -.. literalinclude:: validation/031.php +.. literalinclude:: validation/032.php :lines: 2- Specifying the Template @@ -577,7 +577,7 @@ Rules are stored within simple, namespaced classes. They can be stored any locat autoloader can find it. These files are called RuleSets. To add a new RuleSet, edit **Config/Validation.php** and add the new file to the ``$ruleSets`` array: -.. literalinclude:: validation/032.php +.. literalinclude:: validation/033.php :lines: 2- You can add it as either a simple string with the fully qualified class name, or using the ``::class`` suffix as @@ -586,19 +586,19 @@ shown above. The primary benefit here is that it provides some extra navigation Within the file itself, each method is a rule and must accept a string as the first parameter, and must return a boolean true or false value signifying true if it passed the test or false if it did not: -.. literalinclude:: validation/033.php +.. literalinclude:: validation/034.php :lines: 2- By default, the system will look within ``CodeIgniter\Language\en\Validation.php`` for the language strings used within errors. In custom rules, you may provide error messages by accepting a ``$error`` variable by reference in the second parameter: -.. literalinclude:: validation/034.php +.. literalinclude:: validation/035.php :lines: 2- Your new custom rule could now be used just like any other rule: -.. literalinclude:: validation/035.php +.. literalinclude:: validation/036.php :lines: 2- Allowing Parameters @@ -608,7 +608,7 @@ If your method needs to work with parameters, the function will need a minimum o the parameter string, and an array with all of the data that was submitted the form. The ``$data`` array is especially handy for rules like ``require_with`` that needs to check the value of another submitted field to base its result on: -.. literalinclude:: validation/036.php +.. literalinclude:: validation/037.php :lines: 2- Custom errors can be returned as the fourth parameter, just as described above. @@ -621,7 +621,7 @@ The following is a list of all the native rules that are available to use: .. note:: Rule is a string; there must be **no spaces** between the parameters, especially the ``is_unique`` rule. There can be no spaces before and after ``ignore_value``. -.. literalinclude:: validation/037.php +.. literalinclude:: validation/038.php :lines: 2- ======================= ========== ============================================= =================================================== diff --git a/user_guide_src/source/libraries/validation/029-2.php b/user_guide_src/source/libraries/validation/029-2.php deleted file mode 100644 index f7c69eb42e99..000000000000 --- a/user_guide_src/source/libraries/validation/029-2.php +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/user_guide_src/source/libraries/validation/030.php b/user_guide_src/source/libraries/validation/030.php index 0da86ca2d054..f7c69eb42e99 100644 --- a/user_guide_src/source/libraries/validation/030.php +++ b/user_guide_src/source/libraries/validation/030.php @@ -1,6 +1,7 @@ - 'The username field must be unique.', - 'email' => 'You must provide a valid email address.' -]; + diff --git a/user_guide_src/source/libraries/validation/031.php b/user_guide_src/source/libraries/validation/031.php index 110b159a41cc..0da86ca2d054 100644 --- a/user_guide_src/source/libraries/validation/031.php +++ b/user_guide_src/source/libraries/validation/031.php @@ -1,7 +1,6 @@ 'CodeIgniter\Validation\Views\list', - 'single' => 'CodeIgniter\Validation\Views\single', - 'my_list' => '_errors_list', +$errors = [ + 'username' => 'The username field must be unique.', + 'email' => 'You must provide a valid email address.' ]; diff --git a/user_guide_src/source/libraries/validation/032.php b/user_guide_src/source/libraries/validation/032.php index ccee27b08ad7..110b159a41cc 100644 --- a/user_guide_src/source/libraries/validation/032.php +++ b/user_guide_src/source/libraries/validation/032.php @@ -1,13 +1,7 @@ 'CodeIgniter\Validation\Views\list', + 'single' => 'CodeIgniter\Validation\Views\single', + 'my_list' => '_errors_list', ]; diff --git a/user_guide_src/source/libraries/validation/033.php b/user_guide_src/source/libraries/validation/033.php index d7a10b5071cd..ccee27b08ad7 100644 --- a/user_guide_src/source/libraries/validation/033.php +++ b/user_guide_src/source/libraries/validation/033.php @@ -1,9 +1,13 @@ validate($request, [ - 'foo' => 'required|even', -]); +public function even(string $str, string &$error = null): bool +{ + if ((int) $str % 2 !== 0) { + $error = lang('myerrors.evenError'); + + return false; + } + + return true; +} diff --git a/user_guide_src/source/libraries/validation/036.php b/user_guide_src/source/libraries/validation/036.php index 9511380c04f5..99db5f30eae4 100644 --- a/user_guide_src/source/libraries/validation/036.php +++ b/user_guide_src/source/libraries/validation/036.php @@ -1,34 +1,5 @@ required($str ?? ''); - - if ($present) { - return true; - } - - // Still here? Then we fail this test if - // any of the fields are present in $data - // as $fields is the lis - $requiredFields = []; - - foreach ($fields as $field) { - if (array_key_exists($field, $data)) { - $requiredFields[] = $field; - } - } - - // Remove any keys with empty values since, that means they - // weren't truly there, as far as this is concerned. - $requiredFields = array_filter($requiredFields, function ($item) use ($data) { - return ! empty($data[$item]); - }); - - return empty($requiredFields); -} +$this->validate($request, [ + 'foo' => 'required|even', +]); diff --git a/user_guide_src/source/libraries/validation/037.php b/user_guide_src/source/libraries/validation/037.php index 089b0eeaf465..9511380c04f5 100644 --- a/user_guide_src/source/libraries/validation/037.php +++ b/user_guide_src/source/libraries/validation/037.php @@ -1,10 +1,34 @@ setRules([ - 'name' => "is_unique[supplier.name,uuid, $uuid]", // is not ok - 'name' => "is_unique[supplier.name,uuid,$uuid ]", // is not ok - 'name' => "is_unique[supplier.name,uuid,$uuid]", // is ok - 'name' => "is_unique[supplier.name,uuid,{uuid}]", // is ok - see "Validation Placeholders" -]); +public function required_with($str, string $fields, array $data): bool +{ + $fields = explode(',', $fields); + + // If the field is present we can safely assume that + // the field is here, no matter whether the corresponding + // search field is present or not. + $present = $this->required($str ?? ''); + + if ($present) { + return true; + } + + // Still here? Then we fail this test if + // any of the fields are present in $data + // as $fields is the lis + $requiredFields = []; + + foreach ($fields as $field) { + if (array_key_exists($field, $data)) { + $requiredFields[] = $field; + } + } + + // Remove any keys with empty values since, that means they + // weren't truly there, as far as this is concerned. + $requiredFields = array_filter($requiredFields, function ($item) use ($data) { + return ! empty($data[$item]); + }); + + return empty($requiredFields); +} diff --git a/user_guide_src/source/libraries/validation/038.php b/user_guide_src/source/libraries/validation/038.php new file mode 100644 index 000000000000..089b0eeaf465 --- /dev/null +++ b/user_guide_src/source/libraries/validation/038.php @@ -0,0 +1,10 @@ +setRules([ + 'name' => "is_unique[supplier.name,uuid, $uuid]", // is not ok + 'name' => "is_unique[supplier.name,uuid,$uuid ]", // is not ok + 'name' => "is_unique[supplier.name,uuid,$uuid]", // is ok + 'name' => "is_unique[supplier.name,uuid,{uuid}]", // is ok - see "Validation Placeholders" +]); diff --git a/user_guide_src/source/outgoing/view_parser.rst b/user_guide_src/source/outgoing/view_parser.rst index 4681711398d0..ef17f8d7fa6e 100644 --- a/user_guide_src/source/outgoing/view_parser.rst +++ b/user_guide_src/source/outgoing/view_parser.rst @@ -281,7 +281,7 @@ blocks must be closed with an ``endif`` tag:: This simple block is converted to the following during parsing: -.. literalinclude:: view_parser/010-2.php +.. literalinclude:: view_parser/011.php All variables used within if statements must have been previously set with the same name. Other than that, it is treated exactly like a standard PHP conditional, and all standard PHP rules would apply here. You can use any @@ -413,7 +413,7 @@ You can easily create your own filters by editing **app/Config/View.php** and ad ``$filters`` array. Each key is the name of the filter is called by in the view, and its value is any valid PHP callable: -.. literalinclude:: view_parser/011.php +.. literalinclude:: view_parser/012.php :lines: 2- PHP Native functions as Filters @@ -423,7 +423,7 @@ You can use native php function as filters by editing **app/Config/View.php** an ``$filters`` array.Each key is the name of the native PHP function is called by in the view, and its value is any valid native PHP function prefixed with: -.. literalinclude:: view_parser/012.php +.. literalinclude:: view_parser/013.php :lines: 2- Parser Plugins @@ -481,24 +481,24 @@ At its simplest, all you need to do to register a new plugin and make it ready f **app/Config/View.php**, under the **$plugins** array. The key is the name of the plugin that is used within the template file. The value is any valid PHP callable, including static class methods, and closures: -.. literalinclude:: view_parser/013.php +.. literalinclude:: view_parser/014.php :lines: 2- Any closures that are being used must be defined in the config file's constructor: -.. literalinclude:: view_parser/014.php +.. literalinclude:: view_parser/015.php :lines: 2- If the callable is on its own, it is treated as a single tag, not a open/close one. It will be replaced by the return value from the plugin: -.. literalinclude:: view_parser/015.php +.. literalinclude:: view_parser/016.php :lines: 2- If the callable is wrapped in an array, it is treated as an open/close tag pair that can operate on any of the content between its tags: -.. literalinclude:: view_parser/016.php +.. literalinclude:: view_parser/017.php :lines: 2- *********** @@ -508,20 +508,20 @@ Usage Notes If you include substitution parameters that are not referenced in your template, they are ignored: -.. literalinclude:: view_parser/017.php +.. literalinclude:: view_parser/018.php :lines: 2- If you do not include a substitution parameter that is referenced in your template, the original pseudo-variable is shown in the result: -.. literalinclude:: view_parser/018.php +.. literalinclude:: view_parser/019.php :lines: 2- If you provide a string substitution parameter when an array is expected, i.e., for a variable pair, the substitution is done for the opening variable pair tag, but the closing variable pair tag is not rendered properly: -.. literalinclude:: view_parser/019.php +.. literalinclude:: view_parser/020.php :lines: 2- View Fragments @@ -557,7 +557,7 @@ Result:: An example with the iteration controlled in the controller, using a view fragment: -.. literalinclude:: view_parser/020.php +.. literalinclude:: view_parser/021.php :lines: 2- Result:: @@ -583,7 +583,7 @@ Class Reference Builds the output based upon a file name and any data that has already been set: - .. literalinclude:: view_parser/021.php + .. literalinclude:: view_parser/022.php :lines: 2- Options supported: @@ -608,7 +608,7 @@ Class Reference Builds the output based upon a provided template source and any data that has already been set: - .. literalinclude:: view_parser/021-1.php + .. literalinclude:: view_parser/023.php :lines: 2- Options supported, and behavior, as above. @@ -622,7 +622,7 @@ Class Reference Sets several pieces of view data at once: - .. literalinclude:: view_parser/023.php + .. literalinclude:: view_parser/024.php :lines: 2- Supported escape contexts: html, css, js, url, or attr or raw. @@ -638,7 +638,7 @@ Class Reference Sets a single piece of view data: - .. literalinclude:: view_parser/024.php + .. literalinclude:: view_parser/025.php :lines: 2- Supported escape contexts: html, css, js, url, attr or raw. @@ -653,5 +653,5 @@ Class Reference Override the substitution field delimiters: - .. literalinclude:: view_parser/025.php + .. literalinclude:: view_parser/026.php :lines: 2- diff --git a/user_guide_src/source/outgoing/view_parser/010-2.php b/user_guide_src/source/outgoing/view_parser/010-2.php deleted file mode 100644 index 8030f44e8883..000000000000 --- a/user_guide_src/source/outgoing/view_parser/010-2.php +++ /dev/null @@ -1,3 +0,0 @@ - -

    Welcome, Admin!

    - diff --git a/user_guide_src/source/outgoing/view_parser/011.php b/user_guide_src/source/outgoing/view_parser/011.php index 39eae3da0177..8030f44e8883 100644 --- a/user_guide_src/source/outgoing/view_parser/011.php +++ b/user_guide_src/source/outgoing/view_parser/011.php @@ -1,6 +1,3 @@ - '\CodeIgniter\View\Filters::abs', - 'capitalize' => '\CodeIgniter\View\Filters::capitalize', -]; + +

    Welcome, Admin!

    + diff --git a/user_guide_src/source/outgoing/view_parser/012.php b/user_guide_src/source/outgoing/view_parser/012.php index dbb096b416fb..39eae3da0177 100644 --- a/user_guide_src/source/outgoing/view_parser/012.php +++ b/user_guide_src/source/outgoing/view_parser/012.php @@ -1,5 +1,6 @@ '\str_repeat', + 'abs' => '\CodeIgniter\View\Filters::abs', + 'capitalize' => '\CodeIgniter\View\Filters::capitalize', ]; diff --git a/user_guide_src/source/outgoing/view_parser/013.php b/user_guide_src/source/outgoing/view_parser/013.php index d959d153d415..dbb096b416fb 100644 --- a/user_guide_src/source/outgoing/view_parser/013.php +++ b/user_guide_src/source/outgoing/view_parser/013.php @@ -1,8 +1,5 @@ '\Some\Class::methodName', - 'bar' => function ($str, array $params=[]) { - return $str; - }, +public $filters = [ + 'str_repeat' => '\str_repeat', ]; diff --git a/user_guide_src/source/outgoing/view_parser/014.php b/user_guide_src/source/outgoing/view_parser/014.php index bac6137888f1..d959d153d415 100644 --- a/user_guide_src/source/outgoing/view_parser/014.php +++ b/user_guide_src/source/outgoing/view_parser/014.php @@ -1,15 +1,8 @@ plugins['bar'] = function (array $params=[]) { - return $params[0] ?? ''; - }; - - parent::__construct(); - } -} +public $plugins = [ + 'foo' => '\Some\Class::methodName', + 'bar' => function ($str, array $params=[]) { + return $str; + }, +]; diff --git a/user_guide_src/source/outgoing/view_parser/015.php b/user_guide_src/source/outgoing/view_parser/015.php index 74a18943365c..bac6137888f1 100644 --- a/user_guide_src/source/outgoing/view_parser/015.php +++ b/user_guide_src/source/outgoing/view_parser/015.php @@ -1,8 +1,15 @@ '\Some\Class::methodName' -]; +class View extends \CodeIgniter\Config\View +{ + public $plugins = []; -// Tag is replaced by the return value of Some\Class::methodName static function. -{+ foo +} + public function __construct() + { + $this->plugins['bar'] = function (array $params=[]) { + return $params[0] ?? ''; + }; + + parent::__construct(); + } +} diff --git a/user_guide_src/source/outgoing/view_parser/016.php b/user_guide_src/source/outgoing/view_parser/016.php index 30d72b247059..74a18943365c 100644 --- a/user_guide_src/source/outgoing/view_parser/016.php +++ b/user_guide_src/source/outgoing/view_parser/016.php @@ -1,7 +1,8 @@ ['\Some\Class::methodName'] + 'foo' => '\Some\Class::methodName' ]; -{+ foo +} inner content {+ /foo +} +// Tag is replaced by the return value of Some\Class::methodName static function. +{+ foo +} diff --git a/user_guide_src/source/outgoing/view_parser/017.php b/user_guide_src/source/outgoing/view_parser/017.php index cd9ca09109b9..30d72b247059 100644 --- a/user_guide_src/source/outgoing/view_parser/017.php +++ b/user_guide_src/source/outgoing/view_parser/017.php @@ -1,12 +1,7 @@ 'Mr', - 'firstname' => 'John', - 'lastname' => 'Doe' +public $plugins = [ + 'foo' => ['\Some\Class::methodName'] ]; -echo $parser->setData($data) - ->renderString($template); -// Result: Hello, John Doe +{+ foo +} inner content {+ /foo +} diff --git a/user_guide_src/source/outgoing/view_parser/018.php b/user_guide_src/source/outgoing/view_parser/018.php index dfce0c26ccb4..cd9ca09109b9 100644 --- a/user_guide_src/source/outgoing/view_parser/018.php +++ b/user_guide_src/source/outgoing/view_parser/018.php @@ -1,12 +1,12 @@ 'Mr', 'firstname' => 'John', - 'lastname' => 'Doe', + 'lastname' => 'Doe' ]; echo $parser->setData($data) ->renderString($template); -// Result: Hello, John {initials} Doe +// Result: Hello, John Doe diff --git a/user_guide_src/source/outgoing/view_parser/019.php b/user_guide_src/source/outgoing/view_parser/019.php index 371fa9a21f14..dfce0c26ccb4 100644 --- a/user_guide_src/source/outgoing/view_parser/019.php +++ b/user_guide_src/source/outgoing/view_parser/019.php @@ -1,16 +1,12 @@ 'Mr', + 'title' => 'Mr', 'firstname' => 'John', 'lastname' => 'Doe', - 'titles' => [ - ['degree' => 'BSc'], - ['degree' => 'PhD'], - ], ]; echo $parser->setData($data) ->renderString($template); -// Result: Hello, John Doe (Mr{degree} {/degrees}) +// Result: Hello, John {initials} Doe diff --git a/user_guide_src/source/outgoing/view_parser/020.php b/user_guide_src/source/outgoing/view_parser/020.php index cf7b31fa7e30..371fa9a21f14 100644 --- a/user_guide_src/source/outgoing/view_parser/020.php +++ b/user_guide_src/source/outgoing/view_parser/020.php @@ -1,19 +1,16 @@ {title}'; -$data1 = [ - ['title' => 'First Link', 'link' => '/first'], - ['title' => 'Second Link', 'link' => '/second'], -]; - -foreach ($data1 as $menuItem),{ - $temp .= $parser->setData($menuItem)->renderString($template1); -} - -$template2 = '
      {menuitems}
    '; +$template = 'Hello, {firstname} {lastname} ({degrees}{degree} {/degrees})'; $data = [ - 'menuitems' => $temp, + 'degrees' => 'Mr', + 'firstname' => 'John', + 'lastname' => 'Doe', + 'titles' => [ + ['degree' => 'BSc'], + ['degree' => 'PhD'], + ], ]; echo $parser->setData($data) - ->renderString($template2); + ->renderString($template); + +// Result: Hello, John Doe (Mr{degree} {/degrees}) diff --git a/user_guide_src/source/outgoing/view_parser/021-1.php b/user_guide_src/source/outgoing/view_parser/021-1.php deleted file mode 100644 index 022450bb6fd6..000000000000 --- a/user_guide_src/source/outgoing/view_parser/021-1.php +++ /dev/null @@ -1,3 +0,0 @@ -render('myview'); diff --git a/user_guide_src/source/outgoing/view_parser/021.php b/user_guide_src/source/outgoing/view_parser/021.php index 022450bb6fd6..cf7b31fa7e30 100644 --- a/user_guide_src/source/outgoing/view_parser/021.php +++ b/user_guide_src/source/outgoing/view_parser/021.php @@ -1,3 +1,19 @@ render('myview'); +$temp = ''; +$template1 = '
  • {title}
  • '; +$data1 = [ + ['title' => 'First Link', 'link' => '/first'], + ['title' => 'Second Link', 'link' => '/second'], +]; + +foreach ($data1 as $menuItem),{ + $temp .= $parser->setData($menuItem)->renderString($template1); +} + +$template2 = '
      {menuitems}
    '; +$data = [ + 'menuitems' => $temp, +]; +echo $parser->setData($data) + ->renderString($template2); diff --git a/user_guide_src/source/outgoing/view_parser/023.php b/user_guide_src/source/outgoing/view_parser/023.php index 42ddfa949331..022450bb6fd6 100644 --- a/user_guide_src/source/outgoing/view_parser/023.php +++ b/user_guide_src/source/outgoing/view_parser/023.php @@ -1,3 +1,3 @@ setData(['name' => 'George', 'position' => 'Boss']); +echo $parser->render('myview'); diff --git a/user_guide_src/source/outgoing/view_parser/024.php b/user_guide_src/source/outgoing/view_parser/024.php index 76ba0b537f96..42ddfa949331 100644 --- a/user_guide_src/source/outgoing/view_parser/024.php +++ b/user_guide_src/source/outgoing/view_parser/024.php @@ -1,3 +1,3 @@ setVar('name','Joe','html'); +$renderer->setData(['name' => 'George', 'position' => 'Boss']); diff --git a/user_guide_src/source/outgoing/view_parser/025.php b/user_guide_src/source/outgoing/view_parser/025.php index a8633d5717c7..76ba0b537f96 100644 --- a/user_guide_src/source/outgoing/view_parser/025.php +++ b/user_guide_src/source/outgoing/view_parser/025.php @@ -1,3 +1,3 @@ setDelimiters('[',']'); +$renderer->setVar('name','Joe','html'); diff --git a/user_guide_src/source/outgoing/view_parser/026.php b/user_guide_src/source/outgoing/view_parser/026.php new file mode 100644 index 000000000000..a8633d5717c7 --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/026.php @@ -0,0 +1,3 @@ +setDelimiters('[',']'); diff --git a/user_guide_src/source/testing/response.rst b/user_guide_src/source/testing/response.rst index ae6eb2deb97e..e39df524affc 100644 --- a/user_guide_src/source/testing/response.rst +++ b/user_guide_src/source/testing/response.rst @@ -178,7 +178,7 @@ values of the elements. Instead, they simply check that the elements exist on th You can use **seeLink()** to ensure that a link appears on the page with the specified text: -.. literalinclude:: response/021-2.php +.. literalinclude:: response/021.php :lines: 2- The **seeInField()** method checks for any input tags exist with the name and value: @@ -231,7 +231,7 @@ specific text: Asserts that an anchor tag is found with matching **$text** as the body of the tag: -.. literalinclude:: response/021.php +.. literalinclude:: response/028.php :lines: 2- **assertSeeInField(string $field, string $value=null)** diff --git a/user_guide_src/source/testing/response/021-2.php b/user_guide_src/source/testing/response/021-2.php deleted file mode 100644 index bc74e3ad9124..000000000000 --- a/user_guide_src/source/testing/response/021-2.php +++ /dev/null @@ -1,6 +0,0 @@ -seeLink('Upgrade Account'); -// Check that a link exists with 'Upgrade Account' as the text, AND a class of 'upsell' -$results->seeLink('Upgrade Account', '.upsell'); From 5b84072e32e7dc70a143accdd4f6d4f80b7c784b Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Sun, 20 Feb 2022 09:57:37 +0100 Subject: [PATCH 0525/1246] Fix merge conflicts. --- .../source/incoming/incomingrequest.rst | 282 +++++++----------- .../source/incoming/incomingrequest/006.php | 4 - .../source/incoming/incomingrequest/024.php | 18 -- .../incomingrequest/{001.php => 1.php} | 0 .../incomingrequest/{011.php => 10.php} | 0 .../incomingrequest/{012.php => 11.php} | 0 .../incomingrequest/{013.php => 12.php} | 0 .../incomingrequest/{014.php => 13.php} | 0 .../incomingrequest/{015.php => 14.php} | 0 .../incomingrequest/{016.php => 15.php} | 0 .../incomingrequest/{017.php => 16.php} | 0 .../incomingrequest/{018.php => 17.php} | 0 .../incomingrequest/{019.php => 18.php} | 0 .../incomingrequest/{020.php => 19.php} | 0 .../incomingrequest/{002.php => 2.php} | 0 .../incomingrequest/{021.php => 20.php} | 0 .../incomingrequest/{022.php => 21.php} | 0 .../incomingrequest/{023.php => 22.php} | 0 .../source/incoming/incomingrequest/23.php | 3 + .../incomingrequest/{025.php => 24.php} | 0 .../incomingrequest/{026.php => 25.php} | 0 .../incomingrequest/{027.php => 26.php} | 0 .../incomingrequest/{028.php => 27.php} | 0 .../incomingrequest/{029.php => 28.php} | 0 .../incomingrequest/{030.php => 29.php} | 0 .../incomingrequest/{003.php => 3.php} | 0 .../incomingrequest/{031.php => 30.php} | 0 .../incomingrequest/{032.php => 31.php} | 0 .../incomingrequest/{033.php => 32.php} | 0 .../incomingrequest/{034.php => 33.php} | 0 .../incomingrequest/{035.php => 34.php} | 0 .../incomingrequest/{036.php => 35.php} | 0 .../incomingrequest/{037.php => 36.php} | 0 .../incomingrequest/{038.php => 37.php} | 0 .../incomingrequest/{039.php => 38.php} | 0 .../incomingrequest/{004.php => 4.php} | 0 .../incomingrequest/{005.php => 5.php} | 0 .../incomingrequest/{007.php => 6.php} | 0 .../incomingrequest/{008.php => 7.php} | 0 .../incomingrequest/{009.php => 8.php} | 0 .../incomingrequest/{010.php => 9.php} | 0 41 files changed, 111 insertions(+), 196 deletions(-) delete mode 100644 user_guide_src/source/incoming/incomingrequest/006.php delete mode 100644 user_guide_src/source/incoming/incomingrequest/024.php rename user_guide_src/source/incoming/incomingrequest/{001.php => 1.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{011.php => 10.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{012.php => 11.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{013.php => 12.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{014.php => 13.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{015.php => 14.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{016.php => 15.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{017.php => 16.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{018.php => 17.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{019.php => 18.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{020.php => 19.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{002.php => 2.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{021.php => 20.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{022.php => 21.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{023.php => 22.php} (100%) create mode 100644 user_guide_src/source/incoming/incomingrequest/23.php rename user_guide_src/source/incoming/incomingrequest/{025.php => 24.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{026.php => 25.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{027.php => 26.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{028.php => 27.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{029.php => 28.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{030.php => 29.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{003.php => 3.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{031.php => 30.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{032.php => 31.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{033.php => 32.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{034.php => 33.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{035.php => 34.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{036.php => 35.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{037.php => 36.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{038.php => 37.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{039.php => 38.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{004.php => 4.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{005.php => 5.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{007.php => 6.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{008.php => 7.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{009.php => 8.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{010.php => 9.php} (100%) diff --git a/user_guide_src/source/incoming/incomingrequest.rst b/user_guide_src/source/incoming/incomingrequest.rst index 5e77e9253804..70692d1aa4c4 100644 --- a/user_guide_src/source/incoming/incomingrequest.rst +++ b/user_guide_src/source/incoming/incomingrequest.rst @@ -13,72 +13,38 @@ Accessing the Request --------------------- An instance of the request class already populated for you if the current class is a descendant of -``CodeIgniter\Controller`` and can be accessed as a class property:: +``CodeIgniter\Controller`` and can be accessed as a class property: - request->isAJAX()) { - // ... - } - } - } +.. literalinclude:: incomingrequest/1.php If you are not within a controller, but still need access to the application's Request object, you can -get a copy of it through the :doc:`Services class `:: +get a copy of it through the :doc:`Services class `: - $request = \Config\Services::request(); +.. literalinclude:: incomingrequest/2.php + :lines: 2- It's preferable, though, to pass the request in as a dependency if the class is anything other than -the controller, where you can save it as a class property:: - - request = $request; - } - } +the controller, where you can save it as a class property: - $someClass = new SomeClass(\Config\Services::request()); +.. literalinclude:: incomingrequest/3.php Determining Request Type ------------------------ A request could be of several types, including an AJAX request or a request from the command line. This can -be checked with the ``isAJAX()`` and ``isCLI()`` methods:: +be checked with the ``isAJAX()`` and ``isCLI()`` methods: - // Check for AJAX request. - if ($request->isAJAX()) { - // ... - } - - // Check for CLI Request - if ($request->isCLI()) { - // ... - } +.. literalinclude:: incomingrequest/4.php + :lines: 2- .. note:: The ``isAJAX()`` method depends on the ``X-Requested-With`` header, which in some cases is not sent by default in XHR requests via JavaScript (i.e., fetch). See the :doc:`AJAX Requests ` section on how to avoid this problem. -You can check the HTTP method that this request represents with the ``method()`` method:: +You can check the HTTP method that this request represents with the ``method()`` method: - // Returns 'post' - $method = $request->getMethod(); +.. literalinclude:: incomingrequest/5.php + :lines: 2- By default, the method is returned as a lower-case string (i.e., 'get', 'post', etc). You can get an uppercase version by wrapping the call in ``str_to_upper()``:: @@ -86,11 +52,10 @@ uppercase version by wrapping the call in ``str_to_upper()``:: // Returns 'GET' $method = str_to_upper($request->getMethod()); -You can also check if the request was made through and HTTPS connection with the ``isSecure()`` method:: +You can also check if the request was made through and HTTPS connection with the ``isSecure()`` method: - if (! $request->isSecure()) { - force_https(); - } +.. literalinclude:: incomingrequest/6.php + :lines: 2- Retrieving Input ---------------- @@ -100,13 +65,15 @@ The data is not automatically filtered and returns the raw input data as passed advantages to using these methods instead of accessing them directly ($_POST['something']), is that they will return null if the item doesn't exist, and you can have the data filtered. This lets you conveniently use data without having to test whether an item exists first. In other words, normally you might do something -like this:: +like this: - $something = isset($_POST['foo']) ? $_POST['foo'] : null; +.. literalinclude:: incomingrequest/7.php + :lines: 2- -With CodeIgniter’s built in methods you can simply do this:: +With CodeIgniter’s built in methods you can simply do this: - $something = $request->getVar('foo'); +.. literalinclude:: incomingrequest/8.php + :lines: 2- The ``getVar()`` method will pull from $_REQUEST, so will return any data from $_GET, $POST, or $_COOKIE. While this is convenient, you will often need to use a more specific method, like: @@ -129,9 +96,9 @@ You can grab the contents of php://input as a JSON stream with ``getJSON()``. .. note:: This has no way of checking if the incoming data is valid JSON or not, you should only use this method if you know that you're expecting JSON. -:: - $json = $request->getJSON(); +.. literalinclude:: incomingrequest/9.php + :lines: 2- By default, this will return any objects in the JSON data as objects. If you want that converted to associative arrays, pass in ``true`` as the first parameter. @@ -147,51 +114,32 @@ the JSON stream. Using ``getVar()`` in this way will always return an object. You can get a specific piece of data from a JSON stream by passing a variable name into ``getVar()`` for the data that you want or you can use "dot" notation to dig into the JSON to get data that is not on the root level. -:: - - // With a request body of: - { - "foo": "bar", - "fizz": { - "buzz": "baz" - } - } - $data = $request->getVar('foo'); - // $data = "bar" - $data = $request->getVar('fizz.buzz'); - // $data = "baz" +.. literalinclude:: incomingrequest/10.php + :lines: 2- If you want the result to be an associative array instead of an object, you can use ``getJsonVar()`` instead and pass true in the second parameter. This function can also be used if you can't guarantee that the incoming request will have the correct ``CONTENT_TYPE`` header. -:: - // With the same request as above - $data = $request->getJsonVar('fizz'); - // $data->buzz = "baz" - - $data = $request->getJsonVar('fizz', true); - // $data = ["buzz" => "baz"] +.. literalinclude:: incomingrequest/11.php + :lines: 2- .. note:: See the documentation for ``dot_array_search()`` in the ``Array`` helper for more information on "dot" notation. **Retrieving Raw data (PUT, PATCH, DELETE)** -Finally, you can grab the contents of php://input as a raw stream with ``getRawInput()``:: - - $data = $request->getRawInput(); +Finally, you can grab the contents of php://input as a raw stream with ``getRawInput()``: -This will retrieve data and convert it to an array. Like this:: +.. literalinclude:: incomingrequest/12.php + :lines: 2- - var_dump($request->getRawInput()); +This will retrieve data and convert it to an array. Like this: - [ - 'Param1' => 'Value1', - 'Param2' => 'Value2' - ] +.. literalinclude:: incomingrequest/13.php + :lines: 2- **Filtering Input Data** @@ -200,9 +148,10 @@ pass the type of filter to use as the second parameter of any of these methods. function is used for the filtering. Head over to the PHP manual for a list of `valid filter types `_. -Filtering a POST variable would look like this:: +Filtering a POST variable would look like this: - $email = $request->getVar('email', FILTER_SANITIZE_EMAIL); +.. literalinclude:: incomingrequest/14.php + :lines: 2- All of the methods mentioned above support the filter type passed in as the second parameter, with the exception of ``getJSON()``. @@ -212,75 +161,52 @@ Retrieving Headers You can get access to any header that was sent with the request with the ``headers()`` method, which returns an array of all headers, with the key as the name of the header, and the value is an instance of -``CodeIgniter\HTTP\Header``:: +``CodeIgniter\HTTP\Header``: - var_dump($request->headers()); - - [ - 'Host' => CodeIgniter\HTTP\Header, - 'Cache-Control' => CodeIgniter\HTTP\Header, - 'Accept' => CodeIgniter\HTTP\Header, - ] +.. literalinclude:: incomingrequest/15.php + :lines: 2- If you only need a single header, you can pass the name into the ``header()`` method. This will grab the -specified header object in a case-insensitive manner if it exists. If not, then it will return ``null``:: +specified header object in a case-insensitive manner if it exists. If not, then it will return ``null``: - // these are all equivalent - $host = $request->header('host'); - $host = $request->header('Host'); - $host = $request->header('HOST'); +.. literalinclude:: incomingrequest/16.php + :lines: 2- -You can always use ``hasHeader()`` to see if the header existed in this request:: +You can always use ``hasHeader()`` to see if the header existed in this request: - if ($request->hasHeader('DNT')) { - // Don't track something... - } +.. literalinclude:: incomingrequest/17.php + :lines: 2- -If you need the value of header as a string with all values on one line, you can use the ``getHeaderLine()`` method:: +If you need the value of header as a string with all values on one line, you can use the ``getHeaderLine()`` method: - // Accept-Encoding: gzip, deflate, sdch - echo 'Accept-Encoding: '.$request->getHeaderLine('accept-encoding'); +.. literalinclude:: incomingrequest/18.php + :lines: 2- -If you need the entire header, with the name and values in a single string, simply cast the header as a string:: +If you need the entire header, with the name and values in a single string, simply cast the header as a string: - echo (string)$header; +.. literalinclude:: incomingrequest/19.php + :lines: 2- The Request URL --------------- You can retrieve a :doc:`URI ` object that represents the current URI for this request through the -``$request->getUri()`` method. You can cast this object as a string to get a full URL for the current request:: - - $uri = (string) $request->getUri(); +``$request->getUri()`` method. You can cast this object as a string to get a full URL for the current request: -The object gives you full abilities to grab any part of the request on it's own:: +.. literalinclude:: incomingrequest/20.php + :lines: 2- - $uri = $request->getUri(); +The object gives you full abilities to grab any part of the request on it's own: - echo $uri->getScheme(); // http - echo $uri->getAuthority(); // snoopy:password@example.com:88 - echo $uri->getUserInfo(); // snoopy:password - echo $uri->getHost(); // example.com - echo $uri->getPort(); // 88 - echo $uri->getPath(); // /path/to/page - echo $uri->getQuery(); // foo=bar&bar=baz - echo $uri->getSegments(); // ['path', 'to', 'page'] - echo $uri->getSegment(1); // 'path' - echo $uri->getTotalSegments(); // 3 +.. literalinclude:: incomingrequest/21.php + :lines: 2- You can work with the current URI string (the path relative to your baseURL) using the ``getPath()`` and ``setPath()`` methods. Note that this relative path on the shared instance of ``IncomingRequest`` is what the :doc:`URL Helper ` -functions use, so this is a helpful way to "spoof" an incoming request for testing:: - - class MyMenuTest extends CIUnitTestCase - { - public function testActiveLinkUsesCurrentUrl() - { - service('request')->setPath('users/list'); - $menu = new MyMenu(); - $this->assertTrue('users/list', $menu->getActiveLink()); - } - } +functions use, so this is a helpful way to "spoof" an incoming request for testing: + +.. literalinclude:: incomingrequest/22.php + :lines: 2- Uploaded Files -------------- @@ -288,33 +214,32 @@ Uploaded Files Information about all uploaded files can be retrieved through ``$request->getFiles()``, which returns an array of ``CodeIgniter\HTTP\Files\UploadedFile`` instance. This helps to ease the pain of working with uploaded files, and uses best practices to minimize any security risks. -:: - $files = $request->getFiles(); +.. literalinclude:: incomingrequest/23.php + :lines: 2- See :ref:`Working with Uploaded Files ` for the details. -You can retrieve a single file uploaded on its own, based on the filename given in the HTML file input:: +You can retrieve a single file uploaded on its own, based on the filename given in the HTML file input: - $file = $request->getFile('userfile'); +.. literalinclude:: incomingrequest/24.php + :lines: 2- You can retrieve an array of same-named files uploaded as part of a -multi-file upload, based on the filename given in the HTML file input:: +multi-file upload, based on the filename given in the HTML file input: - $files = $request->getFileMultiple('userfile'); +.. literalinclude:: incomingrequest/25.php + :lines: 2- .. note:: The files here correspond to ``$_FILES``. Even if a user just clicks submit button of a form and does not upload any file, the file will still exist. You can check that the file was actually uploaded by the ``isValid()`` method in UploadedFile. See :ref:`verify-a-file` for more details. Content Negotiation ------------------- -You can easily negotiate content types with the request through the ``negotiate()`` method:: +You can easily negotiate content types with the request through the ``negotiate()`` method: - $language = $request->negotiate('language', ['en-US', 'en-GB', 'fr', 'es-mx']); - $imageType = $request->negotiate('media', ['image/png', 'image/jpg']); - $charset = $request->negotiate('charset', ['UTF-8', 'UTF-16']); - $contentType = $request->negotiate('media', ['text/html', 'text/xml']); - $encoding = $request->negotiate('encoding', ['gzip', 'compress']); +.. literalinclude:: incomingrequest/26.php + :lines: 2- See the :doc:`Content Negotiation ` page for more details. @@ -376,35 +301,39 @@ The methods provided by the parent classes that are available are: :returns: $_REQUEST if no parameters supplied, otherwise the REQUEST value if found, or null if not :rtype: mixed|null - The first parameter will contain the name of the REQUEST item you are looking for:: + The first parameter will contain the name of the REQUEST item you are looking for: - $request->getVar('some_data'); + .. literalinclude:: incomingrequest/27.php + :lines: 2- The method returns null if the item you are attempting to retrieve does not exist. The second optional parameter lets you run the data through the PHP's - filters. Pass in the desired filter type as the second parameter:: + filters. Pass in the desired filter type as the second parameter: - $request->getVar('some_data', FILTER_SANITIZE_FULL_SPECIAL_CHARS); + .. literalinclude:: incomingrequest/28.php + :lines: 2- To return an array of all POST items call without any parameters. To return all POST items and pass them through the filter, set the first parameter to null while setting the second parameter to the filter - you want to use:: + you want to use: - $request->getVar(null, FILTER_SANITIZE_FULL_SPECIAL_CHARS); - // returns all POST items with string sanitation + .. literalinclude:: incomingrequest/29.php + :lines: 2- - To return an array of multiple POST parameters, pass all the required keys as an array:: + To return an array of multiple POST parameters, pass all the required keys as an array: - $request->getVar(['field1', 'field2']); + .. literalinclude:: incomingrequest/30.php + :lines: 2- Same rule applied here, to retrieve the parameters with filtering, set the second parameter to - the filter type to apply:: + the filter type to apply: - $request->getVar(['field1', 'field2'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); + .. literalinclude:: incomingrequest/31.php + :lines: 2- .. php:method:: getGet([$index = null[, $filter = null[, $flags = null]]]) @@ -442,9 +371,10 @@ The methods provided by the parent classes that are available are: This method works pretty much the same way as ``getPost()`` and ``getGet()``, only combined. It will search through both POST and GET streams for data, looking first in POST, and - then in GET:: + then in GET: - $request->getPostGet('field1'); + .. literalinclude:: incomingrequest/32.php + :lines: 2- .. php:method:: getGetPost([$index = null[, $filter = null[, $flags = null]]]) @@ -458,9 +388,10 @@ The methods provided by the parent classes that are available are: This method works pretty much the same way as ``getPost()`` and ``getGet()``, only combined. It will search through both POST and GET streams for data, looking first in GET, and - then in POST:: + then in POST: - $request->getGetPost('field1'); + .. literalinclude:: incomingrequest/33.php + :lines: 2- .. php:method:: getCookie([$index = null[, $filter = null[, $flags = null]]]) :noindex: @@ -473,14 +404,15 @@ The methods provided by the parent classes that are available are: :returns: $_COOKIE if no parameters supplied, otherwise the COOKIE value if found or null if not :rtype: mixed - This method is identical to ``getPost()`` and ``getGet()``, only it fetches cookie data:: + This method is identical to ``getPost()`` and ``getGet()``, only it fetches cookie data: - $request->getCookie('some_cookie'); - $request->getCookie('some_cookie', FILTER_SANITIZE_FULL_SPECIAL_CHARS); // with filter + .. literalinclude:: incomingrequest/34.php + :lines: 2- - To return an array of multiple cookie values, pass all the required keys as an array:: + To return an array of multiple cookie values, pass all the required keys as an array: - $request->getCookie(['some_cookie', 'some_cookie2']); + .. literalinclude:: incomingrequest/35.php + :lines: 2- .. note:: Unlike the :doc:`Cookie Helper <../helpers/cookie_helper>` function :php:func:`get_cookie()`, this method does NOT prepend @@ -498,15 +430,16 @@ The methods provided by the parent classes that are available are: :rtype: mixed This method is identical to the ``getPost()``, ``getGet()`` and ``getCookie()`` - methods, only it fetches getServer data (``$_SERVER``):: + methods, only it fetches getServer data (``$_SERVER``): - $request->getServer('some_data'); + .. literalinclude:: incomingrequest/36.php + :lines: 2- To return an array of multiple ``$_SERVER`` values, pass all the required keys as an array. - :: - $request->getServer(['SERVER_PROTOCOL', 'REQUEST_URI']); + .. literalinclude:: incomingrequest/37.php + :lines: 2- .. php:method:: getUserAgent([$filter = null]) @@ -515,9 +448,10 @@ The methods provided by the parent classes that are available are: :returns: The User Agent string, as found in the SERVER data, or null if not found. :rtype: mixed - This method returns the User Agent string from the SERVER data:: + This method returns the User Agent string from the SERVER data: - $request->getUserAgent(); + .. literalinclude:: incomingrequest/38.php + :lines: 2- .. php:method:: getPath() diff --git a/user_guide_src/source/incoming/incomingrequest/006.php b/user_guide_src/source/incoming/incomingrequest/006.php deleted file mode 100644 index 99e269157152..000000000000 --- a/user_guide_src/source/incoming/incomingrequest/006.php +++ /dev/null @@ -1,4 +0,0 @@ -getMethod()); diff --git a/user_guide_src/source/incoming/incomingrequest/024.php b/user_guide_src/source/incoming/incomingrequest/024.php deleted file mode 100644 index e29f87b9f419..000000000000 --- a/user_guide_src/source/incoming/incomingrequest/024.php +++ /dev/null @@ -1,18 +0,0 @@ -getFiles(); - -// Grab the file by name given in HTML form -if ($files->hasFile('userfile')) { - $file = $files->getFile('userfile'); - - // Generate a new secure name - $name = $file->getRandomName(); - - // Move the file to it's new home - $file->move('/path/to/dir', $name); - - echo $file->getSize('mb'); // 1.23 - echo $file->getExtension(); // jpg - echo $file->getType(); // image/jpg -} diff --git a/user_guide_src/source/incoming/incomingrequest/001.php b/user_guide_src/source/incoming/incomingrequest/1.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/001.php rename to user_guide_src/source/incoming/incomingrequest/1.php diff --git a/user_guide_src/source/incoming/incomingrequest/011.php b/user_guide_src/source/incoming/incomingrequest/10.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/011.php rename to user_guide_src/source/incoming/incomingrequest/10.php diff --git a/user_guide_src/source/incoming/incomingrequest/012.php b/user_guide_src/source/incoming/incomingrequest/11.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/012.php rename to user_guide_src/source/incoming/incomingrequest/11.php diff --git a/user_guide_src/source/incoming/incomingrequest/013.php b/user_guide_src/source/incoming/incomingrequest/12.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/013.php rename to user_guide_src/source/incoming/incomingrequest/12.php diff --git a/user_guide_src/source/incoming/incomingrequest/014.php b/user_guide_src/source/incoming/incomingrequest/13.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/014.php rename to user_guide_src/source/incoming/incomingrequest/13.php diff --git a/user_guide_src/source/incoming/incomingrequest/015.php b/user_guide_src/source/incoming/incomingrequest/14.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/015.php rename to user_guide_src/source/incoming/incomingrequest/14.php diff --git a/user_guide_src/source/incoming/incomingrequest/016.php b/user_guide_src/source/incoming/incomingrequest/15.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/016.php rename to user_guide_src/source/incoming/incomingrequest/15.php diff --git a/user_guide_src/source/incoming/incomingrequest/017.php b/user_guide_src/source/incoming/incomingrequest/16.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/017.php rename to user_guide_src/source/incoming/incomingrequest/16.php diff --git a/user_guide_src/source/incoming/incomingrequest/018.php b/user_guide_src/source/incoming/incomingrequest/17.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/018.php rename to user_guide_src/source/incoming/incomingrequest/17.php diff --git a/user_guide_src/source/incoming/incomingrequest/019.php b/user_guide_src/source/incoming/incomingrequest/18.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/019.php rename to user_guide_src/source/incoming/incomingrequest/18.php diff --git a/user_guide_src/source/incoming/incomingrequest/020.php b/user_guide_src/source/incoming/incomingrequest/19.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/020.php rename to user_guide_src/source/incoming/incomingrequest/19.php diff --git a/user_guide_src/source/incoming/incomingrequest/002.php b/user_guide_src/source/incoming/incomingrequest/2.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/002.php rename to user_guide_src/source/incoming/incomingrequest/2.php diff --git a/user_guide_src/source/incoming/incomingrequest/021.php b/user_guide_src/source/incoming/incomingrequest/20.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/021.php rename to user_guide_src/source/incoming/incomingrequest/20.php diff --git a/user_guide_src/source/incoming/incomingrequest/022.php b/user_guide_src/source/incoming/incomingrequest/21.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/022.php rename to user_guide_src/source/incoming/incomingrequest/21.php diff --git a/user_guide_src/source/incoming/incomingrequest/023.php b/user_guide_src/source/incoming/incomingrequest/22.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/023.php rename to user_guide_src/source/incoming/incomingrequest/22.php diff --git a/user_guide_src/source/incoming/incomingrequest/23.php b/user_guide_src/source/incoming/incomingrequest/23.php new file mode 100644 index 000000000000..de3c1601647d --- /dev/null +++ b/user_guide_src/source/incoming/incomingrequest/23.php @@ -0,0 +1,3 @@ +getFiles(); diff --git a/user_guide_src/source/incoming/incomingrequest/025.php b/user_guide_src/source/incoming/incomingrequest/24.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/025.php rename to user_guide_src/source/incoming/incomingrequest/24.php diff --git a/user_guide_src/source/incoming/incomingrequest/026.php b/user_guide_src/source/incoming/incomingrequest/25.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/026.php rename to user_guide_src/source/incoming/incomingrequest/25.php diff --git a/user_guide_src/source/incoming/incomingrequest/027.php b/user_guide_src/source/incoming/incomingrequest/26.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/027.php rename to user_guide_src/source/incoming/incomingrequest/26.php diff --git a/user_guide_src/source/incoming/incomingrequest/028.php b/user_guide_src/source/incoming/incomingrequest/27.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/028.php rename to user_guide_src/source/incoming/incomingrequest/27.php diff --git a/user_guide_src/source/incoming/incomingrequest/029.php b/user_guide_src/source/incoming/incomingrequest/28.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/029.php rename to user_guide_src/source/incoming/incomingrequest/28.php diff --git a/user_guide_src/source/incoming/incomingrequest/030.php b/user_guide_src/source/incoming/incomingrequest/29.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/030.php rename to user_guide_src/source/incoming/incomingrequest/29.php diff --git a/user_guide_src/source/incoming/incomingrequest/003.php b/user_guide_src/source/incoming/incomingrequest/3.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/003.php rename to user_guide_src/source/incoming/incomingrequest/3.php diff --git a/user_guide_src/source/incoming/incomingrequest/031.php b/user_guide_src/source/incoming/incomingrequest/30.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/031.php rename to user_guide_src/source/incoming/incomingrequest/30.php diff --git a/user_guide_src/source/incoming/incomingrequest/032.php b/user_guide_src/source/incoming/incomingrequest/31.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/032.php rename to user_guide_src/source/incoming/incomingrequest/31.php diff --git a/user_guide_src/source/incoming/incomingrequest/033.php b/user_guide_src/source/incoming/incomingrequest/32.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/033.php rename to user_guide_src/source/incoming/incomingrequest/32.php diff --git a/user_guide_src/source/incoming/incomingrequest/034.php b/user_guide_src/source/incoming/incomingrequest/33.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/034.php rename to user_guide_src/source/incoming/incomingrequest/33.php diff --git a/user_guide_src/source/incoming/incomingrequest/035.php b/user_guide_src/source/incoming/incomingrequest/34.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/035.php rename to user_guide_src/source/incoming/incomingrequest/34.php diff --git a/user_guide_src/source/incoming/incomingrequest/036.php b/user_guide_src/source/incoming/incomingrequest/35.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/036.php rename to user_guide_src/source/incoming/incomingrequest/35.php diff --git a/user_guide_src/source/incoming/incomingrequest/037.php b/user_guide_src/source/incoming/incomingrequest/36.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/037.php rename to user_guide_src/source/incoming/incomingrequest/36.php diff --git a/user_guide_src/source/incoming/incomingrequest/038.php b/user_guide_src/source/incoming/incomingrequest/37.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/038.php rename to user_guide_src/source/incoming/incomingrequest/37.php diff --git a/user_guide_src/source/incoming/incomingrequest/039.php b/user_guide_src/source/incoming/incomingrequest/38.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/039.php rename to user_guide_src/source/incoming/incomingrequest/38.php diff --git a/user_guide_src/source/incoming/incomingrequest/004.php b/user_guide_src/source/incoming/incomingrequest/4.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/004.php rename to user_guide_src/source/incoming/incomingrequest/4.php diff --git a/user_guide_src/source/incoming/incomingrequest/005.php b/user_guide_src/source/incoming/incomingrequest/5.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/005.php rename to user_guide_src/source/incoming/incomingrequest/5.php diff --git a/user_guide_src/source/incoming/incomingrequest/007.php b/user_guide_src/source/incoming/incomingrequest/6.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/007.php rename to user_guide_src/source/incoming/incomingrequest/6.php diff --git a/user_guide_src/source/incoming/incomingrequest/008.php b/user_guide_src/source/incoming/incomingrequest/7.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/008.php rename to user_guide_src/source/incoming/incomingrequest/7.php diff --git a/user_guide_src/source/incoming/incomingrequest/009.php b/user_guide_src/source/incoming/incomingrequest/8.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/009.php rename to user_guide_src/source/incoming/incomingrequest/8.php diff --git a/user_guide_src/source/incoming/incomingrequest/010.php b/user_guide_src/source/incoming/incomingrequest/9.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/010.php rename to user_guide_src/source/incoming/incomingrequest/9.php From b135145df6ddb40ecae45926be50cbac9373f1ce Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Sun, 20 Feb 2022 09:04:22 +0100 Subject: [PATCH 0526/1246] Add script for automatic renumeration of examples. --- .php-cs-fixer.dist.php | 1 + user_guide_src/renumerate.php | 98 +++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 user_guide_src/renumerate.php diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 3c9e05fe3b74..ec0ceaeb0172 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -32,6 +32,7 @@ __DIR__ . '/.no-header.php-cs-fixer.dist.php', __DIR__ . '/rector.php', __DIR__ . '/spark', + __DIR__ . '/user_guide_src/renumerate.php', ]); $overrides = []; diff --git a/user_guide_src/renumerate.php b/user_guide_src/renumerate.php new file mode 100644 index 000000000000..ca885551d168 --- /dev/null +++ b/user_guide_src/renumerate.php @@ -0,0 +1,98 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +$srcFolder = __DIR__ . '/source'; + +// Exclude static folders +$excludes = ['_static', 'images']; + +// Safety prefix +$prefix = 'old_'; + +// Begin user info +echo 'The following sections were renumerated:', PHP_EOL; + +// Loop source directory +$srcIterator = new DirectoryIterator($srcFolder); + +foreach ($srcIterator as $chapterInfo) { + if (! $chapterInfo->isDot() && $chapterInfo->isDir() && ! in_array($chapterInfo->getFilename(), $excludes, true)) { + $chapterName = $chapterInfo->getFilename(); + + // Iterate the working directory + $chapterIterator = new DirectoryIterator($chapterInfo->getPathname()); + + foreach ($chapterIterator as $sectionInfo) { + if (! $sectionInfo->isDot() && $sectionInfo->isFile() && $sectionInfo->getExtension() === 'rst') { + $sectionName = $sectionInfo->getBasename('.rst'); + $sectionFolder = $sectionInfo->getPath() . '/' . $sectionName; + + // Read the section file + $sectionContent = file_get_contents($sectionInfo->getPathname()); + + // Match all includes + preg_match_all("~\\.\\. literalinclude:: {$sectionName}\\/(.+)\\.php(\n[ ]*:lines: 2\\-)?~", $sectionContent, $matches); + $includeStrings = $matches[0]; + $exampleNames = $matches[1]; + + // Exit early if no matches + if (count($exampleNames) === 0) { + continue; + } + + // Check if examples are consecutive + $consecutive = true; + + foreach ($exampleNames as $exampleIndex => $exampleName) { + if (str_pad($exampleIndex + 1, 3, '0', STR_PAD_LEFT) !== $exampleName) { + $consecutive = false; + break; + } + } + + // Exit if examples are already consecutive + if ($consecutive) { + continue; + } + + // Rename all example files to avoid conflicts + $exampleIterator = new DirectoryIterator($sectionFolder); + + foreach ($exampleIterator as $exampleInfo) { + if (! $exampleInfo->isDot() && $exampleInfo->isFile() && $exampleInfo->getExtension() === 'php') { + rename($exampleInfo->getPathname(), $exampleInfo->getPath() . '/' . $prefix . $exampleInfo->getFilename()); + } + } + $sectionContent = preg_replace("~\\.\\. literalinclude:: {$sectionName}\\/(.+)\\.php~", ".. literalinclude:: {$sectionName}/{$prefix}$1.php", $sectionContent); + + // Renumerate examples + foreach ($exampleNames as $exampleIndex => $exampleName) { + $newName = str_pad($exampleIndex + 1, 3, '0', STR_PAD_LEFT); + + // Rename example file + rename($sectionFolder . '/' . $prefix . $exampleName . '.php', $sectionFolder . '/' . $newName . '.php'); + + // Fix include link + $sectionContent = preg_replace(preg_quote(str_replace($exampleName, $prefix . $exampleName, $includeStrings[$exampleIndex]), '~'), str_replace($exampleName, $newName, $includeStrings[$exampleIndex]), $sectionContent, 1, $count); + } + + // Write new content to rst + file_put_contents($sectionInfo->getPathname(), $sectionContent); + + // User info + echo $chapterName, '/', $sectionName, PHP_EOL; + } + } + } +} + +// End user info +echo 'Renumerating finished.', PHP_EOL; From dfce69826845d1b0eba58461004051de61d61c47 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 21 Feb 2022 10:22:16 +0900 Subject: [PATCH 0527/1246] docs: add comment about RecursiveIteratorIterator::hasChildren() --- system/HTTP/Files/FileCollection.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/system/HTTP/Files/FileCollection.php b/system/HTTP/Files/FileCollection.php index 10e58c2eb824..bff2e5d609b4 100644 --- a/system/HTTP/Files/FileCollection.php +++ b/system/HTTP/Files/FileCollection.php @@ -220,6 +220,10 @@ protected function fixFilesArray(array $data): array $pointer = &$stack[count($stack) - 1]; $pointer = &$pointer[$key]; $stack[] = &$pointer; + + // RecursiveIteratorIterator::hasChildren() can be used. RecursiveIteratorIterator + // forwards all unknown method calls to the underlying RecursiveIterator internally. + // See https://github.com/php/doc-en/issues/787#issuecomment-881446121 if (! $iterator->hasChildren()) { $pointer[$field] = $val; } From 2c525a49f983c87151817e1e922e9e8bbfb41d87 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 21 Feb 2022 10:22:58 +0900 Subject: [PATCH 0528/1246] docs: fix typo --- system/HTTP/Files/FileCollection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/HTTP/Files/FileCollection.php b/system/HTTP/Files/FileCollection.php index bff2e5d609b4..87f31ee511ea 100644 --- a/system/HTTP/Files/FileCollection.php +++ b/system/HTTP/Files/FileCollection.php @@ -235,7 +235,7 @@ protected function fixFilesArray(array $data): array } /** - * Navigate through a array looking for a particular index + * Navigate through an array looking for a particular index * * @param array $index The index sequence we are navigating down * @param array $value The portion of the array to process From bb7dc422dbffbcdae6f6023a2d50e98d6f1e8962 Mon Sep 17 00:00:00 2001 From: Nudasoft <30935025+Nudasoft@users.noreply.github.com> Date: Mon, 21 Feb 2022 11:28:40 +0530 Subject: [PATCH 0529/1246] Fix alignment issues on few buttons in debug toobar and few cosmetic tweaks. --- system/Debug/Toolbar/Views/toolbar.css | 32 ++++++++------------------ 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/system/Debug/Toolbar/Views/toolbar.css b/system/Debug/Toolbar/Views/toolbar.css index ed4230be0988..47e74d9a4f1b 100644 --- a/system/Debug/Toolbar/Views/toolbar.css +++ b/system/Debug/Toolbar/Views/toolbar.css @@ -39,16 +39,9 @@ font-size: 16px; font-weight: 400; } #debug-bar h1 { - bottom: 0; - display: inline-block; - font-size: 14px; + display: flex; font-weight: normal; - margin: 0 16px 0 0; - padding: 0; - position: absolute; - right: 30px; - text-align: left; - top: 0; } + margin: 0 0 0 auto; } #debug-bar h1 svg { width: 16px; margin-right: 5px; } @@ -135,15 +128,8 @@ #debug-bar #toolbar-theme a:hover { text-decoration: none; } #debug-bar #debug-bar-link { - bottom: 0; - display: inline-block; - font-size: 16px; - line-height: 36px; padding: 6px; - position: absolute; - right: 10px; - top: 0; - width: 24px; } + display: flex; } #debug-bar .ci-label { display: inline-flex; font-size: 14px; } @@ -329,7 +315,7 @@ #debug-bar .ci-label:hover { background-color: #DFDFDF; } #debug-bar .ci-label .badge { - background-color: #5BC0DE; + background-color: #DD7359; color: #FFFFFF; } #debug-bar .tab { background-color: #FFFFFF; @@ -420,8 +406,8 @@ #debug-bar .ci-label:hover { background-color: #252525; } #debug-bar .ci-label .badge { - background-color: #5BC0DE; - color: #DFDFDF; } + background-color: #DD7359; + color: #FFFFFF; } #debug-bar .tab { background-color: #252525; box-shadow: 0 -1px 4px #434343; @@ -509,8 +495,8 @@ #toolbarContainer.dark #debug-bar .ci-label:hover { background-color: #252525; } #toolbarContainer.dark #debug-bar .ci-label .badge { - background-color: #5BC0DE; - color: #DFDFDF; } + background-color: #DD7359; + color: #FFFFFF; } #toolbarContainer.dark #debug-bar .tab { background-color: #252525; box-shadow: 0 -1px 4px #434343; @@ -602,7 +588,7 @@ #toolbarContainer.light #debug-bar .ci-label:hover { background-color: #DFDFDF; } #toolbarContainer.light #debug-bar .ci-label .badge { - background-color: #5BC0DE; + background-color: #DD7359; color: #FFFFFF; } #toolbarContainer.light #debug-bar .tab { background-color: #FFFFFF; From 2c52bd674693281a70950d04e8cac7b02c1a5ab6 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 22 Feb 2022 08:49:29 +0900 Subject: [PATCH 0530/1246] docs: fix typo --- user_guide_src/source/changelogs/v4.2.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/changelogs/v4.2.0.rst b/user_guide_src/source/changelogs/v4.2.0.rst index cc1561a98949..941875c03b8f 100644 --- a/user_guide_src/source/changelogs/v4.2.0.rst +++ b/user_guide_src/source/changelogs/v4.2.0.rst @@ -28,7 +28,7 @@ Enhancements - Added Validation Strict Rules. See :ref:`validation-traditional-and-strict-rules`. - Added new OCI8 driver for database. - It can access Oracle Database and supports SQL and PL/SQL statements. -- The ``spark routes`` command now shows closure routes, auto routtes, and filters. See :ref:`URI Routing `. +- The ``spark routes`` command now shows closure routes, auto routes, and filters. See :ref:`URI Routing `. - Exception information logged through ``log_message()`` has now improved. It now includes the file and line where the exception originated. It also does not truncate the message anymore. - The log format has also changed. If users are depending on the log format in their apps, the new log format is "<1-based count> (): " From 60abb80ba558105196e9b05274e77d55414471fe Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 22 Feb 2022 08:54:34 +0900 Subject: [PATCH 0531/1246] docs: add SPARKED in Deprecations --- user_guide_src/source/changelogs/v4.2.0.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/user_guide_src/source/changelogs/v4.2.0.rst b/user_guide_src/source/changelogs/v4.2.0.rst index 941875c03b8f..daad84d662fb 100644 --- a/user_guide_src/source/changelogs/v4.2.0.rst +++ b/user_guide_src/source/changelogs/v4.2.0.rst @@ -48,6 +48,7 @@ Deprecations - ``CodeIgniter\Debug\Exceptions::cleanPath()`` and ``CodeIgniter\Debug\Toolbar\Collectors\BaseCollector::cleanPath()`` are deprecated. Use the ``clean_path()`` function instead. - ``CodeIgniter\Log\Logger::cleanFilenames()`` and ``CodeIgniter\Test\TestLogger::cleanup()`` are both deprecated. Use the ``clean_path()`` function instead. - ``CodeIgniter\Router\Router::setDefaultController()`` is deprecated. +- The constant ``SPARKED`` in **spark** is deprecated. Use the ``$context`` property in ``CodeIgniter\CodeIgniter`` instead. Bugs Fixed ********** From 3a216d0f5e7f711c932355f828f1956b43a8c419 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 22 Feb 2022 09:39:09 +0900 Subject: [PATCH 0532/1246] docs: add note about how to check CI version --- user_guide_src/source/installation/upgrading.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/user_guide_src/source/installation/upgrading.rst b/user_guide_src/source/installation/upgrading.rst index 1e1d63abe9f1..322302d3e011 100644 --- a/user_guide_src/source/installation/upgrading.rst +++ b/user_guide_src/source/installation/upgrading.rst @@ -5,6 +5,10 @@ Upgrading From a Previous Version Please read the upgrade notes corresponding to the version you are upgrading from. +.. note:: If you don't know what version of CodeIgniter you are currently running, + you can get it from :ref:`the Debug Toolbar `, + or simply echo the constant ``\CodeIgniter\CodeIgniter::CI_VERSION``. + .. toctree:: :titlesonly: From 52fc49c701774ce7dcacbdced7d20cc633ed143c Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 22 Feb 2022 15:08:44 +0900 Subject: [PATCH 0533/1246] docs: make the file path more detailed --- user_guide_src/source/cli/cli.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/cli/cli.rst b/user_guide_src/source/cli/cli.rst index ba5305e433a6..9c7aa04cd835 100644 --- a/user_guide_src/source/cli/cli.rst +++ b/user_guide_src/source/cli/cli.rst @@ -79,7 +79,7 @@ you with CLI-only tools. CLI-Only Routing ---------------- -In your **Routes.php** file you can create routes that are only accessible from +In your **app/Config/Routes.php** file you can create routes that are only accessible from the CLI as easily as you would create any other route. Instead of using the ``get()``, ``post()``, or similar method, you would use the ``cli()`` method. Everything else works exactly like a normal route definition: From 59715c7b9a7ae0781795f6ae3078e33ce13656ee Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 22 Feb 2022 15:10:14 +0900 Subject: [PATCH 0534/1246] docs: improve page link --- user_guide_src/source/cli/cli.rst | 2 +- user_guide_src/source/incoming/routing.rst | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/user_guide_src/source/cli/cli.rst b/user_guide_src/source/cli/cli.rst index 9c7aa04cd835..e88fc6817f5b 100644 --- a/user_guide_src/source/cli/cli.rst +++ b/user_guide_src/source/cli/cli.rst @@ -87,7 +87,7 @@ works exactly like a normal route definition: .. literalinclude:: cli/002.php :lines: 2- -For more information, see the :doc:`Routes ` page. +For more information, see the :ref:`Routes ` page. The CLI Library --------------- diff --git a/user_guide_src/source/incoming/routing.rst b/user_guide_src/source/incoming/routing.rst index 14d98a8c84ed..c57e08fa3bd3 100644 --- a/user_guide_src/source/incoming/routing.rst +++ b/user_guide_src/source/incoming/routing.rst @@ -335,7 +335,9 @@ You can use the ``add()`` method: only routes that match the current request method are stored, resulting in fewer routes to scan through when trying to find a match. -Command-Line only Routes +.. _command-line-only-routes: + +Command-Line Only Routes ======================== You can create routes that work only from the command-line, and are inaccessible from the web browser, with the From 7c84a3052de2f5ff7ae68e6f86e96d572d0cd633 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 22 Feb 2022 15:10:30 +0900 Subject: [PATCH 0535/1246] docs: add warning about auto-routing --- user_guide_src/source/cli/cli.rst | 3 +++ user_guide_src/source/incoming/routing.rst | 3 +++ 2 files changed, 6 insertions(+) diff --git a/user_guide_src/source/cli/cli.rst b/user_guide_src/source/cli/cli.rst index e88fc6817f5b..45db6a1e6e3e 100644 --- a/user_guide_src/source/cli/cli.rst +++ b/user_guide_src/source/cli/cli.rst @@ -89,6 +89,9 @@ works exactly like a normal route definition: For more information, see the :ref:`Routes ` page. +.. warning:: If you don't disable auto-routing and place the command file in **app/Controllers**, + anyone could access the command with the help of auto-routing via HTTP. + The CLI Library --------------- diff --git a/user_guide_src/source/incoming/routing.rst b/user_guide_src/source/incoming/routing.rst index c57e08fa3bd3..a5c527c3eedb 100644 --- a/user_guide_src/source/incoming/routing.rst +++ b/user_guide_src/source/incoming/routing.rst @@ -348,6 +348,9 @@ available from the command line: .. literalinclude:: routing/028.php :lines: 2- +.. warning:: If you don't disable auto-routing and place the command file in **app/Controllers**, + anyone could access the command with the help of auto-routing via HTTP. + Global Options ============== From a915d8697808288e98cc9d819231034684407b14 Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Tue, 22 Feb 2022 10:19:56 +0100 Subject: [PATCH 0536/1246] Convert non-php code. --- .../source/cli/cli_commands/006.php | 2 +- .../source/cli/cli_commands/007.php | 4 ++-- .../source/database/call_function/002.php | 2 +- .../source/database/configuration/008.php | 6 ++--- .../source/database/query_builder/027.php | 2 +- .../source/extending/events/002.php | 2 +- .../source/extending/events/006.php | 2 +- .../source/general/common_functions/003.php | 2 +- .../source/helpers/array_helper/002.php | 2 +- .../source/helpers/text_helper/020.php | 15 +++++++----- .../source/helpers/url_helper/009.php | 4 ++-- .../source/helpers/url_helper/023.php | 4 +++- .../source/helpers/url_helper/024.php | 4 +++- .../source/incoming/filters/011.php | 2 +- .../source/incoming/incomingrequest/10.php | 15 +++++++----- .../source/incoming/incomingrequest/13.php | 2 +- .../source/incoming/incomingrequest/15.php | 2 +- .../source/incoming/message/003.php | 24 ++++++++++++------- .../source/incoming/message/005.php | 6 +++-- .../source/incoming/routing/029.php | 2 +- .../source/installation/upgrade_412/001.php | 3 +++ .../source/installation/upgrade_412/002.php | 3 +++ .../installation/upgrade_localization/002.php | 2 +- .../installation/upgrade_localization/003.php | 2 +- .../installation/upgrade_responses/001.php | 2 +- .../installation/upgrade_responses/002.php | 2 +- .../installation/upgrade_routing/002.php | 2 +- .../installation/upgrade_security/002.php | 2 +- .../source/libraries/curlrequest/014.php | 11 +++++---- .../source/libraries/curlrequest/019.php | 2 +- .../source/libraries/pagination/011.php | 2 +- .../source/libraries/pagination/012.php | 2 +- .../source/libraries/sessions/002.php | 2 +- .../source/libraries/sessions/005.php | 2 +- .../source/libraries/sessions/007.php | 2 +- .../source/libraries/sessions/009.php | 2 +- .../source/libraries/sessions/010.php | 2 +- .../source/libraries/sessions/014.php | 2 +- .../source/libraries/sessions/024.php | 2 +- .../source/libraries/sessions/033.php | 2 +- .../source/libraries/throttler/003.php | 2 +- user_guide_src/source/libraries/time/038.php | 2 +- user_guide_src/source/libraries/time/041.php | 4 ++-- .../source/libraries/uploaded_files/004.php | 4 ++-- .../source/libraries/uploaded_files/005.php | 4 ++-- .../source/libraries/uploaded_files/006.php | 7 +++--- user_guide_src/source/libraries/uri/020.php | 2 +- user_guide_src/source/libraries/uri/026.php | 2 +- .../source/libraries/validation/002.php | 2 +- .../source/libraries/validation/009.php | 22 +++++++++-------- .../source/libraries/validation/011.php | 13 ++++++---- .../source/libraries/validation/025.php | 2 +- .../source/libraries/validation/027.php | 2 +- user_guide_src/source/models/entities/003.php | 2 +- .../source/outgoing/localization/007.php | 2 +- .../source/outgoing/localization/008.php | 11 +++++---- .../source/outgoing/response/021.php | 2 +- .../source/outgoing/response/026.php | 4 +++- .../source/outgoing/view_parser/016.php | 2 +- .../source/outgoing/view_parser/017.php | 2 +- .../source/outgoing/view_parser/021.php | 2 +- .../source/testing/benchmark/004.php | 2 +- .../source/testing/controllers/012.php | 4 +++- .../source/testing/fabricator/001.php | 4 +++- .../source/testing/fabricator/005.php | 1 + .../source/testing/fabricator/006.php | 3 +++ .../source/testing/fabricator/009.php | 2 +- .../source/testing/fabricator/012.php | 2 +- .../source/testing/fabricator/016.php | 4 ++-- .../source/testing/fabricator/018.php | 4 ++-- .../source/testing/fabricator/021.php | 1 + user_guide_src/source/testing/feature/002.php | 2 +- .../source/testing/overview/006.php | 1 + .../source/testing/overview/007.php | 8 +++++-- .../source/testing/overview/008.php | 2 +- .../source/testing/response/004.php | 2 +- .../source/testing/response/006.php | 2 +- .../source/testing/response/020.php | 2 +- .../source/testing/response/026.php | 2 +- .../source/testing/response/030.php | 12 ++++++---- .../source/testing/response/031.php | 2 +- .../source/testing/response/032.php | 2 +- 82 files changed, 184 insertions(+), 130 deletions(-) diff --git a/user_guide_src/source/cli/cli_commands/006.php b/user_guide_src/source/cli/cli_commands/006.php index 43c03cdab049..bdc252c957be 100644 --- a/user_guide_src/source/cli/cli_commands/006.php +++ b/user_guide_src/source/cli/cli_commands/006.php @@ -1,7 +1,7 @@ showError($e); } diff --git a/user_guide_src/source/cli/cli_commands/007.php b/user_guide_src/source/cli/cli_commands/007.php index 71456025ddac..7fcb90ccf083 100644 --- a/user_guide_src/source/cli/cli_commands/007.php +++ b/user_guide_src/source/cli/cli_commands/007.php @@ -7,5 +7,5 @@ } // Output will be --n Set migration namespace --r override file +// -n Set migration namespace +// -r override file diff --git a/user_guide_src/source/database/call_function/002.php b/user_guide_src/source/database/call_function/002.php index 807a43266dac..64d5e0fbc85f 100644 --- a/user_guide_src/source/database/call_function/002.php +++ b/user_guide_src/source/database/call_function/002.php @@ -1,3 +1,3 @@ callFunction('some_function', $param1, $param2, etc..); +$db->callFunction('some_function', $param1, $param2, /* ... */); diff --git a/user_guide_src/source/database/configuration/008.php b/user_guide_src/source/database/configuration/008.php index 780c89a9b532..9d2d76336d94 100644 --- a/user_guide_src/source/database/configuration/008.php +++ b/user_guide_src/source/database/configuration/008.php @@ -2,9 +2,9 @@ class Database { - public $development = [...]; - public $test = [...]; - public $production = [...]; + public $development = [/* ... */]; + public $test = [/* ... */]; + public $production = [/* ... */]; public function __construct() { diff --git a/user_guide_src/source/database/query_builder/027.php b/user_guide_src/source/database/query_builder/027.php index 8d1b6495e232..7583487da1a2 100644 --- a/user_guide_src/source/database/query_builder/027.php +++ b/user_guide_src/source/database/query_builder/027.php @@ -9,5 +9,5 @@ // Produces: WHERE "advance_amount" < (SELECT MAX(advance_amount) FROM "orders" WHERE "id" > 2) // With builder directly -$subQuery = $db->table('orders')->select('MAX(advance_amount)', false)->where('id >', 2) +$subQuery = $db->table('orders')->select('MAX(advance_amount)', false)->where('id >', 2); $builder->where('advance_amount <', $subQuery); diff --git a/user_guide_src/source/extending/events/002.php b/user_guide_src/source/extending/events/002.php index e41a9880c232..1c28aa8dc471 100644 --- a/user_guide_src/source/extending/events/002.php +++ b/user_guide_src/source/extending/events/002.php @@ -13,5 +13,5 @@ // Use a Closure Events::on('pre_system', function (...$params) { - . . . + // ... }); diff --git a/user_guide_src/source/extending/events/006.php b/user_guide_src/source/extending/events/006.php index ff866f8e2392..5233c94e1808 100644 --- a/user_guide_src/source/extending/events/006.php +++ b/user_guide_src/source/extending/events/006.php @@ -3,5 +3,5 @@ \CodeIgniter\Events\Events::trigger('some_events', $foo, $bar, $baz); Events::on('some_event', function ($foo, $bar, $baz) { - ... + // ... }); diff --git a/user_guide_src/source/general/common_functions/003.php b/user_guide_src/source/general/common_functions/003.php index fd713d756325..4fecfb8fc9a0 100644 --- a/user_guide_src/source/general/common_functions/003.php +++ b/user_guide_src/source/general/common_functions/003.php @@ -5,5 +5,5 @@ // Set timer start and stop points timer('controller_loading'); // Will start the timer -. . . +// ... timer('controller_loading'); // Will stop the running timer diff --git a/user_guide_src/source/helpers/array_helper/002.php b/user_guide_src/source/helpers/array_helper/002.php index 64f6a2891fa0..50ce70084c86 100644 --- a/user_guide_src/source/helpers/array_helper/002.php +++ b/user_guide_src/source/helpers/array_helper/002.php @@ -9,4 +9,4 @@ 'baz' => 23, ] ] -] +]; diff --git a/user_guide_src/source/helpers/text_helper/020.php b/user_guide_src/source/helpers/text_helper/020.php index a6de1d0f67f0..e5e6be9350a6 100644 --- a/user_guide_src/source/helpers/text_helper/020.php +++ b/user_guide_src/source/helpers/text_helper/020.php @@ -3,10 +3,13 @@ $string = "Here is a simple string of text that will help us demonstrate this function."; echo word_wrap($string, 25); -// Would produce: -// Here is a simple string -// of text that will help us -// demonstrate this -// function. +/* + Would produce: -Excessively long words will be split, but URLs will not be. \ No newline at end of file + Here is a simple string + of text that will help us + demonstrate this + function. + + Excessively long words will be split, but URLs will not be. +*/ \ No newline at end of file diff --git a/user_guide_src/source/helpers/url_helper/009.php b/user_guide_src/source/helpers/url_helper/009.php index 960bc6f0430e..d8a04af25055 100644 --- a/user_guide_src/source/helpers/url_helper/009.php +++ b/user_guide_src/source/helpers/url_helper/009.php @@ -4,8 +4,8 @@ 'width' => 800, 'height' => 600, 'scrollbars' => 'yes', - 'status'      => 'yes', - 'resizable'   => 'yes', + 'status' => 'yes', + 'resizable' => 'yes', 'screenx' => 0, 'screeny' => 0, 'window_name' => '_blank', diff --git a/user_guide_src/source/helpers/url_helper/023.php b/user_guide_src/source/helpers/url_helper/023.php index 2c17057179f9..5f12524f3029 100644 --- a/user_guide_src/source/helpers/url_helper/023.php +++ b/user_guide_src/source/helpers/url_helper/023.php @@ -1,3 +1,5 @@ \App\Filters\SecureHeaders::class, ]; diff --git a/user_guide_src/source/incoming/incomingrequest/10.php b/user_guide_src/source/incoming/incomingrequest/10.php index 56f9522366b0..d4118cebda7c 100644 --- a/user_guide_src/source/incoming/incomingrequest/10.php +++ b/user_guide_src/source/incoming/incomingrequest/10.php @@ -1,12 +1,15 @@ getVar('foo'); // $data = "bar" diff --git a/user_guide_src/source/incoming/incomingrequest/13.php b/user_guide_src/source/incoming/incomingrequest/13.php index 2b5ffb8498e0..cf4be2eb10ac 100644 --- a/user_guide_src/source/incoming/incomingrequest/13.php +++ b/user_guide_src/source/incoming/incomingrequest/13.php @@ -5,4 +5,4 @@ [ 'Param1' => 'Value1', 'Param2' => 'Value2' -] +]; diff --git a/user_guide_src/source/incoming/incomingrequest/15.php b/user_guide_src/source/incoming/incomingrequest/15.php index 1584967d3bd8..c6e85bfef577 100644 --- a/user_guide_src/source/incoming/incomingrequest/15.php +++ b/user_guide_src/source/incoming/incomingrequest/15.php @@ -6,4 +6,4 @@ 'Host' => CodeIgniter\HTTP\Header, 'Cache-Control' => CodeIgniter\HTTP\Header, 'Accept' => CodeIgniter\HTTP\Header, -] +]; diff --git a/user_guide_src/source/incoming/message/003.php b/user_guide_src/source/incoming/message/003.php index 3ef7db58835a..41aa837fb49f 100644 --- a/user_guide_src/source/incoming/message/003.php +++ b/user_guide_src/source/incoming/message/003.php @@ -2,18 +2,24 @@ echo $message->header('Accept-Language'); -// Outputs something like: -'Accept-Language: en,en-US' +/* + Outputs something like: + 'Accept-Language: en,en-US' +*/ echo $message->header('Accept-Language')->getValue(); -// Outputs something like: -[ - 'en', - 'en-US' -] +/* + Outputs something like: + [ + 'en', + 'en-US' + ] +*/ echo $message->header('Accept-Language')->getValueLine(); -// Outputs something like: -'en,en-US' +/* + Outputs something like: + 'en,en-US' +*/ diff --git a/user_guide_src/source/incoming/message/005.php b/user_guide_src/source/incoming/message/005.php index dd643a1250e4..ea54a21a4407 100644 --- a/user_guide_src/source/incoming/message/005.php +++ b/user_guide_src/source/incoming/message/005.php @@ -2,5 +2,7 @@ echo $message->getHeaderLine('Accept-Language'); -// Outputs: -en, en-US +/* + Outputs: + en, en-US +*/ diff --git a/user_guide_src/source/incoming/routing/029.php b/user_guide_src/source/incoming/routing/029.php index 31c1dda07a70..fad1213d3f22 100644 --- a/user_guide_src/source/incoming/routing/029.php +++ b/user_guide_src/source/incoming/routing/029.php @@ -11,4 +11,4 @@ $routes->match(['get', 'put'], 'from', 'to', $options); $routes->resource('photos', $options); $routes->map($array, $options); -$routes->group('name', $options, function ()); +$routes->group('name', $options, function (){}); diff --git a/user_guide_src/source/installation/upgrade_412/001.php b/user_guide_src/source/installation/upgrade_412/001.php index 9b9373ac6cf0..94fb395e8077 100644 --- a/user_guide_src/source/installation/upgrade_412/001.php +++ b/user_guide_src/source/installation/upgrade_412/001.php @@ -6,3 +6,6 @@ class MyDatabaseTest extends DatabaseTestCase { public function testBadRow() { + // ... + } +} diff --git a/user_guide_src/source/installation/upgrade_412/002.php b/user_guide_src/source/installation/upgrade_412/002.php index 4fc229a77927..75ac87d0e9cf 100644 --- a/user_guide_src/source/installation/upgrade_412/002.php +++ b/user_guide_src/source/installation/upgrade_412/002.php @@ -9,3 +9,6 @@ class MyDatabaseTest extends CIUnitTestCase public function testBadRow() { + // ... + } +} diff --git a/user_guide_src/source/installation/upgrade_localization/002.php b/user_guide_src/source/installation/upgrade_localization/002.php index a377d18193fc..9c2b650415d9 100644 --- a/user_guide_src/source/installation/upgrade_localization/002.php +++ b/user_guide_src/source/installation/upgrade_localization/002.php @@ -5,7 +5,7 @@ $lang['error_url_missing'] = 'You must submit a URL'; $lang['error_username_missing'] = 'You must submit a username'; -... +// ... $this->lang->load('error', $lang); echo $this->lang->line('error_email_missing'); diff --git a/user_guide_src/source/installation/upgrade_localization/003.php b/user_guide_src/source/installation/upgrade_localization/003.php index e0149516841d..8fa627284bdd 100644 --- a/user_guide_src/source/installation/upgrade_localization/003.php +++ b/user_guide_src/source/installation/upgrade_localization/003.php @@ -12,6 +12,6 @@ ], ]; -... +// ... echo lang('Errors.errorEmailMissing'); diff --git a/user_guide_src/source/installation/upgrade_responses/001.php b/user_guide_src/source/installation/upgrade_responses/001.php index f837ab8b6c3b..74ff3a5dc5c8 100644 --- a/user_guide_src/source/installation/upgrade_responses/001.php +++ b/user_guide_src/source/installation/upgrade_responses/001.php @@ -2,7 +2,7 @@ $this->output->set_status_header(404); -... +// ... $this->output ->set_content_type('application/json') diff --git a/user_guide_src/source/installation/upgrade_responses/002.php b/user_guide_src/source/installation/upgrade_responses/002.php index e84279cf273c..469c1c1467f2 100644 --- a/user_guide_src/source/installation/upgrade_responses/002.php +++ b/user_guide_src/source/installation/upgrade_responses/002.php @@ -2,6 +2,6 @@ $this->response->setStatusCode(404); -... +// ... return $this->response->setJSON(['foo' => 'bar']); diff --git a/user_guide_src/source/installation/upgrade_routing/002.php b/user_guide_src/source/installation/upgrade_routing/002.php index 14097435e586..4bc53ace4321 100644 --- a/user_guide_src/source/installation/upgrade_routing/002.php +++ b/user_guide_src/source/installation/upgrade_routing/002.php @@ -11,7 +11,7 @@ require SYSTEMPATH . 'Config/Routes.php'; } -... +// ... $routes->add('posts/index', 'Posts::index'); $routes->add('teams/create', 'Teams::create'); diff --git a/user_guide_src/source/installation/upgrade_security/002.php b/user_guide_src/source/installation/upgrade_security/002.php index 0419285423b0..c1604ae48317 100644 --- a/user_guide_src/source/installation/upgrade_security/002.php +++ b/user_guide_src/source/installation/upgrade_security/002.php @@ -5,7 +5,7 @@ 'hash' => $this->security->get_csrf_hash() ); -... +// ...
    diff --git a/user_guide_src/source/libraries/curlrequest/014.php b/user_guide_src/source/libraries/curlrequest/014.php index 452f30dd45ed..04f6e02ffb18 100644 --- a/user_guide_src/source/libraries/curlrequest/014.php +++ b/user_guide_src/source/libraries/curlrequest/014.php @@ -2,7 +2,10 @@ $client->request('GET', 'http://example.com', ['allow_redirects' => true]); -// Sets the following defaults: -'max' => 5, // Maximum number of redirects to follow before stopping -'strict' => true, // Ensure POST requests stay POST requests through redirects -'protocols' => ['http', 'https'] // Restrict redirects to one or more protocols +/* + Sets the following defaults: + + 'max' => 5, // Maximum number of redirects to follow before stopping + 'strict' => true, // Ensure POST requests stay POST requests through redirects + 'protocols' => ['http', 'https'] // Restrict redirects to one or more protocols +*/ \ No newline at end of file diff --git a/user_guide_src/source/libraries/curlrequest/019.php b/user_guide_src/source/libraries/curlrequest/019.php index 96f86c9ea6a2..0382d08e1bbc 100644 --- a/user_guide_src/source/libraries/curlrequest/019.php +++ b/user_guide_src/source/libraries/curlrequest/019.php @@ -1,3 +1,3 @@ request('get', '/', ['cert' => ['/path/server.pem', 'password']); +$client->request('get', '/', ['cert' => ['/path/server.pem', 'password']]); diff --git a/user_guide_src/source/libraries/pagination/011.php b/user_guide_src/source/libraries/pagination/011.php index 86c5e0bcd8b5..8000e782737c 100644 --- a/user_guide_src/source/libraries/pagination/011.php +++ b/user_guide_src/source/libraries/pagination/011.php @@ -1,3 +1,3 @@ 'App\Views\Pagers\foundation_full', +['default_full' => 'App\Views\Pagers\foundation_full']; diff --git a/user_guide_src/source/libraries/pagination/012.php b/user_guide_src/source/libraries/pagination/012.php index 841118b57ae1..5a00b20f70c3 100644 --- a/user_guide_src/source/libraries/pagination/012.php +++ b/user_guide_src/source/libraries/pagination/012.php @@ -1,3 +1,3 @@ 'Pagers/foundation_full', +['default_full' => 'Pagers/foundation_full']; diff --git a/user_guide_src/source/libraries/sessions/002.php b/user_guide_src/source/libraries/sessions/002.php index e154d8544546..2ed7fb3cda92 100644 --- a/user_guide_src/source/libraries/sessions/002.php +++ b/user_guide_src/source/libraries/sessions/002.php @@ -1,3 +1,3 @@ item +$session->item; diff --git a/user_guide_src/source/libraries/sessions/009.php b/user_guide_src/source/libraries/sessions/009.php index 7c66bb38e442..12632835f531 100644 --- a/user_guide_src/source/libraries/sessions/009.php +++ b/user_guide_src/source/libraries/sessions/009.php @@ -4,7 +4,7 @@ // or: -$name = $session->name +$name = $session->name; // or: diff --git a/user_guide_src/source/libraries/sessions/010.php b/user_guide_src/source/libraries/sessions/010.php index e723f1b13ddd..c65740c91dbb 100644 --- a/user_guide_src/source/libraries/sessions/010.php +++ b/user_guide_src/source/libraries/sessions/010.php @@ -1,6 +1,6 @@ \App\Filters\Throttle::class, ]; diff --git a/user_guide_src/source/libraries/time/038.php b/user_guide_src/source/libraries/time/038.php index 5284ee5d5828..880bf193a590 100644 --- a/user_guide_src/source/libraries/time/038.php +++ b/user_guide_src/source/libraries/time/038.php @@ -3,5 +3,5 @@ $time = Time::parse('March 10, 2017', 'America/Chicago'); $diff = $time->difference(Time::now()); -$diff = $time->difference(new DateTime('July 4, 1975', 'America/Chicago'); +$diff = $time->difference(new DateTime('July 4, 1975', 'America/Chicago')); $diff = $time->difference('July 4, 1975 13:32:05', 'America/Chicago'); diff --git a/user_guide_src/source/libraries/time/041.php b/user_guide_src/source/libraries/time/041.php index 98a67ecf7998..754e1e25a58d 100644 --- a/user_guide_src/source/libraries/time/041.php +++ b/user_guide_src/source/libraries/time/041.php @@ -1,8 +1,8 @@ difference($test) +$diff = $current->difference($test); echo $diff->humanize(); // 1 year ago diff --git a/user_guide_src/source/libraries/uploaded_files/004.php b/user_guide_src/source/libraries/uploaded_files/004.php index 368facf4f7ab..51b1732bc522 100644 --- a/user_guide_src/source/libraries/uploaded_files/004.php +++ b/user_guide_src/source/libraries/uploaded_files/004.php @@ -1,5 +1,5 @@ // UploadedFile instance -] + 'avatar' => '...' // UploadedFile instance +]; diff --git a/user_guide_src/source/libraries/uploaded_files/005.php b/user_guide_src/source/libraries/uploaded_files/005.php index bf31373e57bd..190021513ef5 100644 --- a/user_guide_src/source/libraries/uploaded_files/005.php +++ b/user_guide_src/source/libraries/uploaded_files/005.php @@ -3,7 +3,7 @@ [ 'my-form' => [ 'details' => [ - 'avatar' => // UploadedFile instance + 'avatar' => '...' // UploadedFile instance ] ] -] +]; diff --git a/user_guide_src/source/libraries/uploaded_files/006.php b/user_guide_src/source/libraries/uploaded_files/006.php index c53d82a298fc..9a1fde0f053e 100644 --- a/user_guide_src/source/libraries/uploaded_files/006.php +++ b/user_guide_src/source/libraries/uploaded_files/006.php @@ -4,8 +4,9 @@ 'my-form' => [ 'details' => [ 'avatar' => [ - 0 => /* UploadedFile instance */, - 1 => /* UploadedFile instance */ + 0 => '...' /* UploadedFile instance */, + 1 => '...' /* UploadedFile instance */ + ] ] ] -] +]; \ No newline at end of file diff --git a/user_guide_src/source/libraries/uri/020.php b/user_guide_src/source/libraries/uri/020.php index ab991a826cff..53c3b8d66dd9 100644 --- a/user_guide_src/source/libraries/uri/020.php +++ b/user_guide_src/source/libraries/uri/020.php @@ -3,7 +3,7 @@ $uri = new \CodeIgniter\HTTP\URI('http://www.example.com?foo=bar&bar=baz&baz=foz'); // Returns 'foo=bar' -echo $uri->getQuery(['only' => ['foo']); +echo $uri->getQuery(['only' => ['foo']]); // Returns 'foo=bar&baz=foz' echo $uri->getQuery(['except' => ['bar']]); diff --git a/user_guide_src/source/libraries/uri/026.php b/user_guide_src/source/libraries/uri/026.php index c5be0f68c2ff..53a42eb788f4 100644 --- a/user_guide_src/source/libraries/uri/026.php +++ b/user_guide_src/source/libraries/uri/026.php @@ -7,4 +7,4 @@ 0 => 'users', 1 => '15', 2 => 'profile' -] +]; diff --git a/user_guide_src/source/libraries/validation/002.php b/user_guide_src/source/libraries/validation/002.php index 46322fe586bd..1cc4b9e188ab 100644 --- a/user_guide_src/source/libraries/validation/002.php +++ b/user_guide_src/source/libraries/validation/002.php @@ -6,5 +6,5 @@ 'passconf' => 'required|matches[password]', 'email' => 'required|valid_email', ])) { - ... + // ... } diff --git a/user_guide_src/source/libraries/validation/009.php b/user_guide_src/source/libraries/validation/009.php index 1678d5530f27..aec2e980c5dc 100644 --- a/user_guide_src/source/libraries/validation/009.php +++ b/user_guide_src/source/libraries/validation/009.php @@ -1,17 +1,19 @@ [ - 'name' => 'Joe Smith', - 'friends' => [ - [ - 'name' => 'Fred Flinstone', - ], - [ - 'name' => 'Wilma', - ], +[ + 'contacts' => [ + 'name' => 'Joe Smith', + 'friends' => [ + [ + 'name' => 'Fred Flinstone', + ], + [ + 'name' => 'Wilma', + ], + ] ] -] +]; // Joe Smith $validation->setRules([ diff --git a/user_guide_src/source/libraries/validation/011.php b/user_guide_src/source/libraries/validation/011.php index 023712f4315e..66fbcda5e1a7 100644 --- a/user_guide_src/source/libraries/validation/011.php +++ b/user_guide_src/source/libraries/validation/011.php @@ -1,11 +1,14 @@ [ - 1, - 2, - 3, -] +[ + 'user_ids' => [ + 1, + 2, + 3, + ] +]; + // Rule $validation->setRules([ 'user_ids.*' => 'required', diff --git a/user_guide_src/source/libraries/validation/025.php b/user_guide_src/source/libraries/validation/025.php index 0531b84be47c..a71f46f29f92 100644 --- a/user_guide_src/source/libraries/validation/025.php +++ b/user_guide_src/source/libraries/validation/025.php @@ -1,3 +1,3 @@ 'Supplied value ({value}) for {field} must have at least {param} characters.' +['min_length' => 'Supplied value ({value}) for {field} must have at least {param} characters.']; diff --git a/user_guide_src/source/libraries/validation/027.php b/user_guide_src/source/libraries/validation/027.php index 57aa5a31cb84..c6afaf393f2a 100644 --- a/user_guide_src/source/libraries/validation/027.php +++ b/user_guide_src/source/libraries/validation/027.php @@ -6,4 +6,4 @@ [ 'field1' => 'error message', 'field2' => 'error message', -] +]; diff --git a/user_guide_src/source/models/entities/003.php b/user_guide_src/source/models/entities/003.php index 4b29ea153692..c8cfd58c14db 100644 --- a/user_guide_src/source/models/entities/003.php +++ b/user_guide_src/source/models/entities/003.php @@ -9,7 +9,7 @@ // Updating unset($user->username); -if (! isset($user->username) { +if (! isset($user->username)) { $user->username = 'something new'; } diff --git a/user_guide_src/source/outgoing/localization/007.php b/user_guide_src/source/outgoing/localization/007.php index 48dc3e455282..e2de3a4644d6 100644 --- a/user_guide_src/source/outgoing/localization/007.php +++ b/user_guide_src/source/outgoing/localization/007.php @@ -1,3 +1,3 @@ 'The actual message to be shown.' +['languageKey' => 'The actual message to be shown.']; diff --git a/user_guide_src/source/outgoing/localization/008.php b/user_guide_src/source/outgoing/localization/008.php index b8975a521320..eac50a5f4861 100644 --- a/user_guide_src/source/outgoing/localization/008.php +++ b/user_guide_src/source/outgoing/localization/008.php @@ -1,7 +1,10 @@ [ - 'nested' => [ - 'key' => 'The actual message to be shown.', +[ + 'languageKey' => [ + 'nested' => [ + 'key' => 'The actual message to be shown.', + ], ], -], +] +; \ No newline at end of file diff --git a/user_guide_src/source/outgoing/response/021.php b/user_guide_src/source/outgoing/response/021.php index 41745631aaac..092a758b18db 100644 --- a/user_guide_src/source/outgoing/response/021.php +++ b/user_guide_src/source/outgoing/response/021.php @@ -3,4 +3,4 @@ $response->noCache(); // Sets the following header: -Cache-Control: no-store, max-age=0, no-cache +// Cache-Control: no-store, max-age=0, no-cache diff --git a/user_guide_src/source/outgoing/response/026.php b/user_guide_src/source/outgoing/response/026.php index 55149496da87..4287ddb889ba 100644 --- a/user_guide_src/source/outgoing/response/026.php +++ b/user_guide_src/source/outgoing/response/026.php @@ -1,3 +1,5 @@ hasCookie($name)) ... +if ($response->hasCookie($name)) { + // ... +} \ No newline at end of file diff --git a/user_guide_src/source/outgoing/view_parser/016.php b/user_guide_src/source/outgoing/view_parser/016.php index 74a18943365c..e93bd3986957 100644 --- a/user_guide_src/source/outgoing/view_parser/016.php +++ b/user_guide_src/source/outgoing/view_parser/016.php @@ -5,4 +5,4 @@ ]; // Tag is replaced by the return value of Some\Class::methodName static function. -{+ foo +} +// {+ foo +} diff --git a/user_guide_src/source/outgoing/view_parser/017.php b/user_guide_src/source/outgoing/view_parser/017.php index 30d72b247059..4e699d190bcd 100644 --- a/user_guide_src/source/outgoing/view_parser/017.php +++ b/user_guide_src/source/outgoing/view_parser/017.php @@ -4,4 +4,4 @@ 'foo' => ['\Some\Class::methodName'] ]; -{+ foo +} inner content {+ /foo +} +// {+ foo +} inner content {+ /foo +} diff --git a/user_guide_src/source/outgoing/view_parser/021.php b/user_guide_src/source/outgoing/view_parser/021.php index cf7b31fa7e30..6dce1f1316e2 100644 --- a/user_guide_src/source/outgoing/view_parser/021.php +++ b/user_guide_src/source/outgoing/view_parser/021.php @@ -7,7 +7,7 @@ ['title' => 'Second Link', 'link' => '/second'], ]; -foreach ($data1 as $menuItem),{ +foreach ($data1 as $menuItem){ $temp .= $parser->setData($menuItem)->renderString($template1); } diff --git a/user_guide_src/source/testing/benchmark/004.php b/user_guide_src/source/testing/benchmark/004.php index 112aea9f2e82..bf84bf6ed21f 100644 --- a/user_guide_src/source/testing/benchmark/004.php +++ b/user_guide_src/source/testing/benchmark/004.php @@ -9,4 +9,4 @@ 'end' => 1345678920, 'duration' => 15.4315, // number of seconds ] -] +]; diff --git a/user_guide_src/source/testing/controllers/012.php b/user_guide_src/source/testing/controllers/012.php index dd3b600d90fd..e9425a085488 100644 --- a/user_guide_src/source/testing/controllers/012.php +++ b/user_guide_src/source/testing/controllers/012.php @@ -10,4 +10,6 @@ protected function testFilterFailsOnAdminRoute() $this->assertHasFilters('unfiltered/route', 'before'); } -... + + // ... +} diff --git a/user_guide_src/source/testing/fabricator/001.php b/user_guide_src/source/testing/fabricator/001.php index f5f2e33ff455..a4e6456549a6 100644 --- a/user_guide_src/source/testing/fabricator/001.php +++ b/user_guide_src/source/testing/fabricator/001.php @@ -1,3 +1,5 @@ config('Auth')->allowRemembering ? date('Y-m-d') : null, ]; } +} \ No newline at end of file diff --git a/user_guide_src/source/testing/fabricator/006.php b/user_guide_src/source/testing/fabricator/006.php index 587a0697d1fa..cfb130f21ede 100644 --- a/user_guide_src/source/testing/fabricator/006.php +++ b/user_guide_src/source/testing/fabricator/006.php @@ -6,3 +6,6 @@ class UserFabricator extends \App\Models\UserModel { public function fake(&$faker) { + // ... + } +} \ No newline at end of file diff --git a/user_guide_src/source/testing/fabricator/009.php b/user_guide_src/source/testing/fabricator/009.php index 3a7507430265..9c8d366d8684 100644 --- a/user_guide_src/source/testing/fabricator/009.php +++ b/user_guide_src/source/testing/fabricator/009.php @@ -6,4 +6,4 @@ 'phone' => "201-886-0269 x3767", 'avatar' => "http://lorempixel.com/800/400/", 'login' => null, -) +); diff --git a/user_guide_src/source/testing/fabricator/012.php b/user_guide_src/source/testing/fabricator/012.php index 782c58f8917f..89731845f145 100644 --- a/user_guide_src/source/testing/fabricator/012.php +++ b/user_guide_src/source/testing/fabricator/012.php @@ -9,4 +9,4 @@ 'login' => null, 'created_at' => "2020-05-08 14:52:10", 'updated_at' => "2020-05-08 14:52:10", -) +); diff --git a/user_guide_src/source/testing/fabricator/016.php b/user_guide_src/source/testing/fabricator/016.php index 72f2b946366e..eb9edc657239 100644 --- a/user_guide_src/source/testing/fabricator/016.php +++ b/user_guide_src/source/testing/fabricator/016.php @@ -6,7 +6,7 @@ 'phone' => "251-806-2169", 'avatar' => "http://lorempixel.com/800/400/", 'login' => null, -) +); array( 'first' => "Bobby", @@ -14,4 +14,4 @@ 'phone' => "525-214-2656 x23546", 'avatar' => "http://lorempixel.com/800/400/", 'login' => null, -) +); diff --git a/user_guide_src/source/testing/fabricator/018.php b/user_guide_src/source/testing/fabricator/018.php index 73a3b932052e..60599b602f6e 100644 --- a/user_guide_src/source/testing/fabricator/018.php +++ b/user_guide_src/source/testing/fabricator/018.php @@ -6,7 +6,7 @@ 'phone' => "741-857-1933 x1351", 'avatar' => "http://lorempixel.com/800/400/", 'login' => null, -) +); array( 'first' => "Hans", @@ -14,4 +14,4 @@ 'phone' => "487-235-7006", 'avatar' => "http://lorempixel.com/800/400/", 'login' => null, -) +); diff --git a/user_guide_src/source/testing/fabricator/021.php b/user_guide_src/source/testing/fabricator/021.php index a1b0111e0903..df10c0b137d7 100644 --- a/user_guide_src/source/testing/fabricator/021.php +++ b/user_guide_src/source/testing/fabricator/021.php @@ -12,3 +12,4 @@ public function fake(Generator &$faker) 'group_id' => rand(1, Fabricator::getCount('groups')), ]; } +} \ No newline at end of file diff --git a/user_guide_src/source/testing/feature/002.php b/user_guide_src/source/testing/feature/002.php index c5f67f42b36c..553aaa0bfd03 100644 --- a/user_guide_src/source/testing/feature/002.php +++ b/user_guide_src/source/testing/feature/002.php @@ -4,7 +4,7 @@ $result = $this->call('get', '/'); // Submit a form -$result = $this->call('post', 'contact'), [ +$result = $this->call('post', 'contact', [ 'name' => 'Fred Flintstone', 'email' => 'flintyfred@example.com' ]); diff --git a/user_guide_src/source/testing/overview/006.php b/user_guide_src/source/testing/overview/006.php index bbd2a333a349..1ab3e692f0eb 100644 --- a/user_guide_src/source/testing/overview/006.php +++ b/user_guide_src/source/testing/overview/006.php @@ -10,3 +10,4 @@ protected function purgeRows() { $this->model->purgeDeleted() } +} diff --git a/user_guide_src/source/testing/overview/007.php b/user_guide_src/source/testing/overview/007.php index 74bbb533de38..d6ec1d6c45c5 100644 --- a/user_guide_src/source/testing/overview/007.php +++ b/user_guide_src/source/testing/overview/007.php @@ -7,9 +7,13 @@ trait AuthTrait $user = $this->createFakeUser(); $this->logInUser($user); } -... + + // ... +} class AuthenticationFeatureTest { use AuthTrait; -... + + // ... +} \ No newline at end of file diff --git a/user_guide_src/source/testing/overview/008.php b/user_guide_src/source/testing/overview/008.php index 9d84f888c1d4..55077ed36818 100644 --- a/user_guide_src/source/testing/overview/008.php +++ b/user_guide_src/source/testing/overview/008.php @@ -3,7 +3,7 @@ $config = new LoggerConfig(); $logger = new Logger($config); -... do something that you expect a log entry from +// ... do something that you expect a log entry from $logger->log('error', "That's no moon"); $this->assertLogged('error', "That's no moon"); diff --git a/user_guide_src/source/testing/response/004.php b/user_guide_src/source/testing/response/004.php index 3cb56ea74b8f..d3ccbf4f4d12 100644 --- a/user_guide_src/source/testing/response/004.php +++ b/user_guide_src/source/testing/response/004.php @@ -1,5 +1,5 @@ isOK()) { - ... + // ... } diff --git a/user_guide_src/source/testing/response/006.php b/user_guide_src/source/testing/response/006.php index 90da5662c383..dcca55a4938b 100644 --- a/user_guide_src/source/testing/response/006.php +++ b/user_guide_src/source/testing/response/006.php @@ -1,5 +1,5 @@ isRedirect()) { - ... + // ... } diff --git a/user_guide_src/source/testing/response/020.php b/user_guide_src/source/testing/response/020.php index cb490d8a98ff..8b716717b696 100644 --- a/user_guide_src/source/testing/response/020.php +++ b/user_guide_src/source/testing/response/020.php @@ -3,6 +3,6 @@ // Check that an element with class 'notice' exists $results->seeElement('.notice'); // Check that an element with id 'title' exists -$results->seeElement('#title') +$results->seeElement('#title'); // Verify that an element with id 'title' does NOT exist $results->dontSeeElement('#title'); diff --git a/user_guide_src/source/testing/response/026.php b/user_guide_src/source/testing/response/026.php index 773b7dd04833..4afd20161b23 100644 --- a/user_guide_src/source/testing/response/026.php +++ b/user_guide_src/source/testing/response/026.php @@ -3,4 +3,4 @@ // Check that an element with class 'notice' exists $results->seeElement('.notice'); // Check that an element with id 'title' exists -$results->seeElement('#title') +$results->seeElement('#title'); diff --git a/user_guide_src/source/testing/response/030.php b/user_guide_src/source/testing/response/030.php index e6417035e73f..7dfa89e51cc1 100644 --- a/user_guide_src/source/testing/response/030.php +++ b/user_guide_src/source/testing/response/030.php @@ -1,11 +1,13 @@ 'bar'] +['foo' => 'bar']; $json = $result->getJSON(); -// $json is this: -{ - "foo": "bar" -} +/* + $json is this: + { + "foo": "bar" + } +`*/ diff --git a/user_guide_src/source/testing/response/031.php b/user_guide_src/source/testing/response/031.php index 0c9ded88a7f5..6e746800e034 100644 --- a/user_guide_src/source/testing/response/031.php +++ b/user_guide_src/source/testing/response/031.php @@ -1,4 +1,4 @@ assertTrue($result->getJSON() !== false) +$this->assertTrue($result->getJSON() !== false); diff --git a/user_guide_src/source/testing/response/032.php b/user_guide_src/source/testing/response/032.php index e808ca1a43dd..c2d093443b9d 100644 --- a/user_guide_src/source/testing/response/032.php +++ b/user_guide_src/source/testing/response/032.php @@ -3,7 +3,7 @@ // Response body is this: [ 'config' => ['key-a', 'key-b'], -] +]; // Is true $result->assertJSONFragment(['config' => ['key-a']]); From 32e72c813123a0973e08fda92d3a688e0a2331cf Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 22 Feb 2022 18:54:07 +0900 Subject: [PATCH 0537/1246] docs: fix @param of view cell --- system/Common.php | 2 +- system/View/Cell.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/system/Common.php b/system/Common.php index 690275c4fedf..257c238d2b42 100644 --- a/system/Common.php +++ b/system/Common.php @@ -1125,7 +1125,7 @@ function view(string $name, array $data = [], array $options = []): string * View cells are used within views to insert HTML chunks that are managed * by other classes. * - * @param null $params + * @param array|string|null $params * * @throws ReflectionException */ diff --git a/system/View/Cell.php b/system/View/Cell.php index 50168a153be6..c4fa23a6fbba 100644 --- a/system/View/Cell.php +++ b/system/View/Cell.php @@ -62,7 +62,7 @@ public function __construct(CacheInterface $cache) /** * Render a cell, returning its body as a string. * - * @param null $params + * @param array|string|null $params * * @throws ReflectionException */ @@ -141,7 +141,7 @@ public function render(string $library, $params = null, int $ttl = 0, ?string $c * If a string, it should be in the format "key1=value key2=value". * It will be split and returned as an array. * - * @param mixed $params + * @param array|string|null $params * * @return array|null */ From dd80915f52bdca560d60257889a136a7ab38d06a Mon Sep 17 00:00:00 2001 From: Nudasoft <30935025+Nudasoft@users.noreply.github.com> Date: Tue, 22 Feb 2022 17:34:56 +0530 Subject: [PATCH 0538/1246] Use native $g-red: #DD4814; color for badge background. Use native $g-red: #DD4814; color for badge background instead a custom color. --- system/Debug/Toolbar/Views/toolbar.css | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/system/Debug/Toolbar/Views/toolbar.css b/system/Debug/Toolbar/Views/toolbar.css index 47e74d9a4f1b..f160dba91f29 100644 --- a/system/Debug/Toolbar/Views/toolbar.css +++ b/system/Debug/Toolbar/Views/toolbar.css @@ -315,7 +315,7 @@ #debug-bar .ci-label:hover { background-color: #DFDFDF; } #debug-bar .ci-label .badge { - background-color: #DD7359; + background-color: #DD4814; color: #FFFFFF; } #debug-bar .tab { background-color: #FFFFFF; @@ -406,7 +406,7 @@ #debug-bar .ci-label:hover { background-color: #252525; } #debug-bar .ci-label .badge { - background-color: #DD7359; + background-color: #DD4814; color: #FFFFFF; } #debug-bar .tab { background-color: #252525; @@ -495,7 +495,7 @@ #toolbarContainer.dark #debug-bar .ci-label:hover { background-color: #252525; } #toolbarContainer.dark #debug-bar .ci-label .badge { - background-color: #DD7359; + background-color: #DD4814; color: #FFFFFF; } #toolbarContainer.dark #debug-bar .tab { background-color: #252525; @@ -588,7 +588,7 @@ #toolbarContainer.light #debug-bar .ci-label:hover { background-color: #DFDFDF; } #toolbarContainer.light #debug-bar .ci-label .badge { - background-color: #DD7359; + background-color: #DD4814; color: #FFFFFF; } #toolbarContainer.light #debug-bar .tab { background-color: #FFFFFF; From 09b4b8db7047dd3adc31cec1d3c2ce892a9e953e Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 22 Feb 2022 21:20:36 +0900 Subject: [PATCH 0539/1246] refactor: remove `&` before $db $db is an object. We don't need to use reference. --- system/Database/BaseBuilder.php | 2 +- system/Database/BasePreparedQuery.php | 2 +- system/Database/BaseUtils.php | 4 ++-- system/Database/Forge.php | 2 +- system/Database/Query.php | 2 +- system/Database/SQLSRV/Utils.php | 2 +- system/Database/Seeder.php | 2 +- system/Model.php | 4 ++-- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/system/Database/BaseBuilder.php b/system/Database/BaseBuilder.php index a3fc6c7563d3..ccfa5bd9d8bb 100644 --- a/system/Database/BaseBuilder.php +++ b/system/Database/BaseBuilder.php @@ -270,7 +270,7 @@ class BaseBuilder * * @throws DatabaseException */ - public function __construct($tableName, ConnectionInterface &$db, ?array $options = null) + public function __construct($tableName, ConnectionInterface $db, ?array $options = null) { if (empty($tableName)) { throw new DatabaseException('A table must be specified when creating a new Query Builder.'); diff --git a/system/Database/BasePreparedQuery.php b/system/Database/BasePreparedQuery.php index ba36915c79fe..b6e2db706d2a 100644 --- a/system/Database/BasePreparedQuery.php +++ b/system/Database/BasePreparedQuery.php @@ -57,7 +57,7 @@ abstract class BasePreparedQuery implements PreparedQueryInterface public function __construct(BaseConnection $db) { - $this->db = &$db; + $this->db = $db; } /** diff --git a/system/Database/BaseUtils.php b/system/Database/BaseUtils.php index 7848ae75ecf0..9ba48c927619 100644 --- a/system/Database/BaseUtils.php +++ b/system/Database/BaseUtils.php @@ -49,9 +49,9 @@ abstract class BaseUtils /** * Class constructor */ - public function __construct(ConnectionInterface &$db) + public function __construct(ConnectionInterface $db) { - $this->db = &$db; + $this->db = $db; } /** diff --git a/system/Database/Forge.php b/system/Database/Forge.php index 60095ae2496f..e5f8c9aedc68 100644 --- a/system/Database/Forge.php +++ b/system/Database/Forge.php @@ -179,7 +179,7 @@ class Forge */ public function __construct(BaseConnection $db) { - $this->db = &$db; + $this->db = $db; } /** diff --git a/system/Database/Query.php b/system/Database/Query.php index b9dc4619dd06..702575ca857c 100644 --- a/system/Database/Query.php +++ b/system/Database/Query.php @@ -91,7 +91,7 @@ class Query implements QueryInterface */ public $db; - public function __construct(ConnectionInterface &$db) + public function __construct(ConnectionInterface $db) { $this->db = $db; } diff --git a/system/Database/SQLSRV/Utils.php b/system/Database/SQLSRV/Utils.php index cf94d3dad783..22a12bcdf02a 100755 --- a/system/Database/SQLSRV/Utils.php +++ b/system/Database/SQLSRV/Utils.php @@ -34,7 +34,7 @@ class Utils extends BaseUtils */ protected $optimizeTable = 'ALTER INDEX all ON %s REORGANIZE'; - public function __construct(ConnectionInterface &$db) + public function __construct(ConnectionInterface $db) { parent::__construct($db); diff --git a/system/Database/Seeder.php b/system/Database/Seeder.php index 94bd0612e393..893de7d56ec4 100644 --- a/system/Database/Seeder.php +++ b/system/Database/Seeder.php @@ -92,7 +92,7 @@ public function __construct(Database $config, ?BaseConnection $db = null) $db ??= Database::connect($this->DBGroup); - $this->db = &$db; + $this->db = $db; $this->forge = Database::forge($this->DBGroup); } diff --git a/system/Model.php b/system/Model.php index e2f5b0fca891..31447cb00d72 100644 --- a/system/Model.php +++ b/system/Model.php @@ -100,14 +100,14 @@ class Model extends BaseModel 'getCompiledUpdate', ]; - public function __construct(?ConnectionInterface &$db = null, ?ValidationInterface $validation = null) + public function __construct(?ConnectionInterface $db = null, ?ValidationInterface $validation = null) { /** * @var BaseConnection|null $db */ $db ??= Database::connect($this->DBGroup); - $this->db = &$db; + $this->db = $db; parent::__construct($validation); } From b4fa714feea036b2a596487004ed10e5fc3eb7bf Mon Sep 17 00:00:00 2001 From: Nudasoft Date: Tue, 22 Feb 2022 22:00:45 +0530 Subject: [PATCH 0540/1246] Use red background color for badges instead using blue. This red background color makes text color pop more and go align with the CI4 theme color. --- admin/css/debug-toolbar/_theme-dark.scss | 4 ++-- admin/css/debug-toolbar/_theme-light.scss | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/admin/css/debug-toolbar/_theme-dark.scss b/admin/css/debug-toolbar/_theme-dark.scss index 801b75664f22..ead7d02a58e3 100644 --- a/admin/css/debug-toolbar/_theme-dark.scss +++ b/admin/css/debug-toolbar/_theme-dark.scss @@ -129,8 +129,8 @@ } .badge { - background-color: $g-blue; - color: $m-gray; + background-color: $g-red; + color: $t-light; } } diff --git a/admin/css/debug-toolbar/_theme-light.scss b/admin/css/debug-toolbar/_theme-light.scss index 41dbb9175fde..4e4295ccd131 100644 --- a/admin/css/debug-toolbar/_theme-light.scss +++ b/admin/css/debug-toolbar/_theme-light.scss @@ -125,7 +125,7 @@ } .badge { - background-color: $g-blue; + background-color: $g-red; color: $t-light; } } From dc43271dbc0eb67db80c531feb7998409e4743a2 Mon Sep 17 00:00:00 2001 From: Nudasoft Date: Tue, 22 Feb 2022 22:01:32 +0530 Subject: [PATCH 0541/1246] Fix alignment issues on few buttons. --- admin/css/debug-toolbar/toolbar.scss | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/admin/css/debug-toolbar/toolbar.scss b/admin/css/debug-toolbar/toolbar.scss index c73510182ac7..d9bc347c4b3b 100644 --- a/admin/css/debug-toolbar/toolbar.scss +++ b/admin/css/debug-toolbar/toolbar.scss @@ -77,16 +77,9 @@ // General elements h1 { - bottom: 0; - display: inline-block; - font-size: $base-size - 2; + display: flex; font-weight: normal; - margin: 0 16px 0 0; - padding: 0; - position: absolute; - right: 30px; - text-align: left; - top: 0; + margin: 0 0 0 auto; svg { width: 16px; @@ -238,15 +231,8 @@ // The "Open/Close" toggle #debug-bar-link { - bottom: 0; - display: inline-block; - font-size: $base-size; - line-height: 36px; + display: flex; padding: 6px; - position: absolute; - right: 10px; - top: 0; - width: 24px; } // The toolbar menus From 0e18a6ca4c07dd4c438de22d12c57cb724152515 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 23 Feb 2022 09:40:33 +0900 Subject: [PATCH 0542/1246] docs: change "previous version" to a specific version --- user_guide_src/source/libraries/sessions.rst | 2 +- user_guide_src/source/libraries/uploaded_files.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/user_guide_src/source/libraries/sessions.rst b/user_guide_src/source/libraries/sessions.rst index ad45f9fea4f3..6c4e71081173 100644 --- a/user_guide_src/source/libraries/sessions.rst +++ b/user_guide_src/source/libraries/sessions.rst @@ -69,7 +69,7 @@ Unless you're developing a website with heavy AJAX usage, you can skip this section. If you are, however, and if you're experiencing performance issues, then this note is exactly what you're looking for. -Sessions in previous versions of CodeIgniter didn't implement locking, +Sessions in CodeIgniter v2.x didn't implement locking, which meant that two HTTP requests using the same session could run exactly at the same time. To use a more appropriate technical term - requests were non-blocking. diff --git a/user_guide_src/source/libraries/uploaded_files.rst b/user_guide_src/source/libraries/uploaded_files.rst index 265eb87dc20a..90a4df446d1a 100644 --- a/user_guide_src/source/libraries/uploaded_files.rst +++ b/user_guide_src/source/libraries/uploaded_files.rst @@ -5,7 +5,7 @@ Working with Uploaded Files CodeIgniter makes working with files uploaded through a form much simpler and more secure than using PHP's ``$_FILES`` array directly. This extends the :doc:`File class ` and thus gains all of the features of that class. -.. note:: This is not the same as the File Uploading class in previous versions of CodeIgniter. This provides a raw +.. note:: This is not the same as the File Uploading class in CodeIgniter v3.x. This provides a raw interface to the uploaded files with a few small features. .. contents:: From 6e1219508ce3bbc544e6e2f272bb375b2289f71e Mon Sep 17 00:00:00 2001 From: Mostafa Khudair <59371810+mostafakhudair@users.noreply.github.com> Date: Wed, 23 Feb 2022 17:18:45 +0200 Subject: [PATCH 0543/1246] Update Forge.php --- system/Database/OCI8/Forge.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/system/Database/OCI8/Forge.php b/system/Database/OCI8/Forge.php index d5ca20a9e4d9..9cd5bad945cd 100644 --- a/system/Database/OCI8/Forge.php +++ b/system/Database/OCI8/Forge.php @@ -11,10 +11,12 @@ namespace CodeIgniter\Database\OCI8; +use CodeIgniter\Database\Forge as BaseForge; + /** * Forge for OCI8 */ -class Forge extends \CodeIgniter\Database\Forge +class Forge extends BaseForge { /** * DROP INDEX statement From 97640c9b107b8213e9b1518f62f5927058a86c28 Mon Sep 17 00:00:00 2001 From: kenjis Date: Thu, 24 Feb 2022 09:11:31 +0900 Subject: [PATCH 0544/1246] fix: forceGlobalSecureRequests break URI schemes other than HTTP --- system/HTTP/URI.php | 5 ++++- tests/system/HTTP/URITest.php | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/system/HTTP/URI.php b/system/HTTP/URI.php index 70305ae5864c..2fe9b430213a 100644 --- a/system/HTTP/URI.php +++ b/system/HTTP/URI.php @@ -586,7 +586,10 @@ public function __toString(): string $baseUri = new self($config->baseURL); // If the hosts matches then assume this should be relative to baseURL - if ($this->getHost() === $baseUri->getHost()) { + if ( + substr($this->getScheme(), 0, 4) === 'http' + && $this->getHost() === $baseUri->getHost() + ) { // Check for additional segments $basePath = trim($baseUri->getPath(), '/') . '/'; $trimPath = ltrim($path, '/'); diff --git a/tests/system/HTTP/URITest.php b/tests/system/HTTP/URITest.php index 8536fcc7c801..a4faacfbdd80 100644 --- a/tests/system/HTTP/URITest.php +++ b/tests/system/HTTP/URITest.php @@ -985,4 +985,20 @@ public function testCreateURIString() $this->assertSame($expected, $uri); } + + /** + * @see https://github.com/codeigniter4/CodeIgniter4/issues/5728 + */ + public function testForceGlobalSecureRequestsAndNonHTTPProtocol() + { + $config = new App(); + $config->forceGlobalSecureRequests = true; + $config->baseURL = 'https://localhost/'; + Factories::injectMock('config', 'App', $config); + + $expected = 'ftp://localhost/path/to/test.txt'; + $uri = new URI($expected); + + $this->assertSame($expected, (string) $uri); + } } From 7c74eae490a92c7b3827d4a76ac31409919e4dd1 Mon Sep 17 00:00:00 2001 From: kenjis Date: Thu, 24 Feb 2022 10:33:31 +0900 Subject: [PATCH 0545/1246] refactor: extract the logic to be deprecated --- system/HTTP/URI.php | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/system/HTTP/URI.php b/system/HTTP/URI.php index 2fe9b430213a..e0a6ff9f2386 100644 --- a/system/HTTP/URI.php +++ b/system/HTTP/URI.php @@ -581,11 +581,30 @@ public function __toString(): string $path = $this->getPath(); $scheme = $this->getScheme(); + // If the hosts matches then assume this should be relative to baseURL + [$scheme, $path] = $this->changeSchemeAndPath($scheme, $path); + + return static::createURIString( + $scheme, + $this->getAuthority(), + $path, // Absolute URIs should use a "/" for an empty path + $this->getQuery(), + $this->getFragment() + ); + } + + /** + * Change the path (and scheme) assuming URIs with the same host as baseURL + * should be relative to the project's configuration. + * + * @deprecated This method will be deleted. + */ + private function changeSchemeAndPath(string $scheme, string $path): array + { // Check if this is an internal URI $config = config('App'); $baseUri = new self($config->baseURL); - // If the hosts matches then assume this should be relative to baseURL if ( substr($this->getScheme(), 0, 4) === 'http' && $this->getHost() === $baseUri->getHost() @@ -604,13 +623,7 @@ public function __toString(): string } } - return static::createURIString( - $scheme, - $this->getAuthority(), - $path, // Absolute URIs should use a "/" for an empty path - $this->getQuery(), - $this->getFragment() - ); + return [$scheme, $path]; } /** From f8e7c78cea6a73e2c6a91e32df8a389f2525d9ab Mon Sep 17 00:00:00 2001 From: "John Paul E. Balandan, CPA" Date: Thu, 24 Feb 2022 10:57:24 +0800 Subject: [PATCH 0546/1246] Add workflow to test SCSS compilation --- .github/workflows/test-scss.yml | 51 +++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 .github/workflows/test-scss.yml diff --git a/.github/workflows/test-scss.yml b/.github/workflows/test-scss.yml new file mode 100644 index 000000000000..b7f66a17f29b --- /dev/null +++ b/.github/workflows/test-scss.yml @@ -0,0 +1,51 @@ +name: SCSS Compilation + +on: + pull_request: + branches: + - 'develop' + - 'v4.x' + paths: + - '**.scss' + - '**.css' + - '.github/workflows/test-scss.yml' + + push: + branches: + - 'develop' + - 'v4.x' + paths: + - '**.scss' + - '**.css' + - '.github/workflows/test-scss.yml' + +jobs: + build: + name: Compilation of SCSS (Dart Sass) + runs-on: ubuntu-20.04 + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup Node + uses: actions/setup-node@v2 + with: + # node version based on dart-sass test workflow + node-version: 16 + + - name: Install Dart Sass + run: | + npm install --global sass + sass --version + + - name: Run Dart Sass + run: sass --no-source-map admin/css/debug-toolbar/toolbar.scss system/Debug/Toolbar/Views/toolbar.css + + - name: Check for changed CSS files + run: | + if [[ -n "$(git status --porcelain 2>/dev/null)" ]]; then + echo "Your changes to the SCSS files did not match the expected CSS output." + git diff-files --patch + exit 1 + fi From ea9ffb0f284b5e37acaa7e9b481aedf57d20d67f Mon Sep 17 00:00:00 2001 From: "John Paul E. Balandan, CPA" Date: Thu, 24 Feb 2022 10:59:22 +0800 Subject: [PATCH 0547/1246] Update contribution guide --- contributing/css.md | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/contributing/css.md b/contributing/css.md index 3108319a0e1b..7accf5e83801 100644 --- a/contributing/css.md +++ b/contributing/css.md @@ -1,6 +1,6 @@ -# Contribution CSS +# Contribution to Debug Toolbar CSS -CodeIgniter uses SASS to generate the debug toolbar's CSS. Therefore, +CodeIgniter uses Dart Sass to generate the debug toolbar's CSS. Therefore, you will need to install it first. You can find further instructions on the official website: @@ -9,34 +9,32 @@ the official website: Open your terminal, and navigate to CodeIgniter's root folder. To generate the CSS file, use the following command: -`sass --no-cache --sourcemap=none admin/css/debug-toolbar/toolbar.scss system/Debug/Toolbar/Views/toolbar.css` +`sass --no-source-map admin/css/debug-toolbar/toolbar.scss system/Debug/Toolbar/Views/toolbar.css` -Details: -- `--no-cache` is a parameter defined to disable SASS cache, -this prevents a "cache" folder from being created -- `--sourcemap=none` is a parameter which prevents soucemap files from being generated -- `admin/css/debug-toolbar/toolbar.scss` is the SASS source +Details: +- `--no-source-map` is an option which prevents sourcemap files from being generated +- `admin/css/debug-toolbar/toolbar.scss` is the SASS source - `system/Debug/Toolbar/Views/toolbar.css` is he CSS destination ## Color scheme **Themes** -Dark: `#252525` / `rgb(37, 37, 37)` -Light: `#FFFFFF` / `rgb(255, 255, 255)` +Dark: `#252525` / `rgb(37, 37, 37)` +Light: `#FFFFFF` / `rgb(255, 255, 255)` **Glossy colors** -Blue: `#5BC0DE` / `rgb(91, 192, 222)` -Gray: `#434343` / `rgb(67, 67, 67)` -Green: `#9ACE25` / `rgb(154, 206, 37)` -Orange: `#DD8615` / `rgb(221, 134, 21)` -Red: `#DD4814` / `rgb(221, 72, 20)` +Blue: `#5BC0DE` / `rgb(91, 192, 222)` +Gray: `#434343` / `rgb(67, 67, 67)` +Green: `#9ACE25` / `rgb(154, 206, 37)` +Orange: `#DD8615` / `rgb(221, 134, 21)` +Red: `#DD4814` / `rgb(221, 72, 20)` **Matt colors** -Blue: `#D8EAF0` / `rgb(216, 234, 240)` -Gray: `#DFDFDF` / `rgb(223, 223, 223)` -Green: `#DFF0D8` / `rgb(223, 240, 216)` -Orange: `#FDC894` / `rgb(253, 200, 148)` -Red: `#EF9090` / `rgb(239, 144, 144)` +Blue: `#D8EAF0` / `rgb(216, 234, 240)` +Gray: `#DFDFDF` / `rgb(223, 223, 223)` +Green: `#DFF0D8` / `rgb(223, 240, 216)` +Orange: `#FDC894` / `rgb(253, 200, 148)` +Red: `#EF9090` / `rgb(239, 144, 144)` From 8721abd5728c8b4ab0cdf7b3825773240573654f Mon Sep 17 00:00:00 2001 From: "John Paul E. Balandan, CPA" Date: Thu, 24 Feb 2022 10:59:45 +0800 Subject: [PATCH 0548/1246] Fix formatting --- system/Debug/Toolbar/Views/toolbar.css | 1211 ++++++++++++++---------- 1 file changed, 687 insertions(+), 524 deletions(-) diff --git a/system/Debug/Toolbar/Views/toolbar.css b/system/Debug/Toolbar/Views/toolbar.css index f160dba91f29..8fb9c15737c5 100644 --- a/system/Debug/Toolbar/Views/toolbar.css +++ b/system/Debug/Toolbar/Views/toolbar.css @@ -16,16 +16,20 @@ margin: 0px; padding: 0px; clear: both; - text-align: center; } - #debug-icon a svg { - margin: 8px; - max-width: 20px; - max-height: 20px; } - #debug-icon.fixed-top { - bottom: auto; - top: 0; } - #debug-icon .debug-bar-ndisplay { - display: none; } + text-align: center; +} +#debug-icon a svg { + margin: 8px; + max-width: 20px; + max-height: 20px; +} +#debug-icon.fixed-top { + bottom: auto; + top: 0; +} +#debug-icon .debug-bar-ndisplay { + display: none; +} #debug-bar { bottom: 0; @@ -37,199 +41,250 @@ line-height: 36px; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; - font-weight: 400; } - #debug-bar h1 { - display: flex; - font-weight: normal; - margin: 0 0 0 auto; } - #debug-bar h1 svg { - width: 16px; - margin-right: 5px; } - #debug-bar h2 { - font-size: 16px; - margin: 0; - padding: 5px 0 10px 0; } - #debug-bar h2 span { - font-size: 13px; } - #debug-bar h3 { - font-size: 12px; - font-weight: 200; - margin: 0 0 0 10px; - padding: 0; - text-transform: uppercase; } - #debug-bar p { - font-size: 12px; - margin: 0 0 0 15px; - padding: 0; } - #debug-bar a { - text-decoration: none; } - #debug-bar a:hover { - text-decoration: underline; } - #debug-bar button { - border: 1px solid; - border-radius: 4px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - cursor: pointer; - line-height: 15px; } - #debug-bar button:hover { - text-decoration: underline; } - #debug-bar table { - border-collapse: collapse; - font-size: 14px; - line-height: normal; - margin: 5px 10px 15px 10px; - width: calc(100% - 10px); } - #debug-bar table strong { - font-weight: 500; } - #debug-bar table th { - display: table-cell; - font-weight: 600; - padding-bottom: 0.7em; - text-align: left; } - #debug-bar table tr { - border: none; } - #debug-bar table td { - border: none; - display: table-cell; - margin: 0; - text-align: left; } - #debug-bar table td:first-child { - max-width: 20%; } - #debug-bar table td:first-child.narrow { - width: 7em; } - #debug-bar td[data-debugbar-route] form { - display: none; } - #debug-bar td[data-debugbar-route]:hover form { - display: block; } - #debug-bar td[data-debugbar-route]:hover > div { - display: none; } - #debug-bar td[data-debugbar-route] input[type=text] { - padding: 2px; } - #debug-bar .toolbar { - display: flex; - overflow: hidden; - overflow-y: auto; - padding: 0 12px 0 12px; - white-space: nowrap; - z-index: 10000; } - #debug-bar.fixed-top { - bottom: auto; - top: 0; } - #debug-bar.fixed-top .tab { - bottom: auto; - top: 36px; } - #debug-bar #toolbar-position a, - #debug-bar #toolbar-theme a { - padding: 0 6px; - display: inline-flex; - vertical-align: top; } - #debug-bar #toolbar-position a:hover, - #debug-bar #toolbar-theme a:hover { - text-decoration: none; } - #debug-bar #debug-bar-link { - padding: 6px; - display: flex; } - #debug-bar .ci-label { - display: inline-flex; - font-size: 14px; } - #debug-bar .ci-label:hover { - cursor: pointer; } - #debug-bar .ci-label a { - color: inherit; - display: flex; - letter-spacing: normal; - padding: 0 10px; - text-decoration: none; - align-items: center; } - #debug-bar .ci-label img { - margin: 6px 3px 6px 0; - width: 16px !important; } - #debug-bar .ci-label .badge { - border-radius: 12px; - -moz-border-radius: 12px; - -webkit-border-radius: 12px; - display: inline-block; - font-size: 75%; - font-weight: bold; - line-height: 12px; - margin-left: 5px; - padding: 2px 5px; - text-align: center; - vertical-align: baseline; - white-space: nowrap; } - #debug-bar .tab { - bottom: 35px; - display: none; - left: 0; - max-height: 62%; - overflow: hidden; - overflow-y: auto; - padding: 1em 2em; - position: fixed; - right: 0; - z-index: 9999; } - #debug-bar .timeline { - margin-left: 0; - width: 100%; } - #debug-bar .timeline th { - border-left: 1px solid; - font-size: 12px; - font-weight: 200; - padding: 5px 5px 10px 5px; - position: relative; - text-align: left; } - #debug-bar .timeline th:first-child { - border-left: 0; } - #debug-bar .timeline td { - border-left: 1px solid; - padding: 5px; - position: relative; } - #debug-bar .timeline td:first-child { - border-left: 0; - max-width: none; } - #debug-bar .timeline td.child-container { - padding: 0px; } - #debug-bar .timeline td.child-container .timeline { - margin: 0px; } - #debug-bar .timeline td.child-container .timeline td:first-child:not(.child-container) { - padding-left: calc(5px + 10px * var(--level)); } - #debug-bar .timeline .timer { - border-radius: 4px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - display: inline-block; - padding: 5px; - position: absolute; - top: 30%; } - #debug-bar .timeline .timeline-parent { - cursor: pointer; } - #debug-bar .timeline .timeline-parent td:first-child nav { - background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMCAxNTAiPjxwYXRoIGQ9Ik02IDdoMThsLTkgMTV6bTAgMzBoMThsLTkgMTV6bTAgNDVoMThsLTktMTV6bTAgMzBoMThsLTktMTV6bTAgMTJsMTggMThtLTE4IDBsMTgtMTgiIGZpbGw9IiM1NTUiLz48cGF0aCBkPSJNNiAxMjZsMTggMThtLTE4IDBsMTgtMTgiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlPSIjNTU1Ii8+PC9zdmc+") no-repeat scroll 0 0/15px 75px transparent; - background-position: 0 25%; - display: inline-block; - height: 15px; - width: 15px; - margin-right: 3px; - vertical-align: middle; } - #debug-bar .timeline .timeline-parent-open { - background-color: #DFDFDF; } - #debug-bar .timeline .timeline-parent-open td:first-child nav { - background-position: 0 75%; } - #debug-bar .timeline .child-row:hover { - background: transparent; } - #debug-bar .route-params, - #debug-bar .route-params-item { - vertical-align: top; } - #debug-bar .route-params td:first-child, - #debug-bar .route-params-item td:first-child { - font-style: italic; - padding-left: 1em; - text-align: right; } + font-weight: 400; +} +#debug-bar h1 { + display: flex; + font-weight: normal; + margin: 0 0 0 auto; +} +#debug-bar h1 svg { + width: 16px; + margin-right: 5px; +} +#debug-bar h2 { + font-size: 16px; + margin: 0; + padding: 5px 0 10px 0; +} +#debug-bar h2 span { + font-size: 13px; +} +#debug-bar h3 { + font-size: 12px; + font-weight: 200; + margin: 0 0 0 10px; + padding: 0; + text-transform: uppercase; +} +#debug-bar p { + font-size: 12px; + margin: 0 0 0 15px; + padding: 0; +} +#debug-bar a { + text-decoration: none; +} +#debug-bar a:hover { + text-decoration: underline; +} +#debug-bar button { + border: 1px solid; + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + cursor: pointer; + line-height: 15px; +} +#debug-bar button:hover { + text-decoration: underline; +} +#debug-bar table { + border-collapse: collapse; + font-size: 14px; + line-height: normal; + margin: 5px 10px 15px 10px; + width: calc(100% - 10px); +} +#debug-bar table strong { + font-weight: 500; +} +#debug-bar table th { + display: table-cell; + font-weight: 600; + padding-bottom: 0.7em; + text-align: left; +} +#debug-bar table tr { + border: none; +} +#debug-bar table td { + border: none; + display: table-cell; + margin: 0; + text-align: left; +} +#debug-bar table td:first-child { + max-width: 20%; +} +#debug-bar table td:first-child.narrow { + width: 7em; +} +#debug-bar td[data-debugbar-route] form { + display: none; +} +#debug-bar td[data-debugbar-route]:hover form { + display: block; +} +#debug-bar td[data-debugbar-route]:hover > div { + display: none; +} +#debug-bar td[data-debugbar-route] input[type=text] { + padding: 2px; +} +#debug-bar .toolbar { + display: flex; + overflow: hidden; + overflow-y: auto; + padding: 0 12px 0 12px; + white-space: nowrap; + z-index: 10000; +} +#debug-bar.fixed-top { + bottom: auto; + top: 0; +} +#debug-bar.fixed-top .tab { + bottom: auto; + top: 36px; +} +#debug-bar #toolbar-position a, +#debug-bar #toolbar-theme a { + padding: 0 6px; + display: inline-flex; + vertical-align: top; +} +#debug-bar #toolbar-position a:hover, +#debug-bar #toolbar-theme a:hover { + text-decoration: none; +} +#debug-bar #debug-bar-link { + display: flex; + padding: 6px; +} +#debug-bar .ci-label { + display: inline-flex; + font-size: 14px; +} +#debug-bar .ci-label:hover { + cursor: pointer; +} +#debug-bar .ci-label a { + color: inherit; + display: flex; + letter-spacing: normal; + padding: 0 10px; + text-decoration: none; + align-items: center; +} +#debug-bar .ci-label img { + margin: 6px 3px 6px 0; + width: 16px !important; +} +#debug-bar .ci-label .badge { + border-radius: 12px; + -moz-border-radius: 12px; + -webkit-border-radius: 12px; + display: inline-block; + font-size: 75%; + font-weight: bold; + line-height: 12px; + margin-left: 5px; + padding: 2px 5px; + text-align: center; + vertical-align: baseline; + white-space: nowrap; +} +#debug-bar .tab { + bottom: 35px; + display: none; + left: 0; + max-height: 62%; + overflow: hidden; + overflow-y: auto; + padding: 1em 2em; + position: fixed; + right: 0; + z-index: 9999; +} +#debug-bar .timeline { + margin-left: 0; + width: 100%; +} +#debug-bar .timeline th { + border-left: 1px solid; + font-size: 12px; + font-weight: 200; + padding: 5px 5px 10px 5px; + position: relative; + text-align: left; +} +#debug-bar .timeline th:first-child { + border-left: 0; +} +#debug-bar .timeline td { + border-left: 1px solid; + padding: 5px; + position: relative; +} +#debug-bar .timeline td:first-child { + border-left: 0; + max-width: none; +} +#debug-bar .timeline td.child-container { + padding: 0px; +} +#debug-bar .timeline td.child-container .timeline { + margin: 0px; +} +#debug-bar .timeline td.child-container .timeline td:first-child:not(.child-container) { + padding-left: calc(5px + 10px * var(--level)); +} +#debug-bar .timeline .timer { + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + display: inline-block; + padding: 5px; + position: absolute; + top: 30%; +} +#debug-bar .timeline .timeline-parent { + cursor: pointer; +} +#debug-bar .timeline .timeline-parent td:first-child nav { + background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMCAxNTAiPjxwYXRoIGQ9Ik02IDdoMThsLTkgMTV6bTAgMzBoMThsLTkgMTV6bTAgNDVoMThsLTktMTV6bTAgMzBoMThsLTktMTV6bTAgMTJsMTggMThtLTE4IDBsMTgtMTgiIGZpbGw9IiM1NTUiLz48cGF0aCBkPSJNNiAxMjZsMTggMThtLTE4IDBsMTgtMTgiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlPSIjNTU1Ii8+PC9zdmc+") no-repeat scroll 0 0/15px 75px transparent; + background-position: 0 25%; + display: inline-block; + height: 15px; + width: 15px; + margin-right: 3px; + vertical-align: middle; +} +#debug-bar .timeline .timeline-parent-open { + background-color: #DFDFDF; +} +#debug-bar .timeline .timeline-parent-open td:first-child nav { + background-position: 0 75%; +} +#debug-bar .timeline .child-row:hover { + background: transparent; +} +#debug-bar .route-params, +#debug-bar .route-params-item { + vertical-align: top; +} +#debug-bar .route-params td:first-child, +#debug-bar .route-params-item td:first-child { + font-style: italic; + padding-left: 1em; + text-align: right; +} .debug-view.show-view { border: 1px solid; - margin: 4px; } + margin: 4px; +} .debug-view-path { font-family: monospace; @@ -237,403 +292,511 @@ letter-spacing: normal; min-height: 16px; padding: 2px; - text-align: left; } + text-align: left; +} .show-view .debug-view-path { - display: block !important; } + display: block !important; +} @media screen and (max-width: 1024px) { #debug-bar .ci-label img { - margin: unset; } - .hide-sm { - display: none !important; } } + margin: unset; + } + .hide-sm { + display: none !important; + } +} #debug-icon { background-color: #FFFFFF; box-shadow: 0 0 4px #DFDFDF; -moz-box-shadow: 0 0 4px #DFDFDF; - -webkit-box-shadow: 0 0 4px #DFDFDF; } - #debug-icon a:active, - #debug-icon a:link, - #debug-icon a:visited { - color: #DD8615; } + -webkit-box-shadow: 0 0 4px #DFDFDF; +} +#debug-icon a:active, +#debug-icon a:link, +#debug-icon a:visited { + color: #DD8615; +} #debug-bar { background-color: #FFFFFF; - color: #434343; } + color: #434343; +} +#debug-bar h1, +#debug-bar h2, +#debug-bar h3, +#debug-bar p, +#debug-bar a, +#debug-bar button, +#debug-bar table, +#debug-bar thead, +#debug-bar tr, +#debug-bar td, +#debug-bar button, +#debug-bar .toolbar { + background-color: transparent; + color: #434343; +} +#debug-bar button { + background-color: #FFFFFF; +} +#debug-bar table strong { + color: #DD8615; +} +#debug-bar table tbody tr:hover { + background-color: #DFDFDF; +} +#debug-bar table tbody tr.current { + background-color: #FDC894; +} +#debug-bar table tbody tr.current:hover td { + background-color: #DD4814; + color: #FFFFFF; +} +#debug-bar .toolbar { + background-color: #FFFFFF; + box-shadow: 0 0 4px #DFDFDF; + -moz-box-shadow: 0 0 4px #DFDFDF; + -webkit-box-shadow: 0 0 4px #DFDFDF; +} +#debug-bar .toolbar img { + filter: brightness(0) invert(0.4); +} +#debug-bar.fixed-top .toolbar { + box-shadow: 0 0 4px #DFDFDF; + -moz-box-shadow: 0 0 4px #DFDFDF; + -webkit-box-shadow: 0 0 4px #DFDFDF; +} +#debug-bar.fixed-top .tab { + box-shadow: 0 1px 4px #DFDFDF; + -moz-box-shadow: 0 1px 4px #DFDFDF; + -webkit-box-shadow: 0 1px 4px #DFDFDF; +} +#debug-bar .muted { + color: #434343; +} +#debug-bar .muted td { + color: #DFDFDF; +} +#debug-bar .muted:hover td { + color: #434343; +} +#debug-bar #toolbar-position, +#debug-bar #toolbar-theme { + filter: brightness(0) invert(0.6); +} +#debug-bar .ci-label.active { + background-color: #DFDFDF; +} +#debug-bar .ci-label:hover { + background-color: #DFDFDF; +} +#debug-bar .ci-label .badge { + background-color: #DD4814; + color: #FFFFFF; +} +#debug-bar .tab { + background-color: #FFFFFF; + box-shadow: 0 -1px 4px #DFDFDF; + -moz-box-shadow: 0 -1px 4px #DFDFDF; + -webkit-box-shadow: 0 -1px 4px #DFDFDF; +} +#debug-bar .timeline th, +#debug-bar .timeline td { + border-color: #DFDFDF; +} +#debug-bar .timeline .timer { + background-color: #DD8615; +} + +.debug-view.show-view { + border-color: #DD8615; +} + +.debug-view-path { + background-color: #FDC894; + color: #434343; +} + +@media (prefers-color-scheme: dark) { + #debug-icon { + background-color: #252525; + box-shadow: 0 0 4px #DFDFDF; + -moz-box-shadow: 0 0 4px #DFDFDF; + -webkit-box-shadow: 0 0 4px #DFDFDF; + } + #debug-icon a:active, +#debug-icon a:link, +#debug-icon a:visited { + color: #DD8615; + } + + #debug-bar { + background-color: #252525; + color: #DFDFDF; + } #debug-bar h1, - #debug-bar h2, - #debug-bar h3, - #debug-bar p, - #debug-bar a, - #debug-bar button, - #debug-bar table, - #debug-bar thead, - #debug-bar tr, - #debug-bar td, - #debug-bar button, - #debug-bar .toolbar { +#debug-bar h2, +#debug-bar h3, +#debug-bar p, +#debug-bar a, +#debug-bar button, +#debug-bar table, +#debug-bar thead, +#debug-bar tr, +#debug-bar td, +#debug-bar button, +#debug-bar .toolbar { background-color: transparent; - color: #434343; } + color: #DFDFDF; + } #debug-bar button { - background-color: #FFFFFF; } + background-color: #252525; + } #debug-bar table strong { - color: #DD8615; } + color: #DD8615; + } #debug-bar table tbody tr:hover { - background-color: #DFDFDF; } + background-color: #434343; + } #debug-bar table tbody tr.current { - background-color: #FDC894; } - #debug-bar table tbody tr.current:hover td { - background-color: #DD4814; - color: #FFFFFF; } + background-color: #FDC894; + } + #debug-bar table tbody tr.current td { + color: #252525; + } + #debug-bar table tbody tr.current:hover td { + background-color: #DD4814; + color: #FFFFFF; + } #debug-bar .toolbar { - background-color: #FFFFFF; - box-shadow: 0 0 4px #DFDFDF; - -moz-box-shadow: 0 0 4px #DFDFDF; - -webkit-box-shadow: 0 0 4px #DFDFDF; } - #debug-bar .toolbar img { - filter: brightness(0) invert(0.4); } + background-color: #434343; + box-shadow: 0 0 4px #434343; + -moz-box-shadow: 0 0 4px #434343; + -webkit-box-shadow: 0 0 4px #434343; + } + #debug-bar .toolbar img { + filter: brightness(0) invert(1); + } #debug-bar.fixed-top .toolbar { - box-shadow: 0 0 4px #DFDFDF; - -moz-box-shadow: 0 0 4px #DFDFDF; - -webkit-box-shadow: 0 0 4px #DFDFDF; } + box-shadow: 0 0 4px #434343; + -moz-box-shadow: 0 0 4px #434343; + -webkit-box-shadow: 0 0 4px #434343; + } #debug-bar.fixed-top .tab { - box-shadow: 0 1px 4px #DFDFDF; - -moz-box-shadow: 0 1px 4px #DFDFDF; - -webkit-box-shadow: 0 1px 4px #DFDFDF; } + box-shadow: 0 1px 4px #434343; + -moz-box-shadow: 0 1px 4px #434343; + -webkit-box-shadow: 0 1px 4px #434343; + } #debug-bar .muted { - color: #434343; } - #debug-bar .muted td { - color: #DFDFDF; } - #debug-bar .muted:hover td { - color: #434343; } + color: #DFDFDF; + } + #debug-bar .muted td { + color: #434343; + } + #debug-bar .muted:hover td { + color: #DFDFDF; + } #debug-bar #toolbar-position, - #debug-bar #toolbar-theme { - filter: brightness(0) invert(0.6); } +#debug-bar #toolbar-theme { + filter: brightness(0) invert(0.6); + } #debug-bar .ci-label.active { - background-color: #DFDFDF; } + background-color: #252525; + } #debug-bar .ci-label:hover { - background-color: #DFDFDF; } + background-color: #252525; + } #debug-bar .ci-label .badge { background-color: #DD4814; - color: #FFFFFF; } + color: #FFFFFF; + } #debug-bar .tab { - background-color: #FFFFFF; - box-shadow: 0 -1px 4px #DFDFDF; - -moz-box-shadow: 0 -1px 4px #DFDFDF; - -webkit-box-shadow: 0 -1px 4px #DFDFDF; } + background-color: #252525; + box-shadow: 0 -1px 4px #434343; + -moz-box-shadow: 0 -1px 4px #434343; + -webkit-box-shadow: 0 -1px 4px #434343; + } #debug-bar .timeline th, - #debug-bar .timeline td { - border-color: #DFDFDF; } +#debug-bar .timeline td { + border-color: #434343; + } #debug-bar .timeline .timer { - background-color: #DD8615; } - -.debug-view.show-view { - border-color: #DD8615; } -#debug-bar tr[data-toggle] { - cursor: pointer; } + background-color: #DD8615; + } -.debug-view-path { - background-color: #FDC894; - color: #434343; } - -@media (prefers-color-scheme: dark) { - #debug-icon { - background-color: #252525; - box-shadow: 0 0 4px #DFDFDF; - -moz-box-shadow: 0 0 4px #DFDFDF; - -webkit-box-shadow: 0 0 4px #DFDFDF; } - #debug-icon a:active, - #debug-icon a:link, - #debug-icon a:visited { - color: #DD8615; } - #debug-bar { - background-color: #252525; - color: #DFDFDF; } - #debug-bar h1, - #debug-bar h2, - #debug-bar h3, - #debug-bar p, - #debug-bar a, - #debug-bar button, - #debug-bar table, - #debug-bar thead, - #debug-bar tr, - #debug-bar td, - #debug-bar button, - #debug-bar .toolbar { - background-color: transparent; - color: #DFDFDF; } - #debug-bar button { - background-color: #252525; } - #debug-bar table strong { - color: #DD8615; } - #debug-bar table tbody tr:hover { - background-color: #434343; } - #debug-bar table tbody tr.current { - background-color: #FDC894; } - #debug-bar table tbody tr.current td { - color: #252525; } - #debug-bar table tbody tr.current:hover td { - background-color: #DD4814; - color: #FFFFFF; } - #debug-bar .toolbar { - background-color: #434343; - box-shadow: 0 0 4px #434343; - -moz-box-shadow: 0 0 4px #434343; - -webkit-box-shadow: 0 0 4px #434343; } - #debug-bar .toolbar img { - filter: brightness(0) invert(1); } - #debug-bar.fixed-top .toolbar { - box-shadow: 0 0 4px #434343; - -moz-box-shadow: 0 0 4px #434343; - -webkit-box-shadow: 0 0 4px #434343; } - #debug-bar.fixed-top .tab { - box-shadow: 0 1px 4px #434343; - -moz-box-shadow: 0 1px 4px #434343; - -webkit-box-shadow: 0 1px 4px #434343; } - #debug-bar .muted { - color: #DFDFDF; } - #debug-bar .muted td { - color: #797979; } - #debug-bar .muted:hover td { - color: #DFDFDF; } - #debug-bar #toolbar-position, - #debug-bar #toolbar-theme { - filter: brightness(0) invert(0.6); } - #debug-bar .ci-label.active { - background-color: #252525; } - #debug-bar .ci-label:hover { - background-color: #252525; } - #debug-bar .ci-label .badge { - background-color: #DD4814; - color: #FFFFFF; } - #debug-bar .tab { - background-color: #252525; - box-shadow: 0 -1px 4px #434343; - -moz-box-shadow: 0 -1px 4px #434343; - -webkit-box-shadow: 0 -1px 4px #434343; } - #debug-bar .timeline th, - #debug-bar .timeline td { - border-color: #434343; } - #debug-bar .timeline .timer { - background-color: #DD8615; } .debug-view.show-view { - border-color: #DD8615; } + border-color: #DD8615; + } + .debug-view-path { background-color: #FDC894; - color: #434343; } } - + color: #434343; + } +} #toolbarContainer.dark #debug-icon { background-color: #252525; box-shadow: 0 0 4px #DFDFDF; -moz-box-shadow: 0 0 4px #DFDFDF; - -webkit-box-shadow: 0 0 4px #DFDFDF; } - #toolbarContainer.dark #debug-icon a:active, - #toolbarContainer.dark #debug-icon a:link, - #toolbarContainer.dark #debug-icon a:visited { - color: #DD8615; } - + -webkit-box-shadow: 0 0 4px #DFDFDF; +} +#toolbarContainer.dark #debug-icon a:active, +#toolbarContainer.dark #debug-icon a:link, +#toolbarContainer.dark #debug-icon a:visited { + color: #DD8615; +} #toolbarContainer.dark #debug-bar { background-color: #252525; - color: #DFDFDF; } - #toolbarContainer.dark #debug-bar h1, - #toolbarContainer.dark #debug-bar h2, - #toolbarContainer.dark #debug-bar h3, - #toolbarContainer.dark #debug-bar p, - #toolbarContainer.dark #debug-bar a, - #toolbarContainer.dark #debug-bar button, - #toolbarContainer.dark #debug-bar table, - #toolbarContainer.dark #debug-bar thead, - #toolbarContainer.dark #debug-bar tr, - #toolbarContainer.dark #debug-bar td, - #toolbarContainer.dark #debug-bar button, - #toolbarContainer.dark #debug-bar .toolbar { - background-color: transparent; - color: #DFDFDF; } - #toolbarContainer.dark #debug-bar button { - background-color: #252525; } - #toolbarContainer.dark #debug-bar table strong { - color: #DD8615; } - #toolbarContainer.dark #debug-bar table tbody tr:hover { - background-color: #434343; } - #toolbarContainer.dark #debug-bar table tbody tr.current { - background-color: #FDC894; } - #toolbarContainer.dark #ci-database table tbody tr.duplicate { - background-color: #434343;} - #toolbarContainer.dark #debug-bar table tbody tr.current td { - color: #252525; } - #toolbarContainer.dark #debug-bar table tbody tr.current:hover td { - background-color: #DD4814; - color: #FFFFFF; } - #toolbarContainer.dark #debug-bar .toolbar { - background-color: #434343; - box-shadow: 0 0 4px #434343; - -moz-box-shadow: 0 0 4px #434343; - -webkit-box-shadow: 0 0 4px #434343; } - #toolbarContainer.dark #debug-bar .toolbar img { - filter: brightness(0) invert(1); } - #toolbarContainer.dark #debug-bar.fixed-top .toolbar { - box-shadow: 0 0 4px #434343; - -moz-box-shadow: 0 0 4px #434343; - -webkit-box-shadow: 0 0 4px #434343; } - #toolbarContainer.dark #debug-bar.fixed-top .tab { - box-shadow: 0 1px 4px #434343; - -moz-box-shadow: 0 1px 4px #434343; - -webkit-box-shadow: 0 1px 4px #434343; } - #toolbarContainer.dark #debug-bar .muted { - color: #DFDFDF; } - #toolbarContainer.dark #debug-bar .muted td { - color: #797979; } - #toolbarContainer.dark #debug-bar .muted:hover td { - color: #DFDFDF; } - #toolbarContainer.dark #debug-bar #toolbar-position, - #toolbarContainer.dark #debug-bar #toolbar-theme { - filter: brightness(0) invert(0.6); } - #toolbarContainer.dark #debug-bar .ci-label.active { - background-color: #252525; } - #toolbarContainer.dark #debug-bar .ci-label:hover { - background-color: #252525; } - #toolbarContainer.dark #debug-bar .ci-label .badge { - background-color: #DD4814; - color: #FFFFFF; } - #toolbarContainer.dark #debug-bar .tab { - background-color: #252525; - box-shadow: 0 -1px 4px #434343; - -moz-box-shadow: 0 -1px 4px #434343; - -webkit-box-shadow: 0 -1px 4px #434343; } - #toolbarContainer.dark #debug-bar .timeline th, - #toolbarContainer.dark #debug-bar .timeline td { - border-color: #434343; } - #toolbarContainer.dark #debug-bar .timeline .timer { - background-color: #DD8615; } - + color: #DFDFDF; +} +#toolbarContainer.dark #debug-bar h1, +#toolbarContainer.dark #debug-bar h2, +#toolbarContainer.dark #debug-bar h3, +#toolbarContainer.dark #debug-bar p, +#toolbarContainer.dark #debug-bar a, +#toolbarContainer.dark #debug-bar button, +#toolbarContainer.dark #debug-bar table, +#toolbarContainer.dark #debug-bar thead, +#toolbarContainer.dark #debug-bar tr, +#toolbarContainer.dark #debug-bar td, +#toolbarContainer.dark #debug-bar button, +#toolbarContainer.dark #debug-bar .toolbar { + background-color: transparent; + color: #DFDFDF; +} +#toolbarContainer.dark #debug-bar button { + background-color: #252525; +} +#toolbarContainer.dark #debug-bar table strong { + color: #DD8615; +} +#toolbarContainer.dark #debug-bar table tbody tr:hover { + background-color: #434343; +} +#toolbarContainer.dark #debug-bar table tbody tr.current { + background-color: #FDC894; +} +#toolbarContainer.dark #debug-bar table tbody tr.current td { + color: #252525; +} +#toolbarContainer.dark #debug-bar table tbody tr.current:hover td { + background-color: #DD4814; + color: #FFFFFF; +} +#toolbarContainer.dark #debug-bar .toolbar { + background-color: #434343; + box-shadow: 0 0 4px #434343; + -moz-box-shadow: 0 0 4px #434343; + -webkit-box-shadow: 0 0 4px #434343; +} +#toolbarContainer.dark #debug-bar .toolbar img { + filter: brightness(0) invert(1); +} +#toolbarContainer.dark #debug-bar.fixed-top .toolbar { + box-shadow: 0 0 4px #434343; + -moz-box-shadow: 0 0 4px #434343; + -webkit-box-shadow: 0 0 4px #434343; +} +#toolbarContainer.dark #debug-bar.fixed-top .tab { + box-shadow: 0 1px 4px #434343; + -moz-box-shadow: 0 1px 4px #434343; + -webkit-box-shadow: 0 1px 4px #434343; +} +#toolbarContainer.dark #debug-bar .muted { + color: #DFDFDF; +} +#toolbarContainer.dark #debug-bar .muted td { + color: #434343; +} +#toolbarContainer.dark #debug-bar .muted:hover td { + color: #DFDFDF; +} +#toolbarContainer.dark #debug-bar #toolbar-position, +#toolbarContainer.dark #debug-bar #toolbar-theme { + filter: brightness(0) invert(0.6); +} +#toolbarContainer.dark #debug-bar .ci-label.active { + background-color: #252525; +} +#toolbarContainer.dark #debug-bar .ci-label:hover { + background-color: #252525; +} +#toolbarContainer.dark #debug-bar .ci-label .badge { + background-color: #DD4814; + color: #FFFFFF; +} +#toolbarContainer.dark #debug-bar .tab { + background-color: #252525; + box-shadow: 0 -1px 4px #434343; + -moz-box-shadow: 0 -1px 4px #434343; + -webkit-box-shadow: 0 -1px 4px #434343; +} +#toolbarContainer.dark #debug-bar .timeline th, +#toolbarContainer.dark #debug-bar .timeline td { + border-color: #434343; +} +#toolbarContainer.dark #debug-bar .timeline .timer { + background-color: #DD8615; +} #toolbarContainer.dark .debug-view.show-view { - border-color: #DD8615; } - + border-color: #DD8615; +} #toolbarContainer.dark .debug-view-path { background-color: #FDC894; - color: #434343; } - + color: #434343; +} #toolbarContainer.dark td[data-debugbar-route] input[type=text] { background: #000; - color: #fff; } + color: #fff; +} #toolbarContainer.light #debug-icon { background-color: #FFFFFF; box-shadow: 0 0 4px #DFDFDF; -moz-box-shadow: 0 0 4px #DFDFDF; - -webkit-box-shadow: 0 0 4px #DFDFDF; } - #toolbarContainer.light #debug-icon a:active, - #toolbarContainer.light #debug-icon a:link, - #toolbarContainer.light #debug-icon a:visited { - color: #DD8615; } - + -webkit-box-shadow: 0 0 4px #DFDFDF; +} +#toolbarContainer.light #debug-icon a:active, +#toolbarContainer.light #debug-icon a:link, +#toolbarContainer.light #debug-icon a:visited { + color: #DD8615; +} #toolbarContainer.light #debug-bar { background-color: #FFFFFF; - color: #434343; } - #toolbarContainer.light #debug-bar h1, - #toolbarContainer.light #debug-bar h2, - #toolbarContainer.light #debug-bar h3, - #toolbarContainer.light #debug-bar p, - #toolbarContainer.light #debug-bar a, - #toolbarContainer.light #debug-bar button, - #toolbarContainer.light #debug-bar table, - #toolbarContainer.light #debug-bar thead, - #toolbarContainer.light #debug-bar tr, - #toolbarContainer.light #debug-bar td, - #toolbarContainer.light #debug-bar button, - #toolbarContainer.light #debug-bar .toolbar { - background-color: transparent; - color: #434343; } - #toolbarContainer.light #debug-bar button { - background-color: #FFFFFF; } - #toolbarContainer.light #debug-bar table strong { - color: #DD8615; } - #toolbarContainer.light #debug-bar table tbody tr:hover { - background-color: #DFDFDF; } - #toolbarContainer.light #debug-bar table tbody tr.current { - background-color: #FDC894; } - #toolbarContainer.light #ci-database table tbody tr.duplicate { - background-color: #DFDFDF;} - #toolbarContainer.light #debug-bar table tbody tr.current:hover td { - background-color: #DD4814; - color: #FFFFFF; } - #toolbarContainer.light #debug-bar .toolbar { - background-color: #FFFFFF; - box-shadow: 0 0 4px #DFDFDF; - -moz-box-shadow: 0 0 4px #DFDFDF; - -webkit-box-shadow: 0 0 4px #DFDFDF; } - #toolbarContainer.light #debug-bar .toolbar img { - filter: brightness(0) invert(0.4); } - #toolbarContainer.light #debug-bar.fixed-top .toolbar { - box-shadow: 0 0 4px #DFDFDF; - -moz-box-shadow: 0 0 4px #DFDFDF; - -webkit-box-shadow: 0 0 4px #DFDFDF; } - #toolbarContainer.light #debug-bar.fixed-top .tab { - box-shadow: 0 1px 4px #DFDFDF; - -moz-box-shadow: 0 1px 4px #DFDFDF; - -webkit-box-shadow: 0 1px 4px #DFDFDF; } - #toolbarContainer.light #debug-bar .muted { - color: #797979; } - #toolbarContainer.light #debug-bar .muted td { - color: #797979; } - #toolbarContainer.light #debug-bar .muted:hover td { - color: #434343; } - #toolbarContainer.light #debug-bar #toolbar-position, - #toolbarContainer.light #debug-bar #toolbar-theme { - filter: brightness(0) invert(0.6); } - #toolbarContainer.light #debug-bar .ci-label.active { - background-color: #DFDFDF; } - #toolbarContainer.light #debug-bar .ci-label:hover { - background-color: #DFDFDF; } - #toolbarContainer.light #debug-bar .ci-label .badge { - background-color: #DD4814; - color: #FFFFFF; } - #toolbarContainer.light #debug-bar .tab { - background-color: #FFFFFF; - box-shadow: 0 -1px 4px #DFDFDF; - -moz-box-shadow: 0 -1px 4px #DFDFDF; - -webkit-box-shadow: 0 -1px 4px #DFDFDF; } - #toolbarContainer.light #debug-bar .timeline th, - #toolbarContainer.light #debug-bar .timeline td { - border-color: #DFDFDF; } - #toolbarContainer.light #debug-bar .timeline .timer { - background-color: #DD8615; } - + color: #434343; +} +#toolbarContainer.light #debug-bar h1, +#toolbarContainer.light #debug-bar h2, +#toolbarContainer.light #debug-bar h3, +#toolbarContainer.light #debug-bar p, +#toolbarContainer.light #debug-bar a, +#toolbarContainer.light #debug-bar button, +#toolbarContainer.light #debug-bar table, +#toolbarContainer.light #debug-bar thead, +#toolbarContainer.light #debug-bar tr, +#toolbarContainer.light #debug-bar td, +#toolbarContainer.light #debug-bar button, +#toolbarContainer.light #debug-bar .toolbar { + background-color: transparent; + color: #434343; +} +#toolbarContainer.light #debug-bar button { + background-color: #FFFFFF; +} +#toolbarContainer.light #debug-bar table strong { + color: #DD8615; +} +#toolbarContainer.light #debug-bar table tbody tr:hover { + background-color: #DFDFDF; +} +#toolbarContainer.light #debug-bar table tbody tr.current { + background-color: #FDC894; +} +#toolbarContainer.light #debug-bar table tbody tr.current:hover td { + background-color: #DD4814; + color: #FFFFFF; +} +#toolbarContainer.light #debug-bar .toolbar { + background-color: #FFFFFF; + box-shadow: 0 0 4px #DFDFDF; + -moz-box-shadow: 0 0 4px #DFDFDF; + -webkit-box-shadow: 0 0 4px #DFDFDF; +} +#toolbarContainer.light #debug-bar .toolbar img { + filter: brightness(0) invert(0.4); +} +#toolbarContainer.light #debug-bar.fixed-top .toolbar { + box-shadow: 0 0 4px #DFDFDF; + -moz-box-shadow: 0 0 4px #DFDFDF; + -webkit-box-shadow: 0 0 4px #DFDFDF; +} +#toolbarContainer.light #debug-bar.fixed-top .tab { + box-shadow: 0 1px 4px #DFDFDF; + -moz-box-shadow: 0 1px 4px #DFDFDF; + -webkit-box-shadow: 0 1px 4px #DFDFDF; +} +#toolbarContainer.light #debug-bar .muted { + color: #434343; +} +#toolbarContainer.light #debug-bar .muted td { + color: #DFDFDF; +} +#toolbarContainer.light #debug-bar .muted:hover td { + color: #434343; +} +#toolbarContainer.light #debug-bar #toolbar-position, +#toolbarContainer.light #debug-bar #toolbar-theme { + filter: brightness(0) invert(0.6); +} +#toolbarContainer.light #debug-bar .ci-label.active { + background-color: #DFDFDF; +} +#toolbarContainer.light #debug-bar .ci-label:hover { + background-color: #DFDFDF; +} +#toolbarContainer.light #debug-bar .ci-label .badge { + background-color: #DD4814; + color: #FFFFFF; +} +#toolbarContainer.light #debug-bar .tab { + background-color: #FFFFFF; + box-shadow: 0 -1px 4px #DFDFDF; + -moz-box-shadow: 0 -1px 4px #DFDFDF; + -webkit-box-shadow: 0 -1px 4px #DFDFDF; +} +#toolbarContainer.light #debug-bar .timeline th, +#toolbarContainer.light #debug-bar .timeline td { + border-color: #DFDFDF; +} +#toolbarContainer.light #debug-bar .timeline .timer { + background-color: #DD8615; +} #toolbarContainer.light .debug-view.show-view { - border-color: #DD8615; } - + border-color: #DD8615; +} #toolbarContainer.light .debug-view-path { background-color: #FDC894; - color: #434343; } + color: #434343; +} .debug-bar-width30 { - width: 30%; } + width: 30%; +} .debug-bar-width10 { - width: 10%; } + width: 10%; +} .debug-bar-width70p { - width: 70px; } + width: 70px; +} .debug-bar-width140p { - width: 140px; } + width: 140px; +} .debug-bar-width20e { - width: 20em; } + width: 20em; +} .debug-bar-width6r { - width: 6rem; } + width: 6rem; +} .debug-bar-ndisplay { - display: none; } + display: none; +} .debug-bar-alignRight { - text-align: right; } + text-align: right; +} .debug-bar-alignLeft { - text-align: left; } + text-align: left; +} .debug-bar-noverflow { - overflow: hidden; } + overflow: hidden; +} From 950d45bf22d0934cc6a3d57250159f4a13512de0 Mon Sep 17 00:00:00 2001 From: Andrey Pyzhikov <5071@mail.ru> Date: Thu, 24 Feb 2022 11:40:01 +0800 Subject: [PATCH 0549/1246] Nonce generation optimization. Signed-off-by: Andrey Pyzhikov <5071@mail.ru> --- system/HTTP/ContentSecurityPolicy.php | 16 +++++----------- tests/system/HTTP/ContentSecurityPolicyTest.php | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/system/HTTP/ContentSecurityPolicy.php b/system/HTTP/ContentSecurityPolicy.php index b7f9b066d7d8..a2d3ec6f0a24 100644 --- a/system/HTTP/ContentSecurityPolicy.php +++ b/system/HTTP/ContentSecurityPolicy.php @@ -671,18 +671,12 @@ protected function generateNonces(ResponseInterface &$response) return; } - // Replace style placeholders with nonces - $pattern = '/' . preg_quote($this->styleNonceTag, '/') . '/'; - $body = preg_replace_callback($pattern, function () { - $nonce = $this->getStyleNonce(); + // Replace style and script placeholders with nonces + $pattern = '/(' . preg_quote($this->styleNonceTag, '/') + . '|' . preg_quote($this->scriptNonceTag, '/') . ')/'; - return "nonce=\"{$nonce}\""; - }, $body); - - // Replace script placeholders with nonces - $pattern = '/' . preg_quote($this->scriptNonceTag, '/') . '/'; - $body = preg_replace_callback($pattern, function () { - $nonce = $this->getScriptNonce(); + $body = preg_replace_callback($pattern, function ($match) { + $nonce = $match[0] === $this->styleNonceTag ? $this->getStyleNonce() : $this->getScriptNonce(); return "nonce=\"{$nonce}\""; }, $body); diff --git a/tests/system/HTTP/ContentSecurityPolicyTest.php b/tests/system/HTTP/ContentSecurityPolicyTest.php index 2ab6ee747d91..d2113e28e366 100644 --- a/tests/system/HTTP/ContentSecurityPolicyTest.php +++ b/tests/system/HTTP/ContentSecurityPolicyTest.php @@ -459,11 +459,16 @@ public function testBodyScriptNonce() $this->response->setBody($body); $this->csp->addScriptSrc('cdn.cloudy.com'); - $result = $this->work($body); + $result = $this->work($body); + $nonceStyle = array_filter( + $this->getPrivateProperty($this->csp, 'styleSrc'), + static fn ($value) => strpos($value, 'nonce-') === 0 + ); $this->assertStringContainsString('nonce=', $this->response->getBody()); $result = $this->getHeaderEmitted('Content-Security-Policy'); $this->assertStringContainsString('nonce-', $result); + $this->assertSame([], $nonceStyle); } public function testBodyScriptNonceCustomScriptTag() @@ -525,11 +530,16 @@ public function testBodyStyleNonce() $this->response->setBody($body); $this->csp->addStyleSrc('cdn.cloudy.com'); - $result = $this->work($body); + $result = $this->work($body); + $nonceScript = array_filter( + $this->getPrivateProperty($this->csp, 'scriptSrc'), + static fn ($value) => strpos($value, 'nonce-') === 0 + ); $this->assertStringContainsString('nonce=', $this->response->getBody()); $result = $this->getHeaderEmitted('Content-Security-Policy'); $this->assertStringContainsString('nonce-', $result); + $this->assertSame([], $nonceScript); } public function testBodyStyleNonceCustomStyleTag() From b7c26b68941e256462e443731993317ce8793645 Mon Sep 17 00:00:00 2001 From: kenjis Date: Thu, 24 Feb 2022 13:35:53 +0900 Subject: [PATCH 0550/1246] refactor: remove unneeded `&` references --- system/HTTP/ContentSecurityPolicy.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/system/HTTP/ContentSecurityPolicy.php b/system/HTTP/ContentSecurityPolicy.php index b7f9b066d7d8..0428431ed41d 100644 --- a/system/HTTP/ContentSecurityPolicy.php +++ b/system/HTTP/ContentSecurityPolicy.php @@ -298,7 +298,7 @@ public function getScriptNonce(): string * * Should be called just prior to sending the response to the user agent. */ - public function finalize(ResponseInterface &$response) + public function finalize(ResponseInterface $response) { if ($this->autoNonce === false) { return; @@ -663,7 +663,7 @@ protected function addOption($options, string $target, ?bool $explicitReporting * placeholders with actual nonces, that we'll then add to our * headers. */ - protected function generateNonces(ResponseInterface &$response) + protected function generateNonces(ResponseInterface $response) { $body = $response->getBody(); @@ -695,7 +695,7 @@ protected function generateNonces(ResponseInterface &$response) * Content-Security-Policy and Content-Security-Policy-Report-Only headers * with their values to the response object. */ - protected function buildHeaders(ResponseInterface &$response) + protected function buildHeaders(ResponseInterface $response) { /** * Ensure both headers are available and arrays... From 1541d0665ae3e29a8527e519f28dc294049e5539 Mon Sep 17 00:00:00 2001 From: Andrey Pyzhikov <5071@mail.ru> Date: Thu, 24 Feb 2022 13:22:49 +0800 Subject: [PATCH 0551/1246] Feature: Subquery for SELECT Signed-off-by: Andrey Pyzhikov <5071@mail.ru> --- system/Database/BaseBuilder.php | 16 ++++++++++++++++ tests/system/Database/Builder/SelectTest.php | 13 +++++++++++++ user_guide_src/source/changelogs/v4.2.0.rst | 1 + user_guide_src/source/database/query_builder.rst | 16 ++++++++++++++++ .../source/database/query_builder/098.php | 7 +++++++ 5 files changed, 53 insertions(+) create mode 100644 user_guide_src/source/database/query_builder/098.php diff --git a/system/Database/BaseBuilder.php b/system/Database/BaseBuilder.php index a3fc6c7563d3..92d35945565e 100644 --- a/system/Database/BaseBuilder.php +++ b/system/Database/BaseBuilder.php @@ -445,6 +445,22 @@ public function selectCount(string $select = '', string $alias = '') return $this->maxMinAvgSum($select, $alias, 'COUNT'); } + /** + * Adds a subquery to the selection + * + * @return static + */ + public function selectSubquery(BaseBuilder $subquery, string $as) + { + if (! $this->isSubquery($subquery)) { + throw new DatabaseException('The BaseBuilder::selectSubquery method expects a BaseBuilder instance'); + } + + $this->QBSelect[] = $this->buildSubquery($subquery, true, $as); + + return $this; + } + /** * SELECT [MAX|MIN|AVG|SUM|COUNT]() * diff --git a/tests/system/Database/Builder/SelectTest.php b/tests/system/Database/Builder/SelectTest.php index 7a9e7570221d..97460f0010da 100644 --- a/tests/system/Database/Builder/SelectTest.php +++ b/tests/system/Database/Builder/SelectTest.php @@ -246,4 +246,17 @@ public function testSimpleSelectWithSQLSRV() $this->assertSame($expected, str_replace("\n", ' ', $builder->getCompiledSelect())); } + + public function testSelectSubquery() + { + $builder = new BaseBuilder('users', $this->db); + $subquery = new BaseBuilder('countries', $this->db); + + $subquery->select('name')->where('id', 1); + $builder->select('name')->selectSubquery($subquery, 'country'); + + $expected = 'SELECT "name", (SELECT "name" FROM "countries" WHERE "id" = 1) AS "country" FROM "users"'; + + $this->assertSame($expected, str_replace("\n", ' ', $builder->getCompiledSelect())); + } } diff --git a/user_guide_src/source/changelogs/v4.2.0.rst b/user_guide_src/source/changelogs/v4.2.0.rst index f22ddae1aa17..a1660d8cf8ca 100644 --- a/user_guide_src/source/changelogs/v4.2.0.rst +++ b/user_guide_src/source/changelogs/v4.2.0.rst @@ -24,6 +24,7 @@ Enhancements - See :ref:`content-security-policy` for details. - New View Decorators allow modifying the generated HTML prior to caching. - Added Subqueries in the FROM section. See :ref:`query-builder-from-subquery`. +- Added Subqueries in the SELECT section. - Added Validation Strict Rules. See :ref:`validation-traditional-and-strict-rules`. - Added new OCI8 driver for database. - It can access Oracle Database and supports SQL and PL/SQL statements. diff --git a/user_guide_src/source/database/query_builder.rst b/user_guide_src/source/database/query_builder.rst index 1969620b63a8..0a1861e23810 100755 --- a/user_guide_src/source/database/query_builder.rst +++ b/user_guide_src/source/database/query_builder.rst @@ -167,6 +167,13 @@ the resulting field. .. literalinclude:: query_builder/014.php :lines: 2- +**$builder->selectSubquery()** + +Adds a subquery to the SELECT section. + +.. literalinclude:: query_builder/098.php + :lines: 2- + From ==== @@ -1066,6 +1073,15 @@ Class Reference Adds a ``SELECT COUNT(field)`` clause to a query. +.. php:method:: selectSubquery(BaseBuilder $subquery, string $as) + + :param string $subquery: Instance of BaseBuilder + :param string $as: Alias for the resulting value name + :returns: ``BaseBuilder`` instance (method chaining) + :rtype: ``BaseBuilder`` + + Adds a subquery to the selection + .. php:method:: distinct([$val = true]) :param bool $val: Desired value of the "distinct" flag diff --git a/user_guide_src/source/database/query_builder/098.php b/user_guide_src/source/database/query_builder/098.php new file mode 100644 index 000000000000..96d1d0d9025b --- /dev/null +++ b/user_guide_src/source/database/query_builder/098.php @@ -0,0 +1,7 @@ +table('countries')->select('name')->where('id', 1); +$builder = $db->table('users')->select('name')->selectSubquery($subquery, 'country'); +$query = $builder->get(); + +// Produces: SELECT `name`, (SELECT `name` FROM `countries` WHERE `id` = 1) AS `country` FROM `users` \ No newline at end of file From f668b8d91e646b5418193658d1c29d853f9a92ac Mon Sep 17 00:00:00 2001 From: "John Paul E. Balandan, CPA" Date: Thu, 24 Feb 2022 10:24:55 +0800 Subject: [PATCH 0552/1246] Limit running PHP workflows to related PHP files --- .github/workflows/test-deptrac.yml | 8 ++++---- .github/workflows/test-phpcpd.yml | 13 +++++++------ .github/workflows/test-phpstan.yml | 19 +++++++++++-------- .github/workflows/test-phpunit.yml | 13 +++++++++---- .github/workflows/test-rector.yml | 17 +++++++++-------- 5 files changed, 40 insertions(+), 30 deletions(-) diff --git a/.github/workflows/test-deptrac.yml b/.github/workflows/test-deptrac.yml index 52b58d51d5d8..262da202c02f 100644 --- a/.github/workflows/test-deptrac.yml +++ b/.github/workflows/test-deptrac.yml @@ -8,8 +8,8 @@ on: - 'develop' - 'v4.*' paths: - - 'app/**' - - 'system/**' + - 'app/**.php' + - 'system/**.php' - 'composer.json' - 'depfile.yaml' - '.github/workflows/test-deptrac.yml' @@ -18,8 +18,8 @@ on: - 'develop' - 'v4.*' paths: - - 'app/**' - - 'system/**' + - 'app/**.php' + - 'system/**.php' - 'composer.json' - 'depfile.yaml' - '.github/workflows/test-deptrac.yml' diff --git a/.github/workflows/test-phpcpd.yml b/.github/workflows/test-phpcpd.yml index 018acd11cbd2..6cfd76a054f1 100644 --- a/.github/workflows/test-phpcpd.yml +++ b/.github/workflows/test-phpcpd.yml @@ -8,18 +8,19 @@ on: - 'develop' - 'v4.*' paths: - - 'app/**' - - 'public/**' - - 'system/**' + - 'app/**.php' + - 'public/**.php' + - 'system/**.php' - '.github/workflows/test-phpcpd.yml' + push: branches: - 'develop' - 'v4.*' paths: - - 'app/**' - - 'public/**' - - 'system/**' + - 'app/**.php' + - 'public/**.php' + - 'system/**.php' - '.github/workflows/test-phpcpd.yml' jobs: diff --git a/.github/workflows/test-phpstan.yml b/.github/workflows/test-phpstan.yml index 6c0d40efa83a..d0235ec9beb6 100644 --- a/.github/workflows/test-phpstan.yml +++ b/.github/workflows/test-phpstan.yml @@ -8,21 +8,24 @@ on: - 'develop' - 'v4.*' paths: - - 'app/**' - - 'system/**' + - 'app/**.php' + - 'system/**.php' + - 'utils/**.php' - composer.json - - phpstan.neon.dist - - phpstan-baseline.neon.dist + - '**.neon.dist' + - '.github/workflows/test-phpstan.yml' + push: branches: - 'develop' - 'v4.*' paths: - - 'app/**' - - 'system/**' + - 'app/**.php' + - 'system/**.php' + - 'utils/**.php' - composer.json - - phpstan.neon.dist - - phpstan-baseline.neon.dist + - '**.neon.dist' + - '.github/workflows/test-phpstan.yml' jobs: build: diff --git a/.github/workflows/test-phpunit.yml b/.github/workflows/test-phpunit.yml index 1d788f9d86e1..964f9fcb3f72 100644 --- a/.github/workflows/test-phpunit.yml +++ b/.github/workflows/test-phpunit.yml @@ -5,20 +5,25 @@ on: branches: - develop paths: + - 'app/**.php' + - 'system/**.php' + - 'tests/**.php' + - 'spark' - composer.json - - spark - phpunit.xml.dist - - '**.php' - .github/workflows/test-phpunit.yml + pull_request: branches: - develop - 'v4.*' paths: + - 'app/**.php' + - 'system/**.php' + - 'tests/**.php' + - 'spark' - composer.json - - spark - phpunit.xml.dist - - '**.php' - .github/workflows/test-phpunit.yml jobs: diff --git a/.github/workflows/test-rector.yml b/.github/workflows/test-rector.yml index 03aa90f9bb8c..1282205c8bf6 100644 --- a/.github/workflows/test-rector.yml +++ b/.github/workflows/test-rector.yml @@ -8,23 +8,24 @@ on: - 'develop' - 'v4.*' paths: - - 'app/**' - - 'system/**' + - 'app/**.php' + - 'system/**.php' + - 'tests/**.php' + - 'utils/**.php' - '.github/workflows/test-rector.yml' - composer.json - - 'utils/Rector/**' - - 'rector.php' + push: branches: - 'develop' - 'v4.*' paths: - - 'app/**' - - 'system/**' + - 'app/**.php' + - 'system/**.php' + - 'tests/**.php' + - 'utils/**.php' - '.github/workflows/test-rector.yml' - composer.json - - 'utils/Rector/**' - - 'rector.php' jobs: build: From c49c8a60abb1f5876bac81162f408a6875a66882 Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Thu, 24 Feb 2022 08:29:44 +0100 Subject: [PATCH 0553/1246] Fix newlines. --- user_guide_src/source/helpers/text_helper/020.php | 2 +- user_guide_src/source/libraries/curlrequest/014.php | 2 +- user_guide_src/source/libraries/uploaded_files/006.php | 2 +- user_guide_src/source/outgoing/localization/008.php | 3 +-- user_guide_src/source/outgoing/response/026.php | 2 +- user_guide_src/source/testing/fabricator/005.php | 2 +- user_guide_src/source/testing/fabricator/006.php | 2 +- user_guide_src/source/testing/fabricator/021.php | 2 +- user_guide_src/source/testing/overview/007.php | 2 +- 9 files changed, 9 insertions(+), 10 deletions(-) diff --git a/user_guide_src/source/helpers/text_helper/020.php b/user_guide_src/source/helpers/text_helper/020.php index e5e6be9350a6..1b235b77497e 100644 --- a/user_guide_src/source/helpers/text_helper/020.php +++ b/user_guide_src/source/helpers/text_helper/020.php @@ -12,4 +12,4 @@ function. Excessively long words will be split, but URLs will not be. -*/ \ No newline at end of file +*/ diff --git a/user_guide_src/source/libraries/curlrequest/014.php b/user_guide_src/source/libraries/curlrequest/014.php index 04f6e02ffb18..9147c8861423 100644 --- a/user_guide_src/source/libraries/curlrequest/014.php +++ b/user_guide_src/source/libraries/curlrequest/014.php @@ -8,4 +8,4 @@ 'max' => 5, // Maximum number of redirects to follow before stopping 'strict' => true, // Ensure POST requests stay POST requests through redirects 'protocols' => ['http', 'https'] // Restrict redirects to one or more protocols -*/ \ No newline at end of file +*/ diff --git a/user_guide_src/source/libraries/uploaded_files/006.php b/user_guide_src/source/libraries/uploaded_files/006.php index 9a1fde0f053e..f046d86b63bc 100644 --- a/user_guide_src/source/libraries/uploaded_files/006.php +++ b/user_guide_src/source/libraries/uploaded_files/006.php @@ -9,4 +9,4 @@ ] ] ] -]; \ No newline at end of file +]; diff --git a/user_guide_src/source/outgoing/localization/008.php b/user_guide_src/source/outgoing/localization/008.php index eac50a5f4861..1b9b79725642 100644 --- a/user_guide_src/source/outgoing/localization/008.php +++ b/user_guide_src/source/outgoing/localization/008.php @@ -6,5 +6,4 @@ 'key' => 'The actual message to be shown.', ], ], -] -; \ No newline at end of file +]; diff --git a/user_guide_src/source/outgoing/response/026.php b/user_guide_src/source/outgoing/response/026.php index 4287ddb889ba..ee92fa38c094 100644 --- a/user_guide_src/source/outgoing/response/026.php +++ b/user_guide_src/source/outgoing/response/026.php @@ -2,4 +2,4 @@ if ($response->hasCookie($name)) { // ... -} \ No newline at end of file +} diff --git a/user_guide_src/source/testing/fabricator/005.php b/user_guide_src/source/testing/fabricator/005.php index 1bee37a0b99a..de1e6d7ef6c5 100644 --- a/user_guide_src/source/testing/fabricator/005.php +++ b/user_guide_src/source/testing/fabricator/005.php @@ -12,4 +12,4 @@ public function fake(Generator &$faker) 'login' => config('Auth')->allowRemembering ? date('Y-m-d') : null, ]; } -} \ No newline at end of file +} diff --git a/user_guide_src/source/testing/fabricator/006.php b/user_guide_src/source/testing/fabricator/006.php index cfb130f21ede..13b4b96cb07d 100644 --- a/user_guide_src/source/testing/fabricator/006.php +++ b/user_guide_src/source/testing/fabricator/006.php @@ -8,4 +8,4 @@ public function fake(&$faker) { // ... } -} \ No newline at end of file +} diff --git a/user_guide_src/source/testing/fabricator/021.php b/user_guide_src/source/testing/fabricator/021.php index df10c0b137d7..d6c848ac3c06 100644 --- a/user_guide_src/source/testing/fabricator/021.php +++ b/user_guide_src/source/testing/fabricator/021.php @@ -12,4 +12,4 @@ public function fake(Generator &$faker) 'group_id' => rand(1, Fabricator::getCount('groups')), ]; } -} \ No newline at end of file +} diff --git a/user_guide_src/source/testing/overview/007.php b/user_guide_src/source/testing/overview/007.php index d6ec1d6c45c5..c829e5b99cce 100644 --- a/user_guide_src/source/testing/overview/007.php +++ b/user_guide_src/source/testing/overview/007.php @@ -16,4 +16,4 @@ class AuthenticationFeatureTest use AuthTrait; // ... -} \ No newline at end of file +} From 9594c458d97b2dd20861170d9d20b7d9a9049a5f Mon Sep 17 00:00:00 2001 From: "John Paul E. Balandan, CPA" <51850998+paulbalandan@users.noreply.github.com> Date: Thu, 24 Feb 2022 15:35:10 +0800 Subject: [PATCH 0554/1246] Delete stale.yml --- stale.yml | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 stale.yml diff --git a/stale.yml b/stale.yml deleted file mode 100644 index 897cc082a10e..000000000000 --- a/stale.yml +++ /dev/null @@ -1,17 +0,0 @@ -# Number of days of inactivity before an issue becomes stale -daysUntilStale: 60 -# Number of days of inactivity before a stale issue is closed -daysUntilClose: 7 -# Issues with these labels will never be considered stale -exemptLabels: - - pinned - - security -# Label to use when marking an issue as stale -staleLabel: wontfix -# Comment to post when marking an issue as stale. Set to `false` to disable -markComment: > - This issue has been automatically marked as stale because it has not had - recent activity. It will be automatically closed in a week if no further activity occurs. - Thank you for your contributions. -# Comment to post when closing a stale issue. Set to `false` to disable -closeComment: false From af4995f2cda37024ab64f32b7bd3b5761638ccb0 Mon Sep 17 00:00:00 2001 From: Alex Schmitz <40514119+sfadschm@users.noreply.github.com> Date: Thu, 24 Feb 2022 11:01:00 +0100 Subject: [PATCH 0555/1246] Fix space. Co-authored-by: kenjis --- user_guide_src/source/incoming/incomingrequest/10.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/incoming/incomingrequest/10.php b/user_guide_src/source/incoming/incomingrequest/10.php index d4118cebda7c..e223b7772d54 100644 --- a/user_guide_src/source/incoming/incomingrequest/10.php +++ b/user_guide_src/source/incoming/incomingrequest/10.php @@ -1,7 +1,7 @@ Date: Thu, 24 Feb 2022 11:33:28 +0100 Subject: [PATCH 0556/1246] Convert array dumps and prints to comments. --- .../source/incoming/incomingrequest/13.php | 12 ++++++--- .../source/incoming/incomingrequest/15.php | 14 ++++++---- user_guide_src/source/libraries/uri/026.php | 15 ++++++----- .../source/libraries/validation/009.php | 27 ++++++++++--------- .../source/libraries/validation/011.php | 17 +++++++----- .../source/libraries/validation/027.php | 13 +++++---- .../source/testing/benchmark/004.php | 17 +++++++----- .../source/testing/response/030.php | 8 ++++-- .../source/testing/response/032.php | 11 +++++--- 9 files changed, 82 insertions(+), 52 deletions(-) diff --git a/user_guide_src/source/incoming/incomingrequest/13.php b/user_guide_src/source/incoming/incomingrequest/13.php index cf4be2eb10ac..8f62b6dd32a9 100644 --- a/user_guide_src/source/incoming/incomingrequest/13.php +++ b/user_guide_src/source/incoming/incomingrequest/13.php @@ -2,7 +2,11 @@ var_dump($request->getRawInput()); -[ - 'Param1' => 'Value1', - 'Param2' => 'Value2' -]; +/* + Outputs: + + [ + 'Param1' => 'Value1', + 'Param2' => 'Value2' + ] +*/ diff --git a/user_guide_src/source/incoming/incomingrequest/15.php b/user_guide_src/source/incoming/incomingrequest/15.php index c6e85bfef577..95d483206211 100644 --- a/user_guide_src/source/incoming/incomingrequest/15.php +++ b/user_guide_src/source/incoming/incomingrequest/15.php @@ -2,8 +2,12 @@ var_dump($request->headers()); -[ - 'Host' => CodeIgniter\HTTP\Header, - 'Cache-Control' => CodeIgniter\HTTP\Header, - 'Accept' => CodeIgniter\HTTP\Header, -]; +/* + Outputs: + + [ + 'Host' => CodeIgniter\HTTP\Header, + 'Cache-Control' => CodeIgniter\HTTP\Header, + 'Accept' => CodeIgniter\HTTP\Header, + ] +*/ diff --git a/user_guide_src/source/libraries/uri/026.php b/user_guide_src/source/libraries/uri/026.php index 53a42eb788f4..6491e0d20ca4 100644 --- a/user_guide_src/source/libraries/uri/026.php +++ b/user_guide_src/source/libraries/uri/026.php @@ -2,9 +2,12 @@ $segments = $uri->getSegments(); -// $segments = -[ - 0 => 'users', - 1 => '15', - 2 => 'profile' -]; +/* + Produces: + + [ + 0 => 'users', + 1 => '15', + 2 => 'profile' + ] +*/ diff --git a/user_guide_src/source/libraries/validation/009.php b/user_guide_src/source/libraries/validation/009.php index aec2e980c5dc..8792a8a8f728 100644 --- a/user_guide_src/source/libraries/validation/009.php +++ b/user_guide_src/source/libraries/validation/009.php @@ -1,19 +1,22 @@ [ - 'name' => 'Joe Smith', - 'friends' => [ - [ - 'name' => 'Fred Flinstone', - ], - [ - 'name' => 'Wilma', - ], +/* + The data to test: + + [ + 'contacts' => [ + 'name' => 'Joe Smith', + 'friends' => [ + [ + 'name' => 'Fred Flinstone', + ], + [ + 'name' => 'Wilma', + ], + ] ] ] -]; +*/ // Joe Smith $validation->setRules([ diff --git a/user_guide_src/source/libraries/validation/011.php b/user_guide_src/source/libraries/validation/011.php index 66fbcda5e1a7..ec6b9c9adbab 100644 --- a/user_guide_src/source/libraries/validation/011.php +++ b/user_guide_src/source/libraries/validation/011.php @@ -1,13 +1,16 @@ [ - 1, - 2, - 3, +/* + The data to test: + + [ + 'user_ids' => [ + 1, + 2, + 3, + ] ] -]; +*/ // Rule $validation->setRules([ diff --git a/user_guide_src/source/libraries/validation/027.php b/user_guide_src/source/libraries/validation/027.php index c6afaf393f2a..e633f5cdd1e3 100644 --- a/user_guide_src/source/libraries/validation/027.php +++ b/user_guide_src/source/libraries/validation/027.php @@ -2,8 +2,11 @@ $errors = $validation->getErrors(); -// Returns: -[ - 'field1' => 'error message', - 'field2' => 'error message', -]; +/* + Produces: + + [ + 'field1' => 'error message', + 'field2' => 'error message', + ] +*/ diff --git a/user_guide_src/source/testing/benchmark/004.php b/user_guide_src/source/testing/benchmark/004.php index bf84bf6ed21f..3048a2851ff3 100644 --- a/user_guide_src/source/testing/benchmark/004.php +++ b/user_guide_src/source/testing/benchmark/004.php @@ -2,11 +2,14 @@ $timers = $benchmark->getTimers(); -// Timers = -[ - 'render view' => [ - 'start' => 1234567890, - 'end' => 1345678920, - 'duration' => 15.4315, // number of seconds +/* + Produces: + + [ + 'render view' => [ + 'start' => 1234567890, + 'end' => 1345678920, + 'duration' => 15.4315, // number of seconds + ] ] -]; +*/ diff --git a/user_guide_src/source/testing/response/030.php b/user_guide_src/source/testing/response/030.php index 7dfa89e51cc1..53887b278572 100644 --- a/user_guide_src/source/testing/response/030.php +++ b/user_guide_src/source/testing/response/030.php @@ -1,12 +1,16 @@ 'bar']; +/* + Response body is this: + + ['foo' => 'bar']; +*/ $json = $result->getJSON(); /* $json is this: + { "foo": "bar" } diff --git a/user_guide_src/source/testing/response/032.php b/user_guide_src/source/testing/response/032.php index c2d093443b9d..6de63a9cfce8 100644 --- a/user_guide_src/source/testing/response/032.php +++ b/user_guide_src/source/testing/response/032.php @@ -1,9 +1,12 @@ ['key-a', 'key-b'], -]; +/* + Response body is this: + + [ + 'config' => ['key-a', 'key-b'], + ] +*/ // Is true $result->assertJSONFragment(['config' => ['key-a']]); From 36976f5945df3484ddf33c0df217e862aee9961a Mon Sep 17 00:00:00 2001 From: Alex Schmitz <40514119+sfadschm@users.noreply.github.com> Date: Thu, 24 Feb 2022 11:38:03 +0100 Subject: [PATCH 0557/1246] Fix output of getHeaderLine. Co-authored-by: kenjis --- user_guide_src/source/incoming/message/005.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/incoming/message/005.php b/user_guide_src/source/incoming/message/005.php index ea54a21a4407..b67851a9258a 100644 --- a/user_guide_src/source/incoming/message/005.php +++ b/user_guide_src/source/incoming/message/005.php @@ -4,5 +4,5 @@ /* Outputs: - en, en-US + 'en,en-US' */ From 087ef29cb56348c1fb437a474b7e23a04ed60c9c Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Thu, 24 Feb 2022 11:52:32 +0100 Subject: [PATCH 0558/1246] Fix delimiters in renumerate script. --- user_guide_src/{renumerate.php => renumerate} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename user_guide_src/{renumerate.php => renumerate} (93%) diff --git a/user_guide_src/renumerate.php b/user_guide_src/renumerate similarity index 93% rename from user_guide_src/renumerate.php rename to user_guide_src/renumerate index ca885551d168..814ea18430d0 100644 --- a/user_guide_src/renumerate.php +++ b/user_guide_src/renumerate @@ -81,7 +81,7 @@ rename($sectionFolder . '/' . $prefix . $exampleName . '.php', $sectionFolder . '/' . $newName . '.php'); // Fix include link - $sectionContent = preg_replace(preg_quote(str_replace($exampleName, $prefix . $exampleName, $includeStrings[$exampleIndex]), '~'), str_replace($exampleName, $newName, $includeStrings[$exampleIndex]), $sectionContent, 1, $count); + $sectionContent = preg_replace('~' . preg_quote(str_replace($exampleName, $prefix . $exampleName, $includeStrings[$exampleIndex]), '~') . '~', str_replace($exampleName, $newName, $includeStrings[$exampleIndex]), $sectionContent, 1, $count); } // Write new content to rst From da96ff3519b5a0eca6fa9e61d834cabe6cd575c9 Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Thu, 24 Feb 2022 11:58:29 +0100 Subject: [PATCH 0559/1246] Revert extraction of single array elements. --- user_guide_src/source/libraries/pagination.rst | 10 ++++------ user_guide_src/source/libraries/pagination/011.php | 3 --- user_guide_src/source/libraries/pagination/012.php | 3 --- user_guide_src/source/libraries/validation.rst | 5 ++--- user_guide_src/source/libraries/validation/025.php | 3 --- 5 files changed, 6 insertions(+), 18 deletions(-) delete mode 100644 user_guide_src/source/libraries/pagination/011.php delete mode 100644 user_guide_src/source/libraries/pagination/012.php delete mode 100644 user_guide_src/source/libraries/validation/025.php diff --git a/user_guide_src/source/libraries/pagination.rst b/user_guide_src/source/libraries/pagination.rst index 8a79531326d6..5eec05cf0c43 100644 --- a/user_guide_src/source/libraries/pagination.rst +++ b/user_guide_src/source/libraries/pagination.rst @@ -166,16 +166,14 @@ methods, respectively. To change the way those are displayed application-wide, y For example, say you create a new view file that works with the Foundation CSS framework, and you place that file at **app/Views/Pagers/foundation_full.php**. Since the **application** directory is namespaced as ``App``, and all directories underneath it map directly to segments of the namespace, you can locate -the view file through it's namespace: +the view file through it's namespace:: -.. literalinclude:: pagination/011.php - :lines: 2- + 'default_full' => 'App\Views\Pagers\foundation_full' Since it is under the standard **app/Views** directory, though, you do not need to namespace it since the -``view()`` method can locate it by filename. In that case, you can simply give the sub-directory and file name: +``view()`` method can locate it by filename. In that case, you can simply give the sub-directory and file name:: -.. literalinclude:: pagination/012.php - :lines: 2- + 'default_full' => 'Pagers/foundation_full' Once you have created the view and set it in the configuration, it will automatically be used. You don't have to replace the existing templates. You can create as many additional templates as you need in the configuration diff --git a/user_guide_src/source/libraries/pagination/011.php b/user_guide_src/source/libraries/pagination/011.php deleted file mode 100644 index 8000e782737c..000000000000 --- a/user_guide_src/source/libraries/pagination/011.php +++ /dev/null @@ -1,3 +0,0 @@ - 'App\Views\Pagers\foundation_full']; diff --git a/user_guide_src/source/libraries/pagination/012.php b/user_guide_src/source/libraries/pagination/012.php deleted file mode 100644 index 5a00b20f70c3..000000000000 --- a/user_guide_src/source/libraries/pagination/012.php +++ /dev/null @@ -1,3 +0,0 @@ - 'Pagers/foundation_full']; diff --git a/user_guide_src/source/libraries/validation.rst b/user_guide_src/source/libraries/validation.rst index a74bca7904d8..4f53eab33260 100644 --- a/user_guide_src/source/libraries/validation.rst +++ b/user_guide_src/source/libraries/validation.rst @@ -435,10 +435,9 @@ Or as a labeled style: :lines: 2- If you’d like to include a field’s “human” name, or the optional parameter some rules allow for (such as max_length), -or the value that was validated you can add the ``{field}``, ``{param}`` and ``{value}`` tags to your message, respectively: +or the value that was validated you can add the ``{field}``, ``{param}`` and ``{value}`` tags to your message, respectively:: -.. literalinclude:: validation/025.php - :lines: 2- + 'min_length' => 'Supplied value ({value}) for {field} must have at least {param} characters.' On a field with the human name Username and a rule of ``min_length[6]`` with a value of “Pizza”, an error would display: “Supplied value (Pizza) for Username must have at least 6 characters.” diff --git a/user_guide_src/source/libraries/validation/025.php b/user_guide_src/source/libraries/validation/025.php deleted file mode 100644 index a71f46f29f92..000000000000 --- a/user_guide_src/source/libraries/validation/025.php +++ /dev/null @@ -1,3 +0,0 @@ - 'Supplied value ({value}) for {field} must have at least {param} characters.']; From c2883077a6acf35cd53676935f4d35583ee126f8 Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Thu, 24 Feb 2022 11:58:35 +0100 Subject: [PATCH 0560/1246] Add return statement for localization arrays. --- user_guide_src/source/outgoing/localization/007.php | 4 +++- user_guide_src/source/outgoing/localization/008.php | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/user_guide_src/source/outgoing/localization/007.php b/user_guide_src/source/outgoing/localization/007.php index e2de3a4644d6..adc24e5d6242 100644 --- a/user_guide_src/source/outgoing/localization/007.php +++ b/user_guide_src/source/outgoing/localization/007.php @@ -1,3 +1,5 @@ 'The actual message to be shown.']; +return [ + 'languageKey' => 'The actual message to be shown.' +]; diff --git a/user_guide_src/source/outgoing/localization/008.php b/user_guide_src/source/outgoing/localization/008.php index 1b9b79725642..319fa750429b 100644 --- a/user_guide_src/source/outgoing/localization/008.php +++ b/user_guide_src/source/outgoing/localization/008.php @@ -1,6 +1,6 @@ [ 'nested' => [ 'key' => 'The actual message to be shown.', From c4d4281274fb016517d197674eb284151dc70dba Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Thu, 24 Feb 2022 11:59:15 +0100 Subject: [PATCH 0561/1246] Remove wrong semicolon in response body. --- user_guide_src/source/testing/response/030.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/testing/response/030.php b/user_guide_src/source/testing/response/030.php index 53887b278572..060f5c551a87 100644 --- a/user_guide_src/source/testing/response/030.php +++ b/user_guide_src/source/testing/response/030.php @@ -3,7 +3,7 @@ /* Response body is this: - ['foo' => 'bar']; + ['foo' => 'bar'] */ $json = $result->getJSON(); From b7bb3f29afad9e577b3fd406ca88e8ded08b5f6d Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Thu, 24 Feb 2022 12:00:43 +0100 Subject: [PATCH 0562/1246] Renumerate incomingrequest, pagination and validation. --- .../source/incoming/incomingrequest.rst | 76 +++++++++---------- .../incomingrequest/{1.php => 001.php} | 0 .../incomingrequest/{2.php => 002.php} | 0 .../incomingrequest/{3.php => 003.php} | 0 .../incomingrequest/{4.php => 004.php} | 0 .../incomingrequest/{5.php => 005.php} | 0 .../incomingrequest/{6.php => 006.php} | 0 .../incomingrequest/{7.php => 007.php} | 0 .../incomingrequest/{8.php => 008.php} | 0 .../incomingrequest/{9.php => 009.php} | 0 .../incomingrequest/{10.php => 010.php} | 0 .../incomingrequest/{11.php => 011.php} | 0 .../incomingrequest/{12.php => 012.php} | 0 .../incomingrequest/{13.php => 013.php} | 0 .../incomingrequest/{14.php => 014.php} | 0 .../incomingrequest/{15.php => 015.php} | 0 .../incomingrequest/{16.php => 016.php} | 0 .../incomingrequest/{17.php => 017.php} | 0 .../incomingrequest/{18.php => 018.php} | 0 .../incomingrequest/{19.php => 019.php} | 0 .../incomingrequest/{20.php => 020.php} | 0 .../incomingrequest/{21.php => 021.php} | 0 .../incomingrequest/{22.php => 022.php} | 0 .../incomingrequest/{23.php => 023.php} | 0 .../incomingrequest/{24.php => 024.php} | 0 .../incomingrequest/{25.php => 025.php} | 0 .../incomingrequest/{26.php => 026.php} | 0 .../incomingrequest/{27.php => 027.php} | 0 .../incomingrequest/{28.php => 028.php} | 0 .../incomingrequest/{29.php => 029.php} | 0 .../incomingrequest/{30.php => 030.php} | 0 .../incomingrequest/{31.php => 031.php} | 0 .../incomingrequest/{32.php => 032.php} | 0 .../incomingrequest/{33.php => 033.php} | 0 .../incomingrequest/{34.php => 034.php} | 0 .../incomingrequest/{35.php => 035.php} | 0 .../incomingrequest/{36.php => 036.php} | 0 .../incomingrequest/{37.php => 037.php} | 0 .../incomingrequest/{38.php => 038.php} | 0 .../source/libraries/pagination.rst | 8 +- .../source/libraries/pagination/011.php | 7 ++ .../source/libraries/pagination/012.php | 39 ++++++++++ .../source/libraries/pagination/013.php | 8 +- .../source/libraries/pagination/014.php | 66 ++++++++-------- .../source/libraries/pagination/015.php | 7 -- .../source/libraries/pagination/016.php | 37 --------- .../source/libraries/validation.rst | 26 +++---- .../source/libraries/validation/025.php | 19 +++++ .../source/libraries/validation/026.php | 25 +++--- .../source/libraries/validation/027.php | 11 +-- .../source/libraries/validation/028.php | 4 +- .../source/libraries/validation/029.php | 12 +-- .../source/libraries/validation/030.php | 13 ++-- .../source/libraries/validation/031.php | 7 +- .../source/libraries/validation/032.php | 14 +++- .../source/libraries/validation/033.php | 18 ++--- .../source/libraries/validation/034.php | 11 ++- .../source/libraries/validation/035.php | 13 +--- .../source/libraries/validation/036.php | 35 ++++++++- .../source/libraries/validation/037.php | 40 ++-------- .../source/libraries/validation/038.php | 10 --- 61 files changed, 253 insertions(+), 253 deletions(-) rename user_guide_src/source/incoming/incomingrequest/{1.php => 001.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{2.php => 002.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{3.php => 003.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{4.php => 004.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{5.php => 005.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{6.php => 006.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{7.php => 007.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{8.php => 008.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{9.php => 009.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{10.php => 010.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{11.php => 011.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{12.php => 012.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{13.php => 013.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{14.php => 014.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{15.php => 015.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{16.php => 016.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{17.php => 017.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{18.php => 018.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{19.php => 019.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{20.php => 020.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{21.php => 021.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{22.php => 022.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{23.php => 023.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{24.php => 024.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{25.php => 025.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{26.php => 026.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{27.php => 027.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{28.php => 028.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{29.php => 029.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{30.php => 030.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{31.php => 031.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{32.php => 032.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{33.php => 033.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{34.php => 034.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{35.php => 035.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{36.php => 036.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{37.php => 037.php} (100%) rename user_guide_src/source/incoming/incomingrequest/{38.php => 038.php} (100%) create mode 100644 user_guide_src/source/libraries/pagination/011.php create mode 100644 user_guide_src/source/libraries/pagination/012.php delete mode 100644 user_guide_src/source/libraries/pagination/015.php delete mode 100644 user_guide_src/source/libraries/pagination/016.php create mode 100644 user_guide_src/source/libraries/validation/025.php delete mode 100644 user_guide_src/source/libraries/validation/038.php diff --git a/user_guide_src/source/incoming/incomingrequest.rst b/user_guide_src/source/incoming/incomingrequest.rst index 70692d1aa4c4..2691a034aeaf 100644 --- a/user_guide_src/source/incoming/incomingrequest.rst +++ b/user_guide_src/source/incoming/incomingrequest.rst @@ -15,18 +15,18 @@ Accessing the Request An instance of the request class already populated for you if the current class is a descendant of ``CodeIgniter\Controller`` and can be accessed as a class property: -.. literalinclude:: incomingrequest/1.php +.. literalinclude:: incomingrequest/001.php If you are not within a controller, but still need access to the application's Request object, you can get a copy of it through the :doc:`Services class `: -.. literalinclude:: incomingrequest/2.php +.. literalinclude:: incomingrequest/002.php :lines: 2- It's preferable, though, to pass the request in as a dependency if the class is anything other than the controller, where you can save it as a class property: -.. literalinclude:: incomingrequest/3.php +.. literalinclude:: incomingrequest/003.php Determining Request Type ------------------------ @@ -34,7 +34,7 @@ Determining Request Type A request could be of several types, including an AJAX request or a request from the command line. This can be checked with the ``isAJAX()`` and ``isCLI()`` methods: -.. literalinclude:: incomingrequest/4.php +.. literalinclude:: incomingrequest/004.php :lines: 2- .. note:: The ``isAJAX()`` method depends on the ``X-Requested-With`` header, @@ -43,7 +43,7 @@ be checked with the ``isAJAX()`` and ``isCLI()`` methods: You can check the HTTP method that this request represents with the ``method()`` method: -.. literalinclude:: incomingrequest/5.php +.. literalinclude:: incomingrequest/005.php :lines: 2- By default, the method is returned as a lower-case string (i.e., 'get', 'post', etc). You can get an @@ -54,7 +54,7 @@ uppercase version by wrapping the call in ``str_to_upper()``:: You can also check if the request was made through and HTTPS connection with the ``isSecure()`` method: -.. literalinclude:: incomingrequest/6.php +.. literalinclude:: incomingrequest/006.php :lines: 2- Retrieving Input @@ -67,12 +67,12 @@ will return null if the item doesn't exist, and you can have the data filtered. use data without having to test whether an item exists first. In other words, normally you might do something like this: -.. literalinclude:: incomingrequest/7.php +.. literalinclude:: incomingrequest/007.php :lines: 2- With CodeIgniter’s built in methods you can simply do this: -.. literalinclude:: incomingrequest/8.php +.. literalinclude:: incomingrequest/008.php :lines: 2- The ``getVar()`` method will pull from $_REQUEST, so will return any data from $_GET, $POST, or $_COOKIE. While this @@ -97,7 +97,7 @@ You can grab the contents of php://input as a JSON stream with ``getJSON()``. method if you know that you're expecting JSON. -.. literalinclude:: incomingrequest/9.php +.. literalinclude:: incomingrequest/009.php :lines: 2- By default, this will return any objects in the JSON data as objects. If you want that converted to associative @@ -115,7 +115,7 @@ You can get a specific piece of data from a JSON stream by passing a variable na data that you want or you can use "dot" notation to dig into the JSON to get data that is not on the root level. -.. literalinclude:: incomingrequest/10.php +.. literalinclude:: incomingrequest/010.php :lines: 2- @@ -124,7 +124,7 @@ true in the second parameter. This function can also be used if you can't guaran correct ``CONTENT_TYPE`` header. -.. literalinclude:: incomingrequest/11.php +.. literalinclude:: incomingrequest/011.php :lines: 2- .. note:: See the documentation for ``dot_array_search()`` in the ``Array`` helper for more information on "dot" notation. @@ -133,12 +133,12 @@ correct ``CONTENT_TYPE`` header. Finally, you can grab the contents of php://input as a raw stream with ``getRawInput()``: -.. literalinclude:: incomingrequest/12.php +.. literalinclude:: incomingrequest/012.php :lines: 2- This will retrieve data and convert it to an array. Like this: -.. literalinclude:: incomingrequest/13.php +.. literalinclude:: incomingrequest/013.php :lines: 2- **Filtering Input Data** @@ -150,7 +150,7 @@ filter types `_. Filtering a POST variable would look like this: -.. literalinclude:: incomingrequest/14.php +.. literalinclude:: incomingrequest/014.php :lines: 2- All of the methods mentioned above support the filter type passed in as the second parameter, with the @@ -163,28 +163,28 @@ You can get access to any header that was sent with the request with the ``heade an array of all headers, with the key as the name of the header, and the value is an instance of ``CodeIgniter\HTTP\Header``: -.. literalinclude:: incomingrequest/15.php +.. literalinclude:: incomingrequest/015.php :lines: 2- If you only need a single header, you can pass the name into the ``header()`` method. This will grab the specified header object in a case-insensitive manner if it exists. If not, then it will return ``null``: -.. literalinclude:: incomingrequest/16.php +.. literalinclude:: incomingrequest/016.php :lines: 2- You can always use ``hasHeader()`` to see if the header existed in this request: -.. literalinclude:: incomingrequest/17.php +.. literalinclude:: incomingrequest/017.php :lines: 2- If you need the value of header as a string with all values on one line, you can use the ``getHeaderLine()`` method: -.. literalinclude:: incomingrequest/18.php +.. literalinclude:: incomingrequest/018.php :lines: 2- If you need the entire header, with the name and values in a single string, simply cast the header as a string: -.. literalinclude:: incomingrequest/19.php +.. literalinclude:: incomingrequest/019.php :lines: 2- The Request URL @@ -193,19 +193,19 @@ The Request URL You can retrieve a :doc:`URI ` object that represents the current URI for this request through the ``$request->getUri()`` method. You can cast this object as a string to get a full URL for the current request: -.. literalinclude:: incomingrequest/20.php +.. literalinclude:: incomingrequest/020.php :lines: 2- The object gives you full abilities to grab any part of the request on it's own: -.. literalinclude:: incomingrequest/21.php +.. literalinclude:: incomingrequest/021.php :lines: 2- You can work with the current URI string (the path relative to your baseURL) using the ``getPath()`` and ``setPath()`` methods. Note that this relative path on the shared instance of ``IncomingRequest`` is what the :doc:`URL Helper ` functions use, so this is a helpful way to "spoof" an incoming request for testing: -.. literalinclude:: incomingrequest/22.php +.. literalinclude:: incomingrequest/022.php :lines: 2- Uploaded Files @@ -215,20 +215,20 @@ Information about all uploaded files can be retrieved through ``$request->getFil ``CodeIgniter\HTTP\Files\UploadedFile`` instance. This helps to ease the pain of working with uploaded files, and uses best practices to minimize any security risks. -.. literalinclude:: incomingrequest/23.php +.. literalinclude:: incomingrequest/023.php :lines: 2- See :ref:`Working with Uploaded Files ` for the details. You can retrieve a single file uploaded on its own, based on the filename given in the HTML file input: -.. literalinclude:: incomingrequest/24.php +.. literalinclude:: incomingrequest/024.php :lines: 2- You can retrieve an array of same-named files uploaded as part of a multi-file upload, based on the filename given in the HTML file input: -.. literalinclude:: incomingrequest/25.php +.. literalinclude:: incomingrequest/025.php :lines: 2- .. note:: The files here correspond to ``$_FILES``. Even if a user just clicks submit button of a form and does not upload any file, the file will still exist. You can check that the file was actually uploaded by the ``isValid()`` method in UploadedFile. See :ref:`verify-a-file` for more details. @@ -238,7 +238,7 @@ Content Negotiation You can easily negotiate content types with the request through the ``negotiate()`` method: -.. literalinclude:: incomingrequest/26.php +.. literalinclude:: incomingrequest/026.php :lines: 2- See the :doc:`Content Negotiation ` page for more details. @@ -303,7 +303,7 @@ The methods provided by the parent classes that are available are: The first parameter will contain the name of the REQUEST item you are looking for: - .. literalinclude:: incomingrequest/27.php + .. literalinclude:: incomingrequest/027.php :lines: 2- The method returns null if the item you are attempting to retrieve @@ -312,7 +312,7 @@ The methods provided by the parent classes that are available are: The second optional parameter lets you run the data through the PHP's filters. Pass in the desired filter type as the second parameter: - .. literalinclude:: incomingrequest/28.php + .. literalinclude:: incomingrequest/028.php :lines: 2- To return an array of all POST items call without any parameters. @@ -321,18 +321,18 @@ The methods provided by the parent classes that are available are: first parameter to null while setting the second parameter to the filter you want to use: - .. literalinclude:: incomingrequest/29.php + .. literalinclude:: incomingrequest/029.php :lines: 2- To return an array of multiple POST parameters, pass all the required keys as an array: - .. literalinclude:: incomingrequest/30.php + .. literalinclude:: incomingrequest/030.php :lines: 2- Same rule applied here, to retrieve the parameters with filtering, set the second parameter to the filter type to apply: - .. literalinclude:: incomingrequest/31.php + .. literalinclude:: incomingrequest/031.php :lines: 2- .. php:method:: getGet([$index = null[, $filter = null[, $flags = null]]]) @@ -373,7 +373,7 @@ The methods provided by the parent classes that are available are: It will search through both POST and GET streams for data, looking first in POST, and then in GET: - .. literalinclude:: incomingrequest/32.php + .. literalinclude:: incomingrequest/032.php :lines: 2- .. php:method:: getGetPost([$index = null[, $filter = null[, $flags = null]]]) @@ -390,7 +390,7 @@ The methods provided by the parent classes that are available are: It will search through both POST and GET streams for data, looking first in GET, and then in POST: - .. literalinclude:: incomingrequest/33.php + .. literalinclude:: incomingrequest/033.php :lines: 2- .. php:method:: getCookie([$index = null[, $filter = null[, $flags = null]]]) @@ -406,12 +406,12 @@ The methods provided by the parent classes that are available are: This method is identical to ``getPost()`` and ``getGet()``, only it fetches cookie data: - .. literalinclude:: incomingrequest/34.php + .. literalinclude:: incomingrequest/034.php :lines: 2- To return an array of multiple cookie values, pass all the required keys as an array: - .. literalinclude:: incomingrequest/35.php + .. literalinclude:: incomingrequest/035.php :lines: 2- .. note:: Unlike the :doc:`Cookie Helper <../helpers/cookie_helper>` @@ -432,13 +432,13 @@ The methods provided by the parent classes that are available are: This method is identical to the ``getPost()``, ``getGet()`` and ``getCookie()`` methods, only it fetches getServer data (``$_SERVER``): - .. literalinclude:: incomingrequest/36.php + .. literalinclude:: incomingrequest/036.php :lines: 2- To return an array of multiple ``$_SERVER`` values, pass all the required keys as an array. - .. literalinclude:: incomingrequest/37.php + .. literalinclude:: incomingrequest/037.php :lines: 2- .. php:method:: getUserAgent([$filter = null]) @@ -450,7 +450,7 @@ The methods provided by the parent classes that are available are: This method returns the User Agent string from the SERVER data: - .. literalinclude:: incomingrequest/38.php + .. literalinclude:: incomingrequest/038.php :lines: 2- .. php:method:: getPath() diff --git a/user_guide_src/source/incoming/incomingrequest/1.php b/user_guide_src/source/incoming/incomingrequest/001.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/1.php rename to user_guide_src/source/incoming/incomingrequest/001.php diff --git a/user_guide_src/source/incoming/incomingrequest/2.php b/user_guide_src/source/incoming/incomingrequest/002.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/2.php rename to user_guide_src/source/incoming/incomingrequest/002.php diff --git a/user_guide_src/source/incoming/incomingrequest/3.php b/user_guide_src/source/incoming/incomingrequest/003.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/3.php rename to user_guide_src/source/incoming/incomingrequest/003.php diff --git a/user_guide_src/source/incoming/incomingrequest/4.php b/user_guide_src/source/incoming/incomingrequest/004.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/4.php rename to user_guide_src/source/incoming/incomingrequest/004.php diff --git a/user_guide_src/source/incoming/incomingrequest/5.php b/user_guide_src/source/incoming/incomingrequest/005.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/5.php rename to user_guide_src/source/incoming/incomingrequest/005.php diff --git a/user_guide_src/source/incoming/incomingrequest/6.php b/user_guide_src/source/incoming/incomingrequest/006.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/6.php rename to user_guide_src/source/incoming/incomingrequest/006.php diff --git a/user_guide_src/source/incoming/incomingrequest/7.php b/user_guide_src/source/incoming/incomingrequest/007.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/7.php rename to user_guide_src/source/incoming/incomingrequest/007.php diff --git a/user_guide_src/source/incoming/incomingrequest/8.php b/user_guide_src/source/incoming/incomingrequest/008.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/8.php rename to user_guide_src/source/incoming/incomingrequest/008.php diff --git a/user_guide_src/source/incoming/incomingrequest/9.php b/user_guide_src/source/incoming/incomingrequest/009.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/9.php rename to user_guide_src/source/incoming/incomingrequest/009.php diff --git a/user_guide_src/source/incoming/incomingrequest/10.php b/user_guide_src/source/incoming/incomingrequest/010.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/10.php rename to user_guide_src/source/incoming/incomingrequest/010.php diff --git a/user_guide_src/source/incoming/incomingrequest/11.php b/user_guide_src/source/incoming/incomingrequest/011.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/11.php rename to user_guide_src/source/incoming/incomingrequest/011.php diff --git a/user_guide_src/source/incoming/incomingrequest/12.php b/user_guide_src/source/incoming/incomingrequest/012.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/12.php rename to user_guide_src/source/incoming/incomingrequest/012.php diff --git a/user_guide_src/source/incoming/incomingrequest/13.php b/user_guide_src/source/incoming/incomingrequest/013.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/13.php rename to user_guide_src/source/incoming/incomingrequest/013.php diff --git a/user_guide_src/source/incoming/incomingrequest/14.php b/user_guide_src/source/incoming/incomingrequest/014.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/14.php rename to user_guide_src/source/incoming/incomingrequest/014.php diff --git a/user_guide_src/source/incoming/incomingrequest/15.php b/user_guide_src/source/incoming/incomingrequest/015.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/15.php rename to user_guide_src/source/incoming/incomingrequest/015.php diff --git a/user_guide_src/source/incoming/incomingrequest/16.php b/user_guide_src/source/incoming/incomingrequest/016.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/16.php rename to user_guide_src/source/incoming/incomingrequest/016.php diff --git a/user_guide_src/source/incoming/incomingrequest/17.php b/user_guide_src/source/incoming/incomingrequest/017.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/17.php rename to user_guide_src/source/incoming/incomingrequest/017.php diff --git a/user_guide_src/source/incoming/incomingrequest/18.php b/user_guide_src/source/incoming/incomingrequest/018.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/18.php rename to user_guide_src/source/incoming/incomingrequest/018.php diff --git a/user_guide_src/source/incoming/incomingrequest/19.php b/user_guide_src/source/incoming/incomingrequest/019.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/19.php rename to user_guide_src/source/incoming/incomingrequest/019.php diff --git a/user_guide_src/source/incoming/incomingrequest/20.php b/user_guide_src/source/incoming/incomingrequest/020.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/20.php rename to user_guide_src/source/incoming/incomingrequest/020.php diff --git a/user_guide_src/source/incoming/incomingrequest/21.php b/user_guide_src/source/incoming/incomingrequest/021.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/21.php rename to user_guide_src/source/incoming/incomingrequest/021.php diff --git a/user_guide_src/source/incoming/incomingrequest/22.php b/user_guide_src/source/incoming/incomingrequest/022.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/22.php rename to user_guide_src/source/incoming/incomingrequest/022.php diff --git a/user_guide_src/source/incoming/incomingrequest/23.php b/user_guide_src/source/incoming/incomingrequest/023.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/23.php rename to user_guide_src/source/incoming/incomingrequest/023.php diff --git a/user_guide_src/source/incoming/incomingrequest/24.php b/user_guide_src/source/incoming/incomingrequest/024.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/24.php rename to user_guide_src/source/incoming/incomingrequest/024.php diff --git a/user_guide_src/source/incoming/incomingrequest/25.php b/user_guide_src/source/incoming/incomingrequest/025.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/25.php rename to user_guide_src/source/incoming/incomingrequest/025.php diff --git a/user_guide_src/source/incoming/incomingrequest/26.php b/user_guide_src/source/incoming/incomingrequest/026.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/26.php rename to user_guide_src/source/incoming/incomingrequest/026.php diff --git a/user_guide_src/source/incoming/incomingrequest/27.php b/user_guide_src/source/incoming/incomingrequest/027.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/27.php rename to user_guide_src/source/incoming/incomingrequest/027.php diff --git a/user_guide_src/source/incoming/incomingrequest/28.php b/user_guide_src/source/incoming/incomingrequest/028.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/28.php rename to user_guide_src/source/incoming/incomingrequest/028.php diff --git a/user_guide_src/source/incoming/incomingrequest/29.php b/user_guide_src/source/incoming/incomingrequest/029.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/29.php rename to user_guide_src/source/incoming/incomingrequest/029.php diff --git a/user_guide_src/source/incoming/incomingrequest/30.php b/user_guide_src/source/incoming/incomingrequest/030.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/30.php rename to user_guide_src/source/incoming/incomingrequest/030.php diff --git a/user_guide_src/source/incoming/incomingrequest/31.php b/user_guide_src/source/incoming/incomingrequest/031.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/31.php rename to user_guide_src/source/incoming/incomingrequest/031.php diff --git a/user_guide_src/source/incoming/incomingrequest/32.php b/user_guide_src/source/incoming/incomingrequest/032.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/32.php rename to user_guide_src/source/incoming/incomingrequest/032.php diff --git a/user_guide_src/source/incoming/incomingrequest/33.php b/user_guide_src/source/incoming/incomingrequest/033.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/33.php rename to user_guide_src/source/incoming/incomingrequest/033.php diff --git a/user_guide_src/source/incoming/incomingrequest/34.php b/user_guide_src/source/incoming/incomingrequest/034.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/34.php rename to user_guide_src/source/incoming/incomingrequest/034.php diff --git a/user_guide_src/source/incoming/incomingrequest/35.php b/user_guide_src/source/incoming/incomingrequest/035.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/35.php rename to user_guide_src/source/incoming/incomingrequest/035.php diff --git a/user_guide_src/source/incoming/incomingrequest/36.php b/user_guide_src/source/incoming/incomingrequest/036.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/36.php rename to user_guide_src/source/incoming/incomingrequest/036.php diff --git a/user_guide_src/source/incoming/incomingrequest/37.php b/user_guide_src/source/incoming/incomingrequest/037.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/37.php rename to user_guide_src/source/incoming/incomingrequest/037.php diff --git a/user_guide_src/source/incoming/incomingrequest/38.php b/user_guide_src/source/incoming/incomingrequest/038.php similarity index 100% rename from user_guide_src/source/incoming/incomingrequest/38.php rename to user_guide_src/source/incoming/incomingrequest/038.php diff --git a/user_guide_src/source/libraries/pagination.rst b/user_guide_src/source/libraries/pagination.rst index 5eec05cf0c43..37163c1ec14d 100644 --- a/user_guide_src/source/libraries/pagination.rst +++ b/user_guide_src/source/libraries/pagination.rst @@ -179,7 +179,7 @@ Once you have created the view and set it in the configuration, it will automati replace the existing templates. You can create as many additional templates as you need in the configuration file. A common situation would be needing different styles for the frontend and the backend of your application. -.. literalinclude:: pagination/013.php +.. literalinclude:: pagination/011.php :lines: 2- Once configured, you can specify it as a the last parameter in the ``links()``, ``simpleLinks()``, and ``makeLinks()`` @@ -196,7 +196,7 @@ When you create a new view, you only need to create the code that is needed for You should not create unnecessary wrapping divs since it might be used in multiple places and you only limit their usefulness. It is easiest to demonstrate creating a new view by showing you the existing ``default_full`` template: -.. literalinclude:: pagination/014.php +.. literalinclude:: pagination/012.php **setSurroundCount()** @@ -226,7 +226,7 @@ result set. Returns an array of data about all of the numbered links. Each link's array contains the uri for the link, the title, which is just the number, and a boolean that tells whether the link is the current/active link or not: -.. literalinclude:: pagination/015.php +.. literalinclude:: pagination/013.php :lines: 2- In the code presented for the standard pagination structure, the methods ``getPrevious()`` and ``getNext()`` are used to obtain the links to the previous and next pagination groups respectively. @@ -235,7 +235,7 @@ If you want to use the pagination structure where prev and next will be links to See following an example with these changes: -.. literalinclude:: pagination/016.php +.. literalinclude:: pagination/014.php **hasPreviousPage()** & **hasNextPage()** diff --git a/user_guide_src/source/libraries/pagination/011.php b/user_guide_src/source/libraries/pagination/011.php new file mode 100644 index 000000000000..fa59edbacf9b --- /dev/null +++ b/user_guide_src/source/libraries/pagination/011.php @@ -0,0 +1,7 @@ + 'CodeIgniter\Pager\Views\default_full', + 'default_simple' => 'CodeIgniter\Pager\Views\default_simple', + 'front_full' => 'App\Views\Pagers\foundation_full', +]; diff --git a/user_guide_src/source/libraries/pagination/012.php b/user_guide_src/source/libraries/pagination/012.php new file mode 100644 index 000000000000..00bdee764c7f --- /dev/null +++ b/user_guide_src/source/libraries/pagination/012.php @@ -0,0 +1,39 @@ +setSurroundCount(2) ?> + + diff --git a/user_guide_src/source/libraries/pagination/013.php b/user_guide_src/source/libraries/pagination/013.php index fa59edbacf9b..43a8f2624d64 100644 --- a/user_guide_src/source/libraries/pagination/013.php +++ b/user_guide_src/source/libraries/pagination/013.php @@ -1,7 +1,7 @@ 'CodeIgniter\Pager\Views\default_full', - 'default_simple' => 'CodeIgniter\Pager\Views\default_simple', - 'front_full' => 'App\Views\Pagers\foundation_full', +$link = [ + 'active' => false, + 'uri' => 'https://example.com/foo?page=2', + 'title' => 1, ]; diff --git a/user_guide_src/source/libraries/pagination/014.php b/user_guide_src/source/libraries/pagination/014.php index 00bdee764c7f..e827bd15a457 100644 --- a/user_guide_src/source/libraries/pagination/014.php +++ b/user_guide_src/source/libraries/pagination/014.php @@ -1,39 +1,37 @@ -setSurroundCount(2) ?> - -
    +?> + + + diff --git a/user_guide_src/source/outgoing/table/015.php b/user_guide_src/source/outgoing/table/015.php index 4f4349ec66b4..5bc5a7029ed3 100644 --- a/user_guide_src/source/outgoing/table/015.php +++ b/user_guide_src/source/outgoing/table/015.php @@ -6,15 +6,28 @@ $table->generate($newList); -// Generates a table with this prototype +?> +
    BlueRedGreenBlueRedGreen
    - - - - - - - - + + + + + + + + + + + + + + + + + + + +
    onetwothree
    fourfivesix
    seveneightnine
    teneleventwelve
    onetwothree
    fourfivesix
    seveneightnine
    teneleventwelve
    diff --git a/user_guide_src/source/outgoing/view_decorators.rst b/user_guide_src/source/outgoing/view_decorators.rst index 1620446785b0..83f3154f54c5 100644 --- a/user_guide_src/source/outgoing/view_decorators.rst +++ b/user_guide_src/source/outgoing/view_decorators.rst @@ -18,7 +18,6 @@ the resulting HTML. Once created, the class must be registered in ``app/Config/View.php``: .. literalinclude:: view_decorators/002.php - :lines: 2- Now that it's registered the decorator will be called for every view that is rendered or parsed. Decorators are called in the order specified in this configuration setting. diff --git a/user_guide_src/source/outgoing/view_layouts.rst b/user_guide_src/source/outgoing/view_layouts.rst index 2dca286b6052..2600b1c08922 100644 --- a/user_guide_src/source/outgoing/view_layouts.rst +++ b/user_guide_src/source/outgoing/view_layouts.rst @@ -80,7 +80,6 @@ Rendering the View Rendering the view and it's layout is done exactly as any other view would be displayed within a controller: .. literalinclude:: view_layouts/001.php - :lines: 2- It renders the View **app/Views/some_view.php** and if it extends ``default``, the Layout **app/Views/default.php** is also used automatically. diff --git a/user_guide_src/source/outgoing/view_parser.rst b/user_guide_src/source/outgoing/view_parser.rst index ef17f8d7fa6e..cee76727ef84 100644 --- a/user_guide_src/source/outgoing/view_parser.rst +++ b/user_guide_src/source/outgoing/view_parser.rst @@ -46,13 +46,11 @@ Using the View Parser Class The simplest method to load the parser class is through its service: .. literalinclude:: view_parser/001.php - :lines: 2- Alternately, if you are not using the ``Parser`` class as your default renderer, you can instantiate it directly: .. literalinclude:: view_parser/002.php - :lines: 2- Then you can use any of the three standard rendering methods that it provides: ``render(viewpath, options, save)``, ``setVar(name, value, context)`` and @@ -90,7 +88,6 @@ You can use the ``render()`` method to parse (or render) simple templates, like this: .. literalinclude:: view_parser/003.php - :lines: 2- View parameters are passed to ``setData()`` as an associative array of data to be replaced in the template. In the above example, the @@ -114,7 +111,6 @@ Several options can be passed to the ``render()`` or ``renderString()`` methods. substitutions; default is **true** .. literalinclude:: view_parser/004.php - :lines: 2- *********************** Substitution Variations @@ -128,7 +124,6 @@ replacement of pseudo-variables where the corresponding data parameter has either a scalar or string value, as in this example: .. literalinclude:: view_parser/005.php - :lines: 2- The ``Parser`` takes substitution a lot further with "variable pairs", used for nested substitutions or looping, and with some advanced @@ -176,7 +171,6 @@ parse single variables, except, you will add a multi-dimensional array corresponding to your variable pair data. Consider this example: .. literalinclude:: view_parser/006.php - :lines: 2- The value for the pseudo-variable ``blog_entries`` is a sequential array of associative arrays. The outer level does not have keys associated @@ -187,7 +181,6 @@ multi-dimensional array, you can simply use the database ``getResultArray()`` method: .. literalinclude:: view_parser/007.php - :lines: 2- If the array you are trying to loop over contains objects instead of arrays, the parser will first look for an ``asArray()`` method on the object. If it exists, @@ -206,7 +199,6 @@ A nested substitution happens when the value for a pseudo-variable is an associative array of values, like a record from a database: .. literalinclude:: view_parser/008.php - :lines: 2- The value for the pseudo-variable ``blog_entry`` is an associative array. The key/value pairs defined inside it will be exposed inside @@ -250,12 +242,10 @@ data pairs into the inner substitution. The following example is not impacted by cascading: .. literalinclude:: view_parser/009.php - :lines: 2- This example gives different results, depending on cascading: .. literalinclude:: view_parser/010.php - :lines: 2- Preventing Parsing ================== @@ -414,7 +404,6 @@ You can easily create your own filters by editing **app/Config/View.php** and ad callable: .. literalinclude:: view_parser/012.php - :lines: 2- PHP Native functions as Filters ------------------------------- @@ -424,7 +413,6 @@ You can use native php function as filters by editing **app/Config/View.php** an function prefixed with: .. literalinclude:: view_parser/013.php - :lines: 2- Parser Plugins ============== @@ -482,24 +470,20 @@ At its simplest, all you need to do to register a new plugin and make it ready f used within the template file. The value is any valid PHP callable, including static class methods, and closures: .. literalinclude:: view_parser/014.php - :lines: 2- Any closures that are being used must be defined in the config file's constructor: .. literalinclude:: view_parser/015.php - :lines: 2- If the callable is on its own, it is treated as a single tag, not a open/close one. It will be replaced by the return value from the plugin: .. literalinclude:: view_parser/016.php - :lines: 2- If the callable is wrapped in an array, it is treated as an open/close tag pair that can operate on any of the content between its tags: .. literalinclude:: view_parser/017.php - :lines: 2- *********** Usage Notes @@ -509,20 +493,17 @@ If you include substitution parameters that are not referenced in your template, they are ignored: .. literalinclude:: view_parser/018.php - :lines: 2- If you do not include a substitution parameter that is referenced in your template, the original pseudo-variable is shown in the result: .. literalinclude:: view_parser/019.php - :lines: 2- If you provide a string substitution parameter when an array is expected, i.e., for a variable pair, the substitution is done for the opening variable pair tag, but the closing variable pair tag is not rendered properly: .. literalinclude:: view_parser/020.php - :lines: 2- View Fragments ============== @@ -558,7 +539,6 @@ An example with the iteration controlled in the controller, using a view fragment: .. literalinclude:: view_parser/021.php - :lines: 2- Result:: @@ -584,7 +564,6 @@ Class Reference Builds the output based upon a file name and any data that has already been set: .. literalinclude:: view_parser/022.php - :lines: 2- Options supported: @@ -609,7 +588,6 @@ Class Reference Builds the output based upon a provided template source and any data that has already been set: .. literalinclude:: view_parser/023.php - :lines: 2- Options supported, and behavior, as above. @@ -623,7 +601,6 @@ Class Reference Sets several pieces of view data at once: .. literalinclude:: view_parser/024.php - :lines: 2- Supported escape contexts: html, css, js, url, or attr or raw. If 'raw', no escaping will happen. @@ -639,7 +616,6 @@ Class Reference Sets a single piece of view data: .. literalinclude:: view_parser/025.php - :lines: 2- Supported escape contexts: html, css, js, url, attr or raw. If 'raw', no escaping will happen. @@ -654,4 +630,3 @@ Class Reference Override the substitution field delimiters: .. literalinclude:: view_parser/026.php - :lines: 2- diff --git a/user_guide_src/source/outgoing/view_renderer.rst b/user_guide_src/source/outgoing/view_renderer.rst index bf1570cede9c..feda1affda3d 100644 --- a/user_guide_src/source/outgoing/view_renderer.rst +++ b/user_guide_src/source/outgoing/view_renderer.rst @@ -15,13 +15,11 @@ exactly what you want, you may find times where you want to work with it more di In that case you can access the View service directly: .. literalinclude:: view_renderer/001.php - :lines: 2- Alternately, if you are not using the ``View`` class as your default renderer, you can instantiate it directly: .. literalinclude:: view_renderer/002.php - :lines: 2- .. important:: You should create services only within controllers. If you need access to the View class from a library, you should set that as a dependency @@ -54,7 +52,6 @@ The ``setVar()`` and ``setData()`` methods are chainable, allowing you to combin number of different calls together in a chain: .. literalinclude:: view_renderer/003.php - :lines: 2- Escaping Data ============= @@ -66,7 +63,6 @@ escape the data for. See below for context descriptions. If you don't want the data to be escaped, you can pass ``null`` or ``'raw'`` as the final parameter to each function: .. literalinclude:: view_renderer/004.php - :lines: 2- If you choose not to escape data, or you are passing in an object instance, you can manually escape the data within the view with the ``esc()`` function. The first parameter is the string to escape. The second parameter is the @@ -123,7 +119,6 @@ Class Reference Builds the output based upon a file name and any data that has already been set: .. literalinclude:: view_renderer/005.php - :lines: 2- .. php:method:: renderString($view[, $options[, $saveData = false]]) :noindex: @@ -137,7 +132,6 @@ Class Reference Builds the output based upon a view fragment and any data that has already been set: .. literalinclude:: view_renderer/006.php - :lines: 2- .. warning:: This could be used for displaying content that might have been stored in a database, but you need to be aware that this is a potential security vulnerability, @@ -155,7 +149,6 @@ Class Reference Sets several pieces of view data at once: .. literalinclude:: view_renderer/007.php - :lines: 2- Supported escape contexts: ``html``, ``css``, ``js``, ``url``, or ``attr`` or ``raw``. If ``'raw'``, no escaping will happen. @@ -175,7 +168,6 @@ Class Reference Sets a single piece of view data: .. literalinclude:: view_renderer/008.php - :lines: 2- Supported escape contexts: ``html``, ``css``, ``js``, ``url``, ``attr`` or ``raw``. If ``'raw'``, no escaping will happen. diff --git a/user_guide_src/source/outgoing/views.rst b/user_guide_src/source/outgoing/views.rst index 2960a3c3c79a..55da9ed98a22 100644 --- a/user_guide_src/source/outgoing/views.rst +++ b/user_guide_src/source/outgoing/views.rst @@ -38,7 +38,6 @@ Displaying a View To load and display a particular view file you will use the following function: .. literalinclude:: views/001.php - :lines: 2- Where *name* is the name of your view file. @@ -73,7 +72,6 @@ Your view files can also be stored within sub-directories if you prefer that typ When doing so you will need to include the directory name loading the view. Example: .. literalinclude:: views/004.php - :lines: 2- Namespaced Views ================ @@ -87,7 +85,6 @@ under the namespace ``Example\Blog``, you could retrieve view files as if they w example, you could load the **blog_view.php** file from **example/blog/Views** by prepending the namespace to the view name: .. literalinclude:: views/005.php - :lines: 2- .. _caching-views: @@ -98,13 +95,11 @@ You can cache a view with the ``view`` command by passing a ``cache`` option wit the view for, in the third parameter: .. literalinclude:: views/006.php - :lines: 2- By default, the view will be cached using the same name as the view file itself. You can customize this by passing along ``cache_name`` and the cache ID you wish to use: .. literalinclude:: views/007.php - :lines: 2- Adding Dynamic Data to the View =============================== @@ -113,7 +108,6 @@ Data is passed from the controller to the view by way of an array in the second Here's an example: .. literalinclude:: views/008.php - :lines: 2- Let's try it with your controller file. Open it and add this code: @@ -138,7 +132,6 @@ other views, potentially causing issues. If you would prefer the data to persist into the `$option` array in the third parameter. .. literalinclude:: views/010.php - :lines: 2- Additionally, if you would like the default functionality of the view function to be that it does save the data between calls, you can set ``$saveData`` to **true** in **app/Config/Views.php**. diff --git a/user_guide_src/source/testing/benchmark.rst b/user_guide_src/source/testing/benchmark.rst index 33fe7c200be9..1e7a5c9607b7 100644 --- a/user_guide_src/source/testing/benchmark.rst +++ b/user_guide_src/source/testing/benchmark.rst @@ -26,12 +26,10 @@ The ``start()`` methods takes a single parameter: the name of this timer. You ca of the timer. It is only used for you to reference later to know which measurement is which: .. literalinclude:: benchmark/001.php - :lines: 2- The ``stop()`` method takes the name of the timer that you want to stop as the only parameter, also: .. literalinclude:: benchmark/002.php - :lines: 2- The name is not case-sensitive, but otherwise must match the name you gave it when you started the timer. @@ -39,7 +37,6 @@ Alternatively, you can use the :doc:`global function and stop timers: .. literalinclude:: benchmark/003.php - :lines: 2- Viewing Your Benchmark Points ============================= @@ -49,13 +46,11 @@ not automatically display them, though. You can retrieve all of your timers by c This returns an array of benchmark information, including start, end, and duration: .. literalinclude:: benchmark/004.php - :lines: 2- You can change the precision of the calculated duration by passing in the number of decimal places you want to be shown as the only parameter. The default value is 4 numbers behind the decimal point: .. literalinclude:: benchmark/005.php - :lines: 2- The timers are automatically displayed in the :doc:`Debub Toolbar `. @@ -67,7 +62,6 @@ the duration of a single timer, in seconds, with the `getElapsedTime()` method. the timer to display. The second is the number of decimal places to display. This defaults to 4: .. literalinclude:: benchmark/006.php - :lines: 2- ================== Using the Iterator @@ -86,7 +80,6 @@ added to the Iterator class through the `add()` method. The first parameter is a this test by. The second parameter is the Closure, itself: .. literalinclude:: benchmark/007.php - :lines: 2- Running the Tasks ================= @@ -96,10 +89,8 @@ By default, it will run each task 1000 times. This is probably sufficient for mo to run the tests more times than that, you can pass the number as the first parameter: .. literalinclude:: benchmark/008.php - :lines: 2- Once it has run, it will return an HTML table with the results of the test. If you don't want the results displayed, you can pass in `false` as the second parameter: .. literalinclude:: benchmark/009.php - :lines: 2- diff --git a/user_guide_src/source/testing/controllers.rst b/user_guide_src/source/testing/controllers.rst index 590e491ed687..604a118e4ead 100644 --- a/user_guide_src/source/testing/controllers.rst +++ b/user_guide_src/source/testing/controllers.rst @@ -37,14 +37,12 @@ Specifies the class name of the controller to test. The first parameter must be (i.e., include the namespace): .. literalinclude:: controllers/003.php - :lines: 2- **execute(string $method, ...$params)** Executes the specified method within the controller. The first parameter is the name of the method to run: .. literalinclude:: controllers/004.php - :lines: 2- By specifying the second and subsequent parameters, you can pass them to the controller method. @@ -56,7 +54,6 @@ for details. Allows you to pass in a modified version of **Config\App.php** to test with different settings: .. literalinclude:: controllers/005.php - :lines: 2- If you do not provide one, the application's App config file will be used. @@ -65,7 +62,6 @@ If you do not provide one, the application's App config file will be used. Allows you to provide an **IncomingRequest** instance tailored to your testing needs: .. literalinclude:: controllers/006.php - :lines: 2- If you do not provide one, a new IncomingRequest instance with the default application values will be passed into your controller. @@ -75,7 +71,6 @@ into your controller. Allows you to provide a **Response** instance: .. literalinclude:: controllers/007.php - :lines: 2- If you do not provide one, a new Response instance with the default application values will be passed into your controller. @@ -85,7 +80,6 @@ into your controller. Allows you to provide a **Logger** instance: .. literalinclude:: controllers/008.php - :lines: 2- If you do not provide one, a new Logger instance with the default configuration values will be passed into your controller. @@ -97,7 +91,6 @@ This is helpful if you need to check URI segments within your controller. The on representing a valid URI: .. literalinclude:: controllers/009.php - :lines: 2- It is a good practice to always provide the URI during testing to avoid surprises. @@ -107,7 +100,6 @@ Allows you to provide a custom body for the request. This can be helpful when te you need to set a JSON value as the body. The only parameter is a string that represents the body of the request: .. literalinclude:: controllers/010.php - :lines: 2- Checking the Response ===================== @@ -149,7 +141,6 @@ a "live" project, but (for example) if you wanted to simulate a filter triggerin on an unfiltered route you could add it to the Config: .. literalinclude:: controllers/012.php - :lines: 2- Checking Routes --------------- @@ -169,7 +160,6 @@ a large performance advantage over Controller and HTTP Testing. Usage example: .. literalinclude:: controllers/013.php - :lines: 2- Calling Filter Methods ---------------------- @@ -188,7 +178,6 @@ method using these properties to test your Filter code safely and check the resu Usage example: .. literalinclude:: controllers/014.php - :lines: 2- Notice how the ``Closure`` can take input parameters which are passed to your filter method. @@ -201,19 +190,15 @@ to streamline your test methods. The **assertFilter()** method checks that the given route at position uses the filter (by its alias): .. literalinclude:: controllers/015.php - :lines: 2- The **assertNotFilter()** method checks that the given route at position does not use the filter (by its alias): .. literalinclude:: controllers/016.php - :lines: 2- The **assertHasFilters()** method checks that the given route at position has at least one filter set: .. literalinclude:: controllers/017.php - :lines: 2- The **assertNotHasFilters()** method checks that the given route at position has no filters set: .. literalinclude:: controllers/018.php - :lines: 2- diff --git a/user_guide_src/source/testing/database.rst b/user_guide_src/source/testing/database.rst index 614099449e29..680c0a3f3518 100644 --- a/user_guide_src/source/testing/database.rst +++ b/user_guide_src/source/testing/database.rst @@ -110,14 +110,12 @@ must be present within the path specified in ``$basePath``. Asserts that a row with criteria matching the key/value pairs in ``$criteria`` DOES NOT exist in the database. .. literalinclude:: database/004.php - :lines: 2- **seeInDatabase($table, $criteria)** Asserts that a row with criteria matching the key/value pairs in ``$criteria`` DOES exist in the database. .. literalinclude:: database/005.php - :lines: 2- **grabFromDatabase($table, $column, $criteria)** @@ -125,7 +123,6 @@ Returns the value of ``$column`` from the specified table where the row matches row is found, it will only test against the first one. .. literalinclude:: database/006.php - :lines: 2- **hasInDatabase($table, $data)** @@ -133,11 +130,9 @@ Inserts a new row into the database. This row is removed after the current test array with the data to insert into the table. .. literalinclude:: database/007.php - :lines: 2- **seeNumRecords($expected, $table, $criteria)** Asserts that a number of matching rows are found in the database that match ``$criteria``. .. literalinclude:: database/008.php - :lines: 2- diff --git a/user_guide_src/source/testing/debugging.rst b/user_guide_src/source/testing/debugging.rst index 0b841517846e..fc04a08921d5 100644 --- a/user_guide_src/source/testing/debugging.rst +++ b/user_guide_src/source/testing/debugging.rst @@ -32,7 +32,6 @@ The ``d()`` method dumps all of the data it knows about the contents passed as t allows the script to continue executing: .. literalinclude:: debugging/001.php - :lines: 2- **dd()** @@ -43,7 +42,6 @@ This method is identical to ``d()``, except that it also ``dies()`` and no furth This provides a backtrace to the current execution point, with Kint's own unique spin: .. literalinclude:: debugging/002.php - :lines: 2- For more information, see `Kint's page `_. @@ -79,7 +77,6 @@ can easily make your own to customize the toolbar. To determine which collectors the **app/Config/Toolbar.php** configuration file: .. literalinclude:: debugging/003.php - :lines: 2- Comment out any collectors that you do not want to show. Add custom Collectors here by providing the fully-qualified class name. The exact collectors that appear here will affect which tabs are shown, as well as what information is @@ -159,7 +156,6 @@ The ``formatTimelineData()`` method must return an array of arrays formatted in it to sort it correctly and display the correct information. The inner arrays must include the following information: .. literalinclude:: debugging/005.php - :lines: 2- Providing Vars -------------- @@ -173,4 +169,3 @@ The ``getVarData()`` method should return an array containing arrays of key/valu outer array's key is the name of the section on the Vars tab: .. literalinclude:: debugging/006.php - :lines: 2- diff --git a/user_guide_src/source/testing/fabricator.rst b/user_guide_src/source/testing/fabricator.rst index 3e419353ef07..9acec31b5db2 100644 --- a/user_guide_src/source/testing/fabricator.rst +++ b/user_guide_src/source/testing/fabricator.rst @@ -17,7 +17,6 @@ Supported Models You may use your own custom models by ensuring they implement ``CodeIgniter\Test\Interfaces\FabricatorModel``: .. literalinclude:: fabricator/001.php - :lines: 2- .. note:: In addition to methods, the interface outlines some necessary properties for the target model. Please see the interface code for details. @@ -27,12 +26,10 @@ Loading Fabricators At its most basic a fabricator takes the model to act on: .. literalinclude:: fabricator/002.php - :lines: 2- The parameter can be a string specifying the name of the model, or an instance of the model itself: .. literalinclude:: fabricator/003.php - :lines: 2- Defining Formatters =================== @@ -44,7 +41,6 @@ correspond with common formatters, or if you don't care much about the content o of the time you will want to specify the formatters to use as the second parameter to the constructor: .. literalinclude:: fabricator/004.php - :lines: 2- You can also change the formatters after a fabricator is initialized by using the ``setFormatters()`` method. @@ -55,7 +51,6 @@ to further limit the scope of random data. A fabricator will check its represent method where you can define exactly what the faked data should look like: .. literalinclude:: fabricator/005.php - :lines: 2- Notice in this example how the first three values are equivalent to the formatters from before. However for ``avatar`` we have requested an image size other than the default and ``login`` uses a conditional based on app configuration, @@ -64,7 +59,6 @@ You may want to keep your test data separate from your production models, so it a child class in your test support folder: .. literalinclude:: fabricator/006.php - :lines: 2- Localization ============ @@ -73,7 +67,6 @@ Faker supports a lot of different locales. Check their documentation to determin support your locale. Specify a locale in the third parameter while initiating a fabricator: .. literalinclude:: fabricator/007.php - :lines: 2- If no locale is specified it will use the one defined in **app/Config/App.php** as ``defaultLocale``. You can check the locale of an existing fabricator using its ``getLocale()`` method. @@ -84,23 +77,19 @@ Faking the Data Once you have a properly-initialized fabricator it is easy to generate test data with the ``make()`` command: .. literalinclude:: fabricator/008.php - :lines: 2- You might get back something like this: .. literalinclude:: fabricator/009.php - :lines: 2- You can also get a lot of them back by supplying a count: .. literalinclude:: fabricator/010.php - :lines: 2- The return type of ``make()`` mimics what is defined in the representative model, but you can force a type using the methods directly: .. literalinclude:: fabricator/011.php - :lines: 2- The return from ``make()`` is ready to be used in tests or inserted into the database. Alternatively ``Fabricator`` includes the ``create()`` command to insert it for you, and return the result. Due @@ -108,19 +97,16 @@ to model callbacks, database formatting, and special keys like primary and times from ``create()`` can differ from ``make()``. You might get back something like this: .. literalinclude:: fabricator/012.php - :lines: 2- Similar to ``make()`` you can supply a count to insert and return an array of objects: .. literalinclude:: fabricator/013.php - :lines: 2- Finally, there may be times you want to test with the full database object but you are not actually using a database. ``create()`` takes a second parameter to allowing mocking the object, returning the object with extra database fields above without actually touching the database: .. literalinclude:: fabricator/014.php - :lines: 2- Specifying Test Data ==================== @@ -130,23 +116,19 @@ compromising your formatters configuration. Rather then creating a new fabricato you can use ``setOverrides()`` to specify the value for any fields: .. literalinclude:: fabricator/015.php - :lines: 2- Now any data generated with ``make()`` or ``create()`` will always use "Bobby" for the ``first`` field: .. literalinclude:: fabricator/016.php - :lines: 2- ``setOverrides()`` can take a second parameter to indicate whether this should be a persistent override or only for a single action: .. literalinclude:: fabricator/017.php - :lines: 2- Notice after the first return the fabricator stops using the overrides: .. literalinclude:: fabricator/018.php - :lines: 2- If no second parameter is supplied then passed values will persist by default. @@ -157,12 +139,10 @@ Often all you will need is a one-and-done fake object for testing. The Test Help the ``fake($model, $overrides, $persist = true)`` function to do just this: .. literalinclude:: fabricator/019.php - :lines: 2- This is equivalent to: .. literalinclude:: fabricator/020.php - :lines: 2- If you just need a fake object without saving it to the database you can pass false into the persist parameter. @@ -179,7 +159,6 @@ Now you want to create fake users but don't want to assign them to a non-existan Your model's fake method could look like this: .. literalinclude:: fabricator/021.php - :lines: 2- Now creating a new user will ensure it is a part of a valid group: ``$user = fake(UserModel::class);`` diff --git a/user_guide_src/source/testing/feature.rst b/user_guide_src/source/testing/feature.rst index 36ab73d4eea2..df40937ed14b 100644 --- a/user_guide_src/source/testing/feature.rst +++ b/user_guide_src/source/testing/feature.rst @@ -31,12 +31,10 @@ superglobal variables for the HTTP verb you are using. So, a method of **GET** w populated, while a **post** request would have the **$_POST** array populated. .. literalinclude:: feature/002.php - :lines: 2- Shorthand methods for each of the HTTP verbs exist to ease typing and make things clearer: .. literalinclude:: feature/003.php - :lines: 2- .. note:: The ``$params`` array does not make sense for every HTTP verb, but is included for consistency. @@ -47,7 +45,6 @@ You can use a custom collection of routes by passing an array of "routes" into t override any existing routes in the system: .. literalinclude:: feature/004.php - :lines: 2- Each of the "routes" is a 3 element array containing the HTTP verb (or "add" for all), the URI to match, and the routing destination. @@ -60,7 +57,6 @@ of key/value pairs that should exist within the ``$_SESSION`` variable when this that the current values of ``$_SESSION`` should be used. This is handy for testing authentication and more. .. literalinclude:: feature/005.php - :lines: 2- Setting Headers --------------- @@ -69,7 +65,6 @@ You can set header values with the ``withHeaders()`` method. This takes an array passed as a header into the call: .. literalinclude:: feature/006.php - :lines: 2- Bypassing Events ---------------- @@ -78,7 +73,6 @@ Events are handy to use in your application, but can be problematic during testi to send out emails. You can tell the system to skip any event handling with the ``skipEvents()`` method: .. literalinclude:: feature/007.php - :lines: 2- Formatting The Request ----------------------- @@ -89,7 +83,6 @@ body of the request in the given format. This will also set the `Content-Type` h This is useful when testing JSON or XML API's so that you can set the request in the form that the controller will expect. .. literalinclude:: feature/008.php - :lines: 2- Setting the Body ---------------- diff --git a/user_guide_src/source/testing/mocking.rst b/user_guide_src/source/testing/mocking.rst index 8c4b8b54d222..967cfba7f634 100644 --- a/user_guide_src/source/testing/mocking.rst +++ b/user_guide_src/source/testing/mocking.rst @@ -17,7 +17,6 @@ Cache You can mock the cache with the ``mock()`` method, using the ``CacheFactory`` as its only parameter. .. literalinclude:: mocking/001.php - :lines: 2- While this returns an instance of ``CodeIgniter\Test\Mock\MockCache`` that you can use directly, it also inserts the mock into the Service class, so any calls within your code to ``service('cache')`` or ``Config\Services::cache()`` will @@ -33,7 +32,6 @@ You can instruct the mocked cache handler to never do any caching with the ``byp using the dummy handler and ensures that your test does not rely on cached data for your tests. .. literalinclude:: mocking/002.php - :lines: 2- Available Assertions -------------------- @@ -41,4 +39,3 @@ Available Assertions The following new assertions are available on the mocked class for using during testing: .. literalinclude:: mocking/003.php - :lines: 2- diff --git a/user_guide_src/source/testing/overview.rst b/user_guide_src/source/testing/overview.rst index 1b32a3337c63..b689a8e90259 100644 --- a/user_guide_src/source/testing/overview.rst +++ b/user_guide_src/source/testing/overview.rst @@ -86,26 +86,22 @@ Most tests require some preparation in order to run correctly. PHPUnit's ``TestC to help with staging and clean up: .. literalinclude:: overview/003.php - :lines: 2- The static methods run before and after the entire test case, whereas the local methods run between each test. If you implement any of these special functions make sure you run their parent as well so extended test cases do not interfere with staging: .. literalinclude:: overview/004.php - :lines: 2- In addition to these methods, ``CIUnitTestCase`` also comes with a convenience property for parameter-free methods you want run during set up and tear down: .. literalinclude:: overview/005.php - :lines: 2- You can see by default these handle the mocking of intrusive services, but your class may override that or provide their own: .. literalinclude:: overview/006.php - :lines: 2- Traits ------ @@ -117,7 +113,6 @@ of your test cases you could create an authentication trait with a set up method logged in user: .. literalinclude:: overview/007.php - :lines: 2- Additional Assertions --------------------- @@ -129,21 +124,18 @@ Additional Assertions Ensure that something you expected to be logged actually was: .. literalinclude:: overview/008.php - :lines: 2- **assertEventTriggered($eventName)** Ensure that an event you expected to be triggered actually was: .. literalinclude:: overview/009.php - :lines: 2- **assertHeaderEmitted($header, $ignoreCase = false)** Ensure that a header or cookie was actually emitted: .. literalinclude:: overview/010.php - :lines: 2- Note: the test case with this should be `run as a separate process in PHPunit `_. @@ -153,7 +145,6 @@ in PHPunit `_. @@ -164,7 +155,6 @@ For extended execution time testing, tests that the absolute difference between expected and actual time is within the prescribed tolerance: .. literalinclude:: overview/012.php - :lines: 2- The above test will allow the actual time to be either 660 or 661 seconds. @@ -174,7 +164,6 @@ For extended execution time testing, tests that the absolute difference between expected and actual time, formatted as strings, is within the prescribed tolerance: .. literalinclude:: overview/013.php - :lines: 2- The above test will allow the actual time to be either 660 or 661 seconds. @@ -190,7 +179,6 @@ Enables you to call private methods from outside the class. This returns a funct parameter is an instance of the class to test. The second parameter is the name of the method you want to call. .. literalinclude:: overview/014.php - :lines: 2- **getPrivateProperty($instance, $property)** @@ -198,7 +186,6 @@ Retrieves the value of a private/protected class property from an instance of a instance of the class to test. The second parameter is the name of the property. .. literalinclude:: overview/015.php - :lines: 2- **setPrivateProperty($instance, $property, $value)** @@ -206,7 +193,6 @@ Set a protected value within a class instance. The first parameter is an instanc parameter is the name of the property to set the value of. The third parameter is the value to set it to: .. literalinclude:: overview/016.php - :lines: 2- Mocking Services ================ @@ -222,7 +208,6 @@ This method allows you to define the exact instance that will be returned by the set properties of a service so that it behaves in a certain way, or replace a service with a mocked class. .. literalinclude:: overview/017.php - :lines: 2- The first parameter is the service that you are replacing. The name must match the function name in the Services class exactly. The second parameter is the instance to replace it with. @@ -246,7 +231,6 @@ static methods like **Services**, but they take an additional preceding paramete component name: .. literalinclude:: overview/018.php - :lines: 2- .. note:: All component Factories are reset by default between each test. Modify your test case's ``$setUpMethods`` if you need instances to persist. @@ -261,4 +245,3 @@ might be helpful. The ``CITestStreamFilter`` helps you capture the output from t An example demonstrating this inside one of your test cases: .. literalinclude:: overview/019.php - :lines: 2- diff --git a/user_guide_src/source/testing/response.rst b/user_guide_src/source/testing/response.rst index e39df524affc..99c44be38c62 100644 --- a/user_guide_src/source/testing/response.rst +++ b/user_guide_src/source/testing/response.rst @@ -8,7 +8,6 @@ from your test cases. Usually a ``TestResponse`` will be provided for you as a r create your own directly using any ``ResponseInterface``: .. literalinclude:: response/001.php - :lines: 2- .. contents:: :local: @@ -28,14 +27,12 @@ Accessing Request/Response You can access directly the Request object, if it was set during testing: .. literalinclude:: response/002.php - :lines: 2- **response()** This allows you direct access to the response object: .. literalinclude:: response/003.php - :lines: 2- Checking Response Status ------------------------ @@ -46,28 +43,24 @@ Returns a boolean true/false based on whether the response is perceived to be "o a response status code in the 200 or 300's. An empty body is not considered valid, unless in redirects. .. literalinclude:: response/004.php - :lines: 2- **assertOK()** This assertion simply uses the **isOK()** method to test a response. **assertNotOK** is the inverse of this assertion. .. literalinclude:: response/005.php - :lines: 2- **isRedirect()** Returns a boolean true/false based on whether the response is a redirected response. .. literalinclude:: response/006.php - :lines: 2- **assertRedirect()** Asserts that the Response is an instance of RedirectResponse. **assertNotRedirect** is the inverse of this assertion. .. literalinclude:: response/007.php - :lines: 2- **assertRedirectTo()** @@ -75,21 +68,18 @@ Asserts that the Response is an instance of RedirectResponse and the destination matches the uri given. .. literalinclude:: response/008.php - :lines: 2- **getRedirectUrl()** Returns the URL set for a RedirectResponse, or null for failure. .. literalinclude:: response/009.php - :lines: 2- **assertStatus(int $code)** Asserts that the HTTP status code returned matches $code. .. literalinclude:: response/010.php - :lines: 2- Session Assertions ------------------ @@ -100,14 +90,12 @@ Asserts that a value exists in the resulting session. If $value is passed, will matches what was specified. .. literalinclude:: response/011.php - :lines: 2- **assertSessionMissing(string $key)** Asserts that the resulting session does not include the specified $key. .. literalinclude:: response/012.php - :lines: 2- Header Assertions ----------------- @@ -118,14 +106,12 @@ Asserts that a header named **$key** exists in the response. If **$value** is no the values match. .. literalinclude:: response/013.php - :lines: 2- **assertHeaderMissing(string $key)** Asserts that a header name **$key** does not exist in the response. .. literalinclude:: response/014.php - :lines: 2- Cookie Assertions ----------------- @@ -136,14 +122,12 @@ Asserts that a cookie named **$key** exists in the response. If **$value** is no the values match. You can set the cookie prefix, if needed, by passing it in as the third parameter. .. literalinclude:: response/015.php - :lines: 2- **assertCookieMissing(string $key)** Asserts that a cookie named **$key** does not exist in the response. .. literalinclude:: response/016.php - :lines: 2- **assertCookieExpired(string $key, string $prefix = '')** @@ -151,7 +135,6 @@ Asserts that a cookie named **$key** exists, but has expired. You can set the co in as the second parameter. .. literalinclude:: response/017.php - :lines: 2- DOM Helpers ----------- @@ -163,33 +146,27 @@ The **see()** method checks the text on the page to see if it exists either by i a tag, as specified by type, class, or id: .. literalinclude:: response/018.php - :lines: 2- The **dontSee()** method is the exact opposite: .. literalinclude:: response/019.php - :lines: 2- The **seeElement()** and **dontSeeElement()** are very similar to the previous methods, but do not look at the values of the elements. Instead, they simply check that the elements exist on the page: .. literalinclude:: response/020.php - :lines: 2- You can use **seeLink()** to ensure that a link appears on the page with the specified text: .. literalinclude:: response/021.php - :lines: 2- The **seeInField()** method checks for any input tags exist with the name and value: .. literalinclude:: response/022.php - :lines: 2- Finally, you can check if a checkbox exists and is checked with the **seeCheckboxIsChecked()** method: .. literalinclude:: response/023.php - :lines: 2- DOM Assertions -------------- @@ -203,21 +180,18 @@ Asserts that text/HTML is on the page, either by itself or - more specifically - a tag, as specified by type, class, or id: .. literalinclude:: response/024.php - :lines: 2- **assertDontSee(string $search = null, string $element = null)** Asserts the exact opposite of the **assertSee()** method: .. literalinclude:: response/025.php - :lines: 2- **assertSeeElement(string $search)** Similar to **assertSee()**, however this only checks for an existing element. It does not check for specific text: .. literalinclude:: response/026.php - :lines: 2- **assertDontSeeElement(string $search)** @@ -225,21 +199,18 @@ Similar to **assertSee()**, however this only checks for an existing element tha specific text: .. literalinclude:: response/027.php - :lines: 2- **assertSeeLink(string $text, string $details=null)** Asserts that an anchor tag is found with matching **$text** as the body of the tag: .. literalinclude:: response/028.php - :lines: 2- **assertSeeInField(string $field, string $value=null)** Asserts that an input tag exists with the name and value: .. literalinclude:: response/029.php - :lines: 2- Working With JSON ----------------- @@ -252,12 +223,10 @@ can help to test the responses. This method will return the body of the response as a JSON string: .. literalinclude:: response/030.php - :lines: 2- You can use this method to determine if ``$response`` actually holds JSON content: .. literalinclude:: response/031.php - :lines: 2- .. note:: Be aware that the JSON string will be pretty-printed in the result. @@ -266,7 +235,6 @@ You can use this method to determine if ``$response`` actually holds JSON conten Asserts that $fragment is found within the JSON response. It does not need to match the entire JSON value. .. literalinclude:: response/032.php - :lines: 2- **assertJSONExact($test)** diff --git a/user_guide_src/source/tutorial/create_news_items.rst b/user_guide_src/source/tutorial/create_news_items.rst index acf04e52d0f6..7925edc05fd1 100644 --- a/user_guide_src/source/tutorial/create_news_items.rst +++ b/user_guide_src/source/tutorial/create_news_items.rst @@ -14,7 +14,6 @@ Before creating a form, let's enable the CSRF protection. Open the **app/Config/Filters.php** file and update the ``$methods`` property like the following: .. literalinclude:: create_news_items/001.php - :lines: 2- It configures the CSRF filter to be enabled for all **POST** requests. You can read more about the CSRF protection in :doc:`Security ` library. @@ -67,7 +66,6 @@ passed the validation rules. You'll use the :doc:`form validation <../libraries/validation>` library to do this. .. literalinclude:: create_news_items/002.php - :lines: 2- The code above adds a lot of functionality. First we load the NewsModel. After that, we check if we deal with the **POST** request and then @@ -130,7 +128,6 @@ as a method instead of a news item's slug. You can read more about different routing types :doc:`here `. .. literalinclude:: create_news_items/004.php - :lines: 2- Now point your browser to your local development environment where you installed CodeIgniter and add ``/news/create`` to the URL. diff --git a/user_guide_src/source/tutorial/news_section.rst b/user_guide_src/source/tutorial/news_section.rst index f51e68c5abc7..9a144dd06c19 100644 --- a/user_guide_src/source/tutorial/news_section.rst +++ b/user_guide_src/source/tutorial/news_section.rst @@ -93,7 +93,6 @@ some additional tools to make working with data simpler. Add the following code to your model. .. literalinclude:: news_section/002.php - :lines: 2- With this code, you can perform two different queries. You can get all news records, or get a news item by its slug. You might have @@ -140,7 +139,6 @@ nothing is displayed yet. The next thing to do is, passing this data to the views. Modify the ``index()`` method to look like this: .. literalinclude:: news_section/004.php - :lines: 2- The code above gets all news records from the model and assigns it to a variable. The value for the title is also assigned to the ``$data['title']`` @@ -167,7 +165,6 @@ add some code to the controller and create a new view. Go back to the ``News`` controller and update the ``view()`` method with the following: .. literalinclude:: news_section/006.php - :lines: 2- Instead of calling the ``getNews()`` method without a parameter, the ``$slug`` variable is passed, so it will return the specific news item. @@ -187,7 +184,6 @@ going directly to the ``Pages`` controller. The first line routes URI's with a slug to the ``view()`` method in the ``News`` controller. .. literalinclude:: news_section/008.php - :lines: 2- Point your browser to your "news" page, i.e., ``localhost:8080/news``, you should see a list of the news items, each of which has a link diff --git a/user_guide_src/source/tutorial/static_pages.rst b/user_guide_src/source/tutorial/static_pages.rst index a5bcaf7fa94b..090a4d79e2f8 100644 --- a/user_guide_src/source/tutorial/static_pages.rst +++ b/user_guide_src/source/tutorial/static_pages.rst @@ -102,7 +102,6 @@ page actually exists. This will be the body of the ``view()`` method in the ``Pages`` controller created above: .. literalinclude:: static_pages/002.php - :lines: 2- Now, when the requested page does exist, it is loaded, including the header and footer, and displayed to the user. If the requested page doesn't exist, a "404 @@ -196,7 +195,6 @@ section of the configuration file. The only uncommented line there to start with should be: .. literalinclude:: static_pages/003.php - :lines: 2- This directive says that any incoming request without any content specified should be handled by the ``index()`` method inside the ``Home`` controller. @@ -204,7 +202,6 @@ specified should be handled by the ``index()`` method inside the ``Home`` contro Add the following line, **after** the route directive for '/'. .. literalinclude:: static_pages/004.php - :lines: 2- CodeIgniter reads its routing rules from top to bottom and routes the request to the first matching rule. Each rule is a regular expression From e5bc03d8037fc1791ef912a85938fd0dabdfd00c Mon Sep 17 00:00:00 2001 From: Andrey Pyzhikov <5071@mail.ru> Date: Sat, 26 Feb 2022 07:59:09 +0800 Subject: [PATCH 0585/1246] Update tests/system/Database/Builder/BaseTest.php Co-authored-by: kenjis --- tests/system/Database/Builder/BaseTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/system/Database/Builder/BaseTest.php b/tests/system/Database/Builder/BaseTest.php index 5a2a4f1578db..c7386066aa74 100644 --- a/tests/system/Database/Builder/BaseTest.php +++ b/tests/system/Database/Builder/BaseTest.php @@ -63,6 +63,5 @@ public function testSubquerySameBaseBuilderObject() $builder = $this->db->table('users'); $builder->fromSubquery($builder, 'sub'); - $builder->getCompiledSelect(); } } From ab30e0ef0cf9c4b41db3792feea352a53d005e1e Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 26 Feb 2022 11:45:43 +0900 Subject: [PATCH 0586/1246] test: fix failed tests --- tests/system/Commands/RoutesTest.php | 5 +++++ tests/system/Commands/ScaffoldGeneratorTest.php | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/tests/system/Commands/RoutesTest.php b/tests/system/Commands/RoutesTest.php index 0f569a2e42ad..dd5e6b3280a8 100644 --- a/tests/system/Commands/RoutesTest.php +++ b/tests/system/Commands/RoutesTest.php @@ -26,6 +26,8 @@ final class RoutesTest extends CIUnitTestCase protected function setUp(): void { + $this->resetServices(); + parent::setUp(); CITestStreamFilter::$buffer = ''; @@ -40,6 +42,8 @@ protected function setUp(): void protected function tearDown(): void { stream_filter_remove($this->streamFilter); + + $this->resetServices(); } protected function getBuffer() @@ -60,6 +64,7 @@ public function testRoutesCommand() public function testRoutesCommandRouteFilterAndAutoRoute() { $routes = Services::routes(); + $routes->setDefaultNamespace('App\Controllers'); $routes->resetRoutes(); $routes->get('/', 'Home::index', ['filter' => 'csrf']); diff --git a/tests/system/Commands/ScaffoldGeneratorTest.php b/tests/system/Commands/ScaffoldGeneratorTest.php index d3cbf1088f30..3aa6164cc2c5 100644 --- a/tests/system/Commands/ScaffoldGeneratorTest.php +++ b/tests/system/Commands/ScaffoldGeneratorTest.php @@ -13,6 +13,9 @@ use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\Filters\CITestStreamFilter; +use Config\Autoload; +use Config\Modules; +use Config\Services; /** * @internal @@ -23,6 +26,9 @@ final class ScaffoldGeneratorTest extends CIUnitTestCase protected function setUp(): void { + $this->resetServices(); + Services::autoloader()->initialize(new Autoload(), new Modules()); + CITestStreamFilter::$buffer = ''; $this->streamFilter = stream_filter_append(STDOUT, 'CITestStreamFilter'); From 257392b70a80c023c96dd56f2a5ee699d1c2da47 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 26 Feb 2022 11:46:51 +0900 Subject: [PATCH 0587/1246] test: remove deprecated `session:migration` command test --- .../system/Commands/SessionsCommandsTest.php | 76 ------------------- 1 file changed, 76 deletions(-) diff --git a/tests/system/Commands/SessionsCommandsTest.php b/tests/system/Commands/SessionsCommandsTest.php index 6af2d09bf536..e69de29bb2d1 100644 --- a/tests/system/Commands/SessionsCommandsTest.php +++ b/tests/system/Commands/SessionsCommandsTest.php @@ -1,76 +0,0 @@ - - * - * For the full copyright and license information, please view - * the LICENSE file that was distributed with this source code. - */ - -namespace CodeIgniter\Commands; - -use CodeIgniter\Test\CIUnitTestCase; -use CodeIgniter\Test\Filters\CITestStreamFilter; - -/** - * @internal - */ -final class SessionsCommandsTest extends CIUnitTestCase -{ - private $streamFilter; - - protected function setUp(): void - { - parent::setUp(); - - CITestStreamFilter::$buffer = ''; - - $this->streamFilter = stream_filter_append(STDOUT, 'CITestStreamFilter'); - $this->streamFilter = stream_filter_append(STDERR, 'CITestStreamFilter'); - } - - protected function tearDown(): void - { - stream_filter_remove($this->streamFilter); - - $result = str_replace(["\033[0;32m", "\033[0m", "\n"], '', CITestStreamFilter::$buffer); - $file = str_replace('APPPATH' . DIRECTORY_SEPARATOR, APPPATH, trim(substr($result, 14))); - if (file_exists($file)) { - unlink($file); - } - } - - public function testCreateMigrationCommand() - { - command('session:migration'); - - // make sure we end up with a migration class in the right place - // or at least that we claim to have done so - // separate assertions avoid console color codes - $this->assertStringContainsString('_CreateCiSessionsTable.php', CITestStreamFilter::$buffer); - } - - public function testOverriddenCreateMigrationCommand() - { - command('session:migration -t mygoodies'); - - // make sure we end up with a migration class in the right place - $this->assertStringContainsString('_CreateMygoodiesTable.php', CITestStreamFilter::$buffer); - } - - public function testCannotWriteFileOnCreateMigrationCommand() - { - if ('\\' === DIRECTORY_SEPARATOR) { - $this->markTestSkipped('chmod does not work as expected on Windows'); - } - - chmod(APPPATH . 'Database/Migrations', 0444); - - command('session:migration'); - $this->assertStringContainsString('Error while creating file:', CITestStreamFilter::$buffer); - - chmod(APPPATH . 'Database/Migrations', 0755); - } -} From e14e709ea29b476d0d0697319d9ee94b6cdf6a54 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 26 Feb 2022 11:59:26 +0900 Subject: [PATCH 0588/1246] test: add param to $this->resetService() --- system/Test/CIUnitTestCase.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/Test/CIUnitTestCase.php b/system/Test/CIUnitTestCase.php index 00d936cd4251..4fd3bca63016 100644 --- a/system/Test/CIUnitTestCase.php +++ b/system/Test/CIUnitTestCase.php @@ -299,9 +299,9 @@ protected function resetFactories() /** * Resets shared instanced for all Services */ - protected function resetServices() + protected function resetServices(bool $initAutoloader = false) { - Services::reset(); + Services::reset($initAutoloader); } /** From 7198b3b556c5bf8d9bc65a1400871cc4660ce4ae Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 26 Feb 2022 15:59:53 +0900 Subject: [PATCH 0589/1246] docs: fix title level and move "Organizing Your Controllers into Sub-directories" It is about auto-routing. --- .../source/incoming/controllers.rst | 82 +++++++++---------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/user_guide_src/source/incoming/controllers.rst b/user_guide_src/source/incoming/controllers.rst index 296e245bd35e..43a8c8d99f04 100644 --- a/user_guide_src/source/incoming/controllers.rst +++ b/user_guide_src/source/incoming/controllers.rst @@ -9,7 +9,7 @@ Controllers are the heart of your application, as they determine how HTTP reques :depth: 2 What is a Controller? -===================== +********************* A Controller is simply a class file that is named in a way that it can be associated with a URI. @@ -141,8 +141,40 @@ see the "Hello World" message. For more information, please refer to the :ref:`routes-configuration-options` section of the :doc:`URI Routing ` documentation. +Organizing Your Controllers into Sub-directories +================================================ + +If you are building a large application you might want to hierarchically +organize or structure your controllers into sub-directories. CodeIgniter +permits you to do this. + +Simply create sub-directories under the main **app/Controllers/**, +and place your controller classes within them. + +.. important:: Folder names MUST start with an uppercase letter and ONLY the first character can be uppercase. + +When using this feature the first segment of your URI must +specify the folder. For example, let's say you have a controller located here:: + + app/Controllers/Products/Shoes.php + +To call the above controller your URI will look something like this:: + + example.com/index.php/products/shoes/show/123 + +.. note:: You cannot have directories with the same name in **app/Controllers/** and **public/**. + This is because if there is a directory, the web server will search for it and + it will not be routed to CodeIgniter. + +Each of your sub-directories may contain a default controller which will be +called if the URL contains *only* the sub-directory. Simply put a controller +in there that matches the name of your default controller as specified in +your **app/Config/Routes.php** file. + +CodeIgniter also permits you to remap your URIs using its :doc:`URI Routing ` feature. + Remapping Method Calls -====================== +********************** As noted above, the second segment of the URI typically determines which method in the controller gets called. CodeIgniter permits you to override @@ -168,7 +200,7 @@ Example: .. literalinclude:: controllers/012.php Private methods -=============== +*************** In some cases, you may want certain methods hidden from public access. To achieve this, simply declare the method as ``private`` or ``protected``. @@ -181,40 +213,8 @@ then trying to access it using the following URL will not work:: example.com/index.php/helloworld/utility/ -Organizing Your Controllers into Sub-directories -================================================ - -If you are building a large application you might want to hierarchically -organize or structure your controllers into sub-directories. CodeIgniter -permits you to do this. - -Simply create sub-directories under the main **app/Controllers/**, -and place your controller classes within them. - -.. important:: Folder names MUST start with an uppercase letter and ONLY the first character can be uppercase. - -When using this feature the first segment of your URI must -specify the folder. For example, let's say you have a controller located here:: - - app/Controllers/Products/Shoes.php - -To call the above controller your URI will look something like this:: - - example.com/index.php/products/shoes/show/123 - -.. note:: You cannot have directories with the same name in **app/Controllers/** and **public/**. - This is because if there is a directory, the web server will search for it and - it will not be routed to CodeIgniter. - -Each of your sub-directories may contain a default controller which will be -called if the URL contains *only* the sub-directory. Simply put a controller -in there that matches the name of your default controller as specified in -your **app/Config/Routes.php** file. - -CodeIgniter also permits you to remap your URIs using its :doc:`URI Routing ` feature. - Included Properties -=================== +******************* Every controller you create should extend ``CodeIgniter\Controller`` class. This class provides several features that are available to all of your controllers. @@ -250,7 +250,7 @@ modify this by passing the duration (in seconds) as the first parameter: .. note:: A number of :doc:`time-based constants ` are always available for you to use, including ``YEAR``, ``MONTH``, and more. Helpers -------- +======= You can define an array of helper files as a class property. Whenever the controller is loaded these helper files will be automatically loaded into memory so that you can use their methods anywhere @@ -261,10 +261,10 @@ inside the controller: .. _controllers-validating-data: Validating data -=============== +*************** $this->validate() ------------------ +================= To simplify data checking, the controller also provides the convenience method ``validate()``. The method accepts an array of rules in the first parameter, @@ -284,7 +284,7 @@ the ``$rules`` array with the name of the group as defined in ``Config\Validatio .. note:: Validation can also be handled automatically in the model, but sometimes it's easier to do it in the controller. Where is up to you. $this->validateData() ---------------------- +===================== Sometimes you may want to check the controller method parameters or other custom data. In that case, you can use the ``$this->validateData()`` method. @@ -293,6 +293,6 @@ The method accepts an array of data to validate in the first parameter: .. literalinclude:: controllers/019.php That's it! -========== +********** That, in a nutshell, is all there is to know about controllers. From 31a941cf6508cd9d7ac6a6b44480052d03d96f2d Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 26 Feb 2022 16:04:54 +0900 Subject: [PATCH 0590/1246] docs: add section title "Auto Routing", and move the section below --- .../source/incoming/controllers.rst | 241 +++++++++--------- 1 file changed, 122 insertions(+), 119 deletions(-) diff --git a/user_guide_src/source/incoming/controllers.rst b/user_guide_src/source/incoming/controllers.rst index 43a8c8d99f04..277b17c0ae6a 100644 --- a/user_guide_src/source/incoming/controllers.rst +++ b/user_guide_src/source/incoming/controllers.rst @@ -13,6 +13,128 @@ What is a Controller? A Controller is simply a class file that is named in a way that it can be associated with a URI. +Remapping Method Calls +********************** + +As noted above, the second segment of the URI typically determines which +method in the controller gets called. CodeIgniter permits you to override +this behavior through the use of the ``_remap()`` method: + +.. literalinclude:: controllers/010.php + +.. important:: If your controller contains a method named ``_remap()``, + it will **always** get called regardless of what your URI contains. It + overrides the normal behavior in which the URI determines which method + is called, allowing you to define your own method routing rules. + +The overridden method call (typically the second segment of the URI) will +be passed as a parameter to the ``_remap()`` method: + +.. literalinclude:: controllers/011.php + +Any extra segments after the method name are passed into ``_remap()``. These parameters can be passed to the method +to emulate CodeIgniter's default behavior. + +Example: + +.. literalinclude:: controllers/012.php + +Private methods +*************** + +In some cases, you may want certain methods hidden from public access. +To achieve this, simply declare the method as ``private`` or ``protected``. +That will prevent it from being served by a URL request. For example, +if you were to define a method like this for the ``Helloworld`` controller: + +.. literalinclude:: controllers/013.php + +then trying to access it using the following URL will not work:: + + example.com/index.php/helloworld/utility/ + +Included Properties +******************* + +Every controller you create should extend ``CodeIgniter\Controller`` class. +This class provides several features that are available to all of your controllers. + +**Request Object** + +The application's main :doc:`Request Instance ` is always available +as a class property, ``$this->request``. + +**Response Object** + +The application's main :doc:`Response Instance ` is always available +as a class property, ``$this->response``. + +**Logger Object** + +An instance of the :doc:`Logger <../general/logging>` class is available as a class property, +``$this->logger``. + +**forceHTTPS** + +A convenience method for forcing a method to be accessed via HTTPS is available within all +controllers: + +.. literalinclude:: controllers/014.php + +By default, and in modern browsers that support the HTTP Strict Transport Security header, this +call should force the browser to convert non-HTTPS calls to HTTPS calls for one year. You can +modify this by passing the duration (in seconds) as the first parameter: + +.. literalinclude:: controllers/015.php + +.. note:: A number of :doc:`time-based constants ` are always available for you to use, including ``YEAR``, ``MONTH``, and more. + +Helpers +======= + +You can define an array of helper files as a class property. Whenever the controller is loaded +these helper files will be automatically loaded into memory so that you can use their methods anywhere +inside the controller: + +.. literalinclude:: controllers/016.php + +.. _controllers-validating-data: + +Validating data +*************** + +$this->validate() +================= + +To simplify data checking, the controller also provides the convenience method ``validate()``. +The method accepts an array of rules in the first parameter, +and in the optional second parameter, an array of custom error messages to display +if the items are not valid. Internally, this uses the controller's +``$this->request`` instance to get the data to be validated. +The :doc:`Validation Library docs ` have details on +rule and message array formats, as well as available rules: + +.. literalinclude:: controllers/017.php + +If you find it simpler to keep the rules in the configuration file, you can replace +the ``$rules`` array with the name of the group as defined in ``Config\Validation.php``: + +.. literalinclude:: controllers/018.php + +.. note:: Validation can also be handled automatically in the model, but sometimes it's easier to do it in the controller. Where is up to you. + +$this->validateData() +===================== + +Sometimes you may want to check the controller method parameters or other custom data. +In that case, you can use the ``$this->validateData()`` method. +The method accepts an array of data to validate in the first parameter: + +.. literalinclude:: controllers/019.php + +Auto Routing +************ + Consider this URI:: example.com/index.php/helloworld/ @@ -173,125 +295,6 @@ your **app/Config/Routes.php** file. CodeIgniter also permits you to remap your URIs using its :doc:`URI Routing ` feature. -Remapping Method Calls -********************** - -As noted above, the second segment of the URI typically determines which -method in the controller gets called. CodeIgniter permits you to override -this behavior through the use of the ``_remap()`` method: - -.. literalinclude:: controllers/010.php - -.. important:: If your controller contains a method named ``_remap()``, - it will **always** get called regardless of what your URI contains. It - overrides the normal behavior in which the URI determines which method - is called, allowing you to define your own method routing rules. - -The overridden method call (typically the second segment of the URI) will -be passed as a parameter to the ``_remap()`` method: - -.. literalinclude:: controllers/011.php - -Any extra segments after the method name are passed into ``_remap()``. These parameters can be passed to the method -to emulate CodeIgniter's default behavior. - -Example: - -.. literalinclude:: controllers/012.php - -Private methods -*************** - -In some cases, you may want certain methods hidden from public access. -To achieve this, simply declare the method as ``private`` or ``protected``. -That will prevent it from being served by a URL request. For example, -if you were to define a method like this for the ``Helloworld`` controller: - -.. literalinclude:: controllers/013.php - -then trying to access it using the following URL will not work:: - - example.com/index.php/helloworld/utility/ - -Included Properties -******************* - -Every controller you create should extend ``CodeIgniter\Controller`` class. -This class provides several features that are available to all of your controllers. - -**Request Object** - -The application's main :doc:`Request Instance ` is always available -as a class property, ``$this->request``. - -**Response Object** - -The application's main :doc:`Response Instance ` is always available -as a class property, ``$this->response``. - -**Logger Object** - -An instance of the :doc:`Logger <../general/logging>` class is available as a class property, -``$this->logger``. - -**forceHTTPS** - -A convenience method for forcing a method to be accessed via HTTPS is available within all -controllers: - -.. literalinclude:: controllers/014.php - -By default, and in modern browsers that support the HTTP Strict Transport Security header, this -call should force the browser to convert non-HTTPS calls to HTTPS calls for one year. You can -modify this by passing the duration (in seconds) as the first parameter: - -.. literalinclude:: controllers/015.php - -.. note:: A number of :doc:`time-based constants ` are always available for you to use, including ``YEAR``, ``MONTH``, and more. - -Helpers -======= - -You can define an array of helper files as a class property. Whenever the controller is loaded -these helper files will be automatically loaded into memory so that you can use their methods anywhere -inside the controller: - -.. literalinclude:: controllers/016.php - -.. _controllers-validating-data: - -Validating data -*************** - -$this->validate() -================= - -To simplify data checking, the controller also provides the convenience method ``validate()``. -The method accepts an array of rules in the first parameter, -and in the optional second parameter, an array of custom error messages to display -if the items are not valid. Internally, this uses the controller's -``$this->request`` instance to get the data to be validated. -The :doc:`Validation Library docs ` have details on -rule and message array formats, as well as available rules: - -.. literalinclude:: controllers/017.php - -If you find it simpler to keep the rules in the configuration file, you can replace -the ``$rules`` array with the name of the group as defined in ``Config\Validation.php``: - -.. literalinclude:: controllers/018.php - -.. note:: Validation can also be handled automatically in the model, but sometimes it's easier to do it in the controller. Where is up to you. - -$this->validateData() -===================== - -Sometimes you may want to check the controller method parameters or other custom data. -In that case, you can use the ``$this->validateData()`` method. -The method accepts an array of data to validate in the first parameter: - -.. literalinclude:: controllers/019.php - That's it! ********** From 1cb1ba695f0585e54f22d7fb3d52ba97d5d8ee17 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 26 Feb 2022 16:07:30 +0900 Subject: [PATCH 0591/1246] docs: add explanation for auto-routing --- user_guide_src/source/incoming/controllers.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/user_guide_src/source/incoming/controllers.rst b/user_guide_src/source/incoming/controllers.rst index 277b17c0ae6a..f21e1aa4d366 100644 --- a/user_guide_src/source/incoming/controllers.rst +++ b/user_guide_src/source/incoming/controllers.rst @@ -135,6 +135,15 @@ The method accepts an array of data to validate in the first parameter: Auto Routing ************ +This section describes the functionality of the auto-routing. +It automatically routes an HTTP request, and executes the corresponding controller method +without route definitions. The auto-routing is enabled by default. + +.. note:: To prevent misconfiguration and miscoding, we recommend that you disable + the auto-routing feature. See :ref:`use-defined-routes-only`. + +.. important:: The auto-routing routes a HTTP request with **any** HTTP method to a controller method. + Consider this URI:: example.com/index.php/helloworld/ From d8a1a0a6a46d11963ed6dda0879d56816f180c28 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 26 Feb 2022 16:07:52 +0900 Subject: [PATCH 0592/1246] docs: update what's controller --- user_guide_src/source/incoming/controllers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/incoming/controllers.rst b/user_guide_src/source/incoming/controllers.rst index f21e1aa4d366..fff2e02ff2ec 100644 --- a/user_guide_src/source/incoming/controllers.rst +++ b/user_guide_src/source/incoming/controllers.rst @@ -11,7 +11,7 @@ Controllers are the heart of your application, as they determine how HTTP reques What is a Controller? ********************* -A Controller is simply a class file that is named in a way that it can be associated with a URI. +A Controller is simply a class file that handles a HTTP request. :doc:`URI Routing ` associates a URI with a controller. Remapping Method Calls ********************** From 77efb6d96cec1b58bd8c536e02485313739b7f45 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 26 Feb 2022 16:09:42 +0900 Subject: [PATCH 0593/1246] docs: change the position of sections --- .../source/incoming/controllers.rst | 80 +++++++++---------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/user_guide_src/source/incoming/controllers.rst b/user_guide_src/source/incoming/controllers.rst index fff2e02ff2ec..dced7111a363 100644 --- a/user_guide_src/source/incoming/controllers.rst +++ b/user_guide_src/source/incoming/controllers.rst @@ -13,46 +13,6 @@ What is a Controller? A Controller is simply a class file that handles a HTTP request. :doc:`URI Routing ` associates a URI with a controller. -Remapping Method Calls -********************** - -As noted above, the second segment of the URI typically determines which -method in the controller gets called. CodeIgniter permits you to override -this behavior through the use of the ``_remap()`` method: - -.. literalinclude:: controllers/010.php - -.. important:: If your controller contains a method named ``_remap()``, - it will **always** get called regardless of what your URI contains. It - overrides the normal behavior in which the URI determines which method - is called, allowing you to define your own method routing rules. - -The overridden method call (typically the second segment of the URI) will -be passed as a parameter to the ``_remap()`` method: - -.. literalinclude:: controllers/011.php - -Any extra segments after the method name are passed into ``_remap()``. These parameters can be passed to the method -to emulate CodeIgniter's default behavior. - -Example: - -.. literalinclude:: controllers/012.php - -Private methods -*************** - -In some cases, you may want certain methods hidden from public access. -To achieve this, simply declare the method as ``private`` or ``protected``. -That will prevent it from being served by a URL request. For example, -if you were to define a method like this for the ``Helloworld`` controller: - -.. literalinclude:: controllers/013.php - -then trying to access it using the following URL will not work:: - - example.com/index.php/helloworld/utility/ - Included Properties ******************* @@ -132,6 +92,20 @@ The method accepts an array of data to validate in the first parameter: .. literalinclude:: controllers/019.php +Private methods +*************** + +In some cases, you may want certain methods hidden from public access. +To achieve this, simply declare the method as ``private`` or ``protected``. +That will prevent it from being served by a URL request. For example, +if you were to define a method like this for the ``Helloworld`` controller: + +.. literalinclude:: controllers/013.php + +then trying to access it using the following URL will not work:: + + example.com/index.php/helloworld/utility/ + Auto Routing ************ @@ -304,6 +278,32 @@ your **app/Config/Routes.php** file. CodeIgniter also permits you to remap your URIs using its :doc:`URI Routing ` feature. +Remapping Method Calls +********************** + +As noted above, the second segment of the URI typically determines which +method in the controller gets called. CodeIgniter permits you to override +this behavior through the use of the ``_remap()`` method: + +.. literalinclude:: controllers/010.php + +.. important:: If your controller contains a method named ``_remap()``, + it will **always** get called regardless of what your URI contains. It + overrides the normal behavior in which the URI determines which method + is called, allowing you to define your own method routing rules. + +The overridden method call (typically the second segment of the URI) will +be passed as a parameter to the ``_remap()`` method: + +.. literalinclude:: controllers/011.php + +Any extra segments after the method name are passed into ``_remap()``. These parameters can be passed to the method +to emulate CodeIgniter's default behavior. + +Example: + +.. literalinclude:: controllers/012.php + That's it! ********** From ffbf4f628c7daa6c3d3e56ca3a1dfd7b11ae010d Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 26 Feb 2022 16:10:29 +0900 Subject: [PATCH 0594/1246] docs: fix title level --- user_guide_src/source/incoming/controllers.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/user_guide_src/source/incoming/controllers.rst b/user_guide_src/source/incoming/controllers.rst index dced7111a363..a4c248d3979d 100644 --- a/user_guide_src/source/incoming/controllers.rst +++ b/user_guide_src/source/incoming/controllers.rst @@ -34,7 +34,8 @@ as a class property, ``$this->response``. An instance of the :doc:`Logger <../general/logging>` class is available as a class property, ``$this->logger``. -**forceHTTPS** +forceHTTPS +********** A convenience method for forcing a method to be accessed via HTTPS is available within all controllers: From d9facbb20901e0e0074b15733ce766b3354cbc41 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 26 Feb 2022 16:13:47 +0900 Subject: [PATCH 0595/1246] docs: change the position of sections --- .../source/incoming/controllers.rst | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/user_guide_src/source/incoming/controllers.rst b/user_guide_src/source/incoming/controllers.rst index a4c248d3979d..0cc90da352a5 100644 --- a/user_guide_src/source/incoming/controllers.rst +++ b/user_guide_src/source/incoming/controllers.rst @@ -34,6 +34,17 @@ as a class property, ``$this->response``. An instance of the :doc:`Logger <../general/logging>` class is available as a class property, ``$this->logger``. +Helpers +======= + +You can define an array of helper files as a class property. Whenever the controller is loaded +these helper files will be automatically loaded into memory so that you can use their methods anywhere +inside the controller: + +.. literalinclude:: controllers/016.php + +.. _controllers-validating-data: + forceHTTPS ********** @@ -50,17 +61,6 @@ modify this by passing the duration (in seconds) as the first parameter: .. note:: A number of :doc:`time-based constants ` are always available for you to use, including ``YEAR``, ``MONTH``, and more. -Helpers -======= - -You can define an array of helper files as a class property. Whenever the controller is loaded -these helper files will be automatically loaded into memory so that you can use their methods anywhere -inside the controller: - -.. literalinclude:: controllers/016.php - -.. _controllers-validating-data: - Validating data *************** From 65c6ad200302b1bf6b0eaa39172b3a458cd1060e Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 26 Feb 2022 16:13:58 +0900 Subject: [PATCH 0596/1246] docs: fix link to Request --- user_guide_src/source/incoming/controllers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/incoming/controllers.rst b/user_guide_src/source/incoming/controllers.rst index 0cc90da352a5..4456eb5c8aa3 100644 --- a/user_guide_src/source/incoming/controllers.rst +++ b/user_guide_src/source/incoming/controllers.rst @@ -21,7 +21,7 @@ This class provides several features that are available to all of your controlle **Request Object** -The application's main :doc:`Request Instance ` is always available +The application's main :doc:`Request Instance ` is always available as a class property, ``$this->request``. **Response Object** From 31451b5353f345558e1c0e454c91fd7cce7df6ca Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 26 Feb 2022 16:17:43 +0900 Subject: [PATCH 0597/1246] docs: change page order, now routing is before controllers --- user_guide_src/source/incoming/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/incoming/index.rst b/user_guide_src/source/incoming/index.rst index b334cc5c5ac2..b4399e18d1ba 100644 --- a/user_guide_src/source/incoming/index.rst +++ b/user_guide_src/source/incoming/index.rst @@ -7,8 +7,8 @@ Controllers handle incoming requests. .. toctree:: :titlesonly: - controllers routing + controllers filters message request From c83057baf505c7224b89ca7ba38aaca9e03086f2 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 26 Feb 2022 16:58:16 +0900 Subject: [PATCH 0598/1246] docs: move auto-routing section down --- .../source/incoming/controllers.rst | 2 + user_guide_src/source/incoming/routing.rst | 76 +++++++++---------- 2 files changed, 36 insertions(+), 42 deletions(-) diff --git a/user_guide_src/source/incoming/controllers.rst b/user_guide_src/source/incoming/controllers.rst index 4456eb5c8aa3..21c717d9eace 100644 --- a/user_guide_src/source/incoming/controllers.rst +++ b/user_guide_src/source/incoming/controllers.rst @@ -107,6 +107,8 @@ then trying to access it using the following URL will not work:: example.com/index.php/helloworld/utility/ +.. _controller-auto-routing: + Auto Routing ************ diff --git a/user_guide_src/source/incoming/routing.rst b/user_guide_src/source/incoming/routing.rst index 716e71674962..1f3bde9a02f0 100644 --- a/user_guide_src/source/incoming/routing.rst +++ b/user_guide_src/source/incoming/routing.rst @@ -6,46 +6,13 @@ URI Routing :local: :depth: 2 -****************************** -Auto Routes and Defined Routes -****************************** +What is URI Routing? +******************** -Auto Routes -=========== +URI Routing associates a URI with a controller's method. -Typically there is a one-to-one relationship between a URL string and its corresponding -controller class/method. The segments in a URI normally follow this pattern:: - - example.com/class/method/id/ - -We call this "**Auto Routes**". CodeIgniter automatically routes an HTTP request, -and executes the corresponding controller method. The auto-routing is enabled by default. - -.. note:: To prevent misconfiguration and miscoding, we recommend that you disable - the auto-routing feature. See :ref:`use-defined-routes-only`. - -.. important:: The auto-routing routes a HTTP request with **any** HTTP method to a controller method. - -Defined Routes -============== - -In some instances, however, you may want to remap this relationship so that a different -class/method can be called instead of the one corresponding to the URL. - -For example, let's say you want your URLs to have this prototype:: - - example.com/product/1/ - example.com/product/2/ - example.com/product/3/ - example.com/product/4/ - -Normally the second segment of the URL path is reserved for the method name, but in the example -above it instead has a product ID. To overcome this, CodeIgniter allows you to remap the URI handler. -We call this "**Defined Routes**". - -****************************** -Setting Your Own Routing Rules -****************************** +Setting Routing Rules +********************* Routing rules are defined in the **app/Config/Routes.php** file. In it you'll see that it creates an instance of the RouteCollection class (``$routes``) that permits you to specify your own routing criteria. @@ -56,7 +23,7 @@ If you expect a GET request, you use the ``get()`` method: .. literalinclude:: routing/001.php -A route simply takes the URI path on the left, and maps it to the controller and method on the right, +A route simply takes the URI path (``/``) on the left, and maps it to the controller and method (``Home::index``) on the right, along with any parameters that should be passed to the controller. The controller and method should be listed in the same way that you would use a static method, by separating the class and its method with a double-colon, like ``Users::list``. If that method requires parameters to be @@ -539,7 +506,7 @@ Use Defined Routes Only ======================= When no defined route is found that matches the URI, the system will attempt to match that URI against the -controllers and methods as described above. You can disable this automatic matching, and restrict routes +controllers and methods as described in :ref:`auto-routing`. You can disable this automatic matching, and restrict routes to only those defined by you, by setting the ``setAutoRoute()`` option to false: .. literalinclude:: routing/046.php @@ -565,7 +532,32 @@ For an example use of lowering the priority see :ref:`routing-priority`: .. literalinclude:: routing/048.php -***************** +.. _auto-routing: + +Auto Routing +************ + +It is recommended that all routes are defined in the **app/Config/Routes.php** file. +However, CodeIgniter can also automatically route HTTP requests based on conventions +and execute the corresponding controller methods. + +Consider this URI:: + + example.com/index.php/helloworld/index/1 + +In the above example, CodeIgniter would attempt to find a controller named **Helloworld.php** +and executes ``index()`` method with passing ``'1'`` as the first argument. + +We call this "**Auto Routes**". CodeIgniter automatically routes an HTTP request, +and executes the corresponding controller method. The auto-routing is enabled by default. + +.. note:: To prevent misconfiguration and miscoding, we recommend that you disable + the auto-routing feature. See :ref:`use-defined-routes-only`. + +.. important:: The auto-routing routes a HTTP request with **any** HTTP method to a controller method. + +See :ref:`Auto Routing in Controllers ` for more info. + Confirming Routes ***************** @@ -601,4 +593,4 @@ But ``[/...]`` in the route of an auto route is indicates any number of segments .. note:: When auto routing is enabled, if you have the route ``home``, it can be also accessd by ``Home``, or maybe by ``hOme``, ``hoMe``, ``HOME``, etc. But the command shows only ``home``. -.. important:: The system is not perfect. If you use Custom Placeholders, *Filters* might not be correct. But the filters defined in **app/Config/Routes.php** are always displayed correctly. \ No newline at end of file +.. important:: The system is not perfect. If you use Custom Placeholders, *Filters* might not be correct. But the filters defined in **app/Config/Routes.php** are always displayed correctly. From 76d3acddbe7bb01d527ba73c33e82f879bd11778 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 26 Feb 2022 17:05:04 +0900 Subject: [PATCH 0599/1246] docs: move the description on auto-routing in general/urls.rst to incoming/routing.rst --- user_guide_src/source/general/urls.rst | 15 ++------------- user_guide_src/source/incoming/routing.rst | 11 +++++++++++ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/user_guide_src/source/general/urls.rst b/user_guide_src/source/general/urls.rst index da056cc96cbc..252a907358dd 100644 --- a/user_guide_src/source/general/urls.rst +++ b/user_guide_src/source/general/urls.rst @@ -11,20 +11,9 @@ By default, URLs in CodeIgniter are designed to be search-engine and human-frien example.com/news/article/my_article -URI Segments -============ +Your URLs can be defined using the :doc:`URI Routing ` feature with flexibility. -The segments in the URL, in following with the Model-View-Controller approach, usually represent:: - - example.com/class/method/ID - -1. The first segment represents the controller **class** that should be invoked. -2. The second segment represents the class **method** that should be called. -3. The third, and any additional segments, represent the ID and any variables that will be passed to the controller. - -The :doc:`URI Library <../libraries/uri>` and the :doc:`URL Helper <../helpers/url_helper>` contain functions that make it easy -to work with your URI data. In addition, your URLs can be remapped using the :doc:`URI Routing ` -feature for more flexibility. +The :doc:`URI Library <../libraries/uri>` and the :doc:`URL Helper <../helpers/url_helper>` contain functions that make it easy to work with your URI data. Removing the index.php file =========================== diff --git a/user_guide_src/source/incoming/routing.rst b/user_guide_src/source/incoming/routing.rst index 1f3bde9a02f0..5c527b7d0ada 100644 --- a/user_guide_src/source/incoming/routing.rst +++ b/user_guide_src/source/incoming/routing.rst @@ -541,6 +541,17 @@ It is recommended that all routes are defined in the **app/Config/Routes.php** f However, CodeIgniter can also automatically route HTTP requests based on conventions and execute the corresponding controller methods. +URI Segments +============ + +The segments in the URL, in following with the Model-View-Controller approach, usually represent:: + + example.com/class/method/ID + +1. The first segment represents the controller **class** that should be invoked. +2. The second segment represents the class **method** that should be called. +3. The third, and any additional segments, represent the ID and any variables that will be passed to the controller. + Consider this URI:: example.com/index.php/helloworld/index/1 From 3fb2756c9258c1da3ad89e35acfe318d6da5eed0 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 26 Feb 2022 18:03:10 +0900 Subject: [PATCH 0600/1246] docs: fix section title level --- user_guide_src/source/incoming/routing.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/user_guide_src/source/incoming/routing.rst b/user_guide_src/source/incoming/routing.rst index 5c527b7d0ada..e5e0d04be5cc 100644 --- a/user_guide_src/source/incoming/routing.rst +++ b/user_guide_src/source/incoming/routing.rst @@ -443,7 +443,6 @@ To disable this functionality, you must call the method with the parameter ``fal .. _routes-configuration-options: -**************************** Routes Configuration Options **************************** From db4acf11d7b6280ca39a785391f33d834a5281b3 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sat, 26 Feb 2022 21:06:35 +0700 Subject: [PATCH 0601/1246] [Doc] Upgrading to 4.2.0 from 4.1.9 Latest version is 4.1.9, so the note should be from 4.1.9 --- user_guide_src/source/installation/upgrade_420.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/installation/upgrade_420.rst b/user_guide_src/source/installation/upgrade_420.rst index d2050e08fa36..a302f113ae61 100644 --- a/user_guide_src/source/installation/upgrade_420.rst +++ b/user_guide_src/source/installation/upgrade_420.rst @@ -1,5 +1,5 @@ ############################# -Upgrading from 4.1.8 to 4.2.0 +Upgrading from 4.1.9 to 4.2.0 ############################# Please refer to the upgrade instructions corresponding to your installation method. From 194c2a072e7060fe7f104ee120d09ceb27eba192 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 27 Feb 2022 09:23:12 +0900 Subject: [PATCH 0602/1246] docs: remove "simply" See https://jameshfisher.com/2017/02/22/dont-use-simply/ --- user_guide_src/source/incoming/routing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/incoming/routing.rst b/user_guide_src/source/incoming/routing.rst index e5e0d04be5cc..83cb4cc95e6d 100644 --- a/user_guide_src/source/incoming/routing.rst +++ b/user_guide_src/source/incoming/routing.rst @@ -23,7 +23,7 @@ If you expect a GET request, you use the ``get()`` method: .. literalinclude:: routing/001.php -A route simply takes the URI path (``/``) on the left, and maps it to the controller and method (``Home::index``) on the right, +A route takes the URI path (``/``) on the left, and maps it to the controller and method (``Home::index``) on the right, along with any parameters that should be passed to the controller. The controller and method should be listed in the same way that you would use a static method, by separating the class and its method with a double-colon, like ``Users::list``. If that method requires parameters to be From e838375e9435a21b67c064bcc985cbdb7285fda0 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 27 Feb 2022 09:28:28 +0900 Subject: [PATCH 0603/1246] docs: make it clear to recommend Composer installation --- user_guide_src/source/installation/index.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/user_guide_src/source/installation/index.rst b/user_guide_src/source/installation/index.rst index 92fe78d38184..3312ee24a4bf 100644 --- a/user_guide_src/source/installation/index.rst +++ b/user_guide_src/source/installation/index.rst @@ -7,10 +7,9 @@ using `Composer `_, or using `Git `_. Which is right for you? +- We recommend the Composer installation. Because it keeps CodeIgniter up to date easily. - If you would like the simple "download & go" install that CodeIgniter3 is known for, choose the manual installation. -- If you plan to add third party packages to your project, or want to keep - CodeIgniter up to date easily, we recommend the Composer installation. .. toctree:: :titlesonly: From cd7e011c951092210567efa6c7bd1e7d47f2edca Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 27 Feb 2022 09:29:10 +0900 Subject: [PATCH 0604/1246] docs: move up paragraph and note --- user_guide_src/source/installation/index.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/user_guide_src/source/installation/index.rst b/user_guide_src/source/installation/index.rst index 3312ee24a4bf..31d58ac25673 100644 --- a/user_guide_src/source/installation/index.rst +++ b/user_guide_src/source/installation/index.rst @@ -11,6 +11,15 @@ Which is right for you? - If you would like the simple "download & go" install that CodeIgniter3 is known for, choose the manual installation. +However you choose to install and run CodeIgniter4, the +`user guide `_ is accessible online. + +.. note:: Before using CodeIgniter 4, make sure that your server meets the + :doc:`requirements `, in particular the PHP + version and the PHP extensions that are needed. + You may find that you have to uncomment the ``php.ini`` "extension" + lines to enable "curl" and "intl", for instance. + .. toctree:: :titlesonly: @@ -21,12 +30,3 @@ Which is right for you? upgrading troubleshooting repositories - -However you choose to install and run CodeIgniter4, the -`user guide `_ is accessible online. - -.. note:: Before using CodeIgniter 4, make sure that your server meets the - :doc:`requirements `, in particular the PHP - version and the PHP extensions that are needed. - You may find that you have to uncomment the ``php.ini`` "extension" - lines to enable "curl" and "intl", for instance. From becabdc48324275e53cf4e238d59ce1fe2889d36 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 27 Feb 2022 19:06:23 +0900 Subject: [PATCH 0605/1246] docs: fix by proofreading Co-authored-by: John Paul E. Balandan, CPA <51850998+paulbalandan@users.noreply.github.com> --- user_guide_src/source/installation/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/installation/index.rst b/user_guide_src/source/installation/index.rst index 31d58ac25673..243dd1a5b314 100644 --- a/user_guide_src/source/installation/index.rst +++ b/user_guide_src/source/installation/index.rst @@ -7,7 +7,7 @@ using `Composer `_, or using `Git `_. Which is right for you? -- We recommend the Composer installation. Because it keeps CodeIgniter up to date easily. +- We recommend the Composer installation because it keeps CodeIgniter up to date easily. - If you would like the simple "download & go" install that CodeIgniter3 is known for, choose the manual installation. From 7aa73b9cd5ce33d50696ad1b3478729bd715127b Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 28 Feb 2022 10:08:23 +0900 Subject: [PATCH 0606/1246] docs: remove unneeded page titles --- .../source/installation/upgrading.rst | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/user_guide_src/source/installation/upgrading.rst b/user_guide_src/source/installation/upgrading.rst index 322302d3e011..aa79ef0d6bc7 100644 --- a/user_guide_src/source/installation/upgrading.rst +++ b/user_guide_src/source/installation/upgrading.rst @@ -12,15 +12,15 @@ upgrading from. .. toctree:: :titlesonly: - Upgrading from 4.1.8 to 4.2.0 - Upgrading from 4.1.7 to 4.1.8 - Upgrading from 4.1.6 to 4.1.7 - Upgrading from 4.1.5 to 4.1.6 - Upgrading from 4.1.4 to 4.1.5 - Upgrading from 4.1.3 to 4.1.4 - Upgrading from 4.1.2 to 4.1.3 - Upgrading from 4.1.1 to 4.1.2 - Upgrading from 4.0.5 to 4.1.0 or 4.1.1 - Upgrading from 4.0.4 to 4.0.5 - Upgrading from 4.0.x to 4.0.4 - Upgrading from 3.x to 4.x + upgrade_420 + upgrade_418 + upgrade_417 + upgrade_416 + upgrade_415 + upgrade_414 + upgrade_413 + upgrade_412 + upgrade_410 + upgrade_405 + upgrade_404 + upgrade_4xx From 4aad6438e1f298170cedbb6a11bfe5c56f840293 Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Mon, 28 Feb 2022 12:11:54 +0100 Subject: [PATCH 0607/1246] Fix cli. --- .../source/cli/cli_commands/004.php | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/user_guide_src/source/cli/cli_commands/004.php b/user_guide_src/source/cli/cli_commands/004.php index 64b5af943315..e6178256c524 100644 --- a/user_guide_src/source/cli/cli_commands/004.php +++ b/user_guide_src/source/cli/cli_commands/004.php @@ -1,11 +1,21 @@ Date: Mon, 28 Feb 2022 12:12:20 +0100 Subject: [PATCH 0608/1246] Fix concepts. --- user_guide_src/source/concepts/factories/003.php | 8 ++++++-- user_guide_src/source/concepts/services/007.php | 7 +++++-- user_guide_src/source/concepts/services/008.php | 7 +++++-- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/user_guide_src/source/concepts/factories/003.php b/user_guide_src/source/concepts/factories/003.php index 6c5b966f35cc..5b34b3ff4fcd 100644 --- a/user_guide_src/source/concepts/factories/003.php +++ b/user_guide_src/source/concepts/factories/003.php @@ -2,6 +2,10 @@ class SomeOtherClass { - $widgets = Factories::models('WidgetModel'); - // ... + public function someFunction() + { + $widgets = Factories::models('WidgetModel'); + + // ... + } } diff --git a/user_guide_src/source/concepts/services/007.php b/user_guide_src/source/concepts/services/007.php index 64a1119f0ace..6096fe592142 100644 --- a/user_guide_src/source/concepts/services/007.php +++ b/user_guide_src/source/concepts/services/007.php @@ -1,6 +1,9 @@ Date: Mon, 28 Feb 2022 12:12:33 +0100 Subject: [PATCH 0609/1246] Fix database. --- .../source/database/configuration/001.php | 39 ++++++++++--------- .../source/database/configuration/006.php | 39 ++++++++++--------- 2 files changed, 42 insertions(+), 36 deletions(-) diff --git a/user_guide_src/source/database/configuration/001.php b/user_guide_src/source/database/configuration/001.php index c868ee08eb37..5a59fabfcfdc 100644 --- a/user_guide_src/source/database/configuration/001.php +++ b/user_guide_src/source/database/configuration/001.php @@ -1,20 +1,23 @@ '', - 'hostname' => 'localhost', - 'username' => 'root', - 'password' => '', - 'database' => 'database_name', - 'DBDriver' => 'MySQLi', - 'DBPrefix' => '', - 'pConnect' => true, - 'DBDebug' => true, - 'charset' => 'utf8', - 'DBCollat' => 'utf8_general_ci', - 'swapPre' => '', - 'encrypt' => false, - 'compress' => false, - 'strictOn' => false, - 'failover' => [], -]; +class Database extends Config +{ + public $default = [ + 'DSN' => '', + 'hostname' => 'localhost', + 'username' => 'root', + 'password' => '', + 'database' => 'database_name', + 'DBDriver' => 'MySQLi', + 'DBPrefix' => '', + 'pConnect' => true, + 'DBDebug' => true, + 'charset' => 'utf8', + 'DBCollat' => 'utf8_general_ci', + 'swapPre' => '', + 'encrypt' => false, + 'compress' => false, + 'strictOn' => false, + 'failover' => [], + ]; +} diff --git a/user_guide_src/source/database/configuration/006.php b/user_guide_src/source/database/configuration/006.php index 31b56a677829..d5b4a5d691d5 100644 --- a/user_guide_src/source/database/configuration/006.php +++ b/user_guide_src/source/database/configuration/006.php @@ -1,20 +1,23 @@ '', - 'hostname' => 'localhost', - 'username' => 'root', - 'password' => '', - 'database' => 'database_name', - 'DBDriver' => 'MySQLi', - 'DBPrefix' => '', - 'pConnect' => true, - 'DBDebug' => true, - 'charset' => 'utf8', - 'DBCollat' => 'utf8_general_ci', - 'swapPre' => '', - 'compress' => false, - 'encrypt' => false, - 'strictOn' => false, - 'failover' => [] -); +class Database extends Config +{ + public $test = [ + 'DSN' => '', + 'hostname' => 'localhost', + 'username' => 'root', + 'password' => '', + 'database' => 'database_name', + 'DBDriver' => 'MySQLi', + 'DBPrefix' => '', + 'pConnect' => true, + 'DBDebug' => true, + 'charset' => 'utf8', + 'DBCollat' => 'utf8_general_ci', + 'swapPre' => '', + 'compress' => false, + 'encrypt' => false, + 'strictOn' => false, + 'failover' => [], + ]; +} From b6fe091fed9b941e39fdde07891aed71b1c011cf Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Mon, 28 Feb 2022 12:12:44 +0100 Subject: [PATCH 0610/1246] Fix dbmgmt. --- user_guide_src/source/dbmgmt/migration/002.php | 12 +++++++----- user_guide_src/source/dbmgmt/seeds/003.php | 9 ++++++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/user_guide_src/source/dbmgmt/migration/002.php b/user_guide_src/source/dbmgmt/migration/002.php index 07d2b2034775..35726a23aade 100644 --- a/user_guide_src/source/dbmgmt/migration/002.php +++ b/user_guide_src/source/dbmgmt/migration/002.php @@ -1,10 +1,12 @@ db->disableForeignKeyChecks() + public function up() + { + $this->db->disableForeignKeyChecks(); - // Migration rules would go here.. - - $this->db->enableForeignKeyChecks(); + // Migration rules would go here.. + $this->db->enableForeignKeyChecks(); + } } diff --git a/user_guide_src/source/dbmgmt/seeds/003.php b/user_guide_src/source/dbmgmt/seeds/003.php index 12dbcbd74835..099904f4f2ab 100644 --- a/user_guide_src/source/dbmgmt/seeds/003.php +++ b/user_guide_src/source/dbmgmt/seeds/003.php @@ -1,7 +1,10 @@ call('UserSeeder'); - $this->call('My\Database\Seeds\CountrySeeder'); + public function run() + { + $this->call('UserSeeder'); + $this->call('My\Database\Seeds\CountrySeeder'); + } } From 6822f25618ba622edac30193523764353ad17383 Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Mon, 28 Feb 2022 12:12:57 +0100 Subject: [PATCH 0611/1246] Fix extending. --- .../source/extending/basecontroller/002.php | 5 ++++- .../source/extending/basecontroller/003.php | 11 +++++++---- .../source/extending/core_classes/002.php | 13 ++++++++----- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/user_guide_src/source/extending/basecontroller/002.php b/user_guide_src/source/extending/basecontroller/002.php index dee702c36ecb..509bb27a8707 100644 --- a/user_guide_src/source/extending/basecontroller/002.php +++ b/user_guide_src/source/extending/basecontroller/002.php @@ -1,3 +1,6 @@ session = \Config\Services::session(); + $this->session = \Config\Services::session(); + } } diff --git a/user_guide_src/source/extending/core_classes/002.php b/user_guide_src/source/extending/core_classes/002.php index 65fb5c240f41..cc3f38347ccf 100644 --- a/user_guide_src/source/extending/core_classes/002.php +++ b/user_guide_src/source/extending/core_classes/002.php @@ -1,10 +1,13 @@ Date: Mon, 28 Feb 2022 12:16:30 +0100 Subject: [PATCH 0612/1246] Fix events. --- user_guide_src/source/database/events/001.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/user_guide_src/source/database/events/001.php b/user_guide_src/source/database/events/001.php index 1c8b56b1d1ca..2065ef3d426b 100644 --- a/user_guide_src/source/database/events/001.php +++ b/user_guide_src/source/database/events/001.php @@ -2,9 +2,3 @@ // In Config\Events.php Events::on('DBQuery', 'CodeIgniter\Debug\Toolbar\Collectors\Database::collect'); - -// Collect the queries so something can be done with them later. -public static function collect(CodeIgniter\Database\Query $query) -{ - static::$queries[] = $query; -} From 591abc91f700137268670c39a3b8f2470647d875 Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Mon, 28 Feb 2022 12:34:03 +0100 Subject: [PATCH 0613/1246] Fix testing. --- .../source/testing/controllers/014.php | 13 ++++++--- .../source/testing/debugging/003.php | 23 ++++++++------- user_guide_src/source/testing/overview.rst | 7 +++-- .../source/testing/overview/003.php | 6 ---- .../source/testing/overview/004.php | 9 ++++-- .../source/testing/overview/005.php | 14 +++++---- .../source/testing/overview/006.php | 4 +-- .../source/testing/overview/007.php | 8 +++-- .../source/testing/overview/017.php | 15 ++++++---- .../source/testing/overview/018.php | 11 ++++--- .../source/testing/overview/019.php | 29 ++++++++++--------- 11 files changed, 80 insertions(+), 59 deletions(-) delete mode 100644 user_guide_src/source/testing/overview/003.php diff --git a/user_guide_src/source/testing/controllers/014.php b/user_guide_src/source/testing/controllers/014.php index 19f2310392fa..bc6dc8bf9e18 100644 --- a/user_guide_src/source/testing/controllers/014.php +++ b/user_guide_src/source/testing/controllers/014.php @@ -1,9 +1,14 @@ getFilterCaller('permission', 'before'); - $result = $caller('MayEditWidgets'); + use FilterTestTrait; - $this->assertInstanceOf('CodeIgniter\HTTP\RedirectResponse', $result); + protected function testUnauthorizedAccessRedirects() + { + $caller = $this->getFilterCaller('permission', 'before'); + $result = $caller('MayEditWidgets'); + + $this->assertInstanceOf('CodeIgniter\HTTP\RedirectResponse', $result); + } } diff --git a/user_guide_src/source/testing/debugging/003.php b/user_guide_src/source/testing/debugging/003.php index b7e19588fae9..de9476fe7d39 100644 --- a/user_guide_src/source/testing/debugging/003.php +++ b/user_guide_src/source/testing/debugging/003.php @@ -1,12 +1,15 @@ model->purgeDeleted() + $this->model->purgeDeleted(); } } diff --git a/user_guide_src/source/testing/overview/007.php b/user_guide_src/source/testing/overview/007.php index c829e5b99cce..1ba21e197b0a 100644 --- a/user_guide_src/source/testing/overview/007.php +++ b/user_guide_src/source/testing/overview/007.php @@ -2,16 +2,18 @@ trait AuthTrait { - protected setUpAuthTrait() + protected function setUpAuthTrait() { $user = $this->createFakeUser(); $this->logInUser($user); } - // ... } -class AuthenticationFeatureTest +/** + * @internal + */ +final class AuthenticationFeatureTest { use AuthTrait; diff --git a/user_guide_src/source/testing/overview/017.php b/user_guide_src/source/testing/overview/017.php index 653c7d0947ba..9fb311e795e3 100644 --- a/user_guide_src/source/testing/overview/017.php +++ b/user_guide_src/source/testing/overview/017.php @@ -1,11 +1,14 @@ getMockBuilder('CodeIgniter\HTTP\CURLRequest') - ->setMethods(['request']) - ->getMock(); - Services::injectMock('curlrequest', $curlrequest); + public function testSomething() + { + $curlrequest = $this->getMockBuilder('CodeIgniter\HTTP\CURLRequest') + ->setMethods(['request']) + ->getMock(); + Services::injectMock('curlrequest', $curlrequest); - // Do normal testing here.... + // Do normal testing here.... + } } diff --git a/user_guide_src/source/testing/overview/018.php b/user_guide_src/source/testing/overview/018.php index 743074117d9e..4c607dddb77e 100644 --- a/user_guide_src/source/testing/overview/018.php +++ b/user_guide_src/source/testing/overview/018.php @@ -1,9 +1,12 @@ stream_filter = stream_filter_append(STDOUT, 'CITestStreamFilter'); -} + protected function setUp() + { + CITestStreamFilter::$buffer = ''; + $this->stream_filter = stream_filter_append(STDOUT, 'CITestStreamFilter'); + } -public function tearDown() -{ - stream_filter_remove($this->stream_filter); -} + protected function tearDown() + { + stream_filter_remove($this->stream_filter); + } -public function testSomeOutput() -{ - CLI::write('first.'); - $expected = "first.\n"; - $this->assertSame($expected, CITestStreamFilter::$buffer); + public function testSomeOutput() + { + CLI::write('first.'); + $expected = "first.\n"; + $this->assertSame($expected, CITestStreamFilter::$buffer); + } } From 237f218424869d0b0707d5b0db2571fdfd5500fd Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Mon, 28 Feb 2022 12:36:03 +0100 Subject: [PATCH 0614/1246] Fix helpers. --- user_guide_src/source/helpers/test_helper/002.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/user_guide_src/source/helpers/test_helper/002.php b/user_guide_src/source/helpers/test_helper/002.php index 58decc5bfeb3..10fb42b1260f 100644 --- a/user_guide_src/source/helpers/test_helper/002.php +++ b/user_guide_src/source/helpers/test_helper/002.php @@ -1,8 +1,11 @@ assertTrue($this->userHasAccess($user)); + $this->assertTrue($this->userHasAccess($user)); + } } From 7c9091c3fe900467d030bf444cdb0b256015ceb1 Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Mon, 28 Feb 2022 13:38:10 +0100 Subject: [PATCH 0615/1246] Fix incoming. --- .../source/incoming/controllers/005.php | 6 +++- .../source/incoming/controllers/010.php | 7 +++-- .../source/incoming/controllers/011.php | 11 ++++--- .../source/incoming/controllers/012.php | 15 ++++++---- .../source/incoming/controllers/013.php | 7 +++-- .../source/incoming/controllers/017.php | 23 +++++++------- .../source/incoming/controllers/018.php | 17 ++++++----- .../source/incoming/controllers/019.php | 30 +++++++++++-------- .../source/incoming/filters/002.php | 11 ++++--- .../source/incoming/filters/003.php | 9 ++++-- .../source/incoming/filters/004.php | 15 ++++++---- .../source/incoming/filters/005.php | 15 ++++++---- .../source/incoming/filters/006.php | 15 ++++++---- .../source/incoming/filters/007.php | 15 ++++++---- .../source/incoming/filters/008.php | 11 ++++--- .../source/incoming/filters/009.php | 11 ++++--- .../source/incoming/filters/011.php | 11 ++++--- .../source/incoming/routing/011.php | 12 +++++--- 18 files changed, 149 insertions(+), 92 deletions(-) diff --git a/user_guide_src/source/incoming/controllers/005.php b/user_guide_src/source/incoming/controllers/005.php index 5d3892bfafb8..84b910be2507 100644 --- a/user_guide_src/source/incoming/controllers/005.php +++ b/user_guide_src/source/incoming/controllers/005.php @@ -1,5 +1,9 @@ (\)*\ +/* + Folder and file structure: + + \(\)*\ + */ $routes->get('helloworld', '\App\Controllers\HelloWorld::index'); diff --git a/user_guide_src/source/incoming/controllers/010.php b/user_guide_src/source/incoming/controllers/010.php index e017dcd45cdb..b74d386d6289 100644 --- a/user_guide_src/source/incoming/controllers/010.php +++ b/user_guide_src/source/incoming/controllers/010.php @@ -1,6 +1,9 @@ $method(); - } else { + public function _remap($method) + { + if ($method === 'some_method') { + return $this->{$method}(); + } + return $this->default_method(); } } diff --git a/user_guide_src/source/incoming/controllers/012.php b/user_guide_src/source/incoming/controllers/012.php index 25d064b859cd..e6cc91140f6f 100644 --- a/user_guide_src/source/incoming/controllers/012.php +++ b/user_guide_src/source/incoming/controllers/012.php @@ -1,12 +1,15 @@ $method(...$params); - } + if (method_exists($this, $method)) { + return $this->{$method}(...$params); + } - throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound(); + throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound(); + } } diff --git a/user_guide_src/source/incoming/controllers/013.php b/user_guide_src/source/incoming/controllers/013.php index eed95b673ad2..2586a7781dfe 100644 --- a/user_guide_src/source/incoming/controllers/013.php +++ b/user_guide_src/source/incoming/controllers/013.php @@ -1,6 +1,9 @@ validate([ - 'email' => "required|is_unique[users.email,id,{$userID}]", - 'name' => 'required|alpha_numeric_spaces' - ])) { - return view('users/update', [ - 'errors' => $this->validator->getErrors() - ]); - } + public function updateUser(int $userID) + { + if (! $this->validate([ + 'email' => "required|is_unique[users.email,id,{$userID}]", + 'name' => 'required|alpha_numeric_spaces', + ])) { + return view('users/update', [ + 'errors' => $this->validator->getErrors(), + ]); + } - // do something here if successful... + // do something here if successful... + } } diff --git a/user_guide_src/source/incoming/controllers/018.php b/user_guide_src/source/incoming/controllers/018.php index 54697409827a..29c3780cc854 100644 --- a/user_guide_src/source/incoming/controllers/018.php +++ b/user_guide_src/source/incoming/controllers/018.php @@ -1,12 +1,15 @@ validate('userRules')) { - return view('users/update', [ - 'errors' => $this->validator->getErrors() - ]); - } + public function updateUser(int $userID) + { + if (! $this->validate('userRules')) { + return view('users/update', [ + 'errors' => $this->validator->getErrors(), + ]); + } - // do something here if successful... + // do something here if successful... + } } diff --git a/user_guide_src/source/incoming/controllers/019.php b/user_guide_src/source/incoming/controllers/019.php index e5a96084c2c2..c27156d7232a 100644 --- a/user_guide_src/source/incoming/controllers/019.php +++ b/user_guide_src/source/incoming/controllers/019.php @@ -1,19 +1,23 @@ $id, - 'name' => $this->request->getVar('name'), - ]; - $rule = [ - 'id' => 'integer', - 'name' => 'required|max_length[255]', - ]; + public function product(int $id) + { + $data = [ + 'id' => $id, + 'name' => $this->request->getVar('name'), + ]; + + $rule = [ + 'id' => 'integer', + 'name' => 'required|max_length[255]', + ]; + + if (! $this->validateData($data, $rule)) { + // ... + } - if (! $this->validateData($data, $rule) { // ... } - - // ... -} \ No newline at end of file +} diff --git a/user_guide_src/source/incoming/filters/002.php b/user_guide_src/source/incoming/filters/002.php index 792921a348ef..b6c77a2eaa34 100644 --- a/user_guide_src/source/incoming/filters/002.php +++ b/user_guide_src/source/incoming/filters/002.php @@ -1,10 +1,13 @@ isLoggedIn()) { - return redirect()->to(site_url('login')); + if (! $auth->isLoggedIn()) { + return redirect()->to(site_url('login')); + } } } diff --git a/user_guide_src/source/incoming/filters/003.php b/user_guide_src/source/incoming/filters/003.php index 1ef6a461f3c6..a757fdf8f029 100644 --- a/user_guide_src/source/incoming/filters/003.php +++ b/user_guide_src/source/incoming/filters/003.php @@ -1,5 +1,8 @@ \CodeIgniter\Filters\CSRF::class, -]; +class Filters extends BaseConfig +{ + public $aliases = [ + 'csrf' => \CodeIgniter\Filters\CSRF::class, + ]; +} diff --git a/user_guide_src/source/incoming/filters/004.php b/user_guide_src/source/incoming/filters/004.php index a7f31363edad..3615cf8f6072 100644 --- a/user_guide_src/source/incoming/filters/004.php +++ b/user_guide_src/source/incoming/filters/004.php @@ -1,8 +1,11 @@ [ - \App\Filters\Negotiate::class, - \App\Filters\ApiAuth::class, - ] -]; +class Filters extends BaseConfig +{ + public $aliases = [ + 'apiPrep' => [ + \App\Filters\Negotiate::class, + \App\Filters\ApiAuth::class, + ], + ]; +} diff --git a/user_guide_src/source/incoming/filters/005.php b/user_guide_src/source/incoming/filters/005.php index 3f3801f5ce59..7599c93e1203 100644 --- a/user_guide_src/source/incoming/filters/005.php +++ b/user_guide_src/source/incoming/filters/005.php @@ -1,8 +1,11 @@ [ - 'csrf', - ], - 'after' => [], -]; +class Filters extends BaseConfig +{ + public $globals = [ + 'before' => [ + 'csrf', + ], + 'after' => [], + ]; +} diff --git a/user_guide_src/source/incoming/filters/006.php b/user_guide_src/source/incoming/filters/006.php index 3706979688cd..3cd37f8224e9 100644 --- a/user_guide_src/source/incoming/filters/006.php +++ b/user_guide_src/source/incoming/filters/006.php @@ -1,8 +1,11 @@ [ - 'csrf' => ['except' => 'api/*'], - ], - 'after' => [], -]; +class Filters extends BaseConfig +{ + public $globals = [ + 'before' => [ + 'csrf' => ['except' => 'api/*'], + ], + 'after' => [], + ]; +} diff --git a/user_guide_src/source/incoming/filters/007.php b/user_guide_src/source/incoming/filters/007.php index a6790adbf9b7..e9c1dba48fc6 100644 --- a/user_guide_src/source/incoming/filters/007.php +++ b/user_guide_src/source/incoming/filters/007.php @@ -1,8 +1,11 @@ [ - 'csrf' => ['except' => ['foo/*', 'bar/*']], - ], - 'after' => [], -]; +class Filters extends BaseConfig +{ + public $globals = [ + 'before' => [ + 'csrf' => ['except' => ['foo/*', 'bar/*']], + ], + 'after' => [], + ]; +} diff --git a/user_guide_src/source/incoming/filters/008.php b/user_guide_src/source/incoming/filters/008.php index 2f216281e982..e50628a13bd5 100644 --- a/user_guide_src/source/incoming/filters/008.php +++ b/user_guide_src/source/incoming/filters/008.php @@ -1,6 +1,9 @@ ['foo', 'bar'], - 'get' => ['baz'], -] +class Filters extends BaseConfig +{ + public $methods = [ + 'post' => ['foo', 'bar'], + 'get' => ['baz'], + ]; +} diff --git a/user_guide_src/source/incoming/filters/009.php b/user_guide_src/source/incoming/filters/009.php index 258edd689d3c..2505d8fcc2a2 100644 --- a/user_guide_src/source/incoming/filters/009.php +++ b/user_guide_src/source/incoming/filters/009.php @@ -1,6 +1,9 @@ ['before' => ['admin/*'], 'after' => ['users/*']], - 'bar' => ['before' => ['api/*', 'admin/*']], -]; +class Filters extends BaseConfig +{ + public $filters = [ + 'foo' => ['before' => ['admin/*'], 'after' => ['users/*']], + 'bar' => ['before' => ['api/*', 'admin/*']], + ]; +} diff --git a/user_guide_src/source/incoming/filters/011.php b/user_guide_src/source/incoming/filters/011.php index 10db5ad2eb40..54b276967859 100644 --- a/user_guide_src/source/incoming/filters/011.php +++ b/user_guide_src/source/incoming/filters/011.php @@ -1,6 +1,9 @@ \App\Filters\SecureHeaders::class, -]; +class Filters extends BaseConfig +{ + public $aliases = [ + // ... + 'secureheaders' => \App\Filters\SecureHeaders::class, + ]; +} diff --git a/user_guide_src/source/incoming/routing/011.php b/user_guide_src/source/incoming/routing/011.php index 11437a5881c2..790f965912ca 100644 --- a/user_guide_src/source/incoming/routing/011.php +++ b/user_guide_src/source/incoming/routing/011.php @@ -1,7 +1,11 @@ Date: Mon, 28 Feb 2022 13:41:56 +0100 Subject: [PATCH 0616/1246] Fix installation. --- .../source/installation/troubleshooting/001.php | 5 ++++- .../source/installation/troubleshooting/002.php | 5 ++++- .../source/installation/upgrade_404.rst | 10 ++++++---- .../source/installation/upgrade_404/001.php | 4 ---- .../source/installation/upgrade_404/002.php | 4 ---- .../source/installation/upgrade_415/001.php | 11 +++++++---- .../installation/upgrade_localization/001.php | 5 ++++- .../source/installation/upgrade_security/001.php | 15 +++++++++------ 8 files changed, 34 insertions(+), 25 deletions(-) delete mode 100644 user_guide_src/source/installation/upgrade_404/001.php delete mode 100644 user_guide_src/source/installation/upgrade_404/002.php diff --git a/user_guide_src/source/installation/troubleshooting/001.php b/user_guide_src/source/installation/troubleshooting/001.php index 54798c261dae..c3aa124d6ce2 100644 --- a/user_guide_src/source/installation/troubleshooting/001.php +++ b/user_guide_src/source/installation/troubleshooting/001.php @@ -1,3 +1,6 @@ ['csrf'], - 'post' => ['csrf'], -]; +class Filters extends BaseConfig +{ + public $methods = [ + 'get' => ['csrf'], + 'post' => ['csrf'], + ]; +} diff --git a/user_guide_src/source/installation/upgrade_localization/001.php b/user_guide_src/source/installation/upgrade_localization/001.php index c3b3de65be20..53d156de0545 100644 --- a/user_guide_src/source/installation/upgrade_localization/001.php +++ b/user_guide_src/source/installation/upgrade_localization/001.php @@ -1,3 +1,6 @@ [ - //'honeypot', - 'csrf', - ] -]; +class Filters extends BaseConfig +{ + public $globals = [ + 'before' => [ + // 'honeypot', + 'csrf', + ], + ]; +} From ab46edc81069ae1344a7a6e458ca2ca891fde39b Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Mon, 28 Feb 2022 14:15:04 +0100 Subject: [PATCH 0617/1246] Fix models. --- user_guide_src/source/models/entities/020.php | 19 ++++++++------ user_guide_src/source/models/model/038.php | 9 ++++--- user_guide_src/source/models/model/040.php | 9 ++++--- user_guide_src/source/models/model/041.php | 5 +++- user_guide_src/source/models/model/050.php | 17 +++++++------ user_guide_src/source/models/model/051.php | 7 ++++-- user_guide_src/source/models/model/052.php | 5 +++- user_guide_src/source/models/model/054.php | 25 +++++++++++-------- 8 files changed, 61 insertions(+), 35 deletions(-) diff --git a/user_guide_src/source/models/entities/020.php b/user_guide_src/source/models/entities/020.php index 4e7908e5c20d..0fa4e8e140df 100644 --- a/user_guide_src/source/models/entities/020.php +++ b/user_guide_src/source/models/entities/020.php @@ -1,11 +1,14 @@ 'class[App\SomeClass, param2, param3]', -]; +class MyEntity extends Entity +{ + // Defining a type with parameters + protected $casts = [ + 'some_attribute' => 'class[App\SomeClass, param2, param3]', + ]; -// Bind the type to the handler -protected $castHandlers = [ - 'class' => 'SomeHandler', -]; + // Bind the type to the handler + protected $castHandlers = [ + 'class' => 'SomeHandler', + ]; +} diff --git a/user_guide_src/source/models/model/038.php b/user_guide_src/source/models/model/038.php index 0a0dffd7dba5..d08b6333bc84 100644 --- a/user_guide_src/source/models/model/038.php +++ b/user_guide_src/source/models/model/038.php @@ -1,5 +1,8 @@ 'required|valid_email|is_unique[users.email,id,{id}]' -]; +class MyModel extends Model +{ + protected $validationRules = [ + 'email' => 'required|valid_email|is_unique[users.email,id,{id}]', + ]; +} diff --git a/user_guide_src/source/models/model/040.php b/user_guide_src/source/models/model/040.php index 68f9c5c13143..9e3402559d62 100644 --- a/user_guide_src/source/models/model/040.php +++ b/user_guide_src/source/models/model/040.php @@ -1,5 +1,8 @@ 'required|valid_email|is_unique[users.email,id,4]' -]; +class MyModel extends Model +{ + protected $validationRules = [ + 'email' => 'required|valid_email|is_unique[users.email,id,4]', + ]; +} diff --git a/user_guide_src/source/models/model/041.php b/user_guide_src/source/models/model/041.php index 8aaa151c61a1..f2f89729a632 100644 --- a/user_guide_src/source/models/model/041.php +++ b/user_guide_src/source/models/model/041.php @@ -1,3 +1,6 @@ getCachedItem($data['id']])) { - $data['data'] = $item; - $data['returnData'] = true; - - return $data; - } + protected $beforeFind = ['checkCache']; // ... + + protected function checkCache(array $data) + { + // Check if the requested item is already in our cache + if (isset($data['id']) && $item = $this->getCachedItem($data['id'])) { + $data['data'] = $item; + $data['returnData'] = true; + + return $data; + } + + // ... + } } From 9b8373600edfd565c990ff8a81c71a599c07d2dd Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Mon, 28 Feb 2022 15:43:42 +0100 Subject: [PATCH 0618/1246] Fix tutorial. --- .../source/tutorial/create_news_items/001.php | 9 +++-- .../source/tutorial/create_news_items/002.php | 35 ++++++++++--------- .../source/tutorial/news_section/002.php | 13 ++++--- .../source/tutorial/news_section/004.php | 21 ++++++----- .../source/tutorial/news_section/006.php | 23 ++++++------ .../source/tutorial/static_pages/002.php | 21 ++++++----- 6 files changed, 70 insertions(+), 52 deletions(-) diff --git a/user_guide_src/source/tutorial/create_news_items/001.php b/user_guide_src/source/tutorial/create_news_items/001.php index 80d86db34633..5091ec750126 100644 --- a/user_guide_src/source/tutorial/create_news_items/001.php +++ b/user_guide_src/source/tutorial/create_news_items/001.php @@ -1,5 +1,8 @@ ['csrf'], -]; +class Filters extends BaseConfig +{ + public $methods = [ + 'post' => ['csrf'], + ]; +} diff --git a/user_guide_src/source/tutorial/create_news_items/002.php b/user_guide_src/source/tutorial/create_news_items/002.php index 2dc230c3a720..b5a5004e0961 100644 --- a/user_guide_src/source/tutorial/create_news_items/002.php +++ b/user_guide_src/source/tutorial/create_news_items/002.php @@ -1,23 +1,26 @@ request->getMethod() === 'post' && $this->validate([ - 'title' => 'required|min_length[3]|max_length[255]', - 'body' => 'required', - ])) { - $model->save([ - 'title' => $this->request->getPost('title'), - 'slug' => url_title($this->request->getPost('title'), '-', true), - 'body' => $this->request->getPost('body'), - ]); + if ($this->request->getMethod() === 'post' && $this->validate([ + 'title' => 'required|min_length[3]|max_length[255]', + 'body' => 'required', + ])) { + $model->save([ + 'title' => $this->request->getPost('title'), + 'slug' => url_title($this->request->getPost('title'), '-', true), + 'body' => $this->request->getPost('body'), + ]); - echo view('news/success'); - } else { - echo view('templates/header', ['title' => 'Create a news item']); - echo view('news/create'); - echo view('templates/footer'); + echo view('news/success'); + } else { + echo view('templates/header', ['title' => 'Create a news item']); + echo view('news/create'); + echo view('templates/footer'); + } } } diff --git a/user_guide_src/source/tutorial/news_section/002.php b/user_guide_src/source/tutorial/news_section/002.php index bf8f4217be57..66a6d8f224dd 100644 --- a/user_guide_src/source/tutorial/news_section/002.php +++ b/user_guide_src/source/tutorial/news_section/002.php @@ -1,10 +1,13 @@ findAll(); - } + public function getNews($slug = false) + { + if ($slug === false) { + return $this->findAll(); + } - return $this->where(['slug' => $slug])->first(); + return $this->where(['slug' => $slug])->first(); + } } diff --git a/user_guide_src/source/tutorial/news_section/004.php b/user_guide_src/source/tutorial/news_section/004.php index 0fac31909775..f6973a3deafc 100644 --- a/user_guide_src/source/tutorial/news_section/004.php +++ b/user_guide_src/source/tutorial/news_section/004.php @@ -1,15 +1,18 @@ $model->getNews(), - 'title' => 'News archive', - ]; + $data = [ + 'news' => $model->getNews(), + 'title' => 'News archive', + ]; - echo view('templates/header', $data); - echo view('news/overview', $data); - echo view('templates/footer', $data); + echo view('templates/header', $data); + echo view('news/overview', $data); + echo view('templates/footer', $data); + } } diff --git a/user_guide_src/source/tutorial/news_section/006.php b/user_guide_src/source/tutorial/news_section/006.php index ea7331dbf77f..afaa1cee5800 100644 --- a/user_guide_src/source/tutorial/news_section/006.php +++ b/user_guide_src/source/tutorial/news_section/006.php @@ -1,18 +1,21 @@ getNews($slug); + $data['news'] = $model->getNews($slug); - if (empty($data['news'])) { - throw new \CodeIgniter\Exceptions\PageNotFoundException('Cannot find the news item: ' . $slug); - } + if (empty($data['news'])) { + throw new \CodeIgniter\Exceptions\PageNotFoundException('Cannot find the news item: ' . $slug); + } - $data['title'] = $data['news']['title']; + $data['title'] = $data['news']['title']; - echo view('templates/header', $data); - echo view('news/view', $data); - echo view('templates/footer', $data); + echo view('templates/header', $data); + echo view('news/view', $data); + echo view('templates/footer', $data); + } } diff --git a/user_guide_src/source/tutorial/static_pages/002.php b/user_guide_src/source/tutorial/static_pages/002.php index 4f5901845f9d..bd3eb8938a57 100644 --- a/user_guide_src/source/tutorial/static_pages/002.php +++ b/user_guide_src/source/tutorial/static_pages/002.php @@ -1,15 +1,18 @@ Date: Mon, 28 Feb 2022 15:48:29 +0100 Subject: [PATCH 0619/1246] Fix general. --- .../source/general/configuration/008.php | 9 ++++++--- user_guide_src/source/general/errors/003.php | 4 +++- user_guide_src/source/general/errors/004.php | 4 +++- user_guide_src/source/general/logging/002.php | 5 ++++- user_guide_src/source/general/logging/003.php | 7 +++++-- user_guide_src/source/general/logging/004.php | 15 +++++++++------ .../source/general/managing_apps/001.php | 5 ++++- user_guide_src/source/general/modules/001.php | 13 ++++++++----- user_guide_src/source/general/modules/002.php | 13 ++++++++----- user_guide_src/source/general/modules/003.php | 13 ++++++++----- user_guide_src/source/general/modules/004.php | 5 ++++- 11 files changed, 62 insertions(+), 31 deletions(-) diff --git a/user_guide_src/source/general/configuration/008.php b/user_guide_src/source/general/configuration/008.php index 54072ca22fba..dd301d8c69a1 100644 --- a/user_guide_src/source/general/configuration/008.php +++ b/user_guide_src/source/general/configuration/008.php @@ -1,5 +1,8 @@ find($id); +} catch (\CodeIgniter\UnknownFileException $e) { // do something here... } diff --git a/user_guide_src/source/general/errors/004.php b/user_guide_src/source/general/errors/004.php index 06a972cfc4d8..752b23bdba30 100644 --- a/user_guide_src/source/general/errors/004.php +++ b/user_guide_src/source/general/errors/004.php @@ -1,6 +1,8 @@ find($id); +} catch (\CodeIgniter\UnknownFileException $e) { // do something here... throw new \RuntimeException($e->getMessage(), $e->getCode(), $e); diff --git a/user_guide_src/source/general/logging/002.php b/user_guide_src/source/general/logging/002.php index bf08b8722b63..d542f40b4ccb 100644 --- a/user_guide_src/source/general/logging/002.php +++ b/user_guide_src/source/general/logging/002.php @@ -1,3 +1,6 @@ [ - 'handles' => ['critical', 'alert', 'emergency', 'debug', 'error', 'info', 'notice', 'warning'], - ] -]; +class Logger extends BaseConfig +{ + public $handlers = [ + // File Handler + 'CodeIgniter\Log\Handlers\FileHandler' => [ + 'handles' => ['critical', 'alert', 'emergency', 'debug', 'error', 'info', 'notice', 'warning'], + ], + ]; +} diff --git a/user_guide_src/source/general/managing_apps/001.php b/user_guide_src/source/general/managing_apps/001.php index 27deaaf4b994..d1690bdd55e6 100644 --- a/user_guide_src/source/general/managing_apps/001.php +++ b/user_guide_src/source/general/managing_apps/001.php @@ -1,3 +1,6 @@ APPPATH, // For custom namespace - 'Config' => APPPATH . 'Config', - 'Acme' => ROOTPATH . 'acme', -]; +class Autoload extends AutoloadConfig +{ + public $psr4 = [ + APP_NAMESPACE => APPPATH, // For custom namespace + 'Config' => APPPATH . 'Config', + 'Acme' => ROOTPATH . 'acme', + ]; +} diff --git a/user_guide_src/source/general/modules/002.php b/user_guide_src/source/general/modules/002.php index 7cab63838ec5..4d7b355da602 100644 --- a/user_guide_src/source/general/modules/002.php +++ b/user_guide_src/source/general/modules/002.php @@ -1,7 +1,10 @@ APPPATH, // For custom namespace - 'Config' => APPPATH . 'Config', - 'Acme\Blog' => ROOTPATH . 'acme/Blog', // Change -]; +class Autoload extends AutoloadConfig +{ + public $psr4 = [ + APP_NAMESPACE => APPPATH, // For custom namespace + 'Config' => APPPATH . 'Config', + 'Acme\Blog' => ROOTPATH . 'acme/Blog', // Change + ]; +} diff --git a/user_guide_src/source/general/modules/004.php b/user_guide_src/source/general/modules/004.php index 56804cc2e579..0f2c1c3967ad 100644 --- a/user_guide_src/source/general/modules/004.php +++ b/user_guide_src/source/general/modules/004.php @@ -1,3 +1,6 @@ Date: Mon, 28 Feb 2022 16:18:16 +0100 Subject: [PATCH 0620/1246] Fix outgoing. --- .../source/outgoing/api_responses/003.php | 11 +++++++---- .../source/outgoing/api_responses/004.php | 11 +++++++---- .../source/outgoing/localization/001.php | 5 ++++- .../source/outgoing/localization/002.php | 5 ++++- .../source/outgoing/localization/003.php | 5 ++++- user_guide_src/source/outgoing/response/011.php | 5 ++++- .../source/outgoing/view_decorators/002.php | 9 ++++++--- .../source/outgoing/view_layouts/001.php | 7 +++++-- .../source/outgoing/view_parser/012.php | 11 +++++++---- .../source/outgoing/view_parser/013.php | 9 ++++++--- .../source/outgoing/view_parser/014.php | 15 +++++++++------ .../source/outgoing/view_parser/016.php | 9 ++++++--- .../source/outgoing/view_parser/017.php | 9 ++++++--- 13 files changed, 75 insertions(+), 36 deletions(-) diff --git a/user_guide_src/source/outgoing/api_responses/003.php b/user_guide_src/source/outgoing/api_responses/003.php index ab1db7ccdc45..a8e8ed09de64 100644 --- a/user_guide_src/source/outgoing/api_responses/003.php +++ b/user_guide_src/source/outgoing/api_responses/003.php @@ -1,6 +1,9 @@ \CodeIgniter\Format\JSONFormatter::class, - 'application/xml' => \CodeIgniter\Format\XMLFormatter::class, -]; +class Format extends BaseConfig +{ + public $formatters = [ + 'application/json' => \CodeIgniter\Format\JSONFormatter::class, + 'application/xml' => \CodeIgniter\Format\XMLFormatter::class, + ]; +} diff --git a/user_guide_src/source/outgoing/localization/001.php b/user_guide_src/source/outgoing/localization/001.php index c3b3de65be20..53d156de0545 100644 --- a/user_guide_src/source/outgoing/localization/001.php +++ b/user_guide_src/source/outgoing/localization/001.php @@ -1,3 +1,6 @@ '\CodeIgniter\View\Filters::abs', - 'capitalize' => '\CodeIgniter\View\Filters::capitalize', -]; +class View extends BaseView +{ + public $filters = [ + 'abs' => '\CodeIgniter\View\Filters::abs', + 'capitalize' => '\CodeIgniter\View\Filters::capitalize', + ]; +} diff --git a/user_guide_src/source/outgoing/view_parser/013.php b/user_guide_src/source/outgoing/view_parser/013.php index dbb096b416fb..78788515d081 100644 --- a/user_guide_src/source/outgoing/view_parser/013.php +++ b/user_guide_src/source/outgoing/view_parser/013.php @@ -1,5 +1,8 @@ '\str_repeat', -]; +class View extends BaseView +{ + public $filters = [ + 'str_repeat' => '\str_repeat', + ]; +} diff --git a/user_guide_src/source/outgoing/view_parser/014.php b/user_guide_src/source/outgoing/view_parser/014.php index d959d153d415..6219ce03b07d 100644 --- a/user_guide_src/source/outgoing/view_parser/014.php +++ b/user_guide_src/source/outgoing/view_parser/014.php @@ -1,8 +1,11 @@ '\Some\Class::methodName', - 'bar' => function ($str, array $params=[]) { - return $str; - }, -]; +class View extends BaseView +{ + 'foo' => '\Some\Class::methodName', + public $plugins = [ + 'bar' => function($str, array $params = []) { + return $str; + }, + ]; +} diff --git a/user_guide_src/source/outgoing/view_parser/016.php b/user_guide_src/source/outgoing/view_parser/016.php index e93bd3986957..5e2f5a2f0b0b 100644 --- a/user_guide_src/source/outgoing/view_parser/016.php +++ b/user_guide_src/source/outgoing/view_parser/016.php @@ -1,8 +1,11 @@ '\Some\Class::methodName' -]; +class View extends BaseView +{ + public $plugins = [ + 'foo' => '\Some\Class::methodName', + ]; +} // Tag is replaced by the return value of Some\Class::methodName static function. // {+ foo +} diff --git a/user_guide_src/source/outgoing/view_parser/017.php b/user_guide_src/source/outgoing/view_parser/017.php index 4e699d190bcd..d38e54c5274f 100644 --- a/user_guide_src/source/outgoing/view_parser/017.php +++ b/user_guide_src/source/outgoing/view_parser/017.php @@ -1,7 +1,10 @@ ['\Some\Class::methodName'] -]; +class View extends BaseView +{ + public $plugins = [ + 'foo' => ['\Some\Class::methodName'], + ]; +} // {+ foo +} inner content {+ /foo +} From e877550f220028a98bf330e484009d263c3be85a Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Mon, 28 Feb 2022 16:31:53 +0100 Subject: [PATCH 0621/1246] Fix libraries. --- .../source/libraries/caching/013.php | 15 +++--- .../source/libraries/caching/014.php | 17 ++++--- .../source/libraries/curlrequest/001.php | 5 +- .../source/libraries/encryption/005.php | 5 +- .../source/libraries/encryption/008.php | 11 +++-- .../source/libraries/honeypot/001.php | 23 +++++---- .../source/libraries/pagination/003.php | 10 ++-- .../source/libraries/pagination/004.php | 22 +++++---- .../source/libraries/pagination/010.php | 11 +++-- .../source/libraries/pagination/011.php | 13 +++-- .../source/libraries/security/002.php | 5 +- .../source/libraries/security/003.php | 5 +- .../source/libraries/security/004.php | 5 +- .../source/libraries/security/005.php | 5 +- .../source/libraries/security/006.php | 15 +++--- .../source/libraries/security/007.php | 13 +++-- .../source/libraries/security/008.php | 13 +++-- .../source/libraries/security/009.php | 11 +++-- .../source/libraries/sessions/040.php | 7 ++- .../source/libraries/sessions/041.php | 5 +- .../source/libraries/sessions/042.php | 7 ++- .../source/libraries/sessions/043.php | 7 ++- .../source/libraries/sessions/044.php | 9 ++-- .../source/libraries/throttler/003.php | 11 +++-- .../source/libraries/throttler/004.php | 9 ++-- .../source/libraries/validation/003.php | 15 +++--- .../source/libraries/validation/031.php | 13 +++-- .../source/libraries/validation/032.php | 15 +++--- .../source/libraries/validation/034.php | 15 +++--- .../source/libraries/validation/036.php | 49 ++++++++++--------- 30 files changed, 228 insertions(+), 138 deletions(-) diff --git a/user_guide_src/source/libraries/caching/013.php b/user_guide_src/source/libraries/caching/013.php index 66f0fa99e959..52e77d4b7f4b 100644 --- a/user_guide_src/source/libraries/caching/013.php +++ b/user_guide_src/source/libraries/caching/013.php @@ -1,8 +1,11 @@ '127.0.0.1', - 'port' => 11211, - 'weight' => 1, - 'raw' => false, -]; +class Cache extends BaseConfig +{ + public $memcached = [ + 'host' => '127.0.0.1', + 'port' => 11211, + 'weight' => 1, + 'raw' => false, + ]; +} diff --git a/user_guide_src/source/libraries/caching/014.php b/user_guide_src/source/libraries/caching/014.php index 20dfb69ce9b0..2c0f5eb719bd 100644 --- a/user_guide_src/source/libraries/caching/014.php +++ b/user_guide_src/source/libraries/caching/014.php @@ -1,9 +1,12 @@ '127.0.0.1', - 'password' => null, - 'port' => 6379, - 'timeout' => 0, - 'database' => 0, -]; +class Cache extends BaseConfig +{ + public $redis = [ + 'host' => '127.0.0.1', + 'password' => null, + 'port' => 6379, + 'timeout' => 0, + 'database' => 0, + ]; +} diff --git a/user_guide_src/source/libraries/curlrequest/001.php b/user_guide_src/source/libraries/curlrequest/001.php index 43e1f74bc943..35d47924e213 100644 --- a/user_guide_src/source/libraries/curlrequest/001.php +++ b/user_guide_src/source/libraries/curlrequest/001.php @@ -1,3 +1,6 @@ ' +class Encryption extends BaseConfig +{ + // In Encryption, you may use + public $key = 'hex2bin:'; -// or -public $key = 'base64:' + // or + public $key = 'base64:'; +} diff --git a/user_guide_src/source/libraries/honeypot/001.php b/user_guide_src/source/libraries/honeypot/001.php index 1ed16460a9a4..8d73a4f1e586 100644 --- a/user_guide_src/source/libraries/honeypot/001.php +++ b/user_guide_src/source/libraries/honeypot/001.php @@ -1,12 +1,15 @@ [ - 'honeypot' - // 'csrf', - ], - 'after' => [ - 'toolbar', - 'honeypot', - ], -]; +class Filters extends BaseConfig +{ + public $globals = [ + 'before' => [ + 'honeypot', + // 'csrf', + ], + 'after' => [ + 'toolbar', + 'honeypot', + ], + ]; +} diff --git a/user_guide_src/source/libraries/pagination/003.php b/user_guide_src/source/libraries/pagination/003.php index f0ea0d90ed76..423adc232c19 100644 --- a/user_guide_src/source/libraries/pagination/003.php +++ b/user_guide_src/source/libraries/pagination/003.php @@ -10,10 +10,14 @@ // You can move the conditions to a separate method. // Model method -public function banned() +class UserModel extends Model { - $this->builder()->where('ban', 1); - return $this; // This will allow the call chain to be used. + public function banned() + { + $this->builder()->where('ban', 1); + + return $this; // This will allow the call chain to be used. + } } $data = [ diff --git a/user_guide_src/source/libraries/pagination/004.php b/user_guide_src/source/libraries/pagination/004.php index cd425a1026eb..6326d1f9c825 100644 --- a/user_guide_src/source/libraries/pagination/004.php +++ b/user_guide_src/source/libraries/pagination/004.php @@ -1,20 +1,22 @@ $userModel->paginate(10, 'group1'), - 'pages' => $pageModel->paginate(15, 'group2'), - 'pager' => $userModel->pager, - ]; + $data = [ + 'users' => $userModel->paginate(10, 'group1'), + 'pages' => $pageModel->paginate(15, 'group2'), + 'pager' => $userModel->pager, + ]; - echo view('users/index', $data); + echo view('users/index', $data); + } } - ?> diff --git a/user_guide_src/source/libraries/pagination/010.php b/user_guide_src/source/libraries/pagination/010.php index 95d27f8e4e3c..1f97238b0506 100644 --- a/user_guide_src/source/libraries/pagination/010.php +++ b/user_guide_src/source/libraries/pagination/010.php @@ -1,6 +1,9 @@ 'CodeIgniter\Pager\Views\default_full', - 'default_simple' => 'CodeIgniter\Pager\Views\default_simple', -]; +class Pager extends BaseConfig +{ + public $templates = [ + 'default_full' => 'CodeIgniter\Pager\Views\default_full', + 'default_simple' => 'CodeIgniter\Pager\Views\default_simple', + ]; +} diff --git a/user_guide_src/source/libraries/pagination/011.php b/user_guide_src/source/libraries/pagination/011.php index fa59edbacf9b..8387b1e82dbd 100644 --- a/user_guide_src/source/libraries/pagination/011.php +++ b/user_guide_src/source/libraries/pagination/011.php @@ -1,7 +1,10 @@ 'CodeIgniter\Pager\Views\default_full', - 'default_simple' => 'CodeIgniter\Pager\Views\default_simple', - 'front_full' => 'App\Views\Pagers\foundation_full', -]; +class Pager extends BaseConfig +{ + public $templates = [ + 'default_full' => 'CodeIgniter\Pager\Views\default_full', + 'default_simple' => 'CodeIgniter\Pager\Views\default_simple', + 'front_full' => 'App\Views\Pagers\foundation_full', + ]; +} diff --git a/user_guide_src/source/libraries/security/002.php b/user_guide_src/source/libraries/security/002.php index 292d5a9410dc..1ce5fbba68d9 100644 --- a/user_guide_src/source/libraries/security/002.php +++ b/user_guide_src/source/libraries/security/002.php @@ -1,3 +1,6 @@ [ - // 'honeypot', - 'csrf', - ], -]; +class Filters extends BaseConfig +{ + public $globals = [ + 'before' => [ + // 'honeypot', + 'csrf', + ], + ]; +} diff --git a/user_guide_src/source/libraries/security/007.php b/user_guide_src/source/libraries/security/007.php index d647d1b8c120..db1b03df65fb 100644 --- a/user_guide_src/source/libraries/security/007.php +++ b/user_guide_src/source/libraries/security/007.php @@ -1,7 +1,10 @@ [ - 'csrf' => ['except' => ['api/record/save']], - ], -]; +class Filters extends BaseConfig +{ + public $globals = [ + 'before' => [ + 'csrf' => ['except' => ['api/record/save']], + ], + ]; +} diff --git a/user_guide_src/source/libraries/security/008.php b/user_guide_src/source/libraries/security/008.php index c78d18937b08..2138994f0241 100644 --- a/user_guide_src/source/libraries/security/008.php +++ b/user_guide_src/source/libraries/security/008.php @@ -1,7 +1,10 @@ [ - 'csrf' => ['except' => ['api/record/[0-9]+']], - ], -]; +class Filters extends BaseConfig +{ + public $globals = [ + 'before' => [ + 'csrf' => ['except' => ['api/record/[0-9]+']], + ], + ]; +} diff --git a/user_guide_src/source/libraries/security/009.php b/user_guide_src/source/libraries/security/009.php index e2b03e79ba25..b2ffbeaadc37 100644 --- a/user_guide_src/source/libraries/security/009.php +++ b/user_guide_src/source/libraries/security/009.php @@ -1,6 +1,9 @@ ['csrf'], - 'post' => ['csrf'], -]; +class Filters extends BaseConfig +{ + public $methods = [ + 'get' => ['csrf'], + 'post' => ['csrf'], + ]; +} diff --git a/user_guide_src/source/libraries/sessions/040.php b/user_guide_src/source/libraries/sessions/040.php index a3724620886d..7aa5f051b875 100644 --- a/user_guide_src/source/libraries/sessions/040.php +++ b/user_guide_src/source/libraries/sessions/040.php @@ -1,4 +1,7 @@ \App\Filters\Throttle::class, -]; +class Filters extends BaseConfig +{ + public $aliases = [ + // ... + 'throttle' => \App\Filters\Throttle::class, + ]; +} diff --git a/user_guide_src/source/libraries/throttler/004.php b/user_guide_src/source/libraries/throttler/004.php index 455874cd5730..e7d0643db053 100644 --- a/user_guide_src/source/libraries/throttler/004.php +++ b/user_guide_src/source/libraries/throttler/004.php @@ -1,5 +1,8 @@ ['throttle'], -]; +class Filters extends BaseConfig +{ + public $methods = [ + 'post' => ['throttle'], + ]; +} diff --git a/user_guide_src/source/libraries/validation/003.php b/user_guide_src/source/libraries/validation/003.php index a6ae3a4a6fff..a9e83b94698b 100644 --- a/user_guide_src/source/libraries/validation/003.php +++ b/user_guide_src/source/libraries/validation/003.php @@ -1,8 +1,11 @@ 'CodeIgniter\Validation\Views\list', - 'single' => 'CodeIgniter\Validation\Views\single', - 'my_list' => '_errors_list', -]; +class Validation +{ + public $templates = [ + 'list' => 'CodeIgniter\Validation\Views\list', + 'single' => 'CodeIgniter\Validation\Views\single', + 'my_list' => '_errors_list', + ]; +} diff --git a/user_guide_src/source/libraries/validation/032.php b/user_guide_src/source/libraries/validation/032.php index ccee27b08ad7..9877e6e85579 100644 --- a/user_guide_src/source/libraries/validation/032.php +++ b/user_guide_src/source/libraries/validation/032.php @@ -5,9 +5,12 @@ use CodeIgniter\Validation\FormatRules; use CodeIgniter\Validation\Rules; -public $ruleSets = [ - Rules::class, - FormatRules::class, - FileRules::class, - CreditCardRules::class, -]; +class Validation +{ + public $ruleSets = [ + Rules::class, + FormatRules::class, + FileRules::class, + CreditCardRules::class, + ]; +} diff --git a/user_guide_src/source/libraries/validation/034.php b/user_guide_src/source/libraries/validation/034.php index a6a9b07f54ef..843b623ba98c 100644 --- a/user_guide_src/source/libraries/validation/034.php +++ b/user_guide_src/source/libraries/validation/034.php @@ -1,12 +1,15 @@ required($str ?? ''); + // If the field is present we can safely assume that + // the field is here, no matter whether the corresponding + // search field is present or not. + $present = $this->required($str ?? ''); - if ($present) { - return true; - } + if ($present) { + return true; + } - // Still here? Then we fail this test if - // any of the fields are present in $data - // as $fields is the lis - $requiredFields = []; + // Still here? Then we fail this test if + // any of the fields are present in $data + // as $fields is the lis + $requiredFields = []; - foreach ($fields as $field) { - if (array_key_exists($field, $data)) { - $requiredFields[] = $field; + foreach ($fields as $field) { + if (array_key_exists($field, $data)) { + $requiredFields[] = $field; + } } - } - // Remove any keys with empty values since, that means they - // weren't truly there, as far as this is concerned. - $requiredFields = array_filter($requiredFields, function ($item) use ($data) { - return ! empty($data[$item]); - }); + // Remove any keys with empty values since, that means they + // weren't truly there, as far as this is concerned. + $requiredFields = array_filter($requiredFields, static function ($item) use ($data) { + return ! empty($data[$item]); + }); - return empty($requiredFields); + return empty($requiredFields); + } } From 9aad6521d16ae398618ba6b2ae1486a88ae48c1e Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Mon, 28 Feb 2022 16:34:19 +0100 Subject: [PATCH 0622/1246] Edit view_parser. --- user_guide_src/source/outgoing/view_parser/014.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/user_guide_src/source/outgoing/view_parser/014.php b/user_guide_src/source/outgoing/view_parser/014.php index 6219ce03b07d..182480337653 100644 --- a/user_guide_src/source/outgoing/view_parser/014.php +++ b/user_guide_src/source/outgoing/view_parser/014.php @@ -2,8 +2,9 @@ class View extends BaseView { - 'foo' => '\Some\Class::methodName', + public $plugins = [ + 'foo' => '\Some\Class::methodName', 'bar' => function($str, array $params = []) { return $str; }, From 439153fe4838ab68ef592d9c227e95fd10a24f2e Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Mon, 28 Feb 2022 16:40:00 +0100 Subject: [PATCH 0623/1246] Fix testing from code review. --- user_guide_src/source/testing/overview.rst | 5 +++-- user_guide_src/source/testing/overview/007.php | 5 +---- user_guide_src/source/testing/overview/019.php | 6 +++--- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/user_guide_src/source/testing/overview.rst b/user_guide_src/source/testing/overview.rst index 648b3b4e79d9..2cfae8328caa 100644 --- a/user_guide_src/source/testing/overview.rst +++ b/user_guide_src/source/testing/overview.rst @@ -87,8 +87,9 @@ to help with staging and clean up:: public static function setUpBeforeClass(): void public static function tearDownAfterClass(): void - public function setUp(): void - public function tearDown(): void + + protected function setUp(): void + protected function tearDown(): void The static methods run before and after the entire test case, whereas the local methods run between each test. If you implement any of these special functions make sure you run their diff --git a/user_guide_src/source/testing/overview/007.php b/user_guide_src/source/testing/overview/007.php index 1ba21e197b0a..4921e027b721 100644 --- a/user_guide_src/source/testing/overview/007.php +++ b/user_guide_src/source/testing/overview/007.php @@ -10,10 +10,7 @@ protected function setUpAuthTrait() // ... } -/** - * @internal - */ -final class AuthenticationFeatureTest +final class AuthenticationFeatureTest extends CIUnitTestCase { use AuthTrait; diff --git a/user_guide_src/source/testing/overview/019.php b/user_guide_src/source/testing/overview/019.php index 3ede5c1e1291..d45682fcffaa 100644 --- a/user_guide_src/source/testing/overview/019.php +++ b/user_guide_src/source/testing/overview/019.php @@ -2,18 +2,18 @@ final class Sometest extends CIUnitTestCase { - protected function setUp() + protected function setUp(): void { CITestStreamFilter::$buffer = ''; $this->stream_filter = stream_filter_append(STDOUT, 'CITestStreamFilter'); } - protected function tearDown() + protected function tearDown(): void { stream_filter_remove($this->stream_filter); } - public function testSomeOutput() + public function testSomeOutput(): void { CLI::write('first.'); $expected = "first.\n"; From a1206a62e64c79cf42d65c4a066025150842cda2 Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Mon, 28 Feb 2022 22:33:01 +0100 Subject: [PATCH 0624/1246] Fix view_parser examples. --- user_guide_src/source/outgoing/view_parser.rst | 4 ++-- user_guide_src/source/outgoing/view_parser/014.php | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/user_guide_src/source/outgoing/view_parser.rst b/user_guide_src/source/outgoing/view_parser.rst index cee76727ef84..2e615e52bdb9 100644 --- a/user_guide_src/source/outgoing/view_parser.rst +++ b/user_guide_src/source/outgoing/view_parser.rst @@ -467,11 +467,11 @@ Registering a Plugin At its simplest, all you need to do to register a new plugin and make it ready for use is to add it to the **app/Config/View.php**, under the **$plugins** array. The key is the name of the plugin that is -used within the template file. The value is any valid PHP callable, including static class methods, and closures: +used within the template file. The value is any valid PHP callable, including static class methods: .. literalinclude:: view_parser/014.php -Any closures that are being used must be defined in the config file's constructor: +You can also use closures, but these can only be defined in the config file's constructor: .. literalinclude:: view_parser/015.php diff --git a/user_guide_src/source/outgoing/view_parser/014.php b/user_guide_src/source/outgoing/view_parser/014.php index 182480337653..22dd679fb9bd 100644 --- a/user_guide_src/source/outgoing/view_parser/014.php +++ b/user_guide_src/source/outgoing/view_parser/014.php @@ -2,11 +2,7 @@ class View extends BaseView { - public $plugins = [ 'foo' => '\Some\Class::methodName', - 'bar' => function($str, array $params = []) { - return $str; - }, ]; } From de2113d130d3739baf4510496a9b7c9c5678e4b5 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 28 Feb 2022 16:36:08 +0900 Subject: [PATCH 0625/1246] docs: add section to link to "Extending the Controller" --- user_guide_src/source/incoming/controllers.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/user_guide_src/source/incoming/controllers.rst b/user_guide_src/source/incoming/controllers.rst index 21c717d9eace..5ade052c563a 100644 --- a/user_guide_src/source/incoming/controllers.rst +++ b/user_guide_src/source/incoming/controllers.rst @@ -307,6 +307,11 @@ Example: .. literalinclude:: controllers/012.php +Extending the Controller +************************ + +If you want to extend the controller, see :doc:`../extending/basecontroller`. + That's it! ********** From 4b5fd2fb341f16d1ea4f3d353b43f98e1964b2c0 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 1 Mar 2022 13:43:29 +0900 Subject: [PATCH 0626/1246] docs: fix section titles and its marks --- .../source/tutorial/create_news_items.rst | 14 ++++++------ .../source/tutorial/news_section.rst | 22 +++++++++---------- .../source/tutorial/static_pages.rst | 16 +++++++------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/user_guide_src/source/tutorial/create_news_items.rst b/user_guide_src/source/tutorial/create_news_items.rst index 7925edc05fd1..4300b44c3155 100644 --- a/user_guide_src/source/tutorial/create_news_items.rst +++ b/user_guide_src/source/tutorial/create_news_items.rst @@ -1,4 +1,4 @@ -Create news items +Create News Items ################# You now know how you can read data from a database using CodeIgniter, but @@ -7,7 +7,7 @@ you'll expand your news controller and model created earlier to include this functionality. Enable CSRF Filter ------------------- +****************** Before creating a form, let's enable the CSRF protection. @@ -22,8 +22,8 @@ You can read more about the CSRF protection in :doc:`Security `. @@ -47,8 +47,8 @@ The seed records might be something like: (2,'Say it isn\'t so!','say-it-isnt-so','Scientists conclude that some programmers have a sense of humor.'), (3,'Caffeination, Yes!','caffeination-yes','World\'s largest coffee shop open onsite nested coffee shop for staff only.'); -Connect to your database -------------------------------------------------------- +Connect to Your Database +************************ The local configuration file, ``.env``, that you created when you installed CodeIgniter, should have the database property settings uncommented and @@ -63,8 +63,8 @@ your database properly as described :doc:`here <../database/configuration>`. database.default.password = root database.default.DBDriver = MySQLi -Setting up your model -------------------------------------------------------- +Setting up Your Model +********************* Instead of writing database operations right in the controller, queries should be placed in a model, so they can easily be reused later. Models @@ -106,8 +106,8 @@ that use the Query Builder to run their commands on the current table, and returning an array of results in the format of your choice. In this example, ``findAll()`` returns an array of array. -Display the news -------------------------------------------------------- +Display the News +**************** Now that the queries are written, the model should be tied to the views that are going to display the news items to the user. This could be done @@ -174,7 +174,7 @@ The only thing left to do is create the corresponding view at .. literalinclude:: news_section/007.php Routing -------------------------------------------------------- +******* Because of the wildcard routing rule created earlier, you need an extra route to view the controller that you just made. Modify your routing file diff --git a/user_guide_src/source/tutorial/static_pages.rst b/user_guide_src/source/tutorial/static_pages.rst index 090a4d79e2f8..c6091aa46609 100644 --- a/user_guide_src/source/tutorial/static_pages.rst +++ b/user_guide_src/source/tutorial/static_pages.rst @@ -1,5 +1,5 @@ -Static pages -############################################################################### +Static Pages +############ .. note:: This tutorial assumes you've downloaded CodeIgniter and :doc:`installed the framework <../installation/index>` in your @@ -27,8 +27,8 @@ you'll see URL patterns that match: As URL schemes become more complex, this may change. But for now, this is all we will need to know. -Let's make our first controller -------------------------------------------------------- +Let's Make our First Controller +******************************* Create a file at **app/Controllers/Pages.php** with the following code. @@ -85,8 +85,8 @@ includes the following code:: function. It's a global function provided by CodeIgniter to help prevent XSS attacks. You can read more about it :doc:`here `. -Adding logic to the controller -------------------------------------------------------- +Adding Logic to the Controller +****************************** Earlier you set up a controller with a ``view()`` method. The method accepts one parameter, which is the name of the page to be loaded. The @@ -131,7 +131,7 @@ view. :doc:`here `. Running the App -------------------------------------------------------- +*************** Ready to test? You cannot run the app using PHP's built-in server, since it will not properly process the ``.htaccess`` rules that are provided in @@ -177,7 +177,7 @@ controller you made above produces... +---------------------------------+-----------------------------------------------------------------+ Routing -------------------------------------------------------- +******* The controller is now functioning! From 6f3dde36f192b77a2f683d2fa2742b361438de16 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 1 Mar 2022 13:47:57 +0900 Subject: [PATCH 0627/1246] docs: fix RST format `::` --- .../source/tutorial/create_news_items.rst | 8 ++----- user_guide_src/source/tutorial/index.rst | 8 ++----- .../source/tutorial/news_section.rst | 21 +++++++------------ .../source/tutorial/static_pages.rst | 16 ++++---------- 4 files changed, 16 insertions(+), 37 deletions(-) diff --git a/user_guide_src/source/tutorial/create_news_items.rst b/user_guide_src/source/tutorial/create_news_items.rst index 4300b44c3155..32bc4b703e18 100644 --- a/user_guide_src/source/tutorial/create_news_items.rst +++ b/user_guide_src/source/tutorial/create_news_items.rst @@ -29,9 +29,7 @@ To input data into the database, you need to create a form where you can input the information to be stored. This means you'll be needing a form with two fields, one for the title and one for the text. You'll derive the slug from our title in the model. Create a new view at -**app/Views/news/create.php**. - -:: +**app/Views/news/create.php**::

    @@ -89,9 +87,7 @@ slug, perfect for creating URIs. After this, a view is loaded to display a success message. Create a view at **app/Views/news/success.php** and write a success message. -This could be as simple as: - -:: +This could be as simple as:: News item created successfully. diff --git a/user_guide_src/source/tutorial/index.rst b/user_guide_src/source/tutorial/index.rst index 35cb5ba9ba7f..a47cdab405d1 100644 --- a/user_guide_src/source/tutorial/index.rst +++ b/user_guide_src/source/tutorial/index.rst @@ -55,9 +55,7 @@ Getting Up and Running You can download a release manually from the site, but for this tutorial we will use the recommended way and install the AppStarter package through Composer. -From your command line type the following: - -:: +From your command line type the following:: > composer create-project codeigniter4/appstarter ci-news @@ -88,9 +86,7 @@ The Welcome Page **************** Now point your browser to the correct URL you will be greeted by a welcome screen. -Try it now by heading to the following URL: - -:: +Try it now by heading to the following URL:: http://localhost:8080 diff --git a/user_guide_src/source/tutorial/news_section.rst b/user_guide_src/source/tutorial/news_section.rst index b9713c3acadb..2797c8a5cfaa 100644 --- a/user_guide_src/source/tutorial/news_section.rst +++ b/user_guide_src/source/tutorial/news_section.rst @@ -18,13 +18,7 @@ commands (mysql, MySQL Workbench, or phpMyAdmin). You need to create a database that can be used for this tutorial, and then configure CodeIgniter to use it. -Using your database client, connect to your database and run the SQL command below (MySQL). -Also, add some seed records. For now, we'll just show you the SQL statements needed -to create the table, but you should be aware that this can be done programmatically -once you are more familiar with CodeIgniter; you can read about :doc:`Migrations <../dbmgmt/migration>` -and :doc:`Seeds <../dbmgmt/seeds>` to create more useful database setups later. - -:: +Using your database client, connect to your database and run the SQL command below (MySQL):: CREATE TABLE news ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, @@ -35,12 +29,15 @@ and :doc:`Seeds <../dbmgmt/seeds>` to create more useful database setups later. KEY slug (slug) ); +Also, add some seed records. For now, we'll just show you the SQL statements needed +to create the table, but you should be aware that this can be done programmatically +once you are more familiar with CodeIgniter; you can read about :doc:`Migrations <../dbmgmt/migration>` +and :doc:`Seeds <../dbmgmt/seeds>` to create more useful database setups later. + A note of interest: a "slug", in the context of web publishing, is a user- and SEO-friendly short text used in a URL to identify and describe a resource. -The seed records might be something like: - -:: +The seed records might be something like:: INSERT INTO news VALUES (1,'Elvis sighted','elvis-sighted','Elvis was sighted at the Podunk internet cafe. It looked like he was writing a CodeIgniter app.'), @@ -53,9 +50,7 @@ Connect to Your Database The local configuration file, ``.env``, that you created when you installed CodeIgniter, should have the database property settings uncommented and set appropriately for the database you want to use. Make sure you've configured -your database properly as described :doc:`here <../database/configuration>`. - -:: +your database properly as described :doc:`here <../database/configuration>`:: database.default.hostname = localhost database.default.database = ci4tutorial diff --git a/user_guide_src/source/tutorial/static_pages.rst b/user_guide_src/source/tutorial/static_pages.rst index c6091aa46609..5128d6665e2c 100644 --- a/user_guide_src/source/tutorial/static_pages.rst +++ b/user_guide_src/source/tutorial/static_pages.rst @@ -9,18 +9,14 @@ The first thing you're going to do is set up a **controller** to handle static pages. A controller is simply a class that helps delegate work. It is the glue of your web application. -For example, when a call is made to: - -:: +For example, when a call is made to:: http://example.com/news/latest/10 We might imagine that there is a controller named "news". The method being called on news would be "latest". The news method's job could be to grab 10 news items, and render them on the page. Very often in MVC, -you'll see URL patterns that match: - -:: +you'll see URL patterns that match:: http://example.com/[controller-class]/[controller-method]/[arguments] @@ -138,9 +134,7 @@ since it will not properly process the ``.htaccess`` rules that are provided in ``public``, and which eliminate the need to specify "index.php/" as part of a URL. CodeIgniter has its own command that you can use though. -From the command line, at the root of your project: - -:: +From the command line, at the root of your project:: > php spark serve @@ -182,9 +176,7 @@ Routing The controller is now functioning! Using custom routing rules, you have the power to map any URI to any -controller and method, and break free from the normal convention: - -:: +controller and method, and break free from the normal convention:: http://example.com/[controller-class]/[controller-method]/[arguments] From 4e4ab0b381e57a334c89d0626812c24746656bf7 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 1 Mar 2022 13:48:24 +0900 Subject: [PATCH 0628/1246] docs: fix out-of-dated description --- user_guide_src/source/tutorial/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/tutorial/index.rst b/user_guide_src/source/tutorial/index.rst index a47cdab405d1..e940ec849057 100644 --- a/user_guide_src/source/tutorial/index.rst +++ b/user_guide_src/source/tutorial/index.rst @@ -22,7 +22,7 @@ This tutorial will primarily focus on: - Model-View-Controller basics - Routing basics - Form validation -- Performing basic database queries using CodeIgniter's "Query Builder" +- Performing basic database queries using CodeIgniter's Model The entire tutorial is split up over several pages, each explaining a small part of the functionality of the CodeIgniter framework. You'll go From 6288b6b60722a750483feed8da5dd90dbe71a24a Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 1 Mar 2022 14:43:32 +0900 Subject: [PATCH 0629/1246] docs: add how to code to prevent CSRF --- user_guide_src/source/libraries/security.rst | 33 +++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/user_guide_src/source/libraries/security.rst b/user_guide_src/source/libraries/security.rst index 7d69bc84ea2c..456d92207ef9 100644 --- a/user_guide_src/source/libraries/security.rst +++ b/user_guide_src/source/libraries/security.rst @@ -22,12 +22,43 @@ If you find a case where you do need direct access though, you may load it throu .. _cross-site-request-forgery: ********************************* -Cross-site request forgery (CSRF) +Cross-Site Request Forgery (CSRF) ********************************* .. warning:: The CSRF Protection is only available for **POST/PUT/PATCH/DELETE** requests. Requests for other methods are not protected. +Prerequisite +============ + +When you use the CodeIgniter's CSRF protection, you still need to code as the following. +Otherwise, the CSRF protection may be bypassed. + +When Auto-Routing is Disabled +----------------------------- + +Do one of the following: + +1. Do not use ``$routes->add()``, and use HTTP verbs in routes. +2. Check the request method in the controller method before processing. + +E.g.:: + + if (strtolower($this->request->getMethod()) !== 'post') { + return $this->response->setStatusCode(405)->setBody('Method Not Allowed'); + } + +When Auto-Routing is Enabled +---------------------------- + +1. Check the request method in the controller method before processing. + +E.g.:: + + if (strtolower($this->request->getMethod()) !== 'post') { + return $this->response->setStatusCode(405)->setBody('Method Not Allowed'); + } + Config for CSRF =============== From bcb3607debb42fa23ee5669ab6ffccf5e91065b6 Mon Sep 17 00:00:00 2001 From: Andrey Pyzhikov <5071@mail.ru> Date: Tue, 1 Mar 2022 14:55:18 +0800 Subject: [PATCH 0630/1246] unnecessary parameter check. Signed-off-by: Andrey Pyzhikov <5071@mail.ru> --- system/Database/BaseBuilder.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/system/Database/BaseBuilder.php b/system/Database/BaseBuilder.php index cc3e245a107b..43ce80c34abf 100644 --- a/system/Database/BaseBuilder.php +++ b/system/Database/BaseBuilder.php @@ -450,12 +450,6 @@ public function selectCount(string $select = '', string $alias = '') */ public function selectSubquery(BaseBuilder $subquery, string $as): self { - if (! $this->isSubquery($subquery)) { - throw new DatabaseException( - 'The BaseBuilder::selectSubquery() method expects a BaseBuilder instance.' - ); - } - $this->QBSelect[] = $this->buildSubquery($subquery, true, $as); return $this; From 8f8a2e760ced0d7ed651c404c35783e858240440 Mon Sep 17 00:00:00 2001 From: Alex Schmitz <40514119+sfadschm@users.noreply.github.com> Date: Tue, 1 Mar 2022 08:48:25 +0100 Subject: [PATCH 0631/1246] Fix class names. Co-authored-by: kenjis --- user_guide_src/source/incoming/controllers/010.php | 2 +- user_guide_src/source/incoming/controllers/011.php | 2 +- user_guide_src/source/incoming/controllers/012.php | 2 +- user_guide_src/source/incoming/controllers/013.php | 2 +- user_guide_src/source/incoming/controllers/017.php | 2 +- user_guide_src/source/incoming/controllers/018.php | 2 +- user_guide_src/source/incoming/controllers/019.php | 2 +- user_guide_src/source/incoming/routing/011.php | 2 +- user_guide_src/source/testing/overview/017.php | 2 +- user_guide_src/source/testing/overview/018.php | 2 +- user_guide_src/source/testing/overview/019.php | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/user_guide_src/source/incoming/controllers/010.php b/user_guide_src/source/incoming/controllers/010.php index b74d386d6289..1add1c02464e 100644 --- a/user_guide_src/source/incoming/controllers/010.php +++ b/user_guide_src/source/incoming/controllers/010.php @@ -1,6 +1,6 @@ Date: Tue, 1 Mar 2022 08:57:39 +0100 Subject: [PATCH 0632/1246] Indicate other class methods/properties by '...'. Co-authored-by: kenjis --- user_guide_src/source/database/configuration/001.php | 2 ++ user_guide_src/source/general/modules/001.php | 2 ++ user_guide_src/source/general/modules/002.php | 4 ++++ user_guide_src/source/general/modules/003.php | 2 ++ user_guide_src/source/general/modules/004.php | 2 ++ user_guide_src/source/incoming/filters/003.php | 2 ++ user_guide_src/source/installation/troubleshooting/001.php | 4 ++++ user_guide_src/source/installation/upgrade_415/001.php | 4 ++++ .../source/installation/upgrade_localization/001.php | 4 ++++ user_guide_src/source/installation/upgrade_security/001.php | 4 ++++ user_guide_src/source/libraries/caching/013.php | 3 +++ user_guide_src/source/libraries/encryption/005.php | 2 ++ 12 files changed, 35 insertions(+) diff --git a/user_guide_src/source/database/configuration/001.php b/user_guide_src/source/database/configuration/001.php index 5a59fabfcfdc..ed5ba8a34304 100644 --- a/user_guide_src/source/database/configuration/001.php +++ b/user_guide_src/source/database/configuration/001.php @@ -20,4 +20,6 @@ class Database extends Config 'strictOn' => false, 'failover' => [], ]; + + // ... } diff --git a/user_guide_src/source/general/modules/001.php b/user_guide_src/source/general/modules/001.php index 47a56e70072f..a11a9c4345cc 100644 --- a/user_guide_src/source/general/modules/001.php +++ b/user_guide_src/source/general/modules/001.php @@ -7,4 +7,6 @@ class Autoload extends AutoloadConfig 'Config' => APPPATH . 'Config', 'Acme' => ROOTPATH . 'acme', ]; + + // ... } diff --git a/user_guide_src/source/general/modules/002.php b/user_guide_src/source/general/modules/002.php index 4d7b355da602..5b2826e9fcbc 100644 --- a/user_guide_src/source/general/modules/002.php +++ b/user_guide_src/source/general/modules/002.php @@ -2,9 +2,13 @@ class Autoload extends AutoloadConfig { + // ... + public $files = [ 'path/to/my/functions.php', 'path/to/my/constants.php', 'path/to/my/bootstrap.php', ]; + + // ... } diff --git a/user_guide_src/source/general/modules/003.php b/user_guide_src/source/general/modules/003.php index 1124ef4d04db..a6247cd94103 100644 --- a/user_guide_src/source/general/modules/003.php +++ b/user_guide_src/source/general/modules/003.php @@ -7,4 +7,6 @@ class Autoload extends AutoloadConfig 'Config' => APPPATH . 'Config', 'Acme\Blog' => ROOTPATH . 'acme/Blog', // Change ]; + + // ... } diff --git a/user_guide_src/source/general/modules/004.php b/user_guide_src/source/general/modules/004.php index 0f2c1c3967ad..c085dfa81736 100644 --- a/user_guide_src/source/general/modules/004.php +++ b/user_guide_src/source/general/modules/004.php @@ -3,4 +3,6 @@ class Modules extends BaseModules { public $discoverInComposer = false; + + // ... } diff --git a/user_guide_src/source/incoming/filters/003.php b/user_guide_src/source/incoming/filters/003.php index a757fdf8f029..6957806f0bf5 100644 --- a/user_guide_src/source/incoming/filters/003.php +++ b/user_guide_src/source/incoming/filters/003.php @@ -5,4 +5,6 @@ class Filters extends BaseConfig public $aliases = [ 'csrf' => \CodeIgniter\Filters\CSRF::class, ]; + + // ... } diff --git a/user_guide_src/source/installation/troubleshooting/001.php b/user_guide_src/source/installation/troubleshooting/001.php index c3aa124d6ce2..f8d52a35fb83 100644 --- a/user_guide_src/source/installation/troubleshooting/001.php +++ b/user_guide_src/source/installation/troubleshooting/001.php @@ -2,5 +2,9 @@ class App extends BaseConfig { + // ... + public $indexPage = 'index.php'; + + // ... } diff --git a/user_guide_src/source/installation/upgrade_415/001.php b/user_guide_src/source/installation/upgrade_415/001.php index b2ffbeaadc37..98909b124369 100644 --- a/user_guide_src/source/installation/upgrade_415/001.php +++ b/user_guide_src/source/installation/upgrade_415/001.php @@ -2,8 +2,12 @@ class Filters extends BaseConfig { + // ... + public $methods = [ 'get' => ['csrf'], 'post' => ['csrf'], ]; + + // ... } diff --git a/user_guide_src/source/installation/upgrade_localization/001.php b/user_guide_src/source/installation/upgrade_localization/001.php index 53d156de0545..a3d7897a9956 100644 --- a/user_guide_src/source/installation/upgrade_localization/001.php +++ b/user_guide_src/source/installation/upgrade_localization/001.php @@ -2,5 +2,9 @@ class App extends BaseConfig { + // ... + public $defaultLocale = 'en'; + + // ... } diff --git a/user_guide_src/source/installation/upgrade_security/001.php b/user_guide_src/source/installation/upgrade_security/001.php index 3e487bb37686..57c7b583ed88 100644 --- a/user_guide_src/source/installation/upgrade_security/001.php +++ b/user_guide_src/source/installation/upgrade_security/001.php @@ -2,10 +2,14 @@ class Filters extends BaseConfig { + // ... + public $globals = [ 'before' => [ // 'honeypot', 'csrf', ], ]; + + // ... } diff --git a/user_guide_src/source/libraries/caching/013.php b/user_guide_src/source/libraries/caching/013.php index 52e77d4b7f4b..a68fb194b935 100644 --- a/user_guide_src/source/libraries/caching/013.php +++ b/user_guide_src/source/libraries/caching/013.php @@ -2,10 +2,13 @@ class Cache extends BaseConfig { + // ... public $memcached = [ 'host' => '127.0.0.1', 'port' => 11211, 'weight' => 1, 'raw' => false, ]; + + // ... } diff --git a/user_guide_src/source/libraries/encryption/005.php b/user_guide_src/source/libraries/encryption/005.php index 992d322a1bd2..37e9ae3fe79b 100644 --- a/user_guide_src/source/libraries/encryption/005.php +++ b/user_guide_src/source/libraries/encryption/005.php @@ -3,4 +3,6 @@ class Encryption extends BaseConfig { public $key = 'YOUR KEY'; + + // ... } From 546015f97e1c5ba96492d58cf5274cdf6e47e35a Mon Sep 17 00:00:00 2001 From: Alex Schmitz <40514119+sfadschm@users.noreply.github.com> Date: Tue, 1 Mar 2022 09:50:45 +0100 Subject: [PATCH 0633/1246] Fix ... Co-authored-by: kenjis --- user_guide_src/source/libraries/encryption/008.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/user_guide_src/source/libraries/encryption/008.php b/user_guide_src/source/libraries/encryption/008.php index 77849fb96f6a..f48f42a0bbf5 100644 --- a/user_guide_src/source/libraries/encryption/008.php +++ b/user_guide_src/source/libraries/encryption/008.php @@ -7,4 +7,6 @@ class Encryption extends BaseConfig // or public $key = 'base64:'; + + // ... } From 4cc4ecc0c2771ba1b30295bf0c613bd9db49c36c Mon Sep 17 00:00:00 2001 From: Alex Schmitz <40514119+sfadschm@users.noreply.github.com> Date: Tue, 1 Mar 2022 09:59:31 +0100 Subject: [PATCH 0634/1246] Add namspaces and use statements - first run. Co-authored-by: kenjis --- user_guide_src/source/database/configuration/001.php | 4 ++++ user_guide_src/source/dbmgmt/migration/002.php | 4 ++++ user_guide_src/source/dbmgmt/seeds/003.php | 4 ++++ user_guide_src/source/extending/basecontroller/002.php | 2 ++ user_guide_src/source/extending/basecontroller/003.php | 2 ++ user_guide_src/source/extending/core_classes/002.php | 4 ++++ user_guide_src/source/general/configuration/008.php | 4 ++++ user_guide_src/source/general/logging/002.php | 4 ++++ user_guide_src/source/general/logging/003.php | 4 ++++ user_guide_src/source/general/logging/004.php | 4 ++++ user_guide_src/source/general/managing_apps/001.php | 2 ++ user_guide_src/source/general/modules/001.php | 4 ++++ user_guide_src/source/general/modules/002.php | 4 ++++ user_guide_src/source/general/modules/003.php | 4 ++++ user_guide_src/source/general/modules/004.php | 4 ++++ user_guide_src/source/incoming/controllers/010.php | 2 ++ user_guide_src/source/incoming/filters/002.php | 6 ++++++ user_guide_src/source/incoming/filters/003.php | 4 ++++ user_guide_src/source/incoming/routing/011.php | 2 ++ user_guide_src/source/installation/troubleshooting/001.php | 4 ++++ user_guide_src/source/installation/upgrade_415/001.php | 4 ++++ .../source/installation/upgrade_localization/001.php | 4 ++++ user_guide_src/source/installation/upgrade_security/001.php | 4 ++++ user_guide_src/source/libraries/caching/013.php | 4 ++++ user_guide_src/source/libraries/curlrequest/001.php | 4 ++++ user_guide_src/source/libraries/encryption/005.php | 4 ++++ 26 files changed, 96 insertions(+) diff --git a/user_guide_src/source/database/configuration/001.php b/user_guide_src/source/database/configuration/001.php index ed5ba8a34304..5631cf7faede 100644 --- a/user_guide_src/source/database/configuration/001.php +++ b/user_guide_src/source/database/configuration/001.php @@ -1,5 +1,9 @@ Date: Tue, 1 Mar 2022 11:05:37 +0100 Subject: [PATCH 0635/1246] Add namespaces and use statements - second run. --- user_guide_src/source/cli/cli_library/001.php | 4 ++-- user_guide_src/source/concepts/services/006.php | 6 +++++- user_guide_src/source/concepts/services/007.php | 4 ++++ user_guide_src/source/concepts/services/008.php | 4 ++++ user_guide_src/source/concepts/services/010.php | 6 +++++- user_guide_src/source/database/configuration/006.php | 4 ++++ user_guide_src/source/database/configuration/008.php | 6 +++++- user_guide_src/source/dbmgmt/migration/005.php | 4 +++- user_guide_src/source/extending/basecontroller/001.php | 2 -- user_guide_src/source/extending/basecontroller/004.php | 8 ++++++-- user_guide_src/source/general/errors/005.php | 4 ++++ user_guide_src/source/general/errors/006.php | 6 +++++- user_guide_src/source/helpers/test_helper/002.php | 4 +++- user_guide_src/source/incoming/controllers/002.php | 2 +- user_guide_src/source/incoming/controllers/003.php | 2 +- user_guide_src/source/incoming/controllers/004.php | 2 +- user_guide_src/source/incoming/controllers/011.php | 2 ++ user_guide_src/source/incoming/controllers/012.php | 2 ++ user_guide_src/source/incoming/controllers/013.php | 2 ++ user_guide_src/source/incoming/controllers/017.php | 2 ++ user_guide_src/source/incoming/controllers/018.php | 2 ++ user_guide_src/source/incoming/controllers/019.php | 2 ++ user_guide_src/source/incoming/filters/003.php | 3 +-- user_guide_src/source/incoming/filters/004.php | 4 ++++ user_guide_src/source/incoming/filters/005.php | 4 ++++ user_guide_src/source/incoming/filters/006.php | 4 ++++ user_guide_src/source/incoming/filters/007.php | 4 ++++ user_guide_src/source/incoming/filters/008.php | 4 ++++ user_guide_src/source/incoming/filters/009.php | 4 ++++ user_guide_src/source/incoming/filters/011.php | 4 ++++ user_guide_src/source/incoming/incomingrequest/022.php | 4 +++- .../source/installation/troubleshooting/002.php | 7 +++++++ user_guide_src/source/installation/upgrade_415/001.php | 5 ++--- .../source/installation/upgrade_security/001.php | 5 ++--- user_guide_src/source/libraries/caching/013.php | 3 +-- user_guide_src/source/libraries/caching/014.php | 4 ++++ user_guide_src/source/libraries/encryption/008.php | 5 ++++- user_guide_src/source/libraries/files/014.php | 4 +++- user_guide_src/source/libraries/honeypot/001.php | 4 ++++ user_guide_src/source/libraries/pagination/004.php | 5 ++++- user_guide_src/source/libraries/pagination/010.php | 4 ++++ user_guide_src/source/libraries/pagination/011.php | 4 ++++ user_guide_src/source/libraries/security/002.php | 4 ++++ user_guide_src/source/libraries/security/003.php | 4 ++++ user_guide_src/source/libraries/security/004.php | 4 ++++ user_guide_src/source/libraries/security/005.php | 4 ++++ user_guide_src/source/libraries/security/006.php | 4 ++++ user_guide_src/source/libraries/security/007.php | 4 ++++ user_guide_src/source/libraries/security/008.php | 4 ++++ user_guide_src/source/libraries/security/009.php | 4 ++++ user_guide_src/source/libraries/sessions/040.php | 4 ++++ user_guide_src/source/libraries/sessions/041.php | 4 ++++ user_guide_src/source/libraries/sessions/042.php | 4 ++++ user_guide_src/source/libraries/sessions/043.php | 4 ++++ user_guide_src/source/libraries/sessions/044.php | 4 ++++ user_guide_src/source/libraries/throttler/003.php | 4 ++++ user_guide_src/source/libraries/throttler/004.php | 4 ++++ user_guide_src/source/libraries/validation/003.php | 2 ++ user_guide_src/source/libraries/validation/013.php | 2 ++ user_guide_src/source/libraries/validation/015.php | 7 ++++--- user_guide_src/source/libraries/validation/016.php | 4 +++- user_guide_src/source/libraries/validation/031.php | 2 ++ user_guide_src/source/libraries/validation/032.php | 2 ++ user_guide_src/source/models/entities/019.php | 4 +++- user_guide_src/source/models/entities/020.php | 4 ++++ user_guide_src/source/models/entities/021.php | 8 +++++--- user_guide_src/source/models/model/021.php | 8 +++++--- user_guide_src/source/models/model/027.php | 9 ++++++--- user_guide_src/source/models/model/034.php | 4 ++++ user_guide_src/source/models/model/038.php | 4 ++++ user_guide_src/source/models/model/040.php | 4 ++++ user_guide_src/source/models/model/041.php | 4 ++++ user_guide_src/source/models/model/050.php | 4 ++++ user_guide_src/source/models/model/051.php | 4 ++++ user_guide_src/source/models/model/052.php | 4 ++++ user_guide_src/source/models/model/054.php | 4 ++++ user_guide_src/source/outgoing/api_responses/001.php | 3 ++- user_guide_src/source/outgoing/api_responses/003.php | 4 ++++ user_guide_src/source/outgoing/api_responses/004.php | 4 ++++ user_guide_src/source/outgoing/localization/001.php | 4 ++++ user_guide_src/source/outgoing/localization/002.php | 4 ++++ user_guide_src/source/outgoing/localization/003.php | 4 ++++ user_guide_src/source/outgoing/localization/005.php | 2 +- user_guide_src/source/outgoing/response/011.php | 4 ++++ user_guide_src/source/outgoing/view_decorators/002.php | 4 ++++ user_guide_src/source/outgoing/view_layouts/001.php | 2 ++ user_guide_src/source/outgoing/view_parser/012.php | 4 ++++ user_guide_src/source/outgoing/view_parser/013.php | 4 ++++ user_guide_src/source/outgoing/view_parser/014.php | 4 ++++ user_guide_src/source/outgoing/view_parser/015.php | 8 ++++++-- user_guide_src/source/outgoing/view_parser/016.php | 4 ++++ user_guide_src/source/outgoing/view_parser/017.php | 4 ++++ user_guide_src/source/outgoing/views/002.php | 4 +++- user_guide_src/source/outgoing/views/003.php | 4 +++- user_guide_src/source/outgoing/views/009.php | 8 +++++--- user_guide_src/source/outgoing/views/011.php | 4 +++- user_guide_src/source/testing/controllers/012.php | 8 ++++++-- user_guide_src/source/testing/controllers/014.php | 5 +++++ user_guide_src/source/testing/debugging/003.php | 4 ++++ user_guide_src/source/testing/fabricator/001.php | 7 ++++++- user_guide_src/source/testing/fabricator/005.php | 2 ++ user_guide_src/source/testing/fabricator/006.php | 4 +++- user_guide_src/source/testing/fabricator/021.php | 4 +++- user_guide_src/source/testing/overview/004.php | 4 ++++ user_guide_src/source/testing/overview/005.php | 4 ++++ user_guide_src/source/testing/overview/006.php | 4 ++++ user_guide_src/source/testing/overview/007.php | 2 ++ user_guide_src/source/testing/overview/017.php | 2 ++ user_guide_src/source/testing/overview/018.php | 2 ++ user_guide_src/source/testing/overview/019.php | 2 ++ user_guide_src/source/tutorial/create_news_items/001.php | 4 ++++ user_guide_src/source/tutorial/create_news_items/002.php | 2 ++ user_guide_src/source/tutorial/news_section/004.php | 4 ++++ user_guide_src/source/tutorial/news_section/006.php | 4 ++++ user_guide_src/source/tutorial/static_pages/002.php | 2 ++ 115 files changed, 404 insertions(+), 58 deletions(-) diff --git a/user_guide_src/source/cli/cli_library/001.php b/user_guide_src/source/cli/cli_library/001.php index d0b0af7095c1..89e798a5647b 100644 --- a/user_guide_src/source/cli/cli_library/001.php +++ b/user_guide_src/source/cli/cli_library/001.php @@ -2,9 +2,9 @@ namespace App\Controllers; -use CodeIgniter\CLI\CLI; +use CodeIgniter\Controller; -class MyController extends \CodeIgniter\Controller +class MyController extends Controller { // ... } diff --git a/user_guide_src/source/concepts/services/006.php b/user_guide_src/source/concepts/services/006.php index 65d27f7c734a..c352a4365710 100644 --- a/user_guide_src/source/concepts/services/006.php +++ b/user_guide_src/source/concepts/services/006.php @@ -1,6 +1,10 @@ \CodeIgniter\Filters\CSRF::class, ]; - // ... } diff --git a/user_guide_src/source/incoming/filters/004.php b/user_guide_src/source/incoming/filters/004.php index 3615cf8f6072..c6ebb321f7e2 100644 --- a/user_guide_src/source/incoming/filters/004.php +++ b/user_guide_src/source/incoming/filters/004.php @@ -1,5 +1,9 @@ ['csrf'], 'post' => ['csrf'], ]; - // ... } diff --git a/user_guide_src/source/installation/upgrade_security/001.php b/user_guide_src/source/installation/upgrade_security/001.php index 70be69c69684..38536bd67cce 100644 --- a/user_guide_src/source/installation/upgrade_security/001.php +++ b/user_guide_src/source/installation/upgrade_security/001.php @@ -2,18 +2,17 @@ namespace Config; -// ... +use CodeIgniter\Config\BaseConfig; class Filters extends BaseConfig { // ... - + public $globals = [ 'before' => [ // 'honeypot', 'csrf', ], ]; - // ... } diff --git a/user_guide_src/source/libraries/caching/013.php b/user_guide_src/source/libraries/caching/013.php index 74bda7604f34..3dd8ff740944 100644 --- a/user_guide_src/source/libraries/caching/013.php +++ b/user_guide_src/source/libraries/caching/013.php @@ -2,7 +2,7 @@ namespace Config; -// ... +use CodeIgniter\Config\BaseConfig; class Cache extends BaseConfig { @@ -13,6 +13,5 @@ class Cache extends BaseConfig 'weight' => 1, 'raw' => false, ]; - // ... } diff --git a/user_guide_src/source/libraries/caching/014.php b/user_guide_src/source/libraries/caching/014.php index 2c0f5eb719bd..716bf637161b 100644 --- a/user_guide_src/source/libraries/caching/014.php +++ b/user_guide_src/source/libraries/caching/014.php @@ -1,5 +1,9 @@ '; - // ... } diff --git a/user_guide_src/source/libraries/files/014.php b/user_guide_src/source/libraries/files/014.php index a768829427f3..cbd6f90e5388 100644 --- a/user_guide_src/source/libraries/files/014.php +++ b/user_guide_src/source/libraries/files/014.php @@ -1,6 +1,8 @@ 'required|matches[password]', 'email' => 'required|valid_email', ]; - public $signup_errors = [ 'username' => [ - 'required' => 'You must choose a username.', + 'required' => 'You must choose a username.', ], - 'email' => [ + 'email' => [ 'valid_email' => 'Please check the Email field. It does not appear to be valid.', ], ]; diff --git a/user_guide_src/source/libraries/validation/016.php b/user_guide_src/source/libraries/validation/016.php index 55d9f6985cf9..3b777bb92ddd 100644 --- a/user_guide_src/source/libraries/validation/016.php +++ b/user_guide_src/source/libraries/validation/016.php @@ -1,5 +1,7 @@ 'You must choose a Username.', ], ], - 'email' => [ + 'email' => [ 'rules' => 'required|valid_email', 'errors' => [ 'valid_email' => 'Please check the Email field. It does not appear to be valid.', diff --git a/user_guide_src/source/libraries/validation/031.php b/user_guide_src/source/libraries/validation/031.php index d8917ff8ec87..e85808bdab63 100644 --- a/user_guide_src/source/libraries/validation/031.php +++ b/user_guide_src/source/libraries/validation/031.php @@ -1,5 +1,7 @@ - // string(13) "App\SomeClass" + // string(13) "App\SomeClass" // [1]=> - // string(6) "param2" + // string(6) "param2" // [2]=> - // string(6) "param3" + // string(6) "param3" // } } } diff --git a/user_guide_src/source/models/model/021.php b/user_guide_src/source/models/model/021.php index a49cfe210163..f0367b5044e2 100644 --- a/user_guide_src/source/models/model/021.php +++ b/user_guide_src/source/models/model/021.php @@ -1,12 +1,14 @@ 'required|alpha_numeric_space|min_length[3]', 'email' => 'required|valid_email|is_unique[users.email]', 'password' => 'required|min_length[8]', 'pass_confirm' => 'required_with[password]|matches[password]', ]; - protected $validationMessages = [ - 'email' => [ + 'email' => [ 'is_unique' => 'Sorry. That email has already been taken. Please choose another.', ], ]; diff --git a/user_guide_src/source/models/model/034.php b/user_guide_src/source/models/model/034.php index 8de746bec4cd..b18544ee555e 100644 --- a/user_guide_src/source/models/model/034.php +++ b/user_guide_src/source/models/model/034.php @@ -1,5 +1,9 @@ plugins['bar'] = function (array $params=[]) { + $this->plugins['bar'] = static function (array $params = []) { return $params[0] ?? ''; }; diff --git a/user_guide_src/source/outgoing/view_parser/016.php b/user_guide_src/source/outgoing/view_parser/016.php index 5e2f5a2f0b0b..a78667ef2762 100644 --- a/user_guide_src/source/outgoing/view_parser/016.php +++ b/user_guide_src/source/outgoing/view_parser/016.php @@ -1,5 +1,9 @@ assertHasFilters('unfiltered/route', 'before'); } - // ... } diff --git a/user_guide_src/source/testing/controllers/014.php b/user_guide_src/source/testing/controllers/014.php index bc6dc8bf9e18..feb1d4448540 100644 --- a/user_guide_src/source/testing/controllers/014.php +++ b/user_guide_src/source/testing/controllers/014.php @@ -1,5 +1,10 @@ $faker->firstName, 'email' => $faker->email, - 'group_id' => rand(1, Fabricator::getCount('groups')), + 'group_id' => mt_rand(1, Fabricator::getCount('groups')), ]; } } diff --git a/user_guide_src/source/testing/overview/004.php b/user_guide_src/source/testing/overview/004.php index 2f8a20c6ca52..4d2e7ef4b5a8 100644 --- a/user_guide_src/source/testing/overview/004.php +++ b/user_guide_src/source/testing/overview/004.php @@ -1,5 +1,9 @@ Date: Tue, 1 Mar 2022 11:16:31 +0100 Subject: [PATCH 0636/1246] Add '...' for config examples. --- user_guide_src/source/concepts/factories/005.php | 1 + user_guide_src/source/concepts/services/007.php | 1 + user_guide_src/source/concepts/services/008.php | 1 + user_guide_src/source/concepts/services/010.php | 1 + user_guide_src/source/database/configuration/006.php | 1 + user_guide_src/source/database/configuration/008.php | 1 + user_guide_src/source/extending/core_classes/002.php | 1 + user_guide_src/source/general/configuration/004.php | 2 +- user_guide_src/source/general/configuration/008.php | 3 +-- user_guide_src/source/general/logging/002.php | 1 + user_guide_src/source/general/logging/003.php | 1 + user_guide_src/source/general/logging/004.php | 1 + user_guide_src/source/general/managing_apps/001.php | 1 + user_guide_src/source/incoming/filters/004.php | 1 + user_guide_src/source/incoming/filters/005.php | 1 + user_guide_src/source/incoming/filters/006.php | 1 + user_guide_src/source/incoming/filters/007.php | 1 + user_guide_src/source/incoming/filters/008.php | 1 + user_guide_src/source/incoming/filters/009.php | 1 + user_guide_src/source/incoming/filters/011.php | 1 + .../source/installation/upgrade_configuration/002.php | 5 +++-- user_guide_src/source/libraries/caching/014.php | 3 +++ user_guide_src/source/libraries/curlrequest/001.php | 1 + user_guide_src/source/libraries/honeypot/001.php | 1 + user_guide_src/source/libraries/pagination/010.php | 1 + user_guide_src/source/libraries/pagination/011.php | 1 + user_guide_src/source/libraries/security/002.php | 1 + user_guide_src/source/libraries/security/003.php | 1 + user_guide_src/source/libraries/security/004.php | 1 + user_guide_src/source/libraries/security/005.php | 1 + user_guide_src/source/libraries/security/006.php | 1 + user_guide_src/source/libraries/security/007.php | 1 + user_guide_src/source/libraries/security/008.php | 1 + user_guide_src/source/libraries/security/009.php | 1 + user_guide_src/source/libraries/sessions/040.php | 1 + user_guide_src/source/libraries/sessions/041.php | 1 + user_guide_src/source/libraries/sessions/042.php | 1 + user_guide_src/source/libraries/sessions/043.php | 1 + user_guide_src/source/libraries/sessions/044.php | 1 + user_guide_src/source/libraries/throttler/003.php | 1 + user_guide_src/source/libraries/throttler/004.php | 1 + user_guide_src/source/libraries/validation/003.php | 1 + user_guide_src/source/libraries/validation/013.php | 1 + user_guide_src/source/libraries/validation/015.php | 1 + user_guide_src/source/libraries/validation/016.php | 1 + user_guide_src/source/libraries/validation/031.php | 1 + user_guide_src/source/libraries/validation/032.php | 1 + user_guide_src/source/outgoing/api_responses/003.php | 1 + user_guide_src/source/outgoing/api_responses/004.php | 1 + user_guide_src/source/outgoing/localization/001.php | 1 + user_guide_src/source/outgoing/localization/002.php | 1 + user_guide_src/source/outgoing/localization/003.php | 1 + user_guide_src/source/outgoing/response/011.php | 1 + user_guide_src/source/outgoing/view_decorators/002.php | 1 + user_guide_src/source/outgoing/view_parser/012.php | 1 + user_guide_src/source/outgoing/view_parser/013.php | 1 + user_guide_src/source/outgoing/view_parser/014.php | 1 + user_guide_src/source/outgoing/view_parser/015.php | 1 + user_guide_src/source/outgoing/view_parser/016.php | 1 + user_guide_src/source/outgoing/view_parser/017.php | 1 + user_guide_src/source/testing/debugging/003.php | 1 + user_guide_src/source/tutorial/create_news_items/001.php | 1 + 62 files changed, 66 insertions(+), 5 deletions(-) diff --git a/user_guide_src/source/concepts/factories/005.php b/user_guide_src/source/concepts/factories/005.php index 10a82b828d73..0c860b7a1672 100644 --- a/user_guide_src/source/concepts/factories/005.php +++ b/user_guide_src/source/concepts/factories/005.php @@ -10,4 +10,5 @@ class Factories extends BaseFactory public $filters = [ 'instanceOf' => FilterInterface::class, ]; + // ... } diff --git a/user_guide_src/source/concepts/services/007.php b/user_guide_src/source/concepts/services/007.php index ed1990b3dca2..298b8abd010f 100644 --- a/user_guide_src/source/concepts/services/007.php +++ b/user_guide_src/source/concepts/services/007.php @@ -10,4 +10,5 @@ public static function routes() { return new \App\Router\MyRouter(); } + // ... } diff --git a/user_guide_src/source/concepts/services/008.php b/user_guide_src/source/concepts/services/008.php index 1f1db41226b0..52edb387792c 100644 --- a/user_guide_src/source/concepts/services/008.php +++ b/user_guide_src/source/concepts/services/008.php @@ -10,4 +10,5 @@ public static function renderer($viewPath = APPPATH . 'views/') { return new \CodeIgniter\View\View($viewPath); } + // ... } diff --git a/user_guide_src/source/concepts/services/010.php b/user_guide_src/source/concepts/services/010.php index f4332f6404e3..fd5d3f6c4e35 100644 --- a/user_guide_src/source/concepts/services/010.php +++ b/user_guide_src/source/concepts/services/010.php @@ -14,4 +14,5 @@ public static function routes($getShared = false) return static::getSharedInstance('routes'); } + // ... } diff --git a/user_guide_src/source/database/configuration/006.php b/user_guide_src/source/database/configuration/006.php index 31cd766c4f8e..afc24022c199 100644 --- a/user_guide_src/source/database/configuration/006.php +++ b/user_guide_src/source/database/configuration/006.php @@ -24,4 +24,5 @@ class Database extends Config 'strictOn' => false, 'failover' => [], ]; + // ... } diff --git a/user_guide_src/source/database/configuration/008.php b/user_guide_src/source/database/configuration/008.php index 5639c484d125..c6084e212234 100644 --- a/user_guide_src/source/database/configuration/008.php +++ b/user_guide_src/source/database/configuration/008.php @@ -14,4 +14,5 @@ public function __construct() { $this->defaultGroup = ENVIRONMENT; } + // ... } diff --git a/user_guide_src/source/extending/core_classes/002.php b/user_guide_src/source/extending/core_classes/002.php index df96db2fa7bf..1d0de27ee238 100644 --- a/user_guide_src/source/extending/core_classes/002.php +++ b/user_guide_src/source/extending/core_classes/002.php @@ -14,4 +14,5 @@ public static function routes(bool $getShared = true) return new \App\Libraries\RouteCollection(static::locator(), config('Modules')); } + // ... } diff --git a/user_guide_src/source/general/configuration/004.php b/user_guide_src/source/general/configuration/004.php index 5d39a34c48b5..cc013d77583f 100644 --- a/user_guide_src/source/general/configuration/004.php +++ b/user_guide_src/source/general/configuration/004.php @@ -8,5 +8,5 @@ class CustomClass extends BaseConfig { public $siteName = 'My Great Site'; public $siteEmail = 'webmaster@example.com'; - + // ... } diff --git a/user_guide_src/source/general/configuration/008.php b/user_guide_src/source/general/configuration/008.php index 197c200970ab..86749331c9c5 100644 --- a/user_guide_src/source/general/configuration/008.php +++ b/user_guide_src/source/general/configuration/008.php @@ -2,11 +2,10 @@ namespace Config; -use CodeIgniter\Config\BaseService; - class MyConfig extends BaseConfig { public static $registrars = [ SupportingPackageRegistrar::class, ]; + // ... } diff --git a/user_guide_src/source/general/logging/002.php b/user_guide_src/source/general/logging/002.php index 8d1409b481fe..1c27f2410126 100644 --- a/user_guide_src/source/general/logging/002.php +++ b/user_guide_src/source/general/logging/002.php @@ -7,4 +7,5 @@ class Logger extends BaseConfig { public $threshold = 5; + // ... } diff --git a/user_guide_src/source/general/logging/003.php b/user_guide_src/source/general/logging/003.php index e34a67075a09..170b74457967 100644 --- a/user_guide_src/source/general/logging/003.php +++ b/user_guide_src/source/general/logging/003.php @@ -8,4 +8,5 @@ class Logger extends BaseConfig { // Log only debug and info type messages public $threshold = [5, 8]; + // ... } diff --git a/user_guide_src/source/general/logging/004.php b/user_guide_src/source/general/logging/004.php index 32746068e2b6..ff5f9511d81f 100644 --- a/user_guide_src/source/general/logging/004.php +++ b/user_guide_src/source/general/logging/004.php @@ -12,4 +12,5 @@ class Logger extends BaseConfig 'handles' => ['critical', 'alert', 'emergency', 'debug', 'error', 'info', 'notice', 'warning'], ], ]; + // ... } diff --git a/user_guide_src/source/general/managing_apps/001.php b/user_guide_src/source/general/managing_apps/001.php index 253d888d316c..2d0690cabc41 100644 --- a/user_guide_src/source/general/managing_apps/001.php +++ b/user_guide_src/source/general/managing_apps/001.php @@ -5,4 +5,5 @@ class Paths { public $appDirectory = '/path/to/your/app'; + // ... } diff --git a/user_guide_src/source/incoming/filters/004.php b/user_guide_src/source/incoming/filters/004.php index c6ebb321f7e2..d39de5a0bee8 100644 --- a/user_guide_src/source/incoming/filters/004.php +++ b/user_guide_src/source/incoming/filters/004.php @@ -12,4 +12,5 @@ class Filters extends BaseConfig \App\Filters\ApiAuth::class, ], ]; + // ... } diff --git a/user_guide_src/source/incoming/filters/005.php b/user_guide_src/source/incoming/filters/005.php index 7dca9d31631d..55b7d1fa522b 100644 --- a/user_guide_src/source/incoming/filters/005.php +++ b/user_guide_src/source/incoming/filters/005.php @@ -12,4 +12,5 @@ class Filters extends BaseConfig ], 'after' => [], ]; + // ... } diff --git a/user_guide_src/source/incoming/filters/006.php b/user_guide_src/source/incoming/filters/006.php index 3781a875cff8..ed7ce0a8a120 100644 --- a/user_guide_src/source/incoming/filters/006.php +++ b/user_guide_src/source/incoming/filters/006.php @@ -12,4 +12,5 @@ class Filters extends BaseConfig ], 'after' => [], ]; + // ... } diff --git a/user_guide_src/source/incoming/filters/007.php b/user_guide_src/source/incoming/filters/007.php index 03844d9f763d..fa79b5bbb7c8 100644 --- a/user_guide_src/source/incoming/filters/007.php +++ b/user_guide_src/source/incoming/filters/007.php @@ -12,4 +12,5 @@ class Filters extends BaseConfig ], 'after' => [], ]; + // ... } diff --git a/user_guide_src/source/incoming/filters/008.php b/user_guide_src/source/incoming/filters/008.php index f35895d26e2e..a37967a538c0 100644 --- a/user_guide_src/source/incoming/filters/008.php +++ b/user_guide_src/source/incoming/filters/008.php @@ -10,4 +10,5 @@ class Filters extends BaseConfig 'post' => ['foo', 'bar'], 'get' => ['baz'], ]; + // ... } diff --git a/user_guide_src/source/incoming/filters/009.php b/user_guide_src/source/incoming/filters/009.php index 1fd9ab69ec4c..bfc7d6176b77 100644 --- a/user_guide_src/source/incoming/filters/009.php +++ b/user_guide_src/source/incoming/filters/009.php @@ -10,4 +10,5 @@ class Filters extends BaseConfig 'foo' => ['before' => ['admin/*'], 'after' => ['users/*']], 'bar' => ['before' => ['api/*', 'admin/*']], ]; + // ... } diff --git a/user_guide_src/source/incoming/filters/011.php b/user_guide_src/source/incoming/filters/011.php index ccc7c2cbd1f5..8b6e24c5fe91 100644 --- a/user_guide_src/source/incoming/filters/011.php +++ b/user_guide_src/source/incoming/filters/011.php @@ -10,4 +10,5 @@ class Filters extends BaseConfig // ... 'secureheaders' => \App\Filters\SecureHeaders::class, ]; + // ... } diff --git a/user_guide_src/source/installation/upgrade_configuration/002.php b/user_guide_src/source/installation/upgrade_configuration/002.php index 5150d6b8896d..cc013d77583f 100644 --- a/user_guide_src/source/installation/upgrade_configuration/002.php +++ b/user_guide_src/source/installation/upgrade_configuration/002.php @@ -6,6 +6,7 @@ class CustomClass extends BaseConfig { - public $siteName = 'My Great Site'; - public $siteEmail = 'webmaster@example.com'; + public $siteName = 'My Great Site'; + public $siteEmail = 'webmaster@example.com'; + // ... } diff --git a/user_guide_src/source/libraries/caching/014.php b/user_guide_src/source/libraries/caching/014.php index 716bf637161b..cfb6eeb6698f 100644 --- a/user_guide_src/source/libraries/caching/014.php +++ b/user_guide_src/source/libraries/caching/014.php @@ -6,6 +6,8 @@ class Cache extends BaseConfig { + // ... + public $redis = [ 'host' => '127.0.0.1', 'password' => null, @@ -13,4 +15,5 @@ class Cache extends BaseConfig 'timeout' => 0, 'database' => 0, ]; + // ... } diff --git a/user_guide_src/source/libraries/curlrequest/001.php b/user_guide_src/source/libraries/curlrequest/001.php index 35fd4621a92a..35486f4e7971 100644 --- a/user_guide_src/source/libraries/curlrequest/001.php +++ b/user_guide_src/source/libraries/curlrequest/001.php @@ -7,4 +7,5 @@ class CURLRequest extends BaseConfig { public $shareOptions = false; + // ... } diff --git a/user_guide_src/source/libraries/honeypot/001.php b/user_guide_src/source/libraries/honeypot/001.php index 5fd6cefc3036..8463a919d54a 100644 --- a/user_guide_src/source/libraries/honeypot/001.php +++ b/user_guide_src/source/libraries/honeypot/001.php @@ -16,4 +16,5 @@ class Filters extends BaseConfig 'honeypot', ], ]; + // ... } diff --git a/user_guide_src/source/libraries/pagination/010.php b/user_guide_src/source/libraries/pagination/010.php index 868bc5e8620f..d168163446ee 100644 --- a/user_guide_src/source/libraries/pagination/010.php +++ b/user_guide_src/source/libraries/pagination/010.php @@ -10,4 +10,5 @@ class Pager extends BaseConfig 'default_full' => 'CodeIgniter\Pager\Views\default_full', 'default_simple' => 'CodeIgniter\Pager\Views\default_simple', ]; + // ... } diff --git a/user_guide_src/source/libraries/pagination/011.php b/user_guide_src/source/libraries/pagination/011.php index 4d596e593312..4302997f8bff 100644 --- a/user_guide_src/source/libraries/pagination/011.php +++ b/user_guide_src/source/libraries/pagination/011.php @@ -11,4 +11,5 @@ class Pager extends BaseConfig 'default_simple' => 'CodeIgniter\Pager\Views\default_simple', 'front_full' => 'App\Views\Pagers\foundation_full', ]; + // ... } diff --git a/user_guide_src/source/libraries/security/002.php b/user_guide_src/source/libraries/security/002.php index 64de01125e4f..39df6fa8d292 100644 --- a/user_guide_src/source/libraries/security/002.php +++ b/user_guide_src/source/libraries/security/002.php @@ -7,4 +7,5 @@ class Security extends BaseConfig { public $csrfProtection = 'session'; + // ... } diff --git a/user_guide_src/source/libraries/security/003.php b/user_guide_src/source/libraries/security/003.php index c877680a923b..7d8b3241c285 100644 --- a/user_guide_src/source/libraries/security/003.php +++ b/user_guide_src/source/libraries/security/003.php @@ -7,4 +7,5 @@ class Security extends BaseConfig { public $tokenRandomize = true; + // ... } diff --git a/user_guide_src/source/libraries/security/004.php b/user_guide_src/source/libraries/security/004.php index d12b4e2243f7..7187a1b523c5 100644 --- a/user_guide_src/source/libraries/security/004.php +++ b/user_guide_src/source/libraries/security/004.php @@ -7,4 +7,5 @@ class Security extends BaseConfig { public $regenerate = true; + // ... } diff --git a/user_guide_src/source/libraries/security/005.php b/user_guide_src/source/libraries/security/005.php index 51040f3be460..f7539874c023 100644 --- a/user_guide_src/source/libraries/security/005.php +++ b/user_guide_src/source/libraries/security/005.php @@ -7,4 +7,5 @@ class Security extends BaseConfig { public $redirect = false; + // ... } diff --git a/user_guide_src/source/libraries/security/006.php b/user_guide_src/source/libraries/security/006.php index c2a392bbcc63..cc3ef9d162c6 100644 --- a/user_guide_src/source/libraries/security/006.php +++ b/user_guide_src/source/libraries/security/006.php @@ -12,4 +12,5 @@ class Filters extends BaseConfig 'csrf', ], ]; + // ... } diff --git a/user_guide_src/source/libraries/security/007.php b/user_guide_src/source/libraries/security/007.php index c32e7bc2b517..0b099addb52c 100644 --- a/user_guide_src/source/libraries/security/007.php +++ b/user_guide_src/source/libraries/security/007.php @@ -11,4 +11,5 @@ class Filters extends BaseConfig 'csrf' => ['except' => ['api/record/save']], ], ]; + // ... } diff --git a/user_guide_src/source/libraries/security/008.php b/user_guide_src/source/libraries/security/008.php index faa45c0bd605..370bd2bcedad 100644 --- a/user_guide_src/source/libraries/security/008.php +++ b/user_guide_src/source/libraries/security/008.php @@ -11,4 +11,5 @@ class Filters extends BaseConfig 'csrf' => ['except' => ['api/record/[0-9]+']], ], ]; + // ... } diff --git a/user_guide_src/source/libraries/security/009.php b/user_guide_src/source/libraries/security/009.php index 397681518d26..d90632e53f1c 100644 --- a/user_guide_src/source/libraries/security/009.php +++ b/user_guide_src/source/libraries/security/009.php @@ -10,4 +10,5 @@ class Filters extends BaseConfig 'get' => ['csrf'], 'post' => ['csrf'], ]; + // ... } diff --git a/user_guide_src/source/libraries/sessions/040.php b/user_guide_src/source/libraries/sessions/040.php index 29d50c78302c..3aedc2f047af 100644 --- a/user_guide_src/source/libraries/sessions/040.php +++ b/user_guide_src/source/libraries/sessions/040.php @@ -8,4 +8,5 @@ class App extends BaseConfig { public $sessionDriver = 'CodeIgniter\Session\Handlers\DatabaseHandler'; public $sessionSavePath = 'ci_sessions'; + // ... } diff --git a/user_guide_src/source/libraries/sessions/041.php b/user_guide_src/source/libraries/sessions/041.php index fe2777cae60c..f645887ec2be 100644 --- a/user_guide_src/source/libraries/sessions/041.php +++ b/user_guide_src/source/libraries/sessions/041.php @@ -7,4 +7,5 @@ class App extends BaseConfig { public $sessionDBGroup = 'groupName'; + // ... } diff --git a/user_guide_src/source/libraries/sessions/042.php b/user_guide_src/source/libraries/sessions/042.php index 830569b5dcbb..f0aed919a816 100644 --- a/user_guide_src/source/libraries/sessions/042.php +++ b/user_guide_src/source/libraries/sessions/042.php @@ -8,4 +8,5 @@ class App extends BaseConfig { public $sessionDiver = 'CodeIgniter\Session\Handlers\RedisHandler'; public $sessionSavePath = 'tcp://localhost:6379'; + // ... } diff --git a/user_guide_src/source/libraries/sessions/043.php b/user_guide_src/source/libraries/sessions/043.php index 4a50d0e20c51..cad56413151c 100644 --- a/user_guide_src/source/libraries/sessions/043.php +++ b/user_guide_src/source/libraries/sessions/043.php @@ -8,4 +8,5 @@ class App extends BaseConfig { public $sessionDriver = 'CodeIgniter\Session\Handlers\MemcachedHandler'; public $sessionSavePath = 'localhost:11211'; + // ... } diff --git a/user_guide_src/source/libraries/sessions/044.php b/user_guide_src/source/libraries/sessions/044.php index 3e889f270f3d..2cc31e9035db 100644 --- a/user_guide_src/source/libraries/sessions/044.php +++ b/user_guide_src/source/libraries/sessions/044.php @@ -9,4 +9,5 @@ class App extends BaseConfig // localhost will be given higher priority (5) here, // compared to 192.0.2.1 with a weight of 1. public $sessionSavePath = 'localhost:11211:5,192.0.2.1:11211:1'; + // ... } diff --git a/user_guide_src/source/libraries/throttler/003.php b/user_guide_src/source/libraries/throttler/003.php index 56b0fe4e1c59..ae13441bb8ad 100644 --- a/user_guide_src/source/libraries/throttler/003.php +++ b/user_guide_src/source/libraries/throttler/003.php @@ -10,4 +10,5 @@ class Filters extends BaseConfig // ... 'throttle' => \App\Filters\Throttle::class, ]; + // ... } diff --git a/user_guide_src/source/libraries/throttler/004.php b/user_guide_src/source/libraries/throttler/004.php index e8ec69b0b046..077cb46a66dc 100644 --- a/user_guide_src/source/libraries/throttler/004.php +++ b/user_guide_src/source/libraries/throttler/004.php @@ -9,4 +9,5 @@ class Filters extends BaseConfig public $methods = [ 'post' => ['throttle'], ]; + // ... } diff --git a/user_guide_src/source/libraries/validation/003.php b/user_guide_src/source/libraries/validation/003.php index 79e2c7820e1d..fbcbb7690260 100644 --- a/user_guide_src/source/libraries/validation/003.php +++ b/user_guide_src/source/libraries/validation/003.php @@ -10,4 +10,5 @@ class Validation \CodeIgniter\Validation\StrictRules\FormatRules::class, \CodeIgniter\Validation\StrictRules\Rules::class, ]; + // ... } diff --git a/user_guide_src/source/libraries/validation/013.php b/user_guide_src/source/libraries/validation/013.php index 827e86e51957..4e2982d7564f 100644 --- a/user_guide_src/source/libraries/validation/013.php +++ b/user_guide_src/source/libraries/validation/013.php @@ -10,4 +10,5 @@ class Validation 'pass_confirm' => 'required|matches[password]', 'email' => 'required|valid_email', ]; + // ... } diff --git a/user_guide_src/source/libraries/validation/015.php b/user_guide_src/source/libraries/validation/015.php index e223cdaaa504..46ef2c4431a1 100644 --- a/user_guide_src/source/libraries/validation/015.php +++ b/user_guide_src/source/libraries/validation/015.php @@ -18,4 +18,5 @@ class Validation 'valid_email' => 'Please check the Email field. It does not appear to be valid.', ], ]; + // ... } diff --git a/user_guide_src/source/libraries/validation/016.php b/user_guide_src/source/libraries/validation/016.php index 3b777bb92ddd..5b08e73980a8 100644 --- a/user_guide_src/source/libraries/validation/016.php +++ b/user_guide_src/source/libraries/validation/016.php @@ -18,4 +18,5 @@ class Validation ], ], ]; + // ... } diff --git a/user_guide_src/source/libraries/validation/031.php b/user_guide_src/source/libraries/validation/031.php index e85808bdab63..7ed5d307b0e2 100644 --- a/user_guide_src/source/libraries/validation/031.php +++ b/user_guide_src/source/libraries/validation/031.php @@ -9,4 +9,5 @@ class Validation 'single' => 'CodeIgniter\Validation\Views\single', 'my_list' => '_errors_list', ]; + // ... } diff --git a/user_guide_src/source/libraries/validation/032.php b/user_guide_src/source/libraries/validation/032.php index 86534cd84ed4..5f16ca283c1e 100644 --- a/user_guide_src/source/libraries/validation/032.php +++ b/user_guide_src/source/libraries/validation/032.php @@ -15,4 +15,5 @@ class Validation FileRules::class, CreditCardRules::class, ]; + // ... } diff --git a/user_guide_src/source/outgoing/api_responses/003.php b/user_guide_src/source/outgoing/api_responses/003.php index 1b5a498b5940..eebb83c43fc1 100644 --- a/user_guide_src/source/outgoing/api_responses/003.php +++ b/user_guide_src/source/outgoing/api_responses/003.php @@ -10,4 +10,5 @@ class Format extends BaseConfig 'application/json', 'application/xml', ]; + // ... } diff --git a/user_guide_src/source/outgoing/api_responses/004.php b/user_guide_src/source/outgoing/api_responses/004.php index b092ec70372e..57532911f13b 100644 --- a/user_guide_src/source/outgoing/api_responses/004.php +++ b/user_guide_src/source/outgoing/api_responses/004.php @@ -10,4 +10,5 @@ class Format extends BaseConfig 'application/json' => \CodeIgniter\Format\JSONFormatter::class, 'application/xml' => \CodeIgniter\Format\XMLFormatter::class, ]; + // ... } diff --git a/user_guide_src/source/outgoing/localization/001.php b/user_guide_src/source/outgoing/localization/001.php index 7af57b09d921..ebc1e57ef45c 100644 --- a/user_guide_src/source/outgoing/localization/001.php +++ b/user_guide_src/source/outgoing/localization/001.php @@ -7,4 +7,5 @@ class App extends BaseConfig { public $defaultLocale = 'en'; + // ... } diff --git a/user_guide_src/source/outgoing/localization/002.php b/user_guide_src/source/outgoing/localization/002.php index ae6aa825e7a8..6a0cce0ea027 100644 --- a/user_guide_src/source/outgoing/localization/002.php +++ b/user_guide_src/source/outgoing/localization/002.php @@ -7,4 +7,5 @@ class App extends BaseConfig { public $negotiateLocale = true; + // ... } diff --git a/user_guide_src/source/outgoing/localization/003.php b/user_guide_src/source/outgoing/localization/003.php index dd3cad7ee548..81aa073152a0 100644 --- a/user_guide_src/source/outgoing/localization/003.php +++ b/user_guide_src/source/outgoing/localization/003.php @@ -7,4 +7,5 @@ class App extends BaseConfig { public $supportedLocales = ['en', 'es', 'fr-FR']; + // ... } diff --git a/user_guide_src/source/outgoing/response/011.php b/user_guide_src/source/outgoing/response/011.php index 5f546ff5781a..2ad152a51755 100644 --- a/user_guide_src/source/outgoing/response/011.php +++ b/user_guide_src/source/outgoing/response/011.php @@ -7,4 +7,5 @@ class App extends BaseConfig { public $CSPEnabled = true; + // ... } diff --git a/user_guide_src/source/outgoing/view_decorators/002.php b/user_guide_src/source/outgoing/view_decorators/002.php index a7d0f3937fa9..6bd050126f90 100644 --- a/user_guide_src/source/outgoing/view_decorators/002.php +++ b/user_guide_src/source/outgoing/view_decorators/002.php @@ -9,4 +9,5 @@ class View extends BaseView public array $decorators = [ 'App\Views\Decorators\MyDecorator', ]; + // ... } diff --git a/user_guide_src/source/outgoing/view_parser/012.php b/user_guide_src/source/outgoing/view_parser/012.php index 40a6a62e3964..a006a51d5c33 100644 --- a/user_guide_src/source/outgoing/view_parser/012.php +++ b/user_guide_src/source/outgoing/view_parser/012.php @@ -10,4 +10,5 @@ class View extends BaseView 'abs' => '\CodeIgniter\View\Filters::abs', 'capitalize' => '\CodeIgniter\View\Filters::capitalize', ]; + // ... } diff --git a/user_guide_src/source/outgoing/view_parser/013.php b/user_guide_src/source/outgoing/view_parser/013.php index 20a7f800af10..c45a72b89bde 100644 --- a/user_guide_src/source/outgoing/view_parser/013.php +++ b/user_guide_src/source/outgoing/view_parser/013.php @@ -9,4 +9,5 @@ class View extends BaseView public $filters = [ 'str_repeat' => '\str_repeat', ]; + // ... } diff --git a/user_guide_src/source/outgoing/view_parser/014.php b/user_guide_src/source/outgoing/view_parser/014.php index 87e70e1a43b5..866a547e3b28 100644 --- a/user_guide_src/source/outgoing/view_parser/014.php +++ b/user_guide_src/source/outgoing/view_parser/014.php @@ -9,4 +9,5 @@ class View extends BaseView public $plugins = [ 'foo' => '\Some\Class::methodName', ]; + // ... } diff --git a/user_guide_src/source/outgoing/view_parser/015.php b/user_guide_src/source/outgoing/view_parser/015.php index 008d6f748622..ecfafffbf97a 100644 --- a/user_guide_src/source/outgoing/view_parser/015.php +++ b/user_guide_src/source/outgoing/view_parser/015.php @@ -16,4 +16,5 @@ public function __construct() parent::__construct(); } + // ... } diff --git a/user_guide_src/source/outgoing/view_parser/016.php b/user_guide_src/source/outgoing/view_parser/016.php index a78667ef2762..0350043cf4fa 100644 --- a/user_guide_src/source/outgoing/view_parser/016.php +++ b/user_guide_src/source/outgoing/view_parser/016.php @@ -9,6 +9,7 @@ class View extends BaseView public $plugins = [ 'foo' => '\Some\Class::methodName', ]; + // ... } // Tag is replaced by the return value of Some\Class::methodName static function. diff --git a/user_guide_src/source/outgoing/view_parser/017.php b/user_guide_src/source/outgoing/view_parser/017.php index 6c98122dd7af..1042665a0fcf 100644 --- a/user_guide_src/source/outgoing/view_parser/017.php +++ b/user_guide_src/source/outgoing/view_parser/017.php @@ -9,6 +9,7 @@ class View extends BaseView public $plugins = [ 'foo' => ['\Some\Class::methodName'], ]; + // ... } // {+ foo +} inner content {+ /foo +} diff --git a/user_guide_src/source/testing/debugging/003.php b/user_guide_src/source/testing/debugging/003.php index ec42da23856a..4c1804e2d82b 100644 --- a/user_guide_src/source/testing/debugging/003.php +++ b/user_guide_src/source/testing/debugging/003.php @@ -16,4 +16,5 @@ class Toolbar extends BaseConfig \CodeIgniter\Debug\Toolbar\Collectors\Routes::class, \CodeIgniter\Debug\Toolbar\Collectors\Events::class, ]; + // ... } diff --git a/user_guide_src/source/tutorial/create_news_items/001.php b/user_guide_src/source/tutorial/create_news_items/001.php index 5982d0b159ab..c63e033af0bf 100644 --- a/user_guide_src/source/tutorial/create_news_items/001.php +++ b/user_guide_src/source/tutorial/create_news_items/001.php @@ -9,4 +9,5 @@ class Filters extends BaseConfig public $methods = [ 'post' => ['csrf'], ]; + // ... } From 589bd7ca252fd757d8617a579bc05b7e4664da5b Mon Sep 17 00:00:00 2001 From: Alex Schmitz <40514119+sfadschm@users.noreply.github.com> Date: Wed, 2 Mar 2022 08:31:36 +0100 Subject: [PATCH 0637/1246] Fix cli_library. Co-authored-by: kenjis --- user_guide_src/source/cli/cli_library/001.php | 1 + 1 file changed, 1 insertion(+) diff --git a/user_guide_src/source/cli/cli_library/001.php b/user_guide_src/source/cli/cli_library/001.php index 89e798a5647b..e42c9a9231e6 100644 --- a/user_guide_src/source/cli/cli_library/001.php +++ b/user_guide_src/source/cli/cli_library/001.php @@ -2,6 +2,7 @@ namespace App\Controllers; +use CodeIgniter\CLI\CLI; use CodeIgniter\Controller; class MyController extends Controller From 8c83892af24a6821ad4d6500c8282cd0508d0877 Mon Sep 17 00:00:00 2001 From: Alex Schmitz <40514119+sfadschm@users.noreply.github.com> Date: Wed, 2 Mar 2022 10:09:59 +0100 Subject: [PATCH 0638/1246] Apply suggestions from code review. Co-authored-by: kenjis --- user_guide_src/source/concepts/factories/005.php | 1 - user_guide_src/source/database/configuration/008.php | 1 - user_guide_src/source/extending/basecontroller/003.php | 2 ++ .../source/installation/upgrade_configuration/002.php | 1 - user_guide_src/source/testing/overview/018.php | 2 +- 5 files changed, 3 insertions(+), 4 deletions(-) diff --git a/user_guide_src/source/concepts/factories/005.php b/user_guide_src/source/concepts/factories/005.php index 0c860b7a1672..10a82b828d73 100644 --- a/user_guide_src/source/concepts/factories/005.php +++ b/user_guide_src/source/concepts/factories/005.php @@ -10,5 +10,4 @@ class Factories extends BaseFactory public $filters = [ 'instanceOf' => FilterInterface::class, ]; - // ... } diff --git a/user_guide_src/source/database/configuration/008.php b/user_guide_src/source/database/configuration/008.php index c6084e212234..5639c484d125 100644 --- a/user_guide_src/source/database/configuration/008.php +++ b/user_guide_src/source/database/configuration/008.php @@ -14,5 +14,4 @@ public function __construct() { $this->defaultGroup = ENVIRONMENT; } - // ... } diff --git a/user_guide_src/source/extending/basecontroller/003.php b/user_guide_src/source/extending/basecontroller/003.php index 4948b49bf0ac..22afdf184f75 100644 --- a/user_guide_src/source/extending/basecontroller/003.php +++ b/user_guide_src/source/extending/basecontroller/003.php @@ -4,6 +4,8 @@ class Home extends BaseController { + // ... + public function initController(/* ... */) { // Do Not Edit This Line diff --git a/user_guide_src/source/installation/upgrade_configuration/002.php b/user_guide_src/source/installation/upgrade_configuration/002.php index cc013d77583f..f62f19b7c5ad 100644 --- a/user_guide_src/source/installation/upgrade_configuration/002.php +++ b/user_guide_src/source/installation/upgrade_configuration/002.php @@ -8,5 +8,4 @@ class CustomClass extends BaseConfig { public $siteName = 'My Great Site'; public $siteEmail = 'webmaster@example.com'; - // ... } diff --git a/user_guide_src/source/testing/overview/018.php b/user_guide_src/source/testing/overview/018.php index b7138b5ec63b..67ccc4a634dc 100644 --- a/user_guide_src/source/testing/overview/018.php +++ b/user_guide_src/source/testing/overview/018.php @@ -4,7 +4,7 @@ final class SomeTest extends CIUnitTestCase { - protected function setUp() + protected function setUp(): void { parent::setUp(); From 7011b01108352310fa7653e9aa42a2e80583c1df Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Wed, 2 Mar 2022 10:14:53 +0100 Subject: [PATCH 0639/1246] Fix spaces. --- user_guide_src/source/models/entities/021.php | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/user_guide_src/source/models/entities/021.php b/user_guide_src/source/models/entities/021.php index a117e2a81f37..219c437b378c 100644 --- a/user_guide_src/source/models/entities/021.php +++ b/user_guide_src/source/models/entities/021.php @@ -9,13 +9,17 @@ class SomeHandler extends BaseCast public static function get($value, array $params = []) { var_dump($params); - // array(3) { - // [0]=> - // string(13) "App\SomeClass" - // [1]=> - // string(6) "param2" - // [2]=> - // string(6) "param3" - // } + /* + Output: + + array(3) { + [0]=> + string(13) "App\SomeClass" + [1]=> + string(6) "param2" + [2]=> + string(6) "param3" + } + */ } } From f7d93e3ed2d2767e8bac8eaaea69c32c496191bc Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Wed, 2 Mar 2022 10:22:34 +0100 Subject: [PATCH 0640/1246] Fix BaseController examples. --- user_guide_src/source/extending/basecontroller/002.php | 8 +++++++- user_guide_src/source/extending/basecontroller/003.php | 6 ++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/user_guide_src/source/extending/basecontroller/002.php b/user_guide_src/source/extending/basecontroller/002.php index bd7de42a0a94..1add155f1b4c 100644 --- a/user_guide_src/source/extending/basecontroller/002.php +++ b/user_guide_src/source/extending/basecontroller/002.php @@ -2,7 +2,13 @@ namespace App\Controllers; -class Home extends BaseController +use CodeIgniter\Controller; + +abstract class BaseController extends Controller { + // ... + protected $helpers = ['html', 'text']; + + // ... } diff --git a/user_guide_src/source/extending/basecontroller/003.php b/user_guide_src/source/extending/basecontroller/003.php index 22afdf184f75..5c9fcf1fc255 100644 --- a/user_guide_src/source/extending/basecontroller/003.php +++ b/user_guide_src/source/extending/basecontroller/003.php @@ -2,10 +2,12 @@ namespace App\Controllers; -class Home extends BaseController +use CodeIgniter\Controller; + +abstract class BaseController extends Controller { // ... - + public function initController(/* ... */) { // Do Not Edit This Line From b4f3c06cd78c8cb73bc64d4b8a9f7c7b8c40cde2 Mon Sep 17 00:00:00 2001 From: Alex Schmitz <40514119+sfadschm@users.noreply.github.com> Date: Wed, 2 Mar 2022 10:22:58 +0100 Subject: [PATCH 0641/1246] Fix empty line. Co-authored-by: kenjis --- user_guide_src/source/dbmgmt/migration/002.php | 1 + 1 file changed, 1 insertion(+) diff --git a/user_guide_src/source/dbmgmt/migration/002.php b/user_guide_src/source/dbmgmt/migration/002.php index 6a8482fb1478..b324f22003a7 100644 --- a/user_guide_src/source/dbmgmt/migration/002.php +++ b/user_guide_src/source/dbmgmt/migration/002.php @@ -11,6 +11,7 @@ public function up() $this->db->disableForeignKeyChecks(); // Migration rules would go here.. + $this->db->enableForeignKeyChecks(); } } From 561706af62db143cbd494e70242a3a4a1d3133c6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 3 Mar 2022 00:45:54 +0800 Subject: [PATCH 0642/1246] chore(deps): bump actions/checkout from 2 to 3 (#5760) Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/deploy-apidocs.yml | 4 ++-- .github/workflows/deploy-framework.yml | 8 ++++---- .github/workflows/deploy-userguide-latest.yml | 2 +- .github/workflows/test-autoreview.yml | 2 +- .github/workflows/test-coding-standards.yml | 2 +- .github/workflows/test-deptrac.yml | 2 +- .github/workflows/test-phpcpd.yml | 2 +- .github/workflows/test-phpstan.yml | 2 +- .github/workflows/test-phpunit.yml | 2 +- .github/workflows/test-rector.yml | 2 +- .github/workflows/test-scss.yml | 2 +- .github/workflows/test-userguide.yml | 2 +- 12 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/deploy-apidocs.yml b/.github/workflows/deploy-apidocs.yml index 4a7d20dd502b..55480f4fd5a4 100644 --- a/.github/workflows/deploy-apidocs.yml +++ b/.github/workflows/deploy-apidocs.yml @@ -24,12 +24,12 @@ jobs: git config --global user.name "${GITHUB_ACTOR}" - name: Checkout source - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: source - name: Checkout target - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: codeigniter4/api token: ${{ secrets.ACCESS_TOKEN }} diff --git a/.github/workflows/deploy-framework.yml b/.github/workflows/deploy-framework.yml index 339565dcfdfc..9fdbc8f08127 100644 --- a/.github/workflows/deploy-framework.yml +++ b/.github/workflows/deploy-framework.yml @@ -18,12 +18,12 @@ jobs: git config --global user.name "${GITHUB_ACTOR}" - name: Checkout source - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: source - name: Checkout target - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: codeigniter4/framework token: ${{ secrets.ACCESS_TOKEN }} @@ -63,12 +63,12 @@ jobs: git config --global user.name "${GITHUB_ACTOR}" - name: Checkout source - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: source - name: Checkout target - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: codeigniter4/appstarter token: ${{ secrets.ACCESS_TOKEN }} diff --git a/.github/workflows/deploy-userguide-latest.yml b/.github/workflows/deploy-userguide-latest.yml index 22e6eed4db4f..fb453f0c9694 100644 --- a/.github/workflows/deploy-userguide-latest.yml +++ b/.github/workflows/deploy-userguide-latest.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Build the latest User Guide - name: Build with Sphinx diff --git a/.github/workflows/test-autoreview.yml b/.github/workflows/test-autoreview.yml index 28f1230b0073..ccc97dcf137e 100644 --- a/.github/workflows/test-autoreview.yml +++ b/.github/workflows/test-autoreview.yml @@ -21,7 +21,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/test-coding-standards.yml b/.github/workflows/test-coding-standards.yml index 583f4d5df72c..4e9509f4fb2e 100644 --- a/.github/workflows/test-coding-standards.yml +++ b/.github/workflows/test-coding-standards.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/test-deptrac.yml b/.github/workflows/test-deptrac.yml index 262da202c02f..ac280f964d0a 100644 --- a/.github/workflows/test-deptrac.yml +++ b/.github/workflows/test-deptrac.yml @@ -30,7 +30,7 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/test-phpcpd.yml b/.github/workflows/test-phpcpd.yml index 6cfd76a054f1..e4d869c09d4a 100644 --- a/.github/workflows/test-phpcpd.yml +++ b/.github/workflows/test-phpcpd.yml @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/test-phpstan.yml b/.github/workflows/test-phpstan.yml index d0235ec9beb6..f7c09d1aa89e 100644 --- a/.github/workflows/test-phpstan.yml +++ b/.github/workflows/test-phpstan.yml @@ -37,7 +37,7 @@ jobs: php-versions: ['8.0', '8.1'] steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/test-phpunit.yml b/.github/workflows/test-phpunit.yml index 964f9fcb3f72..623d13f59475 100644 --- a/.github/workflows/test-phpunit.yml +++ b/.github/workflows/test-phpunit.yml @@ -120,7 +120,7 @@ jobs: run: echo -e "ALTER SESSION SET CONTAINER = XEPDB1;\nCREATE BIGFILE TABLESPACE \"TEST\" DATAFILE '/opt/oracle/product/18c/dbhomeXE/dbs/TEST' SIZE 10M AUTOEXTEND ON MAXSIZE UNLIMITED SEGMENT SPACE MANAGEMENT AUTO EXTENT MANAGEMENT LOCAL AUTOALLOCATE;\nCREATE USER \"ORACLE\" IDENTIFIED BY \"ORACLE\" DEFAULT TABLESPACE \"TEST\" TEMPORARY TABLESPACE TEMP QUOTA UNLIMITED ON \"TEST\";\nGRANT CONNECT,RESOURCE TO \"ORACLE\";\nexit;" | /lib/oracle/18.5/client64/bin/sqlplus -s sys/Oracle18@localhost:1521/XE as sysdba - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup PHP, with composer and extensions uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/test-rector.yml b/.github/workflows/test-rector.yml index 1282205c8bf6..a96821da3191 100644 --- a/.github/workflows/test-rector.yml +++ b/.github/workflows/test-rector.yml @@ -37,7 +37,7 @@ jobs: php-versions: ['7.4', '8.0'] steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/test-scss.yml b/.github/workflows/test-scss.yml index ff65863fe3a6..0d335a29552a 100644 --- a/.github/workflows/test-scss.yml +++ b/.github/workflows/test-scss.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Node uses: actions/setup-node@v3.0.0 diff --git a/.github/workflows/test-userguide.yml b/.github/workflows/test-userguide.yml index 44cfa52c8b17..b01c141a9c61 100644 --- a/.github/workflows/test-userguide.yml +++ b/.github/workflows/test-userguide.yml @@ -17,7 +17,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Detect usage of tabs in RST files run: php utils/check_tabs_in_rst.php From 45c8e27663107cede2a2da64ad07b934a8c19ca6 Mon Sep 17 00:00:00 2001 From: kenjis Date: Thu, 3 Mar 2022 08:56:34 +0900 Subject: [PATCH 0643/1246] docs: fix incorrect config filename --- user_guide_src/source/concepts/factories.rst | 6 +++--- user_guide_src/source/concepts/factories/005.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/user_guide_src/source/concepts/factories.rst b/user_guide_src/source/concepts/factories.rst index db48a58e8f74..2ddab73f2216 100644 --- a/user_guide_src/source/concepts/factories.rst +++ b/user_guide_src/source/concepts/factories.rst @@ -79,8 +79,8 @@ Factories Behavior Options can be applied in one of three ways (listed in ascending priority): -* A configuration file ``Factory`` with a component property. -* The static method ``Factories::setOptions``. +* A configuration class ``Config\Factory`` with a ``$component`` property. +* The static method ``Factories::setOptions()``. * Passing options directly at call time with a parameter. Configurations @@ -89,7 +89,7 @@ Configurations To set default component options, create a new Config files at **app/Config/Factory.php** that supplies options as an array property that matches the name of the component. For example, if you wanted to ensure that all Filters used by your app were valid framework instances, -your **Factories.php** file might look like this: +your **Factory.php** file might look like this: .. literalinclude:: factories/005.php diff --git a/user_guide_src/source/concepts/factories/005.php b/user_guide_src/source/concepts/factories/005.php index 10a82b828d73..1c63105feb04 100644 --- a/user_guide_src/source/concepts/factories/005.php +++ b/user_guide_src/source/concepts/factories/005.php @@ -5,7 +5,7 @@ use CodeIgniter\Config\Factory as BaseFactory; use CodeIgniter\Filters\FilterInterface; -class Factories extends BaseFactory +class Factory extends BaseFactory { public $filters = [ 'instanceOf' => FilterInterface::class, From eb45f56dcd2ef942a044e3ea45df5234954fa091 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Thu, 3 Mar 2022 20:36:03 +0700 Subject: [PATCH 0644/1246] [Rector] Update to Rector 0.12.17 and Re-run it --- composer.json | 2 +- phpstan-baseline.neon.dist | 4 ++++ tests/system/Database/Live/FabricatorLiveTest.php | 2 +- tests/system/Database/Live/ForgeTest.php | 8 ++------ tests/system/Filters/HoneypotTest.php | 2 +- tests/system/HTTP/URITest.php | 2 +- tests/system/Honeypot/HoneypotTest.php | 2 +- tests/system/I18n/TimeTest.php | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/composer.json b/composer.json index d9daf5748fb3..945e9d30e723 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "phpstan/phpstan": "^1.0", "phpunit/phpunit": "^9.1", "predis/predis": "^1.1", - "rector/rector": "0.12.16" + "rector/rector": "0.12.17" }, "suggest": { "ext-fileinfo": "Improves mime type detection for files" diff --git a/phpstan-baseline.neon.dist b/phpstan-baseline.neon.dist index 3343075a3159..7c0704286696 100644 --- a/phpstan-baseline.neon.dist +++ b/phpstan-baseline.neon.dist @@ -915,3 +915,7 @@ parameters: paths: - system/Cache/CacheFactory.php - system/Filters/Filters.php + + - + message: "#^Binary operation \"/\" between string and 8 results in an error\\.$#" + path: system/Encryption/Handlers/OpenSSLHandler.php diff --git a/tests/system/Database/Live/FabricatorLiveTest.php b/tests/system/Database/Live/FabricatorLiveTest.php index b1cf373f1244..761de0a39fae 100644 --- a/tests/system/Database/Live/FabricatorLiveTest.php +++ b/tests/system/Database/Live/FabricatorLiveTest.php @@ -50,7 +50,7 @@ public function testCreateAddsCountToDatabase() // Some countries violate the 40 character limit so override that $fabricator->setOverrides(['country' => 'France']); - $result = $fabricator->create($count); + $fabricator->create($count); $this->seeNumRecords($count, 'user', []); } diff --git a/tests/system/Database/Live/ForgeTest.php b/tests/system/Database/Live/ForgeTest.php index e20f26556f1d..113f2c0a211e 100644 --- a/tests/system/Database/Live/ForgeTest.php +++ b/tests/system/Database/Live/ForgeTest.php @@ -30,11 +30,7 @@ final class ForgeTest extends CIUnitTestCase protected $refresh = true; protected $seed = 'Tests\Support\Database\Seeds\CITestSeeder'; - - /** - * @var Forge - */ - protected $forge; + protected Forge $forge; protected function setUp(): void { @@ -812,7 +808,7 @@ public function testAddFields() $this->forge->addKey('id', true); $this->forge->addUniqueKey(['username', 'active']); - $create = $this->forge->createTable($tableName, true); + $this->forge->createTable($tableName, true); $fieldsNames = $this->db->getFieldNames($tableName); $fieldsData = $this->db->getFieldData($tableName); diff --git a/tests/system/Filters/HoneypotTest.php b/tests/system/Filters/HoneypotTest.php index 938f0fe525f5..4919b8490fde 100644 --- a/tests/system/Filters/HoneypotTest.php +++ b/tests/system/Filters/HoneypotTest.php @@ -53,7 +53,7 @@ public function testBeforeTriggered() $uri = 'admin/foo/bar'; $this->expectException(HoneypotException::class); - $request = $filters->run($uri, 'before'); + $filters->run($uri, 'before'); } public function testBeforeClean() diff --git a/tests/system/HTTP/URITest.php b/tests/system/HTTP/URITest.php index a4faacfbdd80..1a51741b8c36 100644 --- a/tests/system/HTTP/URITest.php +++ b/tests/system/HTTP/URITest.php @@ -155,7 +155,7 @@ public function testMalformedUri() { $this->expectException(HTTPException::class); $url = 'http://abc:a123'; - $uri = new URI($url); + new URI($url); } public function testMissingScheme() diff --git a/tests/system/Honeypot/HoneypotTest.php b/tests/system/Honeypot/HoneypotTest.php index e7f6893b9cf9..860d552d4e86 100644 --- a/tests/system/Honeypot/HoneypotTest.php +++ b/tests/system/Honeypot/HoneypotTest.php @@ -114,7 +114,7 @@ public function testHoneypotFilterBefore() $uri = 'admin/foo/bar'; $this->expectException(HoneypotException::class); - $request = $filters->run($uri, 'before'); + $filters->run($uri, 'before'); } public function testHoneypotFilterAfter() diff --git a/tests/system/I18n/TimeTest.php b/tests/system/I18n/TimeTest.php index bdc605d2d253..ed1b747699a4 100644 --- a/tests/system/I18n/TimeTest.php +++ b/tests/system/I18n/TimeTest.php @@ -235,7 +235,7 @@ public function testCreateFromFormatWithInvalidFormat() $this->expectException(I18nException::class); $this->expectExceptionMessage(lang('Time.invalidFormat', [$format])); - $time = Time::createFromFormat($format, 'America/Chicago'); + Time::createFromFormat($format, 'America/Chicago'); } public function testCreateFromTimestamp() From f9ef14a2064c1c6981d0fa95b02ccec9e09e545a Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 4 Mar 2022 11:37:07 +0900 Subject: [PATCH 0645/1246] docs: change comment style --- user_guide_src/source/cli/cli_library/007.php | 14 ++++++++------ user_guide_src/source/cli/cli_library/008.php | 14 ++++++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/user_guide_src/source/cli/cli_library/007.php b/user_guide_src/source/cli/cli_library/007.php index 474229ba6e6a..6d77ee91e4a0 100644 --- a/user_guide_src/source/cli/cli_library/007.php +++ b/user_guide_src/source/cli/cli_library/007.php @@ -2,9 +2,11 @@ $fruit = CLI::promptByKey('These are your choices:', ['The red apple', 'The plump orange', 'The ripe banana']); -//These are your choices: -// [0] The red apple -// [1] The plump orange -// [2] The ripe banana -// -//[0, 1, 2]: +/* +These are your choices: + [0] The red apple + [1] The plump orange + [2] The ripe banana + +[0, 1, 2]: +*/ diff --git a/user_guide_src/source/cli/cli_library/008.php b/user_guide_src/source/cli/cli_library/008.php index 003c9a362444..b455b7efe22e 100644 --- a/user_guide_src/source/cli/cli_library/008.php +++ b/user_guide_src/source/cli/cli_library/008.php @@ -6,9 +6,11 @@ 'banana' => 'The ripe banana' ]); -//These are your choices: -// [apple] The red apple -// [orange] The plump orange -// [banana] The ripe banana -// -//Which would you like? [apple, orange, banana]: +/* +These are your choices: + [apple] The red apple + [orange] The plump orange + [banana] The ripe banana + +Which would you like? [apple, orange, banana]: +*/ From 85e624f5d724a451d496f0caa90873cbd5a99dcd Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 4 Mar 2022 11:57:25 +0900 Subject: [PATCH 0646/1246] docs: move CodeIgniter 3 sample code to `ci3sample` folder --- user_guide_src/source/installation/upgrade_configuration.rst | 2 +- .../installation/upgrade_configuration/{ => ci3sample}/001.php | 0 user_guide_src/source/installation/upgrade_controllers.rst | 2 +- .../installation/upgrade_controllers/{ => ci3sample}/001.php | 0 user_guide_src/source/installation/upgrade_database.rst | 2 +- .../installation/upgrade_database/{ => ci3sample}/001.php | 0 user_guide_src/source/installation/upgrade_emails.rst | 2 +- .../source/installation/upgrade_emails/{ => ci3sample}/001.php | 0 user_guide_src/source/installation/upgrade_encryption.rst | 2 +- .../installation/upgrade_encryption/{ => ci3sample}/001.php | 0 user_guide_src/source/installation/upgrade_file_upload.rst | 2 +- .../installation/upgrade_file_upload/{ => ci3sample}/001.php | 0 user_guide_src/source/installation/upgrade_html_tables.rst | 2 +- .../installation/upgrade_html_tables/{ => ci3sample}/001.php | 0 user_guide_src/source/installation/upgrade_localization.rst | 2 +- .../installation/upgrade_localization/{ => ci3sample}/002.php | 0 user_guide_src/source/installation/upgrade_migrations.rst | 2 +- .../installation/upgrade_migrations/{ => ci3sample}/001.php | 0 user_guide_src/source/installation/upgrade_models.rst | 2 +- .../source/installation/upgrade_models/{ => ci3sample}/001.php | 0 user_guide_src/source/installation/upgrade_pagination.rst | 2 +- .../installation/upgrade_pagination/{ => ci3sample}/001.php | 0 user_guide_src/source/installation/upgrade_responses.rst | 2 +- .../installation/upgrade_responses/{ => ci3sample}/001.php | 0 user_guide_src/source/installation/upgrade_routing.rst | 2 +- .../source/installation/upgrade_routing/{ => ci3sample}/001.php | 0 user_guide_src/source/installation/upgrade_security.rst | 2 +- .../installation/upgrade_security/{ => ci3sample}/002.php | 0 user_guide_src/source/installation/upgrade_sessions.rst | 2 +- .../installation/upgrade_sessions/{ => ci3sample}/001.php | 0 user_guide_src/source/installation/upgrade_validations.rst | 2 +- .../installation/upgrade_validations/{ => ci3sample}/002.php | 0 user_guide_src/source/installation/upgrade_view_parser.rst | 2 +- .../installation/upgrade_view_parser/{ => ci3sample}/001.php | 0 user_guide_src/source/installation/upgrade_views.rst | 2 +- .../source/installation/upgrade_views/{ => ci3sample}/001.php | 0 36 files changed, 18 insertions(+), 18 deletions(-) rename user_guide_src/source/installation/upgrade_configuration/{ => ci3sample}/001.php (100%) rename user_guide_src/source/installation/upgrade_controllers/{ => ci3sample}/001.php (100%) rename user_guide_src/source/installation/upgrade_database/{ => ci3sample}/001.php (100%) rename user_guide_src/source/installation/upgrade_emails/{ => ci3sample}/001.php (100%) rename user_guide_src/source/installation/upgrade_encryption/{ => ci3sample}/001.php (100%) rename user_guide_src/source/installation/upgrade_file_upload/{ => ci3sample}/001.php (100%) rename user_guide_src/source/installation/upgrade_html_tables/{ => ci3sample}/001.php (100%) rename user_guide_src/source/installation/upgrade_localization/{ => ci3sample}/002.php (100%) rename user_guide_src/source/installation/upgrade_migrations/{ => ci3sample}/001.php (100%) rename user_guide_src/source/installation/upgrade_models/{ => ci3sample}/001.php (100%) rename user_guide_src/source/installation/upgrade_pagination/{ => ci3sample}/001.php (100%) rename user_guide_src/source/installation/upgrade_responses/{ => ci3sample}/001.php (100%) rename user_guide_src/source/installation/upgrade_routing/{ => ci3sample}/001.php (100%) rename user_guide_src/source/installation/upgrade_security/{ => ci3sample}/002.php (100%) rename user_guide_src/source/installation/upgrade_sessions/{ => ci3sample}/001.php (100%) rename user_guide_src/source/installation/upgrade_validations/{ => ci3sample}/002.php (100%) rename user_guide_src/source/installation/upgrade_view_parser/{ => ci3sample}/001.php (100%) rename user_guide_src/source/installation/upgrade_views/{ => ci3sample}/001.php (100%) diff --git a/user_guide_src/source/installation/upgrade_configuration.rst b/user_guide_src/source/installation/upgrade_configuration.rst index 21ae6101c158..6a9f38069478 100644 --- a/user_guide_src/source/installation/upgrade_configuration.rst +++ b/user_guide_src/source/installation/upgrade_configuration.rst @@ -40,7 +40,7 @@ CodeIgniter Version 3.x Path: **application/config**: -.. literalinclude:: upgrade_configuration/001.php +.. literalinclude:: upgrade_configuration/ci3sample/001.php CodeIgniter Version 4.x ----------------------- diff --git a/user_guide_src/source/installation/upgrade_configuration/001.php b/user_guide_src/source/installation/upgrade_configuration/ci3sample/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_configuration/001.php rename to user_guide_src/source/installation/upgrade_configuration/ci3sample/001.php diff --git a/user_guide_src/source/installation/upgrade_controllers.rst b/user_guide_src/source/installation/upgrade_controllers.rst index fc0bcb4d37d7..3e7521445691 100644 --- a/user_guide_src/source/installation/upgrade_controllers.rst +++ b/user_guide_src/source/installation/upgrade_controllers.rst @@ -43,7 +43,7 @@ CodeIgniter Version 3.x Path: **application/controllers**: -.. literalinclude:: upgrade_controllers/001.php +.. literalinclude:: upgrade_controllers/ci3sample/001.php CodeIgniter Version 4.x ----------------------- diff --git a/user_guide_src/source/installation/upgrade_controllers/001.php b/user_guide_src/source/installation/upgrade_controllers/ci3sample/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_controllers/001.php rename to user_guide_src/source/installation/upgrade_controllers/ci3sample/001.php diff --git a/user_guide_src/source/installation/upgrade_database.rst b/user_guide_src/source/installation/upgrade_database.rst index 4479c46ff5e8..10b1e6ac1c96 100644 --- a/user_guide_src/source/installation/upgrade_database.rst +++ b/user_guide_src/source/installation/upgrade_database.rst @@ -46,7 +46,7 @@ Code Example CodeIgniter Version 3.x ------------------------ -.. literalinclude:: upgrade_database/001.php +.. literalinclude:: upgrade_database/ci3sample/001.php CodeIgniter Version 4.x ----------------------- diff --git a/user_guide_src/source/installation/upgrade_database/001.php b/user_guide_src/source/installation/upgrade_database/ci3sample/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_database/001.php rename to user_guide_src/source/installation/upgrade_database/ci3sample/001.php diff --git a/user_guide_src/source/installation/upgrade_emails.rst b/user_guide_src/source/installation/upgrade_emails.rst index 1ece732add8f..af322f2d7c7a 100644 --- a/user_guide_src/source/installation/upgrade_emails.rst +++ b/user_guide_src/source/installation/upgrade_emails.rst @@ -28,7 +28,7 @@ Code Example CodeIgniter Version 3.x ------------------------ -.. literalinclude:: upgrade_emails/001.php +.. literalinclude:: upgrade_emails/ci3sample/001.php CodeIgniter Version 4.x ----------------------- diff --git a/user_guide_src/source/installation/upgrade_emails/001.php b/user_guide_src/source/installation/upgrade_emails/ci3sample/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_emails/001.php rename to user_guide_src/source/installation/upgrade_emails/ci3sample/001.php diff --git a/user_guide_src/source/installation/upgrade_encryption.rst b/user_guide_src/source/installation/upgrade_encryption.rst index fb617a5424d5..9d626d341d5d 100644 --- a/user_guide_src/source/installation/upgrade_encryption.rst +++ b/user_guide_src/source/installation/upgrade_encryption.rst @@ -26,7 +26,7 @@ Code Example CodeIgniter Version 3.x ------------------------ -.. literalinclude:: upgrade_encryption/001.php +.. literalinclude:: upgrade_encryption/ci3sample/001.php CodeIgniter Version 4.x ----------------------- diff --git a/user_guide_src/source/installation/upgrade_encryption/001.php b/user_guide_src/source/installation/upgrade_encryption/ci3sample/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_encryption/001.php rename to user_guide_src/source/installation/upgrade_encryption/ci3sample/001.php diff --git a/user_guide_src/source/installation/upgrade_file_upload.rst b/user_guide_src/source/installation/upgrade_file_upload.rst index f0eb3a24c405..ed620bbaeb67 100644 --- a/user_guide_src/source/installation/upgrade_file_upload.rst +++ b/user_guide_src/source/installation/upgrade_file_upload.rst @@ -27,7 +27,7 @@ Code Example CodeIgniter Version 3.x ------------------------ -.. literalinclude:: upgrade_file_upload/001.php +.. literalinclude:: upgrade_file_upload/ci3sample/001.php CodeIgniter Version 4.x ----------------------- diff --git a/user_guide_src/source/installation/upgrade_file_upload/001.php b/user_guide_src/source/installation/upgrade_file_upload/ci3sample/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_file_upload/001.php rename to user_guide_src/source/installation/upgrade_file_upload/ci3sample/001.php diff --git a/user_guide_src/source/installation/upgrade_html_tables.rst b/user_guide_src/source/installation/upgrade_html_tables.rst index 2a0bbaacd5c7..ae97e8e3baf2 100644 --- a/user_guide_src/source/installation/upgrade_html_tables.rst +++ b/user_guide_src/source/installation/upgrade_html_tables.rst @@ -27,7 +27,7 @@ Code Example CodeIgniter Version 3.x ------------------------ -.. literalinclude:: upgrade_html_tables/001.php +.. literalinclude:: upgrade_html_tables/ci3sample/001.php CodeIgniter Version 4.x ----------------------- diff --git a/user_guide_src/source/installation/upgrade_html_tables/001.php b/user_guide_src/source/installation/upgrade_html_tables/ci3sample/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_html_tables/001.php rename to user_guide_src/source/installation/upgrade_html_tables/ci3sample/001.php diff --git a/user_guide_src/source/installation/upgrade_localization.rst b/user_guide_src/source/installation/upgrade_localization.rst index 0d1ed53f2ebb..782336334974 100644 --- a/user_guide_src/source/installation/upgrade_localization.rst +++ b/user_guide_src/source/installation/upgrade_localization.rst @@ -32,7 +32,7 @@ Code Example CodeIgniter Version 3.x ------------------------ -.. literalinclude:: upgrade_localization/002.php +.. literalinclude:: upgrade_localization/ci3sample/002.php CodeIgniter Version 4.x ----------------------- diff --git a/user_guide_src/source/installation/upgrade_localization/002.php b/user_guide_src/source/installation/upgrade_localization/ci3sample/002.php similarity index 100% rename from user_guide_src/source/installation/upgrade_localization/002.php rename to user_guide_src/source/installation/upgrade_localization/ci3sample/002.php diff --git a/user_guide_src/source/installation/upgrade_migrations.rst b/user_guide_src/source/installation/upgrade_migrations.rst index 07dc32e96675..60f6b8d7b090 100644 --- a/user_guide_src/source/installation/upgrade_migrations.rst +++ b/user_guide_src/source/installation/upgrade_migrations.rst @@ -53,7 +53,7 @@ CodeIgniter Version 3.x Path: **application/migrations**: -.. literalinclude:: upgrade_migrations/001.php +.. literalinclude:: upgrade_migrations/ci3sample/001.php CodeIgniter Version 4.x ----------------------- diff --git a/user_guide_src/source/installation/upgrade_migrations/001.php b/user_guide_src/source/installation/upgrade_migrations/ci3sample/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_migrations/001.php rename to user_guide_src/source/installation/upgrade_migrations/ci3sample/001.php diff --git a/user_guide_src/source/installation/upgrade_models.rst b/user_guide_src/source/installation/upgrade_models.rst index ea9928a8f47e..1ffce60151e0 100644 --- a/user_guide_src/source/installation/upgrade_models.rst +++ b/user_guide_src/source/installation/upgrade_models.rst @@ -42,7 +42,7 @@ CodeIgniter Version 3.x Path: **application/models**: -.. literalinclude:: upgrade_models/001.php +.. literalinclude:: upgrade_models/ci3sample/001.php CodeIgniter Version 4.x ----------------------- diff --git a/user_guide_src/source/installation/upgrade_models/001.php b/user_guide_src/source/installation/upgrade_models/ci3sample/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_models/001.php rename to user_guide_src/source/installation/upgrade_models/ci3sample/001.php diff --git a/user_guide_src/source/installation/upgrade_pagination.rst b/user_guide_src/source/installation/upgrade_pagination.rst index c39638682534..6658ae8e4bd7 100644 --- a/user_guide_src/source/installation/upgrade_pagination.rst +++ b/user_guide_src/source/installation/upgrade_pagination.rst @@ -34,7 +34,7 @@ Code Example CodeIgniter Version 3.x ------------------------ -.. literalinclude:: upgrade_pagination/001.php +.. literalinclude:: upgrade_pagination/ci3sample/001.php CodeIgniter Version 4.x ----------------------- diff --git a/user_guide_src/source/installation/upgrade_pagination/001.php b/user_guide_src/source/installation/upgrade_pagination/ci3sample/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_pagination/001.php rename to user_guide_src/source/installation/upgrade_pagination/ci3sample/001.php diff --git a/user_guide_src/source/installation/upgrade_responses.rst b/user_guide_src/source/installation/upgrade_responses.rst index 455e5aa1617c..c6b925d144f1 100644 --- a/user_guide_src/source/installation/upgrade_responses.rst +++ b/user_guide_src/source/installation/upgrade_responses.rst @@ -25,7 +25,7 @@ Code Example CodeIgniter Version 3.x ------------------------ -.. literalinclude:: upgrade_responses/001.php +.. literalinclude:: upgrade_responses/ci3sample/001.php CodeIgniter Version 4.x ----------------------- diff --git a/user_guide_src/source/installation/upgrade_responses/001.php b/user_guide_src/source/installation/upgrade_responses/ci3sample/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_responses/001.php rename to user_guide_src/source/installation/upgrade_responses/ci3sample/001.php diff --git a/user_guide_src/source/installation/upgrade_routing.rst b/user_guide_src/source/installation/upgrade_routing.rst index 533826babd29..9e6c512ff423 100644 --- a/user_guide_src/source/installation/upgrade_routing.rst +++ b/user_guide_src/source/installation/upgrade_routing.rst @@ -30,7 +30,7 @@ CodeIgniter Version 3.x ------------------------ Path: **application/config/routes.php**: -.. literalinclude:: upgrade_routing/001.php +.. literalinclude:: upgrade_routing/ci3sample/001.php CodeIgniter Version 4.x ----------------------- diff --git a/user_guide_src/source/installation/upgrade_routing/001.php b/user_guide_src/source/installation/upgrade_routing/ci3sample/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_routing/001.php rename to user_guide_src/source/installation/upgrade_routing/ci3sample/001.php diff --git a/user_guide_src/source/installation/upgrade_security.rst b/user_guide_src/source/installation/upgrade_security.rst index 9000bea7167a..0a6d615e0841 100644 --- a/user_guide_src/source/installation/upgrade_security.rst +++ b/user_guide_src/source/installation/upgrade_security.rst @@ -33,7 +33,7 @@ Code Example CodeIgniter Version 3.x ------------------------ -.. literalinclude:: upgrade_security/002.php +.. literalinclude:: upgrade_security/ci3sample/002.php CodeIgniter Version 4.x ----------------------- diff --git a/user_guide_src/source/installation/upgrade_security/002.php b/user_guide_src/source/installation/upgrade_security/ci3sample/002.php similarity index 100% rename from user_guide_src/source/installation/upgrade_security/002.php rename to user_guide_src/source/installation/upgrade_security/ci3sample/002.php diff --git a/user_guide_src/source/installation/upgrade_sessions.rst b/user_guide_src/source/installation/upgrade_sessions.rst index df5ff7daae85..a309033bc816 100644 --- a/user_guide_src/source/installation/upgrade_sessions.rst +++ b/user_guide_src/source/installation/upgrade_sessions.rst @@ -31,7 +31,7 @@ Code Example CodeIgniter Version 3.x ------------------------ -.. literalinclude:: upgrade_sessions/001.php +.. literalinclude:: upgrade_sessions/ci3sample/001.php CodeIgniter Version 4.x ----------------------- diff --git a/user_guide_src/source/installation/upgrade_sessions/001.php b/user_guide_src/source/installation/upgrade_sessions/ci3sample/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_sessions/001.php rename to user_guide_src/source/installation/upgrade_sessions/ci3sample/001.php diff --git a/user_guide_src/source/installation/upgrade_validations.rst b/user_guide_src/source/installation/upgrade_validations.rst index 22dd0a2aff00..3612784ade28 100644 --- a/user_guide_src/source/installation/upgrade_validations.rst +++ b/user_guide_src/source/installation/upgrade_validations.rst @@ -73,7 +73,7 @@ Path: **application/views**:: Path: **application/controllers**: -.. literalinclude:: upgrade_validations/002.php +.. literalinclude:: upgrade_validations/ci3sample/002.php CodeIgniter Version 4.x ----------------------- diff --git a/user_guide_src/source/installation/upgrade_validations/002.php b/user_guide_src/source/installation/upgrade_validations/ci3sample/002.php similarity index 100% rename from user_guide_src/source/installation/upgrade_validations/002.php rename to user_guide_src/source/installation/upgrade_validations/ci3sample/002.php diff --git a/user_guide_src/source/installation/upgrade_view_parser.rst b/user_guide_src/source/installation/upgrade_view_parser.rst index a6faa488471e..5def5e912d5f 100644 --- a/user_guide_src/source/installation/upgrade_view_parser.rst +++ b/user_guide_src/source/installation/upgrade_view_parser.rst @@ -27,7 +27,7 @@ Code Example CodeIgniter Version 3.x ------------------------ -.. literalinclude:: upgrade_view_parser/001.php +.. literalinclude:: upgrade_view_parser/ci3sample/001.php CodeIgniter Version 4.x ----------------------- diff --git a/user_guide_src/source/installation/upgrade_view_parser/001.php b/user_guide_src/source/installation/upgrade_view_parser/ci3sample/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_view_parser/001.php rename to user_guide_src/source/installation/upgrade_view_parser/ci3sample/001.php diff --git a/user_guide_src/source/installation/upgrade_views.rst b/user_guide_src/source/installation/upgrade_views.rst index ac7df48f2844..574de607b42b 100644 --- a/user_guide_src/source/installation/upgrade_views.rst +++ b/user_guide_src/source/installation/upgrade_views.rst @@ -36,7 +36,7 @@ CodeIgniter Version 3.x Path: **application/views**: -.. literalinclude:: upgrade_views/001.php +.. literalinclude:: upgrade_views/ci3sample/001.php CodeIgniter Version 4.x ----------------------- diff --git a/user_guide_src/source/installation/upgrade_views/001.php b/user_guide_src/source/installation/upgrade_views/ci3sample/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_views/001.php rename to user_guide_src/source/installation/upgrade_views/ci3sample/001.php From 7120a4b762af9b10e181c75d1f26881c95d06904 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 4 Mar 2022 13:46:06 +0900 Subject: [PATCH 0647/1246] docs: change comment style --- .../source/cli/cli_commands/007.php | 8 +++-- .../source/database/query_builder/003.php | 7 ++-- .../source/database/query_builder/006.php | 12 ++++--- .../source/database/query_builder/018.php | 7 ++-- .../source/database/query_builder/074.php | 7 ++-- .../source/database/query_builder/087.php | 11 ++++--- .../source/database/query_builder/088.php | 11 ++++--- .../source/database/query_builder/091.php | 23 ++++++------- .../source/database/query_builder/092.php | 2 +- .../source/database/query_builder/093.php | 9 +++--- .../source/database/query_builder/095.php | 7 ++-- .../source/database/query_builder/097.php | 7 ++-- user_guide_src/source/dbmgmt/forge/004.php | 6 ++-- .../source/helpers/array_helper/011.php | 7 ++-- .../source/helpers/form_helper/010.php | 10 +++--- .../source/helpers/form_helper/011.php | 10 +++--- .../source/helpers/form_helper/012.php | 6 ++-- .../source/helpers/form_helper/014.php | 6 ++-- .../source/helpers/form_helper/017.php | 6 ++-- .../source/helpers/form_helper/018.php | 32 ++++++++----------- .../source/helpers/text_helper/020.php | 14 ++++---- .../source/incoming/incomingrequest/010.php | 12 +++---- .../source/libraries/curlrequest/014.php | 10 +++--- .../source/libraries/validation/009.php | 25 +++++++-------- .../source/libraries/validation/011.php | 15 ++++----- .../source/libraries/validation/026.php | 12 +++---- .../source/libraries/validation/028.2.php | 11 +++---- user_guide_src/source/models/entities/021.php | 1 - .../source/outgoing/response/021.php | 7 ++-- .../source/outgoing/view_parser/016.php | 7 ++-- .../source/testing/benchmark/004.php | 16 ++++------ 31 files changed, 159 insertions(+), 165 deletions(-) diff --git a/user_guide_src/source/cli/cli_commands/007.php b/user_guide_src/source/cli/cli_commands/007.php index 7fcb90ccf083..9f9f47f2a4fb 100644 --- a/user_guide_src/source/cli/cli_commands/007.php +++ b/user_guide_src/source/cli/cli_commands/007.php @@ -6,6 +6,8 @@ CLI::write($tab . CLI::color(str_pad($option, $pad), 'green') . $description, 'yellow'); } -// Output will be -// -n Set migration namespace -// -r override file +/* + Output will be + -n Set migration namespace + -r override file +*/ diff --git a/user_guide_src/source/database/query_builder/003.php b/user_guide_src/source/database/query_builder/003.php index 26a9470fb6ef..b5300a358280 100644 --- a/user_guide_src/source/database/query_builder/003.php +++ b/user_guide_src/source/database/query_builder/003.php @@ -1,6 +1,7 @@ get(10, 20); - -// Executes: SELECT * FROM mytable LIMIT 20, 10 -// (in MySQL. Other databases have slightly different syntax) +/* +Executes: SELECT * FROM mytable LIMIT 20, 10 +(in MySQL. Other databases have slightly different syntax) +*/ diff --git a/user_guide_src/source/database/query_builder/006.php b/user_guide_src/source/database/query_builder/006.php index 2868aaa49fee..2d672d5ce9ce 100644 --- a/user_guide_src/source/database/query_builder/006.php +++ b/user_guide_src/source/database/query_builder/006.php @@ -1,10 +1,12 @@ limit(10,20)->getCompiledSelect(false); - -// Prints string: SELECT * FROM mytable LIMIT 20, 10 -// (in MySQL. Other databases have slightly different syntax) +/* +Prints string: SELECT * FROM mytable LIMIT 20, 10 +(in MySQL. Other databases have slightly different syntax) +*/ echo $builder->select('title, content, date')->getCompiledSelect(); - -// Prints string: SELECT title, content, date FROM mytable LIMIT 20, 10 +/* +Prints string: SELECT title, content, date FROM mytable LIMIT 20, 10 +*/ diff --git a/user_guide_src/source/database/query_builder/018.php b/user_guide_src/source/database/query_builder/018.php index 870a45e638e6..17465bd1cb43 100644 --- a/user_guide_src/source/database/query_builder/018.php +++ b/user_guide_src/source/database/query_builder/018.php @@ -4,6 +4,7 @@ $builder->select('*'); $builder->join('comments', 'comments.id = blogs.id'); $query = $builder->get(); - -// Produces: -// SELECT * FROM blogs JOIN comments ON comments.id = blogs.id +/* +Produces: +SELECT * FROM blogs JOIN comments ON comments.id = blogs.id +*/ diff --git a/user_guide_src/source/database/query_builder/074.php b/user_guide_src/source/database/query_builder/074.php index 20025bc32cee..68fbcbb0bf60 100644 --- a/user_guide_src/source/database/query_builder/074.php +++ b/user_guide_src/source/database/query_builder/074.php @@ -10,6 +10,7 @@ ->groupEnd() ->where('d', 'd') ->get(); - -// Generates: -// SELECT * FROM (`my_table`) WHERE ( `a` = 'a' OR ( `b` = 'b' AND `c` = 'c' ) ) AND `d` = 'd' +/* +Generates: +SELECT * FROM (`my_table`) WHERE ( `a` = 'a' OR ( `b` = 'b' AND `c` = 'c' ) ) AND `d` = 'd' +*/ diff --git a/user_guide_src/source/database/query_builder/087.php b/user_guide_src/source/database/query_builder/087.php index 1b99a6196706..3032402a7c32 100644 --- a/user_guide_src/source/database/query_builder/087.php +++ b/user_guide_src/source/database/query_builder/087.php @@ -8,8 +8,9 @@ $builder->where('id', $id); $builder->update($data); -// Produces: -// -// UPDATE mytable -// SET title = '{$title}', name = '{$name}', date = '{$date}' -// WHERE id = $id +/* +Produces: +UPDATE mytable +SET title = '{$title}', name = '{$name}', date = '{$date}' +WHERE id = $id +*/ diff --git a/user_guide_src/source/database/query_builder/088.php b/user_guide_src/source/database/query_builder/088.php index c789d85e02bf..37afb6ce2b46 100644 --- a/user_guide_src/source/database/query_builder/088.php +++ b/user_guide_src/source/database/query_builder/088.php @@ -10,8 +10,9 @@ class Myclass $object = new Myclass; $builder->where('id', $id); $builder->update($object); -// Produces: -// -// UPDATE `mytable` -// SET `title` = '{$title}', `name` = '{$name}', `date` = '{$date}' -// WHERE id = `$id` +/* +Produces: +UPDATE `mytable` +SET `title` = '{$title}', `name` = '{$name}', `date` = '{$date}' +WHERE id = `$id` +*/ diff --git a/user_guide_src/source/database/query_builder/091.php b/user_guide_src/source/database/query_builder/091.php index 545641a98f74..a3943d41cfb9 100644 --- a/user_guide_src/source/database/query_builder/091.php +++ b/user_guide_src/source/database/query_builder/091.php @@ -14,14 +14,15 @@ ]; $builder->updateBatch($data, 'title'); - -// Produces: -// UPDATE `mytable` SET `name` = CASE -// WHEN `title` = 'My title' THEN 'My Name 2' -// WHEN `title` = 'Another title' THEN 'Another Name 2' -// ELSE `name` END, -// `date` = CASE -// WHEN `title` = 'My title' THEN 'My date 2' -// WHEN `title` = 'Another title' THEN 'Another date 2' -// ELSE `date` END -// WHERE `title` IN ('My title','Another title') +/* +Produces: +UPDATE `mytable` SET `name` = CASE +WHEN `title` = 'My title' THEN 'My Name 2' +WHEN `title` = 'Another title' THEN 'Another Name 2' +ELSE `name` END, +`date` = CASE +WHEN `title` = 'My title' THEN 'My date 2' +WHEN `title` = 'Another title' THEN 'Another date 2' +ELSE `date` END +WHERE `title` IN ('My title','Another title') +*/ diff --git a/user_guide_src/source/database/query_builder/092.php b/user_guide_src/source/database/query_builder/092.php index 605d533162bd..ed680a441d98 100644 --- a/user_guide_src/source/database/query_builder/092.php +++ b/user_guide_src/source/database/query_builder/092.php @@ -1,4 +1,4 @@ delete(['id' => $id]); -// Produces: // DELETE FROM mytable // WHERE id = $id +// Produces: DELETE FROM mytable WHERE id = $id diff --git a/user_guide_src/source/database/query_builder/093.php b/user_guide_src/source/database/query_builder/093.php index 6628a09b5056..70e9ed3b7f69 100644 --- a/user_guide_src/source/database/query_builder/093.php +++ b/user_guide_src/source/database/query_builder/093.php @@ -2,7 +2,8 @@ $builder->where('id', $id); $builder->delete(); - -// Produces: -// DELETE FROM mytable -// WHERE id = $id +/* +Produces: +DELETE FROM mytable +WHERE id = $id +*/ diff --git a/user_guide_src/source/database/query_builder/095.php b/user_guide_src/source/database/query_builder/095.php index 0cdf6ef52bfa..c2afc9fe3c2a 100644 --- a/user_guide_src/source/database/query_builder/095.php +++ b/user_guide_src/source/database/query_builder/095.php @@ -1,6 +1,7 @@ truncate(); - -// Produce: -// TRUNCATE mytable +/* +Produce: +TRUNCATE mytable +*/ diff --git a/user_guide_src/source/database/query_builder/097.php b/user_guide_src/source/database/query_builder/097.php index f484292a9d27..ec48b920e406 100644 --- a/user_guide_src/source/database/query_builder/097.php +++ b/user_guide_src/source/database/query_builder/097.php @@ -11,6 +11,7 @@ // ... $data = $builder->get()->getResultArray(); - -// Would execute and return an array of results of the following query: -// SELECT field1, field1 from mytable where field3 = 5; +/* +Would execute and return an array of results of the following query: +SELECT field1, field1 from mytable where field3 = 5; +*/ diff --git a/user_guide_src/source/dbmgmt/forge/004.php b/user_guide_src/source/dbmgmt/forge/004.php index c514b3c0e46a..d793fd8b82d8 100644 --- a/user_guide_src/source/dbmgmt/forge/004.php +++ b/user_guide_src/source/dbmgmt/forge/004.php @@ -1,5 +1,7 @@ createDatabase('my_db', true); -// gives CREATE DATABASE IF NOT EXISTS `my_db` -// or will check if a database exists +/* +gives CREATE DATABASE IF NOT EXISTS `my_db` +or will check if a database exists +*/ diff --git a/user_guide_src/source/helpers/array_helper/011.php b/user_guide_src/source/helpers/array_helper/011.php index 754588747d6c..31ee64387979 100644 --- a/user_guide_src/source/helpers/array_helper/011.php +++ b/user_guide_src/source/helpers/array_helper/011.php @@ -2,12 +2,13 @@ // using the same data from above $flattened = array_flatten_with_dots($arrayToFlatten, 'foo_'); - -// $flattened is now: +/* +$flattened is now: [ 'foo_personal.first_name' => 'john', 'foo_personal.last_name' => 'smith', 'foo_personal.age' => '26', 'foo_personal.address' => 'US', 'foo_other_details' => 'marines officer', -]; +] +*/ diff --git a/user_guide_src/source/helpers/form_helper/010.php b/user_guide_src/source/helpers/form_helper/010.php index 8efbdfdeddf1..401a94c685b1 100644 --- a/user_guide_src/source/helpers/form_helper/010.php +++ b/user_guide_src/source/helpers/form_helper/010.php @@ -7,11 +7,9 @@ ]; echo form_hidden($data); - /* - Would produce: - - - - +Would produce: + + + */ diff --git a/user_guide_src/source/helpers/form_helper/011.php b/user_guide_src/source/helpers/form_helper/011.php index 26641f577429..6e28c61e8352 100644 --- a/user_guide_src/source/helpers/form_helper/011.php +++ b/user_guide_src/source/helpers/form_helper/011.php @@ -7,11 +7,9 @@ ]; echo form_hidden('my_array', $data); - /* - Would produce: - - - - +Would produce: + + + */ diff --git a/user_guide_src/source/helpers/form_helper/012.php b/user_guide_src/source/helpers/form_helper/012.php index 1059821da652..4b232ba110f8 100644 --- a/user_guide_src/source/helpers/form_helper/012.php +++ b/user_guide_src/source/helpers/form_helper/012.php @@ -9,9 +9,7 @@ ]; echo form_input($data); - /* - Would produce: - - +Would produce: + */ diff --git a/user_guide_src/source/helpers/form_helper/014.php b/user_guide_src/source/helpers/form_helper/014.php index 6143aed6eaaf..cf8a20dbadff 100644 --- a/user_guide_src/source/helpers/form_helper/014.php +++ b/user_guide_src/source/helpers/form_helper/014.php @@ -10,9 +10,7 @@ ]; echo form_input($data); - /* - Would produce: - - +Would produce: + */ diff --git a/user_guide_src/source/helpers/form_helper/017.php b/user_guide_src/source/helpers/form_helper/017.php index 0ec6a19ca99f..99106e9b4fa8 100644 --- a/user_guide_src/source/helpers/form_helper/017.php +++ b/user_guide_src/source/helpers/form_helper/017.php @@ -1,9 +1,7 @@ 'Email Address...'], 'email'); - /* - Would produce: - - +Would produce: + */ diff --git a/user_guide_src/source/helpers/form_helper/018.php b/user_guide_src/source/helpers/form_helper/018.php index fc6521be6e06..6e521ed04985 100644 --- a/user_guide_src/source/helpers/form_helper/018.php +++ b/user_guide_src/source/helpers/form_helper/018.php @@ -9,27 +9,23 @@ $shirts_on_sale = ['small', 'large']; echo form_dropdown('shirts', $options, 'large'); - /* - Would produce: - - +Would produce: + */ echo form_dropdown('shirts', $options, $shirts_on_sale); - /* - Would produce: - - +Would produce: + */ diff --git a/user_guide_src/source/helpers/text_helper/020.php b/user_guide_src/source/helpers/text_helper/020.php index 1b235b77497e..4bd123f5ae8a 100644 --- a/user_guide_src/source/helpers/text_helper/020.php +++ b/user_guide_src/source/helpers/text_helper/020.php @@ -2,14 +2,12 @@ $string = "Here is a simple string of text that will help us demonstrate this function."; echo word_wrap($string, 25); - /* - Would produce: - - Here is a simple string - of text that will help us - demonstrate this - function. +Would produce: +Here is a simple string +of text that will help us +demonstrate this +function. - Excessively long words will be split, but URLs will not be. +Excessively long words will be split, but URLs will not be. */ diff --git a/user_guide_src/source/incoming/incomingrequest/010.php b/user_guide_src/source/incoming/incomingrequest/010.php index e223b7772d54..a1dc2ccfb9cd 100644 --- a/user_guide_src/source/incoming/incomingrequest/010.php +++ b/user_guide_src/source/incoming/incomingrequest/010.php @@ -1,13 +1,13 @@ getVar('foo'); diff --git a/user_guide_src/source/libraries/curlrequest/014.php b/user_guide_src/source/libraries/curlrequest/014.php index 9147c8861423..2f7e79cc4be7 100644 --- a/user_guide_src/source/libraries/curlrequest/014.php +++ b/user_guide_src/source/libraries/curlrequest/014.php @@ -1,11 +1,9 @@ request('GET', 'http://example.com', ['allow_redirects' => true]); - /* - Sets the following defaults: - - 'max' => 5, // Maximum number of redirects to follow before stopping - 'strict' => true, // Ensure POST requests stay POST requests through redirects - 'protocols' => ['http', 'https'] // Restrict redirects to one or more protocols +Sets the following defaults: +'max' => 5, // Maximum number of redirects to follow before stopping +'strict' => true, // Ensure POST requests stay POST requests through redirects +'protocols' => ['http', 'https'] // Restrict redirects to one or more protocols */ diff --git a/user_guide_src/source/libraries/validation/009.php b/user_guide_src/source/libraries/validation/009.php index 8792a8a8f728..6f7ce8b9e992 100644 --- a/user_guide_src/source/libraries/validation/009.php +++ b/user_guide_src/source/libraries/validation/009.php @@ -1,21 +1,20 @@ [ - 'name' => 'Joe Smith', - 'friends' => [ - [ - 'name' => 'Fred Flinstone', - ], - [ - 'name' => 'Wilma', - ], - ] +The data to test: +[ + 'contacts' => [ + 'name' => 'Joe Smith', + 'friends' => [ + [ + 'name' => 'Fred Flinstone', + ], + [ + 'name' => 'Wilma', + ], ] ] +] */ // Joe Smith diff --git a/user_guide_src/source/libraries/validation/011.php b/user_guide_src/source/libraries/validation/011.php index ec6b9c9adbab..fa5cad04369c 100644 --- a/user_guide_src/source/libraries/validation/011.php +++ b/user_guide_src/source/libraries/validation/011.php @@ -1,15 +1,14 @@ [ - 1, - 2, - 3, - ] +The data to test: +[ + 'user_ids' => [ + 1, + 2, + 3, ] +] */ // Rule diff --git a/user_guide_src/source/libraries/validation/026.php b/user_guide_src/source/libraries/validation/026.php index e633f5cdd1e3..4c27f4548b0e 100644 --- a/user_guide_src/source/libraries/validation/026.php +++ b/user_guide_src/source/libraries/validation/026.php @@ -1,12 +1,10 @@ getErrors(); - /* - Produces: - - [ - 'field1' => 'error message', - 'field2' => 'error message', - ] +Produces: +[ + 'field1' => 'error message', + 'field2' => 'error message', +] */ diff --git a/user_guide_src/source/libraries/validation/028.2.php b/user_guide_src/source/libraries/validation/028.2.php index 6ad70098c789..34a4d7edefe3 100644 --- a/user_guide_src/source/libraries/validation/028.2.php +++ b/user_guide_src/source/libraries/validation/028.2.php @@ -1,12 +1,11 @@ 'Error', - 'foo.baz.bar' => 'Error', - ] +For errors: +[ + 'foo.0.bar' => 'Error', + 'foo.baz.bar' => 'Error', +] */ // returns true diff --git a/user_guide_src/source/models/entities/021.php b/user_guide_src/source/models/entities/021.php index 219c437b378c..ceb17247a908 100644 --- a/user_guide_src/source/models/entities/021.php +++ b/user_guide_src/source/models/entities/021.php @@ -11,7 +11,6 @@ public static function get($value, array $params = []) var_dump($params); /* Output: - array(3) { [0]=> string(13) "App\SomeClass" diff --git a/user_guide_src/source/outgoing/response/021.php b/user_guide_src/source/outgoing/response/021.php index 092a758b18db..51abaf76bdbd 100644 --- a/user_guide_src/source/outgoing/response/021.php +++ b/user_guide_src/source/outgoing/response/021.php @@ -1,6 +1,7 @@ noCache(); - -// Sets the following header: -// Cache-Control: no-store, max-age=0, no-cache +/* +Sets the following header: +Cache-Control: no-store, max-age=0, no-cache +*/ diff --git a/user_guide_src/source/outgoing/view_parser/016.php b/user_guide_src/source/outgoing/view_parser/016.php index 0350043cf4fa..0c71e3f88fbb 100644 --- a/user_guide_src/source/outgoing/view_parser/016.php +++ b/user_guide_src/source/outgoing/view_parser/016.php @@ -9,8 +9,11 @@ class View extends BaseView public $plugins = [ 'foo' => '\Some\Class::methodName', ]; + // ... } -// Tag is replaced by the return value of Some\Class::methodName static function. -// {+ foo +} +/* +Tag is replaced by the return value of Some\Class::methodName() static function. +{+ foo +} +*/ diff --git a/user_guide_src/source/testing/benchmark/004.php b/user_guide_src/source/testing/benchmark/004.php index 3048a2851ff3..32dc5df31b1a 100644 --- a/user_guide_src/source/testing/benchmark/004.php +++ b/user_guide_src/source/testing/benchmark/004.php @@ -1,15 +1,13 @@ getTimers(); - /* - Produces: - - [ - 'render view' => [ - 'start' => 1234567890, - 'end' => 1345678920, - 'duration' => 15.4315, // number of seconds - ] +Produces: +[ + 'render view' => [ + 'start' => 1234567890, + 'end' => 1345678920, + 'duration' => 15.4315, // number of seconds ] +] */ From 806d5726011d9dcc04fdf7ac951d5007834d7702 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 4 Mar 2022 13:50:09 +0900 Subject: [PATCH 0648/1246] docs: change comment style --- user_guide_src/source/cli/cli_commands/007.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/user_guide_src/source/cli/cli_commands/007.php b/user_guide_src/source/cli/cli_commands/007.php index 9f9f47f2a4fb..3365e8afdd0e 100644 --- a/user_guide_src/source/cli/cli_commands/007.php +++ b/user_guide_src/source/cli/cli_commands/007.php @@ -7,7 +7,7 @@ } /* - Output will be - -n Set migration namespace - -r override file +Output will be: +-n Set migration namespace +-r override file */ From fff15ead6010363f5938bec26c3c08409fe03dd9 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 4 Mar 2022 12:55:51 +0900 Subject: [PATCH 0649/1246] docs: add empty line in sample code --- user_guide_src/source/concepts/services/007.php | 1 + user_guide_src/source/concepts/services/008.php | 1 + user_guide_src/source/concepts/services/010.php | 1 + user_guide_src/source/database/configuration/006.php | 1 + user_guide_src/source/database/helpers/001.php | 1 - user_guide_src/source/database/helpers/002.php | 1 - user_guide_src/source/database/query_builder/005.php | 1 - user_guide_src/source/database/query_builder/008.php | 1 - user_guide_src/source/database/query_builder/016.php | 1 - user_guide_src/source/database/query_builder/017.php | 1 - user_guide_src/source/database/query_builder/027.php | 2 -- user_guide_src/source/database/query_builder/032.php | 1 - user_guide_src/source/database/query_builder/034.php | 1 - user_guide_src/source/database/query_builder/036.php | 1 - user_guide_src/source/database/query_builder/053.php | 1 - user_guide_src/source/database/query_builder/055.php | 1 - user_guide_src/source/database/query_builder/057.php | 1 - user_guide_src/source/database/query_builder/078.php | 1 - user_guide_src/source/database/query_builder/079.php | 2 -- user_guide_src/source/database/query_builder/081.php | 1 - user_guide_src/source/database/query_builder/098.php | 1 - user_guide_src/source/extending/core_classes/002.php | 1 + user_guide_src/source/general/configuration/008.php | 1 + user_guide_src/source/general/logging/002.php | 1 + user_guide_src/source/general/logging/003.php | 1 + user_guide_src/source/general/logging/004.php | 1 + user_guide_src/source/general/managing_apps/001.php | 1 + user_guide_src/source/incoming/filters/003.php | 1 + user_guide_src/source/incoming/filters/004.php | 1 + user_guide_src/source/incoming/filters/005.php | 1 + user_guide_src/source/incoming/filters/006.php | 1 + user_guide_src/source/incoming/filters/007.php | 1 + user_guide_src/source/incoming/filters/008.php | 1 + user_guide_src/source/incoming/filters/009.php | 1 + user_guide_src/source/incoming/filters/011.php | 1 + user_guide_src/source/libraries/caching/013.php | 2 ++ user_guide_src/source/libraries/caching/014.php | 1 + user_guide_src/source/libraries/curlrequest/001.php | 1 + user_guide_src/source/libraries/encryption/008.php | 1 - user_guide_src/source/libraries/honeypot/001.php | 1 + user_guide_src/source/libraries/pagination/010.php | 1 + user_guide_src/source/libraries/pagination/011.php | 1 + user_guide_src/source/libraries/security/002.php | 1 + user_guide_src/source/libraries/security/003.php | 1 + user_guide_src/source/libraries/security/004.php | 1 + user_guide_src/source/libraries/security/006.php | 1 + user_guide_src/source/libraries/security/007.php | 1 + user_guide_src/source/libraries/security/008.php | 1 + user_guide_src/source/libraries/security/009.php | 1 + user_guide_src/source/libraries/sessions/010.php | 2 -- user_guide_src/source/libraries/sessions/017.php | 2 -- user_guide_src/source/libraries/sessions/038.php | 2 -- user_guide_src/source/libraries/sessions/044.php | 1 + user_guide_src/source/libraries/throttler/003.php | 1 + user_guide_src/source/libraries/throttler/004.php | 1 + user_guide_src/source/libraries/validation/003.php | 1 + user_guide_src/source/libraries/validation/013.php | 1 + user_guide_src/source/libraries/validation/015.php | 2 ++ user_guide_src/source/libraries/validation/031.php | 1 + user_guide_src/source/libraries/validation/032.php | 1 + user_guide_src/source/outgoing/api_responses/003.php | 1 + user_guide_src/source/outgoing/api_responses/004.php | 1 + user_guide_src/source/outgoing/localization/001.php | 1 + user_guide_src/source/outgoing/localization/002.php | 1 + user_guide_src/source/outgoing/localization/003.php | 1 + user_guide_src/source/outgoing/response/011.php | 1 + user_guide_src/source/outgoing/view_decorators/002.php | 1 + user_guide_src/source/outgoing/view_parser/005.php | 1 - user_guide_src/source/outgoing/view_parser/012.php | 1 + user_guide_src/source/outgoing/view_parser/013.php | 1 + user_guide_src/source/outgoing/view_parser/014.php | 1 + user_guide_src/source/outgoing/view_parser/015.php | 1 + user_guide_src/source/outgoing/view_parser/017.php | 1 + user_guide_src/source/outgoing/view_parser/018.php | 1 - user_guide_src/source/outgoing/view_parser/019.php | 1 - user_guide_src/source/outgoing/view_parser/020.php | 1 - user_guide_src/source/testing/controllers/012.php | 1 + user_guide_src/source/testing/overview/007.php | 1 + user_guide_src/source/tutorial/create_news_items/001.php | 1 + 79 files changed, 56 insertions(+), 30 deletions(-) diff --git a/user_guide_src/source/concepts/services/007.php b/user_guide_src/source/concepts/services/007.php index 298b8abd010f..296d8445fefc 100644 --- a/user_guide_src/source/concepts/services/007.php +++ b/user_guide_src/source/concepts/services/007.php @@ -10,5 +10,6 @@ public static function routes() { return new \App\Router\MyRouter(); } + // ... } diff --git a/user_guide_src/source/concepts/services/008.php b/user_guide_src/source/concepts/services/008.php index 52edb387792c..5843b28ab5e2 100644 --- a/user_guide_src/source/concepts/services/008.php +++ b/user_guide_src/source/concepts/services/008.php @@ -10,5 +10,6 @@ public static function renderer($viewPath = APPPATH . 'views/') { return new \CodeIgniter\View\View($viewPath); } + // ... } diff --git a/user_guide_src/source/concepts/services/010.php b/user_guide_src/source/concepts/services/010.php index fd5d3f6c4e35..b74d9c470888 100644 --- a/user_guide_src/source/concepts/services/010.php +++ b/user_guide_src/source/concepts/services/010.php @@ -14,5 +14,6 @@ public static function routes($getShared = false) return static::getSharedInstance('routes'); } + // ... } diff --git a/user_guide_src/source/database/configuration/006.php b/user_guide_src/source/database/configuration/006.php index afc24022c199..4381a0a71fff 100644 --- a/user_guide_src/source/database/configuration/006.php +++ b/user_guide_src/source/database/configuration/006.php @@ -24,5 +24,6 @@ class Database extends Config 'strictOn' => false, 'failover' => [], ]; + // ... } diff --git a/user_guide_src/source/database/helpers/001.php b/user_guide_src/source/database/helpers/001.php index f5dea164c946..e36a3989a74f 100644 --- a/user_guide_src/source/database/helpers/001.php +++ b/user_guide_src/source/database/helpers/001.php @@ -1,5 +1,4 @@ table('my_table')->countAll(); - // Produces an integer, like 25 diff --git a/user_guide_src/source/database/helpers/002.php b/user_guide_src/source/database/helpers/002.php index d43cf8dbc3bc..bca6cfe1b5a8 100644 --- a/user_guide_src/source/database/helpers/002.php +++ b/user_guide_src/source/database/helpers/002.php @@ -1,5 +1,4 @@ table('my_table')->like('title', 'match')->countAllResults(); - // Produces an integer, like 5 diff --git a/user_guide_src/source/database/query_builder/005.php b/user_guide_src/source/database/query_builder/005.php index 38bc63a577e7..7a33f8be2d82 100644 --- a/user_guide_src/source/database/query_builder/005.php +++ b/user_guide_src/source/database/query_builder/005.php @@ -2,5 +2,4 @@ $sql = $builder->getCompiledSelect(); echo $sql; - // Prints string: SELECT * FROM mytable diff --git a/user_guide_src/source/database/query_builder/008.php b/user_guide_src/source/database/query_builder/008.php index e2b594d51865..f9ebd8650717 100644 --- a/user_guide_src/source/database/query_builder/008.php +++ b/user_guide_src/source/database/query_builder/008.php @@ -2,5 +2,4 @@ $builder->select('title, content, date'); $query = $builder->get(); - // Executes: SELECT title, content, date FROM mytable diff --git a/user_guide_src/source/database/query_builder/016.php b/user_guide_src/source/database/query_builder/016.php index e505681ddc57..f00c2dbe47c2 100644 --- a/user_guide_src/source/database/query_builder/016.php +++ b/user_guide_src/source/database/query_builder/016.php @@ -3,5 +3,4 @@ $subquery = $db->table('users'); $builder = $db->table('jobs')->fromSubquery($subquery, 'alias'); $query = $builder->get(); - // Produces: SELECT * FROM `jobs`, (SELECT * FROM `users`) AS `alias` diff --git a/user_guide_src/source/database/query_builder/017.php b/user_guide_src/source/database/query_builder/017.php index 938edc98c72c..965ae956a6af 100644 --- a/user_guide_src/source/database/query_builder/017.php +++ b/user_guide_src/source/database/query_builder/017.php @@ -3,5 +3,4 @@ $subquery = $db->table('users')->select('id, name'); $builder = $db->newQuery()->fromSubquery($subquery, 't'); $query = $builder->get(); - // Produces: SELECT * FROM (SELECT `id`, `name` FROM users) AS `t` diff --git a/user_guide_src/source/database/query_builder/027.php b/user_guide_src/source/database/query_builder/027.php index 7583487da1a2..043b7d9e451b 100644 --- a/user_guide_src/source/database/query_builder/027.php +++ b/user_guide_src/source/database/query_builder/027.php @@ -1,11 +1,9 @@ where('advance_amount <', function (BaseBuilder $builder) { return $builder->select('MAX(advance_amount)', false)->from('orders')->where('id >', 2); }); - // Produces: WHERE "advance_amount" < (SELECT MAX(advance_amount) FROM "orders" WHERE "id" > 2) // With builder directly diff --git a/user_guide_src/source/database/query_builder/032.php b/user_guide_src/source/database/query_builder/032.php index 07aee709b79c..7a7a44182396 100644 --- a/user_guide_src/source/database/query_builder/032.php +++ b/user_guide_src/source/database/query_builder/032.php @@ -4,7 +4,6 @@ $builder->orWhereIn('id', function (BaseBuilder $builder) { return $builder->select('job_id')->from('users_jobs')->where('user_id', 3); }); - // Produces: OR "id" IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3) // With builder directly diff --git a/user_guide_src/source/database/query_builder/034.php b/user_guide_src/source/database/query_builder/034.php index e5e366acb069..2316388e16b6 100644 --- a/user_guide_src/source/database/query_builder/034.php +++ b/user_guide_src/source/database/query_builder/034.php @@ -4,7 +4,6 @@ $builder->whereNotIn('id', function (BaseBuilder $builder) { return $builder->select('job_id')->from('users_jobs')->where('user_id', 3); }); - // Produces: WHERE "id" NOT IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3) // With builder directly diff --git a/user_guide_src/source/database/query_builder/036.php b/user_guide_src/source/database/query_builder/036.php index 8b3087cac1c1..d50bcc113853 100644 --- a/user_guide_src/source/database/query_builder/036.php +++ b/user_guide_src/source/database/query_builder/036.php @@ -4,7 +4,6 @@ $builder->orWhereNotIn('id', function (BaseBuilder $builder) { return $builder->select('job_id')->from('users_jobs')->where('user_id', 3); }); - // Produces: OR "id" NOT IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3) // With builder directly diff --git a/user_guide_src/source/database/query_builder/053.php b/user_guide_src/source/database/query_builder/053.php index 3bbf43645915..baa936c5df82 100644 --- a/user_guide_src/source/database/query_builder/053.php +++ b/user_guide_src/source/database/query_builder/053.php @@ -4,7 +4,6 @@ $builder->orHavingIn('id', function (BaseBuilder $builder) { return $builder->select('user_id')->from('users_jobs')->where('group_id', 3); }); - // Produces: OR "id" IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3) // With builder directly diff --git a/user_guide_src/source/database/query_builder/055.php b/user_guide_src/source/database/query_builder/055.php index 2c032a5b1cec..986b3ff24cb9 100644 --- a/user_guide_src/source/database/query_builder/055.php +++ b/user_guide_src/source/database/query_builder/055.php @@ -4,7 +4,6 @@ $builder->havingNotIn('id', function (BaseBuilder $builder) { return $builder->select('user_id')->from('users_jobs')->where('group_id', 3); }); - // Produces: HAVING "id" NOT IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3) // With builder directly diff --git a/user_guide_src/source/database/query_builder/057.php b/user_guide_src/source/database/query_builder/057.php index 7960a3382f79..85cab6e2eba8 100644 --- a/user_guide_src/source/database/query_builder/057.php +++ b/user_guide_src/source/database/query_builder/057.php @@ -4,7 +4,6 @@ $builder->orHavingNotIn('id', function (BaseBuilder $builder) { return $builder->select('user_id')->from('users_jobs')->where('group_id', 3); }); - // Produces: OR "id" NOT IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3) // With builder directly diff --git a/user_guide_src/source/database/query_builder/078.php b/user_guide_src/source/database/query_builder/078.php index e4ddf03e6732..ed0e4cb3f7a1 100644 --- a/user_guide_src/source/database/query_builder/078.php +++ b/user_guide_src/source/database/query_builder/078.php @@ -8,5 +8,4 @@ $sql = $builder->set($data)->getCompiledInsert(); echo $sql; - // Produces string: INSERT INTO mytable (`title`, `name`, `date`) VALUES ('My title', 'My name', 'My date') diff --git a/user_guide_src/source/database/query_builder/079.php b/user_guide_src/source/database/query_builder/079.php index 4e095f9e0c72..1807be1d706a 100644 --- a/user_guide_src/source/database/query_builder/079.php +++ b/user_guide_src/source/database/query_builder/079.php @@ -1,9 +1,7 @@ set('title', 'My Title')->getCompiledInsert(false); - // Produces string: INSERT INTO mytable (`title`) VALUES ('My Title') echo $builder->set('content', 'My Content')->getCompiledInsert(); - // Produces string: INSERT INTO mytable (`title`, `content`) VALUES ('My Title', 'My Content') diff --git a/user_guide_src/source/database/query_builder/081.php b/user_guide_src/source/database/query_builder/081.php index bb263a3b4eba..d4bd972f5830 100644 --- a/user_guide_src/source/database/query_builder/081.php +++ b/user_guide_src/source/database/query_builder/081.php @@ -7,5 +7,4 @@ ]; $builder->replace($data); - // Executes: REPLACE INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date') diff --git a/user_guide_src/source/database/query_builder/098.php b/user_guide_src/source/database/query_builder/098.php index e9be12b58273..a6fb3cc4beed 100644 --- a/user_guide_src/source/database/query_builder/098.php +++ b/user_guide_src/source/database/query_builder/098.php @@ -3,5 +3,4 @@ $subquery = $db->table('countries')->select('name')->where('id', 1); $builder = $db->table('users')->select('name')->selectSubquery($subquery, 'country'); $query = $builder->get(); - // Produces: SELECT `name`, (SELECT `name` FROM `countries` WHERE `id` = 1) AS `country` FROM `users` diff --git a/user_guide_src/source/extending/core_classes/002.php b/user_guide_src/source/extending/core_classes/002.php index 1d0de27ee238..68d22ff508b8 100644 --- a/user_guide_src/source/extending/core_classes/002.php +++ b/user_guide_src/source/extending/core_classes/002.php @@ -14,5 +14,6 @@ public static function routes(bool $getShared = true) return new \App\Libraries\RouteCollection(static::locator(), config('Modules')); } + // ... } diff --git a/user_guide_src/source/general/configuration/008.php b/user_guide_src/source/general/configuration/008.php index 86749331c9c5..752084b65072 100644 --- a/user_guide_src/source/general/configuration/008.php +++ b/user_guide_src/source/general/configuration/008.php @@ -7,5 +7,6 @@ class MyConfig extends BaseConfig public static $registrars = [ SupportingPackageRegistrar::class, ]; + // ... } diff --git a/user_guide_src/source/general/logging/002.php b/user_guide_src/source/general/logging/002.php index 1c27f2410126..7a1e4e97fde5 100644 --- a/user_guide_src/source/general/logging/002.php +++ b/user_guide_src/source/general/logging/002.php @@ -7,5 +7,6 @@ class Logger extends BaseConfig { public $threshold = 5; + // ... } diff --git a/user_guide_src/source/general/logging/003.php b/user_guide_src/source/general/logging/003.php index 170b74457967..926e04a017de 100644 --- a/user_guide_src/source/general/logging/003.php +++ b/user_guide_src/source/general/logging/003.php @@ -8,5 +8,6 @@ class Logger extends BaseConfig { // Log only debug and info type messages public $threshold = [5, 8]; + // ... } diff --git a/user_guide_src/source/general/logging/004.php b/user_guide_src/source/general/logging/004.php index ff5f9511d81f..7691936b3165 100644 --- a/user_guide_src/source/general/logging/004.php +++ b/user_guide_src/source/general/logging/004.php @@ -12,5 +12,6 @@ class Logger extends BaseConfig 'handles' => ['critical', 'alert', 'emergency', 'debug', 'error', 'info', 'notice', 'warning'], ], ]; + // ... } diff --git a/user_guide_src/source/general/managing_apps/001.php b/user_guide_src/source/general/managing_apps/001.php index 2d0690cabc41..c116317678be 100644 --- a/user_guide_src/source/general/managing_apps/001.php +++ b/user_guide_src/source/general/managing_apps/001.php @@ -5,5 +5,6 @@ class Paths { public $appDirectory = '/path/to/your/app'; + // ... } diff --git a/user_guide_src/source/incoming/filters/003.php b/user_guide_src/source/incoming/filters/003.php index 060f5957b5cc..2e7770e88ddd 100644 --- a/user_guide_src/source/incoming/filters/003.php +++ b/user_guide_src/source/incoming/filters/003.php @@ -9,5 +9,6 @@ class Filters extends BaseConfig public $aliases = [ 'csrf' => \CodeIgniter\Filters\CSRF::class, ]; + // ... } diff --git a/user_guide_src/source/incoming/filters/004.php b/user_guide_src/source/incoming/filters/004.php index d39de5a0bee8..c645d9f8191d 100644 --- a/user_guide_src/source/incoming/filters/004.php +++ b/user_guide_src/source/incoming/filters/004.php @@ -12,5 +12,6 @@ class Filters extends BaseConfig \App\Filters\ApiAuth::class, ], ]; + // ... } diff --git a/user_guide_src/source/incoming/filters/005.php b/user_guide_src/source/incoming/filters/005.php index 55b7d1fa522b..226db2389c58 100644 --- a/user_guide_src/source/incoming/filters/005.php +++ b/user_guide_src/source/incoming/filters/005.php @@ -12,5 +12,6 @@ class Filters extends BaseConfig ], 'after' => [], ]; + // ... } diff --git a/user_guide_src/source/incoming/filters/006.php b/user_guide_src/source/incoming/filters/006.php index ed7ce0a8a120..bfddf66c3c4e 100644 --- a/user_guide_src/source/incoming/filters/006.php +++ b/user_guide_src/source/incoming/filters/006.php @@ -12,5 +12,6 @@ class Filters extends BaseConfig ], 'after' => [], ]; + // ... } diff --git a/user_guide_src/source/incoming/filters/007.php b/user_guide_src/source/incoming/filters/007.php index fa79b5bbb7c8..d7f21efa1344 100644 --- a/user_guide_src/source/incoming/filters/007.php +++ b/user_guide_src/source/incoming/filters/007.php @@ -12,5 +12,6 @@ class Filters extends BaseConfig ], 'after' => [], ]; + // ... } diff --git a/user_guide_src/source/incoming/filters/008.php b/user_guide_src/source/incoming/filters/008.php index a37967a538c0..1d99d0226a79 100644 --- a/user_guide_src/source/incoming/filters/008.php +++ b/user_guide_src/source/incoming/filters/008.php @@ -10,5 +10,6 @@ class Filters extends BaseConfig 'post' => ['foo', 'bar'], 'get' => ['baz'], ]; + // ... } diff --git a/user_guide_src/source/incoming/filters/009.php b/user_guide_src/source/incoming/filters/009.php index bfc7d6176b77..162af6dcbaec 100644 --- a/user_guide_src/source/incoming/filters/009.php +++ b/user_guide_src/source/incoming/filters/009.php @@ -10,5 +10,6 @@ class Filters extends BaseConfig 'foo' => ['before' => ['admin/*'], 'after' => ['users/*']], 'bar' => ['before' => ['api/*', 'admin/*']], ]; + // ... } diff --git a/user_guide_src/source/incoming/filters/011.php b/user_guide_src/source/incoming/filters/011.php index 8b6e24c5fe91..fa12db31a9e7 100644 --- a/user_guide_src/source/incoming/filters/011.php +++ b/user_guide_src/source/incoming/filters/011.php @@ -10,5 +10,6 @@ class Filters extends BaseConfig // ... 'secureheaders' => \App\Filters\SecureHeaders::class, ]; + // ... } diff --git a/user_guide_src/source/libraries/caching/013.php b/user_guide_src/source/libraries/caching/013.php index 3dd8ff740944..84287d5e7bcb 100644 --- a/user_guide_src/source/libraries/caching/013.php +++ b/user_guide_src/source/libraries/caching/013.php @@ -7,11 +7,13 @@ class Cache extends BaseConfig { // ... + public $memcached = [ 'host' => '127.0.0.1', 'port' => 11211, 'weight' => 1, 'raw' => false, ]; + // ... } diff --git a/user_guide_src/source/libraries/caching/014.php b/user_guide_src/source/libraries/caching/014.php index cfb6eeb6698f..6b0012696bf3 100644 --- a/user_guide_src/source/libraries/caching/014.php +++ b/user_guide_src/source/libraries/caching/014.php @@ -15,5 +15,6 @@ class Cache extends BaseConfig 'timeout' => 0, 'database' => 0, ]; + // ... } diff --git a/user_guide_src/source/libraries/curlrequest/001.php b/user_guide_src/source/libraries/curlrequest/001.php index 35486f4e7971..e89e0692462f 100644 --- a/user_guide_src/source/libraries/curlrequest/001.php +++ b/user_guide_src/source/libraries/curlrequest/001.php @@ -7,5 +7,6 @@ class CURLRequest extends BaseConfig { public $shareOptions = false; + // ... } diff --git a/user_guide_src/source/libraries/encryption/008.php b/user_guide_src/source/libraries/encryption/008.php index 506a5d594c4e..0fe44575e8db 100644 --- a/user_guide_src/source/libraries/encryption/008.php +++ b/user_guide_src/source/libraries/encryption/008.php @@ -8,7 +8,6 @@ class Encryption extends BaseConfig { // In Encryption, you may use public $key = 'hex2bin:'; - // or public $key = 'base64:'; // ... diff --git a/user_guide_src/source/libraries/honeypot/001.php b/user_guide_src/source/libraries/honeypot/001.php index 8463a919d54a..f0dbf7e64d57 100644 --- a/user_guide_src/source/libraries/honeypot/001.php +++ b/user_guide_src/source/libraries/honeypot/001.php @@ -16,5 +16,6 @@ class Filters extends BaseConfig 'honeypot', ], ]; + // ... } diff --git a/user_guide_src/source/libraries/pagination/010.php b/user_guide_src/source/libraries/pagination/010.php index d168163446ee..86947793c132 100644 --- a/user_guide_src/source/libraries/pagination/010.php +++ b/user_guide_src/source/libraries/pagination/010.php @@ -10,5 +10,6 @@ class Pager extends BaseConfig 'default_full' => 'CodeIgniter\Pager\Views\default_full', 'default_simple' => 'CodeIgniter\Pager\Views\default_simple', ]; + // ... } diff --git a/user_guide_src/source/libraries/pagination/011.php b/user_guide_src/source/libraries/pagination/011.php index 4302997f8bff..6c15797754e0 100644 --- a/user_guide_src/source/libraries/pagination/011.php +++ b/user_guide_src/source/libraries/pagination/011.php @@ -11,5 +11,6 @@ class Pager extends BaseConfig 'default_simple' => 'CodeIgniter\Pager\Views\default_simple', 'front_full' => 'App\Views\Pagers\foundation_full', ]; + // ... } diff --git a/user_guide_src/source/libraries/security/002.php b/user_guide_src/source/libraries/security/002.php index 39df6fa8d292..d7af0b687f0b 100644 --- a/user_guide_src/source/libraries/security/002.php +++ b/user_guide_src/source/libraries/security/002.php @@ -7,5 +7,6 @@ class Security extends BaseConfig { public $csrfProtection = 'session'; + // ... } diff --git a/user_guide_src/source/libraries/security/003.php b/user_guide_src/source/libraries/security/003.php index 7d8b3241c285..f092196845a4 100644 --- a/user_guide_src/source/libraries/security/003.php +++ b/user_guide_src/source/libraries/security/003.php @@ -7,5 +7,6 @@ class Security extends BaseConfig { public $tokenRandomize = true; + // ... } diff --git a/user_guide_src/source/libraries/security/004.php b/user_guide_src/source/libraries/security/004.php index 7187a1b523c5..ff5c6cca8b06 100644 --- a/user_guide_src/source/libraries/security/004.php +++ b/user_guide_src/source/libraries/security/004.php @@ -7,5 +7,6 @@ class Security extends BaseConfig { public $regenerate = true; + // ... } diff --git a/user_guide_src/source/libraries/security/006.php b/user_guide_src/source/libraries/security/006.php index cc3ef9d162c6..9105bc43dd80 100644 --- a/user_guide_src/source/libraries/security/006.php +++ b/user_guide_src/source/libraries/security/006.php @@ -12,5 +12,6 @@ class Filters extends BaseConfig 'csrf', ], ]; + // ... } diff --git a/user_guide_src/source/libraries/security/007.php b/user_guide_src/source/libraries/security/007.php index 0b099addb52c..437bc7bfbead 100644 --- a/user_guide_src/source/libraries/security/007.php +++ b/user_guide_src/source/libraries/security/007.php @@ -11,5 +11,6 @@ class Filters extends BaseConfig 'csrf' => ['except' => ['api/record/save']], ], ]; + // ... } diff --git a/user_guide_src/source/libraries/security/008.php b/user_guide_src/source/libraries/security/008.php index 370bd2bcedad..8a4a6ef4d430 100644 --- a/user_guide_src/source/libraries/security/008.php +++ b/user_guide_src/source/libraries/security/008.php @@ -11,5 +11,6 @@ class Filters extends BaseConfig 'csrf' => ['except' => ['api/record/[0-9]+']], ], ]; + // ... } diff --git a/user_guide_src/source/libraries/security/009.php b/user_guide_src/source/libraries/security/009.php index d90632e53f1c..bd6bc93cfeb6 100644 --- a/user_guide_src/source/libraries/security/009.php +++ b/user_guide_src/source/libraries/security/009.php @@ -10,5 +10,6 @@ class Filters extends BaseConfig 'get' => ['csrf'], 'post' => ['csrf'], ]; + // ... } diff --git a/user_guide_src/source/libraries/sessions/010.php b/user_guide_src/source/libraries/sessions/010.php index fd3471eba73e..4bbbfb2646db 100644 --- a/user_guide_src/source/libraries/sessions/010.php +++ b/user_guide_src/source/libraries/sessions/010.php @@ -1,7 +1,5 @@ get(); diff --git a/user_guide_src/source/libraries/sessions/017.php b/user_guide_src/source/libraries/sessions/017.php index 66a5f8662b39..2b00df65a034 100644 --- a/user_guide_src/source/libraries/sessions/017.php +++ b/user_guide_src/source/libraries/sessions/017.php @@ -1,9 +1,7 @@ destroy(); diff --git a/user_guide_src/source/libraries/sessions/044.php b/user_guide_src/source/libraries/sessions/044.php index 2cc31e9035db..e5fab8602236 100644 --- a/user_guide_src/source/libraries/sessions/044.php +++ b/user_guide_src/source/libraries/sessions/044.php @@ -9,5 +9,6 @@ class App extends BaseConfig // localhost will be given higher priority (5) here, // compared to 192.0.2.1 with a weight of 1. public $sessionSavePath = 'localhost:11211:5,192.0.2.1:11211:1'; + // ... } diff --git a/user_guide_src/source/libraries/throttler/003.php b/user_guide_src/source/libraries/throttler/003.php index ae13441bb8ad..b365df88fa53 100644 --- a/user_guide_src/source/libraries/throttler/003.php +++ b/user_guide_src/source/libraries/throttler/003.php @@ -10,5 +10,6 @@ class Filters extends BaseConfig // ... 'throttle' => \App\Filters\Throttle::class, ]; + // ... } diff --git a/user_guide_src/source/libraries/throttler/004.php b/user_guide_src/source/libraries/throttler/004.php index 077cb46a66dc..ab4d91257f8f 100644 --- a/user_guide_src/source/libraries/throttler/004.php +++ b/user_guide_src/source/libraries/throttler/004.php @@ -9,5 +9,6 @@ class Filters extends BaseConfig public $methods = [ 'post' => ['throttle'], ]; + // ... } diff --git a/user_guide_src/source/libraries/validation/003.php b/user_guide_src/source/libraries/validation/003.php index fbcbb7690260..d27270810429 100644 --- a/user_guide_src/source/libraries/validation/003.php +++ b/user_guide_src/source/libraries/validation/003.php @@ -10,5 +10,6 @@ class Validation \CodeIgniter\Validation\StrictRules\FormatRules::class, \CodeIgniter\Validation\StrictRules\Rules::class, ]; + // ... } diff --git a/user_guide_src/source/libraries/validation/013.php b/user_guide_src/source/libraries/validation/013.php index 4e2982d7564f..671b5386fe98 100644 --- a/user_guide_src/source/libraries/validation/013.php +++ b/user_guide_src/source/libraries/validation/013.php @@ -10,5 +10,6 @@ class Validation 'pass_confirm' => 'required|matches[password]', 'email' => 'required|valid_email', ]; + // ... } diff --git a/user_guide_src/source/libraries/validation/015.php b/user_guide_src/source/libraries/validation/015.php index 46ef2c4431a1..5815abfaccf4 100644 --- a/user_guide_src/source/libraries/validation/015.php +++ b/user_guide_src/source/libraries/validation/015.php @@ -10,6 +10,7 @@ class Validation 'pass_confirm' => 'required|matches[password]', 'email' => 'required|valid_email', ]; + public $signup_errors = [ 'username' => [ 'required' => 'You must choose a username.', @@ -18,5 +19,6 @@ class Validation 'valid_email' => 'Please check the Email field. It does not appear to be valid.', ], ]; + // ... } diff --git a/user_guide_src/source/libraries/validation/031.php b/user_guide_src/source/libraries/validation/031.php index 7ed5d307b0e2..acec3cfc6ba2 100644 --- a/user_guide_src/source/libraries/validation/031.php +++ b/user_guide_src/source/libraries/validation/031.php @@ -9,5 +9,6 @@ class Validation 'single' => 'CodeIgniter\Validation\Views\single', 'my_list' => '_errors_list', ]; + // ... } diff --git a/user_guide_src/source/libraries/validation/032.php b/user_guide_src/source/libraries/validation/032.php index 5f16ca283c1e..890b4c453fc0 100644 --- a/user_guide_src/source/libraries/validation/032.php +++ b/user_guide_src/source/libraries/validation/032.php @@ -15,5 +15,6 @@ class Validation FileRules::class, CreditCardRules::class, ]; + // ... } diff --git a/user_guide_src/source/outgoing/api_responses/003.php b/user_guide_src/source/outgoing/api_responses/003.php index eebb83c43fc1..6e99762ccaed 100644 --- a/user_guide_src/source/outgoing/api_responses/003.php +++ b/user_guide_src/source/outgoing/api_responses/003.php @@ -10,5 +10,6 @@ class Format extends BaseConfig 'application/json', 'application/xml', ]; + // ... } diff --git a/user_guide_src/source/outgoing/api_responses/004.php b/user_guide_src/source/outgoing/api_responses/004.php index 57532911f13b..713d1b314dce 100644 --- a/user_guide_src/source/outgoing/api_responses/004.php +++ b/user_guide_src/source/outgoing/api_responses/004.php @@ -10,5 +10,6 @@ class Format extends BaseConfig 'application/json' => \CodeIgniter\Format\JSONFormatter::class, 'application/xml' => \CodeIgniter\Format\XMLFormatter::class, ]; + // ... } diff --git a/user_guide_src/source/outgoing/localization/001.php b/user_guide_src/source/outgoing/localization/001.php index ebc1e57ef45c..6978e6fb35e7 100644 --- a/user_guide_src/source/outgoing/localization/001.php +++ b/user_guide_src/source/outgoing/localization/001.php @@ -7,5 +7,6 @@ class App extends BaseConfig { public $defaultLocale = 'en'; + // ... } diff --git a/user_guide_src/source/outgoing/localization/002.php b/user_guide_src/source/outgoing/localization/002.php index 6a0cce0ea027..bb4941fd2c14 100644 --- a/user_guide_src/source/outgoing/localization/002.php +++ b/user_guide_src/source/outgoing/localization/002.php @@ -7,5 +7,6 @@ class App extends BaseConfig { public $negotiateLocale = true; + // ... } diff --git a/user_guide_src/source/outgoing/localization/003.php b/user_guide_src/source/outgoing/localization/003.php index 81aa073152a0..36ccb2344557 100644 --- a/user_guide_src/source/outgoing/localization/003.php +++ b/user_guide_src/source/outgoing/localization/003.php @@ -7,5 +7,6 @@ class App extends BaseConfig { public $supportedLocales = ['en', 'es', 'fr-FR']; + // ... } diff --git a/user_guide_src/source/outgoing/response/011.php b/user_guide_src/source/outgoing/response/011.php index 2ad152a51755..4a21b5c29078 100644 --- a/user_guide_src/source/outgoing/response/011.php +++ b/user_guide_src/source/outgoing/response/011.php @@ -7,5 +7,6 @@ class App extends BaseConfig { public $CSPEnabled = true; + // ... } diff --git a/user_guide_src/source/outgoing/view_decorators/002.php b/user_guide_src/source/outgoing/view_decorators/002.php index 6bd050126f90..ba56ea1e80ad 100644 --- a/user_guide_src/source/outgoing/view_decorators/002.php +++ b/user_guide_src/source/outgoing/view_decorators/002.php @@ -9,5 +9,6 @@ class View extends BaseView public array $decorators = [ 'App\Views\Decorators\MyDecorator', ]; + // ... } diff --git a/user_guide_src/source/outgoing/view_parser/005.php b/user_guide_src/source/outgoing/view_parser/005.php index 6681b588d74e..e77c54268648 100644 --- a/user_guide_src/source/outgoing/view_parser/005.php +++ b/user_guide_src/source/outgoing/view_parser/005.php @@ -4,5 +4,4 @@ $data = ['blog_title' => 'My ramblings']; echo $parser->setData($data)->renderString($template); - // Result: My ramblings diff --git a/user_guide_src/source/outgoing/view_parser/012.php b/user_guide_src/source/outgoing/view_parser/012.php index a006a51d5c33..000642837149 100644 --- a/user_guide_src/source/outgoing/view_parser/012.php +++ b/user_guide_src/source/outgoing/view_parser/012.php @@ -10,5 +10,6 @@ class View extends BaseView 'abs' => '\CodeIgniter\View\Filters::abs', 'capitalize' => '\CodeIgniter\View\Filters::capitalize', ]; + // ... } diff --git a/user_guide_src/source/outgoing/view_parser/013.php b/user_guide_src/source/outgoing/view_parser/013.php index c45a72b89bde..e5546bdda272 100644 --- a/user_guide_src/source/outgoing/view_parser/013.php +++ b/user_guide_src/source/outgoing/view_parser/013.php @@ -9,5 +9,6 @@ class View extends BaseView public $filters = [ 'str_repeat' => '\str_repeat', ]; + // ... } diff --git a/user_guide_src/source/outgoing/view_parser/014.php b/user_guide_src/source/outgoing/view_parser/014.php index 866a547e3b28..5153c4ee6757 100644 --- a/user_guide_src/source/outgoing/view_parser/014.php +++ b/user_guide_src/source/outgoing/view_parser/014.php @@ -9,5 +9,6 @@ class View extends BaseView public $plugins = [ 'foo' => '\Some\Class::methodName', ]; + // ... } diff --git a/user_guide_src/source/outgoing/view_parser/015.php b/user_guide_src/source/outgoing/view_parser/015.php index ecfafffbf97a..e499e9805416 100644 --- a/user_guide_src/source/outgoing/view_parser/015.php +++ b/user_guide_src/source/outgoing/view_parser/015.php @@ -16,5 +16,6 @@ public function __construct() parent::__construct(); } + // ... } diff --git a/user_guide_src/source/outgoing/view_parser/017.php b/user_guide_src/source/outgoing/view_parser/017.php index 1042665a0fcf..d9427bde4bf4 100644 --- a/user_guide_src/source/outgoing/view_parser/017.php +++ b/user_guide_src/source/outgoing/view_parser/017.php @@ -9,6 +9,7 @@ class View extends BaseView public $plugins = [ 'foo' => ['\Some\Class::methodName'], ]; + // ... } diff --git a/user_guide_src/source/outgoing/view_parser/018.php b/user_guide_src/source/outgoing/view_parser/018.php index cd9ca09109b9..64101a6a8cfa 100644 --- a/user_guide_src/source/outgoing/view_parser/018.php +++ b/user_guide_src/source/outgoing/view_parser/018.php @@ -8,5 +8,4 @@ ]; echo $parser->setData($data) ->renderString($template); - // Result: Hello, John Doe diff --git a/user_guide_src/source/outgoing/view_parser/019.php b/user_guide_src/source/outgoing/view_parser/019.php index dfce0c26ccb4..2570076b3018 100644 --- a/user_guide_src/source/outgoing/view_parser/019.php +++ b/user_guide_src/source/outgoing/view_parser/019.php @@ -8,5 +8,4 @@ ]; echo $parser->setData($data) ->renderString($template); - // Result: Hello, John {initials} Doe diff --git a/user_guide_src/source/outgoing/view_parser/020.php b/user_guide_src/source/outgoing/view_parser/020.php index 371fa9a21f14..a7966a9c2bfd 100644 --- a/user_guide_src/source/outgoing/view_parser/020.php +++ b/user_guide_src/source/outgoing/view_parser/020.php @@ -12,5 +12,4 @@ ]; echo $parser->setData($data) ->renderString($template); - // Result: Hello, John Doe (Mr{degree} {/degrees}) diff --git a/user_guide_src/source/testing/controllers/012.php b/user_guide_src/source/testing/controllers/012.php index 620bdb363c6e..e94476c6364a 100644 --- a/user_guide_src/source/testing/controllers/012.php +++ b/user_guide_src/source/testing/controllers/012.php @@ -15,5 +15,6 @@ protected function testFilterFailsOnAdminRoute() $this->assertHasFilters('unfiltered/route', 'before'); } + // ... } diff --git a/user_guide_src/source/testing/overview/007.php b/user_guide_src/source/testing/overview/007.php index dec488ef2e5e..6193eb88bf50 100644 --- a/user_guide_src/source/testing/overview/007.php +++ b/user_guide_src/source/testing/overview/007.php @@ -7,6 +7,7 @@ protected function setUpAuthTrait() $user = $this->createFakeUser(); $this->logInUser($user); } + // ... } diff --git a/user_guide_src/source/tutorial/create_news_items/001.php b/user_guide_src/source/tutorial/create_news_items/001.php index c63e033af0bf..4e6615b6bbda 100644 --- a/user_guide_src/source/tutorial/create_news_items/001.php +++ b/user_guide_src/source/tutorial/create_news_items/001.php @@ -9,5 +9,6 @@ class Filters extends BaseConfig public $methods = [ 'post' => ['csrf'], ]; + // ... } From 2854d99655d74450bb23d66daf78a42e724d36b8 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 4 Mar 2022 17:00:23 +0900 Subject: [PATCH 0650/1246] docs: change comment style to `*` each line --- .../source/cli/cli_commands/007.php | 9 +++--- user_guide_src/source/cli/cli_library/007.php | 15 ++++----- user_guide_src/source/cli/cli_library/008.php | 15 ++++----- .../source/database/query_builder/003.php | 6 ++-- .../source/database/query_builder/006.php | 10 +++--- .../source/database/query_builder/018.php | 6 ++-- .../source/database/query_builder/074.php | 6 ++-- .../source/database/query_builder/087.php | 10 +++--- .../source/database/query_builder/088.php | 10 +++--- .../source/database/query_builder/091.php | 22 ++++++------- .../source/database/query_builder/093.php | 8 ++--- .../source/database/query_builder/095.php | 6 ++-- .../source/database/query_builder/097.php | 6 ++-- user_guide_src/source/dbmgmt/forge/004.php | 6 ++-- .../source/helpers/array_helper/011.php | 18 +++++------ .../source/helpers/form_helper/010.php | 10 +++--- .../source/helpers/form_helper/011.php | 10 +++--- .../source/helpers/form_helper/012.php | 6 ++-- .../source/helpers/form_helper/014.php | 6 ++-- .../source/helpers/form_helper/017.php | 6 ++-- .../source/helpers/form_helper/018.php | 32 +++++++++---------- .../source/helpers/text_helper/020.php | 16 +++++----- .../source/incoming/controllers/005.php | 5 ++- .../source/incoming/incomingrequest/010.php | 16 +++++----- .../source/incoming/incomingrequest/013.php | 13 ++++---- .../source/incoming/incomingrequest/015.php | 15 ++++----- .../source/incoming/message/003.php | 27 +++++++--------- .../source/incoming/message/005.php | 7 ++-- .../source/libraries/curlrequest/014.php | 10 +++--- user_guide_src/source/libraries/uri/026.php | 15 ++++----- .../source/libraries/validation/009.php | 30 ++++++++--------- .../source/libraries/validation/011.php | 18 +++++------ .../source/libraries/validation/026.php | 12 +++---- .../source/libraries/validation/028.2.php | 12 +++---- user_guide_src/source/models/entities/021.php | 20 ++++++------ .../source/outgoing/response/021.php | 6 ++-- .../source/outgoing/view_parser/016.php | 6 ++-- .../source/testing/benchmark/004.php | 18 +++++------ .../source/testing/response/030.php | 17 ++++------ .../source/testing/response/032.php | 11 +++---- 40 files changed, 241 insertions(+), 256 deletions(-) diff --git a/user_guide_src/source/cli/cli_commands/007.php b/user_guide_src/source/cli/cli_commands/007.php index 3365e8afdd0e..76150e4d4e5c 100644 --- a/user_guide_src/source/cli/cli_commands/007.php +++ b/user_guide_src/source/cli/cli_commands/007.php @@ -5,9 +5,8 @@ foreach ($this->options as $option => $description) { CLI::write($tab . CLI::color(str_pad($option, $pad), 'green') . $description, 'yellow'); } - /* -Output will be: --n Set migration namespace --r override file -*/ + * Output will be: + * -n Set migration namespace + * -r override file + */ diff --git a/user_guide_src/source/cli/cli_library/007.php b/user_guide_src/source/cli/cli_library/007.php index 6d77ee91e4a0..0c9d257b1ecd 100644 --- a/user_guide_src/source/cli/cli_library/007.php +++ b/user_guide_src/source/cli/cli_library/007.php @@ -1,12 +1,11 @@ 'The plump orange', 'banana' => 'The ripe banana' ]); - /* -These are your choices: - [apple] The red apple - [orange] The plump orange - [banana] The ripe banana - -Which would you like? [apple, orange, banana]: -*/ + * These are your choices: + * [apple] The red apple + * [orange] The plump orange + * [banana] The ripe banana + * + * Which would you like? [apple, orange, banana]: + */ diff --git a/user_guide_src/source/database/query_builder/003.php b/user_guide_src/source/database/query_builder/003.php index b5300a358280..faad112895ba 100644 --- a/user_guide_src/source/database/query_builder/003.php +++ b/user_guide_src/source/database/query_builder/003.php @@ -2,6 +2,6 @@ $query = $builder->get(10, 20); /* -Executes: SELECT * FROM mytable LIMIT 20, 10 -(in MySQL. Other databases have slightly different syntax) -*/ + * Executes: SELECT * FROM mytable LIMIT 20, 10 + * (in MySQL. Other databases have slightly different syntax) + */ diff --git a/user_guide_src/source/database/query_builder/006.php b/user_guide_src/source/database/query_builder/006.php index 2d672d5ce9ce..78a92e7b7b9d 100644 --- a/user_guide_src/source/database/query_builder/006.php +++ b/user_guide_src/source/database/query_builder/006.php @@ -2,11 +2,11 @@ echo $builder->limit(10,20)->getCompiledSelect(false); /* -Prints string: SELECT * FROM mytable LIMIT 20, 10 -(in MySQL. Other databases have slightly different syntax) -*/ + * Prints string: SELECT * FROM mytable LIMIT 20, 10 + * (in MySQL. Other databases have slightly different syntax) + */ echo $builder->select('title, content, date')->getCompiledSelect(); /* -Prints string: SELECT title, content, date FROM mytable LIMIT 20, 10 -*/ + * Prints string: SELECT title, content, date FROM mytable LIMIT 20, 10 + */ diff --git a/user_guide_src/source/database/query_builder/018.php b/user_guide_src/source/database/query_builder/018.php index 17465bd1cb43..159f88e4a984 100644 --- a/user_guide_src/source/database/query_builder/018.php +++ b/user_guide_src/source/database/query_builder/018.php @@ -5,6 +5,6 @@ $builder->join('comments', 'comments.id = blogs.id'); $query = $builder->get(); /* -Produces: -SELECT * FROM blogs JOIN comments ON comments.id = blogs.id -*/ + * Produces: + * SELECT * FROM blogs JOIN comments ON comments.id = blogs.id + */ diff --git a/user_guide_src/source/database/query_builder/074.php b/user_guide_src/source/database/query_builder/074.php index 68fbcbb0bf60..d858451993a2 100644 --- a/user_guide_src/source/database/query_builder/074.php +++ b/user_guide_src/source/database/query_builder/074.php @@ -11,6 +11,6 @@ ->where('d', 'd') ->get(); /* -Generates: -SELECT * FROM (`my_table`) WHERE ( `a` = 'a' OR ( `b` = 'b' AND `c` = 'c' ) ) AND `d` = 'd' -*/ + * Generates: + * SELECT * FROM (`my_table`) WHERE ( `a` = 'a' OR ( `b` = 'b' AND `c` = 'c' ) ) AND `d` = 'd' + */ diff --git a/user_guide_src/source/database/query_builder/087.php b/user_guide_src/source/database/query_builder/087.php index 3032402a7c32..7869b4b4d966 100644 --- a/user_guide_src/source/database/query_builder/087.php +++ b/user_guide_src/source/database/query_builder/087.php @@ -9,8 +9,8 @@ $builder->where('id', $id); $builder->update($data); /* -Produces: -UPDATE mytable -SET title = '{$title}', name = '{$name}', date = '{$date}' -WHERE id = $id -*/ + * Produces: + * UPDATE mytable + * SET title = '{$title}', name = '{$name}', date = '{$date}' + * WHERE id = $id + */ diff --git a/user_guide_src/source/database/query_builder/088.php b/user_guide_src/source/database/query_builder/088.php index 37afb6ce2b46..ce38024e558d 100644 --- a/user_guide_src/source/database/query_builder/088.php +++ b/user_guide_src/source/database/query_builder/088.php @@ -11,8 +11,8 @@ class Myclass $builder->where('id', $id); $builder->update($object); /* -Produces: -UPDATE `mytable` -SET `title` = '{$title}', `name` = '{$name}', `date` = '{$date}' -WHERE id = `$id` -*/ + * Produces: + * UPDATE `mytable` + * SET `title` = '{$title}', `name` = '{$name}', `date` = '{$date}' + * WHERE id = `$id` + */ diff --git a/user_guide_src/source/database/query_builder/091.php b/user_guide_src/source/database/query_builder/091.php index a3943d41cfb9..56f04036cd6f 100644 --- a/user_guide_src/source/database/query_builder/091.php +++ b/user_guide_src/source/database/query_builder/091.php @@ -15,14 +15,14 @@ $builder->updateBatch($data, 'title'); /* -Produces: -UPDATE `mytable` SET `name` = CASE -WHEN `title` = 'My title' THEN 'My Name 2' -WHEN `title` = 'Another title' THEN 'Another Name 2' -ELSE `name` END, -`date` = CASE -WHEN `title` = 'My title' THEN 'My date 2' -WHEN `title` = 'Another title' THEN 'Another date 2' -ELSE `date` END -WHERE `title` IN ('My title','Another title') -*/ + * Produces: + * UPDATE `mytable` SET `name` = CASE + * WHEN `title` = 'My title' THEN 'My Name 2' + * WHEN `title` = 'Another title' THEN 'Another Name 2' + * ELSE `name` END, + * `date` = CASE + * WHEN `title` = 'My title' THEN 'My date 2' + * WHEN `title` = 'Another title' THEN 'Another date 2' + * ELSE `date` END + * WHERE `title` IN ('My title','Another title') + */ diff --git a/user_guide_src/source/database/query_builder/093.php b/user_guide_src/source/database/query_builder/093.php index 70e9ed3b7f69..f1ba27e29ef2 100644 --- a/user_guide_src/source/database/query_builder/093.php +++ b/user_guide_src/source/database/query_builder/093.php @@ -3,7 +3,7 @@ $builder->where('id', $id); $builder->delete(); /* -Produces: -DELETE FROM mytable -WHERE id = $id -*/ + * Produces: + * DELETE FROM mytable + * WHERE id = $id + */ diff --git a/user_guide_src/source/database/query_builder/095.php b/user_guide_src/source/database/query_builder/095.php index c2afc9fe3c2a..a6c0ab4fc069 100644 --- a/user_guide_src/source/database/query_builder/095.php +++ b/user_guide_src/source/database/query_builder/095.php @@ -2,6 +2,6 @@ $builder->truncate(); /* -Produce: -TRUNCATE mytable -*/ + * Produce: + * TRUNCATE mytable + */ diff --git a/user_guide_src/source/database/query_builder/097.php b/user_guide_src/source/database/query_builder/097.php index ec48b920e406..30c4d0c4526a 100644 --- a/user_guide_src/source/database/query_builder/097.php +++ b/user_guide_src/source/database/query_builder/097.php @@ -12,6 +12,6 @@ $data = $builder->get()->getResultArray(); /* -Would execute and return an array of results of the following query: -SELECT field1, field1 from mytable where field3 = 5; -*/ + * Would execute and return an array of results of the following query: + * SELECT field1, field1 from mytable where field3 = 5; + */ diff --git a/user_guide_src/source/dbmgmt/forge/004.php b/user_guide_src/source/dbmgmt/forge/004.php index d793fd8b82d8..6c44a8e553a0 100644 --- a/user_guide_src/source/dbmgmt/forge/004.php +++ b/user_guide_src/source/dbmgmt/forge/004.php @@ -2,6 +2,6 @@ $forge->createDatabase('my_db', true); /* -gives CREATE DATABASE IF NOT EXISTS `my_db` -or will check if a database exists -*/ + * gives CREATE DATABASE IF NOT EXISTS `my_db` + * or will check if a database exists + */ diff --git a/user_guide_src/source/helpers/array_helper/011.php b/user_guide_src/source/helpers/array_helper/011.php index 31ee64387979..c80dc01e0caa 100644 --- a/user_guide_src/source/helpers/array_helper/011.php +++ b/user_guide_src/source/helpers/array_helper/011.php @@ -3,12 +3,12 @@ // using the same data from above $flattened = array_flatten_with_dots($arrayToFlatten, 'foo_'); /* -$flattened is now: -[ - 'foo_personal.first_name' => 'john', - 'foo_personal.last_name' => 'smith', - 'foo_personal.age' => '26', - 'foo_personal.address' => 'US', - 'foo_other_details' => 'marines officer', -] -*/ + * $flattened is now: + * [ + * 'foo_personal.first_name' => 'john', + * 'foo_personal.last_name' => 'smith', + * 'foo_personal.age' => '26', + * 'foo_personal.address' => 'US', + * 'foo_other_details' => 'marines officer', + * ] + */ diff --git a/user_guide_src/source/helpers/form_helper/010.php b/user_guide_src/source/helpers/form_helper/010.php index 401a94c685b1..4edb9a0922c6 100644 --- a/user_guide_src/source/helpers/form_helper/010.php +++ b/user_guide_src/source/helpers/form_helper/010.php @@ -8,8 +8,8 @@ echo form_hidden($data); /* -Would produce: - - - -*/ + * Would produce: + * + * + * + */ diff --git a/user_guide_src/source/helpers/form_helper/011.php b/user_guide_src/source/helpers/form_helper/011.php index 6e28c61e8352..472793162640 100644 --- a/user_guide_src/source/helpers/form_helper/011.php +++ b/user_guide_src/source/helpers/form_helper/011.php @@ -8,8 +8,8 @@ echo form_hidden('my_array', $data); /* -Would produce: - - - -*/ + * Would produce: + * + * + * + */ diff --git a/user_guide_src/source/helpers/form_helper/012.php b/user_guide_src/source/helpers/form_helper/012.php index 4b232ba110f8..2d781ad3effd 100644 --- a/user_guide_src/source/helpers/form_helper/012.php +++ b/user_guide_src/source/helpers/form_helper/012.php @@ -10,6 +10,6 @@ echo form_input($data); /* -Would produce: - -*/ + * Would produce: + * + */ diff --git a/user_guide_src/source/helpers/form_helper/014.php b/user_guide_src/source/helpers/form_helper/014.php index cf8a20dbadff..d194b318d2dd 100644 --- a/user_guide_src/source/helpers/form_helper/014.php +++ b/user_guide_src/source/helpers/form_helper/014.php @@ -11,6 +11,6 @@ echo form_input($data); /* -Would produce: - -*/ + * Would produce: + * + */ diff --git a/user_guide_src/source/helpers/form_helper/017.php b/user_guide_src/source/helpers/form_helper/017.php index 99106e9b4fa8..fb73d427ba63 100644 --- a/user_guide_src/source/helpers/form_helper/017.php +++ b/user_guide_src/source/helpers/form_helper/017.php @@ -2,6 +2,6 @@ echo form_input('email', 'joe@example.com', ['placeholder' => 'Email Address...'], 'email'); /* -Would produce: - -*/ + * Would produce: + * + */ diff --git a/user_guide_src/source/helpers/form_helper/018.php b/user_guide_src/source/helpers/form_helper/018.php index 6e521ed04985..9177e4d3435d 100644 --- a/user_guide_src/source/helpers/form_helper/018.php +++ b/user_guide_src/source/helpers/form_helper/018.php @@ -10,22 +10,22 @@ $shirts_on_sale = ['small', 'large']; echo form_dropdown('shirts', $options, 'large'); /* -Would produce: - -*/ + * Would produce: + * + */ echo form_dropdown('shirts', $options, $shirts_on_sale); /* -Would produce: - -*/ + * Would produce: + * + */ diff --git a/user_guide_src/source/helpers/text_helper/020.php b/user_guide_src/source/helpers/text_helper/020.php index 4bd123f5ae8a..2a4f595f3655 100644 --- a/user_guide_src/source/helpers/text_helper/020.php +++ b/user_guide_src/source/helpers/text_helper/020.php @@ -3,11 +3,11 @@ $string = "Here is a simple string of text that will help us demonstrate this function."; echo word_wrap($string, 25); /* -Would produce: -Here is a simple string -of text that will help us -demonstrate this -function. - -Excessively long words will be split, but URLs will not be. -*/ + * Would produce: + * Here is a simple string + * of text that will help us + * demonstrate this + * function. + * + * Excessively long words will be split, but URLs will not be. + */ diff --git a/user_guide_src/source/incoming/controllers/005.php b/user_guide_src/source/incoming/controllers/005.php index 84b910be2507..efaecbb8f400 100644 --- a/user_guide_src/source/incoming/controllers/005.php +++ b/user_guide_src/source/incoming/controllers/005.php @@ -1,9 +1,8 @@ (\)*\ + * Folder and file structure: + * \(\)*\ */ $routes->get('helloworld', '\App\Controllers\HelloWorld::index'); diff --git a/user_guide_src/source/incoming/incomingrequest/010.php b/user_guide_src/source/incoming/incomingrequest/010.php index a1dc2ccfb9cd..a199c91bffe2 100644 --- a/user_guide_src/source/incoming/incomingrequest/010.php +++ b/user_guide_src/source/incoming/incomingrequest/010.php @@ -1,14 +1,14 @@ getVar('foo'); // $data = "bar" diff --git a/user_guide_src/source/incoming/incomingrequest/013.php b/user_guide_src/source/incoming/incomingrequest/013.php index bdb8b43b5206..483662cbfaf7 100644 --- a/user_guide_src/source/incoming/incomingrequest/013.php +++ b/user_guide_src/source/incoming/incomingrequest/013.php @@ -3,10 +3,9 @@ var_dump($request->getRawInput()); /* - Outputs: - - [ - 'Param1' => 'Value1', - 'Param2' => 'Value2', - ] -*/ + * Outputs: + * [ + * 'Param1' => 'Value1', + * 'Param2' => 'Value2', + * ] + */ diff --git a/user_guide_src/source/incoming/incomingrequest/015.php b/user_guide_src/source/incoming/incomingrequest/015.php index 95d483206211..81043ae80587 100644 --- a/user_guide_src/source/incoming/incomingrequest/015.php +++ b/user_guide_src/source/incoming/incomingrequest/015.php @@ -3,11 +3,10 @@ var_dump($request->headers()); /* - Outputs: - - [ - 'Host' => CodeIgniter\HTTP\Header, - 'Cache-Control' => CodeIgniter\HTTP\Header, - 'Accept' => CodeIgniter\HTTP\Header, - ] -*/ + * Outputs: + * [ + * 'Host' => CodeIgniter\HTTP\Header, + * 'Cache-Control' => CodeIgniter\HTTP\Header, + * 'Accept' => CodeIgniter\HTTP\Header, + * ] + */ diff --git a/user_guide_src/source/incoming/message/003.php b/user_guide_src/source/incoming/message/003.php index 41aa837fb49f..9d51f9a183ab 100644 --- a/user_guide_src/source/incoming/message/003.php +++ b/user_guide_src/source/incoming/message/003.php @@ -1,25 +1,22 @@ header('Accept-Language'); - /* - Outputs something like: - 'Accept-Language: en,en-US' -*/ + * Outputs something like: + * 'Accept-Language: en,en-US' + */ echo $message->header('Accept-Language')->getValue(); - /* - Outputs something like: - [ - 'en', - 'en-US' - ] -*/ + * Outputs something like: + * [ + * 'en', + * 'en-US', + * ] + */ echo $message->header('Accept-Language')->getValueLine(); - /* - Outputs something like: - 'en,en-US' -*/ + * Outputs something like: + * en,en-US' + */ diff --git a/user_guide_src/source/incoming/message/005.php b/user_guide_src/source/incoming/message/005.php index b67851a9258a..5c450073a340 100644 --- a/user_guide_src/source/incoming/message/005.php +++ b/user_guide_src/source/incoming/message/005.php @@ -1,8 +1,7 @@ getHeaderLine('Accept-Language'); - /* - Outputs: - 'en,en-US' -*/ + * Outputs: + * 'en,en-US' + */ diff --git a/user_guide_src/source/libraries/curlrequest/014.php b/user_guide_src/source/libraries/curlrequest/014.php index 2f7e79cc4be7..410ed9980e34 100644 --- a/user_guide_src/source/libraries/curlrequest/014.php +++ b/user_guide_src/source/libraries/curlrequest/014.php @@ -2,8 +2,8 @@ $client->request('GET', 'http://example.com', ['allow_redirects' => true]); /* -Sets the following defaults: -'max' => 5, // Maximum number of redirects to follow before stopping -'strict' => true, // Ensure POST requests stay POST requests through redirects -'protocols' => ['http', 'https'] // Restrict redirects to one or more protocols -*/ + * Sets the following defaults: + * 'max' => 5, // Maximum number of redirects to follow before stopping + * 'strict' => true, // Ensure POST requests stay POST requests through redirects + * 'protocols' => ['http', 'https'] // Restrict redirects to one or more protocols + */ diff --git a/user_guide_src/source/libraries/uri/026.php b/user_guide_src/source/libraries/uri/026.php index 60c076bc13cf..f2d8bb72553f 100644 --- a/user_guide_src/source/libraries/uri/026.php +++ b/user_guide_src/source/libraries/uri/026.php @@ -3,11 +3,10 @@ $segments = $uri->getSegments(); /* - Produces: - - [ - 0 => 'users', - 1 => '15', - 2 => 'profile', - ] -*/ + * Produces: + * [ + * 0 => 'users', + * 1 => '15', + * 2 => 'profile', + * ] + */ diff --git a/user_guide_src/source/libraries/validation/009.php b/user_guide_src/source/libraries/validation/009.php index 6f7ce8b9e992..58f0749a0c5d 100644 --- a/user_guide_src/source/libraries/validation/009.php +++ b/user_guide_src/source/libraries/validation/009.php @@ -1,21 +1,21 @@ [ - 'name' => 'Joe Smith', - 'friends' => [ - [ - 'name' => 'Fred Flinstone', - ], - [ - 'name' => 'Wilma', - ], - ] - ] -] -*/ + * The data to test: + * [ + * 'contacts' => [ + * 'name' => 'Joe Smith', + * 'friends' => [ + * [ + * 'name' => 'Fred Flinstone', + * ], + * [ + * 'name' => 'Wilma', + * ], + * ] + * ] + * ] + */ // Joe Smith $validation->setRules([ diff --git a/user_guide_src/source/libraries/validation/011.php b/user_guide_src/source/libraries/validation/011.php index fa5cad04369c..2754c41ac933 100644 --- a/user_guide_src/source/libraries/validation/011.php +++ b/user_guide_src/source/libraries/validation/011.php @@ -1,15 +1,15 @@ [ - 1, - 2, - 3, - ] -] -*/ + * The data to test: + * [ + * 'user_ids' => [ + * 1, + * 2, + * 3, + * ] + * ] + */ // Rule $validation->setRules([ diff --git a/user_guide_src/source/libraries/validation/026.php b/user_guide_src/source/libraries/validation/026.php index 4c27f4548b0e..4488f2a6be57 100644 --- a/user_guide_src/source/libraries/validation/026.php +++ b/user_guide_src/source/libraries/validation/026.php @@ -2,9 +2,9 @@ $errors = $validation->getErrors(); /* -Produces: -[ - 'field1' => 'error message', - 'field2' => 'error message', -] -*/ + * Produces: + * [ + * 'field1' => 'error message', + * 'field2' => 'error message', + * ] + */ diff --git a/user_guide_src/source/libraries/validation/028.2.php b/user_guide_src/source/libraries/validation/028.2.php index 34a4d7edefe3..5470a1eecea6 100644 --- a/user_guide_src/source/libraries/validation/028.2.php +++ b/user_guide_src/source/libraries/validation/028.2.php @@ -1,12 +1,12 @@ 'Error', - 'foo.baz.bar' => 'Error', -] -*/ + * For errors: + * [ + * 'foo.0.bar' => 'Error', + * 'foo.baz.bar' => 'Error', + * ] + */ // returns true $validation->hasError('foo.*.bar'); diff --git a/user_guide_src/source/models/entities/021.php b/user_guide_src/source/models/entities/021.php index ceb17247a908..1ea3a26de623 100644 --- a/user_guide_src/source/models/entities/021.php +++ b/user_guide_src/source/models/entities/021.php @@ -10,15 +10,15 @@ public static function get($value, array $params = []) { var_dump($params); /* - Output: - array(3) { - [0]=> - string(13) "App\SomeClass" - [1]=> - string(6) "param2" - [2]=> - string(6) "param3" - } - */ + * Output: + * array(3) { + * [0]=> + * string(13) "App\SomeClass" + * [1]=> + * string(6) "param2" + * [2]=> + * string(6) "param3" + * } + */ } } diff --git a/user_guide_src/source/outgoing/response/021.php b/user_guide_src/source/outgoing/response/021.php index 51abaf76bdbd..d5275cfb734e 100644 --- a/user_guide_src/source/outgoing/response/021.php +++ b/user_guide_src/source/outgoing/response/021.php @@ -2,6 +2,6 @@ $response->noCache(); /* -Sets the following header: -Cache-Control: no-store, max-age=0, no-cache -*/ + * Sets the following header: + * Cache-Control: no-store, max-age=0, no-cache + */ diff --git a/user_guide_src/source/outgoing/view_parser/016.php b/user_guide_src/source/outgoing/view_parser/016.php index 0c71e3f88fbb..5120c1eebf27 100644 --- a/user_guide_src/source/outgoing/view_parser/016.php +++ b/user_guide_src/source/outgoing/view_parser/016.php @@ -14,6 +14,6 @@ class View extends BaseView } /* -Tag is replaced by the return value of Some\Class::methodName() static function. -{+ foo +} -*/ + * Tag is replaced by the return value of Some\Class::methodName() static function. + * {+ foo +} + */ diff --git a/user_guide_src/source/testing/benchmark/004.php b/user_guide_src/source/testing/benchmark/004.php index 32dc5df31b1a..8a5c4d248837 100644 --- a/user_guide_src/source/testing/benchmark/004.php +++ b/user_guide_src/source/testing/benchmark/004.php @@ -2,12 +2,12 @@ $timers = $benchmark->getTimers(); /* -Produces: -[ - 'render view' => [ - 'start' => 1234567890, - 'end' => 1345678920, - 'duration' => 15.4315, // number of seconds - ] -] -*/ + * Produces: + * [ + * 'render view' => [ + * 'start' => 1234567890, + * 'end' => 1345678920, + * 'duration' => 15.4315, // number of seconds + * ] + * ] + */ diff --git a/user_guide_src/source/testing/response/030.php b/user_guide_src/source/testing/response/030.php index 060f5c551a87..47e480c6081f 100644 --- a/user_guide_src/source/testing/response/030.php +++ b/user_guide_src/source/testing/response/030.php @@ -1,17 +1,14 @@ 'bar'] -*/ + * Response body is this: + * ['foo' => 'bar'] + */ $json = $result->getJSON(); - /* - $json is this: - - { - "foo": "bar" - } + * $json is this: + * { + * "foo": "bar" + * } `*/ diff --git a/user_guide_src/source/testing/response/032.php b/user_guide_src/source/testing/response/032.php index 6de63a9cfce8..14f13f1942f5 100644 --- a/user_guide_src/source/testing/response/032.php +++ b/user_guide_src/source/testing/response/032.php @@ -1,12 +1,11 @@ ['key-a', 'key-b'], - ] -*/ + * Response body is this: + * [ + * 'config' => ['key-a', 'key-b'], + * ] + */ // Is true $result->assertJSONFragment(['config' => ['key-a']]); From a1e4f09527bb8b484e1a55a3b53e7319bb425316 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 4 Mar 2022 19:11:27 +0900 Subject: [PATCH 0651/1246] docs: fix parent classname --- user_guide_src/source/outgoing/localization/005.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/outgoing/localization/005.php b/user_guide_src/source/outgoing/localization/005.php index be23e05fac89..fa115d6cf3db 100644 --- a/user_guide_src/source/outgoing/localization/005.php +++ b/user_guide_src/source/outgoing/localization/005.php @@ -2,7 +2,7 @@ namespace App\Controllers; -class UserController extends \Controller +class UserController extends BaseController { public function index() { From 3ef6925e4f9fc7424e0f12b11bb0fa361457715d Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 4 Mar 2022 19:11:49 +0900 Subject: [PATCH 0652/1246] docs: add return type void --- user_guide_src/source/testing/database/002.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/user_guide_src/source/testing/database/002.php b/user_guide_src/source/testing/database/002.php index 4702f22d35ba..4b75aa739784 100644 --- a/user_guide_src/source/testing/database/002.php +++ b/user_guide_src/source/testing/database/002.php @@ -9,14 +9,14 @@ class MyTests extends CIUnitTestCase { use DatabaseTestTrait; - public function setUp() + public function setUp(): void { parent::setUp(); // Do something here.... } - public function tearDown() + public function tearDown(): void { parent::tearDown(); From 861f5100c89daa7c7b5a2332b68e8bec79b0cd4c Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 5 Mar 2022 08:37:53 +0900 Subject: [PATCH 0653/1246] docs: run php-cs-fixer php-cs-fixer fix --verbose --diff --config=.user-guide.php-cs-fixer.dist.php --- user_guide_src/source/cli/cli_library/004.php | 2 +- user_guide_src/source/cli/cli_library/008.php | 4 +-- user_guide_src/source/cli/cli_library/013.php | 2 +- user_guide_src/source/cli/cli_library/015.php | 2 +- user_guide_src/source/cli/cli_library/021.php | 2 +- .../source/concepts/autoloader/003.php | 2 +- .../source/database/call_function/004.php | 2 +- .../source/database/configuration/001.php | 2 +- .../source/database/configuration/005.php | 2 +- .../source/database/examples/006.php | 2 +- .../source/database/examples/008.php | 2 +- .../source/database/metadata/007.php | 2 +- .../source/database/queries/003.php | 4 +-- .../source/database/queries/009.php | 2 +- .../source/database/queries/011.php | 2 +- .../source/database/queries/012.php | 2 +- .../source/database/queries/013.php | 2 +- .../source/database/queries/014.php | 2 +- .../source/database/queries/016.php | 4 +-- .../source/database/queries/017.php | 4 +-- .../source/database/queries/018.php | 4 +-- .../source/database/queries/019.php | 4 +-- .../source/database/query_builder/006.php | 6 ++-- .../source/database/query_builder/016.php | 2 +- .../source/database/query_builder/017.php | 2 +- .../source/database/query_builder/026.php | 2 +- .../source/database/query_builder/027.php | 4 +-- .../source/database/query_builder/030.php | 4 +-- .../source/database/query_builder/032.php | 4 +-- .../source/database/query_builder/034.php | 4 +-- .../source/database/query_builder/036.php | 4 +-- .../source/database/query_builder/044.php | 2 +- .../source/database/query_builder/045.php | 2 +- .../source/database/query_builder/047.php | 2 +- .../source/database/query_builder/049.php | 4 +-- .../source/database/query_builder/051.php | 4 +-- .../source/database/query_builder/053.php | 6 ++-- .../source/database/query_builder/055.php | 6 ++-- .../source/database/query_builder/057.php | 6 ++-- .../source/database/query_builder/074.php | 12 +++---- .../source/database/query_builder/076.php | 2 +- .../source/database/query_builder/086.php | 2 +- .../source/database/query_builder/088.php | 2 +- .../source/database/query_builder/089.php | 2 +- .../source/database/query_builder/091.php | 20 ++++++------ .../source/database/query_builder/096.php | 6 ++-- .../source/database/query_builder/097.php | 6 ++-- .../source/database/query_builder/098.php | 2 +- .../source/database/results/001.php | 2 +- .../source/database/results/002.php | 2 +- .../source/database/results/003.php | 2 +- .../source/database/results/004.php | 2 +- .../source/database/results/005.php | 2 +- .../source/database/results/007.php | 4 +-- .../source/database/results/008.php | 2 +- .../source/database/results/010.php | 2 +- .../source/database/results/011.php | 7 ++-- .../source/database/results/013.php | 4 +-- .../source/database/results/014.php | 2 +- .../source/database/results/015.php | 2 +- .../source/database/utilities/001.php | 6 ++-- user_guide_src/source/dbmgmt/forge/007.php | 32 +++++++++---------- user_guide_src/source/dbmgmt/forge/022.php | 2 +- user_guide_src/source/dbmgmt/forge/023.php | 4 +-- .../source/dbmgmt/migration/001.php | 4 +-- .../source/dbmgmt/migration/002.php | 2 +- .../source/dbmgmt/migration/005.php | 3 +- user_guide_src/source/dbmgmt/seeds/001.php | 4 +-- .../source/extending/events/002.php | 3 +- .../source/extending/events/006.php | 2 +- .../source/general/common_functions/001.php | 2 +- .../source/general/common_functions/008.php | 4 +-- .../source/general/configuration/006.php | 4 +-- .../source/general/configuration/009.php | 4 +-- .../source/general/configuration/011.php | 2 +- user_guide_src/source/general/errors/001.php | 2 +- user_guide_src/source/general/errors/002.php | 2 +- user_guide_src/source/general/helpers/005.php | 2 +- user_guide_src/source/general/logging/005.php | 4 +-- user_guide_src/source/general/modules/001.php | 2 +- user_guide_src/source/general/modules/002.php | 2 +- user_guide_src/source/general/modules/003.php | 2 +- user_guide_src/source/general/modules/004.php | 2 +- user_guide_src/source/general/modules/007.php | 2 +- .../source/helpers/array_helper/002.php | 4 +-- .../source/helpers/array_helper/008.php | 6 ++-- .../source/helpers/filesystem_helper/010.php | 2 +- .../source/helpers/filesystem_helper/011.php | 2 +- .../source/helpers/form_helper/020.php | 2 +- .../source/helpers/form_helper/022.php | 4 +-- .../source/helpers/form_helper/025.php | 2 +- .../source/helpers/form_helper/029.php | 2 +- .../source/helpers/form_helper/031.php | 2 +- .../source/helpers/html_helper/011.php | 2 +- .../source/helpers/html_helper/013.php | 8 ++--- .../source/helpers/html_helper/014.php | 17 +++++----- .../source/helpers/html_helper/017.php | 2 +- .../source/helpers/text_helper/006.php | 2 +- .../source/helpers/text_helper/007.php | 4 +-- .../source/helpers/text_helper/008.php | 2 +- .../source/helpers/text_helper/009.php | 4 +-- .../source/helpers/text_helper/010.php | 4 +-- .../source/helpers/text_helper/011.php | 2 +- .../source/helpers/text_helper/012.php | 2 +- .../source/helpers/text_helper/013.php | 2 +- .../source/helpers/text_helper/014.php | 2 +- .../source/helpers/text_helper/019.php | 4 +-- .../source/helpers/text_helper/020.php | 2 +- .../source/incoming/filters/001.php | 2 +- .../source/incoming/incomingrequest/007.php | 2 +- .../source/incoming/incomingrequest/018.php | 2 +- .../source/incoming/incomingrequest/019.php | 2 +- .../source/incoming/restful/001.php | 14 ++++---- .../source/incoming/restful/002.php | 2 +- .../source/incoming/restful/003.php | 2 +- .../source/incoming/restful/009.php | 16 +++++----- .../source/incoming/restful/011.php | 2 +- .../source/incoming/restful/015.php | 1 - .../source/incoming/routing/002.php | 2 +- .../source/incoming/routing/016.php | 2 +- .../source/incoming/routing/019.php | 2 +- .../source/incoming/routing/020.php | 2 +- .../source/incoming/routing/021.php | 2 +- .../source/incoming/routing/022.php | 4 +-- .../source/incoming/routing/024.php | 2 +- .../source/incoming/routing/025.php | 2 +- .../source/incoming/routing/026.php | 2 +- .../source/incoming/routing/029.php | 2 +- .../source/incoming/routing/030.php | 2 +- .../source/incoming/routing/032.php | 2 +- .../source/incoming/routing/033.php | 2 +- .../source/incoming/routing/047.php | 3 +- .../installation/troubleshooting/001.php | 4 +-- .../installation/upgrade_database/002.php | 6 ++-- .../installation/upgrade_encryption/002.php | 2 +- .../installation/upgrade_file_upload/002.php | 8 ++--- .../installation/upgrade_localization/001.php | 4 +-- .../installation/upgrade_validations/001.php | 2 +- .../installation/upgrade_view_parser/002.php | 2 +- .../source/libraries/cookies/003.php | 2 +- .../source/libraries/curlrequest/003.php | 2 +- .../source/libraries/curlrequest/010.php | 2 +- .../source/libraries/curlrequest/015.php | 2 +- .../source/libraries/curlrequest/017.php | 2 +- user_guide_src/source/libraries/email/013.php | 5 ++- user_guide_src/source/libraries/email/022.php | 2 +- .../source/libraries/encryption/002.php | 2 +- .../source/libraries/encryption/005.php | 2 +- user_guide_src/source/libraries/files/004.php | 2 +- .../source/libraries/images/011.php | 2 +- .../source/libraries/images/014.php | 2 +- .../source/libraries/pagination/005.php | 2 +- .../source/libraries/publisher/005.php | 3 +- .../source/libraries/publisher/009.php | 2 -- .../source/libraries/publisher/010.php | 1 + .../source/libraries/sessions/014.php | 2 +- .../source/libraries/sessions/016.php | 2 +- .../source/libraries/sessions/029.php | 4 +-- user_guide_src/source/libraries/time/030.php | 2 +- .../source/libraries/uploaded_files/002.php | 7 ++-- .../source/libraries/uploaded_files/009.php | 2 +- user_guide_src/source/libraries/uri/023.php | 2 +- .../source/libraries/validation/002.php | 2 +- .../source/libraries/validation/004.php | 2 +- .../source/libraries/validation/021.php | 2 +- .../source/libraries/validation/023.php | 5 +-- .../source/libraries/validation/024.php | 5 +-- .../source/libraries/validation/025.php | 3 +- .../source/libraries/validation/030.php | 2 +- .../source/libraries/validation/033.php | 2 +- .../source/libraries/validation/036.php | 4 +-- .../source/libraries/validation/037.php | 8 ++--- user_guide_src/source/models/entities/003.php | 2 +- user_guide_src/source/models/entities/017.php | 2 +- user_guide_src/source/models/model/001.php | 2 +- user_guide_src/source/models/model/007.php | 2 +- user_guide_src/source/models/model/010.php | 2 +- user_guide_src/source/models/model/012.php | 2 +- user_guide_src/source/models/model/018.php | 2 +- user_guide_src/source/models/model/020.php | 4 +-- user_guide_src/source/models/model/022.php | 2 +- user_guide_src/source/models/model/024.php | 2 +- user_guide_src/source/models/model/028.php | 2 +- user_guide_src/source/models/model/029.php | 2 +- user_guide_src/source/models/model/030.php | 2 +- user_guide_src/source/models/model/039.php | 4 +-- user_guide_src/source/models/model/042.php | 4 +-- user_guide_src/source/models/model/045.php | 4 +-- user_guide_src/source/models/model/049.php | 2 +- .../source/outgoing/api_responses/007.php | 1 + .../source/outgoing/api_responses/008.php | 1 + .../source/outgoing/api_responses/009.php | 1 + .../source/outgoing/localization/007.php | 2 +- .../source/outgoing/localization/012.php | 2 +- .../source/outgoing/response/003.php | 2 +- .../source/outgoing/response/004.php | 2 +- .../source/outgoing/response/005.php | 2 +- .../source/outgoing/response/007.php | 1 + .../source/outgoing/response/010.php | 2 +- .../source/outgoing/response/013.php | 2 +- .../source/outgoing/response/016.php | 2 +- .../source/outgoing/response/023.php | 16 +++++----- user_guide_src/source/outgoing/table/005.php | 2 +- user_guide_src/source/outgoing/table/006.php | 32 +++++++++---------- user_guide_src/source/outgoing/table/007.php | 2 +- user_guide_src/source/outgoing/table/008.php | 2 +- user_guide_src/source/outgoing/table/016.php | 2 +- user_guide_src/source/outgoing/table/017.php | 2 +- .../source/outgoing/view_parser/003.php | 2 +- .../source/outgoing/view_parser/006.php | 2 +- .../source/outgoing/view_parser/007.php | 4 +-- .../source/outgoing/view_parser/008.php | 2 +- .../source/outgoing/view_parser/010.php | 4 +-- .../source/outgoing/view_parser/011.php | 2 +- .../source/outgoing/view_parser/015.php | 4 +-- .../source/outgoing/view_parser/018.php | 6 ++-- .../source/outgoing/view_parser/019.php | 4 +-- .../source/outgoing/view_parser/020.php | 4 +-- .../source/outgoing/view_parser/021.php | 10 +++--- .../source/outgoing/view_parser/025.php | 2 +- .../source/outgoing/view_parser/026.php | 2 +- .../source/outgoing/view_renderer/003.php | 4 +-- .../source/outgoing/view_renderer/007.php | 2 +- .../source/outgoing/view_renderer/008.php | 2 +- .../source/testing/benchmark/007.php | 6 ++-- .../source/testing/controllers/001.php | 5 +-- .../source/testing/controllers/002.php | 9 +++--- .../source/testing/controllers/004.php | 2 +- .../source/testing/controllers/005.php | 6 ++-- .../source/testing/controllers/006.php | 4 +-- .../source/testing/controllers/007.php | 4 +-- .../source/testing/controllers/008.php | 6 ++-- .../source/testing/controllers/009.php | 4 +-- .../source/testing/controllers/010.php | 4 +-- .../source/testing/database/002.php | 4 +-- .../source/testing/database/003.php | 2 +- .../source/testing/debugging/006.php | 2 +- .../source/testing/fabricator/009.php | 12 +++---- .../source/testing/fabricator/012.php | 16 +++++----- .../source/testing/fabricator/016.php | 24 +++++++------- .../source/testing/fabricator/018.php | 24 +++++++------- user_guide_src/source/testing/feature/001.php | 3 +- user_guide_src/source/testing/feature/002.php | 2 +- .../source/testing/overview/009.php | 2 +- .../source/testing/overview/010.php | 2 +- .../source/testing/overview/011.php | 2 +- 246 files changed, 442 insertions(+), 464 deletions(-) diff --git a/user_guide_src/source/cli/cli_library/004.php b/user_guide_src/source/cli/cli_library/004.php index 10a92407bcbd..7fae108cd3e7 100644 --- a/user_guide_src/source/cli/cli_library/004.php +++ b/user_guide_src/source/cli/cli_library/004.php @@ -1,3 +1,3 @@ 'The red apple', + 'apple' => 'The red apple', 'orange' => 'The plump orange', - 'banana' => 'The ripe banana' + 'banana' => 'The ripe banana', ]); /* * These are your choices: diff --git a/user_guide_src/source/cli/cli_library/013.php b/user_guide_src/source/cli/cli_library/013.php index cfbeb34a3ffa..64c5ad14f457 100644 --- a/user_guide_src/source/cli/cli_library/013.php +++ b/user_guide_src/source/cli/cli_library/013.php @@ -1,3 +1,3 @@ APPPATH . 'third_party/markdown.php' + 'Markdown' => APPPATH . 'third_party/markdown.php', ]; diff --git a/user_guide_src/source/database/call_function/004.php b/user_guide_src/source/database/call_function/004.php index 2739752f852d..0a8afc4199ef 100644 --- a/user_guide_src/source/database/call_function/004.php +++ b/user_guide_src/source/database/call_function/004.php @@ -1,5 +1,5 @@ query("SOME QUERY"); +$query = $db->query('SOME QUERY'); $query->resultID; diff --git a/user_guide_src/source/database/configuration/001.php b/user_guide_src/source/database/configuration/001.php index 5631cf7faede..eae7a19f2dab 100644 --- a/user_guide_src/source/database/configuration/001.php +++ b/user_guide_src/source/database/configuration/001.php @@ -24,6 +24,6 @@ class Database extends Config 'strictOn' => false, 'failover' => [], ]; - + // ... } diff --git a/user_guide_src/source/database/configuration/005.php b/user_guide_src/source/database/configuration/005.php index acc4a7b8db70..7e2da93f95d3 100644 --- a/user_guide_src/source/database/configuration/005.php +++ b/user_guide_src/source/database/configuration/005.php @@ -32,5 +32,5 @@ 'encrypt' => false, 'compress' => false, 'strictOn' => false, - ] + ], ]; diff --git a/user_guide_src/source/database/examples/006.php b/user_guide_src/source/database/examples/006.php index 1f7ac810d441..5f8843348c60 100644 --- a/user_guide_src/source/database/examples/006.php +++ b/user_guide_src/source/database/examples/006.php @@ -1,5 +1,5 @@ escape($title).", ".$db->escape($name).")"; +$sql = 'INSERT INTO mytable (title, name) VALUES (' . $db->escape($title) . ', ' . $db->escape($name) . ')'; $db->query($sql); echo $db->affectedRows(); diff --git a/user_guide_src/source/database/examples/008.php b/user_guide_src/source/database/examples/008.php index 00ed0b27dbfc..76e35e0e0932 100644 --- a/user_guide_src/source/database/examples/008.php +++ b/user_guide_src/source/database/examples/008.php @@ -3,7 +3,7 @@ $data = [ 'title' => $title, 'name' => $name, - 'date' => $date + 'date' => $date, ]; $db->table('mytable')->insert($data); diff --git a/user_guide_src/source/database/metadata/007.php b/user_guide_src/source/database/metadata/007.php index fdac8c74ffec..2c68fc14b5f4 100644 --- a/user_guide_src/source/database/metadata/007.php +++ b/user_guide_src/source/database/metadata/007.php @@ -1,4 +1,4 @@ query("YOUR QUERY"); +$query = $db->query('YOUR QUERY'); $fields = $query->fieldData(); diff --git a/user_guide_src/source/database/queries/003.php b/user_guide_src/source/database/queries/003.php index 9980b5d1701e..f414f829b39e 100644 --- a/user_guide_src/source/database/queries/003.php +++ b/user_guide_src/source/database/queries/003.php @@ -1,7 +1,7 @@ simpleQuery('YOUR QUERY')) { - echo "Success!"; + echo 'Success!'; } else { - echo "Query failed!"; + echo 'Query failed!'; } diff --git a/user_guide_src/source/database/queries/009.php b/user_guide_src/source/database/queries/009.php index e93ca2da877c..24961e75db6e 100644 --- a/user_guide_src/source/database/queries/009.php +++ b/user_guide_src/source/database/queries/009.php @@ -1,3 +1,3 @@ escape($title) . ")"; +$sql = 'INSERT INTO table (title) VALUES(' . $db->escape($title) . ')'; diff --git a/user_guide_src/source/database/queries/011.php b/user_guide_src/source/database/queries/011.php index 4b4e40660456..e3b1f9033bc9 100644 --- a/user_guide_src/source/database/queries/011.php +++ b/user_guide_src/source/database/queries/011.php @@ -1,5 +1,5 @@ escapeLikeString($search) . "%' ESCAPE '!'"; diff --git a/user_guide_src/source/database/queries/012.php b/user_guide_src/source/database/queries/012.php index 5aebc0688a14..11f1035c0ef7 100644 --- a/user_guide_src/source/database/queries/012.php +++ b/user_guide_src/source/database/queries/012.php @@ -1,4 +1,4 @@ query($sql, [3, 'live', 'Rick']); diff --git a/user_guide_src/source/database/queries/013.php b/user_guide_src/source/database/queries/013.php index 572886ee41b8..1e6afe7861a5 100644 --- a/user_guide_src/source/database/queries/013.php +++ b/user_guide_src/source/database/queries/013.php @@ -1,4 +1,4 @@ query($sql, [[3, 6], 'live', 'Rick']); diff --git a/user_guide_src/source/database/queries/014.php b/user_guide_src/source/database/queries/014.php index 6fadb198fd45..63d156cc6d13 100644 --- a/user_guide_src/source/database/queries/014.php +++ b/user_guide_src/source/database/queries/014.php @@ -1,6 +1,6 @@ query($sql, [ 'id' => 3, 'status' => 'live', diff --git a/user_guide_src/source/database/queries/016.php b/user_guide_src/source/database/queries/016.php index b614183dfa83..f674f7c7ccce 100644 --- a/user_guide_src/source/database/queries/016.php +++ b/user_guide_src/source/database/queries/016.php @@ -1,9 +1,9 @@ prepare(function ($db) { +$pQuery = $db->prepare(static function ($db) { return $db->table('user')->insert([ 'name' => 'x', 'email' => 'y', - 'country' => 'US' + 'country' => 'US', ]); }); diff --git a/user_guide_src/source/database/queries/017.php b/user_guide_src/source/database/queries/017.php index 3862d566dd3f..308412f64653 100644 --- a/user_guide_src/source/database/queries/017.php +++ b/user_guide_src/source/database/queries/017.php @@ -2,8 +2,8 @@ use CodeIgniter\Database\Query; -$pQuery = $db->prepare(function ($db) { - $sql = "INSERT INTO user (name, email, country) VALUES (?, ?, ?)"; +$pQuery = $db->prepare(static function ($db) { + $sql = 'INSERT INTO user (name, email, country) VALUES (?, ?, ?)'; return (new Query($db))->setQuery($sql); }); diff --git a/user_guide_src/source/database/queries/018.php b/user_guide_src/source/database/queries/018.php index ddf8aa0dd58f..a6df9b8d6dbe 100644 --- a/user_guide_src/source/database/queries/018.php +++ b/user_guide_src/source/database/queries/018.php @@ -2,8 +2,8 @@ use CodeIgniter\Database\Query; -$pQuery = $db->prepare(function ($db) { - $sql = "INSERT INTO user (name, email, country) VALUES (?, ?, ?)"; +$pQuery = $db->prepare(static function ($db) { + $sql = 'INSERT INTO user (name, email, country) VALUES (?, ?, ?)'; return (new Query($db))->setQuery($sql); }, $options); diff --git a/user_guide_src/source/database/queries/019.php b/user_guide_src/source/database/queries/019.php index 73467a9394e5..28729f2e484a 100644 --- a/user_guide_src/source/database/queries/019.php +++ b/user_guide_src/source/database/queries/019.php @@ -1,11 +1,11 @@ prepare(function ($db) { +$pQuery = $db->prepare(static function ($db) { return $db->table('user')->insert([ 'name' => 'x', 'email' => 'y', - 'country' => 'US' + 'country' => 'US', ]); }); diff --git a/user_guide_src/source/database/query_builder/006.php b/user_guide_src/source/database/query_builder/006.php index 78a92e7b7b9d..52af6d2a4913 100644 --- a/user_guide_src/source/database/query_builder/006.php +++ b/user_guide_src/source/database/query_builder/006.php @@ -1,12 +1,10 @@ limit(10,20)->getCompiledSelect(false); +echo $builder->limit(10, 20)->getCompiledSelect(false); /* * Prints string: SELECT * FROM mytable LIMIT 20, 10 * (in MySQL. Other databases have slightly different syntax) */ echo $builder->select('title, content, date')->getCompiledSelect(); -/* - * Prints string: SELECT title, content, date FROM mytable LIMIT 20, 10 - */ +// Prints string: SELECT title, content, date FROM mytable LIMIT 20, 10 diff --git a/user_guide_src/source/database/query_builder/016.php b/user_guide_src/source/database/query_builder/016.php index f00c2dbe47c2..1ad1c917ff57 100644 --- a/user_guide_src/source/database/query_builder/016.php +++ b/user_guide_src/source/database/query_builder/016.php @@ -2,5 +2,5 @@ $subquery = $db->table('users'); $builder = $db->table('jobs')->fromSubquery($subquery, 'alias'); -$query = $builder->get(); +$query = $builder->get(); // Produces: SELECT * FROM `jobs`, (SELECT * FROM `users`) AS `alias` diff --git a/user_guide_src/source/database/query_builder/017.php b/user_guide_src/source/database/query_builder/017.php index 965ae956a6af..b33dd475b6f8 100644 --- a/user_guide_src/source/database/query_builder/017.php +++ b/user_guide_src/source/database/query_builder/017.php @@ -2,5 +2,5 @@ $subquery = $db->table('users')->select('id, name'); $builder = $db->newQuery()->fromSubquery($subquery, 't'); -$query = $builder->get(); +$query = $builder->get(); // Produces: SELECT * FROM (SELECT `id`, `name` FROM users) AS `t` diff --git a/user_guide_src/source/database/query_builder/026.php b/user_guide_src/source/database/query_builder/026.php index d4e93699151c..ed45b84bf363 100644 --- a/user_guide_src/source/database/query_builder/026.php +++ b/user_guide_src/source/database/query_builder/026.php @@ -1,5 +1,5 @@ db->escape('Joe'); +$name = $builder->db->escape('Joe'); $where = "name={$name} AND status='boss' OR status='active'"; $builder->where($where); diff --git a/user_guide_src/source/database/query_builder/027.php b/user_guide_src/source/database/query_builder/027.php index 043b7d9e451b..019386718cd1 100644 --- a/user_guide_src/source/database/query_builder/027.php +++ b/user_guide_src/source/database/query_builder/027.php @@ -1,9 +1,7 @@ where('advance_amount <', function (BaseBuilder $builder) { - return $builder->select('MAX(advance_amount)', false)->from('orders')->where('id >', 2); -}); +$builder->where('advance_amount <', static fn (BaseBuilder $builder) => $builder->select('MAX(advance_amount)', false)->from('orders')->where('id >', 2)); // Produces: WHERE "advance_amount" < (SELECT MAX(advance_amount) FROM "orders" WHERE "id" > 2) // With builder directly diff --git a/user_guide_src/source/database/query_builder/030.php b/user_guide_src/source/database/query_builder/030.php index 7f80507b4435..5aa7619c0dc8 100644 --- a/user_guide_src/source/database/query_builder/030.php +++ b/user_guide_src/source/database/query_builder/030.php @@ -1,9 +1,7 @@ whereIn('id', function (BaseBuilder $builder) { - return $builder->select('job_id')->from('users_jobs')->where('user_id', 3); -}); +$builder->whereIn('id', static fn (BaseBuilder $builder) => $builder->select('job_id')->from('users_jobs')->where('user_id', 3)); // Produces: WHERE "id" IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3) // With builder directly diff --git a/user_guide_src/source/database/query_builder/032.php b/user_guide_src/source/database/query_builder/032.php index 7a7a44182396..ae8ddb7ce7a4 100644 --- a/user_guide_src/source/database/query_builder/032.php +++ b/user_guide_src/source/database/query_builder/032.php @@ -1,9 +1,7 @@ orWhereIn('id', function (BaseBuilder $builder) { - return $builder->select('job_id')->from('users_jobs')->where('user_id', 3); -}); +$builder->orWhereIn('id', static fn (BaseBuilder $builder) => $builder->select('job_id')->from('users_jobs')->where('user_id', 3)); // Produces: OR "id" IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3) // With builder directly diff --git a/user_guide_src/source/database/query_builder/034.php b/user_guide_src/source/database/query_builder/034.php index 2316388e16b6..02904a3962f3 100644 --- a/user_guide_src/source/database/query_builder/034.php +++ b/user_guide_src/source/database/query_builder/034.php @@ -1,9 +1,7 @@ whereNotIn('id', function (BaseBuilder $builder) { - return $builder->select('job_id')->from('users_jobs')->where('user_id', 3); -}); +$builder->whereNotIn('id', static fn (BaseBuilder $builder) => $builder->select('job_id')->from('users_jobs')->where('user_id', 3)); // Produces: WHERE "id" NOT IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3) // With builder directly diff --git a/user_guide_src/source/database/query_builder/036.php b/user_guide_src/source/database/query_builder/036.php index d50bcc113853..f5668aa1a30d 100644 --- a/user_guide_src/source/database/query_builder/036.php +++ b/user_guide_src/source/database/query_builder/036.php @@ -1,9 +1,7 @@ orWhereNotIn('id', function (BaseBuilder $builder) { - return $builder->select('job_id')->from('users_jobs')->where('user_id', 3); -}); +$builder->orWhereNotIn('id', static fn (BaseBuilder $builder) => $builder->select('job_id')->from('users_jobs')->where('user_id', 3)); // Produces: OR "id" NOT IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3) // With builder directly diff --git a/user_guide_src/source/database/query_builder/044.php b/user_guide_src/source/database/query_builder/044.php index 1c0a0e15991d..ffe4786baaae 100644 --- a/user_guide_src/source/database/query_builder/044.php +++ b/user_guide_src/source/database/query_builder/044.php @@ -1,4 +1,4 @@ groupBy("title"); +$builder->groupBy('title'); // Produces: GROUP BY title diff --git a/user_guide_src/source/database/query_builder/045.php b/user_guide_src/source/database/query_builder/045.php index 5758e29187be..0872996afe9f 100644 --- a/user_guide_src/source/database/query_builder/045.php +++ b/user_guide_src/source/database/query_builder/045.php @@ -1,4 +1,4 @@ groupBy(["title", "date"]); +$builder->groupBy(['title', 'date']); // Produces: GROUP BY title, date diff --git a/user_guide_src/source/database/query_builder/047.php b/user_guide_src/source/database/query_builder/047.php index cf439e52d0fb..87f435064238 100644 --- a/user_guide_src/source/database/query_builder/047.php +++ b/user_guide_src/source/database/query_builder/047.php @@ -1,4 +1,4 @@ having('user_id = 45'); // Produces: HAVING user_id = 45 -$builder->having('user_id', 45); // Produces: HAVING user_id = 45 +$builder->having('user_id', 45); // Produces: HAVING user_id = 45 diff --git a/user_guide_src/source/database/query_builder/049.php b/user_guide_src/source/database/query_builder/049.php index 4a22eccffc4d..b044b821f388 100644 --- a/user_guide_src/source/database/query_builder/049.php +++ b/user_guide_src/source/database/query_builder/049.php @@ -1,4 +1,4 @@ having('user_id', 45); // Produces: HAVING `user_id` = 45 in some databases such as MySQL -$builder->having('user_id', 45, false); // Produces: HAVING user_id = 45 +$builder->having('user_id', 45); // Produces: HAVING `user_id` = 45 in some databases such as MySQL +$builder->having('user_id', 45, false); // Produces: HAVING user_id = 45 diff --git a/user_guide_src/source/database/query_builder/051.php b/user_guide_src/source/database/query_builder/051.php index 325e99679082..1f5736243866 100644 --- a/user_guide_src/source/database/query_builder/051.php +++ b/user_guide_src/source/database/query_builder/051.php @@ -1,9 +1,7 @@ havingIn('id', function (BaseBuilder $builder) { - return $builder->select('user_id')->from('users_jobs')->where('group_id', 3); -}); +$builder->havingIn('id', static fn (BaseBuilder $builder) => $builder->select('user_id')->from('users_jobs')->where('group_id', 3)); // Produces: HAVING "id" IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3) // With builder directly diff --git a/user_guide_src/source/database/query_builder/053.php b/user_guide_src/source/database/query_builder/053.php index baa936c5df82..8a19ff4ac7d8 100644 --- a/user_guide_src/source/database/query_builder/053.php +++ b/user_guide_src/source/database/query_builder/053.php @@ -1,9 +1,7 @@ orHavingIn('id', function (BaseBuilder $builder) { - return $builder->select('user_id')->from('users_jobs')->where('group_id', 3); -}); +// With closure +$builder->orHavingIn('id', static fn (BaseBuilder $builder) => $builder->select('user_id')->from('users_jobs')->where('group_id', 3)); // Produces: OR "id" IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3) // With builder directly diff --git a/user_guide_src/source/database/query_builder/055.php b/user_guide_src/source/database/query_builder/055.php index 986b3ff24cb9..67a54f87f7bc 100644 --- a/user_guide_src/source/database/query_builder/055.php +++ b/user_guide_src/source/database/query_builder/055.php @@ -1,9 +1,7 @@ havingNotIn('id', function (BaseBuilder $builder) { - return $builder->select('user_id')->from('users_jobs')->where('group_id', 3); -}); +// With closure +$builder->havingNotIn('id', static fn (BaseBuilder $builder) => $builder->select('user_id')->from('users_jobs')->where('group_id', 3)); // Produces: HAVING "id" NOT IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3) // With builder directly diff --git a/user_guide_src/source/database/query_builder/057.php b/user_guide_src/source/database/query_builder/057.php index 85cab6e2eba8..8a92da5725b2 100644 --- a/user_guide_src/source/database/query_builder/057.php +++ b/user_guide_src/source/database/query_builder/057.php @@ -1,9 +1,7 @@ orHavingNotIn('id', function (BaseBuilder $builder) { - return $builder->select('user_id')->from('users_jobs')->where('group_id', 3); -}); +// With closure +$builder->orHavingNotIn('id', static fn (BaseBuilder $builder) => $builder->select('user_id')->from('users_jobs')->where('group_id', 3)); // Produces: OR "id" NOT IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3) // With builder directly diff --git a/user_guide_src/source/database/query_builder/074.php b/user_guide_src/source/database/query_builder/074.php index d858451993a2..1ce884db6e6a 100644 --- a/user_guide_src/source/database/query_builder/074.php +++ b/user_guide_src/source/database/query_builder/074.php @@ -2,14 +2,14 @@ $builder->select('*')->from('my_table') ->groupStart() - ->where('a', 'a') - ->orGroupStart() - ->where('b', 'b') - ->where('c', 'c') - ->groupEnd() + ->where('a', 'a') + ->orGroupStart() + ->where('b', 'b') + ->where('c', 'c') + ->groupEnd() ->groupEnd() ->where('d', 'd') -->get(); + ->get(); /* * Generates: * SELECT * FROM (`my_table`) WHERE ( `a` = 'a' OR ( `b` = 'b' AND `c` = 'c' ) ) AND `d` = 'd' diff --git a/user_guide_src/source/database/query_builder/076.php b/user_guide_src/source/database/query_builder/076.php index cdacf0a53df5..ba38d99ff43b 100644 --- a/user_guide_src/source/database/query_builder/076.php +++ b/user_guide_src/source/database/query_builder/076.php @@ -7,6 +7,6 @@ class Myclass public $date = 'My Date'; } -$object = new Myclass; +$object = new Myclass(); $builder->insert($object); // Produces: INSERT INTO mytable (title, content, date) VALUES ('My Title', 'My Content', 'My Date') diff --git a/user_guide_src/source/database/query_builder/086.php b/user_guide_src/source/database/query_builder/086.php index c7dcd01aa071..d395bc3b8ea9 100644 --- a/user_guide_src/source/database/query_builder/086.php +++ b/user_guide_src/source/database/query_builder/086.php @@ -7,6 +7,6 @@ class Myclass public $date = 'My Date'; } -$object = new Myclass; +$object = new Myclass(); $builder->set($object); $builder->insert(); diff --git a/user_guide_src/source/database/query_builder/088.php b/user_guide_src/source/database/query_builder/088.php index ce38024e558d..445e53716041 100644 --- a/user_guide_src/source/database/query_builder/088.php +++ b/user_guide_src/source/database/query_builder/088.php @@ -7,7 +7,7 @@ class Myclass public $date = 'My Date'; } -$object = new Myclass; +$object = new Myclass(); $builder->where('id', $id); $builder->update($object); /* diff --git a/user_guide_src/source/database/query_builder/089.php b/user_guide_src/source/database/query_builder/089.php index 2a4a01cc6346..d2ed79d26832 100644 --- a/user_guide_src/source/database/query_builder/089.php +++ b/user_guide_src/source/database/query_builder/089.php @@ -1,3 +1,3 @@ update($data, "id = 4"); +$builder->update($data, 'id = 4'); diff --git a/user_guide_src/source/database/query_builder/091.php b/user_guide_src/source/database/query_builder/091.php index 56f04036cd6f..e60b9ee6b486 100644 --- a/user_guide_src/source/database/query_builder/091.php +++ b/user_guide_src/source/database/query_builder/091.php @@ -1,16 +1,16 @@ 'My title' , - 'name' => 'My Name 2' , - 'date' => 'My date 2', - ], - [ - 'title' => 'Another title' , - 'name' => 'Another Name 2' , - 'date' => 'Another date 2', - ], + [ + 'title' => 'My title', + 'name' => 'My Name 2', + 'date' => 'My date 2', + ], + [ + 'title' => 'Another title', + 'name' => 'Another Name 2', + 'date' => 'Another date 2', + ], ]; $builder->updateBatch($data, 'title'); diff --git a/user_guide_src/source/database/query_builder/096.php b/user_guide_src/source/database/query_builder/096.php index 78b57dd13df5..5a05f70d8070 100644 --- a/user_guide_src/source/database/query_builder/096.php +++ b/user_guide_src/source/database/query_builder/096.php @@ -1,6 +1,6 @@ select('title') - ->where('id', $id) - ->limit(10, 20) - ->get(); + ->where('id', $id) + ->limit(10, 20) + ->get(); diff --git a/user_guide_src/source/database/query_builder/097.php b/user_guide_src/source/database/query_builder/097.php index 30c4d0c4526a..50d274d63a54 100644 --- a/user_guide_src/source/database/query_builder/097.php +++ b/user_guide_src/source/database/query_builder/097.php @@ -1,9 +1,9 @@ select(['field1','field2']) - ->where('field3',5) - ->getCompiledSelect(false); +$sql = $builder->select(['field1', 'field2']) + ->where('field3', 5) + ->getCompiledSelect(false); // ... // Do something crazy with the SQL code... like add it to a cron script for diff --git a/user_guide_src/source/database/query_builder/098.php b/user_guide_src/source/database/query_builder/098.php index a6fb3cc4beed..b3890e978005 100644 --- a/user_guide_src/source/database/query_builder/098.php +++ b/user_guide_src/source/database/query_builder/098.php @@ -2,5 +2,5 @@ $subquery = $db->table('countries')->select('name')->where('id', 1); $builder = $db->table('users')->select('name')->selectSubquery($subquery, 'country'); -$query = $builder->get(); +$query = $builder->get(); // Produces: SELECT `name`, (SELECT `name` FROM `countries` WHERE `id` = 1) AS `country` FROM `users` diff --git a/user_guide_src/source/database/results/001.php b/user_guide_src/source/database/results/001.php index 0cbecfb88ba9..af0b6117f689 100644 --- a/user_guide_src/source/database/results/001.php +++ b/user_guide_src/source/database/results/001.php @@ -1,6 +1,6 @@ query("YOUR QUERY"); +$query = $db->query('YOUR QUERY'); foreach ($query->getResult() as $row) { echo $row->title; diff --git a/user_guide_src/source/database/results/002.php b/user_guide_src/source/database/results/002.php index 8b702c8e1150..2ab6e0535a3a 100644 --- a/user_guide_src/source/database/results/002.php +++ b/user_guide_src/source/database/results/002.php @@ -1,6 +1,6 @@ query("YOUR QUERY"); +$query = $db->query('YOUR QUERY'); foreach ($query->getResult('array') as $row) { echo $row['title']; diff --git a/user_guide_src/source/database/results/003.php b/user_guide_src/source/database/results/003.php index 1ad7d7dcb9fe..da55c19717c1 100644 --- a/user_guide_src/source/database/results/003.php +++ b/user_guide_src/source/database/results/003.php @@ -1,6 +1,6 @@ query("SELECT * FROM users;"); +$query = $db->query('SELECT * FROM users;'); foreach ($query->getResult('User') as $user) { echo $user->name; // access attributes diff --git a/user_guide_src/source/database/results/004.php b/user_guide_src/source/database/results/004.php index e8e9acecdcdc..66c537b57344 100644 --- a/user_guide_src/source/database/results/004.php +++ b/user_guide_src/source/database/results/004.php @@ -1,6 +1,6 @@ query("YOUR QUERY"); +$query = $db->query('YOUR QUERY'); foreach ($query->getResultArray() as $row) { echo $row['title']; diff --git a/user_guide_src/source/database/results/005.php b/user_guide_src/source/database/results/005.php index af79170b8b89..bd0e2ed47050 100644 --- a/user_guide_src/source/database/results/005.php +++ b/user_guide_src/source/database/results/005.php @@ -1,6 +1,6 @@ query("YOUR QUERY"); +$query = $db->query('YOUR QUERY'); $row = $query->getRow(); diff --git a/user_guide_src/source/database/results/007.php b/user_guide_src/source/database/results/007.php index 4b46945c285e..6a6c309efb4f 100644 --- a/user_guide_src/source/database/results/007.php +++ b/user_guide_src/source/database/results/007.php @@ -1,7 +1,7 @@ query("SELECT * FROM users LIMIT 1;"); -$row = $query->getRow(0, 'User'); +$query = $db->query('SELECT * FROM users LIMIT 1;'); +$row = $query->getRow(0, 'User'); echo $row->name; // access attributes echo $row->reverse_name(); // or methods defined on the 'User' class diff --git a/user_guide_src/source/database/results/008.php b/user_guide_src/source/database/results/008.php index 8b576d1d3117..9925567c5a01 100644 --- a/user_guide_src/source/database/results/008.php +++ b/user_guide_src/source/database/results/008.php @@ -1,6 +1,6 @@ query("YOUR QUERY"); +$query = $db->query('YOUR QUERY'); $row = $query->getRowArray(); diff --git a/user_guide_src/source/database/results/010.php b/user_guide_src/source/database/results/010.php index ad0b4c326d0f..072c511f89bd 100644 --- a/user_guide_src/source/database/results/010.php +++ b/user_guide_src/source/database/results/010.php @@ -1,6 +1,6 @@ query("YOUR QUERY"); +$query = $db->query('YOUR QUERY'); while ($row = $query->getUnbufferedRow()) { echo $row->title; diff --git a/user_guide_src/source/database/results/011.php b/user_guide_src/source/database/results/011.php index f57aa21a2504..b33681cd74b4 100644 --- a/user_guide_src/source/database/results/011.php +++ b/user_guide_src/source/database/results/011.php @@ -2,14 +2,13 @@ $db->resultMode = MYSQLI_USE_RESULT; // for unbuffered results -$query = $db->query("YOUR QUERY"); +$query = $db->query('YOUR QUERY'); -$file = new \CodeIgniter\Files\File(WRITEPATH.'data.csv'); +$file = new \CodeIgniter\Files\File(WRITEPATH . 'data.csv'); $csv = $file->openFile('w'); -while ($row = $query->getUnbufferedRow('array')) -{ +while ($row = $query->getUnbufferedRow('array')) { $csv->fputcsv($row); } diff --git a/user_guide_src/source/database/results/013.php b/user_guide_src/source/database/results/013.php index 6c47fe5bf256..380945848ebb 100644 --- a/user_guide_src/source/database/results/013.php +++ b/user_guide_src/source/database/results/013.php @@ -22,8 +22,8 @@ public function __set($name, $value) public function __get($name) { - if (isset($this->$name)) { - return $this->$name; + if (isset($this->{$name})) { + return $this->{$name}; } } } diff --git a/user_guide_src/source/database/results/014.php b/user_guide_src/source/database/results/014.php index df6073c5ed79..f0845bf55ac3 100644 --- a/user_guide_src/source/database/results/014.php +++ b/user_guide_src/source/database/results/014.php @@ -1,6 +1,6 @@ query("YOUR QUERY"); +$query = $db->query('YOUR QUERY'); $rows = $query->getCustomResultObject('User'); diff --git a/user_guide_src/source/database/results/015.php b/user_guide_src/source/database/results/015.php index a57dddfa42d0..247d5d8b5313 100644 --- a/user_guide_src/source/database/results/015.php +++ b/user_guide_src/source/database/results/015.php @@ -1,6 +1,6 @@ query("YOUR QUERY"); +$query = $db->query('YOUR QUERY'); $row = $query->getCustomRowObject(0, 'User'); diff --git a/user_guide_src/source/database/utilities/001.php b/user_guide_src/source/database/utilities/001.php index 9b0e88d70753..697e6a786930 100644 --- a/user_guide_src/source/database/utilities/001.php +++ b/user_guide_src/source/database/utilities/001.php @@ -1,12 +1,10 @@ db; -}, null, $model)($model); +$db = \Closure::bind(static fn ($model) => $model->db, null, $model)($model); $util = (new \CodeIgniter\Database\Database())->loadUtils($db); echo $util->getXMLFromResult($model->get()); diff --git a/user_guide_src/source/dbmgmt/forge/007.php b/user_guide_src/source/dbmgmt/forge/007.php index 5150dd8495ef..182ea8347633 100644 --- a/user_guide_src/source/dbmgmt/forge/007.php +++ b/user_guide_src/source/dbmgmt/forge/007.php @@ -1,29 +1,29 @@ [ + 'id' => [ 'type' => 'INT', 'constraint' => 5, 'unsigned' => true, - 'auto_increment' => true + 'auto_increment' => true, ], - 'title' => [ - 'type' => 'VARCHAR', - 'constraint' => '100', - 'unique' => true, + 'title' => [ + 'type' => 'VARCHAR', + 'constraint' => '100', + 'unique' => true, ], - 'author' => [ - 'type' =>'VARCHAR', - 'constraint' => 100, - 'default' => 'King of Town', + 'author' => [ + 'type' => 'VARCHAR', + 'constraint' => 100, + 'default' => 'King of Town', ], 'description' => [ - 'type' => 'TEXT', - 'null' => true, + 'type' => 'TEXT', + 'null' => true, ], - 'status' => [ - 'type' => 'ENUM', - 'constraint' => ['publish', 'pending', 'draft'], - 'default' => 'pending', + 'status' => [ + 'type' => 'ENUM', + 'constraint' => ['publish', 'pending', 'draft'], + 'default' => 'pending', ], ]; diff --git a/user_guide_src/source/dbmgmt/forge/022.php b/user_guide_src/source/dbmgmt/forge/022.php index 22b335fc992c..80b0b9f5e098 100644 --- a/user_guide_src/source/dbmgmt/forge/022.php +++ b/user_guide_src/source/dbmgmt/forge/022.php @@ -1,7 +1,7 @@ ['type' => 'TEXT'] + 'preferences' => ['type' => 'TEXT'], ]; $forge->addColumn('table_name', $fields); // Executes: ALTER TABLE `table_name` ADD `preferences` TEXT diff --git a/user_guide_src/source/dbmgmt/forge/023.php b/user_guide_src/source/dbmgmt/forge/023.php index 50a5bc799909..957d9a37dafc 100644 --- a/user_guide_src/source/dbmgmt/forge/023.php +++ b/user_guide_src/source/dbmgmt/forge/023.php @@ -2,10 +2,10 @@ // Will place the new column after the `another_field` column: $fields = [ - 'preferences' => ['type' => 'TEXT', 'after' => 'another_field'] + 'preferences' => ['type' => 'TEXT', 'after' => 'another_field'], ]; // Will place the new column at the start of the table definition: $fields = [ - 'preferences' => ['type' => 'TEXT', 'first' => true] + 'preferences' => ['type' => 'TEXT', 'first' => true], ]; diff --git a/user_guide_src/source/dbmgmt/migration/001.php b/user_guide_src/source/dbmgmt/migration/001.php index 0d08e2b44308..3f73906231f1 100644 --- a/user_guide_src/source/dbmgmt/migration/001.php +++ b/user_guide_src/source/dbmgmt/migration/001.php @@ -9,13 +9,13 @@ class AddBlog extends Migration public function up() { $this->forge->addField([ - 'blog_id' => [ + 'blog_id' => [ 'type' => 'INT', 'constraint' => 5, 'unsigned' => true, 'auto_increment' => true, ], - 'blog_title' => [ + 'blog_title' => [ 'type' => 'VARCHAR', 'constraint' => '100', ], diff --git a/user_guide_src/source/dbmgmt/migration/002.php b/user_guide_src/source/dbmgmt/migration/002.php index b324f22003a7..ec555bb81cd6 100644 --- a/user_guide_src/source/dbmgmt/migration/002.php +++ b/user_guide_src/source/dbmgmt/migration/002.php @@ -11,7 +11,7 @@ public function up() $this->db->disableForeignKeyChecks(); // Migration rules would go here.. - + $this->db->enableForeignKeyChecks(); } } diff --git a/user_guide_src/source/dbmgmt/migration/005.php b/user_guide_src/source/dbmgmt/migration/005.php index 958aff859e9d..e9b4c2ad37fe 100644 --- a/user_guide_src/source/dbmgmt/migration/005.php +++ b/user_guide_src/source/dbmgmt/migration/005.php @@ -3,6 +3,7 @@ namespace App\Controllers; use CodeIgniter\Controller; +use Throwable; class Migrate extends Controller { @@ -12,7 +13,7 @@ public function index() try { $migrate->latest(); - } catch (\Throwable $e) { + } catch (Throwable $e) { // Do something with the error here... } } diff --git a/user_guide_src/source/dbmgmt/seeds/001.php b/user_guide_src/source/dbmgmt/seeds/001.php index 627f554fc515..b65b92182611 100644 --- a/user_guide_src/source/dbmgmt/seeds/001.php +++ b/user_guide_src/source/dbmgmt/seeds/001.php @@ -10,11 +10,11 @@ public function run() { $data = [ 'username' => 'darth', - 'email' => 'darth@theempire.com' + 'email' => 'darth@theempire.com', ]; // Simple Queries - $this->db->query("INSERT INTO users (username, email) VALUES(:username:, :email:)", $data); + $this->db->query('INSERT INTO users (username, email) VALUES(:username:, :email:)', $data); // Using Query Builder $this->db->table('users')->insert($data); diff --git a/user_guide_src/source/extending/events/002.php b/user_guide_src/source/extending/events/002.php index 1c28aa8dc471..00fa912bd45a 100644 --- a/user_guide_src/source/extending/events/002.php +++ b/user_guide_src/source/extending/events/002.php @@ -11,7 +11,6 @@ Events::on('pre_system', 'SomeClass::someMethod'); // Use a Closure -Events::on('pre_system', function (...$params) -{ +Events::on('pre_system', static function (...$params) { // ... }); diff --git a/user_guide_src/source/extending/events/006.php b/user_guide_src/source/extending/events/006.php index 5233c94e1808..bceef2866e9e 100644 --- a/user_guide_src/source/extending/events/006.php +++ b/user_guide_src/source/extending/events/006.php @@ -2,6 +2,6 @@ \CodeIgniter\Events\Events::trigger('some_events', $foo, $bar, $baz); -Events::on('some_event', function ($foo, $bar, $baz) { +Events::on('some_event', static function ($foo, $bar, $baz) { // ... }); diff --git a/user_guide_src/source/general/common_functions/001.php b/user_guide_src/source/general/common_functions/001.php index f4d4e1521fff..eeb8da7c2069 100644 --- a/user_guide_src/source/general/common_functions/001.php +++ b/user_guide_src/source/general/common_functions/001.php @@ -1,4 +1,4 @@ find($id); } catch (\Exception $e) { - die($e->getMessage()); + exit($e->getMessage()); } diff --git a/user_guide_src/source/general/helpers/005.php b/user_guide_src/source/general/helpers/005.php index 8d58b073035b..13a7f3015387 100644 --- a/user_guide_src/source/general/helpers/005.php +++ b/user_guide_src/source/general/helpers/005.php @@ -1 +1 @@ - + $user->id, - 'ip_address' => $this->request->getIPAddress() + 'id' => $user->id, + 'ip_address' => $this->request->getIPAddress(), ]; log_message('info', 'User {id} logged into the system from {ip_address}', $info); diff --git a/user_guide_src/source/general/modules/001.php b/user_guide_src/source/general/modules/001.php index c8d49bd4d362..4ced75497590 100644 --- a/user_guide_src/source/general/modules/001.php +++ b/user_guide_src/source/general/modules/001.php @@ -11,6 +11,6 @@ class Autoload extends AutoloadConfig 'Config' => APPPATH . 'Config', 'Acme' => ROOTPATH . 'acme', ]; - + // ... } diff --git a/user_guide_src/source/general/modules/002.php b/user_guide_src/source/general/modules/002.php index 1ee3a742d9aa..c23c48890b32 100644 --- a/user_guide_src/source/general/modules/002.php +++ b/user_guide_src/source/general/modules/002.php @@ -13,6 +13,6 @@ class Autoload extends AutoloadConfig 'path/to/my/constants.php', 'path/to/my/bootstrap.php', ]; - + // ... } diff --git a/user_guide_src/source/general/modules/003.php b/user_guide_src/source/general/modules/003.php index 24accb0c737b..93601b2f1d66 100644 --- a/user_guide_src/source/general/modules/003.php +++ b/user_guide_src/source/general/modules/003.php @@ -11,6 +11,6 @@ class Autoload extends AutoloadConfig 'Config' => APPPATH . 'Config', 'Acme\Blog' => ROOTPATH . 'acme/Blog', // Change ]; - + // ... } diff --git a/user_guide_src/source/general/modules/004.php b/user_guide_src/source/general/modules/004.php index 33bbe70b086f..47a4b1bad712 100644 --- a/user_guide_src/source/general/modules/004.php +++ b/user_guide_src/source/general/modules/004.php @@ -7,6 +7,6 @@ class Modules extends BaseModules { public $discoverInComposer = false; - + // ... } diff --git a/user_guide_src/source/general/modules/007.php b/user_guide_src/source/general/modules/007.php index 06038f690a8c..0030a0885214 100644 --- a/user_guide_src/source/general/modules/007.php +++ b/user_guide_src/source/general/modules/007.php @@ -1,5 +1,5 @@ group('blog', ['namespace' => 'Acme\Blog\Controllers'], function ($routes) { +$routes->group('blog', ['namespace' => 'Acme\Blog\Controllers'], static function ($routes) { $routes->get('/', 'Blog::index'); }); diff --git a/user_guide_src/source/helpers/array_helper/002.php b/user_guide_src/source/helpers/array_helper/002.php index 50ce70084c86..8dde5d7a181b 100644 --- a/user_guide_src/source/helpers/array_helper/002.php +++ b/user_guide_src/source/helpers/array_helper/002.php @@ -7,6 +7,6 @@ ], 'bar' => [ 'baz' => 23, - ] - ] + ], + ], ]; diff --git a/user_guide_src/source/helpers/array_helper/008.php b/user_guide_src/source/helpers/array_helper/008.php index 14c6213b8410..64342dc6da9b 100644 --- a/user_guide_src/source/helpers/array_helper/008.php +++ b/user_guide_src/source/helpers/array_helper/008.php @@ -6,7 +6,7 @@ 'team_id' => 5, 'position' => 1, 'team' => [ - 'id' => 5, + 'id' => 5, 'order' => 1, ], ], @@ -15,7 +15,7 @@ 'team_id' => 5, 'position' => 4, 'team' => [ - 'id' => 5, + 'id' => 5, 'order' => 1, ], ], @@ -24,7 +24,7 @@ 'team_id' => 2, 'position' => 3, 'team' => [ - 'id' => 1, + 'id' => 1, 'order' => 2, ], ], diff --git a/user_guide_src/source/helpers/filesystem_helper/010.php b/user_guide_src/source/helpers/filesystem_helper/010.php index 9c703479fe68..51db194b6d63 100644 --- a/user_guide_src/source/helpers/filesystem_helper/010.php +++ b/user_guide_src/source/helpers/filesystem_helper/010.php @@ -1,3 +1,3 @@ 'shirts', - 'onChange' => 'some_function();' + 'onChange' => 'some_function();', ]; echo form_dropdown('shirts', $options, 'large', $js); diff --git a/user_guide_src/source/helpers/form_helper/022.php b/user_guide_src/source/helpers/form_helper/022.php index a8ca201db3e3..77fea178b64c 100644 --- a/user_guide_src/source/helpers/form_helper/022.php +++ b/user_guide_src/source/helpers/form_helper/022.php @@ -2,7 +2,7 @@ $attributes = [ 'id' => 'address_info', - 'class' => 'address_info' + 'class' => 'address_info', ]; echo form_fieldset('Address Information', $attributes); @@ -11,7 +11,7 @@ ?> - +
    Address Information

    form content here

    diff --git a/user_guide_src/source/helpers/form_helper/025.php b/user_guide_src/source/helpers/form_helper/025.php index d889aab62591..3929501e40fb 100644 --- a/user_guide_src/source/helpers/form_helper/025.php +++ b/user_guide_src/source/helpers/form_helper/025.php @@ -5,7 +5,7 @@ 'id' => 'newsletter', 'value' => 'accept', 'checked' => true, - 'style' => 'margin:10px' + 'style' => 'margin:10px', ]; echo form_checkbox($data); diff --git a/user_guide_src/source/helpers/form_helper/029.php b/user_guide_src/source/helpers/form_helper/029.php index c05370129514..9344463584f6 100644 --- a/user_guide_src/source/helpers/form_helper/029.php +++ b/user_guide_src/source/helpers/form_helper/029.php @@ -2,7 +2,7 @@ $attributes = [ 'class' => 'mycustomclass', - 'style' => 'color: #000;' + 'style' => 'color: #000;', ]; echo form_label('What is your Name', 'username', $attributes); diff --git a/user_guide_src/source/helpers/form_helper/031.php b/user_guide_src/source/helpers/form_helper/031.php index 671a69fcf6d8..c95d783fc985 100644 --- a/user_guide_src/source/helpers/form_helper/031.php +++ b/user_guide_src/source/helpers/form_helper/031.php @@ -1,4 +1,4 @@ Content diff --git a/user_guide_src/source/helpers/html_helper/011.php b/user_guide_src/source/helpers/html_helper/011.php index 0d15fc0e6c69..126fd86c4952 100644 --- a/user_guide_src/source/helpers/html_helper/011.php +++ b/user_guide_src/source/helpers/html_helper/011.php @@ -1,6 +1,6 @@ 'js/printer.js']; +$script = ['src' => 'js/printer.js']; echo script_tag($script); // diff --git a/user_guide_src/source/helpers/html_helper/013.php b/user_guide_src/source/helpers/html_helper/013.php index 435ebc5535d2..113ecbbaf6c6 100644 --- a/user_guide_src/source/helpers/html_helper/013.php +++ b/user_guide_src/source/helpers/html_helper/013.php @@ -20,9 +20,9 @@ 'sphere', ], ], - 'moods' => [ + 'moods' => [ 'happy', - 'upset' => [ + 'upset' => [ 'defeated' => [ 'dejected', 'disheartened', @@ -31,8 +31,8 @@ 'annoyed', 'cross', 'angry', - ] - ] + ], + ], ]; echo ul($list, $attributes); diff --git a/user_guide_src/source/helpers/html_helper/014.php b/user_guide_src/source/helpers/html_helper/014.php index 505b771d5f1b..e61c2db89e12 100644 --- a/user_guide_src/source/helpers/html_helper/014.php +++ b/user_guide_src/source/helpers/html_helper/014.php @@ -2,7 +2,7 @@ $tracks = [ track('subtitles_no.vtt', 'subtitles', 'no', 'Norwegian No'), - track('subtitles_yes.vtt', 'subtitles', 'yes', 'Norwegian Yes') + track('subtitles_yes.vtt', 'subtitles', 'yes', 'Norwegian Yes'), ]; echo video('test.mp4', 'Your browser does not support the video tag.', 'controls'); @@ -14,13 +14,14 @@ $tracks ); -echo video([ - source('movie.mp4', 'video/mp4', 'class="test"'), - source('movie.ogg', 'video/ogg'), - source('movie.mov', 'video/quicktime'), - source('movie.ogv', 'video/ogv; codecs=dirac, speex') -], +echo video( + [ + source('movie.mp4', 'video/mp4', 'class="test"'), + source('movie.ogg', 'video/ogg'), + source('movie.mov', 'video/quicktime'), + source('movie.ogv', 'video/ogv; codecs=dirac, speex'), + ], 'Your browser does not support the video tag.', 'class="test" controls', $tracks - ); +); diff --git a/user_guide_src/source/helpers/html_helper/017.php b/user_guide_src/source/helpers/html_helper/017.php index a0b38b79e672..1ff7fb45ba01 100644 --- a/user_guide_src/source/helpers/html_helper/017.php +++ b/user_guide_src/source/helpers/html_helper/017.php @@ -8,6 +8,6 @@ 'class="test"', [ param('foo', 'bar', 'ref', 'class="test"'), - param('hello', 'world', 'ref', 'class="test"') + param('hello', 'world', 'ref', 'class="test"'), ] ); diff --git a/user_guide_src/source/helpers/text_helper/006.php b/user_guide_src/source/helpers/text_helper/006.php index 4c564c6da0f6..3327d2e2176d 100644 --- a/user_guide_src/source/helpers/text_helper/006.php +++ b/user_guide_src/source/helpers/text_helper/006.php @@ -1,4 +1,4 @@ "Is your name O\'reilly?", - 'answer' => "No, my name is O\'connor." + 'question' => "Is your name O\\'reilly?", + 'answer' => "No, my name is O\\'connor.", ]; $str = strip_slashes($str); diff --git a/user_guide_src/source/helpers/text_helper/008.php b/user_guide_src/source/helpers/text_helper/008.php index 073f97ff0046..c4cd2f1c53ca 100644 --- a/user_guide_src/source/helpers/text_helper/008.php +++ b/user_guide_src/source/helpers/text_helper/008.php @@ -2,5 +2,5 @@ [ 'question' => "Is your name O'reilly?", - 'answer' => "No, my name is O'connor." + 'answer' => "No, my name is O'connor.", ]; diff --git a/user_guide_src/source/helpers/text_helper/009.php b/user_guide_src/source/helpers/text_helper/009.php index 8081482f17eb..60f35bc49ead 100644 --- a/user_guide_src/source/helpers/text_helper/009.php +++ b/user_guide_src/source/helpers/text_helper/009.php @@ -1,4 +1,4 @@ ', ''); +$string = 'Here is a nice text string about nothing in particular.'; +echo highlight_phrase($string, 'nice text', '', ''); diff --git a/user_guide_src/source/helpers/text_helper/020.php b/user_guide_src/source/helpers/text_helper/020.php index 2a4f595f3655..8b2606aea1bf 100644 --- a/user_guide_src/source/helpers/text_helper/020.php +++ b/user_guide_src/source/helpers/text_helper/020.php @@ -1,6 +1,6 @@ getHeaderLine('accept-encoding'); +echo 'Accept-Encoding: ' . $request->getHeaderLine('accept-encoding'); diff --git a/user_guide_src/source/incoming/incomingrequest/019.php b/user_guide_src/source/incoming/incomingrequest/019.php index 14e917083397..a31ffd384853 100644 --- a/user_guide_src/source/incoming/incomingrequest/019.php +++ b/user_guide_src/source/incoming/incomingrequest/019.php @@ -1,3 +1,3 @@ resource('photos'); // Equivalent to the following: -$routes->get('photos/new', 'Photos::new'); -$routes->post('photos', 'Photos::create'); -$routes->get('photos', 'Photos::index'); -$routes->get('photos/(:segment)', 'Photos::show/$1'); +$routes->get('photos/new', 'Photos::new'); +$routes->post('photos', 'Photos::create'); +$routes->get('photos', 'Photos::index'); +$routes->get('photos/(:segment)', 'Photos::show/$1'); $routes->get('photos/(:segment)/edit', 'Photos::edit/$1'); -$routes->put('photos/(:segment)', 'Photos::update/$1'); -$routes->patch('photos/(:segment)', 'Photos::update/$1'); -$routes->delete('photos/(:segment)', 'Photos::delete/$1'); +$routes->put('photos/(:segment)', 'Photos::update/$1'); +$routes->patch('photos/(:segment)', 'Photos::update/$1'); +$routes->delete('photos/(:segment)', 'Photos::delete/$1'); diff --git a/user_guide_src/source/incoming/restful/002.php b/user_guide_src/source/incoming/restful/002.php index cc879a2ab667..67ce23393964 100644 --- a/user_guide_src/source/incoming/restful/002.php +++ b/user_guide_src/source/incoming/restful/002.php @@ -4,4 +4,4 @@ // The following equivalent routes are created: $routes->post('photos/(:segment)/delete', 'Photos::delete/$1'); -$routes->post('photos/(:segment)', 'Photos::update/$1'); +$routes->post('photos/(:segment)', 'Photos::update/$1'); diff --git a/user_guide_src/source/incoming/restful/003.php b/user_guide_src/source/incoming/restful/003.php index 1485f3c4edea..6610555f0a5f 100644 --- a/user_guide_src/source/incoming/restful/003.php +++ b/user_guide_src/source/incoming/restful/003.php @@ -1,6 +1,6 @@ resource('photos', ['controller' =>'App\Gallery']); +$routes->resource('photos', ['controller' => 'App\Gallery']); // Would create routes like: $routes->get('photos', 'App\Gallery::index'); diff --git a/user_guide_src/source/incoming/restful/009.php b/user_guide_src/source/incoming/restful/009.php index 5918a044fab5..25e069258781 100644 --- a/user_guide_src/source/incoming/restful/009.php +++ b/user_guide_src/source/incoming/restful/009.php @@ -3,13 +3,13 @@ $routes->presenter('photos'); // Equivalent to the following: -$routes->get('photos/new', 'Photos::new'); -$routes->post('photos/create', 'Photos::create'); -$routes->post('photos', 'Photos::create'); // alias -$routes->get('photos', 'Photos::index'); -$routes->get('photos/show/(:segment)', 'Photos::show/$1'); -$routes->get('photos/(:segment)', 'Photos::show/$1'); // alias -$routes->get('photos/edit/(:segment)', 'Photos::edit/$1'); +$routes->get('photos/new', 'Photos::new'); +$routes->post('photos/create', 'Photos::create'); +$routes->post('photos', 'Photos::create'); // alias +$routes->get('photos', 'Photos::index'); +$routes->get('photos/show/(:segment)', 'Photos::show/$1'); +$routes->get('photos/(:segment)', 'Photos::show/$1'); // alias +$routes->get('photos/edit/(:segment)', 'Photos::edit/$1'); $routes->post('photos/update/(:segment)', 'Photos::update/$1'); -$routes->get('photos/remove/(:segment)', 'Photos::remove/$1'); +$routes->get('photos/remove/(:segment)', 'Photos::remove/$1'); $routes->post('photos/delete/(:segment)', 'Photos::delete/$1'); diff --git a/user_guide_src/source/incoming/restful/011.php b/user_guide_src/source/incoming/restful/011.php index 5c949d80cc29..cbb6f13bdf85 100644 --- a/user_guide_src/source/incoming/restful/011.php +++ b/user_guide_src/source/incoming/restful/011.php @@ -1,6 +1,6 @@ presenter('photos', ['controller' =>'App\Gallery']); +$routes->presenter('photos', ['controller' => 'App\Gallery']); // Would create routes like: $routes->get('photos', 'App\Gallery::index'); diff --git a/user_guide_src/source/incoming/restful/015.php b/user_guide_src/source/incoming/restful/015.php index fc5713b20d61..0600f7c686ef 100644 --- a/user_guide_src/source/incoming/restful/015.php +++ b/user_guide_src/source/incoming/restful/015.php @@ -6,7 +6,6 @@ class Photos extends ResourcePresenter { - protected $modelName = 'App\Models\Photos'; public function index() diff --git a/user_guide_src/source/incoming/routing/002.php b/user_guide_src/source/incoming/routing/002.php index 4ddfd31abaed..030ac6d25045 100644 --- a/user_guide_src/source/incoming/routing/002.php +++ b/user_guide_src/source/incoming/routing/002.php @@ -4,4 +4,4 @@ $routes->get('users', 'Users::list'); // Calls $Users->list(1, 23) -$routes->get('users/1/23', 'Users::list/1/23'); \ No newline at end of file +$routes->get('users/1/23', 'Users::list/1/23'); diff --git a/user_guide_src/source/incoming/routing/016.php b/user_guide_src/source/incoming/routing/016.php index 2d0f48cb284e..e4fc5bde4a68 100644 --- a/user_guide_src/source/incoming/routing/016.php +++ b/user_guide_src/source/incoming/routing/016.php @@ -1,6 +1,6 @@ get('feed', function () { +$routes->get('feed', static function () { $rss = new RSSFeeder(); return $rss->feed('general'); diff --git a/user_guide_src/source/incoming/routing/019.php b/user_guide_src/source/incoming/routing/019.php index 8c770fd05f24..6f08c319c551 100644 --- a/user_guide_src/source/incoming/routing/019.php +++ b/user_guide_src/source/incoming/routing/019.php @@ -1,6 +1,6 @@ group('admin', function ($routes) { +$routes->group('admin', static function ($routes) { $routes->get('users', 'Admin\Users::index'); $routes->get('blog', 'Admin\Blog::index'); }); diff --git a/user_guide_src/source/incoming/routing/020.php b/user_guide_src/source/incoming/routing/020.php index 678e90700e74..7c66c3b693dd 100644 --- a/user_guide_src/source/incoming/routing/020.php +++ b/user_guide_src/source/incoming/routing/020.php @@ -1,5 +1,5 @@ group('api', ['namespace' => 'App\API\v1'], function ($routes) { +$routes->group('api', ['namespace' => 'App\API\v1'], static function ($routes) { $routes->resource('users'); }); diff --git a/user_guide_src/source/incoming/routing/021.php b/user_guide_src/source/incoming/routing/021.php index 395ddfe6c8c8..75cec09100cb 100644 --- a/user_guide_src/source/incoming/routing/021.php +++ b/user_guide_src/source/incoming/routing/021.php @@ -1,5 +1,5 @@ group('api', ['filter' => 'api-auth'], function ($routes) { +$routes->group('api', ['filter' => 'api-auth'], static function ($routes) { $routes->resource('users'); }); diff --git a/user_guide_src/source/incoming/routing/022.php b/user_guide_src/source/incoming/routing/022.php index 08169acec275..1ed2a8a96ee6 100644 --- a/user_guide_src/source/incoming/routing/022.php +++ b/user_guide_src/source/incoming/routing/022.php @@ -1,7 +1,7 @@ group('admin', function ($routes) { - $routes->group('users', function ($routes) { +$routes->group('admin', static function ($routes) { + $routes->group('users', static function ($routes) { $routes->get('list', 'Admin\Users::list'); }); }); diff --git a/user_guide_src/source/incoming/routing/024.php b/user_guide_src/source/incoming/routing/024.php index 69a4c184ab36..53921b33f5eb 100644 --- a/user_guide_src/source/incoming/routing/024.php +++ b/user_guide_src/source/incoming/routing/024.php @@ -1,5 +1,5 @@ environment('development', function ($routes) { +$routes->environment('development', static function ($routes) { $routes->get('builder', 'Tools\Builder::index'); }); diff --git a/user_guide_src/source/incoming/routing/025.php b/user_guide_src/source/incoming/routing/025.php index 3379179f4be1..e6bc6bdfb65f 100644 --- a/user_guide_src/source/incoming/routing/025.php +++ b/user_guide_src/source/incoming/routing/025.php @@ -5,6 +5,6 @@ ?> - + View Gallery diff --git a/user_guide_src/source/incoming/routing/026.php b/user_guide_src/source/incoming/routing/026.php index 604e9f95b26e..1c1c629893e3 100644 --- a/user_guide_src/source/incoming/routing/026.php +++ b/user_guide_src/source/incoming/routing/026.php @@ -5,6 +5,6 @@ ?> - + View Gallery diff --git a/user_guide_src/source/incoming/routing/029.php b/user_guide_src/source/incoming/routing/029.php index fad1213d3f22..ff7e995a1526 100644 --- a/user_guide_src/source/incoming/routing/029.php +++ b/user_guide_src/source/incoming/routing/029.php @@ -11,4 +11,4 @@ $routes->match(['get', 'put'], 'from', 'to', $options); $routes->resource('photos', $options); $routes->map($array, $options); -$routes->group('name', $options, function (){}); +$routes->group('name', $options, static function () {}); diff --git a/user_guide_src/source/incoming/routing/030.php b/user_guide_src/source/incoming/routing/030.php index ca1121e0786d..2515937bb02a 100644 --- a/user_guide_src/source/incoming/routing/030.php +++ b/user_guide_src/source/incoming/routing/030.php @@ -1,3 +1,3 @@ get('admin',' AdminController::index', ['filter' => 'admin-auth']); +$routes->get('admin', ' AdminController::index', ['filter' => 'admin-auth']); diff --git a/user_guide_src/source/incoming/routing/032.php b/user_guide_src/source/incoming/routing/032.php index 14d5142de2f0..dd6cd63ba61d 100644 --- a/user_guide_src/source/incoming/routing/032.php +++ b/user_guide_src/source/incoming/routing/032.php @@ -1,3 +1,3 @@ get('admin',' AdminController::index', ['filter' => \App\Filters\SomeFilter::class]); +$routes->get('admin', ' AdminController::index', ['filter' => \App\Filters\SomeFilter::class]); diff --git a/user_guide_src/source/incoming/routing/033.php b/user_guide_src/source/incoming/routing/033.php index 24cf6c5dbc2d..94ae43246897 100644 --- a/user_guide_src/source/incoming/routing/033.php +++ b/user_guide_src/source/incoming/routing/033.php @@ -1,3 +1,3 @@ get('admin',' AdminController::index', ['filter' => ['admin-auth', \App\Filters\SomeFilter::class]]); +$routes->get('admin', ' AdminController::index', ['filter' => ['admin-auth', \App\Filters\SomeFilter::class]]); diff --git a/user_guide_src/source/incoming/routing/047.php b/user_guide_src/source/incoming/routing/047.php index 1f3758e244d4..dddd067f0f26 100644 --- a/user_guide_src/source/incoming/routing/047.php +++ b/user_guide_src/source/incoming/routing/047.php @@ -4,7 +4,6 @@ $routes->set404Override('App\Errors::show404'); // Will display a custom view -$routes->set404Override(function () -{ +$routes->set404Override(static function () { echo view('my_errors/not_found.html'); }); diff --git a/user_guide_src/source/installation/troubleshooting/001.php b/user_guide_src/source/installation/troubleshooting/001.php index 65f74aae9efc..54f5c279f554 100644 --- a/user_guide_src/source/installation/troubleshooting/001.php +++ b/user_guide_src/source/installation/troubleshooting/001.php @@ -7,8 +7,8 @@ class App extends BaseConfig { // ... - + public $indexPage = 'index.php'; - + // ... } diff --git a/user_guide_src/source/installation/upgrade_database/002.php b/user_guide_src/source/installation/upgrade_database/002.php index 65fdc4c24d1b..18a1e627fe80 100644 --- a/user_guide_src/source/installation/upgrade_database/002.php +++ b/user_guide_src/source/installation/upgrade_database/002.php @@ -3,6 +3,6 @@ $builder = $db->table('mytable'); $query = $builder->select('title') - ->where('id', $id) - ->limit(10, 20) - ->get(); + ->where('id', $id) + ->limit(10, 20) + ->get(); diff --git a/user_guide_src/source/installation/upgrade_encryption/002.php b/user_guide_src/source/installation/upgrade_encryption/002.php index 91b00ee54e83..695d69e24a28 100644 --- a/user_guide_src/source/installation/upgrade_encryption/002.php +++ b/user_guide_src/source/installation/upgrade_encryption/002.php @@ -2,7 +2,7 @@ $encrypter = service('encrypter'); -$plainText = 'This is a plain-text message!'; +$plainText = 'This is a plain-text message!'; $ciphertext = $encrypter->encrypt($plainText); // Outputs: This is a plain-text message! diff --git a/user_guide_src/source/installation/upgrade_file_upload/002.php b/user_guide_src/source/installation/upgrade_file_upload/002.php index 29de4bf665dc..6a4e6c88e250 100644 --- a/user_guide_src/source/installation/upgrade_file_upload/002.php +++ b/user_guide_src/source/installation/upgrade_file_upload/002.php @@ -2,8 +2,8 @@ namespace App\Controllers; -class Upload extends BaseController { - +class Upload extends BaseController +{ public function index() { echo view('upload_form', ['error' => ' ']); @@ -14,13 +14,13 @@ public function do_upload() $this->validate([ 'userfile' => 'uploaded[userfile]|max_size[userfile,100]' . '|mime_in[userfile,image/png,image/jpg,image/gif]' - . '|ext_in[userfile,png,jpg,gif]|max_dims[userfile,1024,768]' + . '|ext_in[userfile,png,jpg,gif]|max_dims[userfile,1024,768]', ]); $file = $this->request->getFile('userfile'); if (! $path = $file->store()) { - echo view('upload_form', ['error' => "upload failed"]); + echo view('upload_form', ['error' => 'upload failed']); } else { $data = ['upload_file_path' => $path]; diff --git a/user_guide_src/source/installation/upgrade_localization/001.php b/user_guide_src/source/installation/upgrade_localization/001.php index 731d1c5f2430..7248a03e3c72 100644 --- a/user_guide_src/source/installation/upgrade_localization/001.php +++ b/user_guide_src/source/installation/upgrade_localization/001.php @@ -7,8 +7,8 @@ class App extends BaseConfig { // ... - + public $defaultLocale = 'en'; - + // ... } diff --git a/user_guide_src/source/installation/upgrade_validations/001.php b/user_guide_src/source/installation/upgrade_validations/001.php index f9730b8f3e3f..36ec03941532 100644 --- a/user_guide_src/source/installation/upgrade_validations/001.php +++ b/user_guide_src/source/installation/upgrade_validations/001.php @@ -3,5 +3,5 @@ $isValid = $this->validate([ 'name' => 'required|min_length[3]', 'email' => 'required|valid_email', - 'phone' => 'required|numeric|max_length[10]' + 'phone' => 'required|numeric|max_length[10]', ]); diff --git a/user_guide_src/source/installation/upgrade_view_parser/002.php b/user_guide_src/source/installation/upgrade_view_parser/002.php index 2f4607092635..6bef47ef69ec 100644 --- a/user_guide_src/source/installation/upgrade_view_parser/002.php +++ b/user_guide_src/source/installation/upgrade_view_parser/002.php @@ -4,7 +4,7 @@ $data = [ 'blog_title' => 'My Blog Title', - 'blog_heading' => 'My Blog Heading' + 'blog_heading' => 'My Blog Heading', ]; echo $parser->setData($data) diff --git a/user_guide_src/source/libraries/cookies/003.php b/user_guide_src/source/libraries/cookies/003.php index 2b41c1e4209f..f878ff8592d1 100644 --- a/user_guide_src/source/libraries/cookies/003.php +++ b/user_guide_src/source/libraries/cookies/003.php @@ -4,7 +4,7 @@ use Config\Cookie as CookieConfig; $oldDefaults = Cookie::setDefaults(new CookieConfig()); -$cookie = new Cookie('my_token', 'muffins'); +$cookie = new Cookie('my_token', 'muffins'); // return the old defaults Cookie::setDefaults($oldDefaults); diff --git a/user_guide_src/source/libraries/curlrequest/003.php b/user_guide_src/source/libraries/curlrequest/003.php index 9eb5d0d1e591..5f02e4f18c00 100644 --- a/user_guide_src/source/libraries/curlrequest/003.php +++ b/user_guide_src/source/libraries/curlrequest/003.php @@ -2,6 +2,6 @@ $options = [ 'baseURI' => 'http://example.com/api/v1/', - 'timeout' => 3, + 'timeout' => 3, ]; $client = \Config\Services::curlrequest($options); diff --git a/user_guide_src/source/libraries/curlrequest/010.php b/user_guide_src/source/libraries/curlrequest/010.php index e13fa1c5e7e3..12e892980beb 100644 --- a/user_guide_src/source/libraries/curlrequest/010.php +++ b/user_guide_src/source/libraries/curlrequest/010.php @@ -5,5 +5,5 @@ // Get all headers foreach ($response->getHeaders() as $name => $value) { - echo $name .': '. $response->getHeaderLine($name) ."\n"; + echo $name . ': ' . $response->getHeaderLine($name) . "\n"; } diff --git a/user_guide_src/source/libraries/curlrequest/015.php b/user_guide_src/source/libraries/curlrequest/015.php index c8c85ee7f116..136a6ca13286 100644 --- a/user_guide_src/source/libraries/curlrequest/015.php +++ b/user_guide_src/source/libraries/curlrequest/015.php @@ -2,5 +2,5 @@ $client->request('GET', 'http://example.com', ['allow_redirects' => [ 'max' => 10, - 'protocols' => ['https'] // Force HTTPS domains only. + 'protocols' => ['https'], // Force HTTPS domains only. ]]); diff --git a/user_guide_src/source/libraries/curlrequest/017.php b/user_guide_src/source/libraries/curlrequest/017.php index fbc6302a68ec..3f6012cfb70b 100644 --- a/user_guide_src/source/libraries/curlrequest/017.php +++ b/user_guide_src/source/libraries/curlrequest/017.php @@ -1,3 +1,3 @@ setBody($body) ->request('put', 'http://example.com'); +$client->setBody($body)->request('put', 'http://example.com'); diff --git a/user_guide_src/source/libraries/email/013.php b/user_guide_src/source/libraries/email/013.php index 744360f49cc1..60147e305d34 100644 --- a/user_guide_src/source/libraries/email/013.php +++ b/user_guide_src/source/libraries/email/013.php @@ -1,12 +1,11 @@ $address) -{ +foreach ($list as $name => $address) { $email->clear(); $email->setTo($address); $email->setFrom('your@example.com'); - $email->setSubject('Here is your info '.$name); + $email->setSubject('Here is your info ' . $name); $email->setMessage('Hi ' . $name . ' Here is the info you requested.'); $email->send(); } diff --git a/user_guide_src/source/libraries/email/022.php b/user_guide_src/source/libraries/email/022.php index a6d9bfadeb70..80dcaf8d85ce 100644 --- a/user_guide_src/source/libraries/email/022.php +++ b/user_guide_src/source/libraries/email/022.php @@ -6,6 +6,6 @@ foreach ($list as $address) { $email->setTo($address); $cid = $email->setAttachmentCID($filename); - $email->setMessage('photo1'); + $email->setMessage('photo1'); $email->send(); } diff --git a/user_guide_src/source/libraries/encryption/002.php b/user_guide_src/source/libraries/encryption/002.php index c7dccced0797..62061dbd928d 100644 --- a/user_guide_src/source/libraries/encryption/002.php +++ b/user_guide_src/source/libraries/encryption/002.php @@ -1,6 +1,6 @@ encrypt($plainText); // Outputs: This is a plain-text message! diff --git a/user_guide_src/source/libraries/encryption/005.php b/user_guide_src/source/libraries/encryption/005.php index cbc92a5d1be1..df42a88d3a08 100644 --- a/user_guide_src/source/libraries/encryption/005.php +++ b/user_guide_src/source/libraries/encryption/005.php @@ -7,6 +7,6 @@ class Encryption extends BaseConfig { public $key = 'YOUR KEY'; - + // ... } diff --git a/user_guide_src/source/libraries/files/004.php b/user_guide_src/source/libraries/files/004.php index e73de3b6cd74..e3998d56af19 100644 --- a/user_guide_src/source/libraries/files/004.php +++ b/user_guide_src/source/libraries/files/004.php @@ -1,3 +1,3 @@ getSize(); // 256901 +$size = $file->getSize(); // 256901 diff --git a/user_guide_src/source/libraries/images/011.php b/user_guide_src/source/libraries/images/011.php index c72932893af8..f18fb55545a1 100644 --- a/user_guide_src/source/libraries/images/011.php +++ b/user_guide_src/source/libraries/images/011.php @@ -7,5 +7,5 @@ \Config\Services::image('imagick') ->withFile('/path/to/image/mypic.png') - ->flatten(25,25,112) + ->flatten(25, 25, 112) ->save('/path/to/new/image.jpg'); diff --git a/user_guide_src/source/libraries/images/014.php b/user_guide_src/source/libraries/images/014.php index 4afd1e12d420..32943ed142c6 100644 --- a/user_guide_src/source/libraries/images/014.php +++ b/user_guide_src/source/libraries/images/014.php @@ -8,6 +8,6 @@ 'withShadow' => true, 'hAlign' => 'center', 'vAlign' => 'bottom', - 'fontSize' => 20 + 'fontSize' => 20, ]) ->save('/path/to/new/image.jpg'); diff --git a/user_guide_src/source/libraries/pagination/005.php b/user_guide_src/source/libraries/pagination/005.php index 149f369b321c..dec2c3161e76 100644 --- a/user_guide_src/source/libraries/pagination/005.php +++ b/user_guide_src/source/libraries/pagination/005.php @@ -1,6 +1,6 @@ paginate(10, 'group1', $page); diff --git a/user_guide_src/source/libraries/publisher/005.php b/user_guide_src/source/libraries/publisher/005.php index 5d598c3f7d1c..d369073dd6df 100644 --- a/user_guide_src/source/libraries/publisher/005.php +++ b/user_guide_src/source/libraries/publisher/005.php @@ -3,8 +3,7 @@ use CodeIgniter\CLI\CLI; use CodeIgniter\Publisher\Publisher; -foreach (Publisher::discover() as $publisher) -{ +foreach (Publisher::discover() as $publisher) { $result = $publisher->publish(); if ($result === false) { diff --git a/user_guide_src/source/libraries/publisher/009.php b/user_guide_src/source/libraries/publisher/009.php index 4756956740bd..1e840ce9da2c 100644 --- a/user_guide_src/source/libraries/publisher/009.php +++ b/user_guide_src/source/libraries/publisher/009.php @@ -27,8 +27,6 @@ class BootstrapPublisher extends Publisher /** * Use the "publish" method to indicate that this * class is ready to be discovered and automated. - * - * @return boolean */ public function publish(): bool { diff --git a/user_guide_src/source/libraries/publisher/010.php b/user_guide_src/source/libraries/publisher/010.php index 3ea9c40e24b6..652322fd0bcb 100644 --- a/user_guide_src/source/libraries/publisher/010.php +++ b/user_guide_src/source/libraries/publisher/010.php @@ -28,6 +28,7 @@ public function run(array $params) ])->merge(false); // Be careful not to overwrite anything } catch (Throwable $e) { $this->showError($e); + return; } diff --git a/user_guide_src/source/libraries/sessions/014.php b/user_guide_src/source/libraries/sessions/014.php index 50b76d2409b5..45bce58b5e06 100644 --- a/user_guide_src/source/libraries/sessions/014.php +++ b/user_guide_src/source/libraries/sessions/014.php @@ -2,6 +2,6 @@ // returns false if the 'some_name' item doesn't exist or is null, // true otherwise: -if(isset($_SESSION['some_name'])) { +if (isset($_SESSION['some_name'])) { // ... } diff --git a/user_guide_src/source/libraries/sessions/016.php b/user_guide_src/source/libraries/sessions/016.php index ef48af6552cc..e80a0177905a 100644 --- a/user_guide_src/source/libraries/sessions/016.php +++ b/user_guide_src/source/libraries/sessions/016.php @@ -1,3 +1,3 @@ push('hobbies', ['sport'=>'tennis']); +$session->push('hobbies', ['sport' => 'tennis']); diff --git a/user_guide_src/source/libraries/sessions/029.php b/user_guide_src/source/libraries/sessions/029.php index 978341190b52..fd8d241ad069 100644 --- a/user_guide_src/source/libraries/sessions/029.php +++ b/user_guide_src/source/libraries/sessions/029.php @@ -6,6 +6,6 @@ // 'item' will be erased after 300 seconds, while 'item2' // will do so after only 240 seconds $session->markAsTempdata([ - 'item' => 300, - 'item2' => 240, + 'item' => 300, + 'item2' => 240, ]); diff --git a/user_guide_src/source/libraries/time/030.php b/user_guide_src/source/libraries/time/030.php index 929a9f272e28..243416cbbdb5 100644 --- a/user_guide_src/source/libraries/time/030.php +++ b/user_guide_src/source/libraries/time/030.php @@ -1,6 +1,6 @@ setTimestamp(strtotime('April 1, 2017')); echo $time->toDateTimeString(); // 2017-05-10 00:00:00 diff --git a/user_guide_src/source/libraries/uploaded_files/002.php b/user_guide_src/source/libraries/uploaded_files/002.php index f186d517fd96..11c6b18698d4 100644 --- a/user_guide_src/source/libraries/uploaded_files/002.php +++ b/user_guide_src/source/libraries/uploaded_files/002.php @@ -39,10 +39,9 @@ public function upload() $data = ['uploaded_flleinfo' => new File($filepath)]; return view('upload_success', $data); - } else { - $data = ['errors' => 'The file has already been moved.']; - - return view('upload_form', $data); } + $data = ['errors' => 'The file has already been moved.']; + + return view('upload_form', $data); } } diff --git a/user_guide_src/source/libraries/uploaded_files/009.php b/user_guide_src/source/libraries/uploaded_files/009.php index f37491c04821..f0be5ba1aafb 100644 --- a/user_guide_src/source/libraries/uploaded_files/009.php +++ b/user_guide_src/source/libraries/uploaded_files/009.php @@ -1,7 +1,7 @@ request->getFiles()) { - foreach($imagefile['images'] as $img) { + foreach ($imagefile['images'] as $img) { if ($img->isValid() && ! $img->hasMoved()) { $newName = $img->getRandomName(); $img->move(WRITEPATH . 'uploads', $newName); diff --git a/user_guide_src/source/libraries/uri/023.php b/user_guide_src/source/libraries/uri/023.php index 8c611f066c28..34e8764cd045 100644 --- a/user_guide_src/source/libraries/uri/023.php +++ b/user_guide_src/source/libraries/uri/023.php @@ -3,6 +3,6 @@ // URI = http://example.com/users/15/profile // Prints '15' -if ($uri->getSegment(1) == 'users') { +if ($uri->getSegment(1) === 'users') { echo $uri->getSegment(2); } diff --git a/user_guide_src/source/libraries/validation/002.php b/user_guide_src/source/libraries/validation/002.php index 1cc4b9e188ab..30b845e20701 100644 --- a/user_guide_src/source/libraries/validation/002.php +++ b/user_guide_src/source/libraries/validation/002.php @@ -4,7 +4,7 @@ 'username' => 'required', 'password' => 'required|min_length[10]', 'passconf' => 'required|matches[password]', - 'email' => 'required|valid_email', + 'email' => 'required|valid_email', ])) { // ... } diff --git a/user_guide_src/source/libraries/validation/004.php b/user_guide_src/source/libraries/validation/004.php index 60b31dec6d82..01e5f9b648bd 100644 --- a/user_guide_src/source/libraries/validation/004.php +++ b/user_guide_src/source/libraries/validation/004.php @@ -1,3 +1,3 @@ 4, + 'id' => 4, 'email' => 'foo@example.com', ]; diff --git a/user_guide_src/source/libraries/validation/023.php b/user_guide_src/source/libraries/validation/023.php index 5d0618b338ee..f9ba86d1f60c 100644 --- a/user_guide_src/source/libraries/validation/023.php +++ b/user_guide_src/source/libraries/validation/023.php @@ -1,8 +1,9 @@ setRules([ +$validation->setRules( + [ 'username' => 'required|is_unique[users.username]', - 'password' => 'required|min_length[10]' + 'password' => 'required|min_length[10]', ], [ // Errors 'username' => [ diff --git a/user_guide_src/source/libraries/validation/024.php b/user_guide_src/source/libraries/validation/024.php index b6b7c7464a5d..84478a772271 100644 --- a/user_guide_src/source/libraries/validation/024.php +++ b/user_guide_src/source/libraries/validation/024.php @@ -1,6 +1,7 @@ setRules([ +$validation->setRules( + [ 'username' => [ 'label' => 'Username', 'rules' => 'required|is_unique[users.username]', @@ -14,6 +15,6 @@ 'errors' => [ 'min_length' => 'Your {field} is too short. You want to get hacked?', ], - ] + ], ] ); diff --git a/user_guide_src/source/libraries/validation/025.php b/user_guide_src/source/libraries/validation/025.php index 50bd0147aaf2..f04a161f4f47 100644 --- a/user_guide_src/source/libraries/validation/025.php +++ b/user_guide_src/source/libraries/validation/025.php @@ -1,6 +1,7 @@ setRules([ +$validation->setRules( + [ 'username' => [ 'label' => 'Rules.username', 'rules' => 'required|is_unique[users.username]', diff --git a/user_guide_src/source/libraries/validation/030.php b/user_guide_src/source/libraries/validation/030.php index 0da86ca2d054..abac67b15dec 100644 --- a/user_guide_src/source/libraries/validation/030.php +++ b/user_guide_src/source/libraries/validation/030.php @@ -2,5 +2,5 @@ $errors = [ 'username' => 'The username field must be unique.', - 'email' => 'You must provide a valid email address.' + 'email' => 'You must provide a valid email address.', ]; diff --git a/user_guide_src/source/libraries/validation/033.php b/user_guide_src/source/libraries/validation/033.php index d7a10b5071cd..282bef9aabbc 100644 --- a/user_guide_src/source/libraries/validation/033.php +++ b/user_guide_src/source/libraries/validation/033.php @@ -4,6 +4,6 @@ class MyRules { public function even(string $str): bool { - return (int) $str % 2 == 0; + return (int) $str % 2 === 0; } } diff --git a/user_guide_src/source/libraries/validation/036.php b/user_guide_src/source/libraries/validation/036.php index 491c528e87e4..9e13c663b0d7 100644 --- a/user_guide_src/source/libraries/validation/036.php +++ b/user_guide_src/source/libraries/validation/036.php @@ -28,9 +28,7 @@ public function required_with($str, string $fields, array $data): bool // Remove any keys with empty values since, that means they // weren't truly there, as far as this is concerned. - $requiredFields = array_filter($requiredFields, static function ($item) use ($data) { - return ! empty($data[$item]); - }); + $requiredFields = array_filter($requiredFields, static fn ($item) => ! empty($data[$item])); return empty($requiredFields); } diff --git a/user_guide_src/source/libraries/validation/037.php b/user_guide_src/source/libraries/validation/037.php index 089b0eeaf465..f37307b0ae07 100644 --- a/user_guide_src/source/libraries/validation/037.php +++ b/user_guide_src/source/libraries/validation/037.php @@ -3,8 +3,8 @@ // is_unique[table.field,ignore_field,ignore_value] $validation->setRules([ - 'name' => "is_unique[supplier.name,uuid, $uuid]", // is not ok - 'name' => "is_unique[supplier.name,uuid,$uuid ]", // is not ok - 'name' => "is_unique[supplier.name,uuid,$uuid]", // is ok - 'name' => "is_unique[supplier.name,uuid,{uuid}]", // is ok - see "Validation Placeholders" + 'name' => "is_unique[supplier.name,uuid, {$uuid}]", // is not ok + 'name' => "is_unique[supplier.name,uuid,{$uuid} ]", // is not ok + 'name' => "is_unique[supplier.name,uuid,{$uuid}]", // is ok + 'name' => 'is_unique[supplier.name,uuid,{uuid}]', // is ok - see "Validation Placeholders" ]); diff --git a/user_guide_src/source/models/entities/003.php b/user_guide_src/source/models/entities/003.php index c8cfd58c14db..3b50b6691d0d 100644 --- a/user_guide_src/source/models/entities/003.php +++ b/user_guide_src/source/models/entities/003.php @@ -16,7 +16,7 @@ $userModel->save($user); // Create -$user = new \App\Entities\User(); +$user = new \App\Entities\User(); $user->username = 'foo'; $user->email = 'foo@example.com'; $userModel->save($user); diff --git a/user_guide_src/source/models/entities/017.php b/user_guide_src/source/models/entities/017.php index 422a28cd1c37..cfbd01207678 100644 --- a/user_guide_src/source/models/entities/017.php +++ b/user_guide_src/source/models/entities/017.php @@ -9,7 +9,7 @@ class CastBase64 extends BaseCast { public static function get($value, array $params = []) { - return base64_decode($value); + return base64_decode($value, true); } public static function set($value, array $params = []) diff --git a/user_guide_src/source/models/model/001.php b/user_guide_src/source/models/model/001.php index ac8ede5c3dec..c9074ddda6cd 100644 --- a/user_guide_src/source/models/model/001.php +++ b/user_guide_src/source/models/model/001.php @@ -12,5 +12,5 @@ // Create shared instance with a supplied database connection // When no namespace is given, it will search through all namespaces // the system knows about and attempt to located the UserModel class. -$db = db_connect('custom'); +$db = db_connect('custom'); $userModel = model('UserModel', true, $db); diff --git a/user_guide_src/source/models/model/007.php b/user_guide_src/source/models/model/007.php index 1c5d65b7d93e..312575c09578 100644 --- a/user_guide_src/source/models/model/007.php +++ b/user_guide_src/source/models/model/007.php @@ -1,3 +1,3 @@ find([1,2,3]); +$users = $userModel->find([1, 2, 3]); diff --git a/user_guide_src/source/models/model/010.php b/user_guide_src/source/models/model/010.php index bc654f2703c9..cdb8fe06588d 100644 --- a/user_guide_src/source/models/model/010.php +++ b/user_guide_src/source/models/model/010.php @@ -1,4 +1,4 @@ where('active', 1) - ->findAll(); + ->findAll(); diff --git a/user_guide_src/source/models/model/012.php b/user_guide_src/source/models/model/012.php index 117771f78ca8..f00b70258b05 100644 --- a/user_guide_src/source/models/model/012.php +++ b/user_guide_src/source/models/model/012.php @@ -1,4 +1,4 @@ where('deleted', 0) - ->first(); + ->first(); diff --git a/user_guide_src/source/models/model/018.php b/user_guide_src/source/models/model/018.php index 8c13a5a85e2a..a5f03a2118dc 100644 --- a/user_guide_src/source/models/model/018.php +++ b/user_guide_src/source/models/model/018.php @@ -1,6 +1,6 @@ whereIn('id', [1,2,3]) + ->whereIn('id', [1, 2, 3]) ->set(['active' => 1]) ->update(); diff --git a/user_guide_src/source/models/model/020.php b/user_guide_src/source/models/model/020.php index ebc37ee608c1..7d659c7fcd36 100644 --- a/user_guide_src/source/models/model/020.php +++ b/user_guide_src/source/models/model/020.php @@ -11,14 +11,14 @@ class Job public function __get($key) { if (property_exists($this, $key)) { - return $this->$key; + return $this->{$key}; } } public function __set($key, $value) { if (property_exists($this, $key)) { - $this->$key = $value; + $this->{$key} = $value; } } } diff --git a/user_guide_src/source/models/model/022.php b/user_guide_src/source/models/model/022.php index e1137c8fa845..0df2b39c0c66 100644 --- a/user_guide_src/source/models/model/022.php +++ b/user_guide_src/source/models/model/022.php @@ -4,7 +4,7 @@ $job = $model->find(15); // Make some changes -$job->name = "Foobar"; +$job->name = 'Foobar'; // Save the changes $model->save($job); diff --git a/user_guide_src/source/models/model/024.php b/user_guide_src/source/models/model/024.php index f6769f061142..cdac096377b2 100644 --- a/user_guide_src/source/models/model/024.php +++ b/user_guide_src/source/models/model/024.php @@ -1,3 +1,3 @@ delete([1,2,3]); +$userModel->delete([1, 2, 3]); diff --git a/user_guide_src/source/models/model/028.php b/user_guide_src/source/models/model/028.php index c9bea660de81..acffbf22be01 100644 --- a/user_guide_src/source/models/model/028.php +++ b/user_guide_src/source/models/model/028.php @@ -1,6 +1,6 @@ setValidationRule($fieldName, $fieldRules); diff --git a/user_guide_src/source/models/model/029.php b/user_guide_src/source/models/model/029.php index 15221f2505a6..b7876797a6e2 100644 --- a/user_guide_src/source/models/model/029.php +++ b/user_guide_src/source/models/model/029.php @@ -2,7 +2,7 @@ $validationRules = [ 'username' => 'required|alpha_numeric_space|min_length[3]', - 'email' => [ + 'email' => [ 'rules' => 'required|valid_email|is_unique[users.email]', 'errors' => [ 'required' => 'We really need your email.', diff --git a/user_guide_src/source/models/model/030.php b/user_guide_src/source/models/model/030.php index deca0d44f722..251f9bade2cd 100644 --- a/user_guide_src/source/models/model/030.php +++ b/user_guide_src/source/models/model/030.php @@ -1,6 +1,6 @@ 'Your name is required here', ]; diff --git a/user_guide_src/source/models/model/039.php b/user_guide_src/source/models/model/039.php index 00ab7df2a766..fa1b37d0f839 100644 --- a/user_guide_src/source/models/model/039.php +++ b/user_guide_src/source/models/model/039.php @@ -1,6 +1,6 @@ 4, - 'email' => 'foo@example.com' + 'id' => 4, + 'email' => 'foo@example.com', ]; diff --git a/user_guide_src/source/models/model/042.php b/user_guide_src/source/models/model/042.php index a3742c451104..7688fa03057f 100644 --- a/user_guide_src/source/models/model/042.php +++ b/user_guide_src/source/models/model/042.php @@ -1,5 +1,5 @@ protect(false) - ->insert($data) - ->protect(true); + ->insert($data) + ->protect(true); diff --git a/user_guide_src/source/models/model/045.php b/user_guide_src/source/models/model/045.php index 9b064dd4fbff..e4d005fb3acc 100644 --- a/user_guide_src/source/models/model/045.php +++ b/user_guide_src/source/models/model/045.php @@ -1,5 +1,5 @@ where('status', 'active') - ->orderBy('last_login', 'asc') - ->findAll(); + ->orderBy('last_login', 'asc') + ->findAll(); diff --git a/user_guide_src/source/models/model/049.php b/user_guide_src/source/models/model/049.php index 0aace6d0fc28..92493d8e47d5 100644 --- a/user_guide_src/source/models/model/049.php +++ b/user_guide_src/source/models/model/049.php @@ -1,6 +1,6 @@ chunk(100, function ($data) { +$userModel->chunk(100, static function ($data) { // do something. // $data is a single row of data. }); diff --git a/user_guide_src/source/outgoing/api_responses/007.php b/user_guide_src/source/outgoing/api_responses/007.php index 568075938d3a..4e30f3e6b6ac 100644 --- a/user_guide_src/source/outgoing/api_responses/007.php +++ b/user_guide_src/source/outgoing/api_responses/007.php @@ -1,4 +1,5 @@ insert($data); + return $this->respondCreated($user); diff --git a/user_guide_src/source/outgoing/api_responses/008.php b/user_guide_src/source/outgoing/api_responses/008.php index 5c1fe47efb65..abbd2322bcda 100644 --- a/user_guide_src/source/outgoing/api_responses/008.php +++ b/user_guide_src/source/outgoing/api_responses/008.php @@ -1,4 +1,5 @@ delete($id); + return $this->respondDeleted(['id' => $id]); diff --git a/user_guide_src/source/outgoing/api_responses/009.php b/user_guide_src/source/outgoing/api_responses/009.php index e7672d94a610..8eea1b15dfaf 100644 --- a/user_guide_src/source/outgoing/api_responses/009.php +++ b/user_guide_src/source/outgoing/api_responses/009.php @@ -1,4 +1,5 @@ respondNoContent(); diff --git a/user_guide_src/source/outgoing/localization/007.php b/user_guide_src/source/outgoing/localization/007.php index adc24e5d6242..035d13bcfb64 100644 --- a/user_guide_src/source/outgoing/localization/007.php +++ b/user_guide_src/source/outgoing/localization/007.php @@ -1,5 +1,5 @@ 'The actual message to be shown.' + 'languageKey' => 'The actual message to be shown.', ]; diff --git a/user_guide_src/source/outgoing/localization/012.php b/user_guide_src/source/outgoing/localization/012.php index 7e3990788c5b..ab4564fece6d 100644 --- a/user_guide_src/source/outgoing/localization/012.php +++ b/user_guide_src/source/outgoing/localization/012.php @@ -8,4 +8,4 @@ ]; // Displays "I have 3 apples." -echo lang('Tests.apples', [ 3 ]); +echo lang('Tests.apples', [3]); diff --git a/user_guide_src/source/outgoing/response/003.php b/user_guide_src/source/outgoing/response/003.php index e8d671f81739..e5bff8cabf2f 100644 --- a/user_guide_src/source/outgoing/response/003.php +++ b/user_guide_src/source/outgoing/response/003.php @@ -2,7 +2,7 @@ $data = [ 'success' => true, - 'id' => 123, + 'id' => 123, ]; return $this->response->setJSON($data); diff --git a/user_guide_src/source/outgoing/response/004.php b/user_guide_src/source/outgoing/response/004.php index 2777aea2795b..0497dea06e58 100644 --- a/user_guide_src/source/outgoing/response/004.php +++ b/user_guide_src/source/outgoing/response/004.php @@ -1,4 +1,4 @@ setHeader('Location', 'http://example.com') - ->setHeader('WWW-Authenticate', 'Negotiate'); + ->setHeader('WWW-Authenticate', 'Negotiate'); diff --git a/user_guide_src/source/outgoing/response/005.php b/user_guide_src/source/outgoing/response/005.php index acc3254fa49a..39276d3f80f1 100644 --- a/user_guide_src/source/outgoing/response/005.php +++ b/user_guide_src/source/outgoing/response/005.php @@ -1,4 +1,4 @@ setHeader('Cache-Control', 'no-cache') - ->appendHeader('Cache-Control', 'must-revalidate'); + ->appendHeader('Cache-Control', 'must-revalidate'); diff --git a/user_guide_src/source/outgoing/response/007.php b/user_guide_src/source/outgoing/response/007.php index c8e545831e00..9f80218ee669 100644 --- a/user_guide_src/source/outgoing/response/007.php +++ b/user_guide_src/source/outgoing/response/007.php @@ -2,4 +2,5 @@ $data = 'Here is some text!'; $name = 'mytext.txt'; + return $response->download($name, $data); diff --git a/user_guide_src/source/outgoing/response/010.php b/user_guide_src/source/outgoing/response/010.php index 724c1fb213a1..93acf62e99fa 100644 --- a/user_guide_src/source/outgoing/response/010.php +++ b/user_guide_src/source/outgoing/response/010.php @@ -3,6 +3,6 @@ $options = [ 'max-age' => 300, 's-maxage' => 900, - 'etag' => 'abcde' + 'etag' => 'abcde', ]; $this->response->setCache($options); diff --git a/user_guide_src/source/outgoing/response/013.php b/user_guide_src/source/outgoing/response/013.php index 8cebd2451096..273d72c29a1d 100644 --- a/user_guide_src/source/outgoing/response/013.php +++ b/user_guide_src/source/outgoing/response/013.php @@ -3,4 +3,4 @@ $response->addChildSrc('https://youtube.com'); // allowed $response->reportOnly(true); $response->addChildSrc('https://metube.com'); // allowed but reported -$response->addChildSrc('https://ourtube.com',false); // allowed +$response->addChildSrc('https://ourtube.com', false); // allowed diff --git a/user_guide_src/source/outgoing/response/016.php b/user_guide_src/source/outgoing/response/016.php index 38d6a8e3b690..31a4990eb9ee 100644 --- a/user_guide_src/source/outgoing/response/016.php +++ b/user_guide_src/source/outgoing/response/016.php @@ -1,3 +1,3 @@ setStatusCode(230, "Tardis initiated"); +$response->setStatusCode(230, 'Tardis initiated'); diff --git a/user_guide_src/source/outgoing/response/023.php b/user_guide_src/source/outgoing/response/023.php index 35d072f354d9..3d0855739e96 100644 --- a/user_guide_src/source/outgoing/response/023.php +++ b/user_guide_src/source/outgoing/response/023.php @@ -1,15 +1,15 @@ 'The Cookie Name', - 'value' => 'The Value', - 'expire' => '86500', - 'domain' => '.some-domain.com', - 'path' => '/', - 'prefix' => 'myprefix_', - 'secure' => true, + 'name' => 'The Cookie Name', + 'value' => 'The Value', + 'expire' => '86500', + 'domain' => '.some-domain.com', + 'path' => '/', + 'prefix' => 'myprefix_', + 'secure' => true, 'httponly' => false, - 'samesite' => 'Lax' + 'samesite' => 'Lax', ]; $response->setCookie($cookie); diff --git a/user_guide_src/source/outgoing/table/005.php b/user_guide_src/source/outgoing/table/005.php index 06eaf75d9f8d..08d6dabb1850 100644 --- a/user_guide_src/source/outgoing/table/005.php +++ b/user_guide_src/source/outgoing/table/005.php @@ -2,7 +2,7 @@ $table = new \CodeIgniter\View\Table(); -$table->setHeading(array('Name', 'Color', 'Size')); +$table->setHeading(['Name', 'Color', 'Size']); $table->addRow(['Fred', 'Blue', 'Small']); $table->addRow(['Mary', 'Red', 'Large']); diff --git a/user_guide_src/source/outgoing/table/006.php b/user_guide_src/source/outgoing/table/006.php index 2bc38b546950..a5955aa5704b 100644 --- a/user_guide_src/source/outgoing/table/006.php +++ b/user_guide_src/source/outgoing/table/006.php @@ -1,38 +1,38 @@ '', + 'table_open' => '
    ', - 'thead_open' => '', - 'thead_close' => '', + 'thead_open' => '', + 'thead_close' => '', 'heading_row_start' => '', 'heading_row_end' => '', 'heading_cell_start' => '', - 'tfoot_open' => '', - 'tfoot_close' => '', + 'tfoot_open' => '', + 'tfoot_close' => '', 'footing_row_start' => '', 'footing_row_end' => '', 'footing_cell_start' => '', - 'tbody_open' => '', - 'tbody_close' => '', + 'tbody_open' => '', + 'tbody_close' => '', - 'row_start' => '', - 'row_end' => '', - 'cell_start' => '', + 'row_start' => '', + 'row_end' => '', + 'cell_start' => '', - 'row_alt_start' => '', - 'row_alt_end' => '', - 'cell_alt_start' => '', + 'row_alt_start' => '', + 'row_alt_end' => '', + 'cell_alt_start' => '', - 'table_close' => '
    ', 'heading_cell_end' => '
    ', 'footing_cell_end' => '
    ', - 'cell_end' => '
    ', + 'cell_end' => '
    ', - 'cell_alt_end' => '
    ', + 'cell_alt_end' => '
    ' + 'table_close' => '', ]; $table->setTemplate($template); diff --git a/user_guide_src/source/outgoing/table/007.php b/user_guide_src/source/outgoing/table/007.php index 307d2e9a6c26..022abfc296ad 100644 --- a/user_guide_src/source/outgoing/table/007.php +++ b/user_guide_src/source/outgoing/table/007.php @@ -1,7 +1,7 @@ '' + 'table_open' => '
    ', ]; $table->setTemplate($template); diff --git a/user_guide_src/source/outgoing/table/008.php b/user_guide_src/source/outgoing/table/008.php index 9d6dbddd40c6..99f12f2b2fcd 100644 --- a/user_guide_src/source/outgoing/table/008.php +++ b/user_guide_src/source/outgoing/table/008.php @@ -1,7 +1,7 @@ '
    ' + 'table_open' => '
    ', ]; $table = new \CodeIgniter\View\Table($customSettings); diff --git a/user_guide_src/source/outgoing/table/016.php b/user_guide_src/source/outgoing/table/016.php index 307d2e9a6c26..022abfc296ad 100644 --- a/user_guide_src/source/outgoing/table/016.php +++ b/user_guide_src/source/outgoing/table/016.php @@ -1,7 +1,7 @@ '
    ' + 'table_open' => '
    ', ]; $table->setTemplate($template); diff --git a/user_guide_src/source/outgoing/table/017.php b/user_guide_src/source/outgoing/table/017.php index 41ecff5926c7..8f7b203a3344 100644 --- a/user_guide_src/source/outgoing/table/017.php +++ b/user_guide_src/source/outgoing/table/017.php @@ -1,3 +1,3 @@ setEmpty(" "); +$table->setEmpty(' '); diff --git a/user_guide_src/source/outgoing/view_parser/003.php b/user_guide_src/source/outgoing/view_parser/003.php index 0eefa68d2781..1ee48b997ae6 100644 --- a/user_guide_src/source/outgoing/view_parser/003.php +++ b/user_guide_src/source/outgoing/view_parser/003.php @@ -6,4 +6,4 @@ ]; echo $parser->setData($data) - ->render('blog_template'); + ->render('blog_template'); diff --git a/user_guide_src/source/outgoing/view_parser/006.php b/user_guide_src/source/outgoing/view_parser/006.php index 1bedecc07c0a..6b1409c46c1d 100644 --- a/user_guide_src/source/outgoing/view_parser/006.php +++ b/user_guide_src/source/outgoing/view_parser/006.php @@ -13,4 +13,4 @@ ]; echo $parser->setData($data) - ->render('blog_template'); + ->render('blog_template'); diff --git a/user_guide_src/source/outgoing/view_parser/007.php b/user_guide_src/source/outgoing/view_parser/007.php index 8932712a7835..032f9d55f268 100644 --- a/user_guide_src/source/outgoing/view_parser/007.php +++ b/user_guide_src/source/outgoing/view_parser/007.php @@ -1,6 +1,6 @@ query("SELECT * FROM blog"); +$query = $db->query('SELECT * FROM blog'); $data = [ 'blog_title' => 'My Blog Title', @@ -9,4 +9,4 @@ ]; echo $parser->setData($data) - ->render('blog_template'); + ->render('blog_template'); diff --git a/user_guide_src/source/outgoing/view_parser/008.php b/user_guide_src/source/outgoing/view_parser/008.php index ef502cf5e3af..62be126a407d 100644 --- a/user_guide_src/source/outgoing/view_parser/008.php +++ b/user_guide_src/source/outgoing/view_parser/008.php @@ -10,4 +10,4 @@ ]; echo $parser->setData($data) - ->render('blog_template'); + ->render('blog_template'); diff --git a/user_guide_src/source/outgoing/view_parser/010.php b/user_guide_src/source/outgoing/view_parser/010.php index 33439f861407..7fcd5bafbfec 100644 --- a/user_guide_src/source/outgoing/view_parser/010.php +++ b/user_guide_src/source/outgoing/view_parser/010.php @@ -7,8 +7,8 @@ 'location' => ['city' => 'Red City', 'planet' => 'Mars'], ]; -echo $parser->setData($data)->renderString($template, ['cascadeData'=>false]); +echo $parser->setData($data)->renderString($template, ['cascadeData' => false]); // Result: {name} lives in Red City on Mars. -echo $parser->setData($data)->renderString($template, ['cascadeData'=>true]); +echo $parser->setData($data)->renderString($template, ['cascadeData' => true]); // Result: George lives in Red City on Mars. diff --git a/user_guide_src/source/outgoing/view_parser/011.php b/user_guide_src/source/outgoing/view_parser/011.php index 8030f44e8883..88e2060b1ed5 100644 --- a/user_guide_src/source/outgoing/view_parser/011.php +++ b/user_guide_src/source/outgoing/view_parser/011.php @@ -1,3 +1,3 @@ - +

    Welcome, Admin!

    diff --git a/user_guide_src/source/outgoing/view_parser/015.php b/user_guide_src/source/outgoing/view_parser/015.php index e499e9805416..c0aa68b3381f 100644 --- a/user_guide_src/source/outgoing/view_parser/015.php +++ b/user_guide_src/source/outgoing/view_parser/015.php @@ -10,9 +10,7 @@ class View extends BaseView public function __construct() { - $this->plugins['bar'] = static function (array $params = []) { - return $params[0] ?? ''; - }; + $this->plugins['bar'] = static fn (array $params = []) => $params[0] ?? ''; parent::__construct(); } diff --git a/user_guide_src/source/outgoing/view_parser/018.php b/user_guide_src/source/outgoing/view_parser/018.php index 64101a6a8cfa..4e039f02a08c 100644 --- a/user_guide_src/source/outgoing/view_parser/018.php +++ b/user_guide_src/source/outgoing/view_parser/018.php @@ -1,11 +1,11 @@ 'Mr', 'firstname' => 'John', - 'lastname' => 'Doe' + 'lastname' => 'Doe', ]; echo $parser->setData($data) - ->renderString($template); + ->renderString($template); // Result: Hello, John Doe diff --git a/user_guide_src/source/outgoing/view_parser/019.php b/user_guide_src/source/outgoing/view_parser/019.php index 2570076b3018..16621ef2f190 100644 --- a/user_guide_src/source/outgoing/view_parser/019.php +++ b/user_guide_src/source/outgoing/view_parser/019.php @@ -1,11 +1,11 @@ 'Mr', 'firstname' => 'John', 'lastname' => 'Doe', ]; echo $parser->setData($data) - ->renderString($template); + ->renderString($template); // Result: Hello, John {initials} Doe diff --git a/user_guide_src/source/outgoing/view_parser/020.php b/user_guide_src/source/outgoing/view_parser/020.php index a7966a9c2bfd..9226793f280d 100644 --- a/user_guide_src/source/outgoing/view_parser/020.php +++ b/user_guide_src/source/outgoing/view_parser/020.php @@ -1,7 +1,7 @@ 'Mr', 'firstname' => 'John', 'lastname' => 'Doe', @@ -11,5 +11,5 @@ ], ]; echo $parser->setData($data) - ->renderString($template); + ->renderString($template); // Result: Hello, John Doe (Mr{degree} {/degrees}) diff --git a/user_guide_src/source/outgoing/view_parser/021.php b/user_guide_src/source/outgoing/view_parser/021.php index 6dce1f1316e2..3c9982437a19 100644 --- a/user_guide_src/source/outgoing/view_parser/021.php +++ b/user_guide_src/source/outgoing/view_parser/021.php @@ -1,19 +1,19 @@ {title}'; -$data1 = [ +$data1 = [ ['title' => 'First Link', 'link' => '/first'], ['title' => 'Second Link', 'link' => '/second'], ]; -foreach ($data1 as $menuItem){ +foreach ($data1 as $menuItem) { $temp .= $parser->setData($menuItem)->renderString($template1); } $template2 = '
      {menuitems}
    '; -$data = [ +$data = [ 'menuitems' => $temp, ]; echo $parser->setData($data) - ->renderString($template2); + ->renderString($template2); diff --git a/user_guide_src/source/outgoing/view_parser/025.php b/user_guide_src/source/outgoing/view_parser/025.php index 76ba0b537f96..8fa85f4faa98 100644 --- a/user_guide_src/source/outgoing/view_parser/025.php +++ b/user_guide_src/source/outgoing/view_parser/025.php @@ -1,3 +1,3 @@ setVar('name','Joe','html'); +$renderer->setVar('name', 'Joe', 'html'); diff --git a/user_guide_src/source/outgoing/view_parser/026.php b/user_guide_src/source/outgoing/view_parser/026.php index a8633d5717c7..46cfd9afd818 100644 --- a/user_guide_src/source/outgoing/view_parser/026.php +++ b/user_guide_src/source/outgoing/view_parser/026.php @@ -1,3 +1,3 @@ setDelimiters('[',']'); +$renderer->setDelimiters('[', ']'); diff --git a/user_guide_src/source/outgoing/view_renderer/003.php b/user_guide_src/source/outgoing/view_renderer/003.php index c4609b018c58..04e8c18a3ca4 100644 --- a/user_guide_src/source/outgoing/view_renderer/003.php +++ b/user_guide_src/source/outgoing/view_renderer/003.php @@ -1,5 +1,5 @@ setVar('one', $one) - ->setVar('two', $two) - ->render('myView'); + ->setVar('two', $two) + ->render('myView'); diff --git a/user_guide_src/source/outgoing/view_renderer/007.php b/user_guide_src/source/outgoing/view_renderer/007.php index 1b45fef3dca5..99080056b1bc 100644 --- a/user_guide_src/source/outgoing/view_renderer/007.php +++ b/user_guide_src/source/outgoing/view_renderer/007.php @@ -1,3 +1,3 @@ setData(['name'=>'George', 'position'=>'Boss']); +$view->setData(['name' => 'George', 'position' => 'Boss']); diff --git a/user_guide_src/source/outgoing/view_renderer/008.php b/user_guide_src/source/outgoing/view_renderer/008.php index 284b58caf6be..f0b868b54bca 100644 --- a/user_guide_src/source/outgoing/view_renderer/008.php +++ b/user_guide_src/source/outgoing/view_renderer/008.php @@ -1,3 +1,3 @@ setVar('name','Joe','html'); +$view->setVar('name', 'Joe', 'html'); diff --git a/user_guide_src/source/testing/benchmark/007.php b/user_guide_src/source/testing/benchmark/007.php index c126ed4a9670..13a95ec66e29 100644 --- a/user_guide_src/source/testing/benchmark/007.php +++ b/user_guide_src/source/testing/benchmark/007.php @@ -3,11 +3,11 @@ $iterator = new \CodeIgniter\Benchmark\Iterator(); // Add a new task -$iterator->add('single_concat', function () { - $str = 'Some basic'.'little'.'string concatenation test.'; +$iterator->add('single_concat', static function () { + $str = 'Some basic' . 'little' . 'string concatenation test.'; }); // Add another task -$iterator->add('double', function ($a = 'little') { +$iterator->add('double', static function ($a = 'little') { $str = "Some basic {$little} string test."; }); diff --git a/user_guide_src/source/testing/controllers/001.php b/user_guide_src/source/testing/controllers/001.php index 9c31d5b62d00..9162fa0aeabd 100644 --- a/user_guide_src/source/testing/controllers/001.php +++ b/user_guide_src/source/testing/controllers/001.php @@ -2,11 +2,12 @@ namespace CodeIgniter; -use CodeIgniter\Test\ControllerTestTrait; use CodeIgniter\Test\CIUnitTestCase; +use CodeIgniter\Test\ControllerTestTrait; use CodeIgniter\Test\DatabaseTestTrait; class TestControllerA extends CIUnitTestCase { - use ControllerTestTrait, DatabaseTestTrait; + use ControllerTestTrait; + use DatabaseTestTrait; } diff --git a/user_guide_src/source/testing/controllers/002.php b/user_guide_src/source/testing/controllers/002.php index 708f7761afbf..a21362e952a2 100644 --- a/user_guide_src/source/testing/controllers/002.php +++ b/user_guide_src/source/testing/controllers/002.php @@ -2,19 +2,20 @@ namespace CodeIgniter; -use CodeIgniter\Test\ControllerTestTrait; use CodeIgniter\Test\CIUnitTestCase; +use CodeIgniter\Test\ControllerTestTrait; use CodeIgniter\Test\DatabaseTestTrait; class TestControllerA extends CIUnitTestCase { - use ControllerTestTrait, DatabaseTestTrait; + use ControllerTestTrait; + use DatabaseTestTrait; public function testShowCategories() { $result = $this->withURI('http://example.com/categories') - ->controller(\App\Controllers\ForumController::class) - ->execute('showCategories'); + ->controller(\App\Controllers\ForumController::class) + ->execute('showCategories'); $this->assertTrue($result->isOK()); } diff --git a/user_guide_src/source/testing/controllers/004.php b/user_guide_src/source/testing/controllers/004.php index d06bb51768c3..17b5f42590ce 100644 --- a/user_guide_src/source/testing/controllers/004.php +++ b/user_guide_src/source/testing/controllers/004.php @@ -1,4 +1,4 @@ controller(\App\Controllers\ForumController::class) - ->execute('showCategories'); + ->execute('showCategories'); diff --git a/user_guide_src/source/testing/controllers/005.php b/user_guide_src/source/testing/controllers/005.php index bffc4c9c8f95..7d2864f5fcbf 100644 --- a/user_guide_src/source/testing/controllers/005.php +++ b/user_guide_src/source/testing/controllers/005.php @@ -1,8 +1,8 @@ appTimezone = 'America/Chicago'; $results = $this->withConfig($config) - ->controller(\App\Controllers\ForumController::class) - ->execute('showCategories'); + ->controller(\App\Controllers\ForumController::class) + ->execute('showCategories'); diff --git a/user_guide_src/source/testing/controllers/006.php b/user_guide_src/source/testing/controllers/006.php index aef7e41e071e..0fc7670487de 100644 --- a/user_guide_src/source/testing/controllers/006.php +++ b/user_guide_src/source/testing/controllers/006.php @@ -4,5 +4,5 @@ $request->setLocale($locale); $results = $this->withRequest($request) - ->controller(\App\Controllers\ForumController::class) - ->execute('showCategories'); + ->controller(\App\Controllers\ForumController::class) + ->execute('showCategories'); diff --git a/user_guide_src/source/testing/controllers/007.php b/user_guide_src/source/testing/controllers/007.php index 73b1d4e122c2..8f7d55448035 100644 --- a/user_guide_src/source/testing/controllers/007.php +++ b/user_guide_src/source/testing/controllers/007.php @@ -3,5 +3,5 @@ $response = new \CodeIgniter\HTTP\Response(new \Config\App()); $results = $this->withResponse($response) - ->controller(\App\Controllers\ForumController::class) - ->execute('showCategories'); + ->controller(\App\Controllers\ForumController::class) + ->execute('showCategories'); diff --git a/user_guide_src/source/testing/controllers/008.php b/user_guide_src/source/testing/controllers/008.php index 4ea1c84dee20..641a7f92f68b 100644 --- a/user_guide_src/source/testing/controllers/008.php +++ b/user_guide_src/source/testing/controllers/008.php @@ -3,6 +3,6 @@ $logger = new \CodeIgniter\Log\Handlers\FileHandler(); $results = $this->withResponse($response) - ->withLogger($logger) - ->controller(\App\Controllers\ForumController::class) - ->execute('showCategories'); + ->withLogger($logger) + ->controller(\App\Controllers\ForumController::class) + ->execute('showCategories'); diff --git a/user_guide_src/source/testing/controllers/009.php b/user_guide_src/source/testing/controllers/009.php index 4559dd8f4711..711d947b4267 100644 --- a/user_guide_src/source/testing/controllers/009.php +++ b/user_guide_src/source/testing/controllers/009.php @@ -1,5 +1,5 @@ withURI('http://example.com/forums/categories') - ->controller(\App\Controllers\ForumController::class) - ->execute('showCategories'); + ->controller(\App\Controllers\ForumController::class) + ->execute('showCategories'); diff --git a/user_guide_src/source/testing/controllers/010.php b/user_guide_src/source/testing/controllers/010.php index 2cf6d9919c31..e257dcbc4928 100644 --- a/user_guide_src/source/testing/controllers/010.php +++ b/user_guide_src/source/testing/controllers/010.php @@ -3,5 +3,5 @@ $body = json_encode(['foo' => 'bar']); $results = $this->withBody($body) - ->controller(\App\Controllers\ForumController::class) - ->execute('showCategories'); + ->controller(\App\Controllers\ForumController::class) + ->execute('showCategories'); diff --git a/user_guide_src/source/testing/database/002.php b/user_guide_src/source/testing/database/002.php index 4b75aa739784..be357858ae62 100644 --- a/user_guide_src/source/testing/database/002.php +++ b/user_guide_src/source/testing/database/002.php @@ -9,14 +9,14 @@ class MyTests extends CIUnitTestCase { use DatabaseTestTrait; - public function setUp(): void + protected function setUp(): void { parent::setUp(); // Do something here.... } - public function tearDown(): void + protected function tearDown(): void { parent::tearDown(); diff --git a/user_guide_src/source/testing/database/003.php b/user_guide_src/source/testing/database/003.php index d293cce95f81..399ddfb04425 100644 --- a/user_guide_src/source/testing/database/003.php +++ b/user_guide_src/source/testing/database/003.php @@ -12,4 +12,4 @@ class MyTests extends CIUnitTestCase protected $refresh = true; protected $seed = 'TestSeeder'; protected $basePath = 'path/to/database/files'; -} \ No newline at end of file +} diff --git a/user_guide_src/source/testing/debugging/006.php b/user_guide_src/source/testing/debugging/006.php index 3140ea7e4a81..3ad25be67894 100644 --- a/user_guide_src/source/testing/debugging/006.php +++ b/user_guide_src/source/testing/debugging/006.php @@ -9,4 +9,4 @@ 'foo' => 'bar', 'bar' => 'baz', ], - ]; +]; diff --git a/user_guide_src/source/testing/fabricator/009.php b/user_guide_src/source/testing/fabricator/009.php index 9c8d366d8684..a82d6063213e 100644 --- a/user_guide_src/source/testing/fabricator/009.php +++ b/user_guide_src/source/testing/fabricator/009.php @@ -1,9 +1,9 @@ "Maynard", - 'email' => "king.alford@example.org", - 'phone' => "201-886-0269 x3767", - 'avatar' => "http://lorempixel.com/800/400/", +[ + 'first' => 'Maynard', + 'email' => 'king.alford@example.org', + 'phone' => '201-886-0269 x3767', + 'avatar' => 'http://lorempixel.com/800/400/', 'login' => null, -); +]; diff --git a/user_guide_src/source/testing/fabricator/012.php b/user_guide_src/source/testing/fabricator/012.php index 89731845f145..98e83b610318 100644 --- a/user_guide_src/source/testing/fabricator/012.php +++ b/user_guide_src/source/testing/fabricator/012.php @@ -1,12 +1,12 @@ 1, - 'first' => "Rachel", - 'email' => "bradley72@gmail.com", - 'phone' => "741-241-2356", - 'avatar' => "http://lorempixel.com/800/400/", + 'first' => 'Rachel', + 'email' => 'bradley72@gmail.com', + 'phone' => '741-241-2356', + 'avatar' => 'http://lorempixel.com/800/400/', 'login' => null, - 'created_at' => "2020-05-08 14:52:10", - 'updated_at' => "2020-05-08 14:52:10", -); + 'created_at' => '2020-05-08 14:52:10', + 'updated_at' => '2020-05-08 14:52:10', +]; diff --git a/user_guide_src/source/testing/fabricator/016.php b/user_guide_src/source/testing/fabricator/016.php index eb9edc657239..8b3f9513280d 100644 --- a/user_guide_src/source/testing/fabricator/016.php +++ b/user_guide_src/source/testing/fabricator/016.php @@ -1,17 +1,17 @@ "Bobby", - 'email' => "latta.kindel@company.org", - 'phone' => "251-806-2169", - 'avatar' => "http://lorempixel.com/800/400/", +[ + 'first' => 'Bobby', + 'email' => 'latta.kindel@company.org', + 'phone' => '251-806-2169', + 'avatar' => 'http://lorempixel.com/800/400/', 'login' => null, -); +]; -array( - 'first' => "Bobby", - 'email' => "melissa.strike@fabricon.us", - 'phone' => "525-214-2656 x23546", - 'avatar' => "http://lorempixel.com/800/400/", +[ + 'first' => 'Bobby', + 'email' => 'melissa.strike@fabricon.us', + 'phone' => '525-214-2656 x23546', + 'avatar' => 'http://lorempixel.com/800/400/', 'login' => null, -); +]; diff --git a/user_guide_src/source/testing/fabricator/018.php b/user_guide_src/source/testing/fabricator/018.php index 60599b602f6e..9eb1dbf0334d 100644 --- a/user_guide_src/source/testing/fabricator/018.php +++ b/user_guide_src/source/testing/fabricator/018.php @@ -1,17 +1,17 @@ "Bobby", - 'email' => "belingadon142@example.org", - 'phone' => "741-857-1933 x1351", - 'avatar' => "http://lorempixel.com/800/400/", +[ + 'first' => 'Bobby', + 'email' => 'belingadon142@example.org', + 'phone' => '741-857-1933 x1351', + 'avatar' => 'http://lorempixel.com/800/400/', 'login' => null, -); +]; -array( - 'first' => "Hans", - 'email' => "hoppifur@metraxalon.com", - 'phone' => "487-235-7006", - 'avatar' => "http://lorempixel.com/800/400/", +[ + 'first' => 'Hans', + 'email' => 'hoppifur@metraxalon.com', + 'phone' => '487-235-7006', + 'avatar' => 'http://lorempixel.com/800/400/', 'login' => null, -); +]; diff --git a/user_guide_src/source/testing/feature/001.php b/user_guide_src/source/testing/feature/001.php index 5449332fe266..0ab640465052 100644 --- a/user_guide_src/source/testing/feature/001.php +++ b/user_guide_src/source/testing/feature/001.php @@ -7,7 +7,8 @@ class TestFoo extends CIUnitTestCase { - use DatabaseTestTrait, FeatureTestTrait; + use DatabaseTestTrait; + use FeatureTestTrait; protected function setUp(): void { diff --git a/user_guide_src/source/testing/feature/002.php b/user_guide_src/source/testing/feature/002.php index 553aaa0bfd03..8af5fda7b7c6 100644 --- a/user_guide_src/source/testing/feature/002.php +++ b/user_guide_src/source/testing/feature/002.php @@ -6,5 +6,5 @@ // Submit a form $result = $this->call('post', 'contact', [ 'name' => 'Fred Flintstone', - 'email' => 'flintyfred@example.com' + 'email' => 'flintyfred@example.com', ]); diff --git a/user_guide_src/source/testing/overview/009.php b/user_guide_src/source/testing/overview/009.php index 115cf6bda9e4..5d69c01c16d5 100644 --- a/user_guide_src/source/testing/overview/009.php +++ b/user_guide_src/source/testing/overview/009.php @@ -1,6 +1,6 @@ response->send(); $output = ob_get_clean(); // in case you want to check the actual body -$this->assertHeaderEmitted("Set-Cookie: foo=bar"); +$this->assertHeaderEmitted('Set-Cookie: foo=bar'); diff --git a/user_guide_src/source/testing/overview/011.php b/user_guide_src/source/testing/overview/011.php index a2aa11c7bb64..10e9d4a0d31b 100644 --- a/user_guide_src/source/testing/overview/011.php +++ b/user_guide_src/source/testing/overview/011.php @@ -6,4 +6,4 @@ $this->response->send(); $output = ob_get_clean(); // in case you want to check the actual body -$this->assertHeaderNotEmitted("Set-Cookie: banana"); +$this->assertHeaderNotEmitted('Set-Cookie: banana'); From e8202c2baa7e325ae85387cf75656596081f8954 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 5 Mar 2022 08:48:32 +0900 Subject: [PATCH 0654/1246] docs: add dummy HTML tags --- user_guide_src/source/general/helpers/005.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/user_guide_src/source/general/helpers/005.php b/user_guide_src/source/general/helpers/005.php index 13a7f3015387..0602338d208b 100644 --- a/user_guide_src/source/general/helpers/005.php +++ b/user_guide_src/source/general/helpers/005.php @@ -1 +1,3 @@ - + + From 170faa1f8f3491ffeb2bbdcfbc268fbafd5af187 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 6 Mar 2022 08:41:56 +0900 Subject: [PATCH 0655/1246] docs: revert method chaining indentation --- user_guide_src/source/database/query_builder/074.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/user_guide_src/source/database/query_builder/074.php b/user_guide_src/source/database/query_builder/074.php index 1ce884db6e6a..3ea4d947f4a7 100644 --- a/user_guide_src/source/database/query_builder/074.php +++ b/user_guide_src/source/database/query_builder/074.php @@ -2,11 +2,11 @@ $builder->select('*')->from('my_table') ->groupStart() - ->where('a', 'a') - ->orGroupStart() - ->where('b', 'b') - ->where('c', 'c') - ->groupEnd() + ->where('a', 'a') + ->orGroupStart() + ->where('b', 'b') + ->where('c', 'c') + ->groupEnd() ->groupEnd() ->where('d', 'd') ->get(); From f8d29aeed1837bf584ba637f2fc55a74e5c48768 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 6 Mar 2022 09:46:28 +0900 Subject: [PATCH 0656/1246] docs: update @param comments --- system/Database/BaseConnection.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/system/Database/BaseConnection.php b/system/Database/BaseConnection.php index 134a50517ae6..6d7170dc5bb3 100644 --- a/system/Database/BaseConnection.php +++ b/system/Database/BaseConnection.php @@ -962,8 +962,9 @@ public function getConnectDuration(int $decimals = 6): string * the correct identifiers. * * @param array|string $item - * @param bool $prefixSingle Prefix an item with no segments? - * @param bool $fieldExists Supplied $item contains a field name? + * @param bool $prefixSingle Prefix a table name with no segments? + * @param bool $protectIdentifiers Protect table or column names? + * @param bool $fieldExists Supplied $item contains a column name? * * @return array|string */ From 30bc414a9e22bf886c1d186691ddce9539e5f974 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 7 Mar 2022 08:25:02 +0900 Subject: [PATCH 0657/1246] fix: table name is double prefixed when LIKE clause --- system/Database/BaseBuilder.php | 4 ++-- tests/system/Database/Builder/LikeTest.php | 23 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/system/Database/BaseBuilder.php b/system/Database/BaseBuilder.php index 79bdf08ffb43..1d0c241903e8 100644 --- a/system/Database/BaseBuilder.php +++ b/system/Database/BaseBuilder.php @@ -1051,7 +1051,7 @@ protected function _like($field, string $match = '', string $type = 'AND ', stri $bind = $this->setBind($k, "%{$v}%", $escape); } - $likeStatement = $this->_like_statement($prefix, $this->db->protectIdentifiers($k, false, $escape), $not, $bind, $insensitiveSearch); + $likeStatement = $this->_like_statement($prefix, $k, $not, $bind, $insensitiveSearch); // some platforms require an escape sequence definition for LIKE wildcards if ($escape === true && $this->db->likeEscapeStr !== '') { @@ -1073,7 +1073,7 @@ protected function _like($field, string $match = '', string $type = 'AND ', stri protected function _like_statement(?string $prefix, string $column, ?string $not, string $bind, bool $insensitiveSearch = false): string { if ($insensitiveSearch === true) { - return "{$prefix} LOWER({$column}) {$not} LIKE :{$bind}:"; + return "{$prefix} LOWER(" . $this->db->escapeIdentifiers($column) . ") {$not} LIKE :{$bind}:"; } return "{$prefix} {$column} {$not} LIKE :{$bind}:"; diff --git a/tests/system/Database/Builder/LikeTest.php b/tests/system/Database/Builder/LikeTest.php index ba7c176b7c90..2d81db2b90fa 100644 --- a/tests/system/Database/Builder/LikeTest.php +++ b/tests/system/Database/Builder/LikeTest.php @@ -183,4 +183,27 @@ public function testCaseInsensitiveLike() $this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledSelect())); $this->assertSame($expectedBinds, $builder->getBinds()); } + + /** + * @see https://github.com/codeigniter4/CodeIgniter4/issues/5775 + */ + public function testDBPrefixAndCoulmnWithTablename() + { + $this->db = new MockConnection(['DBPrefix' => 'db_']); + $builder = new BaseBuilder('test', $this->db); + + $builder->like('test.field', 'string'); + + $expectedSQL = <<<'SQL' + SELECT * FROM "db_test" WHERE "db_test"."field" LIKE '%string%' ESCAPE '!' + SQL; + $expectedBinds = [ + 'test.field' => [ + '%string%', + true, + ], + ]; + $this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledSelect())); + $this->assertSame($expectedBinds, $builder->getBinds()); + } } From 7509003826079c0d1056300e17796fd68a176efe Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 7 Mar 2022 08:25:33 +0900 Subject: [PATCH 0658/1246] refactor: revert unneeded workaround from #5361 --- system/Database/BaseConnection.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/system/Database/BaseConnection.php b/system/Database/BaseConnection.php index 6d7170dc5bb3..4f54c1980830 100644 --- a/system/Database/BaseConnection.php +++ b/system/Database/BaseConnection.php @@ -1022,8 +1022,7 @@ public function protectIdentifiers($item, bool $prefixSingle = false, ?bool $pro // // NOTE: The ! empty() condition prevents this method // from breaking when QB isn't enabled. - $firstSegment = trim($parts[0], $this->escapeChar); - if (! empty($this->aliasedTables) && in_array($firstSegment, $this->aliasedTables, true)) { + if (! empty($this->aliasedTables) && in_array($parts[0], $this->aliasedTables, true)) { if ($protectIdentifiers === true) { foreach ($parts as $key => $val) { if (! in_array($val, $this->reservedIdentifiers, true)) { From 3e52f412d024f0d50f0041d676e7c56197f5a5c0 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 7 Mar 2022 08:43:59 +0900 Subject: [PATCH 0659/1246] fix: app/Config/Routes.php is loaded twice on Windows system/Config/Routes.php is loaded in app/Config/Routes.php --- system/Router/RouteCollection.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/system/Router/RouteCollection.php b/system/Router/RouteCollection.php index 7eded3411b7f..65bf4f4985af 100644 --- a/system/Router/RouteCollection.php +++ b/system/Router/RouteCollection.php @@ -357,9 +357,14 @@ protected function discoverRoutes() if ($this->moduleConfig->shouldDiscover('routes')) { $files = $this->fileLocator->search('Config/Routes.php'); + $excludes = [ + APPPATH . 'Config' . DIRECTORY_SEPARATOR . 'Routes.php', + SYSTEMPATH . 'Config' . DIRECTORY_SEPARATOR . 'Routes.php', + ]; + foreach ($files as $file) { // Don't include our main file again... - if ($file === APPPATH . 'Config/Routes.php') { + if (in_array($file, $excludes, true)) { continue; } From 539cdd7f7925d8f99254542cf65ddb55aa08090d Mon Sep 17 00:00:00 2001 From: MGatner Date: Tue, 8 Mar 2022 01:09:50 +0000 Subject: [PATCH 0660/1246] Add User Guide deploy script --- .github/scripts/deploy-userguide | 36 ++++++++++++++++ .github/workflows/deploy-userguide.yml | 59 ++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100755 .github/scripts/deploy-userguide create mode 100644 .github/workflows/deploy-userguide.yml diff --git a/.github/scripts/deploy-userguide b/.github/scripts/deploy-userguide new file mode 100755 index 000000000000..abbb768a5017 --- /dev/null +++ b/.github/scripts/deploy-userguide @@ -0,0 +1,36 @@ +#!/bin/bash + +## Deploy codeigniter4/userguide + +# Setup variables +SOURCE=$1 +TARGET=$2 +RELEASE=$3 +VERSION=`echo "$RELEASE" | cut -c 2-` + +echo "Preparing for version $3" +echo "Merging files from $1 to $2" + +# Prepare the source +cd $SOURCE +git checkout master +cd user_guide_src +make html +make epub + +# Prepare the target +cd $TARGET +git checkout master +rm -rf docs + +# Copy files +cp -Rf ${SOURCE}/user_guide_src/build/html ./docs +cp -Rf ${SOURCE}/user_guide_src/build/epub/CodeIgniter.epub ./CodeIgniter${VERSION}.epub + +# Ensure underscore prefixed files are published +touch ${TARGET}/docs/.nojekyll + +# Commit the changes +git add . +git commit -m "Release ${RELEASE}" +git push diff --git a/.github/workflows/deploy-userguide.yml b/.github/workflows/deploy-userguide.yml new file mode 100644 index 000000000000..384eeef5186f --- /dev/null +++ b/.github/workflows/deploy-userguide.yml @@ -0,0 +1,59 @@ +# When a new Release is created, deploy relevant +# files to each of the generated repos. +name: Deploy User Guide + +on: + release: + types: [published] + +jobs: + framework: + name: Deploy to userguide + if: (github.repository == 'codeigniter4/CodeIgniter4') + runs-on: ubuntu-latest + steps: + - name: Identify + run: | + git config --global user.email "action@github.com" + git config --global user.name "${GITHUB_ACTOR}" + + - name: Checkout source + uses: actions/checkout@v3 + with: + path: source + + - name: Checkout target + uses: actions/checkout@v3 + with: + repository: codeigniter4/userguide + token: ${{ secrets.ACCESS_TOKEN }} + path: userguide + + - name: Install Sphinx + run: | + sudo apt install python3-sphinx + sudo pip3 install sphinxcontrib-phpdomain + sudo pip3 install sphinx_rtd_theme + + - name: Chmod + run: chmod +x ./source/.github/scripts/deploy-userguide + + - name: Deploy + run: ./source/.github/scripts/deploy-userguide ${GITHUB_WORKSPACE}/source ${GITHUB_WORKSPACE}/userguide ${GITHUB_REF##*/} + + - name: Release + uses: actions/github-script@v6 + with: + github-token: ${{secrets.ACCESS_TOKEN}} + script: | + const release = await github.rest.repos.getLatestRelease({ + owner: context.repo.owner, + repo: context.repo.repo + }) + github.rest.repos.createRelease({ + owner: context.repo.owner, + repo: 'userguide', + tag_name: release.data.tag_name, + name: release.data.name, + body: release.data.body + }) From 3cc2ea9ea2255a8300d20a6532f31c0d076f6128 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 8 Mar 2022 15:30:27 +0900 Subject: [PATCH 0661/1246] chore: fix php-cs-fixer version to 3.6 --- admin/framework/composer.json | 2 +- composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/admin/framework/composer.json b/admin/framework/composer.json index 42ca449ddf3c..03d3965770ba 100644 --- a/admin/framework/composer.json +++ b/admin/framework/composer.json @@ -17,7 +17,7 @@ "require-dev": { "codeigniter/coding-standard": "^1.1", "fakerphp/faker": "^1.9", - "friendsofphp/php-cs-fixer": "^3.6", + "friendsofphp/php-cs-fixer": "3.6.*", "mikey179/vfsstream": "^1.6", "nexusphp/cs-config": "^3.3", "phpunit/phpunit": "^9.1", diff --git a/composer.json b/composer.json index 945e9d30e723..d31045882d31 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "require-dev": { "codeigniter/coding-standard": "^1.1", "fakerphp/faker": "^1.9", - "friendsofphp/php-cs-fixer": "^3.6", + "friendsofphp/php-cs-fixer": "3.6.*", "mikey179/vfsstream": "^1.6", "nexusphp/cs-config": "^3.3", "nexusphp/tachycardia": "^1.0", From 848a72318537da4a88b5118554c478c3284d5020 Mon Sep 17 00:00:00 2001 From: kenjis Date: Thu, 3 Mar 2022 15:58:41 +0900 Subject: [PATCH 0662/1246] chore: add .user-guide.php-cs-fixer.dist.php and update composer cs-fix --- .php-cs-fixer.dist.php | 1 + .user-guide.php-cs-fixer.dist.php | 48 +++++++++++++++++++++++++++++++ composer.json | 2 ++ 3 files changed, 51 insertions(+) create mode 100644 .user-guide.php-cs-fixer.dist.php diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index ec0ceaeb0172..7caeaec1035c 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -30,6 +30,7 @@ ->append([ __FILE__, __DIR__ . '/.no-header.php-cs-fixer.dist.php', + __DIR__ . '/.user-guide.php-cs-fixer.dist.php', __DIR__ . '/rector.php', __DIR__ . '/spark', __DIR__ . '/user_guide_src/renumerate.php', diff --git a/.user-guide.php-cs-fixer.dist.php b/.user-guide.php-cs-fixer.dist.php new file mode 100644 index 000000000000..ba33baaf409d --- /dev/null +++ b/.user-guide.php-cs-fixer.dist.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +use CodeIgniter\CodingStandard\CodeIgniter4; +use Nexus\CsConfig\Factory; +use Nexus\CsConfig\Fixer\Comment\NoCodeSeparatorCommentFixer; +use Nexus\CsConfig\Fixer\Comment\SpaceAfterCommentStartFixer; +use Nexus\CsConfig\FixerGenerator; +use PhpCsFixer\Finder; + +$finder = Finder::create() + ->files() + ->in([ + __DIR__ . '/user_guide_src/source', + ]) + ->notPath([ + 'ci3sample/', + 'libraries/sessions/017.php', + ]); + +$overrides = [ + 'echo_tag_syntax' => false, + 'php_unit_internal_class' => false, + 'no_unused_imports' => false, + 'class_attributes_separation' => false, +]; + +$options = [ + 'cacheFile' => 'build/.user-guide.php-cs-fixer.cache', + 'finder' => $finder, + 'customFixers' => FixerGenerator::create('vendor/nexusphp/cs-config/src/Fixer', 'Nexus\\CsConfig\\Fixer'), + 'customRules' => [ + NoCodeSeparatorCommentFixer::name() => true, + SpaceAfterCommentStartFixer::name() => true, + ], +]; + +return Factory::create(new CodeIgniter4(), $overrides, $options)->forProjects(); diff --git a/composer.json b/composer.json index d31045882d31..ed6ff59ccad4 100644 --- a/composer.json +++ b/composer.json @@ -62,10 +62,12 @@ "analyze": "phpstan analyse", "test": "phpunit", "cs": [ + "php-cs-fixer fix --verbose --dry-run --diff --config=.user-guide.php-cs-fixer.dist.php", "php-cs-fixer fix --verbose --dry-run --diff --config=.no-header.php-cs-fixer.dist.php", "php-cs-fixer fix --verbose --dry-run --diff" ], "cs-fix": [ + "php-cs-fixer fix --verbose --diff --config=.user-guide.php-cs-fixer.dist.php", "php-cs-fixer fix --verbose --diff --config=.no-header.php-cs-fixer.dist.php", "php-cs-fixer fix --verbose --diff" ] From e7095469ef365ad6cd50a19c83352110078ff478 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 4 Mar 2022 09:36:15 +0900 Subject: [PATCH 0663/1246] chore: add checking on user guide PHP coding style --- admin/pre-commit | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/admin/pre-commit b/admin/pre-commit index 4f1e7d11f544..e8fdcff64499 100644 --- a/admin/pre-commit +++ b/admin/pre-commit @@ -63,6 +63,18 @@ if [ "$FILES" != "" ]; then echo "Files in system, tests, utils, or root are not following the coding standards. Please fix them before commit." exit 1 fi + + # Next, run on user_guide_src/source PHP files + if [ -d /proc/cygdrive ]; then + ./vendor/bin/php-cs-fixer fix --verbose --dry-run --diff --config=.user-guide.php-cs-fixer.dist.php + else + php ./vendor/bin/php-cs-fixer fix --verbose --dry-run --diff --config=.user-guide.php-cs-fixer.dist.php + fi + + if [ $? != 0 ]; then + echo "Files in user_guide_src/source are not following the coding standards. Please fix them before commit." + exit 1 + fi fi if [ "$STAGED_RST_FILES" != "" ]; then From 24b2210fdc1596a5e4e867f84175fd70d85048b7 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 6 Mar 2022 08:45:27 +0900 Subject: [PATCH 0664/1246] docs: add file to exclude very special method chaining --- .user-guide.php-cs-fixer.dist.php | 1 + 1 file changed, 1 insertion(+) diff --git a/.user-guide.php-cs-fixer.dist.php b/.user-guide.php-cs-fixer.dist.php index ba33baaf409d..7a48f922f1d7 100644 --- a/.user-guide.php-cs-fixer.dist.php +++ b/.user-guide.php-cs-fixer.dist.php @@ -26,6 +26,7 @@ ->notPath([ 'ci3sample/', 'libraries/sessions/017.php', + 'database/query_builder/074.php', ]); $overrides = [ From 03354eed49cd344dbecfc2e141d47d06fd2f28eb Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 8 Mar 2022 18:52:43 +0900 Subject: [PATCH 0665/1246] chore: add coding style check for user_guide/ in GitHub Action --- .github/workflows/test-coding-standards.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/test-coding-standards.yml b/.github/workflows/test-coding-standards.yml index 4e9509f4fb2e..c966d9e1e603 100644 --- a/.github/workflows/test-coding-standards.yml +++ b/.github/workflows/test-coding-standards.yml @@ -56,3 +56,6 @@ jobs: - name: Run lint on `system/`, `tests`, `utils/`, and root PHP files run: vendor/bin/php-cs-fixer fix --verbose --ansi --dry-run --using-cache=no --diff + + - name: Run lint on `user_guide_src/source/` + run: vendor/bin/php-cs-fixer fix --verbose --ansi --dry-run --config=.user-guide.php-cs-fixer.dist.php --using-cache=no --diff From 5307ec4642c60f51b6427b2d6fbc51c6a06f25e0 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 9 Mar 2022 09:10:01 +0900 Subject: [PATCH 0666/1246] docs: add TOC --- user_guide_src/source/extending/basecontroller.rst | 4 ++++ user_guide_src/source/extending/core_classes.rst | 4 ++++ user_guide_src/source/extending/events.rst | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/user_guide_src/source/extending/basecontroller.rst b/user_guide_src/source/extending/basecontroller.rst index 790eac099060..cdd3710a3c24 100644 --- a/user_guide_src/source/extending/basecontroller.rst +++ b/user_guide_src/source/extending/basecontroller.rst @@ -8,6 +8,10 @@ advantage of preloaded components and any additional functionality you provide: .. literalinclude:: basecontroller/001.php +.. contents:: + :local: + :depth: 2 + Preloading Components ===================== diff --git a/user_guide_src/source/extending/core_classes.rst b/user_guide_src/source/extending/core_classes.rst index fc06e2c305f8..2de8de4d961b 100644 --- a/user_guide_src/source/extending/core_classes.rst +++ b/user_guide_src/source/extending/core_classes.rst @@ -12,6 +12,10 @@ who would like to significantly alter the CodeIgniter core.** .. note:: Messing with a core system class has a lot of implications, so make sure you know what you are doing before attempting it. +.. contents:: + :local: + :depth: 2 + System Class List ================= diff --git a/user_guide_src/source/extending/events.rst b/user_guide_src/source/extending/events.rst index cf15415813a4..c14f56a11022 100644 --- a/user_guide_src/source/extending/events.rst +++ b/user_guide_src/source/extending/events.rst @@ -11,6 +11,10 @@ Events work on a *publish/subscribe* pattern, where an event, is triggered at so Other scripts can "subscribe" to that event by registering with the Events class to let it know they want to perform an action when that event is triggered. +.. contents:: + :local: + :depth: 2 + Enabling Events =============== From e234e9f734a7ba4ac889e598394edf58a06598aa Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 9 Mar 2022 09:10:29 +0900 Subject: [PATCH 0667/1246] docs: update System Class List --- user_guide_src/source/extending/core_classes.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/user_guide_src/source/extending/core_classes.rst b/user_guide_src/source/extending/core_classes.rst index 2de8de4d961b..7695c55ac38d 100644 --- a/user_guide_src/source/extending/core_classes.rst +++ b/user_guide_src/source/extending/core_classes.rst @@ -21,13 +21,16 @@ System Class List The following is a list of the core system files that are invoked every time CodeIgniter runs: -* Config\\Services * CodeIgniter\\Autoloader\\Autoloader +* CodeIgniter\\CodeIgniter * CodeIgniter\\Config\\DotEnv +* CodeIgniter\\Config\\Services * CodeIgniter\\Controller * CodeIgniter\\Debug\\Exceptions * CodeIgniter\\Debug\\Timer * CodeIgniter\\Events\\Events +* CodeIgniter\\Filters\\Filters +* CodeIgniter\\HTTP\\ContentSecurityPolicy * CodeIgniter\\HTTP\\CLIRequest (if launched from command line only) * CodeIgniter\\HTTP\\IncomingRequest (if launched over HTTP) * CodeIgniter\\HTTP\\Request @@ -39,9 +42,7 @@ The following is a list of the core system files that are invoked every time Cod * CodeIgniter\\Log\\Handlers\\FileHandler * CodeIgniter\\Router\\RouteCollection * CodeIgniter\\Router\\Router -* CodeIgniter\\Security\\Security * CodeIgniter\\View\\View -* CodeIgniter\\View\\Escaper Replacing Core Classes ====================== From 43cd7c99e59993f02ebcf7d16f85ef47da2a3613 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 9 Mar 2022 09:18:07 +0900 Subject: [PATCH 0668/1246] docs: decorate classnames with '``' --- .../source/extending/core_classes.rst | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/user_guide_src/source/extending/core_classes.rst b/user_guide_src/source/extending/core_classes.rst index 7695c55ac38d..5530421f24c5 100644 --- a/user_guide_src/source/extending/core_classes.rst +++ b/user_guide_src/source/extending/core_classes.rst @@ -21,28 +21,28 @@ System Class List The following is a list of the core system files that are invoked every time CodeIgniter runs: -* CodeIgniter\\Autoloader\\Autoloader -* CodeIgniter\\CodeIgniter -* CodeIgniter\\Config\\DotEnv -* CodeIgniter\\Config\\Services -* CodeIgniter\\Controller -* CodeIgniter\\Debug\\Exceptions -* CodeIgniter\\Debug\\Timer -* CodeIgniter\\Events\\Events -* CodeIgniter\\Filters\\Filters -* CodeIgniter\\HTTP\\ContentSecurityPolicy -* CodeIgniter\\HTTP\\CLIRequest (if launched from command line only) -* CodeIgniter\\HTTP\\IncomingRequest (if launched over HTTP) -* CodeIgniter\\HTTP\\Request -* CodeIgniter\\HTTP\\Response -* CodeIgniter\\HTTP\\Message -* CodeIgniter\\HTTP\\URI -* CodeIgniter\\Log\\Logger -* CodeIgniter\\Log\\Handlers\\BaseHandler -* CodeIgniter\\Log\\Handlers\\FileHandler -* CodeIgniter\\Router\\RouteCollection -* CodeIgniter\\Router\\Router -* CodeIgniter\\View\\View +* ``CodeIgniter\Autoloader\Autoloader`` +* ``CodeIgniter\CodeIgniter`` +* ``CodeIgniter\Config\DotEnv`` +* ``CodeIgniter\Config\Services`` +* ``CodeIgniter\Controller`` +* ``CodeIgniter\Debug\Exceptions`` +* ``CodeIgniter\Debug\Timer`` +* ``CodeIgniter\Events\Events`` +* ``CodeIgniter\Filters\Filters`` +* ``CodeIgniter\HTTP\ContentSecurityPolicy`` +* ``CodeIgniter\HTTP\CLIRequest`` (if launched from command line only) +* ``CodeIgniter\HTTP\IncomingRequest`` (if launched over HTTP) +* ``CodeIgniter\HTTP\Request`` +* ``CodeIgniter\HTTP\Response`` +* ``CodeIgniter\HTTP\Message`` +* ``CodeIgniter\HTTP\URI`` +* ``CodeIgniter\Log\Logger`` +* ``CodeIgniter\Log\Handlers\BaseHandler`` +* ``CodeIgniter\Log\Handlers\FileHandler`` +* ``CodeIgniter\Router\RouteCollection`` +* ``CodeIgniter\Router\Router`` +* ``CodeIgniter\View\View`` Replacing Core Classes ====================== @@ -69,7 +69,7 @@ identical to replacing a class with one exception: * The class declaration must extend the parent class. -For example, to extend the native RouteCollection class, you would declare your class with: +For example, to extend the native ``RouteCollection`` class, you would declare your class with: .. literalinclude:: core_classes/003.php From caa5d62484d759d3c1befab536d1ea657713c487 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 9 Mar 2022 09:18:44 +0900 Subject: [PATCH 0669/1246] docs: fix words --- user_guide_src/source/extending/core_classes.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/user_guide_src/source/extending/core_classes.rst b/user_guide_src/source/extending/core_classes.rst index 5530421f24c5..8f923a2e14bd 100644 --- a/user_guide_src/source/extending/core_classes.rst +++ b/user_guide_src/source/extending/core_classes.rst @@ -19,7 +19,7 @@ who would like to significantly alter the CodeIgniter core.** System Class List ================= -The following is a list of the core system files that are invoked every time CodeIgniter runs: +The following is a list of the core system classes that are invoked every time CodeIgniter runs: * ``CodeIgniter\Autoloader\Autoloader`` * ``CodeIgniter\CodeIgniter`` @@ -48,7 +48,7 @@ Replacing Core Classes ====================== To use one of your own system classes instead of a default one, ensure that the :doc:`Autoloader <../concepts/autoloader>` -can find your class, that your new class extends the appropriate interface, and modify the appropriate +can find your class, that your new class implements the appropriate interface, and modify the appropriate :doc:`Service <../concepts/services>` to load your class in place of the core class. For example, if you have a new ``App\Libraries\RouteCollection`` class that you would like to use in place of From e80d3b9933ecf5073c11127f7917c6e253030ca5 Mon Sep 17 00:00:00 2001 From: Lonnie Ezell Date: Tue, 8 Mar 2022 22:23:25 -0600 Subject: [PATCH 0670/1246] Extend Validation from BaseConfig so Registrars can add rules. --- app/Config/Validation.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Config/Validation.php b/app/Config/Validation.php index 1cff0424f4de..a254c1850015 100644 --- a/app/Config/Validation.php +++ b/app/Config/Validation.php @@ -2,12 +2,13 @@ namespace Config; +use CodeIgniter\Config\BaseConfig; use CodeIgniter\Validation\CreditCardRules; use CodeIgniter\Validation\FileRules; use CodeIgniter\Validation\FormatRules; use CodeIgniter\Validation\Rules; -class Validation +class Validation extends BaseConfig { //-------------------------------------------------------------------- // Setup From 6804486d254ec67e16fa862c69422d26891bba68 Mon Sep 17 00:00:00 2001 From: kenjis Date: Thu, 10 Mar 2022 09:00:42 +0900 Subject: [PATCH 0671/1246] docs: fix incorrect directory name --- user_guide_src/source/extending/common.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/user_guide_src/source/extending/common.rst b/user_guide_src/source/extending/common.rst index 5c5bf9c999e0..e85ca6c56ef8 100644 --- a/user_guide_src/source/extending/common.rst +++ b/user_guide_src/source/extending/common.rst @@ -4,9 +4,9 @@ Replacing Common Functions There are quite a few functions necessary to CodeIgniter that need to be loaded early for use in the core classes and thus cannot be placed into a helper. While most users will never have any need to do this, but the option to replace -these functions does exist for those who would like to significantly alter the CodeIgniter core. In the ``App\`` -directory there is a file ``Common.php``, and any functions defined in there will take precedence over the versions -found in ``system/Common.php``. This is also an opportunity to create globally-available functions you intend to +these functions does exist for those who would like to significantly alter the CodeIgniter core. In the **app/** +directory there is a file **Common.php**, and any functions defined in there will take precedence over the versions +found in **system/Common.php**. This is also an opportunity to create globally-available functions you intend to use throughout the framework. .. note:: Messing with a core system class has a lot of implications, so make sure you know what you are doing before From a4d777bdcea8a959d984c4362acc40d979a06e2a Mon Sep 17 00:00:00 2001 From: kenjis Date: Thu, 10 Mar 2022 09:03:40 +0900 Subject: [PATCH 0672/1246] docs: fix incorrect event name and method name --- user_guide_src/source/extending/events.rst | 4 ++-- user_guide_src/source/extending/events/001.php | 2 +- user_guide_src/source/extending/events/002.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/user_guide_src/source/extending/events.rst b/user_guide_src/source/extending/events.rst index c14f56a11022..439aaffd4718 100644 --- a/user_guide_src/source/extending/events.rst +++ b/user_guide_src/source/extending/events.rst @@ -29,8 +29,8 @@ a callable that will be run when that event is triggered: .. literalinclude:: events/001.php -In this example, whenever the **pre_controller** event is executed, an instance of ``MyClass`` is created and the -``MyFunction`` method is run. Note that the second parameter can be *any* form of +In this example, whenever the ``pre_system`` event is executed, an instance of ``MyClass`` is created and the +``myFunction()`` method is run. Note that the second parameter can be *any* form of `callable `_ that PHP recognizes: .. literalinclude:: events/002.php diff --git a/user_guide_src/source/extending/events/001.php b/user_guide_src/source/extending/events/001.php index 2a3ee317e594..3702ec7518c2 100644 --- a/user_guide_src/source/extending/events/001.php +++ b/user_guide_src/source/extending/events/001.php @@ -2,4 +2,4 @@ use CodeIgniter\Events\Events; -Events::on('pre_system', ['MyClass', 'MyFunction']); +Events::on('pre_system', ['MyClass', 'myFunction']); diff --git a/user_guide_src/source/extending/events/002.php b/user_guide_src/source/extending/events/002.php index 00fa912bd45a..ca9bf0074209 100644 --- a/user_guide_src/source/extending/events/002.php +++ b/user_guide_src/source/extending/events/002.php @@ -5,7 +5,7 @@ // Call on an instance method $user = new User(); -Events::on('pre_system', [$user, 'some_method']); +Events::on('pre_system', [$user, 'someMethod']); // Call on a static method Events::on('pre_system', 'SomeClass::someMethod'); From d8b3ed4fb47172677665b47757703fb65a9eee81 Mon Sep 17 00:00:00 2001 From: kenjis Date: Thu, 10 Mar 2022 09:04:50 +0900 Subject: [PATCH 0673/1246] docs: decorate classname with '``' --- user_guide_src/source/extending/events.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/extending/events.rst b/user_guide_src/source/extending/events.rst index 439aaffd4718..1b2c53a918cd 100644 --- a/user_guide_src/source/extending/events.rst +++ b/user_guide_src/source/extending/events.rst @@ -24,7 +24,7 @@ Defining an Event ================= Most events are defined within the **app/Config/Events.php** file. You can subscribe an action to an event with -the Events class' ``on()`` method. The first parameter is the name of the event to subscribe to. The second parameter is +the ``Events`` class' ``on()`` method. The first parameter is the name of the event to subscribe to. The second parameter is a callable that will be run when that event is triggered: .. literalinclude:: events/001.php From 7ea657bdff71b9ae7fbe33a5dc0e3635d8a7598e Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 11 Mar 2022 08:49:34 +0900 Subject: [PATCH 0674/1246] docs: fix RST format --- user_guide_src/source/libraries/publisher.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/user_guide_src/source/libraries/publisher.rst b/user_guide_src/source/libraries/publisher.rst index af683bc0afe2..55e68adc5847 100644 --- a/user_guide_src/source/libraries/publisher.rst +++ b/user_guide_src/source/libraries/publisher.rst @@ -80,6 +80,7 @@ In order to prevent modules from injecting malicious code into your projects, `` that defines which directories and file patterns are allowed as destinations. By default, files may only be published to your project (to prevent access to the rest of the filesystem), and the **public/** folder (``FCPATH``) will only receive files with the following extensions: + * Web assets: css, scss, js, map * Non-executable web files: htm, html, xml, json, webmanifest * Fonts: tff, eot, woff From 1f6e857b89fd3a81435f881a7c1b23738aba2ea3 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 11 Mar 2022 08:49:52 +0900 Subject: [PATCH 0675/1246] docs: add config file path --- user_guide_src/source/libraries/publisher.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/libraries/publisher.rst b/user_guide_src/source/libraries/publisher.rst index 55e68adc5847..9acf7ec48011 100644 --- a/user_guide_src/source/libraries/publisher.rst +++ b/user_guide_src/source/libraries/publisher.rst @@ -86,7 +86,7 @@ receive files with the following extensions: * Fonts: tff, eot, woff * Images: gif, jpg, jpeg, tiff, png, webp, bmp, ico, svg -If you need to add or adjust the security for your project then alter the ``$restrictions`` property of ``Config\Publisher``. +If you need to add or adjust the security for your project then alter the ``$restrictions`` property of ``Config\Publisher`` in **app/Config/Publisher.php**. ******** Examples From 7ff85e66362b2f5da8503ab2d78d40322629cdfe Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 11 Mar 2022 08:56:24 +0900 Subject: [PATCH 0676/1246] docs: add .tif --- user_guide_src/source/libraries/publisher.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/libraries/publisher.rst b/user_guide_src/source/libraries/publisher.rst index 9acf7ec48011..69de79bd7464 100644 --- a/user_guide_src/source/libraries/publisher.rst +++ b/user_guide_src/source/libraries/publisher.rst @@ -84,7 +84,7 @@ receive files with the following extensions: * Web assets: css, scss, js, map * Non-executable web files: htm, html, xml, json, webmanifest * Fonts: tff, eot, woff -* Images: gif, jpg, jpeg, tiff, png, webp, bmp, ico, svg +* Images: gif, jpg, jpeg, tif, tiff, png, webp, bmp, ico, svg If you need to add or adjust the security for your project then alter the ``$restrictions`` property of ``Config\Publisher`` in **app/Config/Publisher.php**. From 43ad9b8148d42c014f890434f6febbcad64fe55d Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 11 Mar 2022 08:58:23 +0900 Subject: [PATCH 0677/1246] fix: regex for file extentions to FCPATH --- app/Config/Publisher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Config/Publisher.php b/app/Config/Publisher.php index f3768bc577b4..4f7cf11037f5 100644 --- a/app/Config/Publisher.php +++ b/app/Config/Publisher.php @@ -23,6 +23,6 @@ class Publisher extends BasePublisher */ public $restrictions = [ ROOTPATH => '*', - FCPATH => '#\.(?css|js|map|htm?|xml|json|webmanifest|tff|eot|woff?|gif|jpe?g|tiff?|png|webp|bmp|ico|svg)$#i', + FCPATH => '#\.(s?css|js|map|html?|xml|json|webmanifest|tff|eot|woff|gif|jpe?g|tiff?|png|webp|bmp|ico|svg)$#i', ]; } From 81c588bacf1f6488e6fbe51a3d799c09390b789c Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 11 Mar 2022 09:05:01 +0900 Subject: [PATCH 0678/1246] test: fix classname in comment --- tests/system/Publisher/PublisherRestrictionsTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/Publisher/PublisherRestrictionsTest.php b/tests/system/Publisher/PublisherRestrictionsTest.php index a3750f1427ad..9353c1d6ccfd 100644 --- a/tests/system/Publisher/PublisherRestrictionsTest.php +++ b/tests/system/Publisher/PublisherRestrictionsTest.php @@ -25,7 +25,7 @@ final class PublisherRestrictionsTest extends CIUnitTestCase { /** - * @see Tests\Support\Config\Registrars::Publisher() + * @see \Tests\Support\Config\Registrar::Publisher() */ public function testRegistrarsNotAllowed() { From 3a0d78b664417408ed339b3b7533bba38be1e20c Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 11 Mar 2022 09:05:35 +0900 Subject: [PATCH 0679/1246] test: refactor dataProvider --- tests/system/Publisher/PublisherRestrictionsTest.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/system/Publisher/PublisherRestrictionsTest.php b/tests/system/Publisher/PublisherRestrictionsTest.php index 9353c1d6ccfd..620a74dcf224 100644 --- a/tests/system/Publisher/PublisherRestrictionsTest.php +++ b/tests/system/Publisher/PublisherRestrictionsTest.php @@ -69,11 +69,11 @@ public function testDefaultPublicRestrictions(string $path) public function fileProvider() { - yield 'php' => ['index.php']; - - yield 'exe' => ['cat.exe']; - - yield 'flat' => ['banana']; + yield from [ + 'php' => ['index.php'], + 'exe' => ['cat.exe'], + 'flat' => ['banana'], + ]; } /** From 608fa4251ade74f87164e3656b3e245d1151e79e Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Fri, 11 Mar 2022 17:32:44 +0100 Subject: [PATCH 0680/1246] Renumerate examples. --- user_guide_src/{renumerate => renumerate.php} | 0 .../source/database/query_builder.rst | 168 +++++++++--------- .../source/database/query_builder/015.php | 9 +- .../source/database/query_builder/016.php | 9 +- .../source/database/query_builder/017.php | 6 +- .../source/database/query_builder/018.php | 12 +- .../source/database/query_builder/019.php | 10 +- .../source/database/query_builder/020.php | 4 +- .../source/database/query_builder/021.php | 4 +- .../source/database/query_builder/022.php | 7 +- .../source/database/query_builder/023.php | 6 +- .../source/database/query_builder/024.php | 3 +- .../source/database/query_builder/025.php | 4 +- .../source/database/query_builder/026.php | 3 +- .../source/database/query_builder/027.php | 10 +- .../source/database/query_builder/028.php | 10 +- .../source/database/query_builder/029.php | 6 +- .../source/database/query_builder/030.php | 10 +- .../source/database/query_builder/031.php | 10 +- .../source/database/query_builder/032.php | 10 +- .../source/database/query_builder/033.php | 10 +- .../source/database/query_builder/034.php | 10 +- .../source/database/query_builder/035.php | 10 +- .../source/database/query_builder/036.php | 10 +- .../source/database/query_builder/037.php | 9 +- .../source/database/query_builder/038.php | 3 +- .../source/database/query_builder/039.php | 6 +- .../source/database/query_builder/040.php | 6 +- .../source/database/query_builder/041.php | 5 +- .../source/database/query_builder/042.php | 3 +- .../source/database/query_builder/043.php | 4 +- .../source/database/query_builder/044.php | 5 +- .../source/database/query_builder/045.php | 4 +- .../source/database/query_builder/046.php | 5 +- .../source/database/query_builder/047.php | 5 +- .../source/database/query_builder/048.php | 4 +- .../source/database/query_builder/049.php | 4 +- .../source/database/query_builder/050.php | 5 +- .../source/database/query_builder/051.php | 10 +- .../source/database/query_builder/052.php | 10 +- .../source/database/query_builder/053.php | 10 +- .../source/database/query_builder/054.php | 10 +- .../source/database/query_builder/055.php | 10 +- .../source/database/query_builder/056.php | 10 +- .../source/database/query_builder/057.php | 10 +- .../source/database/query_builder/058.php | 9 +- .../source/database/query_builder/059.php | 3 +- .../source/database/query_builder/060.php | 6 +- .../source/database/query_builder/061.php | 6 +- .../source/database/query_builder/062.php | 5 +- .../source/database/query_builder/063.php | 4 +- .../source/database/query_builder/064.php | 5 +- .../source/database/query_builder/065.php | 5 +- .../source/database/query_builder/066.php | 4 +- .../source/database/query_builder/067.php | 3 +- .../source/database/query_builder/068.php | 8 +- .../source/database/query_builder/069.php | 7 +- .../source/database/query_builder/070.php | 4 +- .../source/database/query_builder/071.php | 6 +- .../source/database/query_builder/072.php | 5 +- .../source/database/query_builder/073.php | 2 +- .../source/database/query_builder/074.php | 15 +- .../source/database/query_builder/075.php | 22 ++- .../source/database/query_builder/076.php | 16 +- .../source/database/query_builder/077.php | 16 +- .../source/database/query_builder/078.php | 5 +- .../source/database/query_builder/079.php | 12 +- .../source/database/query_builder/080.php | 18 +- .../source/database/query_builder/081.php | 17 +- .../source/database/query_builder/082.php | 11 +- .../source/database/query_builder/083.php | 3 +- .../source/database/query_builder/084.php | 13 +- .../source/database/query_builder/085.php | 15 +- .../source/database/query_builder/086.php | 14 +- .../source/database/query_builder/087.php | 22 +-- .../source/database/query_builder/088.php | 20 +-- .../source/database/query_builder/089.php | 17 +- .../source/database/query_builder/090.php | 2 +- .../source/database/query_builder/091.php | 27 +-- .../source/database/query_builder/092.php | 28 ++- .../source/database/query_builder/093.php | 9 +- .../source/database/query_builder/094.php | 9 +- .../source/database/query_builder/095.php | 7 +- .../source/database/query_builder/096.php | 9 +- .../source/database/query_builder/097.php | 19 +- .../source/database/query_builder/098.php | 19 +- .../source/incoming/controllers.rst | 38 ++-- .../source/incoming/controllers/001.php | 7 +- .../source/incoming/controllers/002.php | 7 +- .../source/incoming/controllers/003.php | 7 +- .../source/incoming/controllers/004.php | 16 +- .../source/incoming/controllers/005.php | 19 +- .../source/incoming/controllers/006.php | 23 ++- .../source/incoming/controllers/007.php | 5 +- .../source/incoming/controllers/008.php | 10 +- .../source/incoming/controllers/009.php | 7 +- .../source/incoming/controllers/010.php | 7 +- .../source/incoming/controllers/011.php | 11 +- .../source/incoming/controllers/012.php | 19 +- .../source/incoming/controllers/013.php | 11 +- .../source/incoming/controllers/014.php | 11 +- .../source/incoming/controllers/015.php | 4 +- .../source/incoming/controllers/016.php | 7 +- .../source/incoming/controllers/017.php | 15 +- .../source/incoming/controllers/018.php | 12 +- .../source/incoming/controllers/019.php | 20 +-- user_guide_src/source/incoming/routing.rst | 80 ++++----- .../source/incoming/routing/004_1.php | 3 - .../source/incoming/routing/004_2.php | 5 - .../source/incoming/routing/004_3.php | 8 - .../source/incoming/routing/004_4.php | 8 - .../source/incoming/routing/013.php | 3 +- .../source/incoming/routing/014.php | 4 +- .../source/incoming/routing/015.php | 7 +- .../source/incoming/routing/016.php | 9 +- .../source/incoming/routing/017.php | 8 +- .../source/incoming/routing/018.php | 7 +- .../source/incoming/routing/019.php | 5 +- .../source/incoming/routing/020.php | 6 +- .../source/incoming/routing/021.php | 9 +- .../source/incoming/routing/022.php | 11 +- .../source/incoming/routing/023.php | 7 +- .../source/incoming/routing/024.php | 4 +- .../source/incoming/routing/025.php | 11 +- .../source/incoming/routing/026.php | 13 +- .../source/incoming/routing/027.php | 6 +- .../source/incoming/routing/028.php | 4 +- .../source/incoming/routing/029.php | 20 +-- .../source/incoming/routing/030.php | 9 +- .../source/incoming/routing/031.php | 2 +- .../source/incoming/routing/032.php | 2 +- .../source/incoming/routing/033.php | 13 +- .../source/incoming/routing/034.php | 3 +- .../source/incoming/routing/035.php | 2 +- .../source/incoming/routing/036.php | 3 +- .../source/incoming/routing/037.php | 3 +- .../source/incoming/routing/038.php | 6 +- .../source/incoming/routing/039.php | 11 +- .../source/incoming/routing/040.php | 3 +- .../source/incoming/routing/041.php | 9 +- .../source/incoming/routing/042.php | 9 +- .../source/incoming/routing/043.php | 12 +- .../source/incoming/routing/044.php | 2 +- .../source/incoming/routing/045.php | 8 +- .../source/incoming/routing/046.php | 8 +- .../source/incoming/routing/047.php | 9 +- .../source/incoming/routing/048.php | 6 +- .../source/incoming/routing/049.php | 3 + .../source/incoming/routing/050.php | 3 + .../source/incoming/routing/051.php | 9 + .../source/incoming/routing/052.php | 7 + user_guide_src/source/libraries/sessions.rst | 84 ++++----- .../source/libraries/sessions/002.php | 3 + .../source/libraries/sessions/003.php | 2 +- .../source/libraries/sessions/004.php | 2 +- .../source/libraries/sessions/005.php | 2 +- .../source/libraries/sessions/006.php | 2 +- .../source/libraries/sessions/007.php | 2 +- .../source/libraries/sessions/008.php | 10 +- .../source/libraries/sessions/009.php | 10 +- .../source/libraries/sessions/010.php | 4 +- .../source/libraries/sessions/011.php | 8 +- .../source/libraries/sessions/012.php | 8 +- .../source/libraries/sessions/013.php | 6 +- .../source/libraries/sessions/014.php | 6 +- .../source/libraries/sessions/015.php | 2 +- .../source/libraries/sessions/016.php | 7 +- .../source/libraries/sessions/017.php | 7 +- .../source/libraries/sessions/018.php | 3 +- .../source/libraries/sessions/019.php | 3 +- .../source/libraries/sessions/020.php | 2 +- .../source/libraries/sessions/021.php | 3 +- .../source/libraries/sessions/022.php | 3 +- .../source/libraries/sessions/023.php | 2 +- .../source/libraries/sessions/024.php | 2 +- .../source/libraries/sessions/025.php | 2 +- .../source/libraries/sessions/026.php | 3 +- .../source/libraries/sessions/027.php | 4 +- .../source/libraries/sessions/028.php | 11 +- .../source/libraries/sessions/029.php | 11 +- .../source/libraries/sessions/030.php | 3 +- .../source/libraries/sessions/031.php | 3 +- .../source/libraries/sessions/032.php | 3 +- .../source/libraries/sessions/033.php | 2 +- .../source/libraries/sessions/034.php | 2 +- .../source/libraries/sessions/035.php | 2 +- .../source/libraries/sessions/036.php | 2 +- .../source/libraries/sessions/037.php | 4 +- .../source/libraries/sessions/038.php | 4 +- .../source/libraries/sessions/039.php | 11 +- .../source/libraries/sessions/040.php | 3 +- .../source/libraries/sessions/041.php | 3 +- .../source/libraries/sessions/042.php | 4 +- .../source/libraries/sessions/043.php | 6 +- .../source/libraries/sessions/044.php | 14 -- .../source/libraries/uploaded_files.rst | 34 ++-- .../source/libraries/uploaded_files/004.php | 3 + .../source/libraries/uploaded_files/005.php | 3 + .../source/libraries/uploaded_files/006.php | 10 ++ .../source/libraries/uploaded_files/007.php | 3 +- .../source/libraries/uploaded_files/008.php | 2 +- .../source/libraries/uploaded_files/009.php | 10 +- .../source/libraries/uploaded_files/010.php | 5 +- .../source/libraries/uploaded_files/011.php | 2 +- .../source/libraries/uploaded_files/012.php | 3 +- .../source/libraries/uploaded_files/013.php | 4 +- .../source/libraries/uploaded_files/014.php | 2 +- .../source/libraries/uploaded_files/015.php | 4 +- .../source/libraries/uploaded_files/016.php | 2 +- .../source/libraries/uploaded_files/017.php | 3 +- .../source/libraries/uploaded_files/018.php | 6 +- .../source/libraries/uploaded_files/019.php | 2 +- .../source/libraries/uploaded_files/020.php | 3 +- .../source/libraries/uploaded_files/021.php | 5 - .../source/libraries/uploaded_files/022.php | 3 - .../source/libraries/uploaded_files/023.php | 3 - .../source/libraries/validation.rst | 20 +-- .../source/libraries/validation/028.2.php | 12 -- .../source/libraries/validation/029.php | 19 +- .../source/libraries/validation/030.php | 13 +- .../source/libraries/validation/031.php | 16 +- .../source/libraries/validation/032.php | 14 +- .../source/libraries/validation/033.php | 21 ++- .../source/libraries/validation/034.php | 10 +- .../source/libraries/validation/035.php | 16 +- .../source/libraries/validation/036.php | 36 +--- .../source/libraries/validation/037.php | 41 ++++- .../source/libraries/validation/038.php | 10 ++ user_guide_src/source/testing/overview.rst | 32 ++-- .../source/testing/overview/003.php | 14 ++ .../source/testing/overview/004.php | 10 +- .../source/testing/overview/005.php | 11 +- .../source/testing/overview/006.php | 22 ++- .../source/testing/overview/007.php | 22 +-- .../source/testing/overview/008.php | 10 +- .../source/testing/overview/009.php | 10 +- .../source/testing/overview/010.php | 2 +- .../source/testing/overview/011.php | 10 +- .../source/testing/overview/012.php | 2 +- .../source/testing/overview/013.php | 11 +- .../source/testing/overview/014.php | 7 +- .../source/testing/overview/015.php | 6 +- .../source/testing/overview/016.php | 17 +- .../source/testing/overview/017.php | 10 +- .../source/testing/overview/018.php | 16 +- .../source/testing/overview/019.php | 24 --- 246 files changed, 1209 insertions(+), 1209 deletions(-) rename user_guide_src/{renumerate => renumerate.php} (100%) delete mode 100644 user_guide_src/source/incoming/routing/004_1.php delete mode 100644 user_guide_src/source/incoming/routing/004_2.php delete mode 100644 user_guide_src/source/incoming/routing/004_3.php delete mode 100644 user_guide_src/source/incoming/routing/004_4.php create mode 100644 user_guide_src/source/incoming/routing/049.php create mode 100644 user_guide_src/source/incoming/routing/050.php create mode 100644 user_guide_src/source/incoming/routing/051.php create mode 100644 user_guide_src/source/incoming/routing/052.php create mode 100644 user_guide_src/source/libraries/sessions/002.php delete mode 100644 user_guide_src/source/libraries/sessions/044.php create mode 100644 user_guide_src/source/libraries/uploaded_files/004.php create mode 100644 user_guide_src/source/libraries/uploaded_files/005.php create mode 100644 user_guide_src/source/libraries/uploaded_files/006.php delete mode 100644 user_guide_src/source/libraries/uploaded_files/021.php delete mode 100644 user_guide_src/source/libraries/uploaded_files/022.php delete mode 100644 user_guide_src/source/libraries/uploaded_files/023.php delete mode 100644 user_guide_src/source/libraries/validation/028.2.php create mode 100644 user_guide_src/source/libraries/validation/038.php create mode 100644 user_guide_src/source/testing/overview/003.php delete mode 100644 user_guide_src/source/testing/overview/019.php diff --git a/user_guide_src/renumerate b/user_guide_src/renumerate.php similarity index 100% rename from user_guide_src/renumerate rename to user_guide_src/renumerate.php diff --git a/user_guide_src/source/database/query_builder.rst b/user_guide_src/source/database/query_builder.rst index 2df0d3a03084..d6e5b27aac36 100755 --- a/user_guide_src/source/database/query_builder.rst +++ b/user_guide_src/source/database/query_builder.rst @@ -159,7 +159,7 @@ the resulting field. Adds a subquery to the SELECT section. -.. literalinclude:: query_builder/098.php +.. literalinclude:: query_builder/015.php :lines: 2- From @@ -169,7 +169,7 @@ From Permits you to write the **FROM** portion of your query: -.. literalinclude:: query_builder/015.php +.. literalinclude:: query_builder/016.php .. note:: As shown earlier, the **FROM** portion of your query can be specified in the ``$db->table()`` method. Additional calls to ``from()`` will add more tables @@ -186,11 +186,11 @@ Permits you to write part of a **FROM** query as a subquery. This is where we add a subquery to an existing table: -.. literalinclude:: query_builder/016.php +.. literalinclude:: query_builder/017.php Use the ``$db->newQuery()`` method to make a subquery the main table: -.. literalinclude:: query_builder/017.php +.. literalinclude:: query_builder/018.php Join ==== @@ -199,7 +199,7 @@ Join Permits you to write the **JOIN** portion of your query: -.. literalinclude:: query_builder/018.php +.. literalinclude:: query_builder/019.php Multiple method calls can be made if you need several joins in one query. @@ -208,7 +208,7 @@ If you need a specific type of **JOIN** you can specify it via the third parameter of the method. Options are: ``left``, ``right``, ``outer``, ``inner``, ``left outer``, and ``right outer``. -.. literalinclude:: query_builder/019.php +.. literalinclude:: query_builder/020.php ************************* Looking for Specific Data @@ -227,97 +227,97 @@ methods: #. **Simple key/value method:** - .. literalinclude:: query_builder/020.php + .. literalinclude:: query_builder/021.php Notice that the equal sign is added for you. If you use multiple method calls they will be chained together with **AND** between them: - .. literalinclude:: query_builder/021.php + .. literalinclude:: query_builder/022.php #. **Custom key/value method:** You can include an operator in the first parameter in order to control the comparison: - .. literalinclude:: query_builder/022.php + .. literalinclude:: query_builder/023.php #. **Associative array method:** - .. literalinclude:: query_builder/023.php + .. literalinclude:: query_builder/024.php You can include your own operators using this method as well: - .. literalinclude:: query_builder/024.php + .. literalinclude:: query_builder/025.php #. **Custom string:** You can write your own clauses manually: - .. literalinclude:: query_builder/025.php + .. literalinclude:: query_builder/026.php .. warning:: If you are using user-supplied data within the string, you MUST escape the data manually. Failure to do so could result in SQL injections. - .. literalinclude:: query_builder/026.php + .. literalinclude:: query_builder/027.php .. _query-builder-where-subquery: 5. **Subqueries:** - .. literalinclude:: query_builder/027.php + .. literalinclude:: query_builder/028.php **$builder->orWhere()** This method is identical to the one above, except that multiple instances are joined by **OR**: -.. literalinclude:: query_builder/028.php +.. literalinclude:: query_builder/029.php **$builder->whereIn()** Generates a **WHERE** field IN ('item', 'item') SQL query joined with **AND** if appropriate: -.. literalinclude:: query_builder/029.php +.. literalinclude:: query_builder/030.php You can use subqueries instead of an array of values: -.. literalinclude:: query_builder/030.php +.. literalinclude:: query_builder/031.php **$builder->orWhereIn()** Generates a **WHERE field IN ('item', 'item')** SQL query joined with **OR** if appropriate: -.. literalinclude:: query_builder/031.php +.. literalinclude:: query_builder/032.php You can use subqueries instead of an array of values: -.. literalinclude:: query_builder/032.php +.. literalinclude:: query_builder/033.php **$builder->whereNotIn()** Generates a **WHERE field NOT IN ('item', 'item')** SQL query joined with **AND** if appropriate: -.. literalinclude:: query_builder/033.php +.. literalinclude:: query_builder/034.php You can use subqueries instead of an array of values: -.. literalinclude:: query_builder/034.php +.. literalinclude:: query_builder/035.php **$builder->orWhereNotIn()** Generates a **WHERE field NOT IN ('item', 'item')** SQL query joined with **OR** if appropriate: -.. literalinclude:: query_builder/035.php +.. literalinclude:: query_builder/036.php You can use subqueries instead of an array of values: -.. literalinclude:: query_builder/036.php +.. literalinclude:: query_builder/037.php ************************ Looking for Similar Data @@ -337,76 +337,76 @@ searches. #. **Simple key/value method:** - .. literalinclude:: query_builder/037.php + .. literalinclude:: query_builder/038.php If you use multiple method calls they will be chained together with **AND** between them: - .. literalinclude:: query_builder/038.php + .. literalinclude:: query_builder/039.php If you want to control where the wildcard (**%**) is placed, you can use an optional third argument. Your options are ``before``, ``after`` and ``both`` (which is the default). - .. literalinclude:: query_builder/039.php + .. literalinclude:: query_builder/040.php #. **Associative array method:** - .. literalinclude:: query_builder/040.php + .. literalinclude:: query_builder/041.php **$builder->orLike()** This method is identical to the one above, except that multiple instances are joined by **OR**: -.. literalinclude:: query_builder/041.php +.. literalinclude:: query_builder/042.php **$builder->notLike()** This method is identical to ``like()``, except that it generates **NOT LIKE** statements: -.. literalinclude:: query_builder/042.php +.. literalinclude:: query_builder/043.php **$builder->orNotLike()** This method is identical to ``notLike()``, except that multiple instances are joined by **OR**: -.. literalinclude:: query_builder/043.php +.. literalinclude:: query_builder/044.php **$builder->groupBy()** Permits you to write the **GROUP BY** portion of your query: -.. literalinclude:: query_builder/044.php +.. literalinclude:: query_builder/045.php You can also pass an array of multiple values as well: -.. literalinclude:: query_builder/045.php +.. literalinclude:: query_builder/046.php **$builder->distinct()** Adds the **DISTINCT** keyword to a query -.. literalinclude:: query_builder/046.php +.. literalinclude:: query_builder/047.php **$builder->having()** Permits you to write the **HAVING** portion of your query. There are 2 possible syntaxes, 1 argument or 2: -.. literalinclude:: query_builder/047.php +.. literalinclude:: query_builder/048.php You can also pass an array of multiple values as well: -.. literalinclude:: query_builder/048.php +.. literalinclude:: query_builder/049.php If you are using a database that CodeIgniter escapes queries for, you can prevent escaping content by passing an optional third argument, and setting it to ``false``. -.. literalinclude:: query_builder/049.php +.. literalinclude:: query_builder/050.php **$builder->orHaving()** @@ -417,44 +417,44 @@ Identical to ``having()``, only separates multiple clauses with **OR**. Generates a **HAVING field IN ('item', 'item')** SQL query joined with **AND** if appropriate: -.. literalinclude:: query_builder/050.php +.. literalinclude:: query_builder/051.php You can use subqueries instead of an array of values: -.. literalinclude:: query_builder/051.php +.. literalinclude:: query_builder/052.php **$builder->orHavingIn()** Generates a **HAVING field IN ('item', 'item')** SQL query joined with **OR** if appropriate -.. literalinclude:: query_builder/052.php +.. literalinclude:: query_builder/053.php You can use subqueries instead of an array of values: -.. literalinclude:: query_builder/053.php +.. literalinclude:: query_builder/054.php **$builder->havingNotIn()** Generates a **HAVING field NOT IN ('item', 'item')** SQL query joined with **AND** if appropriate -.. literalinclude:: query_builder/054.php +.. literalinclude:: query_builder/055.php You can use subqueries instead of an array of values: -.. literalinclude:: query_builder/055.php +.. literalinclude:: query_builder/056.php **$builder->orHavingNotIn()** Generates a **HAVING field NOT IN ('item', 'item')** SQL query joined with **OR** if appropriate -.. literalinclude:: query_builder/056.php +.. literalinclude:: query_builder/057.php You can use subqueries instead of an array of values: -.. literalinclude:: query_builder/057.php +.. literalinclude:: query_builder/058.php **$builder->havingLike()** @@ -470,43 +470,43 @@ searches. #. **Simple key/value method:** - .. literalinclude:: query_builder/058.php + .. literalinclude:: query_builder/059.php If you use multiple method calls they will be chained together with **AND** between them: - .. literalinclude:: query_builder/059.php + .. literalinclude:: query_builder/060.php If you want to control where the wildcard (**%**) is placed, you can use an optional third argument. Your options are ``before``, ``after`` and ``both`` (which is the default). - .. literalinclude:: query_builder/060.php + .. literalinclude:: query_builder/061.php #. **Associative array method:** - .. literalinclude:: query_builder/061.php + .. literalinclude:: query_builder/062.php **$builder->orHavingLike()** This method is identical to the one above, except that multiple instances are joined by **OR**: -.. literalinclude:: query_builder/062.php +.. literalinclude:: query_builder/063.php **$builder->notHavingLike()** This method is identical to ``havingLike()``, except that it generates **NOT LIKE** statements: -.. literalinclude:: query_builder/063.php +.. literalinclude:: query_builder/064.php **$builder->orNotHavingLike()** This method is identical to ``notHavingLike()``, except that multiple instances are joined by **OR**: -.. literalinclude:: query_builder/064.php +.. literalinclude:: query_builder/065.php **************** Ordering Results @@ -521,20 +521,20 @@ The first parameter contains the name of the column you would like to order by. The second parameter lets you set the direction of the result. Options are ``ASC``, ``DESC`` AND ``RANDOM``. -.. literalinclude:: query_builder/065.php +.. literalinclude:: query_builder/066.php You can also pass your own string in the first parameter: -.. literalinclude:: query_builder/066.php +.. literalinclude:: query_builder/067.php Or multiple method calls can be made if you need multiple fields. -.. literalinclude:: query_builder/067.php +.. literalinclude:: query_builder/068.php If you choose the ``RANDOM`` direction option, then the first parameters will be ignored, unless you specify a numeric seed value. -.. literalinclude:: query_builder/068.php +.. literalinclude:: query_builder/069.php **************************** Limiting or Counting Results @@ -544,11 +544,11 @@ Limiting or Counting Results Lets you limit the number of rows you would like returned by the query: -.. literalinclude:: query_builder/069.php +.. literalinclude:: query_builder/070.php The second parameter lets you set a result offset. -.. literalinclude:: query_builder/070.php +.. literalinclude:: query_builder/071.php **$builder->countAllResults()** @@ -556,20 +556,20 @@ Permits you to determine the number of rows in a particular Query Builder query. Queries will accept Query Builder restrictors such as ``where()``, ``orWhere()``, ``like()``, ``orLike()``, etc. Example: -.. literalinclude:: query_builder/071.php +.. literalinclude:: query_builder/072.php However, this method also resets any field values that you may have passed to ``select()``. If you need to keep them, you can pass ``false`` as the first parameter. -.. literalinclude:: query_builder/072.php +.. literalinclude:: query_builder/073.php **$builder->countAll()** Permits you to determine the number of rows in a particular table. Example: -.. literalinclude:: query_builder/073.php +.. literalinclude:: query_builder/074.php As is in ``countAllResult()`` method, this method resets any field values that you may have passed to ``select()`` as well. If you need to keep them, you can pass ``false`` as the @@ -582,7 +582,7 @@ Query grouping Query grouping allows you to create groups of **WHERE** clauses by enclosing them in parentheses. This will allow you to create queries with complex **WHERE** clauses. Nested groups are supported. Example: -.. literalinclude:: query_builder/074.php +.. literalinclude:: query_builder/075.php .. note:: Groups need to be balanced, make sure every ``groupStart()`` is matched by a ``groupEnd()``. @@ -636,13 +636,13 @@ Generates an insert string based on the data you supply, and runs the query. You can either pass an **array** or an **object** to the method. Here is an example using an array: -.. literalinclude:: query_builder/075.php +.. literalinclude:: query_builder/076.php The first parameter is an associative array of values. Here is an example using an object: -.. literalinclude:: query_builder/076.php +.. literalinclude:: query_builder/077.php The first parameter is an object. @@ -654,7 +654,7 @@ Generates an insert ignore string based on the data you supply, and runs the query. So if an entry with the same primary key already exists, the query won't be inserted. You can optionally pass an **boolean** to the method. Here is an example using the array of the above example: -.. literalinclude:: query_builder/077.php +.. literalinclude:: query_builder/078.php **$builder->getCompiledInsert()** @@ -663,12 +663,12 @@ Compiles the insertion query just like ``$builder->insert()`` but does not Example: -.. literalinclude:: query_builder/078.php +.. literalinclude:: query_builder/079.php The first parameter enables you to set whether or not the query builder query will be reset (by default it will be--just like ``$builder->insert()``): -.. literalinclude:: query_builder/079.php +.. literalinclude:: query_builder/080.php The reason the second query worked is that the query has not been executed using ``$builder->insert()`` which resets values or reset directly using @@ -682,7 +682,7 @@ Generates an insert string based on the data you supply, and runs the query. You can either pass an **array** or an **object** to the method. Here is an example using an array: -.. literalinclude:: query_builder/080.php +.. literalinclude:: query_builder/081.php The first parameter is an associative array of values. @@ -703,7 +703,7 @@ logics with different combinations of ``select()``, ``update()``, Example: -.. literalinclude:: query_builder/081.php +.. literalinclude:: query_builder/082.php In the above example, if we assume that the ``title`` field is our primary key, then if a row containing ``My title`` as the ``title`` value, that row @@ -719,27 +719,27 @@ This method enables you to set values for inserts or updates. **It can be used instead of passing a data array directly to the insert() or update() methods:** -.. literalinclude:: query_builder/082.php +.. literalinclude:: query_builder/083.php If you use multiple method called they will be assembled properly based on whether you are doing an insert or an update: -.. literalinclude:: query_builder/083.php +.. literalinclude:: query_builder/084.php ``set()`` will also accept an optional third parameter (``$escape``), that will prevent data from being escaped if set to ``false``. To illustrate the difference, here is ``set()`` used both with and without the escape parameter. -.. literalinclude:: query_builder/084.php +.. literalinclude:: query_builder/085.php You can also pass an associative array to this method: -.. literalinclude:: query_builder/085.php +.. literalinclude:: query_builder/086.php Or an object: -.. literalinclude:: query_builder/086.php +.. literalinclude:: query_builder/087.php **$builder->update()** @@ -747,11 +747,11 @@ Generates an update string and runs the query based on the data you supply. You can pass an **array** or an **object** to the method. Here is an example using an array: -.. literalinclude:: query_builder/087.php +.. literalinclude:: query_builder/088.php Or you can supply an object: -.. literalinclude:: query_builder/088.php +.. literalinclude:: query_builder/089.php .. note:: All values are escaped automatically producing safer queries. @@ -759,11 +759,11 @@ You'll notice the use of the ``$builder->where()`` method, enabling you to set the **WHERE** clause. You can optionally pass this information directly into the ``update()`` method as a string: -.. literalinclude:: query_builder/089.php +.. literalinclude:: query_builder/090.php Or as an array: -.. literalinclude:: query_builder/090.php +.. literalinclude:: query_builder/091.php You may also use the ``$builder->set()`` method described above when performing updates. @@ -774,7 +774,7 @@ Generates an update string based on the data you supply, and runs the query. You can either pass an **array** or an **object** to the method. Here is an example using an array: -.. literalinclude:: query_builder/091.php +.. literalinclude:: query_builder/092.php The first parameter is an associative array of values, the second parameter is the where key. @@ -801,13 +801,13 @@ Deleting Data Generates a **DELETE** SQL string and runs the query. -.. literalinclude:: query_builder/092.php +.. literalinclude:: query_builder/093.php The first parameter is the where clause. You can also use the ``where()`` or ``or_where()`` methods instead of passing the data to the first parameter of the method: -.. literalinclude:: query_builder/093.php +.. literalinclude:: query_builder/094.php If you want to delete all data from a table, you can use the ``truncate()`` method, or ``emptyTable()``. @@ -817,13 +817,13 @@ method, or ``emptyTable()``. Generates a **DELETE** SQL string and runs the query: -.. literalinclude:: query_builder/094.php +.. literalinclude:: query_builder/095.php **$builder->truncate()** Generates a **TRUNCATE** SQL string and runs the query. -.. literalinclude:: query_builder/095.php +.. literalinclude:: query_builder/096.php .. note:: If the TRUNCATE command isn't available, ``truncate()`` will execute as "DELETE FROM table". @@ -842,7 +842,7 @@ Method Chaining Method chaining allows you to simplify your syntax by connecting multiple methods. Consider this example: -.. literalinclude:: query_builder/096.php +.. literalinclude:: query_builder/097.php .. _ar-caching: @@ -859,7 +859,7 @@ This is useful in situations where you are using Query Builder to generate SQL (e.g., ``$builder->getCompiledSelect()``) but then choose to, for instance, run the query: -.. literalinclude:: query_builder/097.php +.. literalinclude:: query_builder/098.php *************** Class Reference diff --git a/user_guide_src/source/database/query_builder/015.php b/user_guide_src/source/database/query_builder/015.php index 727a7e5bd3e8..b3890e978005 100644 --- a/user_guide_src/source/database/query_builder/015.php +++ b/user_guide_src/source/database/query_builder/015.php @@ -1,7 +1,6 @@ table('users'); -$builder->select('title, content, date'); -$builder->from('mytable'); -$query = $builder->get(); -// Produces: SELECT title, content, date FROM users, mytable +$subquery = $db->table('countries')->select('name')->where('id', 1); +$builder = $db->table('users')->select('name')->selectSubquery($subquery, 'country'); +$query = $builder->get(); +// Produces: SELECT `name`, (SELECT `name` FROM `countries` WHERE `id` = 1) AS `country` FROM `users` diff --git a/user_guide_src/source/database/query_builder/016.php b/user_guide_src/source/database/query_builder/016.php index 1ad1c917ff57..727a7e5bd3e8 100644 --- a/user_guide_src/source/database/query_builder/016.php +++ b/user_guide_src/source/database/query_builder/016.php @@ -1,6 +1,7 @@ table('users'); -$builder = $db->table('jobs')->fromSubquery($subquery, 'alias'); -$query = $builder->get(); -// Produces: SELECT * FROM `jobs`, (SELECT * FROM `users`) AS `alias` +$builder = $db->table('users'); +$builder->select('title, content, date'); +$builder->from('mytable'); +$query = $builder->get(); +// Produces: SELECT title, content, date FROM users, mytable diff --git a/user_guide_src/source/database/query_builder/017.php b/user_guide_src/source/database/query_builder/017.php index b33dd475b6f8..1ad1c917ff57 100644 --- a/user_guide_src/source/database/query_builder/017.php +++ b/user_guide_src/source/database/query_builder/017.php @@ -1,6 +1,6 @@ table('users')->select('id, name'); -$builder = $db->newQuery()->fromSubquery($subquery, 't'); +$subquery = $db->table('users'); +$builder = $db->table('jobs')->fromSubquery($subquery, 'alias'); $query = $builder->get(); -// Produces: SELECT * FROM (SELECT `id`, `name` FROM users) AS `t` +// Produces: SELECT * FROM `jobs`, (SELECT * FROM `users`) AS `alias` diff --git a/user_guide_src/source/database/query_builder/018.php b/user_guide_src/source/database/query_builder/018.php index 159f88e4a984..b33dd475b6f8 100644 --- a/user_guide_src/source/database/query_builder/018.php +++ b/user_guide_src/source/database/query_builder/018.php @@ -1,10 +1,6 @@ table('blogs'); -$builder->select('*'); -$builder->join('comments', 'comments.id = blogs.id'); -$query = $builder->get(); -/* - * Produces: - * SELECT * FROM blogs JOIN comments ON comments.id = blogs.id - */ +$subquery = $db->table('users')->select('id, name'); +$builder = $db->newQuery()->fromSubquery($subquery, 't'); +$query = $builder->get(); +// Produces: SELECT * FROM (SELECT `id`, `name` FROM users) AS `t` diff --git a/user_guide_src/source/database/query_builder/019.php b/user_guide_src/source/database/query_builder/019.php index 428451dfb822..159f88e4a984 100644 --- a/user_guide_src/source/database/query_builder/019.php +++ b/user_guide_src/source/database/query_builder/019.php @@ -1,4 +1,10 @@ join('comments', 'comments.id = blogs.id', 'left'); -// Produces: LEFT JOIN comments ON comments.id = blogs.id +$builder = $db->table('blogs'); +$builder->select('*'); +$builder->join('comments', 'comments.id = blogs.id'); +$query = $builder->get(); +/* + * Produces: + * SELECT * FROM blogs JOIN comments ON comments.id = blogs.id + */ diff --git a/user_guide_src/source/database/query_builder/020.php b/user_guide_src/source/database/query_builder/020.php index cf0ce1b24ff2..428451dfb822 100644 --- a/user_guide_src/source/database/query_builder/020.php +++ b/user_guide_src/source/database/query_builder/020.php @@ -1,4 +1,4 @@ where('name', $name); -// Produces: WHERE name = 'Joe' +$builder->join('comments', 'comments.id = blogs.id', 'left'); +// Produces: LEFT JOIN comments ON comments.id = blogs.id diff --git a/user_guide_src/source/database/query_builder/021.php b/user_guide_src/source/database/query_builder/021.php index 08d3c63f40d5..cf0ce1b24ff2 100644 --- a/user_guide_src/source/database/query_builder/021.php +++ b/user_guide_src/source/database/query_builder/021.php @@ -1,6 +1,4 @@ where('name', $name); -$builder->where('title', $title); -$builder->where('status', $status); -// WHERE name = 'Joe' AND title = 'boss' AND status = 'active' +// Produces: WHERE name = 'Joe' diff --git a/user_guide_src/source/database/query_builder/022.php b/user_guide_src/source/database/query_builder/022.php index e6950008ff68..08d3c63f40d5 100644 --- a/user_guide_src/source/database/query_builder/022.php +++ b/user_guide_src/source/database/query_builder/022.php @@ -1,5 +1,6 @@ where('name !=', $name); -$builder->where('id <', $id); -// Produces: WHERE name != 'Joe' AND id < 45 +$builder->where('name', $name); +$builder->where('title', $title); +$builder->where('status', $status); +// WHERE name = 'Joe' AND title = 'boss' AND status = 'active' diff --git a/user_guide_src/source/database/query_builder/023.php b/user_guide_src/source/database/query_builder/023.php index 36fdf370be96..e6950008ff68 100644 --- a/user_guide_src/source/database/query_builder/023.php +++ b/user_guide_src/source/database/query_builder/023.php @@ -1,5 +1,5 @@ $name, 'title' => $title, 'status' => $status]; -$builder->where($array); -// Produces: WHERE name = 'Joe' AND title = 'boss' AND status = 'active' +$builder->where('name !=', $name); +$builder->where('id <', $id); +// Produces: WHERE name != 'Joe' AND id < 45 diff --git a/user_guide_src/source/database/query_builder/024.php b/user_guide_src/source/database/query_builder/024.php index d136a85683a9..36fdf370be96 100644 --- a/user_guide_src/source/database/query_builder/024.php +++ b/user_guide_src/source/database/query_builder/024.php @@ -1,4 +1,5 @@ $name, 'id <' => $id, 'date >' => $date]; +$array = ['name' => $name, 'title' => $title, 'status' => $status]; $builder->where($array); +// Produces: WHERE name = 'Joe' AND title = 'boss' AND status = 'active' diff --git a/user_guide_src/source/database/query_builder/025.php b/user_guide_src/source/database/query_builder/025.php index 10175cc40a71..d136a85683a9 100644 --- a/user_guide_src/source/database/query_builder/025.php +++ b/user_guide_src/source/database/query_builder/025.php @@ -1,4 +1,4 @@ where($where); +$array = ['name !=' => $name, 'id <' => $id, 'date >' => $date]; +$builder->where($array); diff --git a/user_guide_src/source/database/query_builder/026.php b/user_guide_src/source/database/query_builder/026.php index ed45b84bf363..10175cc40a71 100644 --- a/user_guide_src/source/database/query_builder/026.php +++ b/user_guide_src/source/database/query_builder/026.php @@ -1,5 +1,4 @@ db->escape('Joe'); -$where = "name={$name} AND status='boss' OR status='active'"; +$where = "name='Joe' AND status='boss' OR status='active'"; $builder->where($where); diff --git a/user_guide_src/source/database/query_builder/027.php b/user_guide_src/source/database/query_builder/027.php index 019386718cd1..ed45b84bf363 100644 --- a/user_guide_src/source/database/query_builder/027.php +++ b/user_guide_src/source/database/query_builder/027.php @@ -1,9 +1,5 @@ where('advance_amount <', static fn (BaseBuilder $builder) => $builder->select('MAX(advance_amount)', false)->from('orders')->where('id >', 2)); -// Produces: WHERE "advance_amount" < (SELECT MAX(advance_amount) FROM "orders" WHERE "id" > 2) - -// With builder directly -$subQuery = $db->table('orders')->select('MAX(advance_amount)', false)->where('id >', 2); -$builder->where('advance_amount <', $subQuery); +$name = $builder->db->escape('Joe'); +$where = "name={$name} AND status='boss' OR status='active'"; +$builder->where($where); diff --git a/user_guide_src/source/database/query_builder/028.php b/user_guide_src/source/database/query_builder/028.php index d925a347e428..019386718cd1 100644 --- a/user_guide_src/source/database/query_builder/028.php +++ b/user_guide_src/source/database/query_builder/028.php @@ -1,5 +1,9 @@ where('name !=', $name); -$builder->orWhere('id >', $id); -// Produces: WHERE name != 'Joe' OR id > 50 +// With closure +$builder->where('advance_amount <', static fn (BaseBuilder $builder) => $builder->select('MAX(advance_amount)', false)->from('orders')->where('id >', 2)); +// Produces: WHERE "advance_amount" < (SELECT MAX(advance_amount) FROM "orders" WHERE "id" > 2) + +// With builder directly +$subQuery = $db->table('orders')->select('MAX(advance_amount)', false)->where('id >', 2); +$builder->where('advance_amount <', $subQuery); diff --git a/user_guide_src/source/database/query_builder/029.php b/user_guide_src/source/database/query_builder/029.php index 6683a842eb99..d925a347e428 100644 --- a/user_guide_src/source/database/query_builder/029.php +++ b/user_guide_src/source/database/query_builder/029.php @@ -1,5 +1,5 @@ whereIn('username', $names); -// Produces: WHERE username IN ('Frank', 'Todd', 'James') +$builder->where('name !=', $name); +$builder->orWhere('id >', $id); +// Produces: WHERE name != 'Joe' OR id > 50 diff --git a/user_guide_src/source/database/query_builder/030.php b/user_guide_src/source/database/query_builder/030.php index 5aa7619c0dc8..6683a842eb99 100644 --- a/user_guide_src/source/database/query_builder/030.php +++ b/user_guide_src/source/database/query_builder/030.php @@ -1,9 +1,5 @@ whereIn('id', static fn (BaseBuilder $builder) => $builder->select('job_id')->from('users_jobs')->where('user_id', 3)); -// Produces: WHERE "id" IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3) - -// With builder directly -$subQuery = $db->table('users_jobs')->select('job_id')->where('user_id', 3); -$builder->whereIn('id', $subQuery); +$names = ['Frank', 'Todd', 'James']; +$builder->whereIn('username', $names); +// Produces: WHERE username IN ('Frank', 'Todd', 'James') diff --git a/user_guide_src/source/database/query_builder/031.php b/user_guide_src/source/database/query_builder/031.php index b1fea4626937..5aa7619c0dc8 100644 --- a/user_guide_src/source/database/query_builder/031.php +++ b/user_guide_src/source/database/query_builder/031.php @@ -1,5 +1,9 @@ orWhereIn('username', $names); -// Produces: OR username IN ('Frank', 'Todd', 'James') +// With closure +$builder->whereIn('id', static fn (BaseBuilder $builder) => $builder->select('job_id')->from('users_jobs')->where('user_id', 3)); +// Produces: WHERE "id" IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3) + +// With builder directly +$subQuery = $db->table('users_jobs')->select('job_id')->where('user_id', 3); +$builder->whereIn('id', $subQuery); diff --git a/user_guide_src/source/database/query_builder/032.php b/user_guide_src/source/database/query_builder/032.php index ae8ddb7ce7a4..b1fea4626937 100644 --- a/user_guide_src/source/database/query_builder/032.php +++ b/user_guide_src/source/database/query_builder/032.php @@ -1,9 +1,5 @@ orWhereIn('id', static fn (BaseBuilder $builder) => $builder->select('job_id')->from('users_jobs')->where('user_id', 3)); -// Produces: OR "id" IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3) - -// With builder directly -$subQuery = $db->table('users_jobs')->select('job_id')->where('user_id', 3); -$builder->orWhereIn('id', $subQuery); +$names = ['Frank', 'Todd', 'James']; +$builder->orWhereIn('username', $names); +// Produces: OR username IN ('Frank', 'Todd', 'James') diff --git a/user_guide_src/source/database/query_builder/033.php b/user_guide_src/source/database/query_builder/033.php index 46b196764e71..ae8ddb7ce7a4 100644 --- a/user_guide_src/source/database/query_builder/033.php +++ b/user_guide_src/source/database/query_builder/033.php @@ -1,5 +1,9 @@ whereNotIn('username', $names); -// Produces: WHERE username NOT IN ('Frank', 'Todd', 'James') +// With closure +$builder->orWhereIn('id', static fn (BaseBuilder $builder) => $builder->select('job_id')->from('users_jobs')->where('user_id', 3)); +// Produces: OR "id" IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3) + +// With builder directly +$subQuery = $db->table('users_jobs')->select('job_id')->where('user_id', 3); +$builder->orWhereIn('id', $subQuery); diff --git a/user_guide_src/source/database/query_builder/034.php b/user_guide_src/source/database/query_builder/034.php index 02904a3962f3..46b196764e71 100644 --- a/user_guide_src/source/database/query_builder/034.php +++ b/user_guide_src/source/database/query_builder/034.php @@ -1,9 +1,5 @@ whereNotIn('id', static fn (BaseBuilder $builder) => $builder->select('job_id')->from('users_jobs')->where('user_id', 3)); -// Produces: WHERE "id" NOT IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3) - -// With builder directly -$subQuery = $db->table('users_jobs')->select('job_id')->where('user_id', 3); -$builder->whereNotIn('id', $subQuery); +$names = ['Frank', 'Todd', 'James']; +$builder->whereNotIn('username', $names); +// Produces: WHERE username NOT IN ('Frank', 'Todd', 'James') diff --git a/user_guide_src/source/database/query_builder/035.php b/user_guide_src/source/database/query_builder/035.php index d37209c5efd8..02904a3962f3 100644 --- a/user_guide_src/source/database/query_builder/035.php +++ b/user_guide_src/source/database/query_builder/035.php @@ -1,5 +1,9 @@ orWhereNotIn('username', $names); -// Produces: OR username NOT IN ('Frank', 'Todd', 'James') +// With closure +$builder->whereNotIn('id', static fn (BaseBuilder $builder) => $builder->select('job_id')->from('users_jobs')->where('user_id', 3)); +// Produces: WHERE "id" NOT IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3) + +// With builder directly +$subQuery = $db->table('users_jobs')->select('job_id')->where('user_id', 3); +$builder->whereNotIn('id', $subQuery); diff --git a/user_guide_src/source/database/query_builder/036.php b/user_guide_src/source/database/query_builder/036.php index f5668aa1a30d..d37209c5efd8 100644 --- a/user_guide_src/source/database/query_builder/036.php +++ b/user_guide_src/source/database/query_builder/036.php @@ -1,9 +1,5 @@ orWhereNotIn('id', static fn (BaseBuilder $builder) => $builder->select('job_id')->from('users_jobs')->where('user_id', 3)); -// Produces: OR "id" NOT IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3) - -// With builder directly -$subQuery = $db->table('users_jobs')->select('job_id')->where('user_id', 3); -$builder->orWhereNotIn('id', $subQuery); +$names = ['Frank', 'Todd', 'James']; +$builder->orWhereNotIn('username', $names); +// Produces: OR username NOT IN ('Frank', 'Todd', 'James') diff --git a/user_guide_src/source/database/query_builder/037.php b/user_guide_src/source/database/query_builder/037.php index d5218d2f8f59..f5668aa1a30d 100644 --- a/user_guide_src/source/database/query_builder/037.php +++ b/user_guide_src/source/database/query_builder/037.php @@ -1,4 +1,9 @@ like('title', 'match'); -// Produces: WHERE `title` LIKE '%match%' ESCAPE '!' +// With closure +$builder->orWhereNotIn('id', static fn (BaseBuilder $builder) => $builder->select('job_id')->from('users_jobs')->where('user_id', 3)); +// Produces: OR "id" NOT IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3) + +// With builder directly +$subQuery = $db->table('users_jobs')->select('job_id')->where('user_id', 3); +$builder->orWhereNotIn('id', $subQuery); diff --git a/user_guide_src/source/database/query_builder/038.php b/user_guide_src/source/database/query_builder/038.php index a8ae3efa1d27..d5218d2f8f59 100644 --- a/user_guide_src/source/database/query_builder/038.php +++ b/user_guide_src/source/database/query_builder/038.php @@ -1,5 +1,4 @@ like('title', 'match'); -$builder->like('body', 'match'); -// WHERE `title` LIKE '%match%' ESCAPE '!' AND `body` LIKE '%match%' ESCAPE '!' +// Produces: WHERE `title` LIKE '%match%' ESCAPE '!' diff --git a/user_guide_src/source/database/query_builder/039.php b/user_guide_src/source/database/query_builder/039.php index 519686f9e4d9..a8ae3efa1d27 100644 --- a/user_guide_src/source/database/query_builder/039.php +++ b/user_guide_src/source/database/query_builder/039.php @@ -1,5 +1,5 @@ like('title', 'match', 'before'); // Produces: WHERE `title` LIKE '%match' ESCAPE '!' -$builder->like('title', 'match', 'after'); // Produces: WHERE `title` LIKE 'match%' ESCAPE '!' -$builder->like('title', 'match', 'both'); // Produces: WHERE `title` LIKE '%match%' ESCAPE '!' +$builder->like('title', 'match'); +$builder->like('body', 'match'); +// WHERE `title` LIKE '%match%' ESCAPE '!' AND `body` LIKE '%match%' ESCAPE '!' diff --git a/user_guide_src/source/database/query_builder/040.php b/user_guide_src/source/database/query_builder/040.php index 0583a2a79187..519686f9e4d9 100644 --- a/user_guide_src/source/database/query_builder/040.php +++ b/user_guide_src/source/database/query_builder/040.php @@ -1,5 +1,5 @@ $match, 'page1' => $match, 'page2' => $match]; -$builder->like($array); -// WHERE `title` LIKE '%match%' ESCAPE '!' AND `page1` LIKE '%match%' ESCAPE '!' AND `page2` LIKE '%match%' ESCAPE '!' +$builder->like('title', 'match', 'before'); // Produces: WHERE `title` LIKE '%match' ESCAPE '!' +$builder->like('title', 'match', 'after'); // Produces: WHERE `title` LIKE 'match%' ESCAPE '!' +$builder->like('title', 'match', 'both'); // Produces: WHERE `title` LIKE '%match%' ESCAPE '!' diff --git a/user_guide_src/source/database/query_builder/041.php b/user_guide_src/source/database/query_builder/041.php index 7c9935e4f356..0583a2a79187 100644 --- a/user_guide_src/source/database/query_builder/041.php +++ b/user_guide_src/source/database/query_builder/041.php @@ -1,4 +1,5 @@ like('title', 'match'); $builder->orLike('body', $match); -// WHERE `title` LIKE '%match%' ESCAPE '!' OR `body` LIKE '%match%' ESCAPE '!' +$array = ['title' => $match, 'page1' => $match, 'page2' => $match]; +$builder->like($array); +// WHERE `title` LIKE '%match%' ESCAPE '!' AND `page1` LIKE '%match%' ESCAPE '!' AND `page2` LIKE '%match%' ESCAPE '!' diff --git a/user_guide_src/source/database/query_builder/042.php b/user_guide_src/source/database/query_builder/042.php index 983068b45fef..7c9935e4f356 100644 --- a/user_guide_src/source/database/query_builder/042.php +++ b/user_guide_src/source/database/query_builder/042.php @@ -1,3 +1,4 @@ notLike('title', 'match'); // WHERE `title` NOT LIKE '%match% ESCAPE '!' +$builder->like('title', 'match'); $builder->orLike('body', $match); +// WHERE `title` LIKE '%match%' ESCAPE '!' OR `body` LIKE '%match%' ESCAPE '!' diff --git a/user_guide_src/source/database/query_builder/043.php b/user_guide_src/source/database/query_builder/043.php index f0f442dfeb78..983068b45fef 100644 --- a/user_guide_src/source/database/query_builder/043.php +++ b/user_guide_src/source/database/query_builder/043.php @@ -1,5 +1,3 @@ like('title', 'match'); -$builder->orNotLike('body', 'match'); -// WHERE `title` LIKE '%match% OR `body` NOT LIKE '%match%' ESCAPE '!' +$builder->notLike('title', 'match'); // WHERE `title` NOT LIKE '%match% ESCAPE '!' diff --git a/user_guide_src/source/database/query_builder/044.php b/user_guide_src/source/database/query_builder/044.php index ffe4786baaae..f0f442dfeb78 100644 --- a/user_guide_src/source/database/query_builder/044.php +++ b/user_guide_src/source/database/query_builder/044.php @@ -1,4 +1,5 @@ groupBy('title'); -// Produces: GROUP BY title +$builder->like('title', 'match'); +$builder->orNotLike('body', 'match'); +// WHERE `title` LIKE '%match% OR `body` NOT LIKE '%match%' ESCAPE '!' diff --git a/user_guide_src/source/database/query_builder/045.php b/user_guide_src/source/database/query_builder/045.php index 0872996afe9f..ffe4786baaae 100644 --- a/user_guide_src/source/database/query_builder/045.php +++ b/user_guide_src/source/database/query_builder/045.php @@ -1,4 +1,4 @@ groupBy(['title', 'date']); -// Produces: GROUP BY title, date +$builder->groupBy('title'); +// Produces: GROUP BY title diff --git a/user_guide_src/source/database/query_builder/046.php b/user_guide_src/source/database/query_builder/046.php index 0e6f6415d6f7..0872996afe9f 100644 --- a/user_guide_src/source/database/query_builder/046.php +++ b/user_guide_src/source/database/query_builder/046.php @@ -1,5 +1,4 @@ distinct(); -$builder->get(); -// Produces: SELECT DISTINCT * FROM mytable +$builder->groupBy(['title', 'date']); +// Produces: GROUP BY title, date diff --git a/user_guide_src/source/database/query_builder/047.php b/user_guide_src/source/database/query_builder/047.php index 87f435064238..0e6f6415d6f7 100644 --- a/user_guide_src/source/database/query_builder/047.php +++ b/user_guide_src/source/database/query_builder/047.php @@ -1,4 +1,5 @@ having('user_id = 45'); // Produces: HAVING user_id = 45 -$builder->having('user_id', 45); // Produces: HAVING user_id = 45 +$builder->distinct(); +$builder->get(); +// Produces: SELECT DISTINCT * FROM mytable diff --git a/user_guide_src/source/database/query_builder/048.php b/user_guide_src/source/database/query_builder/048.php index e911e5e87302..87f435064238 100644 --- a/user_guide_src/source/database/query_builder/048.php +++ b/user_guide_src/source/database/query_builder/048.php @@ -1,4 +1,4 @@ having(['title =' => 'My Title', 'id <' => $id]); -// Produces: HAVING title = 'My Title', id < 45 +$builder->having('user_id = 45'); // Produces: HAVING user_id = 45 +$builder->having('user_id', 45); // Produces: HAVING user_id = 45 diff --git a/user_guide_src/source/database/query_builder/049.php b/user_guide_src/source/database/query_builder/049.php index b044b821f388..e911e5e87302 100644 --- a/user_guide_src/source/database/query_builder/049.php +++ b/user_guide_src/source/database/query_builder/049.php @@ -1,4 +1,4 @@ having('user_id', 45); // Produces: HAVING `user_id` = 45 in some databases such as MySQL -$builder->having('user_id', 45, false); // Produces: HAVING user_id = 45 +$builder->having(['title =' => 'My Title', 'id <' => $id]); +// Produces: HAVING title = 'My Title', id < 45 diff --git a/user_guide_src/source/database/query_builder/050.php b/user_guide_src/source/database/query_builder/050.php index bc6f5a3e1412..b044b821f388 100644 --- a/user_guide_src/source/database/query_builder/050.php +++ b/user_guide_src/source/database/query_builder/050.php @@ -1,5 +1,4 @@ havingIn('group_id', $groups); -// Produces: HAVING group_id IN (1, 2, 3) +$builder->having('user_id', 45); // Produces: HAVING `user_id` = 45 in some databases such as MySQL +$builder->having('user_id', 45, false); // Produces: HAVING user_id = 45 diff --git a/user_guide_src/source/database/query_builder/051.php b/user_guide_src/source/database/query_builder/051.php index 1f5736243866..bc6f5a3e1412 100644 --- a/user_guide_src/source/database/query_builder/051.php +++ b/user_guide_src/source/database/query_builder/051.php @@ -1,9 +1,5 @@ havingIn('id', static fn (BaseBuilder $builder) => $builder->select('user_id')->from('users_jobs')->where('group_id', 3)); -// Produces: HAVING "id" IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3) - -// With builder directly -$subQuery = $db->table('users_jobs')->select('user_id')->where('group_id', 3); -$builder->havingIn('id', $subQuery); +$groups = [1, 2, 3]; +$builder->havingIn('group_id', $groups); +// Produces: HAVING group_id IN (1, 2, 3) diff --git a/user_guide_src/source/database/query_builder/052.php b/user_guide_src/source/database/query_builder/052.php index aa07cad01be9..1f5736243866 100644 --- a/user_guide_src/source/database/query_builder/052.php +++ b/user_guide_src/source/database/query_builder/052.php @@ -1,5 +1,9 @@ orHavingIn('group_id', $groups); -// Produces: OR group_id IN (1, 2, 3) +// With closure +$builder->havingIn('id', static fn (BaseBuilder $builder) => $builder->select('user_id')->from('users_jobs')->where('group_id', 3)); +// Produces: HAVING "id" IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3) + +// With builder directly +$subQuery = $db->table('users_jobs')->select('user_id')->where('group_id', 3); +$builder->havingIn('id', $subQuery); diff --git a/user_guide_src/source/database/query_builder/053.php b/user_guide_src/source/database/query_builder/053.php index 8a19ff4ac7d8..aa07cad01be9 100644 --- a/user_guide_src/source/database/query_builder/053.php +++ b/user_guide_src/source/database/query_builder/053.php @@ -1,9 +1,5 @@ orHavingIn('id', static fn (BaseBuilder $builder) => $builder->select('user_id')->from('users_jobs')->where('group_id', 3)); -// Produces: OR "id" IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3) - -// With builder directly -$subQuery = $db->table('users_jobs')->select('user_id')->where('group_id', 3); -$builder->orHavingIn('id', $subQuery); +$groups = [1, 2, 3]; +$builder->orHavingIn('group_id', $groups); +// Produces: OR group_id IN (1, 2, 3) diff --git a/user_guide_src/source/database/query_builder/054.php b/user_guide_src/source/database/query_builder/054.php index 875a2afcbfe4..8a19ff4ac7d8 100644 --- a/user_guide_src/source/database/query_builder/054.php +++ b/user_guide_src/source/database/query_builder/054.php @@ -1,5 +1,9 @@ havingNotIn('group_id', $groups); -// Produces: HAVING group_id NOT IN (1, 2, 3) +// With closure +$builder->orHavingIn('id', static fn (BaseBuilder $builder) => $builder->select('user_id')->from('users_jobs')->where('group_id', 3)); +// Produces: OR "id" IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3) + +// With builder directly +$subQuery = $db->table('users_jobs')->select('user_id')->where('group_id', 3); +$builder->orHavingIn('id', $subQuery); diff --git a/user_guide_src/source/database/query_builder/055.php b/user_guide_src/source/database/query_builder/055.php index 67a54f87f7bc..875a2afcbfe4 100644 --- a/user_guide_src/source/database/query_builder/055.php +++ b/user_guide_src/source/database/query_builder/055.php @@ -1,9 +1,5 @@ havingNotIn('id', static fn (BaseBuilder $builder) => $builder->select('user_id')->from('users_jobs')->where('group_id', 3)); -// Produces: HAVING "id" NOT IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3) - -// With builder directly -$subQuery = $db->table('users_jobs')->select('user_id')->where('group_id', 3); -$builder->havingNotIn('id', $subQuery); +$groups = [1, 2, 3]; +$builder->havingNotIn('group_id', $groups); +// Produces: HAVING group_id NOT IN (1, 2, 3) diff --git a/user_guide_src/source/database/query_builder/056.php b/user_guide_src/source/database/query_builder/056.php index 6d5a27ad2b95..67a54f87f7bc 100644 --- a/user_guide_src/source/database/query_builder/056.php +++ b/user_guide_src/source/database/query_builder/056.php @@ -1,5 +1,9 @@ havingNotIn('group_id', $groups); -// Produces: OR group_id NOT IN (1, 2, 3) +// With closure +$builder->havingNotIn('id', static fn (BaseBuilder $builder) => $builder->select('user_id')->from('users_jobs')->where('group_id', 3)); +// Produces: HAVING "id" NOT IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3) + +// With builder directly +$subQuery = $db->table('users_jobs')->select('user_id')->where('group_id', 3); +$builder->havingNotIn('id', $subQuery); diff --git a/user_guide_src/source/database/query_builder/057.php b/user_guide_src/source/database/query_builder/057.php index 8a92da5725b2..6d5a27ad2b95 100644 --- a/user_guide_src/source/database/query_builder/057.php +++ b/user_guide_src/source/database/query_builder/057.php @@ -1,9 +1,5 @@ orHavingNotIn('id', static fn (BaseBuilder $builder) => $builder->select('user_id')->from('users_jobs')->where('group_id', 3)); -// Produces: OR "id" NOT IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3) - -// With builder directly -$subQuery = $db->table('users_jobs')->select('user_id')->where('group_id', 3); -$builder->orHavingNotIn('id', $subQuery); +$groups = [1, 2, 3]; +$builder->havingNotIn('group_id', $groups); +// Produces: OR group_id NOT IN (1, 2, 3) diff --git a/user_guide_src/source/database/query_builder/058.php b/user_guide_src/source/database/query_builder/058.php index e24f2ed0ef45..8a92da5725b2 100644 --- a/user_guide_src/source/database/query_builder/058.php +++ b/user_guide_src/source/database/query_builder/058.php @@ -1,4 +1,9 @@ havingLike('title', 'match'); -// Produces: HAVING `title` LIKE '%match%' ESCAPE '!' +// With closure +$builder->orHavingNotIn('id', static fn (BaseBuilder $builder) => $builder->select('user_id')->from('users_jobs')->where('group_id', 3)); +// Produces: OR "id" NOT IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3) + +// With builder directly +$subQuery = $db->table('users_jobs')->select('user_id')->where('group_id', 3); +$builder->orHavingNotIn('id', $subQuery); diff --git a/user_guide_src/source/database/query_builder/059.php b/user_guide_src/source/database/query_builder/059.php index 9ef7f263e19f..e24f2ed0ef45 100644 --- a/user_guide_src/source/database/query_builder/059.php +++ b/user_guide_src/source/database/query_builder/059.php @@ -1,5 +1,4 @@ havingLike('title', 'match'); -$builder->havingLike('body', 'match'); -// HAVING `title` LIKE '%match%' ESCAPE '!' AND `body` LIKE '%match% ESCAPE '!' +// Produces: HAVING `title` LIKE '%match%' ESCAPE '!' diff --git a/user_guide_src/source/database/query_builder/060.php b/user_guide_src/source/database/query_builder/060.php index 3acc5d4f0fd4..9ef7f263e19f 100644 --- a/user_guide_src/source/database/query_builder/060.php +++ b/user_guide_src/source/database/query_builder/060.php @@ -1,5 +1,5 @@ havingLike('title', 'match', 'before'); // Produces: HAVING `title` LIKE '%match' ESCAPE '!' -$builder->havingLike('title', 'match', 'after'); // Produces: HAVING `title` LIKE 'match%' ESCAPE '!' -$builder->havingLike('title', 'match', 'both'); // Produces: HAVING `title` LIKE '%match%' ESCAPE '!' +$builder->havingLike('title', 'match'); +$builder->havingLike('body', 'match'); +// HAVING `title` LIKE '%match%' ESCAPE '!' AND `body` LIKE '%match% ESCAPE '!' diff --git a/user_guide_src/source/database/query_builder/061.php b/user_guide_src/source/database/query_builder/061.php index ba1767f6706e..3acc5d4f0fd4 100644 --- a/user_guide_src/source/database/query_builder/061.php +++ b/user_guide_src/source/database/query_builder/061.php @@ -1,5 +1,5 @@ $match, 'page1' => $match, 'page2' => $match]; -$builder->havingLike($array); -// HAVING `title` LIKE '%match%' ESCAPE '!' AND `page1` LIKE '%match%' ESCAPE '!' AND `page2` LIKE '%match%' ESCAPE '!' +$builder->havingLike('title', 'match', 'before'); // Produces: HAVING `title` LIKE '%match' ESCAPE '!' +$builder->havingLike('title', 'match', 'after'); // Produces: HAVING `title` LIKE 'match%' ESCAPE '!' +$builder->havingLike('title', 'match', 'both'); // Produces: HAVING `title` LIKE '%match%' ESCAPE '!' diff --git a/user_guide_src/source/database/query_builder/062.php b/user_guide_src/source/database/query_builder/062.php index 0b7543273430..ba1767f6706e 100644 --- a/user_guide_src/source/database/query_builder/062.php +++ b/user_guide_src/source/database/query_builder/062.php @@ -1,4 +1,5 @@ havingLike('title', 'match'); $builder->orHavingLike('body', $match); -// HAVING `title` LIKE '%match%' ESCAPE '!' OR `body` LIKE '%match%' ESCAPE '!' +$array = ['title' => $match, 'page1' => $match, 'page2' => $match]; +$builder->havingLike($array); +// HAVING `title` LIKE '%match%' ESCAPE '!' AND `page1` LIKE '%match%' ESCAPE '!' AND `page2` LIKE '%match%' ESCAPE '!' diff --git a/user_guide_src/source/database/query_builder/063.php b/user_guide_src/source/database/query_builder/063.php index a5c028d78e2c..0b7543273430 100644 --- a/user_guide_src/source/database/query_builder/063.php +++ b/user_guide_src/source/database/query_builder/063.php @@ -1,4 +1,4 @@ notHavingLike('title', 'match'); -// HAVING `title` NOT LIKE '%match% ESCAPE '!' +$builder->havingLike('title', 'match'); $builder->orHavingLike('body', $match); +// HAVING `title` LIKE '%match%' ESCAPE '!' OR `body` LIKE '%match%' ESCAPE '!' diff --git a/user_guide_src/source/database/query_builder/064.php b/user_guide_src/source/database/query_builder/064.php index 194a382baa13..a5c028d78e2c 100644 --- a/user_guide_src/source/database/query_builder/064.php +++ b/user_guide_src/source/database/query_builder/064.php @@ -1,5 +1,4 @@ havingLike('title', 'match'); -$builder->orNotHavingLike('body', 'match'); -// HAVING `title` LIKE '%match% OR `body` NOT LIKE '%match%' ESCAPE '!' +$builder->notHavingLike('title', 'match'); +// HAVING `title` NOT LIKE '%match% ESCAPE '!' diff --git a/user_guide_src/source/database/query_builder/065.php b/user_guide_src/source/database/query_builder/065.php index f36b6af2b449..194a382baa13 100644 --- a/user_guide_src/source/database/query_builder/065.php +++ b/user_guide_src/source/database/query_builder/065.php @@ -1,4 +1,5 @@ orderBy('title', 'DESC'); -// Produces: ORDER BY `title` DESC +$builder->havingLike('title', 'match'); +$builder->orNotHavingLike('body', 'match'); +// HAVING `title` LIKE '%match% OR `body` NOT LIKE '%match%' ESCAPE '!' diff --git a/user_guide_src/source/database/query_builder/066.php b/user_guide_src/source/database/query_builder/066.php index 01ef14c9a1c3..f36b6af2b449 100644 --- a/user_guide_src/source/database/query_builder/066.php +++ b/user_guide_src/source/database/query_builder/066.php @@ -1,4 +1,4 @@ orderBy('title DESC, name ASC'); -// Produces: ORDER BY `title` DESC, `name` ASC +$builder->orderBy('title', 'DESC'); +// Produces: ORDER BY `title` DESC diff --git a/user_guide_src/source/database/query_builder/067.php b/user_guide_src/source/database/query_builder/067.php index 6ba7dc157b59..01ef14c9a1c3 100644 --- a/user_guide_src/source/database/query_builder/067.php +++ b/user_guide_src/source/database/query_builder/067.php @@ -1,5 +1,4 @@ orderBy('title', 'DESC'); -$builder->orderBy('name', 'ASC'); +$builder->orderBy('title DESC, name ASC'); // Produces: ORDER BY `title` DESC, `name` ASC diff --git a/user_guide_src/source/database/query_builder/068.php b/user_guide_src/source/database/query_builder/068.php index f038c3e67184..6ba7dc157b59 100644 --- a/user_guide_src/source/database/query_builder/068.php +++ b/user_guide_src/source/database/query_builder/068.php @@ -1,7 +1,5 @@ orderBy('title', 'RANDOM'); -// Produces: ORDER BY RAND() - -$builder->orderBy(42, 'RANDOM'); -// Produces: ORDER BY RAND(42) +$builder->orderBy('title', 'DESC'); +$builder->orderBy('name', 'ASC'); +// Produces: ORDER BY `title` DESC, `name` ASC diff --git a/user_guide_src/source/database/query_builder/069.php b/user_guide_src/source/database/query_builder/069.php index dadbdc5dea19..f038c3e67184 100644 --- a/user_guide_src/source/database/query_builder/069.php +++ b/user_guide_src/source/database/query_builder/069.php @@ -1,4 +1,7 @@ limit(10); -// Produces: LIMIT 10 +$builder->orderBy('title', 'RANDOM'); +// Produces: ORDER BY RAND() + +$builder->orderBy(42, 'RANDOM'); +// Produces: ORDER BY RAND(42) diff --git a/user_guide_src/source/database/query_builder/070.php b/user_guide_src/source/database/query_builder/070.php index 0bfcab7b1fcf..dadbdc5dea19 100644 --- a/user_guide_src/source/database/query_builder/070.php +++ b/user_guide_src/source/database/query_builder/070.php @@ -1,4 +1,4 @@ limit(10, 20); -// Produces: LIMIT 20, 10 (in MySQL. Other databases have slightly different syntax) +$builder->limit(10); +// Produces: LIMIT 10 diff --git a/user_guide_src/source/database/query_builder/071.php b/user_guide_src/source/database/query_builder/071.php index 4b1c33356b7e..0bfcab7b1fcf 100644 --- a/user_guide_src/source/database/query_builder/071.php +++ b/user_guide_src/source/database/query_builder/071.php @@ -1,6 +1,4 @@ countAllResults(); // Produces an integer, like 25 -$builder->like('title', 'match'); -$builder->from('my_table'); -echo $builder->countAllResults(); // Produces an integer, like 17 +$builder->limit(10, 20); +// Produces: LIMIT 20, 10 (in MySQL. Other databases have slightly different syntax) diff --git a/user_guide_src/source/database/query_builder/072.php b/user_guide_src/source/database/query_builder/072.php index bb3a9c4d4b63..4b1c33356b7e 100644 --- a/user_guide_src/source/database/query_builder/072.php +++ b/user_guide_src/source/database/query_builder/072.php @@ -1,3 +1,6 @@ countAllResults(false); // Produces an integer, like 17 +echo $builder->countAllResults(); // Produces an integer, like 25 +$builder->like('title', 'match'); +$builder->from('my_table'); +echo $builder->countAllResults(); // Produces an integer, like 17 diff --git a/user_guide_src/source/database/query_builder/073.php b/user_guide_src/source/database/query_builder/073.php index 11bc5421cb42..bb3a9c4d4b63 100644 --- a/user_guide_src/source/database/query_builder/073.php +++ b/user_guide_src/source/database/query_builder/073.php @@ -1,3 +1,3 @@ countAll(); // Produces an integer, like 25 +echo $builder->countAllResults(false); // Produces an integer, like 17 diff --git a/user_guide_src/source/database/query_builder/074.php b/user_guide_src/source/database/query_builder/074.php index 3ea4d947f4a7..11bc5421cb42 100644 --- a/user_guide_src/source/database/query_builder/074.php +++ b/user_guide_src/source/database/query_builder/074.php @@ -1,16 +1,3 @@ select('*')->from('my_table') - ->groupStart() - ->where('a', 'a') - ->orGroupStart() - ->where('b', 'b') - ->where('c', 'c') - ->groupEnd() - ->groupEnd() - ->where('d', 'd') - ->get(); -/* - * Generates: - * SELECT * FROM (`my_table`) WHERE ( `a` = 'a' OR ( `b` = 'b' AND `c` = 'c' ) ) AND `d` = 'd' - */ +echo $builder->countAll(); // Produces an integer, like 25 diff --git a/user_guide_src/source/database/query_builder/075.php b/user_guide_src/source/database/query_builder/075.php index 2e87e8345dd0..3ea4d947f4a7 100644 --- a/user_guide_src/source/database/query_builder/075.php +++ b/user_guide_src/source/database/query_builder/075.php @@ -1,10 +1,16 @@ 'My title', - 'name' => 'My Name', - 'date' => 'My date', -]; - -$builder->insert($data); -// Produces: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date') +$builder->select('*')->from('my_table') + ->groupStart() + ->where('a', 'a') + ->orGroupStart() + ->where('b', 'b') + ->where('c', 'c') + ->groupEnd() + ->groupEnd() + ->where('d', 'd') + ->get(); +/* + * Generates: + * SELECT * FROM (`my_table`) WHERE ( `a` = 'a' OR ( `b` = 'b' AND `c` = 'c' ) ) AND `d` = 'd' + */ diff --git a/user_guide_src/source/database/query_builder/076.php b/user_guide_src/source/database/query_builder/076.php index ba38d99ff43b..2e87e8345dd0 100644 --- a/user_guide_src/source/database/query_builder/076.php +++ b/user_guide_src/source/database/query_builder/076.php @@ -1,12 +1,10 @@ 'My title', + 'name' => 'My Name', + 'date' => 'My date', +]; -$object = new Myclass(); -$builder->insert($object); -// Produces: INSERT INTO mytable (title, content, date) VALUES ('My Title', 'My Content', 'My Date') +$builder->insert($data); +// Produces: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date') diff --git a/user_guide_src/source/database/query_builder/077.php b/user_guide_src/source/database/query_builder/077.php index bb07bc8bdd9c..ba38d99ff43b 100644 --- a/user_guide_src/source/database/query_builder/077.php +++ b/user_guide_src/source/database/query_builder/077.php @@ -1,10 +1,12 @@ 'My title', - 'name' => 'My Name', - 'date' => 'My date', -]; +class Myclass +{ + public $title = 'My Title'; + public $content = 'My Content'; + public $date = 'My Date'; +} -$builder->ignore(true)->insert($data); -// Produces: INSERT OR IGNORE INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date') +$object = new Myclass(); +$builder->insert($object); +// Produces: INSERT INTO mytable (title, content, date) VALUES ('My Title', 'My Content', 'My Date') diff --git a/user_guide_src/source/database/query_builder/078.php b/user_guide_src/source/database/query_builder/078.php index ed0e4cb3f7a1..bb07bc8bdd9c 100644 --- a/user_guide_src/source/database/query_builder/078.php +++ b/user_guide_src/source/database/query_builder/078.php @@ -6,6 +6,5 @@ 'date' => 'My date', ]; -$sql = $builder->set($data)->getCompiledInsert(); -echo $sql; -// Produces string: INSERT INTO mytable (`title`, `name`, `date`) VALUES ('My title', 'My name', 'My date') +$builder->ignore(true)->insert($data); +// Produces: INSERT OR IGNORE INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date') diff --git a/user_guide_src/source/database/query_builder/079.php b/user_guide_src/source/database/query_builder/079.php index 1807be1d706a..ed0e4cb3f7a1 100644 --- a/user_guide_src/source/database/query_builder/079.php +++ b/user_guide_src/source/database/query_builder/079.php @@ -1,7 +1,11 @@ set('title', 'My Title')->getCompiledInsert(false); -// Produces string: INSERT INTO mytable (`title`) VALUES ('My Title') +$data = [ + 'title' => 'My title', + 'name' => 'My Name', + 'date' => 'My date', +]; -echo $builder->set('content', 'My Content')->getCompiledInsert(); -// Produces string: INSERT INTO mytable (`title`, `content`) VALUES ('My Title', 'My Content') +$sql = $builder->set($data)->getCompiledInsert(); +echo $sql; +// Produces string: INSERT INTO mytable (`title`, `name`, `date`) VALUES ('My title', 'My name', 'My date') diff --git a/user_guide_src/source/database/query_builder/080.php b/user_guide_src/source/database/query_builder/080.php index 0f263005c18e..1807be1d706a 100644 --- a/user_guide_src/source/database/query_builder/080.php +++ b/user_guide_src/source/database/query_builder/080.php @@ -1,17 +1,7 @@ 'My title', - 'name' => 'My Name', - 'date' => 'My date', - ], - [ - 'title' => 'Another title', - 'name' => 'Another Name', - 'date' => 'Another date', - ], -]; +echo $builder->set('title', 'My Title')->getCompiledInsert(false); +// Produces string: INSERT INTO mytable (`title`) VALUES ('My Title') -$builder->insertBatch($data); -// Produces: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date'), ('Another title', 'Another name', 'Another date') +echo $builder->set('content', 'My Content')->getCompiledInsert(); +// Produces string: INSERT INTO mytable (`title`, `content`) VALUES ('My Title', 'My Content') diff --git a/user_guide_src/source/database/query_builder/081.php b/user_guide_src/source/database/query_builder/081.php index d4bd972f5830..0f263005c18e 100644 --- a/user_guide_src/source/database/query_builder/081.php +++ b/user_guide_src/source/database/query_builder/081.php @@ -1,10 +1,17 @@ 'My title', - 'name' => 'My Name', - 'date' => 'My date', + [ + 'title' => 'My title', + 'name' => 'My Name', + 'date' => 'My date', + ], + [ + 'title' => 'Another title', + 'name' => 'Another Name', + 'date' => 'Another date', + ], ]; -$builder->replace($data); -// Executes: REPLACE INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date') +$builder->insertBatch($data); +// Produces: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date'), ('Another title', 'Another name', 'Another date') diff --git a/user_guide_src/source/database/query_builder/082.php b/user_guide_src/source/database/query_builder/082.php index 59d14e130215..d4bd972f5830 100644 --- a/user_guide_src/source/database/query_builder/082.php +++ b/user_guide_src/source/database/query_builder/082.php @@ -1,5 +1,10 @@ set('name', $name); -$builder->insert(); -// Produces: INSERT INTO mytable (`name`) VALUES ('{$name}') +$data = [ + 'title' => 'My title', + 'name' => 'My Name', + 'date' => 'My date', +]; + +$builder->replace($data); +// Executes: REPLACE INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date') diff --git a/user_guide_src/source/database/query_builder/083.php b/user_guide_src/source/database/query_builder/083.php index 8e2fbe2fabe5..59d14e130215 100644 --- a/user_guide_src/source/database/query_builder/083.php +++ b/user_guide_src/source/database/query_builder/083.php @@ -1,6 +1,5 @@ set('name', $name); -$builder->set('title', $title); -$builder->set('status', $status); $builder->insert(); +// Produces: INSERT INTO mytable (`name`) VALUES ('{$name}') diff --git a/user_guide_src/source/database/query_builder/084.php b/user_guide_src/source/database/query_builder/084.php index 2e76bea9e5d5..8e2fbe2fabe5 100644 --- a/user_guide_src/source/database/query_builder/084.php +++ b/user_guide_src/source/database/query_builder/084.php @@ -1,11 +1,6 @@ set('field', 'field+1', false); -$builder->where('id', 2); -$builder->update(); -// gives UPDATE mytable SET field = field+1 WHERE `id` = 2 - -$builder->set('field', 'field+1'); -$builder->where('id', 2); -$builder->update(); -// gives UPDATE `mytable` SET `field` = 'field+1' WHERE `id` = 2 +$builder->set('name', $name); +$builder->set('title', $title); +$builder->set('status', $status); +$builder->insert(); diff --git a/user_guide_src/source/database/query_builder/085.php b/user_guide_src/source/database/query_builder/085.php index 319e29a88142..2e76bea9e5d5 100644 --- a/user_guide_src/source/database/query_builder/085.php +++ b/user_guide_src/source/database/query_builder/085.php @@ -1,10 +1,11 @@ $name, - 'title' => $title, - 'status' => $status, -]; +$builder->set('field', 'field+1', false); +$builder->where('id', 2); +$builder->update(); +// gives UPDATE mytable SET field = field+1 WHERE `id` = 2 -$builder->set($array); -$builder->insert(); +$builder->set('field', 'field+1'); +$builder->where('id', 2); +$builder->update(); +// gives UPDATE `mytable` SET `field` = 'field+1' WHERE `id` = 2 diff --git a/user_guide_src/source/database/query_builder/086.php b/user_guide_src/source/database/query_builder/086.php index d395bc3b8ea9..319e29a88142 100644 --- a/user_guide_src/source/database/query_builder/086.php +++ b/user_guide_src/source/database/query_builder/086.php @@ -1,12 +1,10 @@ $name, + 'title' => $title, + 'status' => $status, +]; -$object = new Myclass(); -$builder->set($object); +$builder->set($array); $builder->insert(); diff --git a/user_guide_src/source/database/query_builder/087.php b/user_guide_src/source/database/query_builder/087.php index 7869b4b4d966..d395bc3b8ea9 100644 --- a/user_guide_src/source/database/query_builder/087.php +++ b/user_guide_src/source/database/query_builder/087.php @@ -1,16 +1,12 @@ $title, - 'name' => $name, - 'date' => $date, -]; +class Myclass +{ + public $title = 'My Title'; + public $content = 'My Content'; + public $date = 'My Date'; +} -$builder->where('id', $id); -$builder->update($data); -/* - * Produces: - * UPDATE mytable - * SET title = '{$title}', name = '{$name}', date = '{$date}' - * WHERE id = $id - */ +$object = new Myclass(); +$builder->set($object); +$builder->insert(); diff --git a/user_guide_src/source/database/query_builder/088.php b/user_guide_src/source/database/query_builder/088.php index 445e53716041..7869b4b4d966 100644 --- a/user_guide_src/source/database/query_builder/088.php +++ b/user_guide_src/source/database/query_builder/088.php @@ -1,18 +1,16 @@ $title, + 'name' => $name, + 'date' => $date, +]; -$object = new Myclass(); $builder->where('id', $id); -$builder->update($object); +$builder->update($data); /* * Produces: - * UPDATE `mytable` - * SET `title` = '{$title}', `name` = '{$name}', `date` = '{$date}' - * WHERE id = `$id` + * UPDATE mytable + * SET title = '{$title}', name = '{$name}', date = '{$date}' + * WHERE id = $id */ diff --git a/user_guide_src/source/database/query_builder/089.php b/user_guide_src/source/database/query_builder/089.php index d2ed79d26832..445e53716041 100644 --- a/user_guide_src/source/database/query_builder/089.php +++ b/user_guide_src/source/database/query_builder/089.php @@ -1,3 +1,18 @@ update($data, 'id = 4'); +class Myclass +{ + public $title = 'My Title'; + public $content = 'My Content'; + public $date = 'My Date'; +} + +$object = new Myclass(); +$builder->where('id', $id); +$builder->update($object); +/* + * Produces: + * UPDATE `mytable` + * SET `title` = '{$title}', `name` = '{$name}', `date` = '{$date}' + * WHERE id = `$id` + */ diff --git a/user_guide_src/source/database/query_builder/090.php b/user_guide_src/source/database/query_builder/090.php index 66a1ee575cee..d2ed79d26832 100644 --- a/user_guide_src/source/database/query_builder/090.php +++ b/user_guide_src/source/database/query_builder/090.php @@ -1,3 +1,3 @@ update($data, ['id' => $id]); +$builder->update($data, 'id = 4'); diff --git a/user_guide_src/source/database/query_builder/091.php b/user_guide_src/source/database/query_builder/091.php index e60b9ee6b486..66a1ee575cee 100644 --- a/user_guide_src/source/database/query_builder/091.php +++ b/user_guide_src/source/database/query_builder/091.php @@ -1,28 +1,3 @@ 'My title', - 'name' => 'My Name 2', - 'date' => 'My date 2', - ], - [ - 'title' => 'Another title', - 'name' => 'Another Name 2', - 'date' => 'Another date 2', - ], -]; - -$builder->updateBatch($data, 'title'); -/* - * Produces: - * UPDATE `mytable` SET `name` = CASE - * WHEN `title` = 'My title' THEN 'My Name 2' - * WHEN `title` = 'Another title' THEN 'Another Name 2' - * ELSE `name` END, - * `date` = CASE - * WHEN `title` = 'My title' THEN 'My date 2' - * WHEN `title` = 'Another title' THEN 'Another date 2' - * ELSE `date` END - * WHERE `title` IN ('My title','Another title') - */ +$builder->update($data, ['id' => $id]); diff --git a/user_guide_src/source/database/query_builder/092.php b/user_guide_src/source/database/query_builder/092.php index ed680a441d98..e60b9ee6b486 100644 --- a/user_guide_src/source/database/query_builder/092.php +++ b/user_guide_src/source/database/query_builder/092.php @@ -1,4 +1,28 @@ delete(['id' => $id]); -// Produces: DELETE FROM mytable WHERE id = $id +$data = [ + [ + 'title' => 'My title', + 'name' => 'My Name 2', + 'date' => 'My date 2', + ], + [ + 'title' => 'Another title', + 'name' => 'Another Name 2', + 'date' => 'Another date 2', + ], +]; + +$builder->updateBatch($data, 'title'); +/* + * Produces: + * UPDATE `mytable` SET `name` = CASE + * WHEN `title` = 'My title' THEN 'My Name 2' + * WHEN `title` = 'Another title' THEN 'Another Name 2' + * ELSE `name` END, + * `date` = CASE + * WHEN `title` = 'My title' THEN 'My date 2' + * WHEN `title` = 'Another title' THEN 'Another date 2' + * ELSE `date` END + * WHERE `title` IN ('My title','Another title') + */ diff --git a/user_guide_src/source/database/query_builder/093.php b/user_guide_src/source/database/query_builder/093.php index f1ba27e29ef2..ed680a441d98 100644 --- a/user_guide_src/source/database/query_builder/093.php +++ b/user_guide_src/source/database/query_builder/093.php @@ -1,9 +1,4 @@ where('id', $id); -$builder->delete(); -/* - * Produces: - * DELETE FROM mytable - * WHERE id = $id - */ +$builder->delete(['id' => $id]); +// Produces: DELETE FROM mytable WHERE id = $id diff --git a/user_guide_src/source/database/query_builder/094.php b/user_guide_src/source/database/query_builder/094.php index 0251fe47031d..f1ba27e29ef2 100644 --- a/user_guide_src/source/database/query_builder/094.php +++ b/user_guide_src/source/database/query_builder/094.php @@ -1,4 +1,9 @@ emptyTable('mytable'); -// Produces: DELETE FROM mytable +$builder->where('id', $id); +$builder->delete(); +/* + * Produces: + * DELETE FROM mytable + * WHERE id = $id + */ diff --git a/user_guide_src/source/database/query_builder/095.php b/user_guide_src/source/database/query_builder/095.php index a6c0ab4fc069..0251fe47031d 100644 --- a/user_guide_src/source/database/query_builder/095.php +++ b/user_guide_src/source/database/query_builder/095.php @@ -1,7 +1,4 @@ truncate(); -/* - * Produce: - * TRUNCATE mytable - */ +$builder->emptyTable('mytable'); +// Produces: DELETE FROM mytable diff --git a/user_guide_src/source/database/query_builder/096.php b/user_guide_src/source/database/query_builder/096.php index 5a05f70d8070..a6c0ab4fc069 100644 --- a/user_guide_src/source/database/query_builder/096.php +++ b/user_guide_src/source/database/query_builder/096.php @@ -1,6 +1,7 @@ select('title') - ->where('id', $id) - ->limit(10, 20) - ->get(); +$builder->truncate(); +/* + * Produce: + * TRUNCATE mytable + */ diff --git a/user_guide_src/source/database/query_builder/097.php b/user_guide_src/source/database/query_builder/097.php index 50d274d63a54..5a05f70d8070 100644 --- a/user_guide_src/source/database/query_builder/097.php +++ b/user_guide_src/source/database/query_builder/097.php @@ -1,17 +1,6 @@ select(['field1', 'field2']) - ->where('field3', 5) - ->getCompiledSelect(false); - -// ... -// Do something crazy with the SQL code... like add it to a cron script for -// later execution or something... -// ... - -$data = $builder->get()->getResultArray(); -/* - * Would execute and return an array of results of the following query: - * SELECT field1, field1 from mytable where field3 = 5; - */ +$query = $builder->select('title') + ->where('id', $id) + ->limit(10, 20) + ->get(); diff --git a/user_guide_src/source/database/query_builder/098.php b/user_guide_src/source/database/query_builder/098.php index b3890e978005..50d274d63a54 100644 --- a/user_guide_src/source/database/query_builder/098.php +++ b/user_guide_src/source/database/query_builder/098.php @@ -1,6 +1,17 @@ table('countries')->select('name')->where('id', 1); -$builder = $db->table('users')->select('name')->selectSubquery($subquery, 'country'); -$query = $builder->get(); -// Produces: SELECT `name`, (SELECT `name` FROM `countries` WHERE `id` = 1) AS `country` FROM `users` +// Note that the second parameter of the ``get_compiled_select`` method is false +$sql = $builder->select(['field1', 'field2']) + ->where('field3', 5) + ->getCompiledSelect(false); + +// ... +// Do something crazy with the SQL code... like add it to a cron script for +// later execution or something... +// ... + +$data = $builder->get()->getResultArray(); +/* + * Would execute and return an array of results of the following query: + * SELECT field1, field1 from mytable where field3 = 5; + */ diff --git a/user_guide_src/source/incoming/controllers.rst b/user_guide_src/source/incoming/controllers.rst index 5ade052c563a..037710255100 100644 --- a/user_guide_src/source/incoming/controllers.rst +++ b/user_guide_src/source/incoming/controllers.rst @@ -41,7 +41,7 @@ You can define an array of helper files as a class property. Whenever the contro these helper files will be automatically loaded into memory so that you can use their methods anywhere inside the controller: -.. literalinclude:: controllers/016.php +.. literalinclude:: controllers/001.php .. _controllers-validating-data: @@ -51,13 +51,13 @@ forceHTTPS A convenience method for forcing a method to be accessed via HTTPS is available within all controllers: -.. literalinclude:: controllers/014.php +.. literalinclude:: controllers/002.php By default, and in modern browsers that support the HTTP Strict Transport Security header, this call should force the browser to convert non-HTTPS calls to HTTPS calls for one year. You can modify this by passing the duration (in seconds) as the first parameter: -.. literalinclude:: controllers/015.php +.. literalinclude:: controllers/003.php .. note:: A number of :doc:`time-based constants ` are always available for you to use, including ``YEAR``, ``MONTH``, and more. @@ -75,12 +75,12 @@ if the items are not valid. Internally, this uses the controller's The :doc:`Validation Library docs ` have details on rule and message array formats, as well as available rules: -.. literalinclude:: controllers/017.php +.. literalinclude:: controllers/004.php If you find it simpler to keep the rules in the configuration file, you can replace the ``$rules`` array with the name of the group as defined in ``Config\Validation.php``: -.. literalinclude:: controllers/018.php +.. literalinclude:: controllers/005.php .. note:: Validation can also be handled automatically in the model, but sometimes it's easier to do it in the controller. Where is up to you. @@ -91,7 +91,7 @@ Sometimes you may want to check the controller method parameters or other custom In that case, you can use the ``$this->validateData()`` method. The method accepts an array of data to validate in the first parameter: -.. literalinclude:: controllers/019.php +.. literalinclude:: controllers/006.php Private methods *************** @@ -101,7 +101,7 @@ To achieve this, simply declare the method as ``private`` or ``protected``. That will prevent it from being served by a URL request. For example, if you were to define a method like this for the ``Helloworld`` controller: -.. literalinclude:: controllers/013.php +.. literalinclude:: controllers/007.php then trying to access it using the following URL will not work:: @@ -141,7 +141,7 @@ controllers. You can extend this class in any new controller. For security reasons be sure to declare any new utility methods as ``protected`` or ``private``: -.. literalinclude:: controllers/001.php +.. literalinclude:: controllers/008.php Then save the file to your **/app/Controllers/** directory. @@ -159,15 +159,15 @@ If you did it right you should see:: This is valid: -.. literalinclude:: controllers/002.php +.. literalinclude:: controllers/009.php This is **not** valid: -.. literalinclude:: controllers/003.php +.. literalinclude:: controllers/010.php This is **not** valid: -.. literalinclude:: controllers/004.php +.. literalinclude:: controllers/011.php Also, always make sure your controller extends the parent controller class so that it can inherit all its methods. @@ -181,7 +181,7 @@ class so that it can inherit all its methods. Here is an example based on PSR-4 Autoloader: - .. literalinclude:: controllers/005.php + .. literalinclude:: controllers/012.php Methods ======= @@ -197,7 +197,7 @@ controller gets called.** Let's try it. Add a new method to your controller: -.. literalinclude:: controllers/006.php +.. literalinclude:: controllers/013.php Now load the following URL to see the comment method:: @@ -217,7 +217,7 @@ For example, let's say you have a URI like this:: Your method will be passed URI segments 3 and 4 (``'sandals'`` and ``'123'``): -.. literalinclude:: controllers/007.php +.. literalinclude:: controllers/014.php .. important:: If you are using the :doc:`URI Routing ` feature, the segments passed to your method will be the re-routed @@ -233,13 +233,13 @@ with the ``Helloworld`` controller. To specify a default controller open your **app/Config/Routes.php** file and set this variable: -.. literalinclude:: controllers/008.php +.. literalinclude:: controllers/015.php Where ``Helloworld`` is the name of the controller class you want to be used. A few lines further down **Routes.php** in the "Route Definitions" section, comment out the line: -.. literalinclude:: controllers/009.php +.. literalinclude:: controllers/016.php If you now browse to your site without specifying any URI segments you'll see the "Hello World" message. @@ -288,7 +288,7 @@ As noted above, the second segment of the URI typically determines which method in the controller gets called. CodeIgniter permits you to override this behavior through the use of the ``_remap()`` method: -.. literalinclude:: controllers/010.php +.. literalinclude:: controllers/017.php .. important:: If your controller contains a method named ``_remap()``, it will **always** get called regardless of what your URI contains. It @@ -298,14 +298,14 @@ this behavior through the use of the ``_remap()`` method: The overridden method call (typically the second segment of the URI) will be passed as a parameter to the ``_remap()`` method: -.. literalinclude:: controllers/011.php +.. literalinclude:: controllers/018.php Any extra segments after the method name are passed into ``_remap()``. These parameters can be passed to the method to emulate CodeIgniter's default behavior. Example: -.. literalinclude:: controllers/012.php +.. literalinclude:: controllers/019.php Extending the Controller ************************ diff --git a/user_guide_src/source/incoming/controllers/001.php b/user_guide_src/source/incoming/controllers/001.php index 926de1e9fbdf..ff3ab9edfcf1 100644 --- a/user_guide_src/source/incoming/controllers/001.php +++ b/user_guide_src/source/incoming/controllers/001.php @@ -2,10 +2,7 @@ namespace App\Controllers; -class Helloworld extends BaseController +class MyController extends BaseController { - public function index() - { - echo 'Hello World!'; - } + protected $helpers = ['url', 'form']; } diff --git a/user_guide_src/source/incoming/controllers/002.php b/user_guide_src/source/incoming/controllers/002.php index 20fe63dc2d69..9414addbb81a 100644 --- a/user_guide_src/source/incoming/controllers/002.php +++ b/user_guide_src/source/incoming/controllers/002.php @@ -1,8 +1,5 @@ request->isSecure()) { + $this->forceHTTPS(); } diff --git a/user_guide_src/source/incoming/controllers/003.php b/user_guide_src/source/incoming/controllers/003.php index 5248ba4b2bdd..c3309ddbf201 100644 --- a/user_guide_src/source/incoming/controllers/003.php +++ b/user_guide_src/source/incoming/controllers/003.php @@ -1,8 +1,5 @@ request->isSecure()) { + $this->forceHTTPS(31536000); // one year } diff --git a/user_guide_src/source/incoming/controllers/004.php b/user_guide_src/source/incoming/controllers/004.php index 7615eecaeba0..65b1c77f8014 100644 --- a/user_guide_src/source/incoming/controllers/004.php +++ b/user_guide_src/source/incoming/controllers/004.php @@ -2,7 +2,19 @@ namespace App\Controllers; -class HelloWorld extends BaseController +class UserController extends BaseController { - // ... + public function updateUser(int $userID) + { + if (! $this->validate([ + 'email' => "required|is_unique[users.email,id,{$userID}]", + 'name' => 'required|alpha_numeric_spaces', + ])) { + return view('users/update', [ + 'errors' => $this->validator->getErrors(), + ]); + } + + // do something here if successful... + } } diff --git a/user_guide_src/source/incoming/controllers/005.php b/user_guide_src/source/incoming/controllers/005.php index efaecbb8f400..48e936b60595 100644 --- a/user_guide_src/source/incoming/controllers/005.php +++ b/user_guide_src/source/incoming/controllers/005.php @@ -1,8 +1,17 @@ (\)*\ - */ +namespace App\Controllers; -$routes->get('helloworld', '\App\Controllers\HelloWorld::index'); +class UserController extends BaseController +{ + public function updateUser(int $userID) + { + if (! $this->validate('userRules')) { + return view('users/update', [ + 'errors' => $this->validator->getErrors(), + ]); + } + + // do something here if successful... + } +} diff --git a/user_guide_src/source/incoming/controllers/006.php b/user_guide_src/source/incoming/controllers/006.php index e43c3e4f2b34..1ae78e5791ff 100644 --- a/user_guide_src/source/incoming/controllers/006.php +++ b/user_guide_src/source/incoming/controllers/006.php @@ -2,15 +2,24 @@ namespace App\Controllers; -class Helloworld extends BaseController +class StoreController extends BaseController { - public function index() + public function product(int $id) { - echo 'Hello World!'; - } + $data = [ + 'id' => $id, + 'name' => $this->request->getVar('name'), + ]; - public function comment() - { - echo 'I am not flat!'; + $rule = [ + 'id' => 'integer', + 'name' => 'required|max_length[255]', + ]; + + if (! $this->validateData($data, $rule)) { + // ... + } + + // ... } } diff --git a/user_guide_src/source/incoming/controllers/007.php b/user_guide_src/source/incoming/controllers/007.php index 319fd8471a7b..7c2e9b7091ea 100644 --- a/user_guide_src/source/incoming/controllers/007.php +++ b/user_guide_src/source/incoming/controllers/007.php @@ -4,9 +4,8 @@ class Products extends BaseController { - public function shoes($sandals, $id) + protected function utility() { - echo $sandals; - echo $id; + // some code } } diff --git a/user_guide_src/source/incoming/controllers/008.php b/user_guide_src/source/incoming/controllers/008.php index 2de1b716d040..926de1e9fbdf 100644 --- a/user_guide_src/source/incoming/controllers/008.php +++ b/user_guide_src/source/incoming/controllers/008.php @@ -1,3 +1,11 @@ setDefaultController('Helloworld'); +namespace App\Controllers; + +class Helloworld extends BaseController +{ + public function index() + { + echo 'Hello World!'; + } +} diff --git a/user_guide_src/source/incoming/controllers/009.php b/user_guide_src/source/incoming/controllers/009.php index d799d1cf0fb5..20fe63dc2d69 100644 --- a/user_guide_src/source/incoming/controllers/009.php +++ b/user_guide_src/source/incoming/controllers/009.php @@ -1,3 +1,8 @@ get('/', 'Home::index'); +namespace App\Controllers; + +class Helloworld extends BaseController +{ + // ... +} diff --git a/user_guide_src/source/incoming/controllers/010.php b/user_guide_src/source/incoming/controllers/010.php index 8bcb6a2b00f9..5248ba4b2bdd 100644 --- a/user_guide_src/source/incoming/controllers/010.php +++ b/user_guide_src/source/incoming/controllers/010.php @@ -2,10 +2,7 @@ namespace App\Controllers; -class Products extends BaseController +class helloworld extends BaseController { - public function _remap() - { - // Some code here... - } + // ... } diff --git a/user_guide_src/source/incoming/controllers/011.php b/user_guide_src/source/incoming/controllers/011.php index 159009b6b855..7615eecaeba0 100644 --- a/user_guide_src/source/incoming/controllers/011.php +++ b/user_guide_src/source/incoming/controllers/011.php @@ -2,14 +2,7 @@ namespace App\Controllers; -class Products extends BaseController +class HelloWorld extends BaseController { - public function _remap($method) - { - if ($method === 'some_method') { - return $this->{$method}(); - } - - return $this->default_method(); - } + // ... } diff --git a/user_guide_src/source/incoming/controllers/012.php b/user_guide_src/source/incoming/controllers/012.php index 4bfdb1393d02..efaecbb8f400 100644 --- a/user_guide_src/source/incoming/controllers/012.php +++ b/user_guide_src/source/incoming/controllers/012.php @@ -1,17 +1,8 @@ (\)*\ + */ -class Products extends BaseController -{ - public function _remap($method, ...$params) - { - $method = 'process_' . $method; - - if (method_exists($this, $method)) { - return $this->{$method}(...$params); - } - - throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound(); - } -} +$routes->get('helloworld', '\App\Controllers\HelloWorld::index'); diff --git a/user_guide_src/source/incoming/controllers/013.php b/user_guide_src/source/incoming/controllers/013.php index 7c2e9b7091ea..e43c3e4f2b34 100644 --- a/user_guide_src/source/incoming/controllers/013.php +++ b/user_guide_src/source/incoming/controllers/013.php @@ -2,10 +2,15 @@ namespace App\Controllers; -class Products extends BaseController +class Helloworld extends BaseController { - protected function utility() + public function index() { - // some code + echo 'Hello World!'; + } + + public function comment() + { + echo 'I am not flat!'; } } diff --git a/user_guide_src/source/incoming/controllers/014.php b/user_guide_src/source/incoming/controllers/014.php index 9414addbb81a..319fd8471a7b 100644 --- a/user_guide_src/source/incoming/controllers/014.php +++ b/user_guide_src/source/incoming/controllers/014.php @@ -1,5 +1,12 @@ request->isSecure()) { - $this->forceHTTPS(); +namespace App\Controllers; + +class Products extends BaseController +{ + public function shoes($sandals, $id) + { + echo $sandals; + echo $id; + } } diff --git a/user_guide_src/source/incoming/controllers/015.php b/user_guide_src/source/incoming/controllers/015.php index c3309ddbf201..2de1b716d040 100644 --- a/user_guide_src/source/incoming/controllers/015.php +++ b/user_guide_src/source/incoming/controllers/015.php @@ -1,5 +1,3 @@ request->isSecure()) { - $this->forceHTTPS(31536000); // one year -} +$routes->setDefaultController('Helloworld'); diff --git a/user_guide_src/source/incoming/controllers/016.php b/user_guide_src/source/incoming/controllers/016.php index ff3ab9edfcf1..d799d1cf0fb5 100644 --- a/user_guide_src/source/incoming/controllers/016.php +++ b/user_guide_src/source/incoming/controllers/016.php @@ -1,8 +1,3 @@ get('/', 'Home::index'); diff --git a/user_guide_src/source/incoming/controllers/017.php b/user_guide_src/source/incoming/controllers/017.php index 65b1c77f8014..8bcb6a2b00f9 100644 --- a/user_guide_src/source/incoming/controllers/017.php +++ b/user_guide_src/source/incoming/controllers/017.php @@ -2,19 +2,10 @@ namespace App\Controllers; -class UserController extends BaseController +class Products extends BaseController { - public function updateUser(int $userID) + public function _remap() { - if (! $this->validate([ - 'email' => "required|is_unique[users.email,id,{$userID}]", - 'name' => 'required|alpha_numeric_spaces', - ])) { - return view('users/update', [ - 'errors' => $this->validator->getErrors(), - ]); - } - - // do something here if successful... + // Some code here... } } diff --git a/user_guide_src/source/incoming/controllers/018.php b/user_guide_src/source/incoming/controllers/018.php index 48e936b60595..159009b6b855 100644 --- a/user_guide_src/source/incoming/controllers/018.php +++ b/user_guide_src/source/incoming/controllers/018.php @@ -2,16 +2,14 @@ namespace App\Controllers; -class UserController extends BaseController +class Products extends BaseController { - public function updateUser(int $userID) + public function _remap($method) { - if (! $this->validate('userRules')) { - return view('users/update', [ - 'errors' => $this->validator->getErrors(), - ]); + if ($method === 'some_method') { + return $this->{$method}(); } - // do something here if successful... + return $this->default_method(); } } diff --git a/user_guide_src/source/incoming/controllers/019.php b/user_guide_src/source/incoming/controllers/019.php index 1ae78e5791ff..4bfdb1393d02 100644 --- a/user_guide_src/source/incoming/controllers/019.php +++ b/user_guide_src/source/incoming/controllers/019.php @@ -2,24 +2,16 @@ namespace App\Controllers; -class StoreController extends BaseController +class Products extends BaseController { - public function product(int $id) + public function _remap($method, ...$params) { - $data = [ - 'id' => $id, - 'name' => $this->request->getVar('name'), - ]; + $method = 'process_' . $method; - $rule = [ - 'id' => 'integer', - 'name' => 'required|max_length[255]', - ]; - - if (! $this->validateData($data, $rule)) { - // ... + if (method_exists($this, $method)) { + return $this->{$method}(...$params); } - // ... + throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound(); } } diff --git a/user_guide_src/source/incoming/routing.rst b/user_guide_src/source/incoming/routing.rst index 83cb4cc95e6d..eb7d57370015 100644 --- a/user_guide_src/source/incoming/routing.rst +++ b/user_guide_src/source/incoming/routing.rst @@ -118,23 +118,23 @@ Array Callable Syntax Since v4.2.0, you can use array callable syntax to specify the controller: -.. literalinclude:: routing/004_1.php +.. literalinclude:: routing/013.php :lines: 2- Or using ``use`` keyword: -.. literalinclude:: routing/004_2.php +.. literalinclude:: routing/014.php :lines: 2- If there are placeholders, it will automatically set the parameters in the specified order: -.. literalinclude:: routing/004_3.php +.. literalinclude:: routing/015.php :lines: 2- But the auto-configured parameters may not be correct if you use regular expressions in routes. In such a case, you can specify the parameters manually: -.. literalinclude:: routing/004_4.php +.. literalinclude:: routing/016.php :lines: 2- Custom Placeholders @@ -147,7 +147,7 @@ You add new placeholders with the ``addPlaceholder()`` method. The first paramet the placeholder. The second parameter is the Regular Expression pattern it should be replaced with. This must be called before you add the route: -.. literalinclude:: routing/013.php +.. literalinclude:: routing/017.php Regular Expressions =================== @@ -158,7 +158,7 @@ is allowed, as are back-references. .. important:: Note: If you use back-references you must use the dollar syntax rather than the double backslash syntax. A typical RegEx route might look something like this: - .. literalinclude:: routing/014.php + .. literalinclude:: routing/018.php In the above example, a URI similar to **products/shirts/123** would instead call the ``show`` method of the ``Products`` controller class, with the original first and second segment passed as arguments to it. @@ -169,7 +169,7 @@ represent the delimiter between multiple segments. For example, if a user accesses a password protected area of your web application and you wish to be able to redirect them back to the same page after they log in, you may find this example useful: -.. literalinclude:: routing/015.php +.. literalinclude:: routing/019.php For those of you who don't know regular expressions and want to learn more about them, `regular-expressions.info `_ might be a good starting point. @@ -183,7 +183,7 @@ You can use an anonymous function, or Closure, as the destination that a route m executed when the user visits that URI. This is handy for quickly executing small tasks, or even just showing a simple view: -.. literalinclude:: routing/016.php +.. literalinclude:: routing/020.php Mapping multiple routes ======================= @@ -192,7 +192,7 @@ While the ``add()`` method is simple to use, it is often handier to work with mu the ``map()`` method. Instead of calling the ``add()`` method for each route that you need to add, you can define an array of routes and then pass it as the first parameter to the ``map()`` method: -.. literalinclude:: routing/017.php +.. literalinclude:: routing/021.php Redirecting Routes ================== @@ -203,7 +203,7 @@ second parameter is either the new URI to redirect to, or the name of a named ro the HTTP status code that should be sent along with the redirect. The default value is ``302`` which is a temporary redirect and is recommended in most cases: -.. literalinclude:: routing/018.php +.. literalinclude:: routing/022.php If a redirect route is matched during a page load, the user will be immediately redirected to the new page before a controller can be loaded. @@ -215,26 +215,26 @@ You can group your routes under a common name with the ``group()`` method. The g appears prior to the routes defined inside of the group. This allows you to reduce the typing needed to build out an extensive set of routes that all share the opening string, like when building an admin area: -.. literalinclude:: routing/019.php +.. literalinclude:: routing/023.php This would prefix the **users** and **blog** URIs with **admin**, handling URLs like **admin/users** and **admin/blog**. If you need to assign options to a group, like a :ref:`assigning-namespace`, do it before the callback: -.. literalinclude:: routing/020.php +.. literalinclude:: routing/024.php This would handle a resource route to the ``App\API\v1\Users`` controller with the **api/users** URI. You can also use a specific :doc:`filter ` for a group of routes. This will always run the filter before or after the controller. This is especially handy during authentication or api logging: -.. literalinclude:: routing/021.php +.. literalinclude:: routing/025.php The value for the filter must match one of the aliases defined within **app/Config/Filters.php**. It is possible to nest groups within groups for finer organization if you need it: -.. literalinclude:: routing/022.php +.. literalinclude:: routing/026.php This would handle the URL at **admin/users/list**. @@ -245,7 +245,7 @@ config options like namespace, subdomain, etc. Without necessarily needing to ad an empty string in place of the prefix and the routes in the group will be routed as though the group never existed but with the given route config options: -.. literalinclude:: routing/023.php +.. literalinclude:: routing/027.php Environment Restrictions ======================== @@ -255,7 +255,7 @@ tools that only the developer can use on their local machines that are not reach This can be done with the ``environment()`` method. The first parameter is the name of the environment. Any routes defined within this closure are only accessible from the given environment: -.. literalinclude:: routing/024.php +.. literalinclude:: routing/028.php Reverse Routing =============== @@ -269,7 +269,7 @@ function to get the current route that should be used. The first parameter is th separated by a double colon (``::``), much like you would use when writing the initial route itself. Any parameters that should be passed to the route are passed in next: -.. literalinclude:: routing/025.php +.. literalinclude:: routing/029.php Using Named Routes ================== @@ -279,7 +279,7 @@ later, and even if the route definition changes, all of the links in your applic will still work without you having to make any changes. A route is named by passing in the ``as`` option with the name of the route: -.. literalinclude:: routing/026.php +.. literalinclude:: routing/030.php This has the added benefit of making the views more readable, too. @@ -289,7 +289,7 @@ Routes with any HTTP verbs It is possible to define a route with any HTTP verbs. You can use the ``add()`` method: -.. literalinclude:: routing/027.php +.. literalinclude:: routing/031.php .. warning:: While the ``add()`` method seems to be convenient, it is recommended to always use the HTTP-verb-based routes, described above, as it is more secure. If you use the :doc:`CSRF protection `, it does not protect **GET** @@ -310,7 +310,7 @@ You can create routes that work only from the command-line, and are inaccessible route methods will also be inaccessible from the CLI, but routes created by the ``add()`` method will still be available from the command line: -.. literalinclude:: routing/028.php +.. literalinclude:: routing/032.php .. warning:: If you don't disable auto-routing and place the command file in **app/Controllers**, anyone could access the command with the help of auto-routing via HTTP. @@ -321,7 +321,7 @@ Global Options All of the methods for creating a route (add, get, post, :doc:`resource ` etc) can take an array of options that can modify the generated routes, or further restrict them. The ``$options`` array is always the last parameter: -.. literalinclude:: routing/029.php +.. literalinclude:: routing/033.php .. _applying-filters: @@ -347,17 +347,17 @@ See :doc:`Controller filters ` for more information on setting up filte You specify an alias defined in **app/Config/Filters.php** for the filter value: -.. literalinclude:: routing/030.php +.. literalinclude:: routing/034.php You may also supply arguments to be passed to the alias filter's ``before()`` and ``after()`` methods: -.. literalinclude:: routing/031.php +.. literalinclude:: routing/035.php **Classname filter** You specify a filter classname for the filter value: -.. literalinclude:: routing/032.php +.. literalinclude:: routing/036.php **Multiple filters** @@ -365,7 +365,7 @@ You specify a filter classname for the filter value: You specify an array for the filter value: -.. literalinclude:: routing/033.php +.. literalinclude:: routing/037.php .. _assigning-namespace: @@ -376,7 +376,7 @@ While a default namespace will be prepended to the generated controllers (see be a different namespace to be used in any options array, with the ``namespace`` option. The value should be the namespace you want modified: -.. literalinclude:: routing/034.php +.. literalinclude:: routing/038.php The new namespace is only applied during that call for any methods that create a single route, like get, post, etc. For any methods that create multiple routes, the new namespace is attached to all routes generated by that function @@ -388,7 +388,7 @@ Limit to Hostname You can restrict groups of routes to function only in certain domain or sub-domains of your application by passing the "hostname" option along with the desired domain to allow it on as part of the options array: -.. literalinclude:: routing/035.php +.. literalinclude:: routing/039.php This example would only allow the specified hosts to work if the domain exactly matched **accounts.example.com**. It would not work under the main site at **example.com**. @@ -399,12 +399,12 @@ Limit to Subdomains When the ``subdomain`` option is present, the system will restrict the routes to only be available on that sub-domain. The route will only be matched if the subdomain is the one the application is being viewed through: -.. literalinclude:: routing/036.php +.. literalinclude:: routing/040.php You can restrict it to any subdomain by setting the value to an asterisk, (``*``). If you are viewing from a URL that does not have any subdomain present, this will not be matched: -.. literalinclude:: routing/037.php +.. literalinclude:: routing/041.php .. important:: The system is not perfect and should be tested for your specific domain before being used in production. Most domains should work fine but some edge case ones, especially with a period in the domain itself (not used @@ -419,7 +419,7 @@ value being the number of segments to offset. This can be beneficial when developing API's with the first URI segment being the version number. It can also be used when the first parameter is a language string: -.. literalinclude:: routing/038.php +.. literalinclude:: routing/042.php .. _routing-priority: @@ -432,11 +432,11 @@ You can solve this problem by lowering the priority of route processing using th accepts positive integers and zero. The higher the number specified in the ``priority``, the lower route priority in the processing queue: -.. literalinclude:: routing/039.php +.. literalinclude:: routing/043.php To disable this functionality, you must call the method with the parameter ``false``: -.. literalinclude:: routing/040.php +.. literalinclude:: routing/044.php .. note:: By default, all routes have a priority of 0. Negative integers will be cast to the absolute value. @@ -458,12 +458,12 @@ specified by the route. By default, this value is ``App\Controllers``. If you set the value empty string (``''``), it leaves each route to specify the fully namespaced controller: -.. literalinclude:: routing/041.php +.. literalinclude:: routing/045.php If your controllers are not explicitly namespaced, there is no need to change this. If you namespace your controllers, then you can change this value to save typing: -.. literalinclude:: routing/042.php +.. literalinclude:: routing/046.php Default Controller ================== @@ -472,7 +472,7 @@ When a user visits the root of your site (i.e., example.com) the controller to u the ``setDefaultController()`` method, unless a route exists for it explicitly. The default value for this is ``Home`` which matches the controller at **app/Controllers/Home.php**: -.. literalinclude:: routing/043.php +.. literalinclude:: routing/047.php The default controller is also used when no matching route has been found, and the URI would point to a directory in the controllers directory. For example, if the user visits **example.com/admin**, if a controller was found at @@ -488,7 +488,7 @@ when a controller is found that matches the URI, but no segment exists for the m In this example, if the user were to visit **example.com/products**, and a ``Products`` controller existed, the ``Products::listAll()`` method would be executed: -.. literalinclude:: routing/044.php +.. literalinclude:: routing/048.php Translate URI Dashes ==================== @@ -497,7 +497,7 @@ This option enables you to automatically replace dashes (``-``) with underscores URI segments, thus saving you additional route entries if you need to do that. This is required because the dash isn't a valid class or method name character and would cause a fatal error if you try to use it: -.. literalinclude:: routing/045.php +.. literalinclude:: routing/049.php .. _use-defined-routes-only: @@ -508,7 +508,7 @@ When no defined route is found that matches the URI, the system will attempt to controllers and methods as described in :ref:`auto-routing`. You can disable this automatic matching, and restrict routes to only those defined by you, by setting the ``setAutoRoute()`` option to false: -.. literalinclude:: routing/046.php +.. literalinclude:: routing/050.php .. warning:: If you use the :doc:`CSRF protection `, it does not protect **GET** requests. If the URI is accessible by the GET method, the CSRF protection will not work. @@ -520,7 +520,7 @@ When a page is not found that matches the current URI, the system will show a ge what happens by specifying an action to happen with the ``set404Override()`` method. The value can be either a valid class/method pair, just like you would show in any route, or a Closure: -.. literalinclude:: routing/047.php +.. literalinclude:: routing/051.php Route processing by priority ============================ @@ -529,7 +529,7 @@ Enables or disables processing of the routes queue by priority. Lowering the pri Disabled by default. This functionality affects all routes. For an example use of lowering the priority see :ref:`routing-priority`: -.. literalinclude:: routing/048.php +.. literalinclude:: routing/052.php .. _auto-routing: diff --git a/user_guide_src/source/incoming/routing/004_1.php b/user_guide_src/source/incoming/routing/004_1.php deleted file mode 100644 index b562d01ba3b2..000000000000 --- a/user_guide_src/source/incoming/routing/004_1.php +++ /dev/null @@ -1,3 +0,0 @@ -get('/', [\App\Controllers\Home::class, 'index']); diff --git a/user_guide_src/source/incoming/routing/004_2.php b/user_guide_src/source/incoming/routing/004_2.php deleted file mode 100644 index 6105564b13f3..000000000000 --- a/user_guide_src/source/incoming/routing/004_2.php +++ /dev/null @@ -1,5 +0,0 @@ -get('/', [Home::class, 'index']); diff --git a/user_guide_src/source/incoming/routing/004_3.php b/user_guide_src/source/incoming/routing/004_3.php deleted file mode 100644 index cd98314d8fe8..000000000000 --- a/user_guide_src/source/incoming/routing/004_3.php +++ /dev/null @@ -1,8 +0,0 @@ -get('product/(:num)/(:num)', [Product::class, 'index']); - -// The above code is the same as the following: -$routes->get('product/(:num)/(:num)', 'Product::index/$1/$2'); diff --git a/user_guide_src/source/incoming/routing/004_4.php b/user_guide_src/source/incoming/routing/004_4.php deleted file mode 100644 index aed6cc5176df..000000000000 --- a/user_guide_src/source/incoming/routing/004_4.php +++ /dev/null @@ -1,8 +0,0 @@ -get('product/(:num)/(:num)', [[Product::class, 'index'], '$2/$1']); - -// The above code is the same as the following: -$routes->get('product/(:num)/(:num)', 'Product::index/$2/$1'); diff --git a/user_guide_src/source/incoming/routing/013.php b/user_guide_src/source/incoming/routing/013.php index cb1cdda7c78c..b562d01ba3b2 100644 --- a/user_guide_src/source/incoming/routing/013.php +++ b/user_guide_src/source/incoming/routing/013.php @@ -1,4 +1,3 @@ addPlaceholder('uuid', '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'); -$routes->get('users/(:uuid)', 'Users::show/$1'); +$routes->get('/', [\App\Controllers\Home::class, 'index']); diff --git a/user_guide_src/source/incoming/routing/014.php b/user_guide_src/source/incoming/routing/014.php index a1619a4bf080..6105564b13f3 100644 --- a/user_guide_src/source/incoming/routing/014.php +++ b/user_guide_src/source/incoming/routing/014.php @@ -1,3 +1,5 @@ get('products/([a-z]+)/(\d+)', 'Products::show/$1/id_$2'); +use App\Controllers\Home; + +$routes->get('/', [Home::class, 'index']); diff --git a/user_guide_src/source/incoming/routing/015.php b/user_guide_src/source/incoming/routing/015.php index c9ddfae73610..cd98314d8fe8 100644 --- a/user_guide_src/source/incoming/routing/015.php +++ b/user_guide_src/source/incoming/routing/015.php @@ -1,3 +1,8 @@ get('login/(.+)', 'Auth::login/$1'); +use App\Controllers\Product; + +$routes->get('product/(:num)/(:num)', [Product::class, 'index']); + +// The above code is the same as the following: +$routes->get('product/(:num)/(:num)', 'Product::index/$1/$2'); diff --git a/user_guide_src/source/incoming/routing/016.php b/user_guide_src/source/incoming/routing/016.php index e4fc5bde4a68..aed6cc5176df 100644 --- a/user_guide_src/source/incoming/routing/016.php +++ b/user_guide_src/source/incoming/routing/016.php @@ -1,7 +1,8 @@ get('feed', static function () { - $rss = new RSSFeeder(); +use App\Controllers\Product; - return $rss->feed('general'); -}); +$routes->get('product/(:num)/(:num)', [[Product::class, 'index'], '$2/$1']); + +// The above code is the same as the following: +$routes->get('product/(:num)/(:num)', 'Product::index/$2/$1'); diff --git a/user_guide_src/source/incoming/routing/017.php b/user_guide_src/source/incoming/routing/017.php index 8ebc27e3f9f5..cb1cdda7c78c 100644 --- a/user_guide_src/source/incoming/routing/017.php +++ b/user_guide_src/source/incoming/routing/017.php @@ -1,8 +1,4 @@ 'Catalog::productLookupById', - 'product/(:alphanum)' => 'Catalog::productLookupByName', -]; - -$routes->map($multipleRoutes); +$routes->addPlaceholder('uuid', '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'); +$routes->get('users/(:uuid)', 'Users::show/$1'); diff --git a/user_guide_src/source/incoming/routing/018.php b/user_guide_src/source/incoming/routing/018.php index d92d9934db5a..a1619a4bf080 100644 --- a/user_guide_src/source/incoming/routing/018.php +++ b/user_guide_src/source/incoming/routing/018.php @@ -1,8 +1,3 @@ get('users/profile', 'Users::profile', ['as' => 'profile']); - -// Redirect to a named route -$routes->addRedirect('users/about', 'profile'); -// Redirect to a URI -$routes->addRedirect('users/about', 'users/profile'); +$routes->get('products/([a-z]+)/(\d+)', 'Products::show/$1/id_$2'); diff --git a/user_guide_src/source/incoming/routing/019.php b/user_guide_src/source/incoming/routing/019.php index 6f08c319c551..c9ddfae73610 100644 --- a/user_guide_src/source/incoming/routing/019.php +++ b/user_guide_src/source/incoming/routing/019.php @@ -1,6 +1,3 @@ group('admin', static function ($routes) { - $routes->get('users', 'Admin\Users::index'); - $routes->get('blog', 'Admin\Blog::index'); -}); +$routes->get('login/(.+)', 'Auth::login/$1'); diff --git a/user_guide_src/source/incoming/routing/020.php b/user_guide_src/source/incoming/routing/020.php index 7c66c3b693dd..e4fc5bde4a68 100644 --- a/user_guide_src/source/incoming/routing/020.php +++ b/user_guide_src/source/incoming/routing/020.php @@ -1,5 +1,7 @@ group('api', ['namespace' => 'App\API\v1'], static function ($routes) { - $routes->resource('users'); +$routes->get('feed', static function () { + $rss = new RSSFeeder(); + + return $rss->feed('general'); }); diff --git a/user_guide_src/source/incoming/routing/021.php b/user_guide_src/source/incoming/routing/021.php index 75cec09100cb..8ebc27e3f9f5 100644 --- a/user_guide_src/source/incoming/routing/021.php +++ b/user_guide_src/source/incoming/routing/021.php @@ -1,5 +1,8 @@ group('api', ['filter' => 'api-auth'], static function ($routes) { - $routes->resource('users'); -}); +$multipleRoutes = [ + 'product/(:num)' => 'Catalog::productLookupById', + 'product/(:alphanum)' => 'Catalog::productLookupByName', +]; + +$routes->map($multipleRoutes); diff --git a/user_guide_src/source/incoming/routing/022.php b/user_guide_src/source/incoming/routing/022.php index 1ed2a8a96ee6..d92d9934db5a 100644 --- a/user_guide_src/source/incoming/routing/022.php +++ b/user_guide_src/source/incoming/routing/022.php @@ -1,7 +1,8 @@ group('admin', static function ($routes) { - $routes->group('users', static function ($routes) { - $routes->get('list', 'Admin\Users::list'); - }); -}); +$routes->get('users/profile', 'Users::profile', ['as' => 'profile']); + +// Redirect to a named route +$routes->addRedirect('users/about', 'profile'); +// Redirect to a URI +$routes->addRedirect('users/about', 'users/profile'); diff --git a/user_guide_src/source/incoming/routing/023.php b/user_guide_src/source/incoming/routing/023.php index d7624ddc6d5c..6f08c319c551 100644 --- a/user_guide_src/source/incoming/routing/023.php +++ b/user_guide_src/source/incoming/routing/023.php @@ -1,7 +1,6 @@ group('', ['namespace' => 'Myth\Auth\Controllers'], static function ($routes) { - $routes->get('login', 'AuthController::login', ['as' => 'login']); - $routes->post('login', 'AuthController::attemptLogin'); - $routes->get('logout', 'AuthController::logout'); +$routes->group('admin', static function ($routes) { + $routes->get('users', 'Admin\Users::index'); + $routes->get('blog', 'Admin\Blog::index'); }); diff --git a/user_guide_src/source/incoming/routing/024.php b/user_guide_src/source/incoming/routing/024.php index 53921b33f5eb..7c66c3b693dd 100644 --- a/user_guide_src/source/incoming/routing/024.php +++ b/user_guide_src/source/incoming/routing/024.php @@ -1,5 +1,5 @@ environment('development', static function ($routes) { - $routes->get('builder', 'Tools\Builder::index'); +$routes->group('api', ['namespace' => 'App\API\v1'], static function ($routes) { + $routes->resource('users'); }); diff --git a/user_guide_src/source/incoming/routing/025.php b/user_guide_src/source/incoming/routing/025.php index e6bc6bdfb65f..75cec09100cb 100644 --- a/user_guide_src/source/incoming/routing/025.php +++ b/user_guide_src/source/incoming/routing/025.php @@ -1,10 +1,5 @@ get('users/(:num)/gallery(:any)', 'App\Controllers\Galleries::showUserGallery/$1/$2'); - -?> - - -View Gallery - +$routes->group('api', ['filter' => 'api-auth'], static function ($routes) { + $routes->resource('users'); +}); diff --git a/user_guide_src/source/incoming/routing/026.php b/user_guide_src/source/incoming/routing/026.php index 1c1c629893e3..1ed2a8a96ee6 100644 --- a/user_guide_src/source/incoming/routing/026.php +++ b/user_guide_src/source/incoming/routing/026.php @@ -1,10 +1,7 @@ get('users/(:num)/gallery(:any)', 'Galleries::showUserGallery/$1/$2', ['as' => 'user_gallery']); - -?> - - -View Gallery - +$routes->group('admin', static function ($routes) { + $routes->group('users', static function ($routes) { + $routes->get('list', 'Admin\Users::list'); + }); +}); diff --git a/user_guide_src/source/incoming/routing/027.php b/user_guide_src/source/incoming/routing/027.php index e2a3784f335f..d7624ddc6d5c 100644 --- a/user_guide_src/source/incoming/routing/027.php +++ b/user_guide_src/source/incoming/routing/027.php @@ -1,3 +1,7 @@ add('products', 'Product::feature'); +$routes->group('', ['namespace' => 'Myth\Auth\Controllers'], static function ($routes) { + $routes->get('login', 'AuthController::login', ['as' => 'login']); + $routes->post('login', 'AuthController::attemptLogin'); + $routes->get('logout', 'AuthController::logout'); +}); diff --git a/user_guide_src/source/incoming/routing/028.php b/user_guide_src/source/incoming/routing/028.php index a82d57ebc5c7..53921b33f5eb 100644 --- a/user_guide_src/source/incoming/routing/028.php +++ b/user_guide_src/source/incoming/routing/028.php @@ -1,3 +1,5 @@ cli('migrate', 'App\Database::migrate'); +$routes->environment('development', static function ($routes) { + $routes->get('builder', 'Tools\Builder::index'); +}); diff --git a/user_guide_src/source/incoming/routing/029.php b/user_guide_src/source/incoming/routing/029.php index ff7e995a1526..e6bc6bdfb65f 100644 --- a/user_guide_src/source/incoming/routing/029.php +++ b/user_guide_src/source/incoming/routing/029.php @@ -1,14 +1,10 @@ add('from', 'to', $options); -$routes->get('from', 'to', $options); -$routes->post('from', 'to', $options); -$routes->put('from', 'to', $options); -$routes->head('from', 'to', $options); -$routes->options('from', 'to', $options); -$routes->delete('from', 'to', $options); -$routes->patch('from', 'to', $options); -$routes->match(['get', 'put'], 'from', 'to', $options); -$routes->resource('photos', $options); -$routes->map($array, $options); -$routes->group('name', $options, static function () {}); +// The route is defined as: +$routes->get('users/(:num)/gallery(:any)', 'App\Controllers\Galleries::showUserGallery/$1/$2'); + +?> + + +View Gallery + diff --git a/user_guide_src/source/incoming/routing/030.php b/user_guide_src/source/incoming/routing/030.php index 2515937bb02a..1c1c629893e3 100644 --- a/user_guide_src/source/incoming/routing/030.php +++ b/user_guide_src/source/incoming/routing/030.php @@ -1,3 +1,10 @@ get('admin', ' AdminController::index', ['filter' => 'admin-auth']); +// The route is defined as: +$routes->get('users/(:num)/gallery(:any)', 'Galleries::showUserGallery/$1/$2', ['as' => 'user_gallery']); + +?> + + +View Gallery + diff --git a/user_guide_src/source/incoming/routing/031.php b/user_guide_src/source/incoming/routing/031.php index b50db49bd962..e2a3784f335f 100644 --- a/user_guide_src/source/incoming/routing/031.php +++ b/user_guide_src/source/incoming/routing/031.php @@ -1,3 +1,3 @@ post('users/delete/(:segment)', 'AdminController::index', ['filter' => 'admin-auth:dual,noreturn']); +$routes->add('products', 'Product::feature'); diff --git a/user_guide_src/source/incoming/routing/032.php b/user_guide_src/source/incoming/routing/032.php index dd6cd63ba61d..a82d57ebc5c7 100644 --- a/user_guide_src/source/incoming/routing/032.php +++ b/user_guide_src/source/incoming/routing/032.php @@ -1,3 +1,3 @@ get('admin', ' AdminController::index', ['filter' => \App\Filters\SomeFilter::class]); +$routes->cli('migrate', 'App\Database::migrate'); diff --git a/user_guide_src/source/incoming/routing/033.php b/user_guide_src/source/incoming/routing/033.php index 94ae43246897..ff7e995a1526 100644 --- a/user_guide_src/source/incoming/routing/033.php +++ b/user_guide_src/source/incoming/routing/033.php @@ -1,3 +1,14 @@ get('admin', ' AdminController::index', ['filter' => ['admin-auth', \App\Filters\SomeFilter::class]]); +$routes->add('from', 'to', $options); +$routes->get('from', 'to', $options); +$routes->post('from', 'to', $options); +$routes->put('from', 'to', $options); +$routes->head('from', 'to', $options); +$routes->options('from', 'to', $options); +$routes->delete('from', 'to', $options); +$routes->patch('from', 'to', $options); +$routes->match(['get', 'put'], 'from', 'to', $options); +$routes->resource('photos', $options); +$routes->map($array, $options); +$routes->group('name', $options, static function () {}); diff --git a/user_guide_src/source/incoming/routing/034.php b/user_guide_src/source/incoming/routing/034.php index b992deb96ecf..2515937bb02a 100644 --- a/user_guide_src/source/incoming/routing/034.php +++ b/user_guide_src/source/incoming/routing/034.php @@ -1,4 +1,3 @@ get('admin/users', 'Users::index', ['namespace' => 'Admin']); +$routes->get('admin', ' AdminController::index', ['filter' => 'admin-auth']); diff --git a/user_guide_src/source/incoming/routing/035.php b/user_guide_src/source/incoming/routing/035.php index 5b415a50138b..b50db49bd962 100644 --- a/user_guide_src/source/incoming/routing/035.php +++ b/user_guide_src/source/incoming/routing/035.php @@ -1,3 +1,3 @@ get('from', 'to', ['hostname' => 'accounts.example.com']); +$routes->post('users/delete/(:segment)', 'AdminController::index', ['filter' => 'admin-auth:dual,noreturn']); diff --git a/user_guide_src/source/incoming/routing/036.php b/user_guide_src/source/incoming/routing/036.php index 32a74934eb3a..dd6cd63ba61d 100644 --- a/user_guide_src/source/incoming/routing/036.php +++ b/user_guide_src/source/incoming/routing/036.php @@ -1,4 +1,3 @@ get('from', 'to', ['subdomain' => 'media']); +$routes->get('admin', ' AdminController::index', ['filter' => \App\Filters\SomeFilter::class]); diff --git a/user_guide_src/source/incoming/routing/037.php b/user_guide_src/source/incoming/routing/037.php index 0d0fd0e67fb4..94ae43246897 100644 --- a/user_guide_src/source/incoming/routing/037.php +++ b/user_guide_src/source/incoming/routing/037.php @@ -1,4 +1,3 @@ get('from', 'to', ['subdomain' => '*']); +$routes->get('admin', ' AdminController::index', ['filter' => ['admin-auth', \App\Filters\SomeFilter::class]]); diff --git a/user_guide_src/source/incoming/routing/038.php b/user_guide_src/source/incoming/routing/038.php index ec7fa680f65e..b992deb96ecf 100644 --- a/user_guide_src/source/incoming/routing/038.php +++ b/user_guide_src/source/incoming/routing/038.php @@ -1,6 +1,4 @@ get('users/(:num)', 'users/show/$1', ['offset' => 1]); - -// Creates: -$routes['users/(:num)'] = 'users/show/$2'; +// Routes to \Admin\Users::index() +$routes->get('admin/users', 'Users::index', ['namespace' => 'Admin']); diff --git a/user_guide_src/source/incoming/routing/039.php b/user_guide_src/source/incoming/routing/039.php index 29fc83e59f17..5b415a50138b 100644 --- a/user_guide_src/source/incoming/routing/039.php +++ b/user_guide_src/source/incoming/routing/039.php @@ -1,12 +1,3 @@ setPrioritize(); - -// App\Config\Routes -$routes->get('(.*)', 'Posts::index', ['priority' => 1]); - -// Modules\Acme\Config\Routes -$routes->get('admin', 'Admin::index'); - -// The "admin" route will now be processed before the wildcard router. +$routes->get('from', 'to', ['hostname' => 'accounts.example.com']); diff --git a/user_guide_src/source/incoming/routing/040.php b/user_guide_src/source/incoming/routing/040.php index 9465f4147e2c..32a74934eb3a 100644 --- a/user_guide_src/source/incoming/routing/040.php +++ b/user_guide_src/source/incoming/routing/040.php @@ -1,3 +1,4 @@ setPrioritize(false); +// Limit to media.example.com +$routes->get('from', 'to', ['subdomain' => 'media']); diff --git a/user_guide_src/source/incoming/routing/041.php b/user_guide_src/source/incoming/routing/041.php index 98aef9276f9d..0d0fd0e67fb4 100644 --- a/user_guide_src/source/incoming/routing/041.php +++ b/user_guide_src/source/incoming/routing/041.php @@ -1,9 +1,4 @@ setDefaultNamespace(''); - -// Controller is \Users -$routes->get('users', 'Users::index'); - -// Controller is \Admin\Users -$routes->get('users', 'Admin\Users::index'); +// Limit to any sub-domain +$routes->get('from', 'to', ['subdomain' => '*']); diff --git a/user_guide_src/source/incoming/routing/042.php b/user_guide_src/source/incoming/routing/042.php index fbbbee2300df..ec7fa680f65e 100644 --- a/user_guide_src/source/incoming/routing/042.php +++ b/user_guide_src/source/incoming/routing/042.php @@ -1,9 +1,6 @@ setDefaultNamespace('App'); +$routes->get('users/(:num)', 'users/show/$1', ['offset' => 1]); -// Controller is \App\Users -$routes->get('users', 'Users::index'); - -// Controller is \App\Admin\Users -$routes->get('users', 'Admin\Users::index'); +// Creates: +$routes['users/(:num)'] = 'users/show/$2'; diff --git a/user_guide_src/source/incoming/routing/043.php b/user_guide_src/source/incoming/routing/043.php index 5d17df8130d4..29fc83e59f17 100644 --- a/user_guide_src/source/incoming/routing/043.php +++ b/user_guide_src/source/incoming/routing/043.php @@ -1,4 +1,12 @@ setDefaultController('Welcome'); +// First you need to enable sorting. +$routes->setPrioritize(); + +// App\Config\Routes +$routes->get('(.*)', 'Posts::index', ['priority' => 1]); + +// Modules\Acme\Config\Routes +$routes->get('admin', 'Admin::index'); + +// The "admin" route will now be processed before the wildcard router. diff --git a/user_guide_src/source/incoming/routing/044.php b/user_guide_src/source/incoming/routing/044.php index e926e651287d..9465f4147e2c 100644 --- a/user_guide_src/source/incoming/routing/044.php +++ b/user_guide_src/source/incoming/routing/044.php @@ -1,3 +1,3 @@ setDefaultMethod('listAll'); +$routes->setPrioritize(false); diff --git a/user_guide_src/source/incoming/routing/045.php b/user_guide_src/source/incoming/routing/045.php index 31d49508ab86..98aef9276f9d 100644 --- a/user_guide_src/source/incoming/routing/045.php +++ b/user_guide_src/source/incoming/routing/045.php @@ -1,3 +1,9 @@ setTranslateURIDashes(true); +$routes->setDefaultNamespace(''); + +// Controller is \Users +$routes->get('users', 'Users::index'); + +// Controller is \Admin\Users +$routes->get('users', 'Admin\Users::index'); diff --git a/user_guide_src/source/incoming/routing/046.php b/user_guide_src/source/incoming/routing/046.php index c331102cd9f4..fbbbee2300df 100644 --- a/user_guide_src/source/incoming/routing/046.php +++ b/user_guide_src/source/incoming/routing/046.php @@ -1,3 +1,9 @@ setAutoRoute(false); +$routes->setDefaultNamespace('App'); + +// Controller is \App\Users +$routes->get('users', 'Users::index'); + +// Controller is \App\Admin\Users +$routes->get('users', 'Admin\Users::index'); diff --git a/user_guide_src/source/incoming/routing/047.php b/user_guide_src/source/incoming/routing/047.php index dddd067f0f26..5d17df8130d4 100644 --- a/user_guide_src/source/incoming/routing/047.php +++ b/user_guide_src/source/incoming/routing/047.php @@ -1,9 +1,4 @@ set404Override('App\Errors::show404'); - -// Will display a custom view -$routes->set404Override(static function () { - echo view('my_errors/not_found.html'); -}); +// example.com routes to app/Controllers/Welcome.php +$routes->setDefaultController('Welcome'); diff --git a/user_guide_src/source/incoming/routing/048.php b/user_guide_src/source/incoming/routing/048.php index e3dd9f60c989..e926e651287d 100644 --- a/user_guide_src/source/incoming/routing/048.php +++ b/user_guide_src/source/incoming/routing/048.php @@ -1,7 +1,3 @@ setPrioritize(); - -// to disable -$routes->setPrioritize(false); +$routes->setDefaultMethod('listAll'); diff --git a/user_guide_src/source/incoming/routing/049.php b/user_guide_src/source/incoming/routing/049.php new file mode 100644 index 000000000000..31d49508ab86 --- /dev/null +++ b/user_guide_src/source/incoming/routing/049.php @@ -0,0 +1,3 @@ +setTranslateURIDashes(true); diff --git a/user_guide_src/source/incoming/routing/050.php b/user_guide_src/source/incoming/routing/050.php new file mode 100644 index 000000000000..c331102cd9f4 --- /dev/null +++ b/user_guide_src/source/incoming/routing/050.php @@ -0,0 +1,3 @@ +setAutoRoute(false); diff --git a/user_guide_src/source/incoming/routing/051.php b/user_guide_src/source/incoming/routing/051.php new file mode 100644 index 000000000000..dddd067f0f26 --- /dev/null +++ b/user_guide_src/source/incoming/routing/051.php @@ -0,0 +1,9 @@ +set404Override('App\Errors::show404'); + +// Will display a custom view +$routes->set404Override(static function () { + echo view('my_errors/not_found.html'); +}); diff --git a/user_guide_src/source/incoming/routing/052.php b/user_guide_src/source/incoming/routing/052.php new file mode 100644 index 000000000000..e3dd9f60c989 --- /dev/null +++ b/user_guide_src/source/incoming/routing/052.php @@ -0,0 +1,7 @@ +setPrioritize(); + +// to disable +$routes->setPrioritize(false); diff --git a/user_guide_src/source/libraries/sessions.rst b/user_guide_src/source/libraries/sessions.rst index 8dea63ab953f..59557db92cf8 100644 --- a/user_guide_src/source/libraries/sessions.rst +++ b/user_guide_src/source/libraries/sessions.rst @@ -37,7 +37,7 @@ Alternatively, you can use the helper function that will use the default configuration options. This version is a little friendlier to read, but does not take any configuration options. -.. literalinclude:: sessions/003.php +.. literalinclude:: sessions/002.php How do Sessions work? ===================== @@ -89,7 +89,7 @@ have the session open, while you've already processed it and therefore no longer need it. So, what you need is to close the session for the current request after you no longer need it. -.. literalinclude:: sessions/004.php +.. literalinclude:: sessions/003.php What is Session Data? ===================== @@ -115,25 +115,25 @@ Retrieving Session Data Any piece of information from the session array is available through the ``$_SESSION`` superglobal: -.. literalinclude:: sessions/005.php +.. literalinclude:: sessions/004.php Or through the conventional accessor method: -.. literalinclude:: sessions/006.php +.. literalinclude:: sessions/005.php Or through the magic getter: -.. literalinclude:: sessions/007.php +.. literalinclude:: sessions/006.php Or even through the session helper method: -.. literalinclude:: sessions/008.php +.. literalinclude:: sessions/007.php Where ``item`` is the array key corresponding to the item you wish to fetch. For example, to assign a previously stored 'name' item to the ``$name`` variable, you will do this: -.. literalinclude:: sessions/009.php +.. literalinclude:: sessions/008.php .. note:: The ``get()`` method returns null if the item you are trying to access does not exist. @@ -141,7 +141,7 @@ variable, you will do this: If you want to retrieve all of the existing userdata, you can simply omit the item key (magic getter only works for single property values): -.. literalinclude:: sessions/010.php +.. literalinclude:: sessions/009.php Adding Session Data =================== @@ -158,26 +158,26 @@ The former userdata method is deprecated, but you can pass an array containing your new session data to the ``set()`` method: -.. literalinclude:: sessions/011.php +.. literalinclude:: sessions/010.php Where ``$array`` is an associative array containing your new data. Here's an example: -.. literalinclude:: sessions/012.php +.. literalinclude:: sessions/011.php If you want to add session data one value at a time, ``set()`` also supports this syntax: -.. literalinclude:: sessions/013.php +.. literalinclude:: sessions/012.php If you want to verify that a session value exists, simply check with ``isset()``: -.. literalinclude:: sessions/014.php +.. literalinclude:: sessions/013.php Or you can call ``has()``: -.. literalinclude:: sessions/015.php +.. literalinclude:: sessions/014.php Pushing new value to session data ================================= @@ -185,7 +185,7 @@ Pushing new value to session data The push method is used to push a new value onto a session value that is an array. For instance, if the 'hobbies' key contains an array of hobbies, you can add a new value onto the array like so: -.. literalinclude:: sessions/016.php +.. literalinclude:: sessions/015.php Removing Session Data ===================== @@ -193,18 +193,18 @@ Removing Session Data Just as with any other variable, unsetting a value in ``$_SESSION`` can be done through ``unset()``: -.. literalinclude:: sessions/017.php +.. literalinclude:: sessions/016.php Also, just as ``set()`` can be used to add information to a session, ``remove()`` can be used to remove it, by passing the session key. For example, if you wanted to remove 'some_name' from your session data array: -.. literalinclude:: sessions/018.php +.. literalinclude:: sessions/017.php This method also accepts an array of item keys to unset: -.. literalinclude:: sessions/019.php +.. literalinclude:: sessions/018.php Flashdata ========= @@ -220,20 +220,20 @@ managed inside the CodeIgniter session handler. To mark an existing item as "flashdata": -.. literalinclude:: sessions/020.php +.. literalinclude:: sessions/019.php If you want to mark multiple items as flashdata, simply pass the keys as an array: -.. literalinclude:: sessions/021.php +.. literalinclude:: sessions/020.php To add flashdata: -.. literalinclude:: sessions/022.php +.. literalinclude:: sessions/021.php Or alternatively, using the ``setFlashdata()`` method: -.. literalinclude:: sessions/023.php +.. literalinclude:: sessions/022.php You can also pass an array to ``setFlashdata()``, in the same manner as ``set()``. @@ -241,7 +241,7 @@ You can also pass an array to ``setFlashdata()``, in the same manner as Reading flashdata variables is the same as reading regular session data through ``$_SESSION``: -.. literalinclude:: sessions/024.php +.. literalinclude:: sessions/023.php .. important:: The ``get()`` method WILL return flashdata items when retrieving a single item by key. It will not return flashdata when @@ -250,11 +250,11 @@ through ``$_SESSION``: However, if you want to be sure that you're reading "flashdata" (and not any other kind), you can also use the ``getFlashdata()`` method: -.. literalinclude:: sessions/025.php +.. literalinclude:: sessions/024.php Or to get an array with all flashdata, simply omit the key parameter: -.. literalinclude:: sessions/026.php +.. literalinclude:: sessions/025.php .. note:: The ``getFlashdata()`` method returns null if the item cannot be found. @@ -263,7 +263,7 @@ If you find that you need to preserve a flashdata variable through an additional request, you can do so using the ``keepFlashdata()`` method. You can either pass a single item or an array of flashdata items to keep. -.. literalinclude:: sessions/027.php +.. literalinclude:: sessions/026.php Tempdata ======== @@ -278,24 +278,24 @@ CodeIgniter session handler. To mark an existing item as "tempdata", simply pass its key and expiry time (in seconds!) to the ``markAsTempdata()`` method: -.. literalinclude:: sessions/028.php +.. literalinclude:: sessions/027.php You can mark multiple items as tempdata in two ways, depending on whether you want them all to have the same expiry time or not: -.. literalinclude:: sessions/029.php +.. literalinclude:: sessions/028.php To add tempdata: -.. literalinclude:: sessions/030.php +.. literalinclude:: sessions/029.php Or alternatively, using the ``setTempdata()`` method: -.. literalinclude:: sessions/031.php +.. literalinclude:: sessions/030.php You can also pass an array to ``setTempdata()``: -.. literalinclude:: sessions/032.php +.. literalinclude:: sessions/031.php .. note:: If the expiration is omitted or set to 0, the default time-to-live value of 300 seconds (or 5 minutes) will be used. @@ -303,7 +303,7 @@ You can also pass an array to ``setTempdata()``: To read a tempdata variable, again you can just access it through the ``$_SESSION`` superglobal array: -.. literalinclude:: sessions/033.php +.. literalinclude:: sessions/032.php .. important:: The ``get()`` method WILL return tempdata items when retrieving a single item by key. It will not return tempdata when @@ -312,11 +312,11 @@ To read a tempdata variable, again you can just access it through the Or if you want to be sure that you're reading "tempdata" (and not any other kind), you can also use the ``getTempdata()`` method: -.. literalinclude:: sessions/034.php +.. literalinclude:: sessions/033.php And of course, if you want to retrieve all existing tempdata: -.. literalinclude:: sessions/035.php +.. literalinclude:: sessions/034.php .. note:: The ``getTempdata()`` method returns null if the item cannot be found. @@ -324,14 +324,14 @@ And of course, if you want to retrieve all existing tempdata: If you need to remove a tempdata value before it expires, you can directly unset it from the ``$_SESSION`` array: -.. literalinclude:: sessions/036.php +.. literalinclude:: sessions/035.php However, this won't remove the marker that makes this specific item to be tempdata (it will be invalidated on the next HTTP request), so if you intend to reuse that same key in the same request, you'd want to use ``removeTempdata()``: -.. literalinclude:: sessions/037.php +.. literalinclude:: sessions/036.php Destroying a Session ==================== @@ -341,7 +341,7 @@ simply use either PHP's `session_destroy() function, or the library's ``destroy()`` method. Both will work in exactly the same way: -.. literalinclude:: sessions/038.php +.. literalinclude:: sessions/037.php .. note:: This must be the last session-related operation that you do during the same request. All session data (including flashdata and @@ -352,7 +352,7 @@ You may also use the ``stop()`` method to completely kill the session by removing the old session_id, destroying all data, and destroying the cookie that contained the session id: -.. literalinclude:: sessions/039.php +.. literalinclude:: sessions/038.php Accessing session metadata ========================== @@ -527,7 +527,7 @@ table that we already mentioned and then set it as your For example, if you would like to use 'ci_sessions' as your table name, you would do this: -.. literalinclude:: sessions/040.php +.. literalinclude:: sessions/039.php And then of course, create the database table ... @@ -567,7 +567,7 @@ setting**. The examples below work both on MySQL and PostgreSQL:: You can choose the Database group to use by adding a new line to the **app/Config/App.php** file with the name of the group to use: -.. literalinclude:: sessions/041.php +.. literalinclude:: sessions/040.php If you'd rather not do all of this by hand, you can use the ``session:migration`` command from the cli to generate a migration file for you:: @@ -620,7 +620,7 @@ link you to it: For the most common case however, a simple ``host:port`` pair should be sufficient: -.. literalinclude:: sessions/042.php +.. literalinclude:: sessions/041.php MemcachedHandler Driver ======================= @@ -647,7 +647,7 @@ considered as it may result in loss of sessions. The ``$sessionSavePath`` format is fairly straightforward here, being just a ``host:port`` pair: -.. literalinclude:: sessions/043.php +.. literalinclude:: sessions/042.php Bonus Tip --------- @@ -659,4 +659,4 @@ to note that we haven't tested if that is reliable. If you want to experiment with this feature (on your own risk), simply separate the multiple server paths with commas: -.. literalinclude:: sessions/044.php +.. literalinclude:: sessions/043.php diff --git a/user_guide_src/source/libraries/sessions/002.php b/user_guide_src/source/libraries/sessions/002.php new file mode 100644 index 000000000000..ba2650b4808a --- /dev/null +++ b/user_guide_src/source/libraries/sessions/002.php @@ -0,0 +1,3 @@ +get('item'); diff --git a/user_guide_src/source/libraries/sessions/006.php b/user_guide_src/source/libraries/sessions/006.php index 3248324f7ee6..180d52833615 100644 --- a/user_guide_src/source/libraries/sessions/006.php +++ b/user_guide_src/source/libraries/sessions/006.php @@ -1,3 +1,3 @@ get('item'); +$item = $session->item; diff --git a/user_guide_src/source/libraries/sessions/007.php b/user_guide_src/source/libraries/sessions/007.php index 180d52833615..2825b97d5c4b 100644 --- a/user_guide_src/source/libraries/sessions/007.php +++ b/user_guide_src/source/libraries/sessions/007.php @@ -1,3 +1,3 @@ item; +$item = session('item'); diff --git a/user_guide_src/source/libraries/sessions/008.php b/user_guide_src/source/libraries/sessions/008.php index 2825b97d5c4b..12632835f531 100644 --- a/user_guide_src/source/libraries/sessions/008.php +++ b/user_guide_src/source/libraries/sessions/008.php @@ -1,3 +1,11 @@ name; + +// or: + +$name = $session->get('name'); diff --git a/user_guide_src/source/libraries/sessions/009.php b/user_guide_src/source/libraries/sessions/009.php index 12632835f531..4bbbfb2646db 100644 --- a/user_guide_src/source/libraries/sessions/009.php +++ b/user_guide_src/source/libraries/sessions/009.php @@ -1,11 +1,5 @@ name; - -// or: - -$name = $session->get('name'); +$userData = $session->get(); diff --git a/user_guide_src/source/libraries/sessions/010.php b/user_guide_src/source/libraries/sessions/010.php index 4bbbfb2646db..b8b949797d22 100644 --- a/user_guide_src/source/libraries/sessions/010.php +++ b/user_guide_src/source/libraries/sessions/010.php @@ -1,5 +1,3 @@ get(); +$session->set($array); diff --git a/user_guide_src/source/libraries/sessions/011.php b/user_guide_src/source/libraries/sessions/011.php index b8b949797d22..01bbbe1670b0 100644 --- a/user_guide_src/source/libraries/sessions/011.php +++ b/user_guide_src/source/libraries/sessions/011.php @@ -1,3 +1,9 @@ set($array); +$newdata = [ + 'username' => 'johndoe', + 'email' => 'johndoe@some-site.com', + 'logged_in' => true, +]; + +$session->set($newdata); diff --git a/user_guide_src/source/libraries/sessions/012.php b/user_guide_src/source/libraries/sessions/012.php index 01bbbe1670b0..0d9c4699281a 100644 --- a/user_guide_src/source/libraries/sessions/012.php +++ b/user_guide_src/source/libraries/sessions/012.php @@ -1,9 +1,3 @@ 'johndoe', - 'email' => 'johndoe@some-site.com', - 'logged_in' => true, -]; - -$session->set($newdata); +$session->set('some_name', 'some_value'); diff --git a/user_guide_src/source/libraries/sessions/013.php b/user_guide_src/source/libraries/sessions/013.php index 0d9c4699281a..45bce58b5e06 100644 --- a/user_guide_src/source/libraries/sessions/013.php +++ b/user_guide_src/source/libraries/sessions/013.php @@ -1,3 +1,7 @@ set('some_name', 'some_value'); +// returns false if the 'some_name' item doesn't exist or is null, +// true otherwise: +if (isset($_SESSION['some_name'])) { + // ... +} diff --git a/user_guide_src/source/libraries/sessions/014.php b/user_guide_src/source/libraries/sessions/014.php index 45bce58b5e06..5b00a839dcb8 100644 --- a/user_guide_src/source/libraries/sessions/014.php +++ b/user_guide_src/source/libraries/sessions/014.php @@ -1,7 +1,3 @@ has('some_name'); diff --git a/user_guide_src/source/libraries/sessions/015.php b/user_guide_src/source/libraries/sessions/015.php index 5b00a839dcb8..e80a0177905a 100644 --- a/user_guide_src/source/libraries/sessions/015.php +++ b/user_guide_src/source/libraries/sessions/015.php @@ -1,3 +1,3 @@ has('some_name'); +$session->push('hobbies', ['sport' => 'tennis']); diff --git a/user_guide_src/source/libraries/sessions/016.php b/user_guide_src/source/libraries/sessions/016.php index e80a0177905a..2b00df65a034 100644 --- a/user_guide_src/source/libraries/sessions/016.php +++ b/user_guide_src/source/libraries/sessions/016.php @@ -1,3 +1,8 @@ push('hobbies', ['sport' => 'tennis']); +unset($_SESSION['some_name']); +// or multiple values: +unset( + $_SESSION['some_name'], + $_SESSION['another_name'] +); diff --git a/user_guide_src/source/libraries/sessions/017.php b/user_guide_src/source/libraries/sessions/017.php index 2b00df65a034..7c7dbf3ca32a 100644 --- a/user_guide_src/source/libraries/sessions/017.php +++ b/user_guide_src/source/libraries/sessions/017.php @@ -1,8 +1,3 @@ remove('some_name'); diff --git a/user_guide_src/source/libraries/sessions/018.php b/user_guide_src/source/libraries/sessions/018.php index 7c7dbf3ca32a..2ebd4f8a4e5f 100644 --- a/user_guide_src/source/libraries/sessions/018.php +++ b/user_guide_src/source/libraries/sessions/018.php @@ -1,3 +1,4 @@ remove('some_name'); +$array_items = ['username', 'email']; +$session->remove($array_items); diff --git a/user_guide_src/source/libraries/sessions/019.php b/user_guide_src/source/libraries/sessions/019.php index 2ebd4f8a4e5f..471c5c5fef96 100644 --- a/user_guide_src/source/libraries/sessions/019.php +++ b/user_guide_src/source/libraries/sessions/019.php @@ -1,4 +1,3 @@ remove($array_items); +$session->markAsFlashdata('item'); diff --git a/user_guide_src/source/libraries/sessions/020.php b/user_guide_src/source/libraries/sessions/020.php index 471c5c5fef96..4be42e7f3a62 100644 --- a/user_guide_src/source/libraries/sessions/020.php +++ b/user_guide_src/source/libraries/sessions/020.php @@ -1,3 +1,3 @@ markAsFlashdata('item'); +$session->markAsFlashdata(['item', 'item2']); diff --git a/user_guide_src/source/libraries/sessions/021.php b/user_guide_src/source/libraries/sessions/021.php index 4be42e7f3a62..d87dd8763d34 100644 --- a/user_guide_src/source/libraries/sessions/021.php +++ b/user_guide_src/source/libraries/sessions/021.php @@ -1,3 +1,4 @@ markAsFlashdata(['item', 'item2']); +$_SESSION['item'] = 'value'; +$session->markAsFlashdata('item'); diff --git a/user_guide_src/source/libraries/sessions/022.php b/user_guide_src/source/libraries/sessions/022.php index d87dd8763d34..f22af522ab61 100644 --- a/user_guide_src/source/libraries/sessions/022.php +++ b/user_guide_src/source/libraries/sessions/022.php @@ -1,4 +1,3 @@ markAsFlashdata('item'); +$session->setFlashdata('item', 'value'); diff --git a/user_guide_src/source/libraries/sessions/023.php b/user_guide_src/source/libraries/sessions/023.php index f22af522ab61..ec1e40879798 100644 --- a/user_guide_src/source/libraries/sessions/023.php +++ b/user_guide_src/source/libraries/sessions/023.php @@ -1,3 +1,3 @@ setFlashdata('item', 'value'); +$item = $_SESSION['item']; diff --git a/user_guide_src/source/libraries/sessions/024.php b/user_guide_src/source/libraries/sessions/024.php index ec1e40879798..407208d20b4a 100644 --- a/user_guide_src/source/libraries/sessions/024.php +++ b/user_guide_src/source/libraries/sessions/024.php @@ -1,3 +1,3 @@ getFlashdata('item'); diff --git a/user_guide_src/source/libraries/sessions/025.php b/user_guide_src/source/libraries/sessions/025.php index 407208d20b4a..7c387b5a4fa2 100644 --- a/user_guide_src/source/libraries/sessions/025.php +++ b/user_guide_src/source/libraries/sessions/025.php @@ -1,3 +1,3 @@ getFlashdata('item'); +$session->getFlashdata(); diff --git a/user_guide_src/source/libraries/sessions/026.php b/user_guide_src/source/libraries/sessions/026.php index 7c387b5a4fa2..94a299006a5d 100644 --- a/user_guide_src/source/libraries/sessions/026.php +++ b/user_guide_src/source/libraries/sessions/026.php @@ -1,3 +1,4 @@ getFlashdata(); +$session->keepFlashdata('item'); +$session->keepFlashdata(['item1', 'item2', 'item3']); diff --git a/user_guide_src/source/libraries/sessions/027.php b/user_guide_src/source/libraries/sessions/027.php index 94a299006a5d..d2ed461826c0 100644 --- a/user_guide_src/source/libraries/sessions/027.php +++ b/user_guide_src/source/libraries/sessions/027.php @@ -1,4 +1,4 @@ keepFlashdata('item'); -$session->keepFlashdata(['item1', 'item2', 'item3']); +// 'item' will be erased after 300 seconds +$session->markAsTempdata('item', 300); diff --git a/user_guide_src/source/libraries/sessions/028.php b/user_guide_src/source/libraries/sessions/028.php index d2ed461826c0..fd8d241ad069 100644 --- a/user_guide_src/source/libraries/sessions/028.php +++ b/user_guide_src/source/libraries/sessions/028.php @@ -1,4 +1,11 @@ markAsTempdata('item', 300); +// Both 'item' and 'item2' will expire after 300 seconds +$session->markAsTempdata(['item', 'item2'], 300); + +// 'item' will be erased after 300 seconds, while 'item2' +// will do so after only 240 seconds +$session->markAsTempdata([ + 'item' => 300, + 'item2' => 240, +]); diff --git a/user_guide_src/source/libraries/sessions/029.php b/user_guide_src/source/libraries/sessions/029.php index fd8d241ad069..d4e8941b5d34 100644 --- a/user_guide_src/source/libraries/sessions/029.php +++ b/user_guide_src/source/libraries/sessions/029.php @@ -1,11 +1,4 @@ markAsTempdata(['item', 'item2'], 300); - -// 'item' will be erased after 300 seconds, while 'item2' -// will do so after only 240 seconds -$session->markAsTempdata([ - 'item' => 300, - 'item2' => 240, -]); +$_SESSION['item'] = 'value'; +$session->markAsTempdata('item', 300); // Expire in 5 minutes diff --git a/user_guide_src/source/libraries/sessions/030.php b/user_guide_src/source/libraries/sessions/030.php index d4e8941b5d34..444c045adae9 100644 --- a/user_guide_src/source/libraries/sessions/030.php +++ b/user_guide_src/source/libraries/sessions/030.php @@ -1,4 +1,3 @@ markAsTempdata('item', 300); // Expire in 5 minutes +$session->setTempdata('item', 'value', 300); diff --git a/user_guide_src/source/libraries/sessions/031.php b/user_guide_src/source/libraries/sessions/031.php index 444c045adae9..f7099d76289a 100644 --- a/user_guide_src/source/libraries/sessions/031.php +++ b/user_guide_src/source/libraries/sessions/031.php @@ -1,3 +1,4 @@ setTempdata('item', 'value', 300); +$tempdata = ['newuser' => true, 'message' => 'Thanks for joining!']; +$session->setTempdata($tempdata, null, $expire); diff --git a/user_guide_src/source/libraries/sessions/032.php b/user_guide_src/source/libraries/sessions/032.php index f7099d76289a..ec1e40879798 100644 --- a/user_guide_src/source/libraries/sessions/032.php +++ b/user_guide_src/source/libraries/sessions/032.php @@ -1,4 +1,3 @@ true, 'message' => 'Thanks for joining!']; -$session->setTempdata($tempdata, null, $expire); +$item = $_SESSION['item']; diff --git a/user_guide_src/source/libraries/sessions/033.php b/user_guide_src/source/libraries/sessions/033.php index ec1e40879798..e940ed0e6a02 100644 --- a/user_guide_src/source/libraries/sessions/033.php +++ b/user_guide_src/source/libraries/sessions/033.php @@ -1,3 +1,3 @@ getTempdata('item'); diff --git a/user_guide_src/source/libraries/sessions/034.php b/user_guide_src/source/libraries/sessions/034.php index e940ed0e6a02..f44b959eee81 100644 --- a/user_guide_src/source/libraries/sessions/034.php +++ b/user_guide_src/source/libraries/sessions/034.php @@ -1,3 +1,3 @@ getTempdata('item'); +$session->getTempdata(); diff --git a/user_guide_src/source/libraries/sessions/035.php b/user_guide_src/source/libraries/sessions/035.php index f44b959eee81..f063fa2907f4 100644 --- a/user_guide_src/source/libraries/sessions/035.php +++ b/user_guide_src/source/libraries/sessions/035.php @@ -1,3 +1,3 @@ getTempdata(); +unset($_SESSION['item']); diff --git a/user_guide_src/source/libraries/sessions/036.php b/user_guide_src/source/libraries/sessions/036.php index f063fa2907f4..0c3302fb6db3 100644 --- a/user_guide_src/source/libraries/sessions/036.php +++ b/user_guide_src/source/libraries/sessions/036.php @@ -1,3 +1,3 @@ removeTempdata('item'); diff --git a/user_guide_src/source/libraries/sessions/037.php b/user_guide_src/source/libraries/sessions/037.php index 0c3302fb6db3..1e7931f34f33 100644 --- a/user_guide_src/source/libraries/sessions/037.php +++ b/user_guide_src/source/libraries/sessions/037.php @@ -1,3 +1,5 @@ removeTempdata('item'); +session_destroy(); +// or +$session->destroy(); diff --git a/user_guide_src/source/libraries/sessions/038.php b/user_guide_src/source/libraries/sessions/038.php index 1e7931f34f33..7b43795e71e4 100644 --- a/user_guide_src/source/libraries/sessions/038.php +++ b/user_guide_src/source/libraries/sessions/038.php @@ -1,5 +1,3 @@ destroy(); +$session->stop(); diff --git a/user_guide_src/source/libraries/sessions/039.php b/user_guide_src/source/libraries/sessions/039.php index 7b43795e71e4..3aedc2f047af 100644 --- a/user_guide_src/source/libraries/sessions/039.php +++ b/user_guide_src/source/libraries/sessions/039.php @@ -1,3 +1,12 @@ stop(); +namespace Config; + +use CodeIgniter\Config\BaseConfig; + +class App extends BaseConfig +{ + public $sessionDriver = 'CodeIgniter\Session\Handlers\DatabaseHandler'; + public $sessionSavePath = 'ci_sessions'; + // ... +} diff --git a/user_guide_src/source/libraries/sessions/040.php b/user_guide_src/source/libraries/sessions/040.php index 3aedc2f047af..f645887ec2be 100644 --- a/user_guide_src/source/libraries/sessions/040.php +++ b/user_guide_src/source/libraries/sessions/040.php @@ -6,7 +6,6 @@ class App extends BaseConfig { - public $sessionDriver = 'CodeIgniter\Session\Handlers\DatabaseHandler'; - public $sessionSavePath = 'ci_sessions'; + public $sessionDBGroup = 'groupName'; // ... } diff --git a/user_guide_src/source/libraries/sessions/041.php b/user_guide_src/source/libraries/sessions/041.php index f645887ec2be..f0aed919a816 100644 --- a/user_guide_src/source/libraries/sessions/041.php +++ b/user_guide_src/source/libraries/sessions/041.php @@ -6,6 +6,7 @@ class App extends BaseConfig { - public $sessionDBGroup = 'groupName'; + public $sessionDiver = 'CodeIgniter\Session\Handlers\RedisHandler'; + public $sessionSavePath = 'tcp://localhost:6379'; // ... } diff --git a/user_guide_src/source/libraries/sessions/042.php b/user_guide_src/source/libraries/sessions/042.php index f0aed919a816..cad56413151c 100644 --- a/user_guide_src/source/libraries/sessions/042.php +++ b/user_guide_src/source/libraries/sessions/042.php @@ -6,7 +6,7 @@ class App extends BaseConfig { - public $sessionDiver = 'CodeIgniter\Session\Handlers\RedisHandler'; - public $sessionSavePath = 'tcp://localhost:6379'; + public $sessionDriver = 'CodeIgniter\Session\Handlers\MemcachedHandler'; + public $sessionSavePath = 'localhost:11211'; // ... } diff --git a/user_guide_src/source/libraries/sessions/043.php b/user_guide_src/source/libraries/sessions/043.php index cad56413151c..e5fab8602236 100644 --- a/user_guide_src/source/libraries/sessions/043.php +++ b/user_guide_src/source/libraries/sessions/043.php @@ -6,7 +6,9 @@ class App extends BaseConfig { - public $sessionDriver = 'CodeIgniter\Session\Handlers\MemcachedHandler'; - public $sessionSavePath = 'localhost:11211'; + // localhost will be given higher priority (5) here, + // compared to 192.0.2.1 with a weight of 1. + public $sessionSavePath = 'localhost:11211:5,192.0.2.1:11211:1'; + // ... } diff --git a/user_guide_src/source/libraries/sessions/044.php b/user_guide_src/source/libraries/sessions/044.php deleted file mode 100644 index e5fab8602236..000000000000 --- a/user_guide_src/source/libraries/sessions/044.php +++ /dev/null @@ -1,14 +0,0 @@ -request->getFile('userfile'); diff --git a/user_guide_src/source/libraries/uploaded_files/005.php b/user_guide_src/source/libraries/uploaded_files/005.php new file mode 100644 index 000000000000..ad71bd5575fb --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/005.php @@ -0,0 +1,3 @@ +request->getFile('my-form.details.avatar'); diff --git a/user_guide_src/source/libraries/uploaded_files/006.php b/user_guide_src/source/libraries/uploaded_files/006.php new file mode 100644 index 000000000000..f0be5ba1aafb --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/006.php @@ -0,0 +1,10 @@ +request->getFiles()) { + foreach ($imagefile['images'] as $img) { + if ($img->isValid() && ! $img->hasMoved()) { + $newName = $img->getRandomName(); + $img->move(WRITEPATH . 'uploads', $newName); + } + } +} diff --git a/user_guide_src/source/libraries/uploaded_files/007.php b/user_guide_src/source/libraries/uploaded_files/007.php index e5f6440d96fb..da51d17dbd15 100644 --- a/user_guide_src/source/libraries/uploaded_files/007.php +++ b/user_guide_src/source/libraries/uploaded_files/007.php @@ -1,3 +1,4 @@ request->getFile('userfile'); +$file1 = $this->request->getFile('images.0'); +$file2 = $this->request->getFile('images.1'); diff --git a/user_guide_src/source/libraries/uploaded_files/008.php b/user_guide_src/source/libraries/uploaded_files/008.php index ad71bd5575fb..646e6bb0b8b9 100644 --- a/user_guide_src/source/libraries/uploaded_files/008.php +++ b/user_guide_src/source/libraries/uploaded_files/008.php @@ -1,3 +1,3 @@ request->getFile('my-form.details.avatar'); +$files = $this->request->getFileMultiple('images'); diff --git a/user_guide_src/source/libraries/uploaded_files/009.php b/user_guide_src/source/libraries/uploaded_files/009.php index f0be5ba1aafb..d18a755ba234 100644 --- a/user_guide_src/source/libraries/uploaded_files/009.php +++ b/user_guide_src/source/libraries/uploaded_files/009.php @@ -1,10 +1,4 @@ request->getFiles()) { - foreach ($imagefile['images'] as $img) { - if ($img->isValid() && ! $img->hasMoved()) { - $newName = $img->getRandomName(); - $img->move(WRITEPATH . 'uploads', $newName); - } - } -} +$file1 = $this->request->getFile('my-form.details.avatars.0'); +$file2 = $this->request->getFile('my-form.details.avatars.1'); diff --git a/user_guide_src/source/libraries/uploaded_files/010.php b/user_guide_src/source/libraries/uploaded_files/010.php index da51d17dbd15..094ea73c1064 100644 --- a/user_guide_src/source/libraries/uploaded_files/010.php +++ b/user_guide_src/source/libraries/uploaded_files/010.php @@ -1,4 +1,5 @@ request->getFile('images.0'); -$file2 = $this->request->getFile('images.1'); +if (! $file->isValid()) { + throw new \RuntimeException($file->getErrorString() . '(' . $file->getError() . ')'); +} diff --git a/user_guide_src/source/libraries/uploaded_files/011.php b/user_guide_src/source/libraries/uploaded_files/011.php index 646e6bb0b8b9..057a56b3e9a0 100644 --- a/user_guide_src/source/libraries/uploaded_files/011.php +++ b/user_guide_src/source/libraries/uploaded_files/011.php @@ -1,3 +1,3 @@ request->getFileMultiple('images'); +$name = $file->getName(); diff --git a/user_guide_src/source/libraries/uploaded_files/012.php b/user_guide_src/source/libraries/uploaded_files/012.php index d18a755ba234..4fb0cae0ad12 100644 --- a/user_guide_src/source/libraries/uploaded_files/012.php +++ b/user_guide_src/source/libraries/uploaded_files/012.php @@ -1,4 +1,3 @@ request->getFile('my-form.details.avatars.0'); -$file2 = $this->request->getFile('my-form.details.avatars.1'); +$originalName = $file->getClientName(); diff --git a/user_guide_src/source/libraries/uploaded_files/013.php b/user_guide_src/source/libraries/uploaded_files/013.php index 094ea73c1064..c9e4774a4bbf 100644 --- a/user_guide_src/source/libraries/uploaded_files/013.php +++ b/user_guide_src/source/libraries/uploaded_files/013.php @@ -1,5 +1,3 @@ isValid()) { - throw new \RuntimeException($file->getErrorString() . '(' . $file->getError() . ')'); -} +$tempfile = $file->getTempName(); diff --git a/user_guide_src/source/libraries/uploaded_files/014.php b/user_guide_src/source/libraries/uploaded_files/014.php index 057a56b3e9a0..867877238c76 100644 --- a/user_guide_src/source/libraries/uploaded_files/014.php +++ b/user_guide_src/source/libraries/uploaded_files/014.php @@ -1,3 +1,3 @@ getName(); +$ext = $file->getClientExtension(); diff --git a/user_guide_src/source/libraries/uploaded_files/015.php b/user_guide_src/source/libraries/uploaded_files/015.php index 4fb0cae0ad12..dd1288e441c3 100644 --- a/user_guide_src/source/libraries/uploaded_files/015.php +++ b/user_guide_src/source/libraries/uploaded_files/015.php @@ -1,3 +1,5 @@ getClientName(); +$type = $file->getClientMimeType(); + +echo $type; // image/png diff --git a/user_guide_src/source/libraries/uploaded_files/016.php b/user_guide_src/source/libraries/uploaded_files/016.php index c9e4774a4bbf..12499a3ca1ba 100644 --- a/user_guide_src/source/libraries/uploaded_files/016.php +++ b/user_guide_src/source/libraries/uploaded_files/016.php @@ -1,3 +1,3 @@ getTempName(); +$file->move(WRITEPATH . 'uploads'); diff --git a/user_guide_src/source/libraries/uploaded_files/017.php b/user_guide_src/source/libraries/uploaded_files/017.php index 867877238c76..2e6b39645a4b 100644 --- a/user_guide_src/source/libraries/uploaded_files/017.php +++ b/user_guide_src/source/libraries/uploaded_files/017.php @@ -1,3 +1,4 @@ getClientExtension(); +$newName = $file->getRandomName(); +$file->move(WRITEPATH . 'uploads', $newName); diff --git a/user_guide_src/source/libraries/uploaded_files/018.php b/user_guide_src/source/libraries/uploaded_files/018.php index dd1288e441c3..7f49d1f5232e 100644 --- a/user_guide_src/source/libraries/uploaded_files/018.php +++ b/user_guide_src/source/libraries/uploaded_files/018.php @@ -1,5 +1,5 @@ getClientMimeType(); - -echo $type; // image/png +if ($file->isValid() && ! $file->hasMoved()) { + $file->move($path); +} diff --git a/user_guide_src/source/libraries/uploaded_files/019.php b/user_guide_src/source/libraries/uploaded_files/019.php index 12499a3ca1ba..90f9495eaf7b 100644 --- a/user_guide_src/source/libraries/uploaded_files/019.php +++ b/user_guide_src/source/libraries/uploaded_files/019.php @@ -1,3 +1,3 @@ move(WRITEPATH . 'uploads'); +$path = $this->request->getFile('userfile')->store(); diff --git a/user_guide_src/source/libraries/uploaded_files/020.php b/user_guide_src/source/libraries/uploaded_files/020.php index 2e6b39645a4b..0e552f417d52 100644 --- a/user_guide_src/source/libraries/uploaded_files/020.php +++ b/user_guide_src/source/libraries/uploaded_files/020.php @@ -1,4 +1,3 @@ getRandomName(); -$file->move(WRITEPATH . 'uploads', $newName); +$path = $this->request->getFile('userfile')->store('head_img/', 'user_name.jpg'); diff --git a/user_guide_src/source/libraries/uploaded_files/021.php b/user_guide_src/source/libraries/uploaded_files/021.php deleted file mode 100644 index 7f49d1f5232e..000000000000 --- a/user_guide_src/source/libraries/uploaded_files/021.php +++ /dev/null @@ -1,5 +0,0 @@ -isValid() && ! $file->hasMoved()) { - $file->move($path); -} diff --git a/user_guide_src/source/libraries/uploaded_files/022.php b/user_guide_src/source/libraries/uploaded_files/022.php deleted file mode 100644 index 90f9495eaf7b..000000000000 --- a/user_guide_src/source/libraries/uploaded_files/022.php +++ /dev/null @@ -1,3 +0,0 @@ -request->getFile('userfile')->store(); diff --git a/user_guide_src/source/libraries/uploaded_files/023.php b/user_guide_src/source/libraries/uploaded_files/023.php deleted file mode 100644 index 0e552f417d52..000000000000 --- a/user_guide_src/source/libraries/uploaded_files/023.php +++ /dev/null @@ -1,3 +0,0 @@ -request->getFile('userfile')->store('head_img/', 'user_name.jpg'); diff --git a/user_guide_src/source/libraries/validation.rst b/user_guide_src/source/libraries/validation.rst index 1d2c8490d339..8d3204804e92 100644 --- a/user_guide_src/source/libraries/validation.rst +++ b/user_guide_src/source/libraries/validation.rst @@ -484,7 +484,7 @@ You can check to see if an error exists with the ``hasError()`` method. The only When specifying a field with a wildcard, all errors matching the mask will be checked: -.. literalinclude:: validation/028.2.php +.. literalinclude:: validation/029.php Customizing Error Display ************************* @@ -500,12 +500,12 @@ The first step is to create custom views. These can be placed anywhere that the which means the standard View directory, or any namespaced View folder will work. For example, you could create a new view at **/app/Views/_errors_list.php**: -.. literalinclude:: validation/029.php +.. literalinclude:: validation/030.php An array named ``$errors`` is available within the view that contains a list of the errors, where the key is the name of the field that had the error, and the value is the error message, like this: -.. literalinclude:: validation/030.php +.. literalinclude:: validation/031.php There are actually two types of views that you can create. The first has an array of all of the errors, and is what we just looked at. The other type is simpler, and only contains a single variable, ``$error`` that contains the @@ -520,7 +520,7 @@ Once you have your views created, you need to let the Validation library know ab Inside, you'll find the ``$templates`` property where you can list as many custom views as you want, and provide an short alias they can be referenced by. If we were to add our example file from above, it would look something like: -.. literalinclude:: validation/031.php +.. literalinclude:: validation/032.php Specifying the Template ======================= @@ -541,7 +541,7 @@ Rules are stored within simple, namespaced classes. They can be stored any locat autoloader can find it. These files are called RuleSets. To add a new RuleSet, edit **Config/Validation.php** and add the new file to the ``$ruleSets`` array: -.. literalinclude:: validation/032.php +.. literalinclude:: validation/033.php You can add it as either a simple string with the fully qualified class name, or using the ``::class`` suffix as shown above. The primary benefit here is that it provides some extra navigation capabilities in more advanced IDEs. @@ -549,17 +549,17 @@ shown above. The primary benefit here is that it provides some extra navigation Within the file itself, each method is a rule and must accept a string as the first parameter, and must return a boolean true or false value signifying true if it passed the test or false if it did not: -.. literalinclude:: validation/033.php +.. literalinclude:: validation/034.php By default, the system will look within ``CodeIgniter\Language\en\Validation.php`` for the language strings used within errors. In custom rules, you may provide error messages by accepting a ``$error`` variable by reference in the second parameter: -.. literalinclude:: validation/034.php +.. literalinclude:: validation/035.php Your new custom rule could now be used just like any other rule: -.. literalinclude:: validation/035.php +.. literalinclude:: validation/036.php Allowing Parameters =================== @@ -568,7 +568,7 @@ If your method needs to work with parameters, the function will need a minimum o the parameter string, and an array with all of the data that was submitted the form. The ``$data`` array is especially handy for rules like ``require_with`` that needs to check the value of another submitted field to base its result on: -.. literalinclude:: validation/036.php +.. literalinclude:: validation/037.php Custom errors can be returned as the fourth parameter, just as described above. @@ -580,7 +580,7 @@ The following is a list of all the native rules that are available to use: .. note:: Rule is a string; there must be **no spaces** between the parameters, especially the ``is_unique`` rule. There can be no spaces before and after ``ignore_value``. -.. literalinclude:: validation/037.php +.. literalinclude:: validation/038.php ======================= ========== ============================================= =================================================== Rule Parameter Description Example diff --git a/user_guide_src/source/libraries/validation/028.2.php b/user_guide_src/source/libraries/validation/028.2.php deleted file mode 100644 index 5470a1eecea6..000000000000 --- a/user_guide_src/source/libraries/validation/028.2.php +++ /dev/null @@ -1,12 +0,0 @@ - 'Error', - * 'foo.baz.bar' => 'Error', - * ] - */ - -// returns true -$validation->hasError('foo.*.bar'); diff --git a/user_guide_src/source/libraries/validation/029.php b/user_guide_src/source/libraries/validation/029.php index f7c69eb42e99..5470a1eecea6 100644 --- a/user_guide_src/source/libraries/validation/029.php +++ b/user_guide_src/source/libraries/validation/029.php @@ -1,7 +1,12 @@ - + 'Error', + * 'foo.baz.bar' => 'Error', + * ] + */ + +// returns true +$validation->hasError('foo.*.bar'); diff --git a/user_guide_src/source/libraries/validation/030.php b/user_guide_src/source/libraries/validation/030.php index abac67b15dec..f7c69eb42e99 100644 --- a/user_guide_src/source/libraries/validation/030.php +++ b/user_guide_src/source/libraries/validation/030.php @@ -1,6 +1,7 @@ - 'The username field must be unique.', - 'email' => 'You must provide a valid email address.', -]; + diff --git a/user_guide_src/source/libraries/validation/031.php b/user_guide_src/source/libraries/validation/031.php index acec3cfc6ba2..abac67b15dec 100644 --- a/user_guide_src/source/libraries/validation/031.php +++ b/user_guide_src/source/libraries/validation/031.php @@ -1,14 +1,6 @@ 'CodeIgniter\Validation\Views\list', - 'single' => 'CodeIgniter\Validation\Views\single', - 'my_list' => '_errors_list', - ]; - - // ... -} +$errors = [ + 'username' => 'The username field must be unique.', + 'email' => 'You must provide a valid email address.', +]; diff --git a/user_guide_src/source/libraries/validation/032.php b/user_guide_src/source/libraries/validation/032.php index 890b4c453fc0..acec3cfc6ba2 100644 --- a/user_guide_src/source/libraries/validation/032.php +++ b/user_guide_src/source/libraries/validation/032.php @@ -2,18 +2,12 @@ namespace Config; -use CodeIgniter\Validation\CreditCardRules; -use CodeIgniter\Validation\FileRules; -use CodeIgniter\Validation\FormatRules; -use CodeIgniter\Validation\Rules; - class Validation { - public $ruleSets = [ - Rules::class, - FormatRules::class, - FileRules::class, - CreditCardRules::class, + public $templates = [ + 'list' => 'CodeIgniter\Validation\Views\list', + 'single' => 'CodeIgniter\Validation\Views\single', + 'my_list' => '_errors_list', ]; // ... diff --git a/user_guide_src/source/libraries/validation/033.php b/user_guide_src/source/libraries/validation/033.php index 282bef9aabbc..890b4c453fc0 100644 --- a/user_guide_src/source/libraries/validation/033.php +++ b/user_guide_src/source/libraries/validation/033.php @@ -1,9 +1,20 @@ validate($request, [ - 'foo' => 'required|even', -]); +class MyRules +{ + public function even(string $str, ?string &$error = null): bool + { + if ((int) $str % 2 !== 0) { + $error = lang('myerrors.evenError'); + + return false; + } + + return true; + } +} diff --git a/user_guide_src/source/libraries/validation/036.php b/user_guide_src/source/libraries/validation/036.php index 9e13c663b0d7..99db5f30eae4 100644 --- a/user_guide_src/source/libraries/validation/036.php +++ b/user_guide_src/source/libraries/validation/036.php @@ -1,35 +1,5 @@ required($str ?? ''); - - if ($present) { - return true; - } - - // Still here? Then we fail this test if - // any of the fields are present in $data - // as $fields is the lis - $requiredFields = []; - - foreach ($fields as $field) { - if (array_key_exists($field, $data)) { - $requiredFields[] = $field; - } - } - - // Remove any keys with empty values since, that means they - // weren't truly there, as far as this is concerned. - $requiredFields = array_filter($requiredFields, static fn ($item) => ! empty($data[$item])); - - return empty($requiredFields); - } -} +$this->validate($request, [ + 'foo' => 'required|even', +]); diff --git a/user_guide_src/source/libraries/validation/037.php b/user_guide_src/source/libraries/validation/037.php index f37307b0ae07..9e13c663b0d7 100644 --- a/user_guide_src/source/libraries/validation/037.php +++ b/user_guide_src/source/libraries/validation/037.php @@ -1,10 +1,35 @@ setRules([ - 'name' => "is_unique[supplier.name,uuid, {$uuid}]", // is not ok - 'name' => "is_unique[supplier.name,uuid,{$uuid} ]", // is not ok - 'name' => "is_unique[supplier.name,uuid,{$uuid}]", // is ok - 'name' => 'is_unique[supplier.name,uuid,{uuid}]', // is ok - see "Validation Placeholders" -]); +class MyRules +{ + public function required_with($str, string $fields, array $data): bool + { + $fields = explode(',', $fields); + + // If the field is present we can safely assume that + // the field is here, no matter whether the corresponding + // search field is present or not. + $present = $this->required($str ?? ''); + + if ($present) { + return true; + } + + // Still here? Then we fail this test if + // any of the fields are present in $data + // as $fields is the lis + $requiredFields = []; + + foreach ($fields as $field) { + if (array_key_exists($field, $data)) { + $requiredFields[] = $field; + } + } + + // Remove any keys with empty values since, that means they + // weren't truly there, as far as this is concerned. + $requiredFields = array_filter($requiredFields, static fn ($item) => ! empty($data[$item])); + + return empty($requiredFields); + } +} diff --git a/user_guide_src/source/libraries/validation/038.php b/user_guide_src/source/libraries/validation/038.php new file mode 100644 index 000000000000..f37307b0ae07 --- /dev/null +++ b/user_guide_src/source/libraries/validation/038.php @@ -0,0 +1,10 @@ +setRules([ + 'name' => "is_unique[supplier.name,uuid, {$uuid}]", // is not ok + 'name' => "is_unique[supplier.name,uuid,{$uuid} ]", // is not ok + 'name' => "is_unique[supplier.name,uuid,{$uuid}]", // is ok + 'name' => 'is_unique[supplier.name,uuid,{uuid}]', // is ok - see "Validation Placeholders" +]); diff --git a/user_guide_src/source/testing/overview.rst b/user_guide_src/source/testing/overview.rst index 2cfae8328caa..2ff02af66ac3 100644 --- a/user_guide_src/source/testing/overview.rst +++ b/user_guide_src/source/testing/overview.rst @@ -95,17 +95,17 @@ The static methods run before and after the entire test case, whereas the local between each test. If you implement any of these special functions make sure you run their parent as well so extended test cases do not interfere with staging: -.. literalinclude:: overview/004.php +.. literalinclude:: overview/003.php In addition to these methods, ``CIUnitTestCase`` also comes with a convenience property for parameter-free methods you want run during set up and tear down: -.. literalinclude:: overview/005.php +.. literalinclude:: overview/004.php You can see by default these handle the mocking of intrusive services, but your class may override that or provide their own: -.. literalinclude:: overview/006.php +.. literalinclude:: overview/005.php Traits ------ @@ -116,7 +116,7 @@ to run named for the trait itself. For example, if you needed to add authenticat of your test cases you could create an authentication trait with a set up method to fake a logged in user: -.. literalinclude:: overview/007.php +.. literalinclude:: overview/006.php Additional Assertions --------------------- @@ -127,19 +127,19 @@ Additional Assertions Ensure that something you expected to be logged actually was: -.. literalinclude:: overview/008.php +.. literalinclude:: overview/007.php **assertEventTriggered($eventName)** Ensure that an event you expected to be triggered actually was: -.. literalinclude:: overview/009.php +.. literalinclude:: overview/008.php **assertHeaderEmitted($header, $ignoreCase = false)** Ensure that a header or cookie was actually emitted: -.. literalinclude:: overview/010.php +.. literalinclude:: overview/009.php Note: the test case with this should be `run as a separate process in PHPunit `_. @@ -148,7 +148,7 @@ in PHPunit `_. @@ -158,7 +158,7 @@ in PHPunit model->purgeDeleted(); + } } diff --git a/user_guide_src/source/testing/overview/006.php b/user_guide_src/source/testing/overview/006.php index 86dc1c44b40f..6193eb88bf50 100644 --- a/user_guide_src/source/testing/overview/006.php +++ b/user_guide_src/source/testing/overview/006.php @@ -1,17 +1,21 @@ createFakeUser(); + $this->logInUser($user); + } + + // ... +} use CodeIgniter\Test\CIUnitTestCase; -final class OneOfMyModelsTest extends CIUnitTestCase +final class AuthenticationFeatureTest extends CIUnitTestCase { - protected $tearDownMethods = [ - 'purgeRows', - ]; + use AuthTrait; - protected function purgeRows() - { - $this->model->purgeDeleted(); - } + // ... } diff --git a/user_guide_src/source/testing/overview/007.php b/user_guide_src/source/testing/overview/007.php index 6193eb88bf50..55077ed36818 100644 --- a/user_guide_src/source/testing/overview/007.php +++ b/user_guide_src/source/testing/overview/007.php @@ -1,21 +1,9 @@ createFakeUser(); - $this->logInUser($user); - } +$config = new LoggerConfig(); +$logger = new Logger($config); - // ... -} +// ... do something that you expect a log entry from +$logger->log('error', "That's no moon"); -use CodeIgniter\Test\CIUnitTestCase; - -final class AuthenticationFeatureTest extends CIUnitTestCase -{ - use AuthTrait; - - // ... -} +$this->assertLogged('error', "That's no moon"); diff --git a/user_guide_src/source/testing/overview/008.php b/user_guide_src/source/testing/overview/008.php index 55077ed36818..5d69c01c16d5 100644 --- a/user_guide_src/source/testing/overview/008.php +++ b/user_guide_src/source/testing/overview/008.php @@ -1,9 +1,9 @@ log('error', "That's no moon"); +Events::trigger('foo', 'bar'); -$this->assertLogged('error', "That's no moon"); +$this->assertEventTriggered('foo'); diff --git a/user_guide_src/source/testing/overview/009.php b/user_guide_src/source/testing/overview/009.php index 5d69c01c16d5..506d75a8d433 100644 --- a/user_guide_src/source/testing/overview/009.php +++ b/user_guide_src/source/testing/overview/009.php @@ -1,9 +1,9 @@ setCookie('foo', 'bar'); -Events::trigger('foo', 'bar'); +ob_start(); +$this->response->send(); +$output = ob_get_clean(); // in case you want to check the actual body -$this->assertEventTriggered('foo'); +$this->assertHeaderEmitted('Set-Cookie: foo=bar'); diff --git a/user_guide_src/source/testing/overview/010.php b/user_guide_src/source/testing/overview/010.php index 506d75a8d433..10e9d4a0d31b 100644 --- a/user_guide_src/source/testing/overview/010.php +++ b/user_guide_src/source/testing/overview/010.php @@ -6,4 +6,4 @@ $this->response->send(); $output = ob_get_clean(); // in case you want to check the actual body -$this->assertHeaderEmitted('Set-Cookie: foo=bar'); +$this->assertHeaderNotEmitted('Set-Cookie: banana'); diff --git a/user_guide_src/source/testing/overview/011.php b/user_guide_src/source/testing/overview/011.php index 10e9d4a0d31b..c9b85aef7f87 100644 --- a/user_guide_src/source/testing/overview/011.php +++ b/user_guide_src/source/testing/overview/011.php @@ -1,9 +1,5 @@ setCookie('foo', 'bar'); - -ob_start(); -$this->response->send(); -$output = ob_get_clean(); // in case you want to check the actual body - -$this->assertHeaderNotEmitted('Set-Cookie: banana'); +$timer = new Timer(); +$timer->start('longjohn', strtotime('-11 minutes')); +$this->assertCloseEnough(11 * 60, $timer->getElapsedTime('longjohn')); diff --git a/user_guide_src/source/testing/overview/012.php b/user_guide_src/source/testing/overview/012.php index c9b85aef7f87..1c03733868e4 100644 --- a/user_guide_src/source/testing/overview/012.php +++ b/user_guide_src/source/testing/overview/012.php @@ -2,4 +2,4 @@ $timer = new Timer(); $timer->start('longjohn', strtotime('-11 minutes')); -$this->assertCloseEnough(11 * 60, $timer->getElapsedTime('longjohn')); +$this->assertCloseEnoughString(11 * 60, $timer->getElapsedTime('longjohn')); diff --git a/user_guide_src/source/testing/overview/013.php b/user_guide_src/source/testing/overview/013.php index 1c03733868e4..f228dcf28963 100644 --- a/user_guide_src/source/testing/overview/013.php +++ b/user_guide_src/source/testing/overview/013.php @@ -1,5 +1,10 @@ start('longjohn', strtotime('-11 minutes')); -$this->assertCloseEnoughString(11 * 60, $timer->getElapsedTime('longjohn')); +// Create an instance of the class to test +$obj = new Foo(); + +// Get the invoker for the 'privateMethod' method. +$method = $this->getPrivateMethodInvoker($obj, 'privateMethod'); + +// Test the results +$this->assertEquals('bar', $method('param1', 'param2')); diff --git a/user_guide_src/source/testing/overview/014.php b/user_guide_src/source/testing/overview/014.php index f228dcf28963..1befb710253e 100644 --- a/user_guide_src/source/testing/overview/014.php +++ b/user_guide_src/source/testing/overview/014.php @@ -3,8 +3,5 @@ // Create an instance of the class to test $obj = new Foo(); -// Get the invoker for the 'privateMethod' method. -$method = $this->getPrivateMethodInvoker($obj, 'privateMethod'); - -// Test the results -$this->assertEquals('bar', $method('param1', 'param2')); +// Test the value +$this->assertEquals('bar', $this->getPrivateProperty($obj, 'baz')); diff --git a/user_guide_src/source/testing/overview/015.php b/user_guide_src/source/testing/overview/015.php index 1befb710253e..c2e815953dd9 100644 --- a/user_guide_src/source/testing/overview/015.php +++ b/user_guide_src/source/testing/overview/015.php @@ -3,5 +3,7 @@ // Create an instance of the class to test $obj = new Foo(); -// Test the value -$this->assertEquals('bar', $this->getPrivateProperty($obj, 'baz')); +// Set the value +$this->setPrivateProperty($obj, 'baz', 'oops!'); + +// Do normal testing... diff --git a/user_guide_src/source/testing/overview/016.php b/user_guide_src/source/testing/overview/016.php index c2e815953dd9..cf0c211496b6 100644 --- a/user_guide_src/source/testing/overview/016.php +++ b/user_guide_src/source/testing/overview/016.php @@ -1,9 +1,16 @@ setPrivateProperty($obj, 'baz', 'oops!'); +final class SomeTest extends CIUnitTestCase +{ + public function testSomething() + { + $curlrequest = $this->getMockBuilder('CodeIgniter\HTTP\CURLRequest') + ->setMethods(['request']) + ->getMock(); + Services::injectMock('curlrequest', $curlrequest); -// Do normal testing... + // Do normal testing here.... + } +} diff --git a/user_guide_src/source/testing/overview/017.php b/user_guide_src/source/testing/overview/017.php index cf0c211496b6..67ccc4a634dc 100644 --- a/user_guide_src/source/testing/overview/017.php +++ b/user_guide_src/source/testing/overview/017.php @@ -4,13 +4,11 @@ final class SomeTest extends CIUnitTestCase { - public function testSomething() + protected function setUp(): void { - $curlrequest = $this->getMockBuilder('CodeIgniter\HTTP\CURLRequest') - ->setMethods(['request']) - ->getMock(); - Services::injectMock('curlrequest', $curlrequest); + parent::setUp(); - // Do normal testing here.... + $model = new MockUserModel(); + Factories::injectMock('models', 'App\Models\UserModel', $model); } } diff --git a/user_guide_src/source/testing/overview/018.php b/user_guide_src/source/testing/overview/018.php index 67ccc4a634dc..e0e55131f5b3 100644 --- a/user_guide_src/source/testing/overview/018.php +++ b/user_guide_src/source/testing/overview/018.php @@ -6,9 +6,19 @@ final class SomeTest extends CIUnitTestCase { protected function setUp(): void { - parent::setUp(); + CITestStreamFilter::$buffer = ''; + $this->stream_filter = stream_filter_append(STDOUT, 'CITestStreamFilter'); + } - $model = new MockUserModel(); - Factories::injectMock('models', 'App\Models\UserModel', $model); + protected function tearDown(): void + { + stream_filter_remove($this->stream_filter); + } + + public function testSomeOutput(): void + { + CLI::write('first.'); + $expected = "first.\n"; + $this->assertSame($expected, CITestStreamFilter::$buffer); } } diff --git a/user_guide_src/source/testing/overview/019.php b/user_guide_src/source/testing/overview/019.php deleted file mode 100644 index e0e55131f5b3..000000000000 --- a/user_guide_src/source/testing/overview/019.php +++ /dev/null @@ -1,24 +0,0 @@ -stream_filter = stream_filter_append(STDOUT, 'CITestStreamFilter'); - } - - protected function tearDown(): void - { - stream_filter_remove($this->stream_filter); - } - - public function testSomeOutput(): void - { - CLI::write('first.'); - $expected = "first.\n"; - $this->assertSame($expected, CITestStreamFilter::$buffer); - } -} From 60c7083a741f20f4f32dd41a87e453c1ad801ffd Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Fri, 11 Mar 2022 17:41:49 +0100 Subject: [PATCH 0681/1246] Renumerate installation. --- .../source/installation/upgrade_configuration.rst | 2 +- .../upgrade_configuration/{002.php => 001.php} | 0 .../source/installation/upgrade_controllers.rst | 2 +- .../upgrade_controllers/{002.php => 001.php} | 0 .../source/installation/upgrade_database.rst | 2 +- .../installation/upgrade_database/{002.php => 001.php} | 0 user_guide_src/source/installation/upgrade_emails.rst | 2 +- .../installation/upgrade_emails/{002.php => 001.php} | 0 .../source/installation/upgrade_encryption.rst | 2 +- .../upgrade_encryption/{002.php => 001.php} | 0 .../source/installation/upgrade_file_upload.rst | 2 +- .../upgrade_file_upload/{002.php => 001.php} | 0 .../source/installation/upgrade_html_tables.rst | 2 +- .../upgrade_html_tables/{002.php => 001.php} | 0 .../source/installation/upgrade_localization.rst | 2 +- .../upgrade_localization/{003.php => 002.php} | 0 .../source/installation/upgrade_migrations.rst | 2 +- .../upgrade_migrations/{002.php => 001.php} | 0 user_guide_src/source/installation/upgrade_models.rst | 2 +- .../installation/upgrade_models/{002.php => 001.php} | 0 .../source/installation/upgrade_pagination.rst | 2 +- .../upgrade_pagination/{002.php => 001.php} | 0 .../source/installation/upgrade_responses.rst | 2 +- .../upgrade_responses/{002.php => 001.php} | 0 user_guide_src/source/installation/upgrade_routing.rst | 2 +- .../installation/upgrade_routing/{002.php => 001.php} | 0 .../source/installation/upgrade_security.rst | 10 +--------- .../source/installation/upgrade_security/002.php | 8 ++++++++ .../source/installation/upgrade_sessions.rst | 2 +- .../installation/upgrade_sessions/{002.php => 001.php} | 0 .../source/installation/upgrade_validations.rst | 2 +- .../upgrade_validations/{003.php => 002.php} | 0 .../source/installation/upgrade_view_parser.rst | 2 +- .../upgrade_view_parser/{002.php => 001.php} | 0 user_guide_src/source/installation/upgrade_views.rst | 2 +- .../installation/upgrade_views/{002.php => 001.php} | 0 36 files changed, 26 insertions(+), 26 deletions(-) rename user_guide_src/source/installation/upgrade_configuration/{002.php => 001.php} (100%) rename user_guide_src/source/installation/upgrade_controllers/{002.php => 001.php} (100%) rename user_guide_src/source/installation/upgrade_database/{002.php => 001.php} (100%) rename user_guide_src/source/installation/upgrade_emails/{002.php => 001.php} (100%) rename user_guide_src/source/installation/upgrade_encryption/{002.php => 001.php} (100%) rename user_guide_src/source/installation/upgrade_file_upload/{002.php => 001.php} (100%) rename user_guide_src/source/installation/upgrade_html_tables/{002.php => 001.php} (100%) rename user_guide_src/source/installation/upgrade_localization/{003.php => 002.php} (100%) rename user_guide_src/source/installation/upgrade_migrations/{002.php => 001.php} (100%) rename user_guide_src/source/installation/upgrade_models/{002.php => 001.php} (100%) rename user_guide_src/source/installation/upgrade_pagination/{002.php => 001.php} (100%) rename user_guide_src/source/installation/upgrade_responses/{002.php => 001.php} (100%) rename user_guide_src/source/installation/upgrade_routing/{002.php => 001.php} (100%) create mode 100644 user_guide_src/source/installation/upgrade_security/002.php rename user_guide_src/source/installation/upgrade_sessions/{002.php => 001.php} (100%) rename user_guide_src/source/installation/upgrade_validations/{003.php => 002.php} (100%) rename user_guide_src/source/installation/upgrade_view_parser/{002.php => 001.php} (100%) rename user_guide_src/source/installation/upgrade_views/{002.php => 001.php} (100%) diff --git a/user_guide_src/source/installation/upgrade_configuration.rst b/user_guide_src/source/installation/upgrade_configuration.rst index 6a9f38069478..aca4af05d4a7 100644 --- a/user_guide_src/source/installation/upgrade_configuration.rst +++ b/user_guide_src/source/installation/upgrade_configuration.rst @@ -47,4 +47,4 @@ CodeIgniter Version 4.x Path: **app/Config**: -.. literalinclude:: upgrade_configuration/002.php +.. literalinclude:: upgrade_configuration/001.php diff --git a/user_guide_src/source/installation/upgrade_configuration/002.php b/user_guide_src/source/installation/upgrade_configuration/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_configuration/002.php rename to user_guide_src/source/installation/upgrade_configuration/001.php diff --git a/user_guide_src/source/installation/upgrade_controllers.rst b/user_guide_src/source/installation/upgrade_controllers.rst index 3e7521445691..1810ea615506 100644 --- a/user_guide_src/source/installation/upgrade_controllers.rst +++ b/user_guide_src/source/installation/upgrade_controllers.rst @@ -50,4 +50,4 @@ CodeIgniter Version 4.x Path: **app/Controllers**: -.. literalinclude:: upgrade_controllers/002.php +.. literalinclude:: upgrade_controllers/001.php diff --git a/user_guide_src/source/installation/upgrade_controllers/002.php b/user_guide_src/source/installation/upgrade_controllers/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_controllers/002.php rename to user_guide_src/source/installation/upgrade_controllers/001.php diff --git a/user_guide_src/source/installation/upgrade_database.rst b/user_guide_src/source/installation/upgrade_database.rst index 10b1e6ac1c96..f62044d8a302 100644 --- a/user_guide_src/source/installation/upgrade_database.rst +++ b/user_guide_src/source/installation/upgrade_database.rst @@ -51,4 +51,4 @@ CodeIgniter Version 3.x CodeIgniter Version 4.x ----------------------- -.. literalinclude:: upgrade_database/002.php +.. literalinclude:: upgrade_database/001.php diff --git a/user_guide_src/source/installation/upgrade_database/002.php b/user_guide_src/source/installation/upgrade_database/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_database/002.php rename to user_guide_src/source/installation/upgrade_database/001.php diff --git a/user_guide_src/source/installation/upgrade_emails.rst b/user_guide_src/source/installation/upgrade_emails.rst index af322f2d7c7a..7eb40a050042 100644 --- a/user_guide_src/source/installation/upgrade_emails.rst +++ b/user_guide_src/source/installation/upgrade_emails.rst @@ -33,4 +33,4 @@ CodeIgniter Version 3.x CodeIgniter Version 4.x ----------------------- -.. literalinclude:: upgrade_emails/002.php +.. literalinclude:: upgrade_emails/001.php diff --git a/user_guide_src/source/installation/upgrade_emails/002.php b/user_guide_src/source/installation/upgrade_emails/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_emails/002.php rename to user_guide_src/source/installation/upgrade_emails/001.php diff --git a/user_guide_src/source/installation/upgrade_encryption.rst b/user_guide_src/source/installation/upgrade_encryption.rst index 9d626d341d5d..a4d8a74ce659 100644 --- a/user_guide_src/source/installation/upgrade_encryption.rst +++ b/user_guide_src/source/installation/upgrade_encryption.rst @@ -31,4 +31,4 @@ CodeIgniter Version 3.x CodeIgniter Version 4.x ----------------------- -.. literalinclude:: upgrade_encryption/002.php +.. literalinclude:: upgrade_encryption/001.php diff --git a/user_guide_src/source/installation/upgrade_encryption/002.php b/user_guide_src/source/installation/upgrade_encryption/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_encryption/002.php rename to user_guide_src/source/installation/upgrade_encryption/001.php diff --git a/user_guide_src/source/installation/upgrade_file_upload.rst b/user_guide_src/source/installation/upgrade_file_upload.rst index ed620bbaeb67..d7a38a1f97d8 100644 --- a/user_guide_src/source/installation/upgrade_file_upload.rst +++ b/user_guide_src/source/installation/upgrade_file_upload.rst @@ -32,4 +32,4 @@ CodeIgniter Version 3.x CodeIgniter Version 4.x ----------------------- -.. literalinclude:: upgrade_file_upload/002.php +.. literalinclude:: upgrade_file_upload/001.php diff --git a/user_guide_src/source/installation/upgrade_file_upload/002.php b/user_guide_src/source/installation/upgrade_file_upload/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_file_upload/002.php rename to user_guide_src/source/installation/upgrade_file_upload/001.php diff --git a/user_guide_src/source/installation/upgrade_html_tables.rst b/user_guide_src/source/installation/upgrade_html_tables.rst index ae97e8e3baf2..09059e547abe 100644 --- a/user_guide_src/source/installation/upgrade_html_tables.rst +++ b/user_guide_src/source/installation/upgrade_html_tables.rst @@ -32,4 +32,4 @@ CodeIgniter Version 3.x CodeIgniter Version 4.x ----------------------- -.. literalinclude:: upgrade_html_tables/002.php +.. literalinclude:: upgrade_html_tables/001.php diff --git a/user_guide_src/source/installation/upgrade_html_tables/002.php b/user_guide_src/source/installation/upgrade_html_tables/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_html_tables/002.php rename to user_guide_src/source/installation/upgrade_html_tables/001.php diff --git a/user_guide_src/source/installation/upgrade_localization.rst b/user_guide_src/source/installation/upgrade_localization.rst index 782336334974..d962eb462fd4 100644 --- a/user_guide_src/source/installation/upgrade_localization.rst +++ b/user_guide_src/source/installation/upgrade_localization.rst @@ -37,4 +37,4 @@ CodeIgniter Version 3.x CodeIgniter Version 4.x ----------------------- -.. literalinclude:: upgrade_localization/003.php +.. literalinclude:: upgrade_localization/002.php diff --git a/user_guide_src/source/installation/upgrade_localization/003.php b/user_guide_src/source/installation/upgrade_localization/002.php similarity index 100% rename from user_guide_src/source/installation/upgrade_localization/003.php rename to user_guide_src/source/installation/upgrade_localization/002.php diff --git a/user_guide_src/source/installation/upgrade_migrations.rst b/user_guide_src/source/installation/upgrade_migrations.rst index 60f6b8d7b090..31eabc0766e1 100644 --- a/user_guide_src/source/installation/upgrade_migrations.rst +++ b/user_guide_src/source/installation/upgrade_migrations.rst @@ -60,7 +60,7 @@ CodeIgniter Version 4.x Path: **app/Database/Migrations**: -.. literalinclude:: upgrade_migrations/002.php +.. literalinclude:: upgrade_migrations/001.php Search & Replace ================ diff --git a/user_guide_src/source/installation/upgrade_migrations/002.php b/user_guide_src/source/installation/upgrade_migrations/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_migrations/002.php rename to user_guide_src/source/installation/upgrade_migrations/001.php diff --git a/user_guide_src/source/installation/upgrade_models.rst b/user_guide_src/source/installation/upgrade_models.rst index 1ffce60151e0..6acf6aa76969 100644 --- a/user_guide_src/source/installation/upgrade_models.rst +++ b/user_guide_src/source/installation/upgrade_models.rst @@ -49,6 +49,6 @@ CodeIgniter Version 4.x Path: **app/Models**: -.. literalinclude:: upgrade_models/002.php +.. literalinclude:: upgrade_models/001.php To insert data you can just directly call the ``$model->insert()`` method because this method is built-in since CI4. diff --git a/user_guide_src/source/installation/upgrade_models/002.php b/user_guide_src/source/installation/upgrade_models/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_models/002.php rename to user_guide_src/source/installation/upgrade_models/001.php diff --git a/user_guide_src/source/installation/upgrade_pagination.rst b/user_guide_src/source/installation/upgrade_pagination.rst index 6658ae8e4bd7..69e19d57164c 100644 --- a/user_guide_src/source/installation/upgrade_pagination.rst +++ b/user_guide_src/source/installation/upgrade_pagination.rst @@ -39,4 +39,4 @@ CodeIgniter Version 3.x CodeIgniter Version 4.x ----------------------- -.. literalinclude:: upgrade_pagination/002.php +.. literalinclude:: upgrade_pagination/001.php diff --git a/user_guide_src/source/installation/upgrade_pagination/002.php b/user_guide_src/source/installation/upgrade_pagination/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_pagination/002.php rename to user_guide_src/source/installation/upgrade_pagination/001.php diff --git a/user_guide_src/source/installation/upgrade_responses.rst b/user_guide_src/source/installation/upgrade_responses.rst index c6b925d144f1..6788468c0b57 100644 --- a/user_guide_src/source/installation/upgrade_responses.rst +++ b/user_guide_src/source/installation/upgrade_responses.rst @@ -30,4 +30,4 @@ CodeIgniter Version 3.x CodeIgniter Version 4.x ----------------------- -.. literalinclude:: upgrade_responses/002.php +.. literalinclude:: upgrade_responses/001.php diff --git a/user_guide_src/source/installation/upgrade_responses/002.php b/user_guide_src/source/installation/upgrade_responses/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_responses/002.php rename to user_guide_src/source/installation/upgrade_responses/001.php diff --git a/user_guide_src/source/installation/upgrade_routing.rst b/user_guide_src/source/installation/upgrade_routing.rst index 9e6c512ff423..882ef380ca92 100644 --- a/user_guide_src/source/installation/upgrade_routing.rst +++ b/user_guide_src/source/installation/upgrade_routing.rst @@ -36,4 +36,4 @@ CodeIgniter Version 4.x ----------------------- Path: **app/Config/Routes.php**: -.. literalinclude:: upgrade_routing/002.php +.. literalinclude:: upgrade_routing/001.php diff --git a/user_guide_src/source/installation/upgrade_routing/002.php b/user_guide_src/source/installation/upgrade_routing/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_routing/002.php rename to user_guide_src/source/installation/upgrade_routing/001.php diff --git a/user_guide_src/source/installation/upgrade_security.rst b/user_guide_src/source/installation/upgrade_security.rst index 0a6d615e0841..c520b9c50350 100644 --- a/user_guide_src/source/installation/upgrade_security.rst +++ b/user_guide_src/source/installation/upgrade_security.rst @@ -37,13 +37,5 @@ CodeIgniter Version 3.x CodeIgniter Version 4.x ----------------------- -:: - - - - - - - - +.. literalinclude:: upgrade_security/002.php diff --git a/user_guide_src/source/installation/upgrade_security/002.php b/user_guide_src/source/installation/upgrade_security/002.php new file mode 100644 index 000000000000..89c3b3882c56 --- /dev/null +++ b/user_guide_src/source/installation/upgrade_security/002.php @@ -0,0 +1,8 @@ +
    + + + + + + + diff --git a/user_guide_src/source/installation/upgrade_sessions.rst b/user_guide_src/source/installation/upgrade_sessions.rst index a309033bc816..177552282a9c 100644 --- a/user_guide_src/source/installation/upgrade_sessions.rst +++ b/user_guide_src/source/installation/upgrade_sessions.rst @@ -36,4 +36,4 @@ CodeIgniter Version 3.x CodeIgniter Version 4.x ----------------------- -.. literalinclude:: upgrade_sessions/002.php +.. literalinclude:: upgrade_sessions/001.php diff --git a/user_guide_src/source/installation/upgrade_sessions/002.php b/user_guide_src/source/installation/upgrade_sessions/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_sessions/002.php rename to user_guide_src/source/installation/upgrade_sessions/001.php diff --git a/user_guide_src/source/installation/upgrade_validations.rst b/user_guide_src/source/installation/upgrade_validations.rst index 3612784ade28..5bd6a2a1d514 100644 --- a/user_guide_src/source/installation/upgrade_validations.rst +++ b/user_guide_src/source/installation/upgrade_validations.rst @@ -110,4 +110,4 @@ Path: **app/Views**:: Path: **app/Controllers**: -.. literalinclude:: upgrade_validations/003.php +.. literalinclude:: upgrade_validations/002.php diff --git a/user_guide_src/source/installation/upgrade_validations/003.php b/user_guide_src/source/installation/upgrade_validations/002.php similarity index 100% rename from user_guide_src/source/installation/upgrade_validations/003.php rename to user_guide_src/source/installation/upgrade_validations/002.php diff --git a/user_guide_src/source/installation/upgrade_view_parser.rst b/user_guide_src/source/installation/upgrade_view_parser.rst index 5def5e912d5f..55e86fb357a4 100644 --- a/user_guide_src/source/installation/upgrade_view_parser.rst +++ b/user_guide_src/source/installation/upgrade_view_parser.rst @@ -32,4 +32,4 @@ CodeIgniter Version 3.x CodeIgniter Version 4.x ----------------------- -.. literalinclude:: upgrade_view_parser/002.php +.. literalinclude:: upgrade_view_parser/001.php diff --git a/user_guide_src/source/installation/upgrade_view_parser/002.php b/user_guide_src/source/installation/upgrade_view_parser/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_view_parser/002.php rename to user_guide_src/source/installation/upgrade_view_parser/001.php diff --git a/user_guide_src/source/installation/upgrade_views.rst b/user_guide_src/source/installation/upgrade_views.rst index 574de607b42b..8509705c76dc 100644 --- a/user_guide_src/source/installation/upgrade_views.rst +++ b/user_guide_src/source/installation/upgrade_views.rst @@ -43,4 +43,4 @@ CodeIgniter Version 4.x Path: **app/Views**: -.. literalinclude:: upgrade_views/002.php +.. literalinclude:: upgrade_views/001.php diff --git a/user_guide_src/source/installation/upgrade_views/002.php b/user_guide_src/source/installation/upgrade_views/001.php similarity index 100% rename from user_guide_src/source/installation/upgrade_views/002.php rename to user_guide_src/source/installation/upgrade_views/001.php From 2ccc2cdb9ea562c0e23dc953bcd1f328903099a3 Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Fri, 11 Mar 2022 17:53:48 +0100 Subject: [PATCH 0682/1246] Delete renumerate script. --- user_guide_src/renumerate.php | 98 ----------------------------------- 1 file changed, 98 deletions(-) delete mode 100644 user_guide_src/renumerate.php diff --git a/user_guide_src/renumerate.php b/user_guide_src/renumerate.php deleted file mode 100644 index 7ecf1a631e4b..000000000000 --- a/user_guide_src/renumerate.php +++ /dev/null @@ -1,98 +0,0 @@ - - * - * For the full copyright and license information, please view - * the LICENSE file that was distributed with this source code. - */ - -$srcFolder = __DIR__ . '/source'; - -// Exclude static folders -$excludes = ['_static', 'images']; - -// Safety prefix -$prefix = 'old_'; - -// Begin user info -echo 'The following sections were renumerated:', PHP_EOL; - -// Loop source directory -$srcIterator = new DirectoryIterator($srcFolder); - -foreach ($srcIterator as $chapterInfo) { - if (! $chapterInfo->isDot() && $chapterInfo->isDir() && ! in_array($chapterInfo->getFilename(), $excludes, true)) { - $chapterName = $chapterInfo->getFilename(); - - // Iterate the working directory - $chapterIterator = new DirectoryIterator($chapterInfo->getPathname()); - - foreach ($chapterIterator as $sectionInfo) { - if (! $sectionInfo->isDot() && $sectionInfo->isFile() && $sectionInfo->getExtension() === 'rst') { - $sectionName = $sectionInfo->getBasename('.rst'); - $sectionFolder = $sectionInfo->getPath() . '/' . $sectionName; - - // Read the section file - $sectionContent = file_get_contents($sectionInfo->getPathname()); - - // Match all includes - preg_match_all("~\\.\\. literalinclude:: {$sectionName}\\/(.+)\\.php~", $sectionContent, $matches); - $includeStrings = $matches[0]; - $exampleNames = $matches[1]; - - // Exit early if no matches - if (count($exampleNames) === 0) { - continue; - } - - // Check if examples are consecutive - $consecutive = true; - - foreach ($exampleNames as $exampleIndex => $exampleName) { - if (str_pad($exampleIndex + 1, 3, '0', STR_PAD_LEFT) !== $exampleName) { - $consecutive = false; - break; - } - } - - // Exit if examples are already consecutive - if ($consecutive) { - continue; - } - - // Rename all example files to avoid conflicts - $exampleIterator = new DirectoryIterator($sectionFolder); - - foreach ($exampleIterator as $exampleInfo) { - if (! $exampleInfo->isDot() && $exampleInfo->isFile() && $exampleInfo->getExtension() === 'php') { - rename($exampleInfo->getPathname(), $exampleInfo->getPath() . '/' . $prefix . $exampleInfo->getFilename()); - } - } - $sectionContent = preg_replace("~\\.\\. literalinclude:: {$sectionName}\\/(.+)\\.php~", ".. literalinclude:: {$sectionName}/{$prefix}$1.php", $sectionContent); - - // Renumerate examples - foreach ($exampleNames as $exampleIndex => $exampleName) { - $newName = str_pad($exampleIndex + 1, 3, '0', STR_PAD_LEFT); - - // Rename example file - rename($sectionFolder . '/' . $prefix . $exampleName . '.php', $sectionFolder . '/' . $newName . '.php'); - - // Fix include link - $sectionContent = preg_replace('~' . preg_quote(str_replace($exampleName, $prefix . $exampleName, $includeStrings[$exampleIndex]), '~') . '~', str_replace($exampleName, $newName, $includeStrings[$exampleIndex]), $sectionContent, 1, $count); - } - - // Write new content to rst - file_put_contents($sectionInfo->getPathname(), $sectionContent); - - // User info - echo $chapterName, '/', $sectionName, PHP_EOL; - } - } - } -} - -// End user info -echo 'Renumerating finished.', PHP_EOL; From 27a2132c598de9a9990207aa8ecfb5a156fba9d9 Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Fri, 11 Mar 2022 18:00:21 +0100 Subject: [PATCH 0683/1246] Update cs-fixer excludes. --- .user-guide.php-cs-fixer.dist.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.user-guide.php-cs-fixer.dist.php b/.user-guide.php-cs-fixer.dist.php index 7a48f922f1d7..900c26ec81e1 100644 --- a/.user-guide.php-cs-fixer.dist.php +++ b/.user-guide.php-cs-fixer.dist.php @@ -25,8 +25,8 @@ ]) ->notPath([ 'ci3sample/', - 'libraries/sessions/017.php', - 'database/query_builder/074.php', + 'libraries/sessions/016.php', + 'database/query_builder/075.php', ]); $overrides = [ From 929cf6158fbb22657fb71b982e3780d6a546c37a Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 12 Mar 2022 09:22:42 +0900 Subject: [PATCH 0684/1246] docs: fix `@return` description --- system/Debug/Timer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/Debug/Timer.php b/system/Debug/Timer.php index 5783c77aae72..9be1dd121f1a 100644 --- a/system/Debug/Timer.php +++ b/system/Debug/Timer.php @@ -78,7 +78,7 @@ public function stop(string $name) * @param string $name The name of the timer. * @param int $decimals Number of decimal places. * - * @return float|null Returns null if timer exists by that name. + * @return float|null Returns null if timer does not exist by that name. * Returns a float representing the number of * seconds elapsed while that timer was running. */ From 3c706a52b112aa7ea309a4d7c56dadfad6d956f5 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 12 Mar 2022 09:23:28 +0900 Subject: [PATCH 0685/1246] fix: Timer::getElapsedTime() returns incorrect value --- system/Debug/Timer.php | 2 +- tests/system/Debug/TimerTest.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/system/Debug/Timer.php b/system/Debug/Timer.php index 9be1dd121f1a..9ca51d1c9b08 100644 --- a/system/Debug/Timer.php +++ b/system/Debug/Timer.php @@ -96,7 +96,7 @@ public function getElapsedTime(string $name, int $decimals = 4) $timer['end'] = microtime(true); } - return (float) number_format($timer['end'] - $timer['start'], $decimals); + return (float) number_format($timer['end'] - $timer['start'], $decimals, '.', ''); } /** diff --git a/tests/system/Debug/TimerTest.php b/tests/system/Debug/TimerTest.php index 7b7b75199ea9..fdd09829d9ff 100644 --- a/tests/system/Debug/TimerTest.php +++ b/tests/system/Debug/TimerTest.php @@ -92,8 +92,8 @@ public function testThrowsExceptionStoppingNonTimer() public function testLongExecutionTime() { $timer = new Timer(); - $timer->start('longjohn', strtotime('-11 minutes')); - $this->assertCloseEnough(11 * 60, $timer->getElapsedTime('longjohn')); + $timer->start('longjohn', strtotime('-110 minutes')); + $this->assertCloseEnough(110 * 60, $timer->getElapsedTime('longjohn')); } public function testLongExecutionTimeThroughCommonFunc() From 81f062f84fe7d3e6cb19203596ad7d2ae516de02 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 12 Mar 2022 10:40:57 +0900 Subject: [PATCH 0686/1246] config: add .woff2 --- app/Config/Publisher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Config/Publisher.php b/app/Config/Publisher.php index 4f7cf11037f5..7088703fc0d5 100644 --- a/app/Config/Publisher.php +++ b/app/Config/Publisher.php @@ -23,6 +23,6 @@ class Publisher extends BasePublisher */ public $restrictions = [ ROOTPATH => '*', - FCPATH => '#\.(s?css|js|map|html?|xml|json|webmanifest|tff|eot|woff|gif|jpe?g|tiff?|png|webp|bmp|ico|svg)$#i', + FCPATH => '#\.(s?css|js|map|html?|xml|json|webmanifest|tff|eot|woff2?|gif|jpe?g|tiff?|png|webp|bmp|ico|svg)$#i', ]; } From 5d4753c824fcdfbdd6bc36888780debc62633116 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 12 Mar 2022 10:42:30 +0900 Subject: [PATCH 0687/1246] docs: add .woff2 --- user_guide_src/source/libraries/publisher.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/libraries/publisher.rst b/user_guide_src/source/libraries/publisher.rst index 69de79bd7464..947a102019e1 100644 --- a/user_guide_src/source/libraries/publisher.rst +++ b/user_guide_src/source/libraries/publisher.rst @@ -83,7 +83,7 @@ receive files with the following extensions: * Web assets: css, scss, js, map * Non-executable web files: htm, html, xml, json, webmanifest -* Fonts: tff, eot, woff +* Fonts: tff, eot, woff, woff2 * Images: gif, jpg, jpeg, tif, tiff, png, webp, bmp, ico, svg If you need to add or adjust the security for your project then alter the ``$restrictions`` property of ``Config\Publisher`` in **app/Config/Publisher.php**. From 7b0520e495c7fbe3ee2c2c184cb41f7b897e80b2 Mon Sep 17 00:00:00 2001 From: MGatner Date: Tue, 15 Mar 2022 00:30:45 +0000 Subject: [PATCH 0688/1246] Fix extension typo --- app/Config/Publisher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Config/Publisher.php b/app/Config/Publisher.php index 7088703fc0d5..47475112c080 100644 --- a/app/Config/Publisher.php +++ b/app/Config/Publisher.php @@ -23,6 +23,6 @@ class Publisher extends BasePublisher */ public $restrictions = [ ROOTPATH => '*', - FCPATH => '#\.(s?css|js|map|html?|xml|json|webmanifest|tff|eot|woff2?|gif|jpe?g|tiff?|png|webp|bmp|ico|svg)$#i', + FCPATH => '#\.(s?css|js|map|html?|xml|json|webmanifest|ttf|eot|woff2?|gif|jpe?g|tiff?|png|webp|bmp|ico|svg)$#i', ]; } From 75184b97b686f5283a5e5cfb57d12d8af9d9ded2 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 15 Mar 2022 09:58:46 +0900 Subject: [PATCH 0689/1246] docs: fix extension typo See #5800 --- user_guide_src/source/libraries/publisher.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/libraries/publisher.rst b/user_guide_src/source/libraries/publisher.rst index 947a102019e1..5b37369445f1 100644 --- a/user_guide_src/source/libraries/publisher.rst +++ b/user_guide_src/source/libraries/publisher.rst @@ -83,7 +83,7 @@ receive files with the following extensions: * Web assets: css, scss, js, map * Non-executable web files: htm, html, xml, json, webmanifest -* Fonts: tff, eot, woff, woff2 +* Fonts: ttf, eot, woff, woff2 * Images: gif, jpg, jpeg, tif, tiff, png, webp, bmp, ico, svg If you need to add or adjust the security for your project then alter the ``$restrictions`` property of ``Config\Publisher`` in **app/Config/Publisher.php**. From 74daf1aa53f10166671cd295b8e68e336c77c68e Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 16 Mar 2022 08:50:11 +0900 Subject: [PATCH 0690/1246] test: remove helper('url') URL Helper is automatically loaded. --- tests/system/HTTP/UserAgentTest.php | 2 -- tests/system/Helpers/HTMLHelperTest.php | 2 -- tests/system/Helpers/URLHelper/CurrentUrlTest.php | 7 ------- tests/system/Helpers/URLHelper/MiscUrlTest.php | 7 ------- tests/system/Helpers/URLHelper/SiteUrlTest.php | 7 ------- tests/system/Pager/PagerTest.php | 1 - tests/system/View/ParserPluginTest.php | 5 ----- 7 files changed, 31 deletions(-) diff --git a/tests/system/HTTP/UserAgentTest.php b/tests/system/HTTP/UserAgentTest.php index 6b80d8f25b30..e4f2d1e7f025 100644 --- a/tests/system/HTTP/UserAgentTest.php +++ b/tests/system/HTTP/UserAgentTest.php @@ -34,8 +34,6 @@ protected function setUp(): void $_SERVER['HTTP_USER_AGENT'] = $this->_user_agent; $this->agent = new UserAgent(); - - helper('url'); } public function testMobile() diff --git a/tests/system/Helpers/HTMLHelperTest.php b/tests/system/Helpers/HTMLHelperTest.php index 79cb5da92334..b3ed47d0c3e6 100755 --- a/tests/system/Helpers/HTMLHelperTest.php +++ b/tests/system/Helpers/HTMLHelperTest.php @@ -35,8 +35,6 @@ protected function setUp(): void { parent::setUp(); - // URL is needed by the HTML Helper. - helper('url'); helper('html'); $this->tracks = [ diff --git a/tests/system/Helpers/URLHelper/CurrentUrlTest.php b/tests/system/Helpers/URLHelper/CurrentUrlTest.php index b4f522f16071..0f316a305988 100644 --- a/tests/system/Helpers/URLHelper/CurrentUrlTest.php +++ b/tests/system/Helpers/URLHelper/CurrentUrlTest.php @@ -30,13 +30,6 @@ final class CurrentUrlTest extends CIUnitTestCase { private App $config; - public static function setUpBeforeClass(): void - { - parent::setUpBeforeClass(); - - helper('url'); - } - protected function setUp(): void { parent::setUp(); diff --git a/tests/system/Helpers/URLHelper/MiscUrlTest.php b/tests/system/Helpers/URLHelper/MiscUrlTest.php index a5a78c5cc687..709d1b815207 100644 --- a/tests/system/Helpers/URLHelper/MiscUrlTest.php +++ b/tests/system/Helpers/URLHelper/MiscUrlTest.php @@ -27,13 +27,6 @@ final class MiscUrlTest extends CIUnitTestCase { private App $config; - public static function setUpBeforeClass(): void - { - parent::setUpBeforeClass(); - - helper('url'); - } - protected function setUp(): void { parent::setUp(); diff --git a/tests/system/Helpers/URLHelper/SiteUrlTest.php b/tests/system/Helpers/URLHelper/SiteUrlTest.php index e9b5ec9c25dd..f942ce453af8 100644 --- a/tests/system/Helpers/URLHelper/SiteUrlTest.php +++ b/tests/system/Helpers/URLHelper/SiteUrlTest.php @@ -30,13 +30,6 @@ final class SiteUrlTest extends CIUnitTestCase { private App $config; - public static function setUpBeforeClass(): void - { - parent::setUpBeforeClass(); - - helper('url'); - } - protected function setUp(): void { parent::setUp(); diff --git a/tests/system/Pager/PagerTest.php b/tests/system/Pager/PagerTest.php index 05b069d83c21..745a8464111b 100644 --- a/tests/system/Pager/PagerTest.php +++ b/tests/system/Pager/PagerTest.php @@ -35,7 +35,6 @@ final class PagerTest extends CIUnitTestCase protected function setUp(): void { parent::setUp(); - helper('url'); $_SERVER['HTTP_HOST'] = 'example.com'; $_SERVER['REQUEST_URI'] = '/'; diff --git a/tests/system/View/ParserPluginTest.php b/tests/system/View/ParserPluginTest.php index 55e5e4ce9c75..7a4a94a87cc2 100644 --- a/tests/system/View/ParserPluginTest.php +++ b/tests/system/View/ParserPluginTest.php @@ -42,7 +42,6 @@ protected function setUp(): void public function testCurrentURL() { - helper('url'); $template = '{+ current_url +}'; $this->assertSame(current_url(), $this->parser->renderString($template)); @@ -50,7 +49,6 @@ public function testCurrentURL() public function testPreviousURL() { - helper('url'); $template = '{+ previous_url +}'; // Ensure a previous URL exists to work with. @@ -61,7 +59,6 @@ public function testPreviousURL() public function testMailto() { - helper('url'); $template = '{+ mailto email=foo@example.com title=Silly +}'; $this->assertSame(mailto('foo@example.com', 'Silly'), $this->parser->renderString($template)); @@ -72,7 +69,6 @@ public function testMailto() */ public function testMailtoWithDashAndParenthesis() { - helper('url'); $template = '{+ mailto email=foo-bar@example.com title="Scilly (the Great)" +}'; $this->assertSame(mailto('foo-bar@example.com', 'Scilly (the Great)'), $this->parser->renderString($template)); @@ -80,7 +76,6 @@ public function testMailtoWithDashAndParenthesis() public function testSafeMailto() { - helper('url'); $template = '{+ safe_mailto email=foo@example.com title=Silly +}'; $this->assertSame(safe_mailto('foo@example.com', 'Silly'), $this->parser->renderString($template)); From f83160b2be6393938a46bf04e378c05b21ed7e2f Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 16 Mar 2022 11:34:22 +0900 Subject: [PATCH 0691/1246] test: refactor setUp() $_SERVER['HTTP_HOST'] is not used in Pager or Request. --- tests/system/Pager/PagerTest.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/system/Pager/PagerTest.php b/tests/system/Pager/PagerTest.php index 745a8464111b..1259e0065b50 100644 --- a/tests/system/Pager/PagerTest.php +++ b/tests/system/Pager/PagerTest.php @@ -36,18 +36,16 @@ protected function setUp(): void { parent::setUp(); - $_SERVER['HTTP_HOST'] = 'example.com'; $_SERVER['REQUEST_URI'] = '/'; $_GET = []; $config = new App(); $config->baseURL = 'http://example.com/'; $request = Services::request($config); - $request->uri = new URI('http://example.com'); + $request->uri = new URI($config->baseURL); Services::injectMock('request', $request); - $_GET = []; $this->config = new Pager(); $this->pager = new \CodeIgniter\Pager\Pager($this->config, Services::renderer()); } From d071fc4bb97e7d83b9724e9f98c1874e5cb37140 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 16 Mar 2022 11:37:07 +0900 Subject: [PATCH 0692/1246] test: extract createPager() method --- tests/system/Pager/PagerTest.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/system/Pager/PagerTest.php b/tests/system/Pager/PagerTest.php index 1259e0065b50..4a317fcdef42 100644 --- a/tests/system/Pager/PagerTest.php +++ b/tests/system/Pager/PagerTest.php @@ -36,13 +36,18 @@ protected function setUp(): void { parent::setUp(); - $_SERVER['REQUEST_URI'] = '/'; + $this->createPager('/'); + } + + private function createPager(string $path): void + { + $_SERVER['REQUEST_URI'] = $path; $_GET = []; $config = new App(); $config->baseURL = 'http://example.com/'; $request = Services::request($config); - $request->uri = new URI($config->baseURL); + $request->uri = new URI($config->baseURL . ltrim($path, '/')); Services::injectMock('request', $request); From 82a5a98e6ff887323c008a01f73e5fecfe7d0c1a Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 16 Mar 2022 11:45:00 +0900 Subject: [PATCH 0693/1246] test: fix Request and Config state Setting $request->uri later does not make correct state of Request. At least Request::$path is incorrect. --- tests/system/Pager/PagerTest.php | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/tests/system/Pager/PagerTest.php b/tests/system/Pager/PagerTest.php index 4a317fcdef42..c4b180a00f05 100644 --- a/tests/system/Pager/PagerTest.php +++ b/tests/system/Pager/PagerTest.php @@ -11,7 +11,10 @@ namespace CodeIgniter\Pager; +use CodeIgniter\Config\Factories; +use CodeIgniter\HTTP\IncomingRequest; use CodeIgniter\HTTP\URI; +use CodeIgniter\HTTP\UserAgent; use CodeIgniter\Pager\Exceptions\PagerException; use CodeIgniter\Test\CIUnitTestCase; use Config\App; @@ -46,8 +49,16 @@ private function createPager(string $path): void $config = new App(); $config->baseURL = 'http://example.com/'; - $request = Services::request($config); - $request->uri = new URI($config->baseURL . ltrim($path, '/')); + Factories::injectMock('config', 'App', $config); + + $request = new IncomingRequest( + $config, + new URI($config->baseURL . ltrim($path, '/')), + 'php://input', + new UserAgent() + ); + $request = $request->withMethod('GET'); + Services::injectMock('request', $request); Services::injectMock('request', $request); @@ -148,11 +159,11 @@ public function testStoreWithQueries() $this->pager->store('default', 3, 25, 100); - $this->assertSame('http://example.com/index.php?page=2&foo=bar', $this->pager->getPreviousPageURI()); - $this->assertSame('http://example.com/index.php?page=4&foo=bar', $this->pager->getNextPageURI()); - $this->assertSame('http://example.com/index.php?page=5&foo=bar', $this->pager->getPageURI(5)); + $this->assertSame('http://example.com/index.php/?page=2&foo=bar', $this->pager->getPreviousPageURI()); + $this->assertSame('http://example.com/index.php/?page=4&foo=bar', $this->pager->getNextPageURI()); + $this->assertSame('http://example.com/index.php/?page=5&foo=bar', $this->pager->getPageURI(5)); $this->assertSame( - 'http://example.com/index.php?foo=bar&page=5', + 'http://example.com/index.php/?foo=bar&page=5', $this->pager->only(['foo'])->getPageURI(5) ); } From 1094c371bc32e253bf4abea9c211fafcf86a69aa Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 16 Mar 2022 12:55:16 +0900 Subject: [PATCH 0694/1246] test: remove `index.php` from URI --- tests/system/Pager/PagerTest.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/system/Pager/PagerTest.php b/tests/system/Pager/PagerTest.php index c4b180a00f05..e3f61694d76b 100644 --- a/tests/system/Pager/PagerTest.php +++ b/tests/system/Pager/PagerTest.php @@ -45,10 +45,12 @@ protected function setUp(): void private function createPager(string $path): void { $_SERVER['REQUEST_URI'] = $path; + $_SERVER['SCRIPT_NAME'] = '/index.php'; $_GET = []; - $config = new App(); - $config->baseURL = 'http://example.com/'; + $config = new App(); + $config->baseURL = 'http://example.com/'; + $config->indexPage = ''; Factories::injectMock('config', 'App', $config); $request = new IncomingRequest( @@ -159,11 +161,11 @@ public function testStoreWithQueries() $this->pager->store('default', 3, 25, 100); - $this->assertSame('http://example.com/index.php/?page=2&foo=bar', $this->pager->getPreviousPageURI()); - $this->assertSame('http://example.com/index.php/?page=4&foo=bar', $this->pager->getNextPageURI()); - $this->assertSame('http://example.com/index.php/?page=5&foo=bar', $this->pager->getPageURI(5)); + $this->assertSame('http://example.com/?page=2&foo=bar', $this->pager->getPreviousPageURI()); + $this->assertSame('http://example.com/?page=4&foo=bar', $this->pager->getNextPageURI()); + $this->assertSame('http://example.com/?page=5&foo=bar', $this->pager->getPageURI(5)); $this->assertSame( - 'http://example.com/index.php/?foo=bar&page=5', + 'http://example.com/?foo=bar&page=5', $this->pager->only(['foo'])->getPageURI(5) ); } From 41845d4ebe878caa519bdf8a355cb64765951afc Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 16 Mar 2022 13:05:49 +0900 Subject: [PATCH 0695/1246] fix: can't get current page from segment --- system/Pager/Pager.php | 7 ++++++- tests/system/Pager/PagerTest.php | 10 ++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/system/Pager/Pager.php b/system/Pager/Pager.php index f3d6d4bec39d..76eed216f5d5 100644 --- a/system/Pager/Pager.php +++ b/system/Pager/Pager.php @@ -163,6 +163,10 @@ public function setSegment(int $number, string $group = 'default') { $this->segment[$group] = $number; + // Recalculate current page + $this->ensureGroup($group); + $this->calculateCurrentPage($group); + return $this; } @@ -383,6 +387,7 @@ protected function ensureGroup(string $group, ?int $perPage = null) } $this->groups[$group] = [ + 'currentUri' => clone current_url(true), 'uri' => clone current_url(true), 'hasMore' => false, 'total' => null, @@ -405,7 +410,7 @@ protected function calculateCurrentPage(string $group) { if (array_key_exists($group, $this->segment)) { try { - $this->groups[$group]['currentPage'] = (int) $this->groups[$group]['uri']->setSilent(false)->getSegment($this->segment[$group]); + $this->groups[$group]['currentPage'] = (int) $this->groups[$group]['currentUri']->setSilent(false)->getSegment($this->segment[$group]); } catch (HTTPException $e) { $this->groups[$group]['currentPage'] = 1; } diff --git a/tests/system/Pager/PagerTest.php b/tests/system/Pager/PagerTest.php index e3f61694d76b..085c569864fa 100644 --- a/tests/system/Pager/PagerTest.php +++ b/tests/system/Pager/PagerTest.php @@ -229,6 +229,16 @@ public function testGetCurrentPageDetectsGroupedURI() $this->assertSame(2, $this->pager->getCurrentPage('foo')); } + public function testGetCurrentPageFromSegment() + { + $this->createPager('/page/2'); + + $this->pager->setPath('foo'); + $this->pager->setSegment(2); + + $this->assertSame(2, $this->pager->getCurrentPage()); + } + public function testGetTotalPagesDefaultsToOne() { $this->assertSame(1, $this->pager->getPageCount()); From e07611de529ca9c580b18a38788186c0812111a7 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 16 Mar 2022 13:28:39 +0900 Subject: [PATCH 0696/1246] test: rename variable name --- tests/system/Pager/PagerTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/system/Pager/PagerTest.php b/tests/system/Pager/PagerTest.php index 085c569864fa..6c6b14fdca7b 100644 --- a/tests/system/Pager/PagerTest.php +++ b/tests/system/Pager/PagerTest.php @@ -42,9 +42,9 @@ protected function setUp(): void $this->createPager('/'); } - private function createPager(string $path): void + private function createPager(string $requestUri): void { - $_SERVER['REQUEST_URI'] = $path; + $_SERVER['REQUEST_URI'] = $requestUri; $_SERVER['SCRIPT_NAME'] = '/index.php'; $_GET = []; @@ -55,7 +55,7 @@ private function createPager(string $path): void $request = new IncomingRequest( $config, - new URI($config->baseURL . ltrim($path, '/')), + new URI($config->baseURL . ltrim($requestUri, '/')), 'php://input', new UserAgent() ); From 65f5f6f6032f64a9ffd3349f7784118d7001d772 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 16 Mar 2022 13:39:25 +0900 Subject: [PATCH 0697/1246] refactor: break long lines --- system/Pager/Pager.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/system/Pager/Pager.php b/system/Pager/Pager.php index 76eed216f5d5..32843ba9e98d 100644 --- a/system/Pager/Pager.php +++ b/system/Pager/Pager.php @@ -283,7 +283,15 @@ public function getPageURI(?int $page = null, string $group = 'default', bool $r $uri->setQueryArray($query); } - return $returnObject === true ? $uri : URI::createURIString($uri->getScheme(), $uri->getAuthority(), $uri->getPath(), $uri->getQuery(), $uri->getFragment()); + return ($returnObject === true) + ? $uri + : URI::createURIString( + $uri->getScheme(), + $uri->getAuthority(), + $uri->getPath(), + $uri->getQuery(), + $uri->getFragment() + ); } /** @@ -410,7 +418,8 @@ protected function calculateCurrentPage(string $group) { if (array_key_exists($group, $this->segment)) { try { - $this->groups[$group]['currentPage'] = (int) $this->groups[$group]['currentUri']->setSilent(false)->getSegment($this->segment[$group]); + $this->groups[$group]['currentPage'] = (int) $this->groups[$group]['currentUri'] + ->setSilent(false)->getSegment($this->segment[$group]); } catch (HTTPException $e) { $this->groups[$group]['currentPage'] = 1; } From e954172459431185ad8233c446507a8bb4453f53 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 16 Mar 2022 14:16:20 +0900 Subject: [PATCH 0698/1246] fix: ErrorException when the field is not sent ErrorException DateTime::createFromFormat(): Passing null to parameter #2 ($datetime) of type string is deprecated --- system/Validation/FormatRules.php | 4 ++++ tests/system/Validation/FormatRulesTest.php | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/system/Validation/FormatRules.php b/system/Validation/FormatRules.php index 990ea8128809..676ae8485ba2 100644 --- a/system/Validation/FormatRules.php +++ b/system/Validation/FormatRules.php @@ -333,6 +333,10 @@ public function valid_url_strict(?string $str = null, ?string $validSchemes = nu */ public function valid_date(?string $str = null, ?string $format = null): bool { + if (($str === null)) { + return false; + } + if (empty($format)) { return strtotime($str) !== false; } diff --git a/tests/system/Validation/FormatRulesTest.php b/tests/system/Validation/FormatRulesTest.php index f4a22b2af973..bf9bf92eb6dc 100644 --- a/tests/system/Validation/FormatRulesTest.php +++ b/tests/system/Validation/FormatRulesTest.php @@ -1206,6 +1206,11 @@ public function testValidDate(?string $str, ?string $format, bool $expected): vo public function validDateProvider(): Generator { yield from [ + [ + null, + 'Y-m-d', + false, + ], [ 'Sun', 'D', From 6bd3ee9ae10c21330f1bcbddcb3b3e7c39442dd7 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 16 Mar 2022 21:13:35 +0900 Subject: [PATCH 0699/1246] refactor: remove uneeded parentheses --- system/Validation/FormatRules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/Validation/FormatRules.php b/system/Validation/FormatRules.php index 676ae8485ba2..21353d1a3385 100644 --- a/system/Validation/FormatRules.php +++ b/system/Validation/FormatRules.php @@ -333,7 +333,7 @@ public function valid_url_strict(?string $str = null, ?string $validSchemes = nu */ public function valid_date(?string $str = null, ?string $format = null): bool { - if (($str === null)) { + if ($str === null) { return false; } From 2a2e9dae03905d7438dacbebce448383233167d7 Mon Sep 17 00:00:00 2001 From: "John Paul E. Balandan, CPA" Date: Thu, 17 Mar 2022 13:10:11 +0800 Subject: [PATCH 0700/1246] Update Laminas Escaper to v2.10 --- system/ThirdParty/Escaper/Escaper.php | 30 +++++++++------------------ 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/system/ThirdParty/Escaper/Escaper.php b/system/ThirdParty/Escaper/Escaper.php index ca0f1a9dd21c..d6a02e14c9be 100644 --- a/system/ThirdParty/Escaper/Escaper.php +++ b/system/ThirdParty/Escaper/Escaper.php @@ -6,10 +6,8 @@ use function bin2hex; use function ctype_digit; -use function function_exists; use function hexdec; use function htmlspecialchars; -use function iconv; use function in_array; use function mb_convert_encoding; use function ord; @@ -38,7 +36,7 @@ class Escaper * entities that XML supports. Using HTML entities would result in this error: * XML Parsing Error: undefined entity * - * @var array + * @var array */ protected static $htmlNamedEntityMap = [ 34 => 'quot', // quotation mark @@ -67,6 +65,7 @@ class Escaper * Static Matcher which escapes characters for HTML Attribute contexts * * @var callable + * @psalm-var callable(array):string */ protected $htmlAttrMatcher; @@ -74,6 +73,7 @@ class Escaper * Static Matcher which escapes characters for Javascript contexts * * @var callable + * @psalm-var callable(array):string */ protected $jsMatcher; @@ -81,6 +81,7 @@ class Escaper * Static Matcher which escapes characters for CSS Attribute contexts * * @var callable + * @psalm-var callable(array):string */ protected $cssMatcher; @@ -255,7 +256,7 @@ public function escapeCss(string $string) * Callback function for preg_replace_callback that applies HTML Attribute * escaping to all matches. * - * @param array $matches + * @param array $matches * @return string */ protected function htmlAttrMatcher($matches) @@ -302,7 +303,7 @@ protected function htmlAttrMatcher($matches) * Callback function for preg_replace_callback that applies Javascript * escaping to all matches. * - * @param array $matches + * @param array $matches * @return string */ protected function jsMatcher($matches) @@ -325,7 +326,7 @@ protected function jsMatcher($matches) * Callback function for preg_replace_callback that applies CSS * escaping to all matches. * - * @param array $matches + * @param array $matches * @return string */ protected function cssMatcher($matches) @@ -391,32 +392,21 @@ protected function isUtf8($string) } /** - * Encoding conversion helper which wraps iconv and mbstring where they exist or throws - * and exception where neither is available. + * Encoding conversion helper which wraps mb_convert_encoding * * @param string $string * @param string $to * @param array|string $from - * @throws Exception\RuntimeException * @return string */ protected function convertEncoding($string, $to, $from) { - if (function_exists('iconv')) { - $result = iconv($from, $to, $string); - } elseif (function_exists('mb_convert_encoding')) { - $result = mb_convert_encoding($string, $to, $from); - } else { - throw new Exception\RuntimeException( - static::class - . ' requires either the iconv or mbstring extension to be installed' - . ' when escaping for non UTF-8 strings.' - ); - } + $result = mb_convert_encoding($string, $to, $from); if ($result === false) { return ''; // return non-fatal blank string on encoding errors from users } + return $result; } } From b3589085dd1643e0c953d396d7515514651c1356 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 18 Mar 2022 11:59:00 +0900 Subject: [PATCH 0701/1246] docs: clarify that current_url() returns URL based on Config\App --- system/Helpers/url_helper.php | 2 +- user_guide_src/source/helpers/url_helper.rst | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/system/Helpers/url_helper.php b/system/Helpers/url_helper.php index 98dd596c1a4d..e1e8b8a30e32 100644 --- a/system/Helpers/url_helper.php +++ b/system/Helpers/url_helper.php @@ -109,7 +109,7 @@ function base_url($relativePath = '', ?string $scheme = null): string if (! function_exists('current_url')) { /** - * Returns the current full URL based on the IncomingRequest. + * Returns the current full URL based on the Config\App settings and IncomingRequest. * String returns ignore query and fragment parts. * * @param bool $returnObject True to return an object instead of a string diff --git a/user_guide_src/source/helpers/url_helper.rst b/user_guide_src/source/helpers/url_helper.rst index 37374890548e..8f0252c27cff 100644 --- a/user_guide_src/source/helpers/url_helper.rst +++ b/user_guide_src/source/helpers/url_helper.rst @@ -88,8 +88,9 @@ The following functions are available: :returns: The current URL :rtype: string|\\CodeIgniter\\HTTP\\URI - Returns the full URL (including segments) of the page being currently - viewed. + Returns the full URL (including segments) of the page being currently viewed. + However for security reasons, it is created based on the ``Config\App`` settings, + and not intended to match the browser URL. .. note:: Calling this function is the same as doing this: From 5b528af01f1a2b478454ff10c528c1aaecd54252 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 6 Mar 2022 14:38:42 +0900 Subject: [PATCH 0702/1246] fix: now initEnvValue() converts type when the default property value is int and float --- system/Config/BaseConfig.php | 22 ++++++++++++++----- tests/system/Config/BaseConfigTest.php | 19 ++++++++++++++++ tests/system/Config/fixtures/.env | 5 +++++ tests/system/Config/fixtures/SimpleConfig.php | 3 +++ 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/system/Config/BaseConfig.php b/system/Config/BaseConfig.php index 9b71a4963bab..359fcc1488ba 100644 --- a/system/Config/BaseConfig.php +++ b/system/Config/BaseConfig.php @@ -88,7 +88,7 @@ public function __construct() * * @param mixed $property * - * @return mixed + * @return void */ protected function initEnvValue(&$property, string $name, string $prefix, string $shortPrefix) { @@ -102,16 +102,28 @@ protected function initEnvValue(&$property, string $name, string $prefix, string } elseif ($value === 'true') { $value = true; } - $property = is_bool($value) ? $value : trim($value, '\'"'); - } + if (is_bool($value)) { + $property = $value; + + return; + } + + $value = trim($value, '\'"'); - return $property; + if (is_int($property)) { + $value = (int) $value; + } elseif (is_float($property)) { + $value = (float) $value; + } + + $property = $value; + } } /** * Retrieve an environment-specific configuration setting * - * @return mixed + * @return string|null */ protected function getEnvValue(string $property, string $prefix, string $shortPrefix) { diff --git a/tests/system/Config/BaseConfigTest.php b/tests/system/Config/BaseConfigTest.php index 4c2d4ba20ccb..667a877287fb 100644 --- a/tests/system/Config/BaseConfigTest.php +++ b/tests/system/Config/BaseConfigTest.php @@ -55,6 +55,25 @@ public function testBasicValues() $this->assertSame(18, $config->golf); } + public function testUseDefaultValueTypeIntAndFloatValues() + { + $dotenv = new DotEnv($this->fixturesFolder, '.env'); + $dotenv->load(); + $config = new SimpleConfig(); + + $this->assertSame(0.0, $config->float); + $this->assertSame(999, $config->int); + } + + public function testUseDefaultValueTypeStringValue() + { + $dotenv = new DotEnv($this->fixturesFolder, '.env'); + $dotenv->load(); + $config = new SimpleConfig(); + + $this->assertSame('123456', $config->password); + } + /** * @runInSeparateProcess * @preserveGlobalState disabled diff --git a/tests/system/Config/fixtures/.env b/tests/system/Config/fixtures/.env index 2f859cc9faca..38ca0bed6f0b 100644 --- a/tests/system/Config/fixtures/.env +++ b/tests/system/Config/fixtures/.env @@ -32,3 +32,8 @@ SimpleConfig.crew.captain = Malcolm SimpleConfig.crew.pilot = Wash SimpleConfig.crew.comms = true SimpleConfig.crew.doctor = false + +SimpleConfig.float = '0.0' +SimpleConfig.int = '999' + +SimpleConfig.password = 123456 diff --git a/tests/system/Config/fixtures/SimpleConfig.php b/tests/system/Config/fixtures/SimpleConfig.php index 69f5590e90f1..d64aa1a0d741 100644 --- a/tests/system/Config/fixtures/SimpleConfig.php +++ b/tests/system/Config/fixtures/SimpleConfig.php @@ -48,4 +48,7 @@ class SimpleConfig extends \CodeIgniter\Config\BaseConfig public $one_deep = [ 'under_deep' => null, ]; + public $float = 12.34; + public $int = 1234; + public $password = 'secret'; } From 8524bb963bd79bd3be676fa21ab82b8c98b6a412 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 18 Mar 2022 16:08:22 +0900 Subject: [PATCH 0703/1246] test: add test for nullable int property --- tests/system/Config/BaseConfigTest.php | 3 +++ tests/system/Config/fixtures/.env | 2 ++ tests/system/Config/fixtures/SimpleConfig.php | 7 ++++--- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/system/Config/BaseConfigTest.php b/tests/system/Config/BaseConfigTest.php index 667a877287fb..20d2f77c8421 100644 --- a/tests/system/Config/BaseConfigTest.php +++ b/tests/system/Config/BaseConfigTest.php @@ -117,6 +117,9 @@ public function testEnvironmentOverrides() $this->assertSame('bar', $config->onedeep_value); // array property name with underscore and key with underscore $this->assertSame('foo', $config->one_deep['under_deep']); + + // The default property value is null but has type + $this->assertSame(20, $config->size); } public function testPrefixedValues() diff --git a/tests/system/Config/fixtures/.env b/tests/system/Config/fixtures/.env index 38ca0bed6f0b..36f5651cf532 100644 --- a/tests/system/Config/fixtures/.env +++ b/tests/system/Config/fixtures/.env @@ -37,3 +37,5 @@ SimpleConfig.float = '0.0' SimpleConfig.int = '999' SimpleConfig.password = 123456 + +SimpleConfig.size=20 diff --git a/tests/system/Config/fixtures/SimpleConfig.php b/tests/system/Config/fixtures/SimpleConfig.php index d64aa1a0d741..9870c72b0ac2 100644 --- a/tests/system/Config/fixtures/SimpleConfig.php +++ b/tests/system/Config/fixtures/SimpleConfig.php @@ -48,7 +48,8 @@ class SimpleConfig extends \CodeIgniter\Config\BaseConfig public $one_deep = [ 'under_deep' => null, ]; - public $float = 12.34; - public $int = 1234; - public $password = 'secret'; + public $float = 12.34; + public $int = 1234; + public $password = 'secret'; + public ?int $size = null; } From 2609cc949c1fdb05f585f2211c12e8b9ca8c3887 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 18 Mar 2022 17:30:31 +0900 Subject: [PATCH 0704/1246] docs: add note about `attributes` --- user_guide_src/source/models/entities.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/user_guide_src/source/models/entities.rst b/user_guide_src/source/models/entities.rst index a1941fb31d97..d2c99c8623b6 100644 --- a/user_guide_src/source/models/entities.rst +++ b/user_guide_src/source/models/entities.rst @@ -31,6 +31,8 @@ Assume you have a database table named ``users`` that has the following schema:: password - string created_at - datetime +.. important:: ``attributes`` is a reserved word for internal use. If you use it as a column name, the Entity does not work correctly. + Create the Entity Class ----------------------- From d61b3c7487f2168f38b6f01ea2398b409d7c2523 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 19 Mar 2022 10:11:18 +0900 Subject: [PATCH 0705/1246] test: change .env entry Do not recommend to use `'` for int/float value. --- tests/system/Config/fixtures/.env | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/system/Config/fixtures/.env b/tests/system/Config/fixtures/.env index 36f5651cf532..17d9e8e9116e 100644 --- a/tests/system/Config/fixtures/.env +++ b/tests/system/Config/fixtures/.env @@ -33,9 +33,12 @@ SimpleConfig.crew.pilot = Wash SimpleConfig.crew.comms = true SimpleConfig.crew.doctor = false -SimpleConfig.float = '0.0' -SimpleConfig.int = '999' +# The default value's type in the Config class is float, so it will be converted to float +SimpleConfig.float = 0.0 +# The default value's type in the Config class is int, so it will be converted to int +SimpleConfig.int = 999 SimpleConfig.password = 123456 +# The property type in the Config class is ?int, so it will be converted to int by PHP SimpleConfig.size=20 From 4f97aac34420631753a936c2b7decd7f17cb68c0 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sat, 19 Mar 2022 22:52:14 +0700 Subject: [PATCH 0706/1246] [Rector] Clean up skip config and re-run Rector --- app/Config/App.php | 3 +- app/Config/Database.php | 3 +- app/Config/Format.php | 8 +++-- app/Config/Logger.php | 3 +- rector.php | 16 +++++++--- system/Cache/Handlers/PredisHandler.php | 2 +- system/CodeIgniter.php | 2 +- system/Commands/Database/CreateDatabase.php | 3 +- .../Generators/ControllerGenerator.php | 9 ++++-- system/Config/AutoloadConfig.php | 28 +++++++++++------ system/Config/BaseService.php | 4 +-- system/Database/BaseConnection.php | 2 +- system/Database/BasePreparedQuery.php | 2 +- system/Database/BaseResult.php | 3 +- system/Database/MySQLi/Result.php | 2 +- system/Database/OCI8/Result.php | 2 +- system/Database/Postgre/Result.php | 2 +- system/Database/SQLSRV/Result.php | 2 +- system/Database/SQLite3/Connection.php | 2 +- system/Database/SQLite3/Result.php | 4 +-- system/Images/Handlers/ImageMagickHandler.php | 2 +- system/Language/Language.php | 2 +- system/Test/Fabricator.php | 3 +- system/Test/Mock/MockResult.php | 3 +- system/View/View.php | 3 +- tests/system/API/ResponseTraitTest.php | 8 ++--- tests/system/Autoloader/AutoloaderTest.php | 11 +++---- tests/system/Autoloader/FileLocatorTest.php | 5 +-- tests/system/CLI/CLITest.php | 5 +-- tests/system/Cache/CacheFactoryTest.php | 9 +++--- .../system/Cache/Handlers/BaseHandlerTest.php | 5 +-- .../system/Cache/Handlers/FileHandlerTest.php | 3 +- tests/system/CodeIgniterTest.php | 9 ++---- tests/system/CommonFunctionsTest.php | 2 +- tests/system/Config/DotEnvTest.php | 5 +-- tests/system/Config/ServicesTest.php | 3 +- tests/system/Database/Builder/InsertTest.php | 7 +++-- tests/system/Database/Builder/ReplaceTest.php | 3 +- tests/system/Database/Builder/UpdateTest.php | 9 +++--- tests/system/Database/ConfigTest.php | 13 ++++---- tests/system/Database/DatabaseSeederTest.php | 7 +++-- tests/system/Database/Live/DbUtilsTest.php | 5 +-- tests/system/Database/Live/DeleteTest.php | 2 +- tests/system/Database/Live/ForgeTest.php | 31 ++++++++++--------- tests/system/Database/Live/GetTest.php | 5 +-- .../Database/Live/SQLite/AlterTableTest.php | 16 ++++------ .../Migrations/MigrationRunnerTest.php | 5 +-- tests/system/Encryption/EncryptionTest.php | 14 ++++----- .../Handlers/OpenSSLHandlerTest.php | 12 +++---- .../Encryption/Handlers/SodiumHandlerTest.php | 24 ++++++-------- tests/system/Entity/EntityTest.php | 2 +- tests/system/Files/FileTest.php | 3 +- tests/system/Format/FormatTest.php | 8 ++--- tests/system/Format/JSONFormatterTest.php | 3 +- .../HTTP/CURLRequestDoNotShareOptionsTest.php | 7 ++--- tests/system/HTTP/CURLRequestTest.php | 7 ++--- tests/system/Helpers/ArrayHelperTest.php | 6 ++-- tests/system/HomeTest.php | 3 +- tests/system/Honeypot/HoneypotTest.php | 4 +-- tests/system/I18n/TimeTest.php | 22 ++++++------- tests/system/Language/LanguageTest.php | 5 +-- tests/system/Models/FindModelTest.php | 3 +- .../system/RESTful/ResourceControllerTest.php | 10 +++--- .../system/RESTful/ResourcePresenterTest.php | 18 +++++------ .../Session/Handlers/DatabaseHandlerTest.php | 2 +- tests/system/Session/SessionTest.php | 2 +- tests/system/Test/FabricatorTest.php | 8 ++--- tests/system/Test/FilterTestTraitTest.php | 6 ++-- tests/system/View/CellTest.php | 9 ++---- 69 files changed, 235 insertions(+), 226 deletions(-) diff --git a/app/Config/App.php b/app/Config/App.php index 7ab0c7d7cfcb..c6c716822756 100644 --- a/app/Config/App.php +++ b/app/Config/App.php @@ -3,6 +3,7 @@ namespace Config; use CodeIgniter\Config\BaseConfig; +use CodeIgniter\Session\Handlers\FileHandler; class App extends BaseConfig { @@ -151,7 +152,7 @@ class App extends BaseConfig * * @var string */ - public $sessionDriver = 'CodeIgniter\Session\Handlers\FileHandler'; + public $sessionDriver = FileHandler::class; /** * -------------------------------------------------------------------------- diff --git a/app/Config/Database.php b/app/Config/Database.php index 1e6340899bf4..376de53a821d 100644 --- a/app/Config/Database.php +++ b/app/Config/Database.php @@ -3,6 +3,7 @@ namespace Config; use CodeIgniter\Database\Config; +use SQLite3; /** * Database Configuration @@ -62,7 +63,7 @@ class Database extends Config 'username' => '', 'password' => '', 'database' => ':memory:', - 'DBDriver' => 'SQLite3', + 'DBDriver' => SQLite3::class, 'DBPrefix' => 'db_', // Needed to ensure we're working correctly with prefixes live. DO NOT REMOVE FOR CI DEVS 'pConnect' => false, 'DBDebug' => (ENVIRONMENT !== 'production'), diff --git a/app/Config/Format.php b/app/Config/Format.php index 533540e27918..d89e40842c22 100644 --- a/app/Config/Format.php +++ b/app/Config/Format.php @@ -4,6 +4,8 @@ use CodeIgniter\Config\BaseConfig; use CodeIgniter\Format\FormatterInterface; +use CodeIgniter\Format\JSONFormatter; +use CodeIgniter\Format\XMLFormatter; class Format extends BaseConfig { @@ -40,9 +42,9 @@ class Format extends BaseConfig * @var array */ public $formatters = [ - 'application/json' => 'CodeIgniter\Format\JSONFormatter', - 'application/xml' => 'CodeIgniter\Format\XMLFormatter', - 'text/xml' => 'CodeIgniter\Format\XMLFormatter', + 'application/json' => JSONFormatter::class, + 'application/xml' => XMLFormatter::class, + 'text/xml' => XMLFormatter::class, ]; /** diff --git a/app/Config/Logger.php b/app/Config/Logger.php index a4eaeb648955..406d9aaccc85 100644 --- a/app/Config/Logger.php +++ b/app/Config/Logger.php @@ -2,6 +2,7 @@ namespace Config; +use CodeIgniter\Log\Handlers\FileHandler; use CodeIgniter\Config\BaseConfig; class Logger extends BaseConfig @@ -83,7 +84,7 @@ class Logger extends BaseConfig * File Handler * -------------------------------------------------------------------- */ - 'CodeIgniter\Log\Handlers\FileHandler' => [ + FileHandler::class => [ // The log levels that this handler will handle. 'handles' => [ diff --git a/rector.php b/rector.php index b90225d80fcf..6c2bc99bcf8d 100644 --- a/rector.php +++ b/rector.php @@ -84,8 +84,6 @@ RemoveUnusedPrivateMethodRector::class => [ // private method called via getPrivateMethodInvoker __DIR__ . '/tests/system/Test/ReflectionHelperTest.php', - // Rector bug? - __DIR__ . '/system/CodeIgniter.php', ], // call on purpose for nothing happen check @@ -103,9 +101,17 @@ __DIR__ . '/system/Session/Handlers', ], - // may cause load view files directly when detecting class that - // make warning - StringClassNameToClassConstantRector::class, + StringClassNameToClassConstantRector::class => [ + // may cause load view files directly when detecting namespaced string + // due to internal PHPStan issue + __DIR__ . '/app/Config/Pager.php', + __DIR__ . '/app/Config/Validation.php', + __DIR__ . '/tests/system/Validation/StrictRules/ValidationTest.php', + __DIR__ . '/tests/system/Validation/ValidationTest.php', + + // expected Qualified name + __DIR__ . '/tests/system/Autoloader/FileLocatorTest.php', + ], // sometime too detail CountOnNullRector::class, diff --git a/system/Cache/Handlers/PredisHandler.php b/system/Cache/Handlers/PredisHandler.php index 5d1f37cdfc24..87ab4e333dca 100644 --- a/system/Cache/Handlers/PredisHandler.php +++ b/system/Cache/Handlers/PredisHandler.php @@ -222,6 +222,6 @@ public function getMetaData(string $key) */ public function isSupported(): bool { - return class_exists('Predis\Client'); + return class_exists(Client::class); } } diff --git a/system/CodeIgniter.php b/system/CodeIgniter.php index 86e70546dd41..127e087458a0 100644 --- a/system/CodeIgniter.php +++ b/system/CodeIgniter.php @@ -830,7 +830,7 @@ protected function startController() $this->benchmark->start('controller_constructor'); // Is it routed to a Closure? - if (is_object($this->controller) && (get_class($this->controller) === 'Closure')) { + if (is_object($this->controller) && (get_class($this->controller) === Closure::class)) { $controller = $this->controller; return $controller(...$this->router->params()); diff --git a/system/Commands/Database/CreateDatabase.php b/system/Commands/Database/CreateDatabase.php index 17e1e51bb68b..0682f945b9bf 100644 --- a/system/Commands/Database/CreateDatabase.php +++ b/system/Commands/Database/CreateDatabase.php @@ -16,6 +16,7 @@ use CodeIgniter\Config\Factories; use CodeIgniter\Database\SQLite3\Connection; use Config\Database; +use SQLite3; use Throwable; /** @@ -106,7 +107,7 @@ public function run(array $params) $name = str_replace(['.db', '.sqlite'], '', $name) . ".{$ext}"; } - $config->{$group}['DBDriver'] = 'SQLite3'; + $config->{$group}['DBDriver'] = SQLite3::class; $config->{$group}['database'] = $name; if ($name !== ':memory:') { diff --git a/system/Commands/Generators/ControllerGenerator.php b/system/Commands/Generators/ControllerGenerator.php index 36a951cf0df0..f27c77ee0fe5 100644 --- a/system/Commands/Generators/ControllerGenerator.php +++ b/system/Commands/Generators/ControllerGenerator.php @@ -14,6 +14,9 @@ use CodeIgniter\CLI\BaseCommand; use CodeIgniter\CLI\CLI; use CodeIgniter\CLI\GeneratorTrait; +use CodeIgniter\Controller; +use CodeIgniter\RESTful\ResourceController; +use CodeIgniter\RESTful\ResourcePresenter; /** * Generates a skeleton controller file. @@ -99,7 +102,7 @@ protected function prepare(string $class): string // Gets the appropriate parent class to extend. if ($bare || $rest) { if ($bare) { - $useStatement = 'CodeIgniter\Controller'; + $useStatement = Controller::class; $extends = 'Controller'; } elseif ($rest) { $rest = is_string($rest) ? $rest : 'controller'; @@ -112,10 +115,10 @@ protected function prepare(string $class): string } if ($rest === 'controller') { - $useStatement = 'CodeIgniter\RESTful\ResourceController'; + $useStatement = ResourceController::class; $extends = 'ResourceController'; } elseif ($rest === 'presenter') { - $useStatement = 'CodeIgniter\RESTful\ResourcePresenter'; + $useStatement = ResourcePresenter::class; $extends = 'ResourcePresenter'; } } diff --git a/system/Config/AutoloadConfig.php b/system/Config/AutoloadConfig.php index d3dbefcd7c3c..13a6721fd2e6 100644 --- a/system/Config/AutoloadConfig.php +++ b/system/Config/AutoloadConfig.php @@ -11,6 +11,16 @@ namespace CodeIgniter\Config; +use Laminas\Escaper\Escaper; +use Psr\Log\AbstractLogger; +use Psr\Log\InvalidArgumentException; +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerAwareTrait; +use Psr\Log\LoggerInterface; +use Psr\Log\LoggerTrait; +use Psr\Log\LogLevel; +use Psr\Log\NullLogger; + /** * AUTOLOADER CONFIGURATION * @@ -93,15 +103,15 @@ class AutoloadConfig * @var array */ protected $coreClassmap = [ - 'Psr\Log\AbstractLogger' => SYSTEMPATH . 'ThirdParty/PSR/Log/AbstractLogger.php', - 'Psr\Log\InvalidArgumentException' => SYSTEMPATH . 'ThirdParty/PSR/Log/InvalidArgumentException.php', - 'Psr\Log\LoggerAwareInterface' => SYSTEMPATH . 'ThirdParty/PSR/Log/LoggerAwareInterface.php', - 'Psr\Log\LoggerAwareTrait' => SYSTEMPATH . 'ThirdParty/PSR/Log/LoggerAwareTrait.php', - 'Psr\Log\LoggerInterface' => SYSTEMPATH . 'ThirdParty/PSR/Log/LoggerInterface.php', - 'Psr\Log\LoggerTrait' => SYSTEMPATH . 'ThirdParty/PSR/Log/LoggerTrait.php', - 'Psr\Log\LogLevel' => SYSTEMPATH . 'ThirdParty/PSR/Log/LogLevel.php', - 'Psr\Log\NullLogger' => SYSTEMPATH . 'ThirdParty/PSR/Log/NullLogger.php', - 'Laminas\Escaper\Escaper' => SYSTEMPATH . 'ThirdParty/Escaper/Escaper.php', + AbstractLogger::class => SYSTEMPATH . 'ThirdParty/PSR/Log/AbstractLogger.php', + InvalidArgumentException::class => SYSTEMPATH . 'ThirdParty/PSR/Log/InvalidArgumentException.php', + LoggerAwareInterface::class => SYSTEMPATH . 'ThirdParty/PSR/Log/LoggerAwareInterface.php', + LoggerAwareTrait::class => SYSTEMPATH . 'ThirdParty/PSR/Log/LoggerAwareTrait.php', + LoggerInterface::class => SYSTEMPATH . 'ThirdParty/PSR/Log/LoggerInterface.php', + LoggerTrait::class => SYSTEMPATH . 'ThirdParty/PSR/Log/LoggerTrait.php', + LogLevel::class => SYSTEMPATH . 'ThirdParty/PSR/Log/LogLevel.php', + NullLogger::class => SYSTEMPATH . 'ThirdParty/PSR/Log/NullLogger.php', + Escaper::class => SYSTEMPATH . 'ThirdParty/Escaper/Escaper.php', ]; /** diff --git a/system/Config/BaseService.php b/system/Config/BaseService.php index 572b6cf576bd..4244b7a7097d 100644 --- a/system/Config/BaseService.php +++ b/system/Config/BaseService.php @@ -332,7 +332,7 @@ protected static function discoverServices(string $name, array $arguments) foreach ($files as $file) { $classname = $locator->getClassname($file); - if (! in_array($classname, ['CodeIgniter\\Config\\Services'], true)) { + if (! in_array($classname, [\CodeIgniter\Config\Services::class], true)) { static::$services[] = new $classname(); } } @@ -369,7 +369,7 @@ protected static function buildServicesCache(): void foreach ($files as $file) { $classname = $locator->getClassname($file); - if ($classname !== 'CodeIgniter\\Config\\Services') { + if ($classname !== \CodeIgniter\Config\Services::class) { self::$serviceNames[] = $classname; static::$services[] = new $classname(); } diff --git a/system/Database/BaseConnection.php b/system/Database/BaseConnection.php index 4f54c1980830..d2ce3fdd390a 100644 --- a/system/Database/BaseConnection.php +++ b/system/Database/BaseConnection.php @@ -326,7 +326,7 @@ abstract class BaseConnection implements ConnectionInterface * * @var string */ - protected $queryClass = 'CodeIgniter\\Database\\Query'; + protected $queryClass = Query::class; /** * Saves our connection settings. diff --git a/system/Database/BasePreparedQuery.php b/system/Database/BasePreparedQuery.php index b6e2db706d2a..ce5a208a1ef3 100644 --- a/system/Database/BasePreparedQuery.php +++ b/system/Database/BasePreparedQuery.php @@ -69,7 +69,7 @@ public function __construct(BaseConnection $db) * * @return mixed */ - public function prepare(string $sql, array $options = [], string $queryClass = 'CodeIgniter\\Database\\Query') + public function prepare(string $sql, array $options = [], string $queryClass = Query::class) { // We only supports positional placeholders (?) // in order to work with the execute method below, so we diff --git a/system/Database/BaseResult.php b/system/Database/BaseResult.php index 5d223c7fc08b..b5818525dc30 100644 --- a/system/Database/BaseResult.php +++ b/system/Database/BaseResult.php @@ -12,6 +12,7 @@ namespace CodeIgniter\Database; use CodeIgniter\Entity\Entity; +use stdClass; /** * Class BaseResult @@ -508,5 +509,5 @@ abstract protected function fetchAssoc(); * * @return object */ - abstract protected function fetchObject(string $className = 'stdClass'); + abstract protected function fetchObject(string $className = stdClass::class); } diff --git a/system/Database/MySQLi/Result.php b/system/Database/MySQLi/Result.php index 7eab7d86c685..35f480776c85 100644 --- a/system/Database/MySQLi/Result.php +++ b/system/Database/MySQLi/Result.php @@ -139,7 +139,7 @@ protected function fetchAssoc() * * @return bool|Entity|object */ - protected function fetchObject(string $className = 'stdClass') + protected function fetchObject(string $className = stdClass::class) { if (is_subclass_of($className, Entity::class)) { return empty($data = $this->fetchAssoc()) ? false : (new $className())->setAttributes($data); diff --git a/system/Database/OCI8/Result.php b/system/Database/OCI8/Result.php index ce3a73def1c4..6ad26b649480 100644 --- a/system/Database/OCI8/Result.php +++ b/system/Database/OCI8/Result.php @@ -98,7 +98,7 @@ protected function fetchObject(string $className = stdClass::class) { $row = oci_fetch_object($this->resultID); - if ($className === 'stdClass' || ! $row) { + if ($className === stdClass::class || ! $row) { return $row; } if (is_subclass_of($className, Entity::class)) { diff --git a/system/Database/Postgre/Result.php b/system/Database/Postgre/Result.php index 76a0dd956515..581d79b1d421 100644 --- a/system/Database/Postgre/Result.php +++ b/system/Database/Postgre/Result.php @@ -105,7 +105,7 @@ protected function fetchAssoc() * * @return bool|Entity|object */ - protected function fetchObject(string $className = 'stdClass') + protected function fetchObject(string $className = stdClass::class) { if (is_subclass_of($className, Entity::class)) { return empty($data = $this->fetchAssoc()) ? false : (new $className())->setAttributes($data); diff --git a/system/Database/SQLSRV/Result.php b/system/Database/SQLSRV/Result.php index 2a55e452ac09..045a5eebd81a 100755 --- a/system/Database/SQLSRV/Result.php +++ b/system/Database/SQLSRV/Result.php @@ -147,7 +147,7 @@ protected function fetchAssoc() * * @return bool|Entity|object */ - protected function fetchObject(string $className = 'stdClass') + protected function fetchObject(string $className = stdClass::class) { if (is_subclass_of($className, Entity::class)) { return empty($data = $this->fetchAssoc()) ? false : (new $className())->setAttributes($data); diff --git a/system/Database/SQLite3/Connection.php b/system/Database/SQLite3/Connection.php index 39fbca8bcfea..e335e7985ba7 100644 --- a/system/Database/SQLite3/Connection.php +++ b/system/Database/SQLite3/Connection.php @@ -28,7 +28,7 @@ class Connection extends BaseConnection * * @var string */ - public $DBDriver = 'SQLite3'; + public $DBDriver = SQLite3::class; /** * Identifier escape character diff --git a/system/Database/SQLite3/Result.php b/system/Database/SQLite3/Result.php index 6afc04c51578..39b9897af1e4 100644 --- a/system/Database/SQLite3/Result.php +++ b/system/Database/SQLite3/Result.php @@ -122,14 +122,14 @@ protected function fetchAssoc() * * @return bool|object */ - protected function fetchObject(string $className = 'stdClass') + protected function fetchObject(string $className = stdClass::class) { // No native support for fetching rows as objects if (($row = $this->fetchAssoc()) === false) { return false; } - if ($className === 'stdClass') { + if ($className === stdClass::class) { return (object) $row; } diff --git a/system/Images/Handlers/ImageMagickHandler.php b/system/Images/Handlers/ImageMagickHandler.php index 37bd168ead02..5e0bafe00841 100644 --- a/system/Images/Handlers/ImageMagickHandler.php +++ b/system/Images/Handlers/ImageMagickHandler.php @@ -49,7 +49,7 @@ public function __construct($config = null) // We should never see this, so can't test it // @codeCoverageIgnoreStart - if (! (extension_loaded('imagick') || class_exists('Imagick'))) { + if (! (extension_loaded('imagick') || class_exists(Imagick::class))) { throw ImageException::forMissingExtension('IMAGICK'); } // @codeCoverageIgnoreEnd diff --git a/system/Language/Language.php b/system/Language/Language.php index 299618657aa2..640dcfaa552d 100644 --- a/system/Language/Language.php +++ b/system/Language/Language.php @@ -57,7 +57,7 @@ public function __construct(string $locale) { $this->locale = $locale; - if (class_exists('MessageFormatter')) { + if (class_exists(MessageFormatter::class)) { $this->intlSupport = true; } } diff --git a/system/Test/Fabricator.php b/system/Test/Fabricator.php index d4369765f0ee..d474e796df78 100644 --- a/system/Test/Fabricator.php +++ b/system/Test/Fabricator.php @@ -17,6 +17,7 @@ use Faker\Generator; use InvalidArgumentException; use RuntimeException; +use stdClass; /** * Fabricator @@ -409,7 +410,7 @@ public function makeObject(?string $className = null): object { if ($className === null) { if ($this->model->returnType === 'object' || $this->model->returnType === 'array') { - $className = 'stdClass'; + $className = stdClass::class; } else { $className = $this->model->returnType; } diff --git a/system/Test/Mock/MockResult.php b/system/Test/Mock/MockResult.php index 0aaa340a95de..f3807d9170c9 100644 --- a/system/Test/Mock/MockResult.php +++ b/system/Test/Mock/MockResult.php @@ -12,6 +12,7 @@ namespace CodeIgniter\Test\Mock; use CodeIgniter\Database\BaseResult; +use stdClass; class MockResult extends BaseResult { @@ -81,7 +82,7 @@ protected function fetchAssoc() * * @return object */ - protected function fetchObject($className = 'stdClass') + protected function fetchObject($className = stdClass::class) { return new $className(); } diff --git a/system/View/View.php b/system/View/View.php index f557b6629b0a..b0206d67caba 100644 --- a/system/View/View.php +++ b/system/View/View.php @@ -13,6 +13,7 @@ use CodeIgniter\Autoloader\FileLocator; use CodeIgniter\Debug\Toolbar\Collectors\Views; +use CodeIgniter\Filters\DebugToolbar; use CodeIgniter\View\Exceptions\ViewException; use Config\Services; use Config\Toolbar; @@ -235,7 +236,7 @@ public function render(string $view, ?array $options = null, ?bool $saveData = n $this->logPerformance($this->renderVars['start'], microtime(true), $this->renderVars['view']); if (($this->debug && (! isset($options['debug']) || $options['debug'] === true)) - && in_array('CodeIgniter\Filters\DebugToolbar', service('filters')->getFiltersClass()['after'], true) + && in_array(DebugToolbar::class, service('filters')->getFiltersClass()['after'], true) ) { $toolbarCollectors = config(Toolbar::class)->collectors; diff --git a/tests/system/API/ResponseTraitTest.php b/tests/system/API/ResponseTraitTest.php index 8cf06372dcdd..821e217a35b8 100644 --- a/tests/system/API/ResponseTraitTest.php +++ b/tests/system/API/ResponseTraitTest.php @@ -29,11 +29,7 @@ final class ResponseTraitTest extends CIUnitTestCase { protected $request; protected $response; - - /** - * @var FormatterInterface|null - */ - protected $formatter; + protected ?FormatterInterface $formatter = null; protected function setUp(): void { @@ -505,7 +501,7 @@ public function testXMLFormatter() $this->formatter = new XMLFormatter(); $controller = $this->makeController(); - $this->assertInstanceOf('CodeIgniter\Format\XMLFormatter', $this->formatter); + $this->assertInstanceOf(XMLFormatter::class, $this->formatter); $this->invoke($controller, 'respondCreated', [['id' => 3], 'A Custom Reason']); diff --git a/tests/system/Autoloader/AutoloaderTest.php b/tests/system/Autoloader/AutoloaderTest.php index 3c7156abdde2..95d74c6c1b7e 100644 --- a/tests/system/Autoloader/AutoloaderTest.php +++ b/tests/system/Autoloader/AutoloaderTest.php @@ -15,6 +15,7 @@ use Config\Autoload; use Config\Modules; use Config\Services; +use InvalidArgumentException; use UnnamespacedClass; /** @@ -22,12 +23,8 @@ */ final class AutoloaderTest extends CIUnitTestCase { - /** - * @var Autoloader - */ - protected $loader; - - protected $filesPath = SUPPORTPATH . 'Autoloader/'; + protected Autoloader $loader; + protected string $filesPath = SUPPORTPATH . 'Autoloader/'; protected function setUp(): void { @@ -58,7 +55,7 @@ public function testLoadStoredClass() public function testInitializeWithInvalidArguments() { - $this->expectException('InvalidArgumentException'); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage("Config array must contain either the 'psr4' key or the 'classmap' key."); $config = new Autoload(); diff --git a/tests/system/Autoloader/FileLocatorTest.php b/tests/system/Autoloader/FileLocatorTest.php index 3a40ed24345b..54a471d74453 100644 --- a/tests/system/Autoloader/FileLocatorTest.php +++ b/tests/system/Autoloader/FileLocatorTest.php @@ -20,10 +20,7 @@ */ final class FileLocatorTest extends CIUnitTestCase { - /** - * @var FileLocator - */ - protected $locator; + protected FileLocator $locator; protected function setUp(): void { diff --git a/tests/system/CLI/CLITest.php b/tests/system/CLI/CLITest.php index 68008ccc1e4d..107ac1463e67 100644 --- a/tests/system/CLI/CLITest.php +++ b/tests/system/CLI/CLITest.php @@ -14,6 +14,7 @@ use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\Filters\CITestStreamFilter; use ReflectionProperty; +use RuntimeException; /** * @internal @@ -100,7 +101,7 @@ public function testNewLine() public function testColorExceptionForeground() { - $this->expectException('RuntimeException'); + $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Invalid foreground color: Foreground'); CLI::color('test', 'Foreground'); @@ -108,7 +109,7 @@ public function testColorExceptionForeground() public function testColorExceptionBackground() { - $this->expectException('RuntimeException'); + $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Invalid background color: Background'); CLI::color('test', 'white', 'Background'); diff --git a/tests/system/Cache/CacheFactoryTest.php b/tests/system/Cache/CacheFactoryTest.php index c67d1c805ad0..45bc16df58e8 100644 --- a/tests/system/Cache/CacheFactoryTest.php +++ b/tests/system/Cache/CacheFactoryTest.php @@ -11,6 +11,7 @@ namespace CodeIgniter\Cache; +use CodeIgniter\Cache\Exceptions\CacheException; use CodeIgniter\Cache\Handlers\DummyHandler; use CodeIgniter\Test\CIUnitTestCase; use Config\Cache; @@ -50,7 +51,7 @@ public function testNew() public function testGetHandlerExceptionCacheInvalidHandlers() { - $this->expectException('CodeIgniter\Cache\Exceptions\CacheException'); + $this->expectException(CacheException::class); $this->expectExceptionMessage('Cache config must have an array of $validHandlers.'); $this->config->validHandlers = null; @@ -60,7 +61,7 @@ public function testGetHandlerExceptionCacheInvalidHandlers() public function testGetHandlerExceptionCacheNoBackup() { - $this->expectException('CodeIgniter\Cache\Exceptions\CacheException'); + $this->expectException(CacheException::class); $this->expectExceptionMessage('Cache config must have a handler and backupHandler set.'); $this->config->backupHandler = null; @@ -70,7 +71,7 @@ public function testGetHandlerExceptionCacheNoBackup() public function testGetHandlerExceptionCacheNoHandler() { - $this->expectException('CodeIgniter\Cache\Exceptions\CacheException'); + $this->expectException(CacheException::class); $this->expectExceptionMessage('Cache config must have a handler and backupHandler set.'); $this->config->handler = null; @@ -80,7 +81,7 @@ public function testGetHandlerExceptionCacheNoHandler() public function testGetHandlerExceptionCacheHandlerNotFound() { - $this->expectException('CodeIgniter\Cache\Exceptions\CacheException'); + $this->expectException(CacheException::class); $this->expectExceptionMessage('Cache config has an invalid handler or backup handler specified.'); unset($this->config->validHandlers[$this->config->handler]); diff --git a/tests/system/Cache/Handlers/BaseHandlerTest.php b/tests/system/Cache/Handlers/BaseHandlerTest.php index b2ebb61e01ef..18bfcff0d113 100644 --- a/tests/system/Cache/Handlers/BaseHandlerTest.php +++ b/tests/system/Cache/Handlers/BaseHandlerTest.php @@ -12,6 +12,7 @@ namespace CodeIgniter\Cache\Handlers; use CodeIgniter\Test\CIUnitTestCase; +use InvalidArgumentException; use stdClass; use Tests\Support\Cache\RestrictiveHandler; @@ -27,7 +28,7 @@ final class BaseHandlerTest extends CIUnitTestCase */ public function testValidateKeyInvalidType($input) { - $this->expectException('InvalidArgumentException'); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Cache key must be a string'); BaseHandler::validateKey($input); @@ -48,7 +49,7 @@ public function testValidateKeyUsesConfig() { config('Cache')->reservedCharacters = 'b'; - $this->expectException('InvalidArgumentException'); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Cache key contains reserved characters b'); BaseHandler::validateKey('banana'); diff --git a/tests/system/Cache/Handlers/FileHandlerTest.php b/tests/system/Cache/Handlers/FileHandlerTest.php index 032243d890f1..23573dee3314 100644 --- a/tests/system/Cache/Handlers/FileHandlerTest.php +++ b/tests/system/Cache/Handlers/FileHandlerTest.php @@ -11,6 +11,7 @@ namespace CodeIgniter\Cache\Handlers; +use CodeIgniter\Cache\Exceptions\CacheException; use CodeIgniter\CLI\CLI; use Config\Cache; @@ -76,7 +77,7 @@ public function testNew() public function testNewWithNonWritablePath() { - $this->expectException('CodeIgniter\Cache\Exceptions\CacheException'); + $this->expectException(CacheException::class); chmod($this->config->file['storePath'], 0444); new FileHandler($this->config); diff --git a/tests/system/CodeIgniterTest.php b/tests/system/CodeIgniterTest.php index 418bde4530f6..42706e39d110 100644 --- a/tests/system/CodeIgniterTest.php +++ b/tests/system/CodeIgniterTest.php @@ -12,6 +12,7 @@ namespace CodeIgniter; use CodeIgniter\Config\Services; +use CodeIgniter\HTTP\Response; use CodeIgniter\Router\RouteCollection; use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\Mock\MockCodeIgniter; @@ -26,11 +27,7 @@ */ final class CodeIgniterTest extends CIUnitTestCase { - /** - * @var CodeIgniter - */ - protected $codeigniter; - + protected CodeIgniter $codeigniter; protected $routes; protected function setUp(): void @@ -218,7 +215,7 @@ public function testResponseConfigEmpty() $response = Services::response(null, false); - $this->assertInstanceOf('\CodeIgniter\HTTP\Response', $response); + $this->assertInstanceOf(Response::class, $response); } public function testRoutesIsEmpty() diff --git a/tests/system/CommonFunctionsTest.php b/tests/system/CommonFunctionsTest.php index 1c8088fdf227..758e1727eca1 100644 --- a/tests/system/CommonFunctionsTest.php +++ b/tests/system/CommonFunctionsTest.php @@ -399,7 +399,7 @@ public function testSlashItem() protected function injectSessionMock() { $defaults = [ - 'sessionDriver' => 'CodeIgniter\Session\Handlers\FileHandler', + 'sessionDriver' => FileHandler::class, 'sessionCookieName' => 'ci_session', 'sessionExpiration' => 7200, 'sessionSavePath' => null, diff --git a/tests/system/Config/DotEnvTest.php b/tests/system/Config/DotEnvTest.php index 2aff090b9576..077bd8f23ea4 100644 --- a/tests/system/Config/DotEnvTest.php +++ b/tests/system/Config/DotEnvTest.php @@ -12,6 +12,7 @@ namespace CodeIgniter\Config; use CodeIgniter\Test\CIUnitTestCase; +use InvalidArgumentException; use org\bovigo\vfs\vfsStream; /** @@ -115,7 +116,7 @@ public function testLoadsUnreadableFile() $file = 'unreadable.env'; $path = rtrim($this->fixturesFolder, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $file; chmod($path, 0000); - $this->expectException('\InvalidArgumentException'); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage("The .env file is not readable: {$path}"); $dotenv = new DotEnv($this->fixturesFolder, $file); $dotenv->load(); @@ -135,7 +136,7 @@ public function testQuotedDotenvLoadsEnvironmentVars() public function testSpacedValuesWithoutQuotesThrowsException() { - $this->expectException('InvalidArgumentException'); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('.env values containing spaces must be surrounded by quotes.'); $dotenv = new DotEnv($this->fixturesFolder, 'spaced-wrong.env'); diff --git a/tests/system/Config/ServicesTest.php b/tests/system/Config/ServicesTest.php index b33ff13f9387..14fbd27a2910 100644 --- a/tests/system/Config/ServicesTest.php +++ b/tests/system/Config/ServicesTest.php @@ -43,6 +43,7 @@ use CodeIgniter\View\Parser; use Config\App; use Config\Exceptions; +use RuntimeException; use Tests\Support\Config\Services; /** @@ -69,7 +70,7 @@ protected function tearDown(): void public function testCanReplaceFrameworkServices() { - $this->expectException('RuntimeException'); + $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Service originated from Tests\Support\Config\Services'); Services::uri('testCanReplaceFrameworkServices'); diff --git a/tests/system/Database/Builder/InsertTest.php b/tests/system/Database/Builder/InsertTest.php index 1844434d3a1c..713e77bd15a7 100644 --- a/tests/system/Database/Builder/InsertTest.php +++ b/tests/system/Database/Builder/InsertTest.php @@ -11,6 +11,7 @@ namespace CodeIgniter\Database\Builder; +use CodeIgniter\Database\Exceptions\DatabaseException; use CodeIgniter\Database\Query; use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\Mock\MockConnection; @@ -62,7 +63,7 @@ public function testThrowsExceptionOnNoValuesSet() { $builder = $this->db->table('jobs'); - $this->expectException('\CodeIgniter\Database\Exceptions\DatabaseException'); + $this->expectException(DatabaseException::class); $this->expectExceptionMessage('You must use the "set" method to update an entry.'); $builder->testMode()->insert(null, true); @@ -192,7 +193,7 @@ public function testInsertBatchThrowsExceptionOnNoData() { $builder = $this->db->table('jobs'); - $this->expectException('\CodeIgniter\Database\Exceptions\DatabaseException'); + $this->expectException(DatabaseException::class); $this->expectExceptionMessage('You must use the "set" method to update an entry.'); $builder->insertBatch(); } @@ -201,7 +202,7 @@ public function testInsertBatchThrowsExceptionOnEmptyData() { $builder = $this->db->table('jobs'); - $this->expectException('\CodeIgniter\Database\Exceptions\DatabaseException'); + $this->expectException(DatabaseException::class); $this->expectExceptionMessage('insertBatch() called with no data'); $builder->insertBatch([]); } diff --git a/tests/system/Database/Builder/ReplaceTest.php b/tests/system/Database/Builder/ReplaceTest.php index 4197ed05449d..e7a1262cb107 100644 --- a/tests/system/Database/Builder/ReplaceTest.php +++ b/tests/system/Database/Builder/ReplaceTest.php @@ -11,6 +11,7 @@ namespace CodeIgniter\Database\Builder; +use CodeIgniter\Database\Exceptions\DatabaseException; use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\Mock\MockConnection; @@ -47,7 +48,7 @@ public function testReplaceThrowsExceptionWithNoData() { $builder = $this->db->table('jobs'); - $this->expectException('\CodeIgniter\Database\Exceptions\DatabaseException'); + $this->expectException(DatabaseException::class); $this->expectExceptionMessage('You must use the "set" method to update an entry.'); $builder->replace(); diff --git a/tests/system/Database/Builder/UpdateTest.php b/tests/system/Database/Builder/UpdateTest.php index bda9ae49915d..5af1490f6f66 100644 --- a/tests/system/Database/Builder/UpdateTest.php +++ b/tests/system/Database/Builder/UpdateTest.php @@ -12,6 +12,7 @@ namespace CodeIgniter\Database\Builder; use CodeIgniter\Database\BaseBuilder; +use CodeIgniter\Database\Exceptions\DatabaseException; use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\Mock\MockConnection; use CodeIgniter\Test\Mock\MockQuery; @@ -177,7 +178,7 @@ public function testUpdateThrowsExceptionWithNoData() { $builder = new BaseBuilder('jobs', $this->db); - $this->expectException('CodeIgniter\Database\Exceptions\DatabaseException'); + $this->expectException(DatabaseException::class); $this->expectExceptionMessage('You must use the "set" method to update an entry.'); $builder->update(null, null, null); @@ -266,7 +267,7 @@ public function testUpdateBatchThrowsExceptionWithNoData() { $builder = new BaseBuilder('jobs', $this->db); - $this->expectException('\CodeIgniter\Database\Exceptions\DatabaseException'); + $this->expectException(DatabaseException::class); $this->expectExceptionMessage('You must use the "set" method to update an entry.'); $builder->updateBatch(null, 'id'); @@ -276,7 +277,7 @@ public function testUpdateBatchThrowsExceptionWithNoID() { $builder = new BaseBuilder('jobs', $this->db); - $this->expectException('\CodeIgniter\Database\Exceptions\DatabaseException'); + $this->expectException(DatabaseException::class); $this->expectExceptionMessage('You must specify an index to match on for batch updates.'); $builder->updateBatch([]); @@ -286,7 +287,7 @@ public function testUpdateBatchThrowsExceptionWithEmptySetArray() { $builder = new BaseBuilder('jobs', $this->db); - $this->expectException('\CodeIgniter\Database\Exceptions\DatabaseException'); + $this->expectException(DatabaseException::class); $this->expectExceptionMessage('updateBatch() called with no data'); $builder->updateBatch([], 'id'); diff --git a/tests/system/Database/ConfigTest.php b/tests/system/Database/ConfigTest.php index 0dc9a1619485..301a95158bf1 100644 --- a/tests/system/Database/ConfigTest.php +++ b/tests/system/Database/ConfigTest.php @@ -13,6 +13,7 @@ use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\ReflectionHelper; +use SQLite3; /** * @internal @@ -21,7 +22,7 @@ final class ConfigTest extends CIUnitTestCase { use ReflectionHelper; - protected $group = [ + protected array $group = [ 'DSN' => '', 'hostname' => 'localhost', 'username' => 'first', @@ -40,13 +41,13 @@ final class ConfigTest extends CIUnitTestCase 'failover' => [], 'port' => 3306, ]; - protected $dsnGroup = [ + protected array $dsnGroup = [ 'DSN' => 'MySQLi://user:pass@localhost:3306/dbname?DBPrefix=test_&pConnect=true&charset=latin1&DBCollat=latin1_swedish_ci', 'hostname' => '', 'username' => '', 'password' => '', 'database' => '', - 'DBDriver' => 'SQLite3', + 'DBDriver' => SQLite3::class, 'DBPrefix' => 't_', 'pConnect' => false, 'DBDebug' => (ENVIRONMENT !== 'production'), @@ -59,13 +60,13 @@ final class ConfigTest extends CIUnitTestCase 'failover' => [], 'port' => 3306, ]; - protected $dsnGroupPostgre = [ + protected array $dsnGroupPostgre = [ 'DSN' => 'Postgre://user:pass@localhost:5432/dbname?DBPrefix=test_&connect_timeout=5&sslmode=1', 'hostname' => '', 'username' => '', 'password' => '', 'database' => '', - 'DBDriver' => 'SQLite3', + 'DBDriver' => SQLite3::class, 'DBPrefix' => 't_', 'pConnect' => false, 'DBDebug' => (ENVIRONMENT !== 'production'), @@ -78,7 +79,7 @@ final class ConfigTest extends CIUnitTestCase 'failover' => [], 'port' => 5432, ]; - protected $dsnGroupPostgreNative = [ + protected array $dsnGroupPostgreNative = [ 'DSN' => 'pgsql:host=localhost;port=5432;dbname=database_name', 'hostname' => '', 'username' => '', diff --git a/tests/system/Database/DatabaseSeederTest.php b/tests/system/Database/DatabaseSeederTest.php index 7e08d6648508..70721718ea8a 100644 --- a/tests/system/Database/DatabaseSeederTest.php +++ b/tests/system/Database/DatabaseSeederTest.php @@ -14,6 +14,7 @@ use CodeIgniter\Test\CIUnitTestCase; use Config\Database; use Faker\Generator; +use InvalidArgumentException; /** * @internal @@ -22,7 +23,7 @@ final class DatabaseSeederTest extends CIUnitTestCase { public function testInstantiateNoSeedPath() { - $this->expectException('InvalidArgumentException'); + $this->expectException(InvalidArgumentException::class); $config = new Database(); $config->filesPath = ''; @@ -31,7 +32,7 @@ public function testInstantiateNoSeedPath() public function testInstantiateNotDirSeedPath() { - $this->expectException('InvalidArgumentException'); + $this->expectException(InvalidArgumentException::class); $config = new Database(); $config->filesPath = APPPATH . 'Foo'; @@ -48,7 +49,7 @@ public function testFakerGet() public function testCallOnEmptySeeder() { - $this->expectException('InvalidArgumentException'); + $this->expectException(InvalidArgumentException::class); $seeder = new Seeder(new Database()); $seeder->call(''); diff --git a/tests/system/Database/Live/DbUtilsTest.php b/tests/system/Database/Live/DbUtilsTest.php index e767d0b6991d..414412a72ded 100644 --- a/tests/system/Database/Live/DbUtilsTest.php +++ b/tests/system/Database/Live/DbUtilsTest.php @@ -15,6 +15,7 @@ use CodeIgniter\Database\Exceptions\DatabaseException; use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\DatabaseTestTrait; +use SQLite3; /** * @group DatabaseLive @@ -80,7 +81,7 @@ public function testUtilsListDatabases() $databases = $util->listDatabases(); $this->assertContains($this->db->getDatabase(), $databases); - } elseif ($this->db->DBDriver === 'SQLite3') { + } elseif ($this->db->DBDriver === SQLite3::class) { $this->expectException(DatabaseException::class); $this->expectExceptionMessage('Unsupported feature of the database platform you are using.'); @@ -96,7 +97,7 @@ public function testUtilsDatabaseExist() $exist = $util->databaseExists($this->db->getDatabase()); $this->assertTrue($exist); - } elseif ($this->db->DBDriver === 'SQLite3') { + } elseif ($this->db->DBDriver === SQLite3::class) { $this->expectException(DatabaseException::class); $this->expectExceptionMessage('Unsupported feature of the database platform you are using.'); diff --git a/tests/system/Database/Live/DeleteTest.php b/tests/system/Database/Live/DeleteTest.php index 31b89412e78a..f8311e9d042a 100644 --- a/tests/system/Database/Live/DeleteTest.php +++ b/tests/system/Database/Live/DeleteTest.php @@ -29,7 +29,7 @@ final class DeleteTest extends CIUnitTestCase public function testDeleteThrowExceptionWithNoCriteria() { - $this->expectException('\CodeIgniter\Database\Exceptions\DatabaseException'); + $this->expectException(DatabaseException::class); $this->db->table('job')->delete(); } diff --git a/tests/system/Database/Live/ForgeTest.php b/tests/system/Database/Live/ForgeTest.php index 113f2c0a211e..f83593ed320e 100644 --- a/tests/system/Database/Live/ForgeTest.php +++ b/tests/system/Database/Live/ForgeTest.php @@ -18,6 +18,7 @@ use Config\Database; use InvalidArgumentException; use RuntimeException; +use SQLite3; /** * @group DatabaseLive @@ -56,7 +57,7 @@ public function testCreateDatabaseIfNotExists() $dbName = 'test_forge_database_exist'; $databaseCreateIfNotExists = $this->forge->createDatabase($dbName, true); - if ($this->db->DBDriver !== 'SQLite3') { + if ($this->db->DBDriver !== SQLite3::class) { $this->forge->dropDatabase($dbName); } @@ -72,7 +73,7 @@ public function testCreateDatabaseIfNotExistsWithDb() $this->forge->createDatabase($dbName); $databaseExists = $this->forge->createDatabase($dbName, true); - if ($this->db->DBDriver !== 'SQLite3') { + if ($this->db->DBDriver !== SQLite3::class) { $this->forge->dropDatabase($dbName); } @@ -84,7 +85,7 @@ public function testDropDatabase() if ($this->db->DBDriver === 'OCI8') { $this->markTestSkipped('OCI8 does not support drop database.'); } - if ($this->db->DBDriver === 'SQLite3') { + if ($this->db->DBDriver === SQLite3::class) { $this->markTestSkipped('SQLite3 requires file path to drop database'); } @@ -97,7 +98,7 @@ public function testCreateDatabaseExceptionNoCreateStatement() { $this->setPrivateProperty($this->forge, 'createDatabaseStr', false); - if ($this->db->DBDriver === 'SQLite3') { + if ($this->db->DBDriver === SQLite3::class) { $databaseCreated = $this->forge->createDatabase('test_forge_database'); $this->assertTrue($databaseCreated); } else { @@ -112,7 +113,7 @@ public function testDropDatabaseExceptionNoDropStatement() { $this->setPrivateProperty($this->forge, 'dropDatabaseStr', false); - if ($this->db->DBDriver === 'SQLite3') { + if ($this->db->DBDriver === SQLite3::class) { $this->markTestSkipped('SQLite3 requires file path to drop database'); } else { $this->expectException(DatabaseException::class); @@ -175,7 +176,7 @@ public function testCreateTableApplyBigInt() $this->assertSame(strtolower($fieldsData[0]->type), 'bigint'); } elseif ($this->db->DBDriver === 'Postgre') { $this->assertSame(strtolower($fieldsData[0]->type), 'bigint'); - } elseif ($this->db->DBDriver === 'SQLite3') { + } elseif ($this->db->DBDriver === SQLite3::class) { $this->assertSame(strtolower($fieldsData[0]->type), 'integer'); } elseif ($this->db->DBDriver === 'OCI8') { $this->assertSame(strtolower($fieldsData[0]->type), 'number'); @@ -191,7 +192,7 @@ public function testCreateTableWithAttributes() if ($this->db->DBDriver === 'OCI8') { $this->markTestSkipped('OCI8 does not support comments on tables or columns.'); } - if ($this->db->DBDriver === 'SQLite3') { + if ($this->db->DBDriver === SQLite3::class) { $this->markTestSkipped('SQLite3 does not support comments on tables or columns.'); } @@ -213,7 +214,7 @@ public function testCreateTableWithAttributes() public function testCreateTableWithArrayFieldConstraints() { - if (in_array($this->db->DBDriver, ['MySQLi', 'SQLite3'], true)) { + if (in_array($this->db->DBDriver, ['MySQLi', SQLite3::class], true)) { $this->forge->dropTable('forge_array_constraint', true); $this->forge->addField([ 'status' => [ @@ -231,7 +232,7 @@ public function testCreateTableWithArrayFieldConstraints() $this->assertSame('status', $fields[0]->name); - if ($this->db->DBDriver === 'SQLite3') { + if ($this->db->DBDriver === SQLite3::class) { // SQLite3 converts array constraints to TEXT CHECK(...) $this->assertSame('TEXT', $fields[0]->type); } else { @@ -431,7 +432,7 @@ public function testForeignKey() $foreignKeyData = $this->db->getForeignKeyData($tableName); - if ($this->db->DBDriver === 'SQLite3') { + if ($this->db->DBDriver === SQLite3::class) { $this->assertSame($foreignKeyData[0]->constraint_name, 'users_id to db_forge_test_users.id'); $this->assertSame($foreignKeyData[0]->sequence, 0); } elseif ($this->db->DBDriver === 'OCI8') { @@ -553,7 +554,7 @@ public function testCompositeForeignKey() $foreignKeyData = $this->db->getForeignKeyData($forgeTestInvoicesTableName); - if ($this->db->DBDriver === 'SQLite3') { + if ($this->db->DBDriver === SQLite3::class) { $this->assertSame('users_id to db_forge_test_users.id', $foreignKeyData[0]->constraint_name); $this->assertSame(0, $foreignKeyData[0]->sequence); $this->assertSame('users_second_id to db_forge_test_users.second_id', $foreignKeyData[1]->constraint_name); @@ -843,7 +844,7 @@ public function testAddFields() $this->assertSame(32, (int) $fieldsData[0]->max_length); $this->assertNull($fieldsData[1]->default); $this->assertSame(255, (int) $fieldsData[1]->max_length); - } elseif ($this->db->DBDriver === 'SQLite3') { + } elseif ($this->db->DBDriver === SQLite3::class) { $this->assertSame('integer', strtolower($fieldsData[0]->type)); $this->assertSame('varchar', strtolower($fieldsData[1]->type)); $this->assertNull($fieldsData[1]->default); @@ -868,7 +869,7 @@ public function testAddFields() public function testCompositeKey() { // SQLite3 uses auto increment different - $uniqueOrAuto = $this->db->DBDriver === 'SQLite3' ? 'unique' : 'auto_increment'; + $uniqueOrAuto = $this->db->DBDriver === SQLite3::class ? 'unique' : 'auto_increment'; $this->forge->addField([ 'id' => [ @@ -916,7 +917,7 @@ public function testCompositeKey() $this->assertSame($keys['db_forge_test_1_code_active']->name, 'db_forge_test_1_code_active'); $this->assertSame($keys['db_forge_test_1_code_active']->fields, ['code', 'active']); $this->assertSame($keys['db_forge_test_1_code_active']->type, 'UNIQUE'); - } elseif ($this->db->DBDriver === 'SQLite3') { + } elseif ($this->db->DBDriver === SQLite3::class) { $this->assertSame($keys['sqlite_autoindex_db_forge_test_1_1']->name, 'sqlite_autoindex_db_forge_test_1_1'); $this->assertSame($keys['sqlite_autoindex_db_forge_test_1_1']->fields, ['id']); $this->assertSame($keys['db_forge_test_1_code_company']->name, 'db_forge_test_1_code_company'); @@ -1054,7 +1055,7 @@ public function testDropTableSuccess() $this->assertFalse($this->db->tableExists('dropTest')); - if ($this->db->DBDriver === 'SQLite3') { + if ($this->db->DBDriver === SQLite3::class) { $this->assertCount(0, $this->db->getIndexData('droptest')); } } diff --git a/tests/system/Database/Live/GetTest.php b/tests/system/Database/Live/GetTest.php index 20ae2e099d0d..768f24d72de3 100644 --- a/tests/system/Database/Live/GetTest.php +++ b/tests/system/Database/Live/GetTest.php @@ -14,6 +14,7 @@ use CodeIgniter\Database\Exceptions\DatabaseException; use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\DatabaseTestTrait; +use SQLite3; /** * @group DatabaseLive @@ -91,7 +92,7 @@ public function testGetFieldData() $typeTest = $this->db->table('type_test')->get()->getFieldData(); - if ($this->db->DBDriver === 'SQLite3') { + if ($this->db->DBDriver === SQLite3::class) { $this->assertSame('integer', $typeTest[0]->type_name); // INTEGER AUTO INC $this->assertSame('text', $typeTest[1]->type_name); // VARCHAR $this->assertSame('text', $typeTest[2]->type_name); // CHAR @@ -172,7 +173,7 @@ public function testGetDataSeek() { $data = $this->db->table('job')->get(); - if ($this->db->DBDriver === 'SQLite3') { + if ($this->db->DBDriver === SQLite3::class) { $this->expectException(DatabaseException::class); $this->expectExceptionMessage('SQLite3 doesn\'t support seeking to other offset.'); } elseif ($this->db->DBDriver === 'OCI8') { diff --git a/tests/system/Database/Live/SQLite/AlterTableTest.php b/tests/system/Database/Live/SQLite/AlterTableTest.php index 2816008a2a54..8889c9d8f639 100644 --- a/tests/system/Database/Live/SQLite/AlterTableTest.php +++ b/tests/system/Database/Live/SQLite/AlterTableTest.php @@ -11,12 +11,14 @@ namespace CodeIgniter\Database\Live\SQLite; +use CodeIgniter\Database\Exceptions\DataException; use CodeIgniter\Database\SQLite3\Connection; use CodeIgniter\Database\SQLite3\Forge; use CodeIgniter\Database\SQLite3\Table; use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\DatabaseTestTrait; use Config\Database; +use SQLite3; /** * @group DatabaseLive @@ -34,27 +36,21 @@ final class AlterTableTest extends CIUnitTestCase */ protected $migrate = false; - /** - * @var Table - */ - protected $table; + protected Table $table; /** * @var Connection */ protected $db; - /** - * @var Forge - */ - protected $forge; + protected Forge $forge; protected function setUp(): void { parent::setUp(); $config = [ - 'DBDriver' => 'SQLite3', + 'DBDriver' => SQLite3::class, 'database' => 'database.db', ]; @@ -77,7 +73,7 @@ private function dropTables() public function testFromTableThrowsOnNoTable() { - $this->expectException('CodeIgniter\Database\Exceptions\DataException'); + $this->expectException(DataException::class); $this->expectExceptionMessage('Table `foo` was not found in the current database.'); $this->table->fromTable('foo'); diff --git a/tests/system/Database/Migrations/MigrationRunnerTest.php b/tests/system/Database/Migrations/MigrationRunnerTest.php index 2c9fa09e1d73..9a5f467ed9c2 100644 --- a/tests/system/Database/Migrations/MigrationRunnerTest.php +++ b/tests/system/Database/Migrations/MigrationRunnerTest.php @@ -22,6 +22,7 @@ use Config\Migrations; use Config\Services; use org\bovigo\vfs\vfsStream; +use SQLite3; /** * @group DatabaseLive @@ -74,7 +75,7 @@ public function testLoadsDefaultDatabaseWhenNoneSpecified() $this->assertInstanceOf(BaseConnection::class, $db); $this->assertSame( - ($dbConfig->tests['DBDriver'] === 'SQLite3' ? WRITEPATH : '') . $dbConfig->tests['database'], + ($dbConfig->tests['DBDriver'] === SQLite3::class ? WRITEPATH : '') . $dbConfig->tests['database'], $this->getPrivateProperty($db, 'database') ); $this->assertSame($dbConfig->tests['DBDriver'], $this->getPrivateProperty($db, 'DBDriver')); @@ -254,7 +255,7 @@ public function testFindMigrationsSuccessTimestamp() public function testMigrationThrowsDisabledException() { - $this->expectException('CodeIgniter\Exceptions\ConfigException'); + $this->expectException(ConfigException::class); $this->expectExceptionMessage('Migrations have been loaded but are disabled or setup incorrectly.'); $config = $this->config; diff --git a/tests/system/Encryption/EncryptionTest.php b/tests/system/Encryption/EncryptionTest.php index a1f6085a33a6..cb4eb4cad7da 100644 --- a/tests/system/Encryption/EncryptionTest.php +++ b/tests/system/Encryption/EncryptionTest.php @@ -11,6 +11,7 @@ namespace CodeIgniter\Encryption; +use CodeIgniter\Encryption\Exceptions\EncryptionException; use CodeIgniter\Test\CIUnitTestCase; use Config\Encryption as EncryptionConfig; use Config\Services; @@ -20,10 +21,7 @@ */ final class EncryptionTest extends CIUnitTestCase { - /** - * @var \CodeIgniter\Encryption\Encryption - */ - protected $encryption; + protected \CodeIgniter\Encryption\Encryption $encryption; protected function setUp(): void { @@ -57,7 +55,7 @@ public function testConstructor() */ public function testBadDriver() { - $this->expectException('CodeIgniter\Encryption\Exceptions\EncryptionException'); + $this->expectException(EncryptionException::class); // ask for a bad driver $config = new EncryptionConfig(); @@ -72,7 +70,7 @@ public function testBadDriver() */ public function testMissingDriver() { - $this->expectException('CodeIgniter\Encryption\Exceptions\EncryptionException'); + $this->expectException(EncryptionException::class); // ask for a bad driver $config = new EncryptionConfig(); @@ -101,7 +99,7 @@ public function testServiceSuccess() public function testServiceFailure() { - $this->expectException('CodeIgniter\Encryption\Exceptions\EncryptionException'); + $this->expectException(EncryptionException::class); // ask for a bad driver $config = new EncryptionConfig(); @@ -113,7 +111,7 @@ public function testServiceFailure() public function testServiceWithoutKey() { - $this->expectException('CodeIgniter\Encryption\Exceptions\EncryptionException'); + $this->expectException(EncryptionException::class); Services::encrypter(); } diff --git a/tests/system/Encryption/Handlers/OpenSSLHandlerTest.php b/tests/system/Encryption/Handlers/OpenSSLHandlerTest.php index 89886b6f8901..5427c99a5edb 100644 --- a/tests/system/Encryption/Handlers/OpenSSLHandlerTest.php +++ b/tests/system/Encryption/Handlers/OpenSSLHandlerTest.php @@ -12,6 +12,7 @@ namespace CodeIgniter\Encryption\Handlers; use CodeIgniter\Encryption\Encryption; +use CodeIgniter\Encryption\Exceptions\EncryptionException; use CodeIgniter\Test\CIUnitTestCase; use Config\Encryption as EncryptionConfig; @@ -20,10 +21,7 @@ */ final class OpenSSLHandlerTest extends CIUnitTestCase { - /** - * @var \CodeIgniter\Encryption\Encryption - */ - protected $encryption; + protected \CodeIgniter\Encryption\Encryption $encryption; protected function setUp(): void { @@ -79,7 +77,7 @@ public function testSimple() */ public function testWithoutKey() { - $this->expectException('CodeIgniter\Encryption\Exceptions\EncryptionException'); + $this->expectException(EncryptionException::class); $encrypter = new OpenSSLHandler(); $message1 = 'This is a plain-text message.'; @@ -100,7 +98,7 @@ public function testWithKeyString() */ public function testWithWrongKeyString() { - $this->expectException('CodeIgniter\Encryption\Exceptions\EncryptionException'); + $this->expectException(EncryptionException::class); $key1 = 'abracadabra'; $encrypter = new OpenSSLHandler(); @@ -125,7 +123,7 @@ public function testWithKeyArray() */ public function testWithWrongKeyArray() { - $this->expectException('CodeIgniter\Encryption\Exceptions\EncryptionException'); + $this->expectException(EncryptionException::class); $key1 = 'abracadabra'; $encrypter = new OpenSSLHandler(); diff --git a/tests/system/Encryption/Handlers/SodiumHandlerTest.php b/tests/system/Encryption/Handlers/SodiumHandlerTest.php index fc5f353d2ffb..421af43e1330 100644 --- a/tests/system/Encryption/Handlers/SodiumHandlerTest.php +++ b/tests/system/Encryption/Handlers/SodiumHandlerTest.php @@ -12,6 +12,7 @@ namespace CodeIgniter\Encryption\Handlers; use CodeIgniter\Encryption\Encryption; +use CodeIgniter\Encryption\Exceptions\EncryptionException; use CodeIgniter\Test\CIUnitTestCase; use Config\Encryption as EncryptionConfig; @@ -20,15 +21,8 @@ */ final class SodiumHandlerTest extends CIUnitTestCase { - /** - * @var \CodeIgniter\Encryption\Encryption - */ - protected $encryption; - - /** - * @var \Config\Encryption - */ - protected $config; + protected \CodeIgniter\Encryption\Encryption $encryption; + protected \Config\Encryption $config; protected function setUp(): void { @@ -57,7 +51,7 @@ public function testPropertiesGetter() public function testEmptyKeyThrowsErrorOnInitialize() { - $this->expectException('CodeIgniter\Encryption\Exceptions\EncryptionException'); + $this->expectException(EncryptionException::class); $this->config->key = ''; $this->encryption->initialize($this->config); @@ -65,7 +59,7 @@ public function testEmptyKeyThrowsErrorOnInitialize() public function testEmptyKeyThrowsErrorOnEncrypt() { - $this->expectException('CodeIgniter\Encryption\Exceptions\EncryptionException'); + $this->expectException(EncryptionException::class); $encrypter = $this->encryption->initialize($this->config); $encrypter->encrypt('Some message to encrypt', ''); @@ -73,7 +67,7 @@ public function testEmptyKeyThrowsErrorOnEncrypt() public function testInvalidBlockSizeThrowsErrorOnEncrypt() { - $this->expectException('CodeIgniter\Encryption\Exceptions\EncryptionException'); + $this->expectException(EncryptionException::class); $this->config->blockSize = -1; $encrypter = $this->encryption->initialize($this->config); @@ -82,7 +76,7 @@ public function testInvalidBlockSizeThrowsErrorOnEncrypt() public function testEmptyKeyThrowsErrorOnDecrypt() { - $this->expectException('CodeIgniter\Encryption\Exceptions\EncryptionException'); + $this->expectException(EncryptionException::class); $encrypter = $this->encryption->initialize($this->config); $ciphertext = $encrypter->encrypt('Some message to encrypt'); @@ -92,7 +86,7 @@ public function testEmptyKeyThrowsErrorOnDecrypt() public function testInvalidBlockSizeThrowsErrorOnDecrypt() { - $this->expectException('CodeIgniter\Encryption\Exceptions\EncryptionException'); + $this->expectException(EncryptionException::class); $key = $this->config->key; $encrypter = $this->encryption->initialize($this->config); @@ -103,7 +97,7 @@ public function testInvalidBlockSizeThrowsErrorOnDecrypt() public function testTruncatedMessageThrowsErrorOnDecrypt() { - $this->expectException('CodeIgniter\Encryption\Exceptions\EncryptionException'); + $this->expectException(EncryptionException::class); $encrypter = $this->encryption->initialize($this->config); $ciphertext = $encrypter->encrypt('Some message to encrypt'); diff --git a/tests/system/Entity/EntityTest.php b/tests/system/Entity/EntityTest.php index a9a59502575f..82c758f92f5e 100644 --- a/tests/system/Entity/EntityTest.php +++ b/tests/system/Entity/EntityTest.php @@ -382,7 +382,7 @@ public function testCastDateTime() $entity->eighth = 'March 12, 2017'; - $this->assertInstanceOf('DateTime', $entity->eighth); + $this->assertInstanceOf(DateTime::class, $entity->eighth); $this->assertSame('2017-03-12', $entity->eighth->format('Y-m-d')); } diff --git a/tests/system/Files/FileTest.php b/tests/system/Files/FileTest.php index 6ff5b77fd3bc..573c8cdb3499 100644 --- a/tests/system/Files/FileTest.php +++ b/tests/system/Files/FileTest.php @@ -11,6 +11,7 @@ namespace CodeIgniter\Files; +use CodeIgniter\Files\Exceptions\FileNotFoundException; use CodeIgniter\Test\CIUnitTestCase; /** @@ -85,7 +86,7 @@ public function testGetSizeReturnsBytes() public function testThrowsExceptionIfNotAFile() { - $this->expectException('CodeIgniter\Files\Exceptions\FileNotFoundException'); + $this->expectException(FileNotFoundException::class); new File(SYSTEMPATH . 'Commoner.php', true); } diff --git a/tests/system/Format/FormatTest.php b/tests/system/Format/FormatTest.php index 0cd53e62a22c..3bc6854fa3ae 100644 --- a/tests/system/Format/FormatTest.php +++ b/tests/system/Format/FormatTest.php @@ -12,6 +12,7 @@ namespace CodeIgniter\Format; use CodeIgniter\Format\Exceptions\FormatException; +use CodeIgniter\HTTP\URI; use CodeIgniter\Test\CIUnitTestCase; /** @@ -19,10 +20,7 @@ */ final class FormatTest extends CIUnitTestCase { - /** - * @var Format - */ - protected $format; + protected Format $format; protected function setUp(): void { @@ -66,7 +64,7 @@ public function testGetFormatterExpectsExceptionOnClassNotImplementingFormatterI { $this->format->getConfig()->formatters = array_merge( $this->format->getConfig()->formatters, - ['text/xml' => 'CodeIgniter\HTTP\URI'] + ['text/xml' => URI::class] ); $this->expectException(FormatException::class); diff --git a/tests/system/Format/JSONFormatterTest.php b/tests/system/Format/JSONFormatterTest.php index b2eb5f2e0d5e..19dacb02e86c 100644 --- a/tests/system/Format/JSONFormatterTest.php +++ b/tests/system/Format/JSONFormatterTest.php @@ -12,6 +12,7 @@ namespace CodeIgniter\Format; use CodeIgniter\Test\CIUnitTestCase; +use RuntimeException; /** * @internal @@ -67,7 +68,7 @@ public function testKeepsURLs() public function testJSONError() { - $this->expectException('RuntimeException'); + $this->expectException(RuntimeException::class); $data = ["\xB1\x31"]; $expected = 'Boom'; diff --git a/tests/system/HTTP/CURLRequestDoNotShareOptionsTest.php b/tests/system/HTTP/CURLRequestDoNotShareOptionsTest.php index 21070736d741..bcf9d1c51124 100644 --- a/tests/system/HTTP/CURLRequestDoNotShareOptionsTest.php +++ b/tests/system/HTTP/CURLRequestDoNotShareOptionsTest.php @@ -25,10 +25,7 @@ */ final class CURLRequestDoNotShareOptionsTest extends CIUnitTestCase { - /** - * @var MockCURLRequest - */ - protected $request; + protected MockCURLRequest $request; protected function setUp(): void { @@ -96,7 +93,7 @@ public function testSendReturnsResponse() $response = $this->request->setOutput($output)->send('get', 'http://example.com'); - $this->assertInstanceOf('CodeIgniter\\HTTP\\Response', $response); + $this->assertInstanceOf(Response::class, $response); $this->assertSame($output, $response->getBody()); } diff --git a/tests/system/HTTP/CURLRequestTest.php b/tests/system/HTTP/CURLRequestTest.php index 64b824cbad56..31808a739e29 100644 --- a/tests/system/HTTP/CURLRequestTest.php +++ b/tests/system/HTTP/CURLRequestTest.php @@ -25,10 +25,7 @@ */ final class CURLRequestTest extends CIUnitTestCase { - /** - * @var MockCURLRequest - */ - protected $request; + protected MockCURLRequest $request; protected function setUp(): void { @@ -96,7 +93,7 @@ public function testSendReturnsResponse() $response = $this->request->setOutput($output)->send('get', 'http://example.com'); - $this->assertInstanceOf('CodeIgniter\\HTTP\\Response', $response); + $this->assertInstanceOf(Response::class, $response); $this->assertSame($output, $response->getBody()); } diff --git a/tests/system/Helpers/ArrayHelperTest.php b/tests/system/Helpers/ArrayHelperTest.php index 90413c570a00..59257fbab7d6 100644 --- a/tests/system/Helpers/ArrayHelperTest.php +++ b/tests/system/Helpers/ArrayHelperTest.php @@ -12,6 +12,8 @@ namespace CodeIgniter\Helpers; use CodeIgniter\Test\CIUnitTestCase; +use ErrorException; +use ValueError; /** * @internal @@ -295,9 +297,9 @@ public function testArraySortByMultipleKeysFailsInconsistentArraySizes($data) { // PHP 8 changes this error type if (version_compare(PHP_VERSION, '8.0', '<')) { - $this->expectException('ErrorException'); + $this->expectException(ErrorException::class); } else { - $this->expectException('ValueError'); + $this->expectException(ValueError::class); } $this->expectExceptionMessage('Array sizes are inconsistent'); diff --git a/tests/system/HomeTest.php b/tests/system/HomeTest.php index fca482d3dec8..382e6c4ee522 100644 --- a/tests/system/HomeTest.php +++ b/tests/system/HomeTest.php @@ -13,6 +13,7 @@ use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\FeatureTestTrait; +use CodeIgniter\Test\TestResponse; /** * @internal @@ -32,7 +33,7 @@ public function testPageLoadsSuccessfully() ]); $response = $this->get('home'); - $this->assertInstanceOf('CodeIgniter\Test\TestResponse', $response); + $this->assertInstanceOf(TestResponse::class, $response); $this->assertTrue($response->isOK()); } } diff --git a/tests/system/Honeypot/HoneypotTest.php b/tests/system/Honeypot/HoneypotTest.php index 860d552d4e86..b732b27fca7b 100644 --- a/tests/system/Honeypot/HoneypotTest.php +++ b/tests/system/Honeypot/HoneypotTest.php @@ -103,7 +103,7 @@ public function testConfigName() public function testHoneypotFilterBefore() { $config = [ - 'aliases' => ['trap' => '\CodeIgniter\Filters\Honeypot'], + 'aliases' => ['trap' => \CodeIgniter\Filters\Honeypot::class], 'globals' => [ 'before' => ['trap'], 'after' => [], @@ -120,7 +120,7 @@ public function testHoneypotFilterBefore() public function testHoneypotFilterAfter() { $config = [ - 'aliases' => ['trap' => '\CodeIgniter\Filters\Honeypot'], + 'aliases' => ['trap' => \CodeIgniter\Filters\Honeypot::class], 'globals' => [ 'before' => [], 'after' => ['trap'], diff --git a/tests/system/I18n/TimeTest.php b/tests/system/I18n/TimeTest.php index ed1b747699a4..03f142479478 100644 --- a/tests/system/I18n/TimeTest.php +++ b/tests/system/I18n/TimeTest.php @@ -497,7 +497,7 @@ public function testSetDay() public function testSetDayOverMaxInCurrentMonth() { - $this->expectException('CodeIgniter\I18n\Exceptions\I18nException'); + $this->expectException(I18nException::class); $time = Time::parse('Feb 02, 2009'); $time->setDay(29); @@ -545,7 +545,7 @@ public function testSetSecond() public function testSetMonthTooSmall() { - $this->expectException('CodeIgniter\I18n\Exceptions\I18nException'); + $this->expectException(I18nException::class); $time = Time::parse('May 10, 2017'); $time->setMonth(-5); @@ -553,7 +553,7 @@ public function testSetMonthTooSmall() public function testSetMonthTooBig() { - $this->expectException('CodeIgniter\I18n\Exceptions\I18nException'); + $this->expectException(I18nException::class); $time = Time::parse('May 10, 2017'); $time->setMonth(30); @@ -561,7 +561,7 @@ public function testSetMonthTooBig() public function testSetDayTooSmall() { - $this->expectException('CodeIgniter\I18n\Exceptions\I18nException'); + $this->expectException(I18nException::class); $time = Time::parse('May 10, 2017'); $time->setDay(-5); @@ -569,7 +569,7 @@ public function testSetDayTooSmall() public function testSetDayTooBig() { - $this->expectException('CodeIgniter\I18n\Exceptions\I18nException'); + $this->expectException(I18nException::class); $time = Time::parse('May 10, 2017'); $time->setDay(80); @@ -577,7 +577,7 @@ public function testSetDayTooBig() public function testSetHourTooSmall() { - $this->expectException('CodeIgniter\I18n\Exceptions\I18nException'); + $this->expectException(I18nException::class); $time = Time::parse('May 10, 2017'); $time->setHour(-5); @@ -585,7 +585,7 @@ public function testSetHourTooSmall() public function testSetHourTooBig() { - $this->expectException('CodeIgniter\I18n\Exceptions\I18nException'); + $this->expectException(I18nException::class); $time = Time::parse('May 10, 2017'); $time->setHour(80); @@ -593,7 +593,7 @@ public function testSetHourTooBig() public function testSetMinuteTooSmall() { - $this->expectException('CodeIgniter\I18n\Exceptions\I18nException'); + $this->expectException(I18nException::class); $time = Time::parse('May 10, 2017'); $time->setMinute(-5); @@ -601,7 +601,7 @@ public function testSetMinuteTooSmall() public function testSetMinuteTooBig() { - $this->expectException('CodeIgniter\I18n\Exceptions\I18nException'); + $this->expectException(I18nException::class); $time = Time::parse('May 10, 2017'); $time->setMinute(80); @@ -609,7 +609,7 @@ public function testSetMinuteTooBig() public function testSetSecondTooSmall() { - $this->expectException('CodeIgniter\I18n\Exceptions\I18nException'); + $this->expectException(I18nException::class); $time = Time::parse('May 10, 2017'); $time->setSecond(-5); @@ -617,7 +617,7 @@ public function testSetSecondTooSmall() public function testSetSecondTooBig() { - $this->expectException('CodeIgniter\I18n\Exceptions\I18nException'); + $this->expectException(I18nException::class); $time = Time::parse('May 10, 2017'); $time->setSecond(80); diff --git a/tests/system/Language/LanguageTest.php b/tests/system/Language/LanguageTest.php index f89e6dd18125..58994434b3ec 100644 --- a/tests/system/Language/LanguageTest.php +++ b/tests/system/Language/LanguageTest.php @@ -14,6 +14,7 @@ use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\Mock\MockLanguage; use Config\Services; +use MessageFormatter; use Tests\Support\Language\SecondMockLanguage; /** @@ -96,7 +97,7 @@ public function testGetLineArrayReturnsLineArray() public function testGetLineFormatsMessage() { // No intl extension? then we can't test this - go away.... - if (! class_exists('MessageFormatter')) { + if (! class_exists(MessageFormatter::class)) { $this->markTestSkipped('No intl support.'); } @@ -110,7 +111,7 @@ public function testGetLineFormatsMessage() public function testGetLineArrayFormatsMessages() { // No intl extension? Then we can't test this - go away... - if (! class_exists('MessageFormatter')) { + if (! class_exists(MessageFormatter::class)) { $this->markTestSkipped('No intl support.'); } diff --git a/tests/system/Models/FindModelTest.php b/tests/system/Models/FindModelTest.php index e564f570ec8c..e0fdad5024a1 100644 --- a/tests/system/Models/FindModelTest.php +++ b/tests/system/Models/FindModelTest.php @@ -13,6 +13,7 @@ use CodeIgniter\Database\Exceptions\DataException; use CodeIgniter\Exceptions\ModelException; +use stdClass; use Tests\Support\Models\JobModel; use Tests\Support\Models\SecondaryModel; use Tests\Support\Models\UserModel; @@ -295,7 +296,7 @@ public function testFirstWithNoPrimaryKey(): void ]); $record = $this->model->first(); - $this->assertInstanceOf('stdClass', $record); + $this->assertInstanceOf(stdClass::class, $record); $this->assertSame('foo', $record->key); } diff --git a/tests/system/RESTful/ResourceControllerTest.php b/tests/system/RESTful/ResourceControllerTest.php index e6098527d09c..06719fdbfd85 100644 --- a/tests/system/RESTful/ResourceControllerTest.php +++ b/tests/system/RESTful/ResourceControllerTest.php @@ -19,6 +19,7 @@ use CodeIgniter\HTTP\Response; use CodeIgniter\HTTP\URI; use CodeIgniter\HTTP\UserAgent; +use CodeIgniter\Model; use CodeIgniter\Router\RouteCollection; use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\Mock\MockCodeIgniter; @@ -40,10 +41,7 @@ */ final class ResourceControllerTest extends CIUnitTestCase { - /** - * @var CodeIgniter - */ - protected $codeigniter; + protected CodeIgniter $codeigniter; /** * @var RouteCollection @@ -247,7 +245,7 @@ public function testModelByName() { $resource = new MockResourceController(); $resource->setModel('\Tests\Support\Models\UserModel'); - $this->assertInstanceOf('CodeIgniter\Model', $resource->getModel()); + $this->assertInstanceOf(Model::class, $resource->getModel()); $this->assertSame('\Tests\Support\Models\UserModel', $resource->getModelName()); } @@ -256,7 +254,7 @@ public function testModelByObject() $resource = new MockResourceController(); $model = new UserModel(); $resource->setModel($model); - $this->assertInstanceOf('CodeIgniter\Model', $resource->getModel()); + $this->assertInstanceOf(Model::class, $resource->getModel()); // Note that the leading backslash is missing if we build it this way $this->assertSame('Tests\Support\Models\UserModel', $resource->getModelName()); diff --git a/tests/system/RESTful/ResourcePresenterTest.php b/tests/system/RESTful/ResourcePresenterTest.php index 26ea1084b196..568b395a778c 100644 --- a/tests/system/RESTful/ResourcePresenterTest.php +++ b/tests/system/RESTful/ResourcePresenterTest.php @@ -13,6 +13,7 @@ use CodeIgniter\CodeIgniter; use CodeIgniter\Config\Services; +use CodeIgniter\Model; use CodeIgniter\Router\RouteCollection; use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\Mock\MockCodeIgniter; @@ -34,10 +35,7 @@ */ final class ResourcePresenterTest extends CIUnitTestCase { - /** - * @var CodeIgniter - */ - protected $codeigniter; + protected CodeIgniter $codeigniter; /** * @var RouteCollection @@ -247,7 +245,7 @@ public function testModelByName() { $resource = new MockResourcePresenter(); $resource->setModel('\Tests\Support\Models\UserModel'); - $this->assertInstanceOf('CodeIgniter\Model', $resource->getModel()); + $this->assertInstanceOf(Model::class, $resource->getModel()); $this->assertSame('\Tests\Support\Models\UserModel', $resource->getModelName()); } @@ -256,7 +254,7 @@ public function testModelByObject() $resource = new MockResourcePresenter(); $model = new UserModel(); $resource->setModel($model); - $this->assertInstanceOf('CodeIgniter\Model', $resource->getModel()); + $this->assertInstanceOf(Model::class, $resource->getModel()); // Note that the leading backslash is missing if we build it this way $this->assertSame('Tests\Support\Models\UserModel', $resource->getModelName()); @@ -266,12 +264,12 @@ public function testChangeSetModelByObject() { $resource = new MockResourcePresenter(); $resource->setModel('\Tests\Support\Models\UserModel'); - $this->assertInstanceOf('CodeIgniter\Model', $resource->getModel()); + $this->assertInstanceOf(Model::class, $resource->getModel()); $this->assertSame('\Tests\Support\Models\UserModel', $resource->getModelName()); $model = new EntityModel(); $resource->setModel($model); - $this->assertInstanceOf('CodeIgniter\Model', $resource->getModel()); + $this->assertInstanceOf(Model::class, $resource->getModel()); $this->assertSame('Tests\Support\Models\EntityModel', $resource->getModelName()); } @@ -279,11 +277,11 @@ public function testChangeSetModelByName() { $resource = new MockResourcePresenter(); $resource->setModel('\Tests\Support\Models\UserModel'); - $this->assertInstanceOf('CodeIgniter\Model', $resource->getModel()); + $this->assertInstanceOf(Model::class, $resource->getModel()); $this->assertSame('\Tests\Support\Models\UserModel', $resource->getModelName()); $resource->setModel('\Tests\Support\Models\EntityModel'); - $this->assertInstanceOf('CodeIgniter\Model', $resource->getModel()); + $this->assertInstanceOf(Model::class, $resource->getModel()); $this->assertSame('\Tests\Support\Models\EntityModel', $resource->getModelName()); } } diff --git a/tests/system/Session/Handlers/DatabaseHandlerTest.php b/tests/system/Session/Handlers/DatabaseHandlerTest.php index 2349bc292bd8..7af077606cba 100644 --- a/tests/system/Session/Handlers/DatabaseHandlerTest.php +++ b/tests/system/Session/Handlers/DatabaseHandlerTest.php @@ -40,7 +40,7 @@ protected function setUp(): void protected function getInstance($options = []) { $defaults = [ - 'sessionDriver' => 'CodeIgniter\Session\Handlers\DatabaseHandler', + 'sessionDriver' => DatabaseHandler::class, 'sessionCookieName' => 'ci_session', 'sessionExpiration' => 7200, 'sessionSavePath' => 'ci_sessions', diff --git a/tests/system/Session/SessionTest.php b/tests/system/Session/SessionTest.php index c295e26ba7d3..574ffaf99ce9 100644 --- a/tests/system/Session/SessionTest.php +++ b/tests/system/Session/SessionTest.php @@ -41,7 +41,7 @@ protected function setUp(): void protected function getInstance($options = []) { $defaults = [ - 'sessionDriver' => 'CodeIgniter\Session\Handlers\FileHandler', + 'sessionDriver' => FileHandler::class, 'sessionCookieName' => 'ci_session', 'sessionExpiration' => 7200, 'sessionSavePath' => null, diff --git a/tests/system/Test/FabricatorTest.php b/tests/system/Test/FabricatorTest.php index f7ba5781979a..13de446cbcb9 100644 --- a/tests/system/Test/FabricatorTest.php +++ b/tests/system/Test/FabricatorTest.php @@ -26,10 +26,8 @@ final class FabricatorTest extends CIUnitTestCase { /** * Default formatters to use for UserModel. Should match detected version. - * - * @var array */ - protected $formatters = [ + protected array $formatters = [ 'name' => 'name', 'email' => 'email', 'country' => 'country', @@ -363,7 +361,7 @@ public function testMakeReturnsSingleton() $result = $fabricator->make(); - $this->assertInstanceOf('stdClass', $result); + $this->assertInstanceOf(stdClass::class, $result); } public function testMakeReturnsExpectedCount() @@ -383,7 +381,7 @@ public function testCreateMockReturnsSingleton() $result = $fabricator->create(null, true); - $this->assertInstanceOf('stdClass', $result); + $this->assertInstanceOf(stdClass::class, $result); } public function testCreateMockReturnsExpectedCount() diff --git a/tests/system/Test/FilterTestTraitTest.php b/tests/system/Test/FilterTestTraitTest.php index 15b98379fbcf..f3cb0a4a6165 100644 --- a/tests/system/Test/FilterTestTraitTest.php +++ b/tests/system/Test/FilterTestTraitTest.php @@ -11,8 +11,10 @@ namespace CodeIgniter\Test; +use Closure; use CodeIgniter\Filters\Filters; use CodeIgniter\HTTP\RequestInterface; +use InvalidArgumentException; use Tests\Support\Filters\Customfilter; /** @@ -50,12 +52,12 @@ public function testGetCallerReturnsClosure() $caller = $this->getFilterCaller('test-customfilter', 'before'); $this->assertIsCallable($caller); - $this->assertInstanceOf('Closure', $caller); + $this->assertInstanceOf(Closure::class, $caller); } public function testGetCallerInvalidPosition() { - $this->expectException('InvalidArgumentException'); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Invalid filter position passed: banana'); $this->getFilterCaller('test-customfilter', 'banana'); diff --git a/tests/system/View/CellTest.php b/tests/system/View/CellTest.php index 2d05fad5fbf2..f15e7ce16abb 100644 --- a/tests/system/View/CellTest.php +++ b/tests/system/View/CellTest.php @@ -11,6 +11,7 @@ namespace CodeIgniter\View; +use CodeIgniter\HTTP\Response; use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\Mock\MockCache; use CodeIgniter\View\Exceptions\ViewException; @@ -21,11 +22,7 @@ final class CellTest extends CIUnitTestCase { protected $cache; - - /** - * @var Cell - */ - protected $cell; + protected Cell $cell; protected function setUp(): void { @@ -252,6 +249,6 @@ public function testParametersDontMatch() public function testCallInitControllerIfMethodExists() { - $this->assertSame('CodeIgniter\HTTP\Response', $this->cell->render('\Tests\Support\View\SampleClassWithInitController::index')); + $this->assertSame(Response::class, $this->cell->render('\Tests\Support\View\SampleClassWithInitController::index')); } } From f33b0feb28c724df00273846512b1c0ef9f56412 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sun, 20 Mar 2022 01:25:13 +0700 Subject: [PATCH 0707/1246] Update system/Config/BaseService.php Co-authored-by: Mostafa Khudair <59371810+mostafakhudair@users.noreply.github.com> --- system/Config/BaseService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/Config/BaseService.php b/system/Config/BaseService.php index 4244b7a7097d..0e36c6254e9f 100644 --- a/system/Config/BaseService.php +++ b/system/Config/BaseService.php @@ -332,7 +332,7 @@ protected static function discoverServices(string $name, array $arguments) foreach ($files as $file) { $classname = $locator->getClassname($file); - if (! in_array($classname, [\CodeIgniter\Config\Services::class], true)) { + if (! in_array($classname, [Services::class], true)) { static::$services[] = new $classname(); } } From 74cb75c1b02a0fcc9812d7e8995805c2c28a7c69 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sun, 20 Mar 2022 01:25:18 +0700 Subject: [PATCH 0708/1246] Update system/Config/BaseService.php Co-authored-by: Mostafa Khudair <59371810+mostafakhudair@users.noreply.github.com> --- system/Config/BaseService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/Config/BaseService.php b/system/Config/BaseService.php index 0e36c6254e9f..ba2779d4f580 100644 --- a/system/Config/BaseService.php +++ b/system/Config/BaseService.php @@ -369,7 +369,7 @@ protected static function buildServicesCache(): void foreach ($files as $file) { $classname = $locator->getClassname($file); - if ($classname !== \CodeIgniter\Config\Services::class) { + if ($classname !== Services::class) { self::$serviceNames[] = $classname; static::$services[] = new $classname(); } From 8aa0a1eae255f5e0e81f7d098a4a1d39d2763669 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 20 Mar 2022 09:30:15 +0900 Subject: [PATCH 0709/1246] refactor: rename variable names --- system/Router/Router.php | 52 ++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/system/Router/Router.php b/system/Router/Router.php index da00d054e4af..f930a3ba3f9b 100644 --- a/system/Router/Router.php +++ b/system/Router/Router.php @@ -362,31 +362,31 @@ protected function checkRoutes(string $uri): bool : trim($uri, '/ '); // Loop through the route array looking for wildcards - foreach ($routes as $key => $val) { + foreach ($routes as $routeKey => $handler) { // Reset localeSegment $localeSegment = null; - $key = $key === '/' - ? $key - : ltrim($key, '/ '); + $routeKey = $routeKey === '/' + ? $routeKey + : ltrim($routeKey, '/ '); - $matchedKey = $key; + $matchedKey = $routeKey; // Are we dealing with a locale? - if (strpos($key, '{locale}') !== false) { - $localeSegment = array_search('{locale}', preg_split('/[\/]*((^[a-zA-Z0-9])|\(([^()]*)\))*[\/]+/m', $key), true); + if (strpos($routeKey, '{locale}') !== false) { + $localeSegment = array_search('{locale}', preg_split('/[\/]*((^[a-zA-Z0-9])|\(([^()]*)\))*[\/]+/m', $routeKey), true); // Replace it with a regex so it // will actually match. - $key = str_replace('/', '\/', $key); - $key = str_replace('{locale}', '[^\/]+', $key); + $routeKey = str_replace('/', '\/', $routeKey); + $routeKey = str_replace('{locale}', '[^\/]+', $routeKey); } // Does the RegEx match? - if (preg_match('#^' . $key . '$#u', $uri, $matches)) { + if (preg_match('#^' . $routeKey . '$#u', $uri, $matches)) { // Is this route supposed to redirect to another? - if ($this->collection->isRedirect($key)) { - throw new RedirectException(is_array($val) ? key($val) : $val, $this->collection->getRedirectCode($key)); + if ($this->collection->isRedirect($routeKey)) { + throw new RedirectException(is_array($handler) ? key($handler) : $handler, $this->collection->getRedirectCode($routeKey)); } // Store our locale so CodeIgniter object can // assign it to the Request. @@ -399,8 +399,8 @@ protected function checkRoutes(string $uri): bool // Are we using Closures? If so, then we need // to collect the params into an array // so it can be passed to the controller method later. - if (! is_string($val) && is_callable($val)) { - $this->controller = $val; + if (! is_string($handler) && is_callable($handler)) { + $this->controller = $handler; // Remove the original string from the matches array array_shift($matches); @@ -409,7 +409,7 @@ protected function checkRoutes(string $uri): bool $this->matchedRoute = [ $matchedKey, - $val, + $handler, ]; $this->matchedRouteOptions = $this->collection->getRoutesOptions($matchedKey); @@ -420,26 +420,26 @@ protected function checkRoutes(string $uri): bool // Support resource route when function with subdirectory // ex: $routes->resource('Admin/Admins'); - if (strpos($val, '$') !== false && strpos($key, '(') !== false && strpos($key, '/') !== false) { - $replacekey = str_replace('/(.*)', '', $key); - $val = preg_replace('#^' . $key . '$#u', $val, $uri); - $val = str_replace($replacekey, str_replace('/', '\\', $replacekey), $val); - } elseif (strpos($val, '$') !== false && strpos($key, '(') !== false) { - $val = preg_replace('#^' . $key . '$#u', $val, $uri); - } elseif (strpos($val, '/') !== false) { - [$controller, $method] = explode('::', $val); + if (strpos($handler, '$') !== false && strpos($routeKey, '(') !== false && strpos($routeKey, '/') !== false) { + $replacekey = str_replace('/(.*)', '', $routeKey); + $handler = preg_replace('#^' . $routeKey . '$#u', $handler, $uri); + $handler = str_replace($replacekey, str_replace('/', '\\', $replacekey), $handler); + } elseif (strpos($handler, '$') !== false && strpos($routeKey, '(') !== false) { + $handler = preg_replace('#^' . $routeKey . '$#u', $handler, $uri); + } elseif (strpos($handler, '/') !== false) { + [$controller, $method] = explode('::', $handler); // Only replace slashes in the controller, not in the method. $controller = str_replace('/', '\\', $controller); - $val = $controller . '::' . $method; + $handler = $controller . '::' . $method; } - $this->setRequest(explode('/', $val)); + $this->setRequest(explode('/', $handler)); $this->matchedRoute = [ $matchedKey, - $val, + $handler, ]; $this->matchedRouteOptions = $this->collection->getRoutesOptions($matchedKey); From bb6f480e3039939241257b29d7be30bb8f5ef9e0 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 20 Mar 2022 09:40:58 +0900 Subject: [PATCH 0710/1246] docs: remove comments I don't understand what's saying. --- system/Router/Router.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/system/Router/Router.php b/system/Router/Router.php index f930a3ba3f9b..1f8d2ea2f7db 100644 --- a/system/Router/Router.php +++ b/system/Router/Router.php @@ -416,10 +416,7 @@ protected function checkRoutes(string $uri): bool return true; } - // Are we using the default method for back-references? - // Support resource route when function with subdirectory - // ex: $routes->resource('Admin/Admins'); if (strpos($handler, '$') !== false && strpos($routeKey, '(') !== false && strpos($routeKey, '/') !== false) { $replacekey = str_replace('/(.*)', '', $routeKey); $handler = preg_replace('#^' . $routeKey . '$#u', $handler, $uri); From 44d68fa6908f554708b795e098ab1f0b4161f63e Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 20 Mar 2022 09:46:49 +0900 Subject: [PATCH 0711/1246] test: fix route key All lowercase is better. --- tests/system/Router/RouterTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/system/Router/RouterTest.php b/tests/system/Router/RouterTest.php index 4ba9972b1288..c3fed4d15660 100644 --- a/tests/system/Router/RouterTest.php +++ b/tests/system/Router/RouterTest.php @@ -59,7 +59,7 @@ protected function setUp(): void 'books/(:num)/(:alpha)/(:num)' => 'Blog::show/$3/$1', 'closure/(:num)/(:alpha)' => static fn ($num, $str) => $num . '-' . $str, '{locale}/pages' => 'App\Pages::list_all', - 'Admin/Admins' => 'App\Admin\Admins::list_all', + 'admin/admins' => 'App\Admin\Admins::list_all', '/some/slash' => 'App\Slash::index', 'objects/(:segment)/sort/(:segment)/([A-Z]{3,7})' => 'AdminList::objectsSortCreate/$1/$2/$3', ]; @@ -398,7 +398,7 @@ public function testRouteResource() { $router = new Router($this->collection, $this->request); - $router->handle('Admin/Admins'); + $router->handle('admin/admins'); $this->assertSame('\App\Admin\Admins', $router->controllerName()); $this->assertSame('list_all', $router->methodName()); From 53ac90afe0e73b19ec3aca8399c52a1a7665b50f Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 20 Mar 2022 10:00:22 +0900 Subject: [PATCH 0712/1246] test: remove empty tearDown() --- tests/system/Router/RouterTest.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/system/Router/RouterTest.php b/tests/system/Router/RouterTest.php index c3fed4d15660..06e6b2033daa 100644 --- a/tests/system/Router/RouterTest.php +++ b/tests/system/Router/RouterTest.php @@ -69,10 +69,6 @@ protected function setUp(): void $this->request->setMethod('get'); } - protected function tearDown(): void - { - } - public function testEmptyURIMatchesDefaults() { $router = new Router($this->collection, $this->request); From 98fdcb909e0d37ed14244d5d436ce9d7c6864ffe Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 20 Mar 2022 10:00:45 +0900 Subject: [PATCH 0713/1246] refactor: make if conditions a bit easier to read --- system/Router/Router.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/system/Router/Router.php b/system/Router/Router.php index 1f8d2ea2f7db..ccf83f143740 100644 --- a/system/Router/Router.php +++ b/system/Router/Router.php @@ -417,12 +417,16 @@ protected function checkRoutes(string $uri): bool return true; } - if (strpos($handler, '$') !== false && strpos($routeKey, '(') !== false && strpos($routeKey, '/') !== false) { - $replacekey = str_replace('/(.*)', '', $routeKey); - $handler = preg_replace('#^' . $routeKey . '$#u', $handler, $uri); - $handler = str_replace($replacekey, str_replace('/', '\\', $replacekey), $handler); - } elseif (strpos($handler, '$') !== false && strpos($routeKey, '(') !== false) { - $handler = preg_replace('#^' . $routeKey . '$#u', $handler, $uri); + if (strpos($handler, '$') !== false && strpos($routeKey, '(') !== false) { + // Using back-references + + if (strpos($routeKey, '/') !== false) { + $replacekey = str_replace('/(.*)', '', $routeKey); + $handler = preg_replace('#^' . $routeKey . '$#u', $handler, $uri); + $handler = str_replace($replacekey, str_replace('/', '\\', $replacekey), $handler); + } else { + $handler = preg_replace('#^' . $routeKey . '$#u', $handler, $uri); + } } elseif (strpos($handler, '/') !== false) { [$controller, $method] = explode('::', $handler); From 46401c205dcf7c63fab4d31a70fcb87ae052b49a Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 20 Mar 2022 10:21:04 +0900 Subject: [PATCH 0714/1246] fix: add check for dynamic controller Dynamic controller should not be used, but if you set a route like this, it worked. $routes->get('(:segment)/(:segment)/(:segment)', '\App\Controllers\\\\$2::$3'); --- system/Language/en/Router.php | 5 +++-- system/Router/Exceptions/RouterException.php | 10 ++++++++++ system/Router/Router.php | 6 ++++++ tests/system/Router/RouterTest.php | 12 ++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/system/Language/en/Router.php b/system/Language/en/Router.php index 9f6cdb700f04..90aaa132b489 100644 --- a/system/Language/en/Router.php +++ b/system/Language/en/Router.php @@ -11,6 +11,7 @@ // Router language settings return [ - 'invalidParameter' => 'A parameter does not match the expected type.', - 'missingDefaultRoute' => 'Unable to determine what should be displayed. A default route has not been specified in the routing file.', + 'invalidParameter' => 'A parameter does not match the expected type.', + 'missingDefaultRoute' => 'Unable to determine what should be displayed. A default route has not been specified in the routing file.', + 'invalidDynamicController' => 'A dynamic controller is not allowed for security reasons. Route handler: {0}', ]; diff --git a/system/Router/Exceptions/RouterException.php b/system/Router/Exceptions/RouterException.php index 8c469d967b78..b50042b3421b 100644 --- a/system/Router/Exceptions/RouterException.php +++ b/system/Router/Exceptions/RouterException.php @@ -58,4 +58,14 @@ public static function forInvalidRoute(string $route) { return new static(lang('HTTP.invalidRoute', [$route])); } + + /** + * Throw when dynamic controller. + * + * @return RouterException + */ + public static function forDynamicController(string $handler) + { + return new static(lang('Router.invalidDynamicController', [$handler])); + } } diff --git a/system/Router/Router.php b/system/Router/Router.php index ccf83f143740..42f2eb0c7a42 100644 --- a/system/Router/Router.php +++ b/system/Router/Router.php @@ -420,6 +420,12 @@ protected function checkRoutes(string $uri): bool if (strpos($handler, '$') !== false && strpos($routeKey, '(') !== false) { // Using back-references + // Checks dynamic controller + [$controller, ] = explode('::', $handler); + if (strpos($controller, '$') !== false) { + throw RouterException::forDynamicController($handler); + } + if (strpos($routeKey, '/') !== false) { $replacekey = str_replace('/(.*)', '', $routeKey); $handler = preg_replace('#^' . $routeKey . '$#u', $handler, $uri); diff --git a/tests/system/Router/RouterTest.php b/tests/system/Router/RouterTest.php index 06e6b2033daa..b2c476f5add6 100644 --- a/tests/system/Router/RouterTest.php +++ b/tests/system/Router/RouterTest.php @@ -14,6 +14,7 @@ use CodeIgniter\Config\Services; use CodeIgniter\Exceptions\PageNotFoundException; use CodeIgniter\HTTP\IncomingRequest; +use CodeIgniter\Router\Exceptions\RouterException; use CodeIgniter\Test\CIUnitTestCase; use Config\Modules; use Tests\Support\Filters\Customfilter; @@ -62,6 +63,7 @@ protected function setUp(): void 'admin/admins' => 'App\Admin\Admins::list_all', '/some/slash' => 'App\Slash::index', 'objects/(:segment)/sort/(:segment)/([A-Z]{3,7})' => 'AdminList::objectsSortCreate/$1/$2/$3', + '(:segment)/(:segment)/(:segment)' => '$2::$3/$1', ]; $this->collection->map($routes); @@ -410,6 +412,16 @@ public function testRouteWithLeadingSlash() $this->assertSame('index', $router->methodName()); } + public function testRouteWithDynamicController() + { + $this->expectException(RouterException::class); + $this->expectExceptionMessage('A dynamic controller is not allowed for security reasons. Route handler: \$2::$3/$1'); + + $router = new Router($this->collection, $this->request); + + $router->handle('en/zoo/bar'); + } + // options need to be declared separately, to not confuse PHPCBF public function testMatchedRouteOptions() { From 579d0d5119423a8c7d4bc350c1bcf622a623c422 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 20 Mar 2022 11:13:40 +0900 Subject: [PATCH 0715/1246] docs: change the description to note to make it stand out --- user_guide_src/source/helpers/url_helper.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/user_guide_src/source/helpers/url_helper.rst b/user_guide_src/source/helpers/url_helper.rst index 8f0252c27cff..9f673b88e8bb 100644 --- a/user_guide_src/source/helpers/url_helper.rst +++ b/user_guide_src/source/helpers/url_helper.rst @@ -106,10 +106,10 @@ The following functions are available: Returns the full URL (including segments) of the page the user was previously on. - Due to security issues of blindly trusting the HTTP_REFERER system variable, CodeIgniter will - store previously visited pages in the session if it's available. This ensures that we always - use a known and trusted source. If the session hasn't been loaded, or is otherwise unavailable, - then a sanitized version of HTTP_REFERER will be used. + .. note:: Due to security issues of blindly trusting the HTTP_REFERER system variable, CodeIgniter will + store previously visited pages in the session if it's available. This ensures that we always + use a known and trusted source. If the session hasn't been loaded, or is otherwise unavailable, + then a sanitized version of HTTP_REFERER will be used. .. php:function:: uri_string([$relative = false]) From fedf4f18ec2752b4f3651ead5dfe0430ba19a736 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 20 Mar 2022 11:14:36 +0900 Subject: [PATCH 0716/1246] docs: add explanation about redirect()->back() --- user_guide_src/source/general/common_functions.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/user_guide_src/source/general/common_functions.rst b/user_guide_src/source/general/common_functions.rst index 920e2496b43b..f8cbcf69bc53 100755 --- a/user_guide_src/source/general/common_functions.rst +++ b/user_guide_src/source/general/common_functions.rst @@ -303,6 +303,10 @@ Miscellaneous Functions .. literalinclude:: common_functions/005.php + .. note:: ``redirect()->back()`` is not the same as browser "back" button. + It takes a visitor to "the last page viewed during the Session" when the Session is available. + If the Session hasn’t been loaded, or is otherwise unavailable, then a sanitized version of HTTP_REFERER will be used. + When passing an argument into the function, it is treated as a named/reverse-routed route, not a relative/full URI, treating it the same as using ``redirect()->route()``: From e4fcba2749b3e7e5dd3af55b5cdd057820343fe0 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 20 Mar 2022 16:14:40 +0900 Subject: [PATCH 0717/1246] fix: failover's DBPrefix not working Fixes #5812 --- system/Database/BaseConnection.php | 7 +++++++ tests/system/Database/Live/ConnectTest.php | 12 ++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/system/Database/BaseConnection.php b/system/Database/BaseConnection.php index 4f54c1980830..9c803d0c1372 100644 --- a/system/Database/BaseConnection.php +++ b/system/Database/BaseConnection.php @@ -342,6 +342,13 @@ public function __construct(array $params) if (class_exists($queryClass)) { $this->queryClass = $queryClass; } + + if ($this->failover !== []) { + // If there is a failover database, connect now to do failover. + // Otherwise, Query Builder creates SQL statement with the main database config + // (DBPrefix) even when the main database is down. + $this->initialize(); + } } /** diff --git a/tests/system/Database/Live/ConnectTest.php b/tests/system/Database/Live/ConnectTest.php index 743b5450cca3..1757f91cb676 100644 --- a/tests/system/Database/Live/ConnectTest.php +++ b/tests/system/Database/Live/ConnectTest.php @@ -95,14 +95,22 @@ public function testConnectWorksWithGroupName() public function testConnectWithFailover() { $this->tests['failover'][] = $this->tests; - unset($this->tests['failover'][0]['failover']); + // Change main's DBPrefix + $this->tests['DBPrefix'] = 'main_'; + + if ($this->tests['DBDriver'] === 'SQLite3') { + // Change main's database path to fail to connect + $this->tests['database'] = '/does/not/exists/test.db'; + } + $this->tests['username'] = 'wrong'; $db1 = Database::connect($this->tests); - $this->assertSame($this->tests['failover'][0]['DBDriver'], $this->getPrivateProperty($db1, 'DBDriver')); + $this->assertSame($this->tests['failover'][0]['DBPrefix'], $this->getPrivateProperty($db1, 'DBPrefix')); + $this->assertGreaterThanOrEqual(0, count($db1->listTables())); } } From 5a456125d8a8503945568564b91a2ad256d2d184 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 20 Mar 2022 16:40:08 +0900 Subject: [PATCH 0718/1246] test: fix failed test --- tests/system/Database/BaseConnectionTest.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/system/Database/BaseConnectionTest.php b/tests/system/Database/BaseConnectionTest.php index 9bb8ddee1499..781588dd78e8 100644 --- a/tests/system/Database/BaseConnectionTest.php +++ b/tests/system/Database/BaseConnectionTest.php @@ -105,8 +105,11 @@ public function testCanConnectToFailoverWhenNoConnectionAvailable() $options = $this->options; $options['failover'] = [$this->failoverOptions]; - $db = new MockConnection($options); - $db->shouldReturn('connect', [false, 345])->initialize(); + $db = new class ($options) extends MockConnection { + protected $returnValues = [ + 'connect' => [false, 345], + ]; + }; $this->assertSame(345, $db->getConnection()); $this->assertSame('failover', $db->username); From 6a0ed54b9922c7c88dce16033615750d7fe67d36 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sun, 20 Mar 2022 15:45:17 +0700 Subject: [PATCH 0719/1246] revert SQLite3 as string --- app/Config/Database.php | 3 +- rector.php | 11 +++++++ system/Commands/Database/CreateDatabase.php | 3 +- system/Database/SQLite3/Connection.php | 2 +- tests/system/Database/ConfigTest.php | 5 ++- tests/system/Database/Live/DbUtilsTest.php | 5 ++- tests/system/Database/Live/ForgeTest.php | 31 +++++++++---------- tests/system/Database/Live/GetTest.php | 5 ++- .../Database/Live/SQLite/AlterTableTest.php | 3 +- .../Migrations/MigrationRunnerTest.php | 3 +- 10 files changed, 37 insertions(+), 34 deletions(-) diff --git a/app/Config/Database.php b/app/Config/Database.php index 376de53a821d..1e6340899bf4 100644 --- a/app/Config/Database.php +++ b/app/Config/Database.php @@ -3,7 +3,6 @@ namespace Config; use CodeIgniter\Database\Config; -use SQLite3; /** * Database Configuration @@ -63,7 +62,7 @@ class Database extends Config 'username' => '', 'password' => '', 'database' => ':memory:', - 'DBDriver' => SQLite3::class, + 'DBDriver' => 'SQLite3', 'DBPrefix' => 'db_', // Needed to ensure we're working correctly with prefixes live. DO NOT REMOVE FOR CI DEVS 'pConnect' => false, 'DBDebug' => (ENVIRONMENT !== 'production'), diff --git a/rector.php b/rector.php index 6c2bc99bcf8d..c43f25f3a274 100644 --- a/rector.php +++ b/rector.php @@ -111,6 +111,17 @@ // expected Qualified name __DIR__ . '/tests/system/Autoloader/FileLocatorTest.php', + + // SQLite3 as string + __DIR__ . '/app/Config/Database.php', + __DIR__ . '/system/Commands/Database/CreateDatabase.php', + __DIR__ . '/system/Database/SQLite3/Connection.php', + __DIR__ . '/tests/system/Database/ConfigTest.php', + __DIR__ . '/tests/system/Database/Live/DbUtilsTest.php', + __DIR__ . '/tests/system/Database/Live/ForgeTest.php', + __DIR__ . '/tests/system/Database/Live/GetTest.php', + __DIR__ . '/tests/system/Database/Live/SQLite/AlterTableTest.php', + __DIR__ . '/tests/system/Database/Migrations/MigrationRunnerTest.php', ], // sometime too detail diff --git a/system/Commands/Database/CreateDatabase.php b/system/Commands/Database/CreateDatabase.php index 0682f945b9bf..17e1e51bb68b 100644 --- a/system/Commands/Database/CreateDatabase.php +++ b/system/Commands/Database/CreateDatabase.php @@ -16,7 +16,6 @@ use CodeIgniter\Config\Factories; use CodeIgniter\Database\SQLite3\Connection; use Config\Database; -use SQLite3; use Throwable; /** @@ -107,7 +106,7 @@ public function run(array $params) $name = str_replace(['.db', '.sqlite'], '', $name) . ".{$ext}"; } - $config->{$group}['DBDriver'] = SQLite3::class; + $config->{$group}['DBDriver'] = 'SQLite3'; $config->{$group}['database'] = $name; if ($name !== ':memory:') { diff --git a/system/Database/SQLite3/Connection.php b/system/Database/SQLite3/Connection.php index e335e7985ba7..39fbca8bcfea 100644 --- a/system/Database/SQLite3/Connection.php +++ b/system/Database/SQLite3/Connection.php @@ -28,7 +28,7 @@ class Connection extends BaseConnection * * @var string */ - public $DBDriver = SQLite3::class; + public $DBDriver = 'SQLite3'; /** * Identifier escape character diff --git a/tests/system/Database/ConfigTest.php b/tests/system/Database/ConfigTest.php index 301a95158bf1..fdbc42749d1d 100644 --- a/tests/system/Database/ConfigTest.php +++ b/tests/system/Database/ConfigTest.php @@ -13,7 +13,6 @@ use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\ReflectionHelper; -use SQLite3; /** * @internal @@ -47,7 +46,7 @@ final class ConfigTest extends CIUnitTestCase 'username' => '', 'password' => '', 'database' => '', - 'DBDriver' => SQLite3::class, + 'DBDriver' => 'SQLite3', 'DBPrefix' => 't_', 'pConnect' => false, 'DBDebug' => (ENVIRONMENT !== 'production'), @@ -66,7 +65,7 @@ final class ConfigTest extends CIUnitTestCase 'username' => '', 'password' => '', 'database' => '', - 'DBDriver' => SQLite3::class, + 'DBDriver' => 'SQLite3', 'DBPrefix' => 't_', 'pConnect' => false, 'DBDebug' => (ENVIRONMENT !== 'production'), diff --git a/tests/system/Database/Live/DbUtilsTest.php b/tests/system/Database/Live/DbUtilsTest.php index 414412a72ded..e767d0b6991d 100644 --- a/tests/system/Database/Live/DbUtilsTest.php +++ b/tests/system/Database/Live/DbUtilsTest.php @@ -15,7 +15,6 @@ use CodeIgniter\Database\Exceptions\DatabaseException; use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\DatabaseTestTrait; -use SQLite3; /** * @group DatabaseLive @@ -81,7 +80,7 @@ public function testUtilsListDatabases() $databases = $util->listDatabases(); $this->assertContains($this->db->getDatabase(), $databases); - } elseif ($this->db->DBDriver === SQLite3::class) { + } elseif ($this->db->DBDriver === 'SQLite3') { $this->expectException(DatabaseException::class); $this->expectExceptionMessage('Unsupported feature of the database platform you are using.'); @@ -97,7 +96,7 @@ public function testUtilsDatabaseExist() $exist = $util->databaseExists($this->db->getDatabase()); $this->assertTrue($exist); - } elseif ($this->db->DBDriver === SQLite3::class) { + } elseif ($this->db->DBDriver === 'SQLite3') { $this->expectException(DatabaseException::class); $this->expectExceptionMessage('Unsupported feature of the database platform you are using.'); diff --git a/tests/system/Database/Live/ForgeTest.php b/tests/system/Database/Live/ForgeTest.php index f83593ed320e..113f2c0a211e 100644 --- a/tests/system/Database/Live/ForgeTest.php +++ b/tests/system/Database/Live/ForgeTest.php @@ -18,7 +18,6 @@ use Config\Database; use InvalidArgumentException; use RuntimeException; -use SQLite3; /** * @group DatabaseLive @@ -57,7 +56,7 @@ public function testCreateDatabaseIfNotExists() $dbName = 'test_forge_database_exist'; $databaseCreateIfNotExists = $this->forge->createDatabase($dbName, true); - if ($this->db->DBDriver !== SQLite3::class) { + if ($this->db->DBDriver !== 'SQLite3') { $this->forge->dropDatabase($dbName); } @@ -73,7 +72,7 @@ public function testCreateDatabaseIfNotExistsWithDb() $this->forge->createDatabase($dbName); $databaseExists = $this->forge->createDatabase($dbName, true); - if ($this->db->DBDriver !== SQLite3::class) { + if ($this->db->DBDriver !== 'SQLite3') { $this->forge->dropDatabase($dbName); } @@ -85,7 +84,7 @@ public function testDropDatabase() if ($this->db->DBDriver === 'OCI8') { $this->markTestSkipped('OCI8 does not support drop database.'); } - if ($this->db->DBDriver === SQLite3::class) { + if ($this->db->DBDriver === 'SQLite3') { $this->markTestSkipped('SQLite3 requires file path to drop database'); } @@ -98,7 +97,7 @@ public function testCreateDatabaseExceptionNoCreateStatement() { $this->setPrivateProperty($this->forge, 'createDatabaseStr', false); - if ($this->db->DBDriver === SQLite3::class) { + if ($this->db->DBDriver === 'SQLite3') { $databaseCreated = $this->forge->createDatabase('test_forge_database'); $this->assertTrue($databaseCreated); } else { @@ -113,7 +112,7 @@ public function testDropDatabaseExceptionNoDropStatement() { $this->setPrivateProperty($this->forge, 'dropDatabaseStr', false); - if ($this->db->DBDriver === SQLite3::class) { + if ($this->db->DBDriver === 'SQLite3') { $this->markTestSkipped('SQLite3 requires file path to drop database'); } else { $this->expectException(DatabaseException::class); @@ -176,7 +175,7 @@ public function testCreateTableApplyBigInt() $this->assertSame(strtolower($fieldsData[0]->type), 'bigint'); } elseif ($this->db->DBDriver === 'Postgre') { $this->assertSame(strtolower($fieldsData[0]->type), 'bigint'); - } elseif ($this->db->DBDriver === SQLite3::class) { + } elseif ($this->db->DBDriver === 'SQLite3') { $this->assertSame(strtolower($fieldsData[0]->type), 'integer'); } elseif ($this->db->DBDriver === 'OCI8') { $this->assertSame(strtolower($fieldsData[0]->type), 'number'); @@ -192,7 +191,7 @@ public function testCreateTableWithAttributes() if ($this->db->DBDriver === 'OCI8') { $this->markTestSkipped('OCI8 does not support comments on tables or columns.'); } - if ($this->db->DBDriver === SQLite3::class) { + if ($this->db->DBDriver === 'SQLite3') { $this->markTestSkipped('SQLite3 does not support comments on tables or columns.'); } @@ -214,7 +213,7 @@ public function testCreateTableWithAttributes() public function testCreateTableWithArrayFieldConstraints() { - if (in_array($this->db->DBDriver, ['MySQLi', SQLite3::class], true)) { + if (in_array($this->db->DBDriver, ['MySQLi', 'SQLite3'], true)) { $this->forge->dropTable('forge_array_constraint', true); $this->forge->addField([ 'status' => [ @@ -232,7 +231,7 @@ public function testCreateTableWithArrayFieldConstraints() $this->assertSame('status', $fields[0]->name); - if ($this->db->DBDriver === SQLite3::class) { + if ($this->db->DBDriver === 'SQLite3') { // SQLite3 converts array constraints to TEXT CHECK(...) $this->assertSame('TEXT', $fields[0]->type); } else { @@ -432,7 +431,7 @@ public function testForeignKey() $foreignKeyData = $this->db->getForeignKeyData($tableName); - if ($this->db->DBDriver === SQLite3::class) { + if ($this->db->DBDriver === 'SQLite3') { $this->assertSame($foreignKeyData[0]->constraint_name, 'users_id to db_forge_test_users.id'); $this->assertSame($foreignKeyData[0]->sequence, 0); } elseif ($this->db->DBDriver === 'OCI8') { @@ -554,7 +553,7 @@ public function testCompositeForeignKey() $foreignKeyData = $this->db->getForeignKeyData($forgeTestInvoicesTableName); - if ($this->db->DBDriver === SQLite3::class) { + if ($this->db->DBDriver === 'SQLite3') { $this->assertSame('users_id to db_forge_test_users.id', $foreignKeyData[0]->constraint_name); $this->assertSame(0, $foreignKeyData[0]->sequence); $this->assertSame('users_second_id to db_forge_test_users.second_id', $foreignKeyData[1]->constraint_name); @@ -844,7 +843,7 @@ public function testAddFields() $this->assertSame(32, (int) $fieldsData[0]->max_length); $this->assertNull($fieldsData[1]->default); $this->assertSame(255, (int) $fieldsData[1]->max_length); - } elseif ($this->db->DBDriver === SQLite3::class) { + } elseif ($this->db->DBDriver === 'SQLite3') { $this->assertSame('integer', strtolower($fieldsData[0]->type)); $this->assertSame('varchar', strtolower($fieldsData[1]->type)); $this->assertNull($fieldsData[1]->default); @@ -869,7 +868,7 @@ public function testAddFields() public function testCompositeKey() { // SQLite3 uses auto increment different - $uniqueOrAuto = $this->db->DBDriver === SQLite3::class ? 'unique' : 'auto_increment'; + $uniqueOrAuto = $this->db->DBDriver === 'SQLite3' ? 'unique' : 'auto_increment'; $this->forge->addField([ 'id' => [ @@ -917,7 +916,7 @@ public function testCompositeKey() $this->assertSame($keys['db_forge_test_1_code_active']->name, 'db_forge_test_1_code_active'); $this->assertSame($keys['db_forge_test_1_code_active']->fields, ['code', 'active']); $this->assertSame($keys['db_forge_test_1_code_active']->type, 'UNIQUE'); - } elseif ($this->db->DBDriver === SQLite3::class) { + } elseif ($this->db->DBDriver === 'SQLite3') { $this->assertSame($keys['sqlite_autoindex_db_forge_test_1_1']->name, 'sqlite_autoindex_db_forge_test_1_1'); $this->assertSame($keys['sqlite_autoindex_db_forge_test_1_1']->fields, ['id']); $this->assertSame($keys['db_forge_test_1_code_company']->name, 'db_forge_test_1_code_company'); @@ -1055,7 +1054,7 @@ public function testDropTableSuccess() $this->assertFalse($this->db->tableExists('dropTest')); - if ($this->db->DBDriver === SQLite3::class) { + if ($this->db->DBDriver === 'SQLite3') { $this->assertCount(0, $this->db->getIndexData('droptest')); } } diff --git a/tests/system/Database/Live/GetTest.php b/tests/system/Database/Live/GetTest.php index 768f24d72de3..20ae2e099d0d 100644 --- a/tests/system/Database/Live/GetTest.php +++ b/tests/system/Database/Live/GetTest.php @@ -14,7 +14,6 @@ use CodeIgniter\Database\Exceptions\DatabaseException; use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\DatabaseTestTrait; -use SQLite3; /** * @group DatabaseLive @@ -92,7 +91,7 @@ public function testGetFieldData() $typeTest = $this->db->table('type_test')->get()->getFieldData(); - if ($this->db->DBDriver === SQLite3::class) { + if ($this->db->DBDriver === 'SQLite3') { $this->assertSame('integer', $typeTest[0]->type_name); // INTEGER AUTO INC $this->assertSame('text', $typeTest[1]->type_name); // VARCHAR $this->assertSame('text', $typeTest[2]->type_name); // CHAR @@ -173,7 +172,7 @@ public function testGetDataSeek() { $data = $this->db->table('job')->get(); - if ($this->db->DBDriver === SQLite3::class) { + if ($this->db->DBDriver === 'SQLite3') { $this->expectException(DatabaseException::class); $this->expectExceptionMessage('SQLite3 doesn\'t support seeking to other offset.'); } elseif ($this->db->DBDriver === 'OCI8') { diff --git a/tests/system/Database/Live/SQLite/AlterTableTest.php b/tests/system/Database/Live/SQLite/AlterTableTest.php index 8889c9d8f639..ff103d699510 100644 --- a/tests/system/Database/Live/SQLite/AlterTableTest.php +++ b/tests/system/Database/Live/SQLite/AlterTableTest.php @@ -18,7 +18,6 @@ use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\DatabaseTestTrait; use Config\Database; -use SQLite3; /** * @group DatabaseLive @@ -50,7 +49,7 @@ protected function setUp(): void parent::setUp(); $config = [ - 'DBDriver' => SQLite3::class, + 'DBDriver' => 'SQLite3', 'database' => 'database.db', ]; diff --git a/tests/system/Database/Migrations/MigrationRunnerTest.php b/tests/system/Database/Migrations/MigrationRunnerTest.php index 9a5f467ed9c2..e97e4e38e56c 100644 --- a/tests/system/Database/Migrations/MigrationRunnerTest.php +++ b/tests/system/Database/Migrations/MigrationRunnerTest.php @@ -22,7 +22,6 @@ use Config\Migrations; use Config\Services; use org\bovigo\vfs\vfsStream; -use SQLite3; /** * @group DatabaseLive @@ -75,7 +74,7 @@ public function testLoadsDefaultDatabaseWhenNoneSpecified() $this->assertInstanceOf(BaseConnection::class, $db); $this->assertSame( - ($dbConfig->tests['DBDriver'] === SQLite3::class ? WRITEPATH : '') . $dbConfig->tests['database'], + ($dbConfig->tests['DBDriver'] === 'SQLite3' ? WRITEPATH : '') . $dbConfig->tests['database'], $this->getPrivateProperty($db, 'database') ); $this->assertSame($dbConfig->tests['DBDriver'], $this->getPrivateProperty($db, 'DBDriver')); From 4ccda780e5f8300cc210a6834851f8f99f94d4c9 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sun, 20 Mar 2022 17:58:20 +0700 Subject: [PATCH 0720/1246] Update tests/system/Encryption/Handlers/SodiumHandlerTest.php Co-authored-by: kenjis --- tests/system/Encryption/Handlers/SodiumHandlerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/Encryption/Handlers/SodiumHandlerTest.php b/tests/system/Encryption/Handlers/SodiumHandlerTest.php index 421af43e1330..e7cf3a54eef5 100644 --- a/tests/system/Encryption/Handlers/SodiumHandlerTest.php +++ b/tests/system/Encryption/Handlers/SodiumHandlerTest.php @@ -21,7 +21,7 @@ */ final class SodiumHandlerTest extends CIUnitTestCase { - protected \CodeIgniter\Encryption\Encryption $encryption; + protected Encryption $encryption; protected \Config\Encryption $config; protected function setUp(): void From de9adf5d2e2061abfc156f4450aa7e2d175c8f26 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sun, 20 Mar 2022 17:58:55 +0700 Subject: [PATCH 0721/1246] Update tests/system/Encryption/Handlers/SodiumHandlerTest.php Co-authored-by: kenjis --- tests/system/Encryption/Handlers/SodiumHandlerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/Encryption/Handlers/SodiumHandlerTest.php b/tests/system/Encryption/Handlers/SodiumHandlerTest.php index e7cf3a54eef5..28319b477ea6 100644 --- a/tests/system/Encryption/Handlers/SodiumHandlerTest.php +++ b/tests/system/Encryption/Handlers/SodiumHandlerTest.php @@ -22,7 +22,7 @@ final class SodiumHandlerTest extends CIUnitTestCase { protected Encryption $encryption; - protected \Config\Encryption $config; + protected EncryptionConfig $config; protected function setUp(): void { From 977defed45be74def619915bb5390fee789056e2 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sun, 20 Mar 2022 18:00:43 +0700 Subject: [PATCH 0722/1246] use Encryption class --- tests/system/Encryption/EncryptionTest.php | 2 +- tests/system/Encryption/Handlers/OpenSSLHandlerTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/system/Encryption/EncryptionTest.php b/tests/system/Encryption/EncryptionTest.php index cb4eb4cad7da..c5681e10e66a 100644 --- a/tests/system/Encryption/EncryptionTest.php +++ b/tests/system/Encryption/EncryptionTest.php @@ -21,7 +21,7 @@ */ final class EncryptionTest extends CIUnitTestCase { - protected \CodeIgniter\Encryption\Encryption $encryption; + protected Encryption $encryption; protected function setUp(): void { diff --git a/tests/system/Encryption/Handlers/OpenSSLHandlerTest.php b/tests/system/Encryption/Handlers/OpenSSLHandlerTest.php index 5427c99a5edb..81f3959710bc 100644 --- a/tests/system/Encryption/Handlers/OpenSSLHandlerTest.php +++ b/tests/system/Encryption/Handlers/OpenSSLHandlerTest.php @@ -21,7 +21,7 @@ */ final class OpenSSLHandlerTest extends CIUnitTestCase { - protected \CodeIgniter\Encryption\Encryption $encryption; + protected Encryption $encryption; protected function setUp(): void { From 0176bb4224c3fcdf86b5c526808a1d754035154b Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Mon, 21 Mar 2022 01:39:09 +0700 Subject: [PATCH 0723/1246] exclude native classes --- rector.php | 20 +++++++++---------- system/CodeIgniter.php | 2 +- system/Database/BaseResult.php | 3 +-- system/Database/MySQLi/Result.php | 2 +- system/Database/OCI8/Result.php | 5 ++--- system/Database/Postgre/Result.php | 2 +- system/Database/SQLSRV/Result.php | 2 +- system/Database/SQLite3/Result.php | 4 ++-- system/Test/Fabricator.php | 3 +-- system/Test/Mock/MockResult.php | 3 +-- tests/system/Autoloader/AutoloaderTest.php | 3 +-- .../system/Cache/Handlers/BaseHandlerTest.php | 5 ++--- tests/system/CommonFunctionsTest.php | 3 +-- tests/system/Config/DotEnvTest.php | 5 ++--- tests/system/Config/FactoriesTest.php | 8 ++++---- tests/system/Cookie/CookieTest.php | 3 +-- tests/system/Database/Builder/WhereTest.php | 5 ++--- tests/system/Database/DatabaseSeederTest.php | 7 +++---- tests/system/Database/Live/ForgeTest.php | 7 +++---- tests/system/Entity/EntityTest.php | 5 ++--- tests/system/Helpers/FilesystemHelperTest.php | 5 ++--- tests/system/Models/FindModelTest.php | 3 +-- .../system/Models/MiscellaneousModelTest.php | 3 +-- tests/system/Test/ControllerTestTraitTest.php | 5 ++--- tests/system/Test/DOMParserTest.php | 4 +--- tests/system/Test/FabricatorTest.php | 12 +++++------ tests/system/Test/FilterTestTraitTest.php | 6 ++---- 27 files changed, 55 insertions(+), 80 deletions(-) diff --git a/rector.php b/rector.php index c43f25f3a274..9ee8a4217d21 100644 --- a/rector.php +++ b/rector.php @@ -111,17 +111,6 @@ // expected Qualified name __DIR__ . '/tests/system/Autoloader/FileLocatorTest.php', - - // SQLite3 as string - __DIR__ . '/app/Config/Database.php', - __DIR__ . '/system/Commands/Database/CreateDatabase.php', - __DIR__ . '/system/Database/SQLite3/Connection.php', - __DIR__ . '/tests/system/Database/ConfigTest.php', - __DIR__ . '/tests/system/Database/Live/DbUtilsTest.php', - __DIR__ . '/tests/system/Database/Live/ForgeTest.php', - __DIR__ . '/tests/system/Database/Live/GetTest.php', - __DIR__ . '/tests/system/Database/Live/SQLite/AlterTableTest.php', - __DIR__ . '/tests/system/Database/Migrations/MigrationRunnerTest.php', ], // sometime too detail @@ -164,4 +153,13 @@ $services->set(MakeInheritedMethodVisibilitySameAsParentRector::class); $services->set(SimplifyEmptyArrayCheckRector::class); $services->set(NormalizeNamespaceByPSR4ComposerAutoloadRector::class); + $services->set(StringClassNameToClassConstantRector::class) + ->configure([ + 'Error', + 'Exception', + 'InvalidArgumentException', + 'Closure', + 'stdClass', + 'SQLite3', + ]); }; diff --git a/system/CodeIgniter.php b/system/CodeIgniter.php index 127e087458a0..86e70546dd41 100644 --- a/system/CodeIgniter.php +++ b/system/CodeIgniter.php @@ -830,7 +830,7 @@ protected function startController() $this->benchmark->start('controller_constructor'); // Is it routed to a Closure? - if (is_object($this->controller) && (get_class($this->controller) === Closure::class)) { + if (is_object($this->controller) && (get_class($this->controller) === 'Closure')) { $controller = $this->controller; return $controller(...$this->router->params()); diff --git a/system/Database/BaseResult.php b/system/Database/BaseResult.php index b5818525dc30..5d223c7fc08b 100644 --- a/system/Database/BaseResult.php +++ b/system/Database/BaseResult.php @@ -12,7 +12,6 @@ namespace CodeIgniter\Database; use CodeIgniter\Entity\Entity; -use stdClass; /** * Class BaseResult @@ -509,5 +508,5 @@ abstract protected function fetchAssoc(); * * @return object */ - abstract protected function fetchObject(string $className = stdClass::class); + abstract protected function fetchObject(string $className = 'stdClass'); } diff --git a/system/Database/MySQLi/Result.php b/system/Database/MySQLi/Result.php index 35f480776c85..7eab7d86c685 100644 --- a/system/Database/MySQLi/Result.php +++ b/system/Database/MySQLi/Result.php @@ -139,7 +139,7 @@ protected function fetchAssoc() * * @return bool|Entity|object */ - protected function fetchObject(string $className = stdClass::class) + protected function fetchObject(string $className = 'stdClass') { if (is_subclass_of($className, Entity::class)) { return empty($data = $this->fetchAssoc()) ? false : (new $className())->setAttributes($data); diff --git a/system/Database/OCI8/Result.php b/system/Database/OCI8/Result.php index 6ad26b649480..72a1b0980a28 100644 --- a/system/Database/OCI8/Result.php +++ b/system/Database/OCI8/Result.php @@ -14,7 +14,6 @@ use CodeIgniter\Database\BaseResult; use CodeIgniter\Database\ResultInterface; use CodeIgniter\Entity; -use stdClass; /** * Result for OCI8 @@ -94,11 +93,11 @@ protected function fetchAssoc() * * @return bool|Entity|object */ - protected function fetchObject(string $className = stdClass::class) + protected function fetchObject(string $className = 'stdClass') { $row = oci_fetch_object($this->resultID); - if ($className === stdClass::class || ! $row) { + if ($className === 'stdClass' || ! $row) { return $row; } if (is_subclass_of($className, Entity::class)) { diff --git a/system/Database/Postgre/Result.php b/system/Database/Postgre/Result.php index 581d79b1d421..76a0dd956515 100644 --- a/system/Database/Postgre/Result.php +++ b/system/Database/Postgre/Result.php @@ -105,7 +105,7 @@ protected function fetchAssoc() * * @return bool|Entity|object */ - protected function fetchObject(string $className = stdClass::class) + protected function fetchObject(string $className = 'stdClass') { if (is_subclass_of($className, Entity::class)) { return empty($data = $this->fetchAssoc()) ? false : (new $className())->setAttributes($data); diff --git a/system/Database/SQLSRV/Result.php b/system/Database/SQLSRV/Result.php index 045a5eebd81a..2a55e452ac09 100755 --- a/system/Database/SQLSRV/Result.php +++ b/system/Database/SQLSRV/Result.php @@ -147,7 +147,7 @@ protected function fetchAssoc() * * @return bool|Entity|object */ - protected function fetchObject(string $className = stdClass::class) + protected function fetchObject(string $className = 'stdClass') { if (is_subclass_of($className, Entity::class)) { return empty($data = $this->fetchAssoc()) ? false : (new $className())->setAttributes($data); diff --git a/system/Database/SQLite3/Result.php b/system/Database/SQLite3/Result.php index 39b9897af1e4..6afc04c51578 100644 --- a/system/Database/SQLite3/Result.php +++ b/system/Database/SQLite3/Result.php @@ -122,14 +122,14 @@ protected function fetchAssoc() * * @return bool|object */ - protected function fetchObject(string $className = stdClass::class) + protected function fetchObject(string $className = 'stdClass') { // No native support for fetching rows as objects if (($row = $this->fetchAssoc()) === false) { return false; } - if ($className === stdClass::class) { + if ($className === 'stdClass') { return (object) $row; } diff --git a/system/Test/Fabricator.php b/system/Test/Fabricator.php index d474e796df78..d4369765f0ee 100644 --- a/system/Test/Fabricator.php +++ b/system/Test/Fabricator.php @@ -17,7 +17,6 @@ use Faker\Generator; use InvalidArgumentException; use RuntimeException; -use stdClass; /** * Fabricator @@ -410,7 +409,7 @@ public function makeObject(?string $className = null): object { if ($className === null) { if ($this->model->returnType === 'object' || $this->model->returnType === 'array') { - $className = stdClass::class; + $className = 'stdClass'; } else { $className = $this->model->returnType; } diff --git a/system/Test/Mock/MockResult.php b/system/Test/Mock/MockResult.php index f3807d9170c9..0aaa340a95de 100644 --- a/system/Test/Mock/MockResult.php +++ b/system/Test/Mock/MockResult.php @@ -12,7 +12,6 @@ namespace CodeIgniter\Test\Mock; use CodeIgniter\Database\BaseResult; -use stdClass; class MockResult extends BaseResult { @@ -82,7 +81,7 @@ protected function fetchAssoc() * * @return object */ - protected function fetchObject($className = stdClass::class) + protected function fetchObject($className = 'stdClass') { return new $className(); } diff --git a/tests/system/Autoloader/AutoloaderTest.php b/tests/system/Autoloader/AutoloaderTest.php index 95d74c6c1b7e..f9a56cae82db 100644 --- a/tests/system/Autoloader/AutoloaderTest.php +++ b/tests/system/Autoloader/AutoloaderTest.php @@ -15,7 +15,6 @@ use Config\Autoload; use Config\Modules; use Config\Services; -use InvalidArgumentException; use UnnamespacedClass; /** @@ -55,7 +54,7 @@ public function testLoadStoredClass() public function testInitializeWithInvalidArguments() { - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); $this->expectExceptionMessage("Config array must contain either the 'psr4' key or the 'classmap' key."); $config = new Autoload(); diff --git a/tests/system/Cache/Handlers/BaseHandlerTest.php b/tests/system/Cache/Handlers/BaseHandlerTest.php index 18bfcff0d113..b2ebb61e01ef 100644 --- a/tests/system/Cache/Handlers/BaseHandlerTest.php +++ b/tests/system/Cache/Handlers/BaseHandlerTest.php @@ -12,7 +12,6 @@ namespace CodeIgniter\Cache\Handlers; use CodeIgniter\Test\CIUnitTestCase; -use InvalidArgumentException; use stdClass; use Tests\Support\Cache\RestrictiveHandler; @@ -28,7 +27,7 @@ final class BaseHandlerTest extends CIUnitTestCase */ public function testValidateKeyInvalidType($input) { - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); $this->expectExceptionMessage('Cache key must be a string'); BaseHandler::validateKey($input); @@ -49,7 +48,7 @@ public function testValidateKeyUsesConfig() { config('Cache')->reservedCharacters = 'b'; - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); $this->expectExceptionMessage('Cache key contains reserved characters b'); BaseHandler::validateKey('banana'); diff --git a/tests/system/CommonFunctionsTest.php b/tests/system/CommonFunctionsTest.php index 758e1727eca1..b69f6120656a 100644 --- a/tests/system/CommonFunctionsTest.php +++ b/tests/system/CommonFunctionsTest.php @@ -29,7 +29,6 @@ use Config\App; use Config\Logger; use Config\Modules; -use InvalidArgumentException; use Kint; use stdClass; use Tests\Support\Models\JobModel; @@ -167,7 +166,7 @@ public function testEscapeWithDifferentEncodings() public function testEscapeBadContext() { - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); esc(['width' => '800', 'height' => '600'], 'bogus'); } diff --git a/tests/system/Config/DotEnvTest.php b/tests/system/Config/DotEnvTest.php index 077bd8f23ea4..71fb1b560f77 100644 --- a/tests/system/Config/DotEnvTest.php +++ b/tests/system/Config/DotEnvTest.php @@ -12,7 +12,6 @@ namespace CodeIgniter\Config; use CodeIgniter\Test\CIUnitTestCase; -use InvalidArgumentException; use org\bovigo\vfs\vfsStream; /** @@ -116,7 +115,7 @@ public function testLoadsUnreadableFile() $file = 'unreadable.env'; $path = rtrim($this->fixturesFolder, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $file; chmod($path, 0000); - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); $this->expectExceptionMessage("The .env file is not readable: {$path}"); $dotenv = new DotEnv($this->fixturesFolder, $file); $dotenv->load(); @@ -136,7 +135,7 @@ public function testQuotedDotenvLoadsEnvironmentVars() public function testSpacedValuesWithoutQuotesThrowsException() { - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); $this->expectExceptionMessage('.env values containing spaces must be surrounded by quotes.'); $dotenv = new DotEnv($this->fixturesFolder, 'spaced-wrong.env'); diff --git a/tests/system/Config/FactoriesTest.php b/tests/system/Config/FactoriesTest.php index 3a8cb7584f7d..92356d638106 100644 --- a/tests/system/Config/FactoriesTest.php +++ b/tests/system/Config/FactoriesTest.php @@ -189,7 +189,7 @@ public function testInjection() $result = Factories::widgets('Banana'); - $this->assertInstanceOf(stdClass::class, $result); + $this->assertInstanceOf('stdClass', $result); } public function testRespectsComponentAlias() @@ -210,7 +210,7 @@ public function testRespectsPath() public function testRespectsInstanceOf() { - Factories::setOptions('widgets', ['instanceOf' => stdClass::class]); + Factories::setOptions('widgets', ['instanceOf' => 'stdClass']); $result = Factories::widgets('SomeWidget'); $this->assertInstanceOf(SomeWidget::class, $result); @@ -223,13 +223,13 @@ public function testSharedRespectsInstanceOf() { Factories::injectMock('widgets', 'SomeWidget', new OtherWidget()); - $result = Factories::widgets('SomeWidget', ['instanceOf' => stdClass::class]); + $result = Factories::widgets('SomeWidget', ['instanceOf' => 'stdClass']); $this->assertInstanceOf(SomeWidget::class, $result); } public function testPrioritizesParameterOptions() { - Factories::setOptions('widgets', ['instanceOf' => stdClass::class]); + Factories::setOptions('widgets', ['instanceOf' => 'stdClass']); $result = Factories::widgets('OtherWidget', ['instanceOf' => null]); $this->assertInstanceOf(OtherWidget::class, $result); diff --git a/tests/system/Cookie/CookieTest.php b/tests/system/Cookie/CookieTest.php index 34d9d59955e6..341280024ae4 100644 --- a/tests/system/Cookie/CookieTest.php +++ b/tests/system/Cookie/CookieTest.php @@ -16,7 +16,6 @@ use Config\Cookie as CookieConfig; use DateTimeImmutable; use DateTimeZone; -use InvalidArgumentException; use LogicException; /** @@ -274,7 +273,7 @@ public function testArrayAccessOfCookie(): void $this->assertArrayHasKey('path', $cookie); $this->assertSame($cookie['path'], $cookie->getPath()); - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); $cookie['expiry']; } diff --git a/tests/system/Database/Builder/WhereTest.php b/tests/system/Database/Builder/WhereTest.php index 60d328483972..ace628f6bc38 100644 --- a/tests/system/Database/Builder/WhereTest.php +++ b/tests/system/Database/Builder/WhereTest.php @@ -14,7 +14,6 @@ use CodeIgniter\Database\BaseBuilder; use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\Mock\MockConnection; -use InvalidArgumentException; use stdClass; /** @@ -267,7 +266,7 @@ public function provideInvalidKeys() */ public function testWhereInvalidKeyThrowInvalidArgumentException($key) { - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); $builder = $this->db->table('jobs'); $builder->whereIn($key, ['Politician', 'Accountant']); @@ -289,7 +288,7 @@ public function provideInvalidValues() */ public function testWhereInEmptyValuesThrowInvalidArgumentException($values) { - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); $builder = $this->db->table('jobs'); $builder->whereIn('name', $values); diff --git a/tests/system/Database/DatabaseSeederTest.php b/tests/system/Database/DatabaseSeederTest.php index 70721718ea8a..7e08d6648508 100644 --- a/tests/system/Database/DatabaseSeederTest.php +++ b/tests/system/Database/DatabaseSeederTest.php @@ -14,7 +14,6 @@ use CodeIgniter\Test\CIUnitTestCase; use Config\Database; use Faker\Generator; -use InvalidArgumentException; /** * @internal @@ -23,7 +22,7 @@ final class DatabaseSeederTest extends CIUnitTestCase { public function testInstantiateNoSeedPath() { - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); $config = new Database(); $config->filesPath = ''; @@ -32,7 +31,7 @@ public function testInstantiateNoSeedPath() public function testInstantiateNotDirSeedPath() { - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); $config = new Database(); $config->filesPath = APPPATH . 'Foo'; @@ -49,7 +48,7 @@ public function testFakerGet() public function testCallOnEmptySeeder() { - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); $seeder = new Seeder(new Database()); $seeder->call(''); diff --git a/tests/system/Database/Live/ForgeTest.php b/tests/system/Database/Live/ForgeTest.php index 113f2c0a211e..47eadc34d0b2 100644 --- a/tests/system/Database/Live/ForgeTest.php +++ b/tests/system/Database/Live/ForgeTest.php @@ -16,7 +16,6 @@ use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\DatabaseTestTrait; use Config\Database; -use InvalidArgumentException; use RuntimeException; /** @@ -297,7 +296,7 @@ public function testCreateTableWithEmptyName() $this->forge->addField('id'); $this->forge->addField('name varchar(100) NULL'); - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); $this->expectExceptionMessage('A table name is required for that operation.'); $this->forge->createTable(''); @@ -315,7 +314,7 @@ public function testCreateTableWithNoFields() public function testCreateTableWithStringFieldException() { - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); $this->expectExceptionMessage('Field information is required for that operation.'); $this->forge->dropTable('forge_test_table', true); @@ -351,7 +350,7 @@ public function testRenameTableEmptyNameException() $this->forge->createTable('forge_test_table'); - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); $this->expectExceptionMessage('A table name is required for that operation.'); $this->forge->renameTable('forge_test_table', ''); diff --git a/tests/system/Entity/EntityTest.php b/tests/system/Entity/EntityTest.php index 82c758f92f5e..d88f509694f7 100644 --- a/tests/system/Entity/EntityTest.php +++ b/tests/system/Entity/EntityTest.php @@ -19,7 +19,6 @@ use CodeIgniter\Test\ReflectionHelper; use DateTime; use ReflectionException; -use stdClass; use Tests\Support\Entity\Cast\CastBase64; use Tests\Support\Entity\Cast\CastPassParameters; use Tests\Support\Entity\Cast\NotExtendsBaseCast; @@ -372,7 +371,7 @@ public function testCastObject() $entity->sixth = $data; $this->assertIsObject($entity->sixth); - $this->assertInstanceOf(stdClass::class, $entity->sixth); + $this->assertInstanceOf('stdClass', $entity->sixth); $this->assertSame($data, (array) $entity->sixth); } @@ -516,7 +515,7 @@ public function testCastAsJSON() $check = $this->getPrivateProperty($entity, 'attributes')['tenth']; $this->assertSame('{"foo":"bar"}', $check); - $this->assertInstanceOf(stdClass::class, $entity->tenth); + $this->assertInstanceOf('stdClass', $entity->tenth); $this->assertSame(['foo' => 'bar'], (array) $entity->tenth); } diff --git a/tests/system/Helpers/FilesystemHelperTest.php b/tests/system/Helpers/FilesystemHelperTest.php index 7b837064a410..d20d93481e39 100644 --- a/tests/system/Helpers/FilesystemHelperTest.php +++ b/tests/system/Helpers/FilesystemHelperTest.php @@ -12,7 +12,6 @@ namespace CodeIgniter\Helpers; use CodeIgniter\Test\CIUnitTestCase; -use InvalidArgumentException; use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\visitor\vfsStreamStructureVisitor; @@ -525,13 +524,13 @@ public function testSymbolicPermissions() public function testRealPathURL() { - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); set_realpath('http://somewhere.com/overtherainbow'); } public function testRealPathInvalid() { - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); set_realpath(SUPPORTPATH . 'root/../', true); } diff --git a/tests/system/Models/FindModelTest.php b/tests/system/Models/FindModelTest.php index e0fdad5024a1..e564f570ec8c 100644 --- a/tests/system/Models/FindModelTest.php +++ b/tests/system/Models/FindModelTest.php @@ -13,7 +13,6 @@ use CodeIgniter\Database\Exceptions\DataException; use CodeIgniter\Exceptions\ModelException; -use stdClass; use Tests\Support\Models\JobModel; use Tests\Support\Models\SecondaryModel; use Tests\Support\Models\UserModel; @@ -296,7 +295,7 @@ public function testFirstWithNoPrimaryKey(): void ]); $record = $this->model->first(); - $this->assertInstanceOf(stdClass::class, $record); + $this->assertInstanceOf('stdClass', $record); $this->assertSame('foo', $record->key); } diff --git a/tests/system/Models/MiscellaneousModelTest.php b/tests/system/Models/MiscellaneousModelTest.php index 1c4af20a87f0..80a9639cd2f1 100644 --- a/tests/system/Models/MiscellaneousModelTest.php +++ b/tests/system/Models/MiscellaneousModelTest.php @@ -13,7 +13,6 @@ use CodeIgniter\Database\Exceptions\DataException; use CodeIgniter\I18n\Time; -use InvalidArgumentException; use Tests\Support\Models\EntityModel; use Tests\Support\Models\JobModel; use Tests\Support\Models\SimpleEntity; @@ -102,7 +101,7 @@ public function testGetValidationMessagesForReplace(): void public function testUndefinedTypeInTransformDataToArray(): void { - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); $this->expectExceptionMessage('Invalid type "whatever" used upon transforming data to array.'); $this->createModel(JobModel::class); diff --git a/tests/system/Test/ControllerTestTraitTest.php b/tests/system/Test/ControllerTestTraitTest.php index 65a671bf4df9..a5e10323a4ee 100644 --- a/tests/system/Test/ControllerTestTraitTest.php +++ b/tests/system/Test/ControllerTestTraitTest.php @@ -17,7 +17,6 @@ use CodeIgniter\Test\Mock\MockLogger as LoggerConfig; use Config\App; use Config\Services; -use InvalidArgumentException; use Tests\Support\Controllers\Popcorn; /** @@ -34,7 +33,7 @@ final class ControllerTestTraitTest extends CIUnitTestCase public function testBadController() { - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); $logger = new Logger(new LoggerConfig()); $this->withURI('http://example.com') ->withLogger($logger) @@ -44,7 +43,7 @@ public function testBadController() public function testBadControllerMethod() { - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); $logger = new Logger(new LoggerConfig()); $this->withURI('http://example.com') ->withLogger($logger) diff --git a/tests/system/Test/DOMParserTest.php b/tests/system/Test/DOMParserTest.php index 7eeee05e4385..e700a3daa163 100644 --- a/tests/system/Test/DOMParserTest.php +++ b/tests/system/Test/DOMParserTest.php @@ -11,8 +11,6 @@ namespace CodeIgniter\Test; -use InvalidArgumentException; - /** * @internal */ @@ -396,7 +394,7 @@ public function testWithNotFile() $filename = APPPATH . 'bogus.html'; - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); $dom->withFile($filename); } diff --git a/tests/system/Test/FabricatorTest.php b/tests/system/Test/FabricatorTest.php index 13de446cbcb9..701eecb02c30 100644 --- a/tests/system/Test/FabricatorTest.php +++ b/tests/system/Test/FabricatorTest.php @@ -12,8 +12,6 @@ namespace CodeIgniter\Test; use CodeIgniter\Database\ModelFactory; -use InvalidArgumentException; -use stdClass; use Tests\Support\Models\EntityModel; use Tests\Support\Models\EventModel; use Tests\Support\Models\FabricatorModel; @@ -59,7 +57,7 @@ public function testConstructorWithInstance() public function testConstructorWithInvalid() { - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); $this->expectExceptionMessage(lang('Fabricator.invalidModel')); new Fabricator('SillyRabbit\Models\AreForKids'); @@ -313,7 +311,7 @@ public function testMakeObjectReturnsStdClassForArrayReturnType() $result = $fabricator->makeObject(); - $this->assertInstanceOf(stdClass::class, $result); + $this->assertInstanceOf('stdClass', $result); } public function testMakeObjectReturnsStdClassForObjectReturnType() @@ -322,7 +320,7 @@ public function testMakeObjectReturnsStdClassForObjectReturnType() $result = $fabricator->makeObject(); - $this->assertInstanceOf(stdClass::class, $result); + $this->assertInstanceOf('stdClass', $result); } public function testMakeObjectUsesOverrides() @@ -361,7 +359,7 @@ public function testMakeReturnsSingleton() $result = $fabricator->make(); - $this->assertInstanceOf(stdClass::class, $result); + $this->assertInstanceOf('stdClass', $result); } public function testMakeReturnsExpectedCount() @@ -381,7 +379,7 @@ public function testCreateMockReturnsSingleton() $result = $fabricator->create(null, true); - $this->assertInstanceOf(stdClass::class, $result); + $this->assertInstanceOf('stdClass', $result); } public function testCreateMockReturnsExpectedCount() diff --git a/tests/system/Test/FilterTestTraitTest.php b/tests/system/Test/FilterTestTraitTest.php index f3cb0a4a6165..15b98379fbcf 100644 --- a/tests/system/Test/FilterTestTraitTest.php +++ b/tests/system/Test/FilterTestTraitTest.php @@ -11,10 +11,8 @@ namespace CodeIgniter\Test; -use Closure; use CodeIgniter\Filters\Filters; use CodeIgniter\HTTP\RequestInterface; -use InvalidArgumentException; use Tests\Support\Filters\Customfilter; /** @@ -52,12 +50,12 @@ public function testGetCallerReturnsClosure() $caller = $this->getFilterCaller('test-customfilter', 'before'); $this->assertIsCallable($caller); - $this->assertInstanceOf(Closure::class, $caller); + $this->assertInstanceOf('Closure', $caller); } public function testGetCallerInvalidPosition() { - $this->expectException(InvalidArgumentException::class); + $this->expectException('InvalidArgumentException'); $this->expectExceptionMessage('Invalid filter position passed: banana'); $this->getFilterCaller('test-customfilter', 'banana'); From 42d50cc9353aaf8f761cdf4a40b75cc2fea95177 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 15:03:28 +0000 Subject: [PATCH 0724/1246] chore(deps): bump actions/cache from 2 to 3 Bumps [actions/cache](https://github.com/actions/cache) from 2 to 3. - [Release notes](https://github.com/actions/cache/releases) - [Commits](https://github.com/actions/cache/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/test-autoreview.yml | 2 +- .github/workflows/test-coding-standards.yml | 2 +- .github/workflows/test-deptrac.yml | 4 ++-- .github/workflows/test-phpstan.yml | 4 ++-- .github/workflows/test-phpunit.yml | 2 +- .github/workflows/test-rector.yml | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test-autoreview.yml b/.github/workflows/test-autoreview.yml index ccc97dcf137e..7e6ff05c2734 100644 --- a/.github/workflows/test-autoreview.yml +++ b/.github/workflows/test-autoreview.yml @@ -34,7 +34,7 @@ jobs: run: echo "::set-output name=dir::$(composer config cache-files-dir)" - name: Cache dependencies - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.composercache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} diff --git a/.github/workflows/test-coding-standards.yml b/.github/workflows/test-coding-standards.yml index c966d9e1e603..e5b4a2043342 100644 --- a/.github/workflows/test-coding-standards.yml +++ b/.github/workflows/test-coding-standards.yml @@ -40,7 +40,7 @@ jobs: run: echo "::set-output name=dir::$(composer config cache-files-dir)" - name: Cache dependencies - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }} diff --git a/.github/workflows/test-deptrac.yml b/.github/workflows/test-deptrac.yml index ac280f964d0a..42b77998325c 100644 --- a/.github/workflows/test-deptrac.yml +++ b/.github/workflows/test-deptrac.yml @@ -50,7 +50,7 @@ jobs: run: mkdir -p ${{ steps.composer-cache.outputs.dir }} - name: Cache composer dependencies - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} @@ -60,7 +60,7 @@ jobs: run: mkdir -p build/ - name: Cache Deptrac results - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: build key: ${{ runner.os }}-deptrac-${{ github.sha }} diff --git a/.github/workflows/test-phpstan.yml b/.github/workflows/test-phpstan.yml index f7c09d1aa89e..805e34edcdde 100644 --- a/.github/workflows/test-phpstan.yml +++ b/.github/workflows/test-phpstan.yml @@ -59,7 +59,7 @@ jobs: run: mkdir -p ${{ steps.composer-cache.outputs.dir }} - name: Cache composer dependencies - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} @@ -69,7 +69,7 @@ jobs: run: mkdir -p build/phpstan - name: Cache PHPStan result cache directory - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: build/phpstan key: ${{ runner.os }}-phpstan-${{ github.sha }} diff --git a/.github/workflows/test-phpunit.yml b/.github/workflows/test-phpunit.yml index 623d13f59475..9b7850ea03d5 100644 --- a/.github/workflows/test-phpunit.yml +++ b/.github/workflows/test-phpunit.yml @@ -144,7 +144,7 @@ jobs: run: echo "::set-output name=dir::$(composer config cache-files-dir)" - name: Cache dependencies - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.composercache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} diff --git a/.github/workflows/test-rector.yml b/.github/workflows/test-rector.yml index a96821da3191..372b10289291 100644 --- a/.github/workflows/test-rector.yml +++ b/.github/workflows/test-rector.yml @@ -59,7 +59,7 @@ jobs: run: mkdir -p ${{ steps.composer-cache.outputs.dir }} - name: Cache composer dependencies - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} From 50c0bb1bb96214f2ea9c2500f82ce06ae7b5f1f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 15:03:33 +0000 Subject: [PATCH 0725/1246] chore(deps-dev): update rector/rector requirement Updates the requirements on [rector/rector](https://github.com/rectorphp/rector) to permit the latest version. - [Release notes](https://github.com/rectorphp/rector/releases) - [Commits](https://github.com/rectorphp/rector/compare/0.12.17...0.12.18) --- updated-dependencies: - dependency-name: rector/rector dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index ed6ff59ccad4..bee1f4e924d1 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "phpstan/phpstan": "^1.0", "phpunit/phpunit": "^9.1", "predis/predis": "^1.1", - "rector/rector": "0.12.17" + "rector/rector": "0.12.18" }, "suggest": { "ext-fileinfo": "Improves mime type detection for files" From 7784157f4482a90c5d02c363f14054d1c2c6759f Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 15 Feb 2022 12:01:35 +0900 Subject: [PATCH 0726/1246] refactor: Database Session Handler --- system/Config/Services.php | 20 +- .../Handlers/Database/MySQLiHandler.php | 53 ++++++ .../Handlers/Database/PostgreHandler.php | 175 ++++++++++++++++++ system/Session/Handlers/DatabaseHandler.php | 79 +------- .../AbstactHandlerTestCase.php} | 33 +--- .../Handlers/Database/MySQLiHandlerTest.php | 57 ++++++ .../Handlers/Database/PostgreHandlerTest.php | 57 ++++++ 7 files changed, 374 insertions(+), 100 deletions(-) create mode 100644 system/Session/Handlers/Database/MySQLiHandler.php create mode 100644 system/Session/Handlers/Database/PostgreHandler.php rename tests/system/Session/Handlers/{DatabaseHandlerTest.php => Database/AbstactHandlerTestCase.php} (77%) create mode 100644 tests/system/Session/Handlers/Database/MySQLiHandlerTest.php create mode 100644 tests/system/Session/Handlers/Database/PostgreHandlerTest.php diff --git a/system/Config/Services.php b/system/Config/Services.php index 2d44e3ccfd78..9dca50115f51 100644 --- a/system/Config/Services.php +++ b/system/Config/Services.php @@ -47,6 +47,9 @@ use CodeIgniter\Router\RouteCollectionInterface; use CodeIgniter\Router\Router; use CodeIgniter\Security\Security; +use CodeIgniter\Session\Handlers\Database\MySQLiHandler; +use CodeIgniter\Session\Handlers\Database\PostgreHandler; +use CodeIgniter\Session\Handlers\DatabaseHandler; use CodeIgniter\Session\Session; use CodeIgniter\Throttle\Throttler; use CodeIgniter\Typography\Typography; @@ -58,6 +61,7 @@ use Config\App; use Config\Cache; use Config\ContentSecurityPolicy as CSPConfig; +use Config\Database; use Config\Email as EmailConfig; use Config\Encryption as EncryptionConfig; use Config\Exceptions as ExceptionsConfig; @@ -585,7 +589,21 @@ public static function session(?App $config = null, bool $getShared = true) $logger = AppServices::logger(); $driverName = $config->sessionDriver; - $driver = new $driverName($config, AppServices::request()->getIPAddress()); + + if ($driverName === DatabaseHandler::class) { + $DBGroup = $config->sessionDBGroup ?? config(Database::class)->defaultGroup; + $db = Database::connect($DBGroup); + + $driver = $db->getPlatform(); + + if ($driver === 'MySQLi') { + $driverName = MySQLiHandler::class; + } elseif ($driver === 'Postgre') { + $driverName = PostgreHandler::class; + } + } + + $driver = new $driverName($config, AppServices::request()->getIPAddress()); $driver->setLogger($logger); $session = new Session($driver, $config); diff --git a/system/Session/Handlers/Database/MySQLiHandler.php b/system/Session/Handlers/Database/MySQLiHandler.php new file mode 100644 index 000000000000..fabaae451e6a --- /dev/null +++ b/system/Session/Handlers/Database/MySQLiHandler.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter\Session\Handlers\Database; + +use CodeIgniter\Session\Handlers\DatabaseHandler; + +/** + * Session handler for MySQLi + */ +class MySQLiHandler extends DatabaseHandler +{ + /** + * Lock the session. + */ + protected function lockSession(string $sessionID): bool + { + $arg = md5($sessionID . ($this->matchIP ? '_' . $this->ipAddress : '')); + if ($this->db->query("SELECT GET_LOCK('{$arg}', 300) AS ci_session_lock")->getRow()->ci_session_lock) { + $this->lock = $arg; + + return true; + } + + return $this->fail(); + } + + /** + * Releases the lock, if any. + */ + protected function releaseLock(): bool + { + if (! $this->lock) { + return true; + } + + if ($this->db->query("SELECT RELEASE_LOCK('{$this->lock}') AS ci_session_lock")->getRow()->ci_session_lock) { + $this->lock = false; + + return true; + } + + return $this->fail(); + } +} diff --git a/system/Session/Handlers/Database/PostgreHandler.php b/system/Session/Handlers/Database/PostgreHandler.php new file mode 100644 index 000000000000..a75d4ea4eaf0 --- /dev/null +++ b/system/Session/Handlers/Database/PostgreHandler.php @@ -0,0 +1,175 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter\Session\Handlers\Database; + +use CodeIgniter\Session\Handlers\DatabaseHandler; +use ReturnTypeWillChange; + +/** + * Session handler for Postgre + */ +class PostgreHandler extends DatabaseHandler +{ + /** + * Reads the session data from the session storage, and returns the results. + * + * @param string $id The session ID + * + * @return false|string Returns an encoded string of the read data. + * If nothing was read, it must return false. + */ + #[ReturnTypeWillChange] + public function read($id) + { + if ($this->lockSession($id) === false) { + $this->fingerprint = md5(''); + + return ''; + } + + if (! isset($this->sessionID)) { + $this->sessionID = $id; + } + + $builder = $this->db->table($this->table) + ->select("encode(data, 'base64') AS data") + ->where('id', $id); + + if ($this->matchIP) { + $builder = $builder->where('ip_address', $this->ipAddress); + } + + $result = $builder->get()->getRow(); + + if ($result === null) { + // PHP7 will reuse the same SessionHandler object after + // ID regeneration, so we need to explicitly set this to + // FALSE instead of relying on the default ... + $this->rowExists = false; + $this->fingerprint = md5(''); + + return ''; + } + + $result = is_bool($result) ? '' : base64_decode(rtrim($result->data), true); + + $this->fingerprint = md5($result); + $this->rowExists = true; + + return $result; + } + + /** + * Writes the session data to the session storage. + * + * @param string $id The session ID + * @param string $data The encoded session data + */ + public function write($id, $data): bool + { + if ($this->lock === false) { + return $this->fail(); + } + + if ($this->sessionID !== $id) { + $this->rowExists = false; + $this->sessionID = $id; + } + + if ($this->rowExists === false) { + $insertData = [ + 'id' => $id, + 'ip_address' => $this->ipAddress, + 'data' => '\x' . bin2hex($data), + ]; + + if (! $this->db->table($this->table)->set('timestamp', 'now()', false)->insert($insertData)) { + return $this->fail(); + } + + $this->fingerprint = md5($data); + $this->rowExists = true; + + return true; + } + + $builder = $this->db->table($this->table)->where('id', $id); + + if ($this->matchIP) { + $builder = $builder->where('ip_address', $this->ipAddress); + } + + $updateData = []; + + if ($this->fingerprint !== md5($data)) { + $updateData['data'] = '\x' . bin2hex($data); + } + + if (! $builder->set('timestamp', 'now()', false)->update($updateData)) { + return $this->fail(); + } + + $this->fingerprint = md5($data); + + return true; + } + + /** + * Cleans up expired sessions. + * + * @param int $max_lifetime Sessions that have not updated + * for the last max_lifetime seconds will be removed. + * + * @return false|int Returns the number of deleted sessions on success, or false on failure. + */ + #[ReturnTypeWillChange] + public function gc($max_lifetime) + { + $separator = '\''; + $interval = implode($separator, ['', "{$max_lifetime} second", '']); + + return $this->db->table($this->table)->where('timestamp <', "now() - INTERVAL {$interval}", false)->delete() ? 1 : $this->fail(); + } + + /** + * Lock the session. + */ + protected function lockSession(string $sessionID): bool + { + $arg = "hashtext('{$sessionID}')" . ($this->matchIP ? ", hashtext('{$this->ipAddress}')" : ''); + if ($this->db->simpleQuery("SELECT pg_advisory_lock({$arg})")) { + $this->lock = $arg; + + return true; + } + + return $this->fail(); + } + + /** + * Releases the lock, if any. + */ + protected function releaseLock(): bool + { + if (! $this->lock) { + return true; + } + + if ($this->db->simpleQuery("SELECT pg_advisory_unlock({$this->lock})")) { + $this->lock = false; + + return true; + } + + return $this->fail(); + } +} diff --git a/system/Session/Handlers/DatabaseHandler.php b/system/Session/Handlers/DatabaseHandler.php index dfaa472029fd..64c6a1c511d1 100644 --- a/system/Session/Handlers/DatabaseHandler.php +++ b/system/Session/Handlers/DatabaseHandler.php @@ -18,7 +18,9 @@ use ReturnTypeWillChange; /** - * Session handler using current Database for storage + * Base database session handler + * + * Do not use this class. Use database specific handler class. */ class DatabaseHandler extends BaseHandler { @@ -44,7 +46,7 @@ class DatabaseHandler extends BaseHandler protected $db; /** - * The database type, for locking purposes. + * The database type * * @var string */ @@ -73,13 +75,7 @@ public function __construct(AppConfig $config, string $ipAddress) $this->db = Database::connect($this->DBGroup); - $driver = strtolower(get_class($this->db)); - - if (strpos($driver, 'mysql') !== false) { - $this->platform = 'mysql'; - } elseif (strpos($driver, 'postgre') !== false) { - $this->platform = 'postgre'; - } + $this->platform = $this->db->getPlatform(); } /** @@ -119,7 +115,7 @@ public function read($id) } $builder = $this->db->table($this->table) - ->select($this->platform === 'postgre' ? "encode(data, 'base64') AS data" : 'data') + ->select('data') ->where('id', $id); if ($this->matchIP) { @@ -138,11 +134,7 @@ public function read($id) return ''; } - if (is_bool($result)) { - $result = ''; - } else { - $result = ($this->platform === 'postgre') ? base64_decode(rtrim($result->data), true) : $result->data; - } + $result = is_bool($result) ? '' : $result->data; $this->fingerprint = md5($result); $this->rowExists = true; @@ -171,7 +163,7 @@ public function write($id, $data): bool $insertData = [ 'id' => $id, 'ip_address' => $this->ipAddress, - 'data' => $this->platform === 'postgre' ? '\x' . bin2hex($data) : $data, + 'data' => $data, ]; if (! $this->db->table($this->table)->set('timestamp', 'now()', false)->insert($insertData)) { @@ -193,7 +185,7 @@ public function write($id, $data): bool $updateData = []; if ($this->fingerprint !== md5($data)) { - $updateData['data'] = ($this->platform === 'postgre') ? '\x' . bin2hex($data) : $data; + $updateData['data'] = $data; } if (! $builder->set('timestamp', 'now()', false)->update($updateData)) { @@ -252,43 +244,12 @@ public function destroy($id): bool #[ReturnTypeWillChange] public function gc($max_lifetime) { - $separator = $this->platform === 'postgre' ? '\'' : ' '; + $separator = ' '; $interval = implode($separator, ['', "{$max_lifetime} second", '']); return $this->db->table($this->table)->where('timestamp <', "now() - INTERVAL {$interval}", false)->delete() ? 1 : $this->fail(); } - /** - * Lock the session. - */ - protected function lockSession(string $sessionID): bool - { - if ($this->platform === 'mysql') { - $arg = md5($sessionID . ($this->matchIP ? '_' . $this->ipAddress : '')); - if ($this->db->query("SELECT GET_LOCK('{$arg}', 300) AS ci_session_lock")->getRow()->ci_session_lock) { - $this->lock = $arg; - - return true; - } - - return $this->fail(); - } - - if ($this->platform === 'postgre') { - $arg = "hashtext('{$sessionID}')" . ($this->matchIP ? ", hashtext('{$this->ipAddress}')" : ''); - if ($this->db->simpleQuery("SELECT pg_advisory_lock({$arg})")) { - $this->lock = $arg; - - return true; - } - - return $this->fail(); - } - - // Unsupported DB? Let the parent handle the simplified version. - return parent::lockSession($sessionID); - } - /** * Releases the lock, if any. */ @@ -298,26 +259,6 @@ protected function releaseLock(): bool return true; } - if ($this->platform === 'mysql') { - if ($this->db->query("SELECT RELEASE_LOCK('{$this->lock}') AS ci_session_lock")->getRow()->ci_session_lock) { - $this->lock = false; - - return true; - } - - return $this->fail(); - } - - if ($this->platform === 'postgre') { - if ($this->db->simpleQuery("SELECT pg_advisory_unlock({$this->lock})")) { - $this->lock = false; - - return true; - } - - return $this->fail(); - } - // Unsupported DB? Let the parent handle the simple version. return parent::releaseLock(); } diff --git a/tests/system/Session/Handlers/DatabaseHandlerTest.php b/tests/system/Session/Handlers/Database/AbstactHandlerTestCase.php similarity index 77% rename from tests/system/Session/Handlers/DatabaseHandlerTest.php rename to tests/system/Session/Handlers/Database/AbstactHandlerTestCase.php index 7af077606cba..9d6a6781ce57 100644 --- a/tests/system/Session/Handlers/DatabaseHandlerTest.php +++ b/tests/system/Session/Handlers/Database/AbstactHandlerTestCase.php @@ -9,18 +9,16 @@ * the LICENSE file that was distributed with this source code. */ -namespace CodeIgniter\Session\Handlers; +namespace CodeIgniter\Session\Handlers\Database; use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\DatabaseTestTrait; use CodeIgniter\Test\ReflectionHelper; -use Config\App as AppConfig; -use Config\Database as DatabaseConfig; /** * @internal */ -final class DatabaseHandlerTest extends CIUnitTestCase +abstract class AbstactHandlerTestCase extends CIUnitTestCase { use DatabaseTestTrait; use ReflectionHelper; @@ -37,32 +35,7 @@ protected function setUp(): void } } - protected function getInstance($options = []) - { - $defaults = [ - 'sessionDriver' => DatabaseHandler::class, - 'sessionCookieName' => 'ci_session', - 'sessionExpiration' => 7200, - 'sessionSavePath' => 'ci_sessions', - 'sessionMatchIP' => false, - 'sessionTimeToUpdate' => 300, - 'sessionRegenerateDestroy' => false, - 'cookieDomain' => '', - 'cookiePrefix' => '', - 'cookiePath' => '/', - 'cookieSecure' => false, - 'cookieSameSite' => 'Lax', - ]; - - $config = array_merge($defaults, $options); - $appConfig = new AppConfig(); - - foreach ($config as $key => $c) { - $appConfig->{$key} = $c; - } - - return new DatabaseHandler($appConfig, '127.0.0.1'); - } + abstract protected function getInstance($options = []); public function testOpen() { diff --git a/tests/system/Session/Handlers/Database/MySQLiHandlerTest.php b/tests/system/Session/Handlers/Database/MySQLiHandlerTest.php new file mode 100644 index 000000000000..b1fcd51dd24c --- /dev/null +++ b/tests/system/Session/Handlers/Database/MySQLiHandlerTest.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter\Session\Handlers\Database; + +use Config\App as AppConfig; +use Config\Database as DatabaseConfig; + +/** + * @internal + */ +final class MySQLiHandlerTest extends AbstactHandlerTestCase +{ + protected function setUp(): void + { + parent::setUp(); + + if (config(DatabaseConfig::class)->tests['DBDriver'] !== 'MySQLi') { + $this->markTestSkipped('This test case needs MySQLi'); + } + } + + protected function getInstance($options = []) + { + $defaults = [ + 'sessionDriver' => 'CodeIgniter\Session\Handlers\DatabaseHandler', + 'sessionCookieName' => 'ci_session', + 'sessionExpiration' => 7200, + 'sessionSavePath' => 'ci_sessions', + 'sessionMatchIP' => false, + 'sessionTimeToUpdate' => 300, + 'sessionRegenerateDestroy' => false, + 'cookieDomain' => '', + 'cookiePrefix' => '', + 'cookiePath' => '/', + 'cookieSecure' => false, + 'cookieSameSite' => 'Lax', + ]; + + $config = array_merge($defaults, $options); + $appConfig = new AppConfig(); + + foreach ($config as $key => $c) { + $appConfig->{$key} = $c; + } + + return new MySQLiHandler($appConfig, '127.0.0.1'); + } +} diff --git a/tests/system/Session/Handlers/Database/PostgreHandlerTest.php b/tests/system/Session/Handlers/Database/PostgreHandlerTest.php new file mode 100644 index 000000000000..b84298f92868 --- /dev/null +++ b/tests/system/Session/Handlers/Database/PostgreHandlerTest.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter\Session\Handlers\Database; + +use Config\App as AppConfig; +use Config\Database as DatabaseConfig; + +/** + * @internal + */ +final class PostgreHandlerTest extends AbstactHandlerTestCase +{ + protected function setUp(): void + { + parent::setUp(); + + if (config(DatabaseConfig::class)->tests['DBDriver'] !== 'Postgre') { + $this->markTestSkipped('This test case needs Postgre'); + } + } + + protected function getInstance($options = []) + { + $defaults = [ + 'sessionDriver' => 'CodeIgniter\Session\Handlers\DatabaseHandler', + 'sessionCookieName' => 'ci_session', + 'sessionExpiration' => 7200, + 'sessionSavePath' => 'ci_sessions', + 'sessionMatchIP' => false, + 'sessionTimeToUpdate' => 300, + 'sessionRegenerateDestroy' => false, + 'cookieDomain' => '', + 'cookiePrefix' => '', + 'cookiePath' => '/', + 'cookieSecure' => false, + 'cookieSameSite' => 'Lax', + ]; + + $config = array_merge($defaults, $options); + $appConfig = new AppConfig(); + + foreach ($config as $key => $c) { + $appConfig->{$key} = $c; + } + + return new PostgreHandler($appConfig, '127.0.0.1'); + } +} From 43f2453472ef06d5806cd7174c0e4fe0e6c14bb4 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 15 Feb 2022 12:02:40 +0900 Subject: [PATCH 0727/1246] docs: fix PHPDocs --- phpstan-baseline.neon.dist | 20 -------------------- system/Database/BaseConnection.php | 2 +- system/Session/Handlers/BaseHandler.php | 2 +- 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/phpstan-baseline.neon.dist b/phpstan-baseline.neon.dist index 7c0704286696..1021eb445899 100644 --- a/phpstan-baseline.neon.dist +++ b/phpstan-baseline.neon.dist @@ -745,26 +745,6 @@ parameters: count: 1 path: system/Session/Handlers/DatabaseHandler.php - - - message: "#^Property CodeIgniter\\\\Session\\\\Handlers\\\\BaseHandler\\:\\:\\$sessionID \\(string\\) in isset\\(\\) is not nullable\\.$#" - count: 1 - path: system/Session/Handlers/DatabaseHandler.php - - - - message: "#^Property CodeIgniter\\\\Session\\\\Handlers\\\\BaseHandler\\:\\:\\$sessionID \\(string\\) in isset\\(\\) is not nullable\\.$#" - count: 1 - path: system/Session/Handlers/FileHandler.php - - - - message: "#^Property CodeIgniter\\\\Session\\\\Handlers\\\\BaseHandler\\:\\:\\$sessionID \\(string\\) in isset\\(\\) is not nullable\\.$#" - count: 1 - path: system/Session/Handlers/MemcachedHandler.php - - - - message: "#^Property CodeIgniter\\\\Session\\\\Handlers\\\\BaseHandler\\:\\:\\$sessionID \\(string\\) in isset\\(\\) is not nullable\\.$#" - count: 1 - path: system/Session/Handlers/RedisHandler.php - - message: "#^Strict comparison using \\=\\=\\= between string and true will always evaluate to false\\.$#" count: 1 diff --git a/system/Database/BaseConnection.php b/system/Database/BaseConnection.php index d2ce3fdd390a..23a78d423c47 100644 --- a/system/Database/BaseConnection.php +++ b/system/Database/BaseConnection.php @@ -508,7 +508,7 @@ public function getPrefix(): string } /** - * The name of the platform in use (MySQLi, mssql, etc) + * The name of the platform in use (MySQLi, Postgre, SQLite3, OCI8, etc) */ public function getPlatform(): string { diff --git a/system/Session/Handlers/BaseHandler.php b/system/Session/Handlers/BaseHandler.php index f6fa57b23b68..008cae369e80 100644 --- a/system/Session/Handlers/BaseHandler.php +++ b/system/Session/Handlers/BaseHandler.php @@ -81,7 +81,7 @@ abstract class BaseHandler implements SessionHandlerInterface /** * Current session ID * - * @var string + * @var string|null */ protected $sessionID; From 9cf3b5e45279b812c5a985062574c693b20f6dee Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 15 Feb 2022 14:06:17 +0900 Subject: [PATCH 0728/1246] refactor: remove duplicate code in write() --- .../Handlers/Database/PostgreHandler.php | 53 ++----------------- system/Session/Handlers/DatabaseHandler.php | 12 ++++- 2 files changed, 13 insertions(+), 52 deletions(-) diff --git a/system/Session/Handlers/Database/PostgreHandler.php b/system/Session/Handlers/Database/PostgreHandler.php index a75d4ea4eaf0..3a708fefc746 100644 --- a/system/Session/Handlers/Database/PostgreHandler.php +++ b/system/Session/Handlers/Database/PostgreHandler.php @@ -69,58 +69,11 @@ public function read($id) } /** - * Writes the session data to the session storage. - * - * @param string $id The session ID - * @param string $data The encoded session data + * Prepare data to insert/update */ - public function write($id, $data): bool + protected function prepareData(string $data): string { - if ($this->lock === false) { - return $this->fail(); - } - - if ($this->sessionID !== $id) { - $this->rowExists = false; - $this->sessionID = $id; - } - - if ($this->rowExists === false) { - $insertData = [ - 'id' => $id, - 'ip_address' => $this->ipAddress, - 'data' => '\x' . bin2hex($data), - ]; - - if (! $this->db->table($this->table)->set('timestamp', 'now()', false)->insert($insertData)) { - return $this->fail(); - } - - $this->fingerprint = md5($data); - $this->rowExists = true; - - return true; - } - - $builder = $this->db->table($this->table)->where('id', $id); - - if ($this->matchIP) { - $builder = $builder->where('ip_address', $this->ipAddress); - } - - $updateData = []; - - if ($this->fingerprint !== md5($data)) { - $updateData['data'] = '\x' . bin2hex($data); - } - - if (! $builder->set('timestamp', 'now()', false)->update($updateData)) { - return $this->fail(); - } - - $this->fingerprint = md5($data); - - return true; + return '\x' . bin2hex($data); } /** diff --git a/system/Session/Handlers/DatabaseHandler.php b/system/Session/Handlers/DatabaseHandler.php index 64c6a1c511d1..6f20c7688dd8 100644 --- a/system/Session/Handlers/DatabaseHandler.php +++ b/system/Session/Handlers/DatabaseHandler.php @@ -163,7 +163,7 @@ public function write($id, $data): bool $insertData = [ 'id' => $id, 'ip_address' => $this->ipAddress, - 'data' => $data, + 'data' => $this->prepareData($data), ]; if (! $this->db->table($this->table)->set('timestamp', 'now()', false)->insert($insertData)) { @@ -185,7 +185,7 @@ public function write($id, $data): bool $updateData = []; if ($this->fingerprint !== md5($data)) { - $updateData['data'] = $data; + $updateData['data'] = $this->prepareData($data); } if (! $builder->set('timestamp', 'now()', false)->update($updateData)) { @@ -197,6 +197,14 @@ public function write($id, $data): bool return true; } + /** + * Prepare data to insert/update + */ + protected function prepareData(string $data): string + { + return $data; + } + /** * Closes the current session. */ From 0b2f01c6befbde7d9604351b9825ade841e8f0e6 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 15 Feb 2022 14:41:46 +0900 Subject: [PATCH 0729/1246] refactor: remove duplicate code in read() --- .../Handlers/Database/PostgreHandler.php | 56 +++++-------------- system/Session/Handlers/DatabaseHandler.php | 29 ++++++++-- 2 files changed, 39 insertions(+), 46 deletions(-) diff --git a/system/Session/Handlers/Database/PostgreHandler.php b/system/Session/Handlers/Database/PostgreHandler.php index 3a708fefc746..2b730d831c89 100644 --- a/system/Session/Handlers/Database/PostgreHandler.php +++ b/system/Session/Handlers/Database/PostgreHandler.php @@ -11,6 +11,7 @@ namespace CodeIgniter\Session\Handlers\Database; +use CodeIgniter\Database\BaseBuilder; use CodeIgniter\Session\Handlers\DatabaseHandler; use ReturnTypeWillChange; @@ -20,52 +21,23 @@ class PostgreHandler extends DatabaseHandler { /** - * Reads the session data from the session storage, and returns the results. + * Sets SELECT clause + */ + protected function setSelect(BaseBuilder $builder) + { + $builder->select("encode(data, 'base64') AS data"); + } + + /** + * Decodes column data * - * @param string $id The session ID + * @param mixed $data * - * @return false|string Returns an encoded string of the read data. - * If nothing was read, it must return false. + * @return false|string */ - #[ReturnTypeWillChange] - public function read($id) + protected function decodeData($data) { - if ($this->lockSession($id) === false) { - $this->fingerprint = md5(''); - - return ''; - } - - if (! isset($this->sessionID)) { - $this->sessionID = $id; - } - - $builder = $this->db->table($this->table) - ->select("encode(data, 'base64') AS data") - ->where('id', $id); - - if ($this->matchIP) { - $builder = $builder->where('ip_address', $this->ipAddress); - } - - $result = $builder->get()->getRow(); - - if ($result === null) { - // PHP7 will reuse the same SessionHandler object after - // ID regeneration, so we need to explicitly set this to - // FALSE instead of relying on the default ... - $this->rowExists = false; - $this->fingerprint = md5(''); - - return ''; - } - - $result = is_bool($result) ? '' : base64_decode(rtrim($result->data), true); - - $this->fingerprint = md5($result); - $this->rowExists = true; - - return $result; + return base64_decode(rtrim($data), true); } /** diff --git a/system/Session/Handlers/DatabaseHandler.php b/system/Session/Handlers/DatabaseHandler.php index 6f20c7688dd8..8cbf43ca280a 100644 --- a/system/Session/Handlers/DatabaseHandler.php +++ b/system/Session/Handlers/DatabaseHandler.php @@ -11,6 +11,7 @@ namespace CodeIgniter\Session\Handlers; +use CodeIgniter\Database\BaseBuilder; use CodeIgniter\Database\BaseConnection; use CodeIgniter\Session\Exceptions\SessionException; use Config\App as AppConfig; @@ -114,14 +115,14 @@ public function read($id) $this->sessionID = $id; } - $builder = $this->db->table($this->table) - ->select('data') - ->where('id', $id); + $builder = $this->db->table($this->table)->where('id', $id); if ($this->matchIP) { $builder = $builder->where('ip_address', $this->ipAddress); } + $this->setSelect($builder); + $result = $builder->get()->getRow(); if ($result === null) { @@ -134,7 +135,7 @@ public function read($id) return ''; } - $result = is_bool($result) ? '' : $result->data; + $result = is_bool($result) ? '' : $this->decodeData($result->data); $this->fingerprint = md5($result); $this->rowExists = true; @@ -142,6 +143,26 @@ public function read($id) return $result; } + /** + * Sets SELECT clause + */ + protected function setSelect(BaseBuilder $builder) + { + $builder->select('data'); + } + + /** + * Decodes column data + * + * @param mixed $data + * + * @return false|string + */ + protected function decodeData($data) + { + return $data; + } + /** * Writes the session data to the session storage. * From 685a11bdf6ed209641fd4602e938bd9ffa5a249e Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 22 Mar 2022 10:54:57 +0900 Subject: [PATCH 0730/1246] refactor: vendor/bin/rector --- tests/system/Session/Handlers/Database/MySQLiHandlerTest.php | 3 ++- tests/system/Session/Handlers/Database/PostgreHandlerTest.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/system/Session/Handlers/Database/MySQLiHandlerTest.php b/tests/system/Session/Handlers/Database/MySQLiHandlerTest.php index b1fcd51dd24c..469b0c8e1f7e 100644 --- a/tests/system/Session/Handlers/Database/MySQLiHandlerTest.php +++ b/tests/system/Session/Handlers/Database/MySQLiHandlerTest.php @@ -11,6 +11,7 @@ namespace CodeIgniter\Session\Handlers\Database; +use CodeIgniter\Session\Handlers\DatabaseHandler; use Config\App as AppConfig; use Config\Database as DatabaseConfig; @@ -31,7 +32,7 @@ protected function setUp(): void protected function getInstance($options = []) { $defaults = [ - 'sessionDriver' => 'CodeIgniter\Session\Handlers\DatabaseHandler', + 'sessionDriver' => DatabaseHandler::class, 'sessionCookieName' => 'ci_session', 'sessionExpiration' => 7200, 'sessionSavePath' => 'ci_sessions', diff --git a/tests/system/Session/Handlers/Database/PostgreHandlerTest.php b/tests/system/Session/Handlers/Database/PostgreHandlerTest.php index b84298f92868..9575b68e499f 100644 --- a/tests/system/Session/Handlers/Database/PostgreHandlerTest.php +++ b/tests/system/Session/Handlers/Database/PostgreHandlerTest.php @@ -11,6 +11,7 @@ namespace CodeIgniter\Session\Handlers\Database; +use CodeIgniter\Session\Handlers\DatabaseHandler; use Config\App as AppConfig; use Config\Database as DatabaseConfig; @@ -31,7 +32,7 @@ protected function setUp(): void protected function getInstance($options = []) { $defaults = [ - 'sessionDriver' => 'CodeIgniter\Session\Handlers\DatabaseHandler', + 'sessionDriver' => DatabaseHandler::class, 'sessionCookieName' => 'ci_session', 'sessionExpiration' => 7200, 'sessionSavePath' => 'ci_sessions', From 036d9b55993ac1edd6157daa7aec04b36e78ea84 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 22 Mar 2022 11:08:03 +0900 Subject: [PATCH 0731/1246] test: fix mistake of rebase --- .../system/Session/Handlers/Database/AbstactHandlerTestCase.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/system/Session/Handlers/Database/AbstactHandlerTestCase.php b/tests/system/Session/Handlers/Database/AbstactHandlerTestCase.php index 9d6a6781ce57..7434301f40cc 100644 --- a/tests/system/Session/Handlers/Database/AbstactHandlerTestCase.php +++ b/tests/system/Session/Handlers/Database/AbstactHandlerTestCase.php @@ -14,6 +14,7 @@ use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\DatabaseTestTrait; use CodeIgniter\Test\ReflectionHelper; +use Config\Database as DatabaseConfig; /** * @internal From 51057f144c2b461f2ec89fdb46b2e0b89f079c79 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 22 Mar 2022 17:24:36 +0900 Subject: [PATCH 0732/1246] docs: add full support for PHP 8.1 --- user_guide_src/source/changelogs/v4.1.6.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/user_guide_src/source/changelogs/v4.1.6.rst b/user_guide_src/source/changelogs/v4.1.6.rst index 2321f413e173..84e4f9f7d39e 100644 --- a/user_guide_src/source/changelogs/v4.1.6.rst +++ b/user_guide_src/source/changelogs/v4.1.6.rst @@ -37,6 +37,7 @@ Validation changes Enhancements ************ +- Full support for PHP 8.1. - Database pane on debug toolbar now displays location where Query was called from. Also displays full backtrace. - :ref:`Subqueries ` in QueryBuilder can now be an instance of the BaseBuilder class. - Kint was updated from ^3.3 to ^4.0. From 4ba72e6ab7df9a40e2d376cb5d2abe4e7fa572b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Beganovi=C4=87?= Date: Tue, 22 Mar 2022 16:33:11 +0100 Subject: [PATCH 0733/1246] Update incomingrequest.rst --- user_guide_src/source/incoming/incomingrequest.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/user_guide_src/source/incoming/incomingrequest.rst b/user_guide_src/source/incoming/incomingrequest.rst index c20e897b92de..74f3cf5289b0 100644 --- a/user_guide_src/source/incoming/incomingrequest.rst +++ b/user_guide_src/source/incoming/incomingrequest.rst @@ -44,10 +44,10 @@ You can check the HTTP method that this request represents with the ``method()`` .. literalinclude:: incomingrequest/005.php By default, the method is returned as a lower-case string (i.e., 'get', 'post', etc). You can get an -uppercase version by wrapping the call in ``str_to_upper()``:: +uppercase version by wrapping the call in ``strtoupper()``:: // Returns 'GET' - $method = str_to_upper($request->getMethod()); + $method = strtoupper($request->getMethod()); You can also check if the request was made through and HTTPS connection with the ``isSecure()`` method: From 57e0594a8d2a12b32de852ecd52a1ab679fa4705 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 23 Mar 2022 09:13:11 +0900 Subject: [PATCH 0734/1246] chore: remove App\ and Config\ in autoload.psr-4 in app starter composer.json Revert #3423 Problems: - Cannot change `app` folder name. Because the composer's path overwrite the config in Config\Autoload. - Causes error when defining new namespace under app/. See #5818 --- admin/starter/composer.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/admin/starter/composer.json b/admin/starter/composer.json index f2959dd49b51..026329ca9a24 100644 --- a/admin/starter/composer.json +++ b/admin/starter/composer.json @@ -17,10 +17,6 @@ "ext-fileinfo": "Improves mime type detection for files" }, "autoload": { - "psr-4": { - "App\\": "app", - "Config\\": "app/Config" - }, "exclude-from-classmap": [ "**/Database/Migrations/**" ] From 135222d40724d3b6bc470fd88bf9c85b1fff9b95 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 23 Mar 2022 09:23:43 +0900 Subject: [PATCH 0735/1246] docs: add @TODO --- system/CLI/Commands.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/system/CLI/Commands.php b/system/CLI/Commands.php index 3f84f33d918f..d153b3aa857a 100644 --- a/system/CLI/Commands.php +++ b/system/CLI/Commands.php @@ -76,6 +76,10 @@ public function getCommands() /** * Discovers all commands in the framework and within user code, * and collects instances of them to work with. + * + * @TODO this approach (find qualified classname from path) causes error, + * when using Composer autoloader. + * See https://github.com/codeigniter4/CodeIgniter4/issues/5818 */ public function discoverCommands() { From 15931e9c4283f01474c56874ec7dec2c3c68c1b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Mar 2022 17:27:04 +0000 Subject: [PATCH 0736/1246] chore(deps-dev): update rector/rector requirement Updates the requirements on [rector/rector](https://github.com/rectorphp/rector) to permit the latest version. - [Release notes](https://github.com/rectorphp/rector/releases) - [Commits](https://github.com/rectorphp/rector/compare/0.12.18...0.12.19) --- updated-dependencies: - dependency-name: rector/rector dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index bee1f4e924d1..8d77bc48cde8 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "phpstan/phpstan": "^1.0", "phpunit/phpunit": "^9.1", "predis/predis": "^1.1", - "rector/rector": "0.12.18" + "rector/rector": "0.12.19" }, "suggest": { "ext-fileinfo": "Improves mime type detection for files" From c5eb48011648c5f9dfa0f2390f69297a13d7e651 Mon Sep 17 00:00:00 2001 From: "John Paul E. Balandan, CPA" Date: Sun, 27 Mar 2022 00:11:10 +0800 Subject: [PATCH 0737/1246] Rename `Abstact` to `Abstract` --- .../{AbstactHandlerTestCase.php => AbstractHandlerTestCase.php} | 2 +- tests/system/Session/Handlers/Database/MySQLiHandlerTest.php | 2 +- tests/system/Session/Handlers/Database/PostgreHandlerTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename tests/system/Session/Handlers/Database/{AbstactHandlerTestCase.php => AbstractHandlerTestCase.php} (98%) diff --git a/tests/system/Session/Handlers/Database/AbstactHandlerTestCase.php b/tests/system/Session/Handlers/Database/AbstractHandlerTestCase.php similarity index 98% rename from tests/system/Session/Handlers/Database/AbstactHandlerTestCase.php rename to tests/system/Session/Handlers/Database/AbstractHandlerTestCase.php index 7434301f40cc..f252fc24fb43 100644 --- a/tests/system/Session/Handlers/Database/AbstactHandlerTestCase.php +++ b/tests/system/Session/Handlers/Database/AbstractHandlerTestCase.php @@ -19,7 +19,7 @@ /** * @internal */ -abstract class AbstactHandlerTestCase extends CIUnitTestCase +abstract class AbstractHandlerTestCase extends CIUnitTestCase { use DatabaseTestTrait; use ReflectionHelper; diff --git a/tests/system/Session/Handlers/Database/MySQLiHandlerTest.php b/tests/system/Session/Handlers/Database/MySQLiHandlerTest.php index 469b0c8e1f7e..5fba8bb779d0 100644 --- a/tests/system/Session/Handlers/Database/MySQLiHandlerTest.php +++ b/tests/system/Session/Handlers/Database/MySQLiHandlerTest.php @@ -18,7 +18,7 @@ /** * @internal */ -final class MySQLiHandlerTest extends AbstactHandlerTestCase +final class MySQLiHandlerTest extends AbstractHandlerTestCase { protected function setUp(): void { diff --git a/tests/system/Session/Handlers/Database/PostgreHandlerTest.php b/tests/system/Session/Handlers/Database/PostgreHandlerTest.php index 9575b68e499f..d28d1fab7134 100644 --- a/tests/system/Session/Handlers/Database/PostgreHandlerTest.php +++ b/tests/system/Session/Handlers/Database/PostgreHandlerTest.php @@ -18,7 +18,7 @@ /** * @internal */ -final class PostgreHandlerTest extends AbstactHandlerTestCase +final class PostgreHandlerTest extends AbstractHandlerTestCase { protected function setUp(): void { From 7612cdb09129ab2ce3e736fa3c131f834b52caa9 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 28 Mar 2022 12:46:08 +0900 Subject: [PATCH 0738/1246] docs: add index.php/spark changes in changelog --- user_guide_src/source/changelogs/v4.2.0.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/user_guide_src/source/changelogs/v4.2.0.rst b/user_guide_src/source/changelogs/v4.2.0.rst index 9751dd06fee0..f12a13bcb416 100644 --- a/user_guide_src/source/changelogs/v4.2.0.rst +++ b/user_guide_src/source/changelogs/v4.2.0.rst @@ -13,6 +13,9 @@ BREAKING ******** - The method signature of ``Validation::setRule()`` has been changed. The ``string`` typehint on the ``$rules`` parameter was removed. Extending classes should likewise remove the parameter so as not to break LSP. +- The ``CodeIgniter\CodeIgniter`` class has a new property ``$context`` and it must have the correct context at runtime. So the following files have been changed: + - ``public/index.php`` + - ``spark`` Enhancements ************ From 2f8157dc34d328ba450788ab473fcc076f3a3772 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 28 Mar 2022 13:02:28 +0900 Subject: [PATCH 0739/1246] chore: fix ImportError ImportError: cannot import name 'environmentfilter' from 'jinja2' (/usr/local/lib/python3.10/site-packages/jinja2/__init__.py) See https://github.com/sphinx-doc/sphinx/issues/10291 --- user_guide_src/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/user_guide_src/requirements.txt b/user_guide_src/requirements.txt index 19f5064b9815..5d11554964d1 100644 --- a/user_guide_src/requirements.txt +++ b/user_guide_src/requirements.txt @@ -2,3 +2,4 @@ sphinx>=2.4.4,<3 sphinxcontrib-phpdomain>=0.7.1 docutils>=0.16 sphinx-rtd-theme>=0.5.0 +jinja2<3.1 From 4138c04808f95699699a9140671a9fe605e5c2eb Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 29 Mar 2022 21:16:43 +0900 Subject: [PATCH 0740/1246] config: add mime type for webp --- app/Config/Mimes.php | 1 + user_guide_src/source/changelogs/v4.2.0.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/app/Config/Mimes.php b/app/Config/Mimes.php index 786bc6a1e5c7..a1bb458a2804 100644 --- a/app/Config/Mimes.php +++ b/app/Config/Mimes.php @@ -260,6 +260,7 @@ class Mimes 'image/png', 'image/x-png', ], + 'webp' => 'image/webp', 'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'css' => [ diff --git a/user_guide_src/source/changelogs/v4.2.0.rst b/user_guide_src/source/changelogs/v4.2.0.rst index f12a13bcb416..a0494ebd47c0 100644 --- a/user_guide_src/source/changelogs/v4.2.0.rst +++ b/user_guide_src/source/changelogs/v4.2.0.rst @@ -34,6 +34,7 @@ Enhancements - The ``spark routes`` command now shows closure routes, auto routes, and filters. See :ref:`URI Routing `. - Exception information logged through ``log_message()`` has now improved. It now includes the file and line where the exception originated. It also does not truncate the message anymore. - The log format has also changed. If users are depending on the log format in their apps, the new log format is "<1-based count> (): " +- Added support for webp files to **app/Config/Mimes.php**. Changes ******* From 250b0cadc1a453573a86d721ad9acbf31e8dfc0b Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 30 Mar 2022 11:27:59 +0900 Subject: [PATCH 0741/1246] docs: fix comment --- system/View/Parser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/View/Parser.php b/system/View/Parser.php index 6834c003e500..dbb0395fbd0b 100644 --- a/system/View/Parser.php +++ b/system/View/Parser.php @@ -289,7 +289,7 @@ protected function parsePair(string $variable, array $data, string $template): a */ foreach ($matches as $match) { // Loop over each piece of $data, replacing - // it's contents so that we know what to replace in parse() + // its contents so that we know what to replace in parse() $str = ''; // holds the new contents for this tag pair. foreach ($data as $row) { From 9a85788f51b056c24c1d7c4477a4108e52bec9f1 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 30 Mar 2022 11:28:59 +0900 Subject: [PATCH 0742/1246] fix: view parser fails with ({variable}) in loop --- system/View/Parser.php | 11 +---------- tests/system/View/ParserTest.php | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/system/View/Parser.php b/system/View/Parser.php index dbb0395fbd0b..6f62ca4fb333 100644 --- a/system/View/Parser.php +++ b/system/View/Parser.php @@ -338,8 +338,7 @@ protected function parsePair(string $variable, array $data, string $template): a $str .= $out; } - // Escape | character from filters as it's handled as OR in regex - $escapedMatch = preg_replace('/(?assertSame("Super Heroes\nTom Dick Henry ", $this->parser->renderString($template)); } + /** + * @see https://github.com/codeigniter4/CodeIgniter4/issues/5825 + */ + public function testParseLoopVariableWithParentheses() + { + $data = [ + 'title' => 'Super Heroes', + 'powers' => [ + ['name' => 'Tom'], + ['name' => 'Dick'], + ['name' => 'Henry'], + ], + ]; + + $template = "{title}\n{powers}({name}) {/powers}"; + + $this->parser->setData($data); + $this->assertSame("Super Heroes\n(Tom) (Dick) (Henry) ", $this->parser->renderString($template)); + } + public function testParseLoopObjectProperties() { $obj1 = new stdClass(); From 78d42a58f57eb4cc6a8a6e9f74be876b93b4051c Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 28 Mar 2022 11:40:45 +0900 Subject: [PATCH 0743/1246] fix: spark can't use options in PHP 7.4 Cannot unpack array with string keys at SYSTEMPATH/CodeIgniter.php:893 --- system/CLI/CommandRunner.php | 4 ++-- system/CodeIgniter.php | 10 +++++---- tests/system/CLI/CommandRunnerTest.php | 2 +- tests/system/SparkTest.php | 29 ++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 tests/system/SparkTest.php diff --git a/system/CLI/CommandRunner.php b/system/CLI/CommandRunner.php index a6985d0db931..06d06863de2f 100644 --- a/system/CLI/CommandRunner.php +++ b/system/CLI/CommandRunner.php @@ -40,13 +40,13 @@ public function __construct() * so we have the chance to look for a Command first. * * @param string $method - * @param array ...$params + * @param array $params * * @throws ReflectionException * * @return mixed */ - public function _remap($method, ...$params) + public function _remap($method, $params) { // The first param is usually empty, so scrap it. if (empty($params[0])) { diff --git a/system/CodeIgniter.php b/system/CodeIgniter.php index 86e70546dd41..093687254c77 100644 --- a/system/CodeIgniter.php +++ b/system/CodeIgniter.php @@ -884,14 +884,16 @@ protected function runController($class) /** @var CLIRequest $request */ $request = $this->request; $params = $request->getArgs(); + + $output = $class->_remap($this->method, $params); } else { // This is a Web request or PHP CLI request $params = $this->router->params(); - } - $output = method_exists($class, '_remap') - ? $class->_remap($this->method, ...$params) - : $class->{$this->method}(...$params); + $output = method_exists($class, '_remap') + ? $class->_remap($this->method, ...$params) + : $class->{$this->method}(...$params); + } $this->benchmark->stop('controller'); diff --git a/tests/system/CLI/CommandRunnerTest.php b/tests/system/CLI/CommandRunnerTest.php index 32ca71357e75..c9e3245b932c 100644 --- a/tests/system/CLI/CommandRunnerTest.php +++ b/tests/system/CLI/CommandRunnerTest.php @@ -123,7 +123,7 @@ public function testBadCommand() */ public function testRemapEmptyFirstParams() { - self::$runner->_remap('anyvalue', null, 'list'); + self::$runner->_remap('anyvalue', [null, 'list']); $result = CITestStreamFilter::$buffer; // make sure the result looks like a command list diff --git a/tests/system/SparkTest.php b/tests/system/SparkTest.php new file mode 100644 index 000000000000..0cd76453c02a --- /dev/null +++ b/tests/system/SparkTest.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter; + +use CodeIgniter\Test\CIUnitTestCase; + +/** + * @internal + */ +final class SparkTest extends CIUnitTestCase +{ + public function testCanUseOption() + { + ob_start(); + passthru('php spark list --simple'); + $output = ob_get_clean(); + + $this->assertStringContainsString('cache:clear', $output); + } +} From 9cade91cf68f5121428c507135aba69a7dc182c4 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 28 Mar 2022 11:44:41 +0900 Subject: [PATCH 0744/1246] refactor: remove unneeded logic It seems out of dated logic. --- system/CLI/CommandRunner.php | 5 ----- tests/system/CLI/CommandRunnerTest.php | 12 ------------ 2 files changed, 17 deletions(-) diff --git a/system/CLI/CommandRunner.php b/system/CLI/CommandRunner.php index 06d06863de2f..ef4ed057b606 100644 --- a/system/CLI/CommandRunner.php +++ b/system/CLI/CommandRunner.php @@ -48,11 +48,6 @@ public function __construct() */ public function _remap($method, $params) { - // The first param is usually empty, so scrap it. - if (empty($params[0])) { - array_shift($params); - } - return $this->index($params); } diff --git a/tests/system/CLI/CommandRunnerTest.php b/tests/system/CLI/CommandRunnerTest.php index c9e3245b932c..892b7b5ff516 100644 --- a/tests/system/CLI/CommandRunnerTest.php +++ b/tests/system/CLI/CommandRunnerTest.php @@ -117,16 +117,4 @@ public function testBadCommand() // make sure the result looks like a command list $this->assertStringContainsString('Command "bogus" not found', CITestStreamFilter::$buffer); } - - /** - * @TODO When the first param is empty? Use case? - */ - public function testRemapEmptyFirstParams() - { - self::$runner->_remap('anyvalue', [null, 'list']); - $result = CITestStreamFilter::$buffer; - - // make sure the result looks like a command list - $this->assertStringContainsString('Lists the available commands.', $result); - } } From d0b323d9fbf7a7227551b7190f80ba0dbbf265ef Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 30 Mar 2022 19:16:35 +0900 Subject: [PATCH 0745/1246] docs: add CommandRunner::_remap() change in changelogs --- user_guide_src/source/changelogs/v4.2.0.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/user_guide_src/source/changelogs/v4.2.0.rst b/user_guide_src/source/changelogs/v4.2.0.rst index f12a13bcb416..34daeff2f474 100644 --- a/user_guide_src/source/changelogs/v4.2.0.rst +++ b/user_guide_src/source/changelogs/v4.2.0.rst @@ -16,6 +16,7 @@ BREAKING - The ``CodeIgniter\CodeIgniter`` class has a new property ``$context`` and it must have the correct context at runtime. So the following files have been changed: - ``public/index.php`` - ``spark`` +- The method signature of ``CodeIgniter\CLI\CommandRunner::_remap()`` has been changed to fix a bug. Enhancements ************ From 60ee4f3b946b7984ce7465d4770b4cd97bd3d2fe Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 1 Mar 2022 11:09:11 +0900 Subject: [PATCH 0746/1246] config: disable auto-routing by default --- app/Config/Routes.php | 2 +- system/Router/RouteCollection.php | 2 +- tests/system/CodeIgniterTest.php | 14 ++++++++++++++ tests/system/Commands/RoutesTest.php | 1 + .../Utilities/Routes/FilterCollectorTest.php | 2 ++ tests/system/Router/RouterTest.php | 4 ++++ user_guide_src/source/changelogs/v4.2.0.rst | 1 + 7 files changed, 24 insertions(+), 2 deletions(-) diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 0060a6f67dff..2b35d0dda6f8 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -21,7 +21,7 @@ $routes->setDefaultMethod('index'); $routes->setTranslateURIDashes(false); $routes->set404Override(); -$routes->setAutoRoute(true); +$routes->setAutoRoute(false); /* * -------------------------------------------------------------------- diff --git a/system/Router/RouteCollection.php b/system/Router/RouteCollection.php index 65bf4f4985af..a1dd7b1a8fe7 100644 --- a/system/Router/RouteCollection.php +++ b/system/Router/RouteCollection.php @@ -76,7 +76,7 @@ class RouteCollection implements RouteCollectionInterface * * @var bool */ - protected $autoRoute = true; + protected $autoRoute = false; /** * A callable that will be shown diff --git a/tests/system/CodeIgniterTest.php b/tests/system/CodeIgniterTest.php index 42706e39d110..a29879522e37 100644 --- a/tests/system/CodeIgniterTest.php +++ b/tests/system/CodeIgniterTest.php @@ -47,6 +47,8 @@ protected function tearDown(): void if (count(ob_list_handlers()) > 1) { ob_end_clean(); } + + $this->resetServices(); } public function testRunEmptyDefaultRoute() @@ -469,6 +471,12 @@ public function testSpoofRequestMethodCanUsePUT() $_POST['_method'] = 'PUT'; + $routes = \Config\Services::routes(); + $routes->setDefaultNamespace('App\Controllers'); + $routes->resetRoutes(); + $routes->post('/', 'Home::index'); + $routes->put('/', 'Home::index'); + ob_start(); $this->codeigniter->useSafeOutput(true)->run(); ob_get_clean(); @@ -487,6 +495,12 @@ public function testSpoofRequestMethodCannotUseGET() $_POST['_method'] = 'GET'; + $routes = \Config\Services::routes(); + $routes->setDefaultNamespace('App\Controllers'); + $routes->resetRoutes(); + $routes->post('/', 'Home::index'); + $routes->get('/', 'Home::index'); + ob_start(); $this->codeigniter->useSafeOutput(true)->run(); ob_get_clean(); diff --git a/tests/system/Commands/RoutesTest.php b/tests/system/Commands/RoutesTest.php index dd5e6b3280a8..1787e8bef3fa 100644 --- a/tests/system/Commands/RoutesTest.php +++ b/tests/system/Commands/RoutesTest.php @@ -67,6 +67,7 @@ public function testRoutesCommandRouteFilterAndAutoRoute() $routes->setDefaultNamespace('App\Controllers'); $routes->resetRoutes(); $routes->get('/', 'Home::index', ['filter' => 'csrf']); + $routes->setAutoRoute(true); command('routes'); diff --git a/tests/system/Commands/Utilities/Routes/FilterCollectorTest.php b/tests/system/Commands/Utilities/Routes/FilterCollectorTest.php index 6002323d3393..5037c148b704 100644 --- a/tests/system/Commands/Utilities/Routes/FilterCollectorTest.php +++ b/tests/system/Commands/Utilities/Routes/FilterCollectorTest.php @@ -23,6 +23,8 @@ public function testGet() { $routes = Services::routes(); $routes->resetRoutes(); + $routes->setDefaultNamespace('App\Controllers'); + $routes->get('/', 'Home::index'); $collector = new FilterCollector(); diff --git a/tests/system/Router/RouterTest.php b/tests/system/Router/RouterTest.php index b2c476f5add6..d3ca04422c41 100644 --- a/tests/system/Router/RouterTest.php +++ b/tests/system/Router/RouterTest.php @@ -728,7 +728,10 @@ public function testAutoRouteMatchesZeroParams() public function testAutoRouteMethodEmpty() { $router = new Router($this->collection, $this->request); + $this->collection->setAutoRoute(true); + $router->handle('Home/'); + $this->assertSame('Home', $router->controllerName()); $this->assertSame('index', $router->methodName()); } @@ -775,6 +778,7 @@ public function testRegularExpressionPlaceholderWithUnicode() public function testRouterPriorDirectory() { $router = new Router($this->collection, $this->request); + $this->collection->setAutoRoute(true); $router->setDirectory('foo/bar/baz', false, true); $router->handle('Some_controller/some_method/param1/param2/param3'); diff --git a/user_guide_src/source/changelogs/v4.2.0.rst b/user_guide_src/source/changelogs/v4.2.0.rst index f12a13bcb416..55f7986375aa 100644 --- a/user_guide_src/source/changelogs/v4.2.0.rst +++ b/user_guide_src/source/changelogs/v4.2.0.rst @@ -43,6 +43,7 @@ Changes - The process of sending cookies has been moved to the ``Response`` class. Now the ``Session`` class doesn't send cookies, set them to the Response. - Validation. Changed generation of errors when using fields with a wildcard (*). Now the error key contains the full path. See :ref:`validation-getting-all-errors`. - ``Validation::getError()`` when using a wildcard will return all found errors matching the mask as a string. +- To make the default configuration more secure, auto-routing has been changed to disabled by default. Deprecations ************ From d9a2389bf4437bf811368568cd536ba216bc5fc1 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 1 Mar 2022 11:33:42 +0900 Subject: [PATCH 0747/1246] docs: move "Default Controller" in the "Auto Routing" --- user_guide_src/source/incoming/routing.rst | 50 +++++++++++----------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/user_guide_src/source/incoming/routing.rst b/user_guide_src/source/incoming/routing.rst index eb7d57370015..3a761ed1d5a0 100644 --- a/user_guide_src/source/incoming/routing.rst +++ b/user_guide_src/source/incoming/routing.rst @@ -465,31 +465,6 @@ then you can change this value to save typing: .. literalinclude:: routing/046.php -Default Controller -================== - -When a user visits the root of your site (i.e., example.com) the controller to use is determined by the value set by -the ``setDefaultController()`` method, unless a route exists for it explicitly. The default value for this is ``Home`` -which matches the controller at **app/Controllers/Home.php**: - -.. literalinclude:: routing/047.php - -The default controller is also used when no matching route has been found, and the URI would point to a directory -in the controllers directory. For example, if the user visits **example.com/admin**, if a controller was found at -**app/Controllers/Admin/Home.php**, it would be used. - -Default Method -============== - -This works similar to the default controller setting, but is used to determine the default method that is used -when a controller is found that matches the URI, but no segment exists for the method. The default value is -``index``. - -In this example, if the user were to visit **example.com/products**, and a ``Products`` controller existed, the -``Products::listAll()`` method would be executed: - -.. literalinclude:: routing/048.php - Translate URI Dashes ==================== @@ -566,8 +541,33 @@ and executes the corresponding controller method. The auto-routing is enabled by .. important:: The auto-routing routes a HTTP request with **any** HTTP method to a controller method. +Default Controller +================== + +When a user visits the root of your site (i.e., example.com) the controller to use is determined by the value set by +the ``setDefaultController()`` method, unless a route exists for it explicitly. The default value for this is ``Home`` +which matches the controller at **app/Controllers/Home.php**: + +.. literalinclude:: routing/047.php + +The default controller is also used when no matching route has been found, and the URI would point to a directory +in the controllers directory. For example, if the user visits **example.com/admin**, if a controller was found at +**app/Controllers/Admin/Home.php**, it would be used. + See :ref:`Auto Routing in Controllers ` for more info. +Default Method +============== + +This works similar to the default controller setting, but is used to determine the default method that is used +when a controller is found that matches the URI, but no segment exists for the method. The default value is +``index``. + +In this example, if the user were to visit **example.com/products**, and a ``Products`` controller existed, the +``Products::listAll()`` method would be executed: + +.. literalinclude:: routing/048.php + Confirming Routes ***************** From aa69f381eae378e867d940c38363efc548ec047f Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 1 Mar 2022 11:40:19 +0900 Subject: [PATCH 0748/1246] docs: move "Default Method" in "Auto Routing" --- user_guide_src/source/incoming/routing.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/user_guide_src/source/incoming/routing.rst b/user_guide_src/source/incoming/routing.rst index 3a761ed1d5a0..d4b4c2f34cf1 100644 --- a/user_guide_src/source/incoming/routing.rst +++ b/user_guide_src/source/incoming/routing.rst @@ -539,10 +539,13 @@ and executes the corresponding controller method. The auto-routing is enabled by .. note:: To prevent misconfiguration and miscoding, we recommend that you disable the auto-routing feature. See :ref:`use-defined-routes-only`. +Configuration Options +===================== + .. important:: The auto-routing routes a HTTP request with **any** HTTP method to a controller method. Default Controller -================== +------------------ When a user visits the root of your site (i.e., example.com) the controller to use is determined by the value set by the ``setDefaultController()`` method, unless a route exists for it explicitly. The default value for this is ``Home`` @@ -557,7 +560,7 @@ in the controllers directory. For example, if the user visits **example.com/admi See :ref:`Auto Routing in Controllers ` for more info. Default Method -============== +-------------- This works similar to the default controller setting, but is used to determine the default method that is used when a controller is found that matches the URI, but no segment exists for the method. The default value is From fabcf1c4ab76efdc41faf24553d094bde2cee385 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 1 Mar 2022 11:53:07 +0900 Subject: [PATCH 0749/1246] docs: add "Enable Auto Routing" --- user_guide_src/source/incoming/routing.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/user_guide_src/source/incoming/routing.rst b/user_guide_src/source/incoming/routing.rst index d4b4c2f34cf1..04beafd9f2dc 100644 --- a/user_guide_src/source/incoming/routing.rst +++ b/user_guide_src/source/incoming/routing.rst @@ -515,6 +515,15 @@ It is recommended that all routes are defined in the **app/Config/Routes.php** f However, CodeIgniter can also automatically route HTTP requests based on conventions and execute the corresponding controller methods. +Enable Auto Routing +=================== + +Since v4.2.0, the auto-routing is disabled by default. + +To use it, you need to change the setting ``setAutoRoute()`` option to true in **app/Config/Routes.php**:: + + $routes->setAutoRoute(true); + URI Segments ============ From a514043270fa56efe301f37e5a4955d140a72527 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 1 Mar 2022 11:53:54 +0900 Subject: [PATCH 0750/1246] docs: update existing description for disabling auto-routing by default --- user_guide_src/source/incoming/controllers.rst | 6 +++--- user_guide_src/source/incoming/routing.rst | 14 +++++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/user_guide_src/source/incoming/controllers.rst b/user_guide_src/source/incoming/controllers.rst index 037710255100..287d6ae28153 100644 --- a/user_guide_src/source/incoming/controllers.rst +++ b/user_guide_src/source/incoming/controllers.rst @@ -114,10 +114,10 @@ Auto Routing This section describes the functionality of the auto-routing. It automatically routes an HTTP request, and executes the corresponding controller method -without route definitions. The auto-routing is enabled by default. +without route definitions. The auto-routing is disabled by default. .. note:: To prevent misconfiguration and miscoding, we recommend that you disable - the auto-routing feature. See :ref:`use-defined-routes-only`. + the auto-routing feature. .. important:: The auto-routing routes a HTTP request with **any** HTTP method to a controller method. @@ -220,7 +220,7 @@ Your method will be passed URI segments 3 and 4 (``'sandals'`` and ``'123'``): .. literalinclude:: controllers/014.php .. important:: If you are using the :doc:`URI Routing ` - feature, the segments passed to your method will be the re-routed + feature, the segments passed to your method will be the defined ones. Defining a Default Controller diff --git a/user_guide_src/source/incoming/routing.rst b/user_guide_src/source/incoming/routing.rst index 04beafd9f2dc..77d68533fba2 100644 --- a/user_guide_src/source/incoming/routing.rst +++ b/user_guide_src/source/incoming/routing.rst @@ -312,7 +312,7 @@ available from the command line: .. literalinclude:: routing/032.php -.. warning:: If you don't disable auto-routing and place the command file in **app/Controllers**, +.. warning:: If you enable auto-routing and place the command file in **app/Controllers**, anyone could access the command with the help of auto-routing via HTTP. Global Options @@ -515,6 +515,11 @@ It is recommended that all routes are defined in the **app/Config/Routes.php** f However, CodeIgniter can also automatically route HTTP requests based on conventions and execute the corresponding controller methods. +.. warning:: To prevent misconfiguration and miscoding, we recommend that you disable + the auto-routing feature. + +.. important:: The auto-routing routes a HTTP request with **any** HTTP method to a controller method. + Enable Auto Routing =================== @@ -543,15 +548,14 @@ In the above example, CodeIgniter would attempt to find a controller named **Hel and executes ``index()`` method with passing ``'1'`` as the first argument. We call this "**Auto Routes**". CodeIgniter automatically routes an HTTP request, -and executes the corresponding controller method. The auto-routing is enabled by default. +and executes the corresponding controller method. The auto-routing is disabled by default. -.. note:: To prevent misconfiguration and miscoding, we recommend that you disable - the auto-routing feature. See :ref:`use-defined-routes-only`. +See :ref:`Auto Routing in Controllers ` for more info. Configuration Options ===================== -.. important:: The auto-routing routes a HTTP request with **any** HTTP method to a controller method. +These options are available at the top of **app/Config/Routes.php**. Default Controller ------------------ From 1e6a48625fd77546390107b71823a095f9b13428 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 1 Mar 2022 12:51:06 +0900 Subject: [PATCH 0751/1246] docs: replace remap with map --- user_guide_src/source/incoming/controllers.rst | 2 +- user_guide_src/source/incoming/routing.rst | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/user_guide_src/source/incoming/controllers.rst b/user_guide_src/source/incoming/controllers.rst index 287d6ae28153..a4c635a6532c 100644 --- a/user_guide_src/source/incoming/controllers.rst +++ b/user_guide_src/source/incoming/controllers.rst @@ -279,7 +279,7 @@ called if the URL contains *only* the sub-directory. Simply put a controller in there that matches the name of your default controller as specified in your **app/Config/Routes.php** file. -CodeIgniter also permits you to remap your URIs using its :doc:`URI Routing ` feature. +CodeIgniter also permits you to map your URIs using its :doc:`URI Routing ` feature. Remapping Method Calls ********************** diff --git a/user_guide_src/source/incoming/routing.rst b/user_guide_src/source/incoming/routing.rst index 77d68533fba2..41741fb93ebf 100644 --- a/user_guide_src/source/incoming/routing.rst +++ b/user_guide_src/source/incoming/routing.rst @@ -76,22 +76,22 @@ Examples Here are a few basic routing examples. -A URL containing the word **journals** in the first segment will be remapped to the ``\App\Controllers\Blogs`` class, +A URL containing the word **journals** in the first segment will be mapped to the ``\App\Controllers\Blogs`` class, and the default method, which is usually ``index()``: .. literalinclude:: routing/006.php -A URL containing the segments **blog/joe** will be remapped to the ``\App\Controllers\Blogs`` class and the ``users`` method. +A URL containing the segments **blog/joe** will be mapped to the ``\App\Controllers\Blogs`` class and the ``users`` method. The ID will be set to ``34``: .. literalinclude:: routing/007.php -A URL with **product** as the first segment, and anything in the second will be remapped to the ``\App\Controllers\Catalog`` class +A URL with **product** as the first segment, and anything in the second will be mapped to the ``\App\Controllers\Catalog`` class and the ``productLookup`` method: .. literalinclude:: routing/008.php -A URL with **product** as the first segment, and a number in the second will be remapped to the ``\App\Controllers\Catalog`` class +A URL with **product** as the first segment, and a number in the second will be mapped to the ``\App\Controllers\Catalog`` class and the ``productLookupByID`` method passing in the match as a variable to the method: .. literalinclude:: routing/009.php From 08ecf84170635df1235ae757c6d9ff4b4ee1fe92 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 1 Mar 2022 12:55:26 +0900 Subject: [PATCH 0752/1246] docs: add `()` at the end of method names --- user_guide_src/source/incoming/routing.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/user_guide_src/source/incoming/routing.rst b/user_guide_src/source/incoming/routing.rst index 41741fb93ebf..4103abb6e428 100644 --- a/user_guide_src/source/incoming/routing.rst +++ b/user_guide_src/source/incoming/routing.rst @@ -81,18 +81,18 @@ and the default method, which is usually ``index()``: .. literalinclude:: routing/006.php -A URL containing the segments **blog/joe** will be mapped to the ``\App\Controllers\Blogs`` class and the ``users`` method. +A URL containing the segments **blog/joe** will be mapped to the ``\App\Controllers\Blogs`` class and the ``users()`` method. The ID will be set to ``34``: .. literalinclude:: routing/007.php A URL with **product** as the first segment, and anything in the second will be mapped to the ``\App\Controllers\Catalog`` class -and the ``productLookup`` method: +and the ``productLookup()`` method: .. literalinclude:: routing/008.php A URL with **product** as the first segment, and a number in the second will be mapped to the ``\App\Controllers\Catalog`` class -and the ``productLookupByID`` method passing in the match as a variable to the method: +and the ``productLookupByID()`` method passing in the match as a variable to the method: .. literalinclude:: routing/009.php From ab1d3d862c2774b51e432279412124daa5344e04 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 2 Mar 2022 09:32:49 +0900 Subject: [PATCH 0753/1246] docs: update Tutorial --- .../source/tutorial/create_news_items.rst | 2 +- .../source/tutorial/create_news_items/004.php | 5 + .../source/tutorial/news_section.rst | 3 +- .../source/tutorial/news_section/008.php | 5 + .../source/tutorial/static_pages.rst | 120 +++++++----------- .../source/tutorial/static_pages/003.php | 6 + .../source/tutorial/static_pages/004.php | 1 + 7 files changed, 68 insertions(+), 74 deletions(-) diff --git a/user_guide_src/source/tutorial/create_news_items.rst b/user_guide_src/source/tutorial/create_news_items.rst index 32bc4b703e18..49ebc36c2bc3 100644 --- a/user_guide_src/source/tutorial/create_news_items.rst +++ b/user_guide_src/source/tutorial/create_news_items.rst @@ -119,7 +119,7 @@ Routing Before you can start adding news items into your CodeIgniter application you have to add an extra rule to **app/Config/Routes.php** file. Make sure your -file contains the following. This makes sure CodeIgniter sees ``create`` +file contains the following. This makes sure CodeIgniter sees ``create()`` as a method instead of a news item's slug. You can read more about different routing types :doc:`here `. diff --git a/user_guide_src/source/tutorial/create_news_items/004.php b/user_guide_src/source/tutorial/create_news_items/004.php index c8c66824fd82..8a0905770c82 100644 --- a/user_guide_src/source/tutorial/create_news_items/004.php +++ b/user_guide_src/source/tutorial/create_news_items/004.php @@ -1,6 +1,11 @@ match(['get', 'post'], 'news/create', 'News::create'); $routes->get('news/(:segment)', 'News::view/$1'); $routes->get('news', 'News::index'); +$routes->get('pages', 'Pages::index'); $routes->get('(:any)', 'Pages::view/$1'); + +// ... diff --git a/user_guide_src/source/tutorial/news_section.rst b/user_guide_src/source/tutorial/news_section.rst index 2797c8a5cfaa..a27902819265 100644 --- a/user_guide_src/source/tutorial/news_section.rst +++ b/user_guide_src/source/tutorial/news_section.rst @@ -171,8 +171,7 @@ The only thing left to do is create the corresponding view at Routing ******* -Because of the wildcard routing rule created earlier, you need an extra -route to view the controller that you just made. Modify your routing file +Modify your routing file (**app/Config/Routes.php**) so it looks as follows. This makes sure the requests reach the ``News`` controller instead of going directly to the ``Pages`` controller. The first line routes URI's diff --git a/user_guide_src/source/tutorial/news_section/008.php b/user_guide_src/source/tutorial/news_section/008.php index 8943925258bd..4ba41638ef7f 100644 --- a/user_guide_src/source/tutorial/news_section/008.php +++ b/user_guide_src/source/tutorial/news_section/008.php @@ -1,5 +1,10 @@ get('news/(:segment)', 'News::view/$1'); $routes->get('news', 'News::index'); +$routes->get('pages', 'Pages::index'); $routes->get('(:any)', 'Pages::view/$1'); + +// ... diff --git a/user_guide_src/source/tutorial/static_pages.rst b/user_guide_src/source/tutorial/static_pages.rst index 5128d6665e2c..6c39f82b5f80 100644 --- a/user_guide_src/source/tutorial/static_pages.rst +++ b/user_guide_src/source/tutorial/static_pages.rst @@ -9,20 +9,6 @@ The first thing you're going to do is set up a **controller** to handle static pages. A controller is simply a class that helps delegate work. It is the glue of your web application. -For example, when a call is made to:: - - http://example.com/news/latest/10 - -We might imagine that there is a controller named "news". The method -being called on news would be "latest". The news method's job could be to -grab 10 news items, and render them on the page. Very often in MVC, -you'll see URL patterns that match:: - - http://example.com/[controller-class]/[controller-method]/[arguments] - -As URL schemes become more complex, this may change. But for now, this -is all we will need to know. - Let's Make our First Controller ******************************* @@ -126,59 +112,11 @@ view. throw errors on case-sensitive platforms. You can read more about it :doc:`here `. -Running the App -*************** - -Ready to test? You cannot run the app using PHP's built-in server, -since it will not properly process the ``.htaccess`` rules that are provided in -``public``, and which eliminate the need to specify "index.php/" -as part of a URL. CodeIgniter has its own command that you can use though. - -From the command line, at the root of your project:: - - > php spark serve - -will start a web server, accessible on port 8080. If you set the location field -in your browser to ``localhost:8080``, you should see the CodeIgniter welcome page. - -You can now try several URLs in the browser location field, to see what the ``Pages`` -controller you made above produces... - -.. table:: - :widths: 20 80 - - +---------------------------------+-----------------------------------------------------------------+ - | URL | Will show | - +=================================+=================================================================+ - | localhost:8080/pages | the results from the `index` method inside our `Pages` | - | | controller, which is to display the CodeIgniter "welcome" page, | - | | because "index" is the default controller method | - +---------------------------------+-----------------------------------------------------------------+ - | localhost:8080/pages/index | the CodeIgniter "welcome" page, because we explicitly asked for | - | | the "index" method | - +---------------------------------+-----------------------------------------------------------------+ - | localhost:8080/pages/view | the "home" page that you made above, because it is the default | - | | "page" parameter to the ``view()`` method. | - +---------------------------------+-----------------------------------------------------------------+ - | localhost:8080/pages/view/home | show the "home" page that you made above, because we explicitly | - | | asked for it | - +---------------------------------+-----------------------------------------------------------------+ - | localhost:8080/pages/view/about | the "about" page that you made above, because we explicitly | - | | asked for it | - +---------------------------------+-----------------------------------------------------------------+ - | localhost:8080/pages/view/shop | a "404 - File Not Found" error page, because there is no | - | | `app/Views/pages/shop.php` | - +---------------------------------+-----------------------------------------------------------------+ - Routing ******* -The controller is now functioning! - -Using custom routing rules, you have the power to map any URI to any -controller and method, and break free from the normal convention:: - - http://example.com/[controller-class]/[controller-method]/[arguments] +We have made the controller. The next thing is to set routing rules. +Routing associates a URI with a controller's method. Let's do that. Open the routing file located at **app/Config/Routes.php** and look for the "Route Definitions" @@ -191,9 +129,10 @@ The only uncommented line there to start with should be: This directive says that any incoming request without any content specified should be handled by the ``index()`` method inside the ``Home`` controller. -Add the following line, **after** the route directive for '/'. +Add the following lines, **after** the route directive for '/'. .. literalinclude:: static_pages/004.php + :lines: 2- CodeIgniter reads its routing rules from top to bottom and routes the request to the first matching rule. Each rule is a regular expression @@ -205,18 +144,57 @@ arguments. More information about routing can be found in the URI Routing :doc:`documentation `. -Here, the second rule in the ``$routes`` object matches **any** request -using the wildcard string ``(:any)``. and passes the parameter to the +Here, the second rule in the ``$routes`` object matches GET request +to the URI path ``/pages`` maps the ``index()`` method of the ``Pages`` class. + +The third rule in the ``$routes`` object matches GET request to **any** URI path +using the wildcard string ``(:any)``, and passes the parameter to the ``view()`` method of the ``Pages`` class. +Running the App +*************** + +Ready to test? You cannot run the app using PHP's built-in server, +since it will not properly process the ``.htaccess`` rules that are provided in +``public``, and which eliminate the need to specify "index.php/" +as part of a URL. CodeIgniter has its own command that you can use though. + +From the command line, at the root of your project:: + + > php spark serve + +will start a web server, accessible on port 8080. If you set the location field +in your browser to ``localhost:8080``, you should see the CodeIgniter welcome page. + Now visit ``localhost:8080/home``. Did it get routed correctly to the ``view()`` -method in the pages controller? Awesome! +method in the ``Pages`` controller? Awesome! You should see something like the following: .. image:: ../images/tutorial1.png :align: center -.. note:: When manually specifying routes, it is recommended to disable - auto-routing by setting ``$routes->setAutoRoute(false);`` in the **Routes.php** file. - This ensures that only routes you define can be accessed. +You can now try several URLs in the browser location field, to see what the ``Pages`` +controller you made above produces... + +.. table:: + :widths: 20 80 + + +---------------------------------+-----------------------------------------------------------------+ + | URL | Will show | + +=================================+=================================================================+ + | localhost:8080/pages | the results from the ``index()`` method inside our ``Pages`` | + | | controller, which is to display the CodeIgniter "welcome" page. | + +---------------------------------+-----------------------------------------------------------------+ + | localhost:8080/pages/view | the "home" page that you made above, because it is the default | + | | "page" parameter to the ``view()`` method. | + +---------------------------------+-----------------------------------------------------------------+ + | localhost:8080/pages/view/home | show the "home" page that you made above, because we explicitly | + | | asked for it. | + +---------------------------------+-----------------------------------------------------------------+ + | localhost:8080/pages/view/about | the "about" page that you made above, because we explicitly | + | | asked for it. | + +---------------------------------+-----------------------------------------------------------------+ + | localhost:8080/pages/view/shop | a "404 - File Not Found" error page, because there is no | + | | **app/Views/pages/shop.php**. | + +---------------------------------+-----------------------------------------------------------------+ diff --git a/user_guide_src/source/tutorial/static_pages/003.php b/user_guide_src/source/tutorial/static_pages/003.php index d799d1cf0fb5..956c097d390f 100644 --- a/user_guide_src/source/tutorial/static_pages/003.php +++ b/user_guide_src/source/tutorial/static_pages/003.php @@ -1,3 +1,9 @@ get('/', 'Home::index'); + +// ... diff --git a/user_guide_src/source/tutorial/static_pages/004.php b/user_guide_src/source/tutorial/static_pages/004.php index f998b89762fd..a48a8caf18cb 100644 --- a/user_guide_src/source/tutorial/static_pages/004.php +++ b/user_guide_src/source/tutorial/static_pages/004.php @@ -1,3 +1,4 @@ get('pages', 'Pages::index'); $routes->get('(:any)', 'Pages::view/$1'); From 4027b1f9247ea3d6cf5b18c26a3d21179ccd7a67 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 2 Mar 2022 10:00:10 +0900 Subject: [PATCH 0754/1246] docs: change "note" to "warning" --- user_guide_src/source/incoming/controllers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/incoming/controllers.rst b/user_guide_src/source/incoming/controllers.rst index a4c635a6532c..928a16fff9b3 100644 --- a/user_guide_src/source/incoming/controllers.rst +++ b/user_guide_src/source/incoming/controllers.rst @@ -116,7 +116,7 @@ This section describes the functionality of the auto-routing. It automatically routes an HTTP request, and executes the corresponding controller method without route definitions. The auto-routing is disabled by default. -.. note:: To prevent misconfiguration and miscoding, we recommend that you disable +.. warning:: To prevent misconfiguration and miscoding, we recommend that you disable the auto-routing feature. .. important:: The auto-routing routes a HTTP request with **any** HTTP method to a controller method. From c7edb7c4c26ce82044b29607177de761e84b5311 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 2 Mar 2022 12:26:02 +0900 Subject: [PATCH 0755/1246] docs: make warning more detailed --- user_guide_src/source/incoming/controllers.rst | 5 +++-- user_guide_src/source/incoming/routing.rst | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/user_guide_src/source/incoming/controllers.rst b/user_guide_src/source/incoming/controllers.rst index 928a16fff9b3..99c22b5a356d 100644 --- a/user_guide_src/source/incoming/controllers.rst +++ b/user_guide_src/source/incoming/controllers.rst @@ -116,8 +116,9 @@ This section describes the functionality of the auto-routing. It automatically routes an HTTP request, and executes the corresponding controller method without route definitions. The auto-routing is disabled by default. -.. warning:: To prevent misconfiguration and miscoding, we recommend that you disable - the auto-routing feature. +.. warning:: To prevent misconfiguration and miscoding, we recommend that you do not use + the auto-routing feature. It is easy to create vulnerable apps where controller filters + or CSRF protection are bypassed. .. important:: The auto-routing routes a HTTP request with **any** HTTP method to a controller method. diff --git a/user_guide_src/source/incoming/routing.rst b/user_guide_src/source/incoming/routing.rst index 4103abb6e428..504e555dd76c 100644 --- a/user_guide_src/source/incoming/routing.rst +++ b/user_guide_src/source/incoming/routing.rst @@ -515,8 +515,9 @@ It is recommended that all routes are defined in the **app/Config/Routes.php** f However, CodeIgniter can also automatically route HTTP requests based on conventions and execute the corresponding controller methods. -.. warning:: To prevent misconfiguration and miscoding, we recommend that you disable - the auto-routing feature. +.. warning:: To prevent misconfiguration and miscoding, we recommend that you do not use + the auto-routing feature. It is easy to create vulnerable apps where controller filters + or CSRF protection are bypassed. .. important:: The auto-routing routes a HTTP request with **any** HTTP method to a controller method. From d811d5b37ad4ede6d04afb4dd51ff510481e9205 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 2 Mar 2022 12:27:06 +0900 Subject: [PATCH 0756/1246] docs: update description --- user_guide_src/source/cli/cli.rst | 2 +- user_guide_src/source/incoming/routing.rst | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/user_guide_src/source/cli/cli.rst b/user_guide_src/source/cli/cli.rst index f3ffcc9285f6..bd57d4f608fd 100644 --- a/user_guide_src/source/cli/cli.rst +++ b/user_guide_src/source/cli/cli.rst @@ -88,7 +88,7 @@ works exactly like a normal route definition: For more information, see the :ref:`Routes ` page. -.. warning:: If you don't disable auto-routing and place the command file in **app/Controllers**, +.. warning:: If you enable auto-routing and place the command file in **app/Controllers**, anyone could access the command with the help of auto-routing via HTTP. The CLI Library diff --git a/user_guide_src/source/incoming/routing.rst b/user_guide_src/source/incoming/routing.rst index 504e555dd76c..4989f0891e0b 100644 --- a/user_guide_src/source/incoming/routing.rst +++ b/user_guide_src/source/incoming/routing.rst @@ -479,8 +479,12 @@ dash isn't a valid class or method name character and would cause a fatal error Use Defined Routes Only ======================= +Since v4.2.0, the auto-routing is disabled by default. + When no defined route is found that matches the URI, the system will attempt to match that URI against the -controllers and methods as described in :ref:`auto-routing`. You can disable this automatic matching, and restrict routes +controllers and methods when :ref:`auto-routing` is enabled. + +You can disable this automatic matching, and restrict routes to only those defined by you, by setting the ``setAutoRoute()`` option to false: .. literalinclude:: routing/050.php From 1fe49bafc27d3483f9d0c863c4dbc4c29fb853fb Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 2 Mar 2022 12:33:35 +0900 Subject: [PATCH 0757/1246] docs: add warning as a comment --- app/Config/Routes.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 2b35d0dda6f8..15371af7de5e 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -21,7 +21,10 @@ $routes->setDefaultMethod('index'); $routes->setTranslateURIDashes(false); $routes->set404Override(); -$routes->setAutoRoute(false); +// The auto-routing is very dangerous. It is easy to create vulnerable apps +// where controller filters or CSRF protection are bypassed. +// It is recommended that you do not set it to `true`. +//$routes->setAutoRoute(false); /* * -------------------------------------------------------------------- From a65bc3ab2f5302c11bff26e545b12ec7b75e4e8f Mon Sep 17 00:00:00 2001 From: kenjis Date: Thu, 3 Mar 2022 09:21:21 +0900 Subject: [PATCH 0758/1246] docs: add about the config change of auto-routing in Upgrade Note --- user_guide_src/source/installation/upgrade_420.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/user_guide_src/source/installation/upgrade_420.rst b/user_guide_src/source/installation/upgrade_420.rst index a302f113ae61..daf89b39290f 100644 --- a/user_guide_src/source/installation/upgrade_420.rst +++ b/user_guide_src/source/installation/upgrade_420.rst @@ -49,7 +49,8 @@ Content Changes The following files received significant changes (including deprecations or visual adjustments) and it is recommended that you merge the updated versions with your application: -* +* ``app/Config/Routes.php`` + * To make the default configuration more secure, auto-routing has been changed to disabled by default. All Changes =========== From dafce4979cba1aed3b8a39705b919014fa6cd340 Mon Sep 17 00:00:00 2001 From: kenjis Date: Thu, 31 Mar 2022 10:34:00 +0900 Subject: [PATCH 0759/1246] feat: add options to change delimitors for conditionals To avoid accidentally changing JavaScript code. --- system/View/Parser.php | 45 +++++++++++++++++++++++++++-- tests/system/View/ParserTest.php | 49 ++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 3 deletions(-) diff --git a/system/View/Parser.php b/system/View/Parser.php index 6834c003e500..665347d8f978 100644 --- a/system/View/Parser.php +++ b/system/View/Parser.php @@ -37,6 +37,16 @@ class Parser extends View */ public $rightDelimiter = '}'; + /** + * Left delimiter characters for conditionals + */ + protected string $leftConditionalDelimiter = '{'; + + /** + * Right delimiter characters for conditionals + */ + protected string $rightConditionalDelimiter = '}'; + /** * Stores extracted noparse blocks. * @@ -405,7 +415,14 @@ public function insertNoparse(string $template): string */ protected function parseConditionals(string $template): string { - $pattern = '/\{\s*(if|elseif)\s*((?:\()?(.*?)(?:\))?)\s*\}/ms'; + $leftDelimiter = preg_quote($this->leftConditionalDelimiter, '/'); + $rightDelimiter = preg_quote($this->rightConditionalDelimiter, '/'); + + $pattern = '/' + . $leftDelimiter + . '\s*(if|elseif)\s*((?:\()?(.*?)(?:\))?)\s*' + . $rightDelimiter + . '/ms'; /* * For each match: @@ -424,8 +441,16 @@ protected function parseConditionals(string $template): string $template = str_replace($match[0], $statement, $template); } - $template = preg_replace('/\{\s*else\s*\}/ms', '', $template); - $template = preg_replace('/\{\s*endif\s*\}/ms', '', $template); + $template = preg_replace( + '/' . $leftDelimiter . '\s*else\s*' . $rightDelimiter . '/ms', + '', + $template + ); + $template = preg_replace( + '/' . $leftDelimiter . '\s*endif\s*' . $rightDelimiter . '/ms', + '', + $template + ); // Parse the PHP itself, or insert an error so they can debug ob_start(); @@ -461,6 +486,20 @@ public function setDelimiters($leftDelimiter = '{', $rightDelimiter = '}'): Rend return $this; } + /** + * Over-ride the substitution conditional delimiters. + * + * @param string $leftDelimiter + * @param string $rightDelimiter + */ + public function setConditionalDelimiters($leftDelimiter = '{', $rightDelimiter = '}'): RendererInterface + { + $this->leftConditionalDelimiter = $leftDelimiter; + $this->rightConditionalDelimiter = $rightDelimiter; + + return $this; + } + /** * Handles replacing a pseudo-variable with the actual content. Will double-check * for escaping brackets. diff --git a/tests/system/View/ParserTest.php b/tests/system/View/ParserTest.php index 3462b0cc2a84..bf307a419f61 100644 --- a/tests/system/View/ParserTest.php +++ b/tests/system/View/ParserTest.php @@ -938,4 +938,53 @@ public function testRenderFindsOtherView() $expected = '

    Hello World

    '; $this->assertSame($expected, $this->parser->render('Simpler.html')); } + + public function testChangedConditionalDelimitersTrue() + { + $this->parser->setConditionalDelimiters('{%', '%}'); + + $data = [ + 'doit' => true, + 'dontdoit' => false, + ]; + $this->parser->setData($data); + + $template = '{% if $doit %}Howdy{% endif %}{% if $dontdoit === false %}Welcome{% endif %}'; + $output = $this->parser->renderString($template); + + $this->assertSame('HowdyWelcome', $output); + } + + /** + * @see https://github.com/codeigniter4/CodeIgniter4/issues/5831 + */ + public function testChangeConditionalDelimitersWorkWithJavaScriptCode() + { + $this->parser->setConditionalDelimiters('{%', '%}'); + + $data = [ + 'message' => 'Warning!', + ]; + $this->parser->setData($data); + + $template = <<<'EOL' + + EOL; + $expected = <<<'EOL' + + EOL; + $this->assertSame($expected, $this->parser->renderString($template)); + } } From 2d90f0cc6ca2bca0927bd73413d04f60d77fd9a2 Mon Sep 17 00:00:00 2001 From: kenjis Date: Thu, 31 Mar 2022 10:55:53 +0900 Subject: [PATCH 0760/1246] docs: add setConditionalDelimiters() --- .../source/outgoing/view_parser.rst | 25 +++++++++++++++++++ .../source/outgoing/view_parser/027.php | 3 +++ 2 files changed, 28 insertions(+) create mode 100644 user_guide_src/source/outgoing/view_parser/027.php diff --git a/user_guide_src/source/outgoing/view_parser.rst b/user_guide_src/source/outgoing/view_parser.rst index 2e615e52bdb9..752dcc489590 100644 --- a/user_guide_src/source/outgoing/view_parser.rst +++ b/user_guide_src/source/outgoing/view_parser.rst @@ -290,6 +290,31 @@ of the comparison operators you would normally, like ``==``, ``===``, ``!==``, ` .. warning:: In the background, conditionals are parsed using an ``eval()``, so you must ensure that you take care with the user data that is used within conditionals, or you could open your application up to security risks. +Changing the Conditional Delimiters +----------------------------------- + +If you have JavaScript code like the following in your templates, the Parser raises a syntax error because there are strings that can be interpreted as a conditional:: + + + +In that case, you can change the delimiters for conditionals with the ``setConditionalDelimiters()`` method to avoid misinterpretations: + +.. literalinclude:: view_parser/027.php + +In this case, you will write code in your template:: + + {% if $role=='admin' %} +

    Welcome, Admin

    + {% else %} +

    Welcome, User

    + {% endif %} + Escaping Data ============= diff --git a/user_guide_src/source/outgoing/view_parser/027.php b/user_guide_src/source/outgoing/view_parser/027.php new file mode 100644 index 000000000000..84730679ced5 --- /dev/null +++ b/user_guide_src/source/outgoing/view_parser/027.php @@ -0,0 +1,3 @@ +setConditionalDelimiters('{%', '%}'); From e521f66fdabee7d0d109761caf084809132ccebc Mon Sep 17 00:00:00 2001 From: kenjis Date: Thu, 31 Mar 2022 11:40:15 +0900 Subject: [PATCH 0761/1246] docs: replace variables with properties They are different. --- user_guide_src/source/tutorial/static_pages.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/tutorial/static_pages.rst b/user_guide_src/source/tutorial/static_pages.rst index 6c39f82b5f80..668683995231 100644 --- a/user_guide_src/source/tutorial/static_pages.rst +++ b/user_guide_src/source/tutorial/static_pages.rst @@ -30,7 +30,7 @@ displays the CodeIgniter welcome page. The ``Pages`` class is extending the ``BaseController`` class that extends the ``CodeIgniter\Controller`` class. This means that the new Pages class can access the -methods and variables defined in the ``CodeIgniter\Controller`` class +methods and properties defined in the ``CodeIgniter\Controller`` class (**system/Controller.php**). The **controller is what will become the center of every request** to From 5dacb15c7ccd93ecb74b99d9788397941dd642cb Mon Sep 17 00:00:00 2001 From: kenjis Date: Thu, 31 Mar 2022 11:59:08 +0900 Subject: [PATCH 0762/1246] fix: remove session _ci_validation_errors before running validation --- system/Validation/Validation.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/system/Validation/Validation.php b/system/Validation/Validation.php index 155efc223492..f330c91799f6 100644 --- a/system/Validation/Validation.php +++ b/system/Validation/Validation.php @@ -108,6 +108,12 @@ public function __construct($config, RendererInterface $view) */ public function run(?array $data = null, ?string $group = null, ?string $dbGroup = null): bool { + // If there are still validation errors for redirect_with_input request, remove them. + // See `getErrors()` method. + if (isset($_SESSION, $_SESSION['_ci_validation_errors'])) { + unset($_SESSION['_ci_validation_errors']); + } + $data ??= $this->data; // i.e. is_unique From 35c2947d1a1988f37a422275e5ba037f32f11aa3 Mon Sep 17 00:00:00 2001 From: kenjis Date: Thu, 31 Mar 2022 11:40:53 +0900 Subject: [PATCH 0763/1246] docs: remove `echo` in the controller and use `return` echo() has side effects, so return is better. --- .../source/tutorial/create_news_items/002.php | 10 +++++----- user_guide_src/source/tutorial/news_section/004.php | 6 +++--- user_guide_src/source/tutorial/news_section/006.php | 6 +++--- user_guide_src/source/tutorial/static_pages/002.php | 6 +++--- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/user_guide_src/source/tutorial/create_news_items/002.php b/user_guide_src/source/tutorial/create_news_items/002.php index cdebb0a71e6a..66ff5e26776b 100644 --- a/user_guide_src/source/tutorial/create_news_items/002.php +++ b/user_guide_src/source/tutorial/create_news_items/002.php @@ -18,11 +18,11 @@ public function create() 'body' => $this->request->getPost('body'), ]); - echo view('news/success'); - } else { - echo view('templates/header', ['title' => 'Create a news item']); - echo view('news/create'); - echo view('templates/footer'); + return view('news/success'); } + + return view('templates/header', ['title' => 'Create a news item']) + . view('news/create') + . view('templates/footer'); } } diff --git a/user_guide_src/source/tutorial/news_section/004.php b/user_guide_src/source/tutorial/news_section/004.php index 475b86fa2f45..b62562bfe351 100644 --- a/user_guide_src/source/tutorial/news_section/004.php +++ b/user_guide_src/source/tutorial/news_section/004.php @@ -15,8 +15,8 @@ public function index() 'title' => 'News archive', ]; - echo view('templates/header', $data); - echo view('news/overview', $data); - echo view('templates/footer', $data); + return view('templates/header', $data) + . view('news/overview', $data) + . view('templates/footer', $data); } } diff --git a/user_guide_src/source/tutorial/news_section/006.php b/user_guide_src/source/tutorial/news_section/006.php index 36faacb39a50..8bfc123e43f7 100644 --- a/user_guide_src/source/tutorial/news_section/006.php +++ b/user_guide_src/source/tutorial/news_section/006.php @@ -18,8 +18,8 @@ public function view($slug = null) $data['title'] = $data['news']['title']; - echo view('templates/header', $data); - echo view('news/view', $data); - echo view('templates/footer', $data); + return view('templates/header', $data) + . view('news/view', $data) + . view('templates/footer', $data); } } diff --git a/user_guide_src/source/tutorial/static_pages/002.php b/user_guide_src/source/tutorial/static_pages/002.php index 970e663558d5..9f80c4556a58 100644 --- a/user_guide_src/source/tutorial/static_pages/002.php +++ b/user_guide_src/source/tutorial/static_pages/002.php @@ -13,8 +13,8 @@ public function view($page = 'home') $data['title'] = ucfirst($page); // Capitalize the first letter - echo view('templates/header', $data); - echo view('pages/' . $page, $data); - echo view('templates/footer', $data); + return view('templates/header', $data) + . view('pages/' . $page, $data) + . view('templates/footer', $data); } } From 59260c1cceda48673214e82b4607ba8567f135c4 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 1 Apr 2022 11:27:15 +0900 Subject: [PATCH 0764/1246] docs: remove unneeded & in sample code --- user_guide_src/source/models/model/055.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/user_guide_src/source/models/model/055.php b/user_guide_src/source/models/model/055.php index 1d62c54ba058..537199753d49 100644 --- a/user_guide_src/source/models/model/055.php +++ b/user_guide_src/source/models/model/055.php @@ -8,8 +8,8 @@ class UserModel { protected $db; - public function __construct(ConnectionInterface &$db) + public function __construct(ConnectionInterface $db) { - $this->db = &$db; + $this->db = $db; } } From d84440415a86cfd5deb32a88d74bbf4236ef9e75 Mon Sep 17 00:00:00 2001 From: Toto Date: Fri, 1 Apr 2022 21:26:11 +0700 Subject: [PATCH 0765/1246] update link https://codeigniter.com/en/contribute not found --- app/Views/welcome_message.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Views/welcome_message.php b/app/Views/welcome_message.php index 9ee2e427c308..b982f58aa158 100644 --- a/app/Views/welcome_message.php +++ b/app/Views/welcome_message.php @@ -279,7 +279,7 @@

    CodeIgniter is a community driven project and accepts contributions of code and documentation from the community. Why not - + join us ?

    From 88a7f8b88a9bbd29daaea1f94deeb95a618ccd76 Mon Sep 17 00:00:00 2001 From: Lonnie Ezell Date: Fri, 1 Apr 2022 12:28:28 -0500 Subject: [PATCH 0766/1246] Added contributors to readme --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a8a3566e395d..d8525f299037 100644 --- a/README.md +++ b/README.md @@ -69,10 +69,19 @@ to optional packages, with their own repository. ## Contributing -We **are** accepting contributions from the community! +We **are** accepting contributions from the community! It doesn't matter whether you can code, write documentation, or help find bugs, +all contributions are welcome. Please read the [*Contributing to CodeIgniter*](https://github.com/codeigniter4/CodeIgniter4/blob/develop/contributing/README.md). +CodeIgniter has had thousands on contributions from people since its creation. This project would not be what it is without them. + + + + + +Made with [contrib.rocks](https://contrib.rocks). + ## Server Requirements PHP version 7.4 or higher is required, with the following extensions installed: From 27a74023bb25aefd752beb8f473393e84ac4fbfd Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 2 Apr 2022 12:50:56 +0900 Subject: [PATCH 0767/1246] fix: FileLocator::listFiles() returns directories We don't need directories. --- system/Autoloader/FileLocator.php | 3 +++ tests/system/Autoloader/FileLocatorTest.php | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/system/Autoloader/FileLocator.php b/system/Autoloader/FileLocator.php index f9734828b692..0b7b5d1d4345 100644 --- a/system/Autoloader/FileLocator.php +++ b/system/Autoloader/FileLocator.php @@ -309,6 +309,9 @@ public function listFiles(string $path): array $tempFiles = get_filenames($fullPath, true); + // Remove directories + $tempFiles = array_filter($tempFiles, static fn ($path) => strtolower(substr($path, -4)) === '.php'); + if (! empty($tempFiles)) { $files = array_merge($files, $tempFiles); } diff --git a/tests/system/Autoloader/FileLocatorTest.php b/tests/system/Autoloader/FileLocatorTest.php index 54a471d74453..3b86cfb7e535 100644 --- a/tests/system/Autoloader/FileLocatorTest.php +++ b/tests/system/Autoloader/FileLocatorTest.php @@ -211,6 +211,18 @@ public function testListFilesSimple() $this->assertTrue(in_array($expectedWin, $files, true) || in_array($expectedLin, $files, true)); } + public function testListFilesDoesNotContainDirectories() + { + $files = $this->locator->listFiles('Config/'); + + $directory = str_replace( + '/', + DIRECTORY_SEPARATOR, + APPPATH . 'Config/Boot' + ); + $this->assertNotContains($directory, $files); + } + public function testListFilesWithFileAsInput() { $files = $this->locator->listFiles('Config/App.php'); From 37e99bf13f1db654c546c2187d30dc9ec3c8b6f1 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 2 Apr 2022 12:53:10 +0900 Subject: [PATCH 0768/1246] docs: add @return --- system/Autoloader/FileLocator.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/system/Autoloader/FileLocator.php b/system/Autoloader/FileLocator.php index 0b7b5d1d4345..cfe12b79c2fa 100644 --- a/system/Autoloader/FileLocator.php +++ b/system/Autoloader/FileLocator.php @@ -289,6 +289,8 @@ public function findQualifiedNameFromPath(string $path) /** * Scans the defined namespaces, returning a list of all files * that are contained within the subpath specified by $path. + * + * @return string[] List of file paths */ public function listFiles(string $path): array { @@ -323,6 +325,8 @@ public function listFiles(string $path): array /** * Scans the provided namespace, returning a list of all files * that are contained within the sub path specified by $path. + * + * @return string[] List of file paths */ public function listNamespaceFiles(string $prefix, string $path): array { From 7aba08ab2f93a2e42a452a6fd995ad9b5c308318 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 2 Apr 2022 12:53:51 +0900 Subject: [PATCH 0769/1246] fix: discoverCommands() loads incorrect classname --- system/CLI/Commands.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/system/CLI/Commands.php b/system/CLI/Commands.php index d153b3aa857a..2714db30bcf9 100644 --- a/system/CLI/Commands.php +++ b/system/CLI/Commands.php @@ -76,10 +76,6 @@ public function getCommands() /** * Discovers all commands in the framework and within user code, * and collects instances of them to work with. - * - * @TODO this approach (find qualified classname from path) causes error, - * when using Composer autoloader. - * See https://github.com/codeigniter4/CodeIgniter4/issues/5818 */ public function discoverCommands() { @@ -100,9 +96,9 @@ public function discoverCommands() // Loop over each file checking to see if a command with that // alias exists in the class. foreach ($files as $file) { - $className = $locator->findQualifiedNameFromPath($file); + $className = $locator->getClassname($file); - if (empty($className) || ! class_exists($className)) { + if ($className === '' || ! class_exists($className)) { continue; } From 4c1dc38a75847a52e9efe2dab952cdcdbbc46ed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tuna=20=C3=87a=C4=9Flar=20G=C3=BCm=C3=BC=C5=9F?= Date: Sat, 2 Apr 2022 13:58:12 +0300 Subject: [PATCH 0770/1246] wrong function name. Needs to be orWhere(). There is no or_where in CI 4. --- user_guide_src/source/database/query_builder.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/database/query_builder.rst b/user_guide_src/source/database/query_builder.rst index d6e5b27aac36..5e05f0ce6b0b 100755 --- a/user_guide_src/source/database/query_builder.rst +++ b/user_guide_src/source/database/query_builder.rst @@ -804,7 +804,7 @@ Generates a **DELETE** SQL string and runs the query. .. literalinclude:: query_builder/093.php The first parameter is the where clause. -You can also use the ``where()`` or ``or_where()`` methods instead of passing +You can also use the ``where()`` or ``orWhere()`` methods instead of passing the data to the first parameter of the method: .. literalinclude:: query_builder/094.php From de7c19c456bf944e61c9e32835097727cd5d79ef Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 2 Apr 2022 14:02:14 +0900 Subject: [PATCH 0771/1246] test: fix assertions If we use Compoesr autoloader, the path would be like `/vendor/composer/../../app/Controllers/Home.php`. --- tests/system/Autoloader/AutoloaderTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/system/Autoloader/AutoloaderTest.php b/tests/system/Autoloader/AutoloaderTest.php index f9a56cae82db..82e0307affad 100644 --- a/tests/system/Autoloader/AutoloaderTest.php +++ b/tests/system/Autoloader/AutoloaderTest.php @@ -88,7 +88,7 @@ public function testServiceAutoLoaderFromShareInstances() // look for Home controller, as that should be in base repo $actual = $autoloader->loadClass('App\Controllers\Home'); $expected = APPPATH . 'Controllers' . DIRECTORY_SEPARATOR . 'Home.php'; - $this->assertSame($expected, $actual); + $this->assertSame($expected, realpath($actual) ?: $actual); } public function testServiceAutoLoader() @@ -99,7 +99,7 @@ public function testServiceAutoLoader() // look for Home controller, as that should be in base repo $actual = $autoloader->loadClass('App\Controllers\Home'); $expected = APPPATH . 'Controllers' . DIRECTORY_SEPARATOR . 'Home.php'; - $this->assertSame($expected, $actual); + $this->assertSame($expected, realpath($actual) ?: $actual); } public function testExistingFile() From 46b3de8aef4d74600235693a09a9052c476df731 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 2 Apr 2022 14:07:33 +0900 Subject: [PATCH 0772/1246] refactor: extract method --- system/Autoloader/Autoloader.php | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/system/Autoloader/Autoloader.php b/system/Autoloader/Autoloader.php index bfd535f856ca..7423fc235586 100644 --- a/system/Autoloader/Autoloader.php +++ b/system/Autoloader/Autoloader.php @@ -106,7 +106,8 @@ public function initialize(Autoload $config, Modules $modules) // Should we load through Composer's namespaces, also? if ($modules->discoverInComposer) { - $this->discoverComposerNamespaces(); + $this->loadComposerClassmap(); + $this->loadComposerNamespaces(); } return $this; @@ -296,10 +297,7 @@ public function sanitizeFilename(string $filename): string return trim($filename, '.-_'); } - /** - * Locates autoload information from Composer, if available. - */ - protected function discoverComposerNamespaces() + protected function loadComposerNamespaces() { if (! is_file(COMPOSER_PATH)) { return; @@ -310,7 +308,6 @@ protected function discoverComposerNamespaces() */ $composer = include COMPOSER_PATH; $paths = $composer->getPrefixesPsr4(); - $classes = $composer->getClassMap(); unset($composer); @@ -327,6 +324,23 @@ protected function discoverComposerNamespaces() } $this->prefixes = array_merge($this->prefixes, $newPaths); + } + + protected function loadComposerClassmap(): void + { + if (! is_file(COMPOSER_PATH)) { + return; + } + + /** + * @var ClassLoader $composer + */ + $composer = include COMPOSER_PATH; + + $classes = $composer->getClassMap(); + + unset($composer); + $this->classmap = array_merge($this->classmap, $classes); } } From ceb9418bd5ea051fd0a71fb916cb90a399bb0bda Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 2 Apr 2022 14:17:41 +0900 Subject: [PATCH 0773/1246] refactor: move duplicated logic up --- system/Autoloader/Autoloader.php | 44 ++++++++++++-------------------- 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/system/Autoloader/Autoloader.php b/system/Autoloader/Autoloader.php index 7423fc235586..88f3dd743470 100644 --- a/system/Autoloader/Autoloader.php +++ b/system/Autoloader/Autoloader.php @@ -104,10 +104,19 @@ public function initialize(Autoload $config, Modules $modules) $this->files = $config->files; } - // Should we load through Composer's namespaces, also? - if ($modules->discoverInComposer) { - $this->loadComposerClassmap(); - $this->loadComposerNamespaces(); + if (is_file(COMPOSER_PATH)) { + /** + * @var ClassLoader $composer + */ + $composer = include COMPOSER_PATH; + + // Should we load through Composer's namespaces, also? + if ($modules->discoverInComposer) { + $this->loadComposerClassmap($composer); + $this->loadComposerNamespaces($composer); + } + + unset($composer); } return $this; @@ -297,19 +306,9 @@ public function sanitizeFilename(string $filename): string return trim($filename, '.-_'); } - protected function loadComposerNamespaces() + protected function loadComposerNamespaces(ClassLoader $composer): void { - if (! is_file(COMPOSER_PATH)) { - return; - } - - /** - * @var ClassLoader $composer - */ - $composer = include COMPOSER_PATH; - $paths = $composer->getPrefixesPsr4(); - - unset($composer); + $paths = $composer->getPrefixesPsr4(); // Get rid of CodeIgniter so we don't have duplicates if (isset($paths['CodeIgniter\\'])) { @@ -326,21 +325,10 @@ protected function loadComposerNamespaces() $this->prefixes = array_merge($this->prefixes, $newPaths); } - protected function loadComposerClassmap(): void + protected function loadComposerClassmap(ClassLoader $composer): void { - if (! is_file(COMPOSER_PATH)) { - return; - } - - /** - * @var ClassLoader $composer - */ - $composer = include COMPOSER_PATH; - $classes = $composer->getClassMap(); - unset($composer); - $this->classmap = array_merge($this->classmap, $classes); } } From 954b647ddd7ac3df8f455a44b4cbfa13f6f68194 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 2 Apr 2022 14:18:22 +0900 Subject: [PATCH 0774/1246] fix: don't load Composer classmap if $discoverInComposer is false Now it always loads and uses Composer classmap if it is available. --- system/Autoloader/Autoloader.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/system/Autoloader/Autoloader.php b/system/Autoloader/Autoloader.php index 88f3dd743470..f4c37b4d250e 100644 --- a/system/Autoloader/Autoloader.php +++ b/system/Autoloader/Autoloader.php @@ -110,9 +110,10 @@ public function initialize(Autoload $config, Modules $modules) */ $composer = include COMPOSER_PATH; + $this->loadComposerClassmap($composer); + // Should we load through Composer's namespaces, also? if ($modules->discoverInComposer) { - $this->loadComposerClassmap($composer); $this->loadComposerNamespaces($composer); } From 783835efddd6c383de74c42402380c95903f88f5 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 2 Apr 2022 14:20:09 +0900 Subject: [PATCH 0775/1246] refactor: extract method --- system/Autoloader/Autoloader.php | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/system/Autoloader/Autoloader.php b/system/Autoloader/Autoloader.php index f4c37b4d250e..cca4a7d28f1e 100644 --- a/system/Autoloader/Autoloader.php +++ b/system/Autoloader/Autoloader.php @@ -105,22 +105,27 @@ public function initialize(Autoload $config, Modules $modules) } if (is_file(COMPOSER_PATH)) { - /** - * @var ClassLoader $composer - */ - $composer = include COMPOSER_PATH; + $this->loadComposerInfo($modules); + } - $this->loadComposerClassmap($composer); + return $this; + } - // Should we load through Composer's namespaces, also? - if ($modules->discoverInComposer) { - $this->loadComposerNamespaces($composer); - } + protected function loadComposerInfo(Modules $modules): void + { + /** + * @var ClassLoader $composer + */ + $composer = include COMPOSER_PATH; + + $this->loadComposerClassmap($composer); - unset($composer); + // Should we load through Composer's namespaces, also? + if ($modules->discoverInComposer) { + $this->loadComposerNamespaces($composer); } - return $this; + unset($composer); } /** From c179ed044558faa93d7ad05869b1e4c9b22069ca Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 3 Apr 2022 08:01:39 +0900 Subject: [PATCH 0776/1246] refactor: restore discoverComposerNamespaces() and deprecate --- system/Autoloader/Autoloader.php | 36 ++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/system/Autoloader/Autoloader.php b/system/Autoloader/Autoloader.php index cca4a7d28f1e..7152f160c652 100644 --- a/system/Autoloader/Autoloader.php +++ b/system/Autoloader/Autoloader.php @@ -337,4 +337,40 @@ protected function loadComposerClassmap(ClassLoader $composer): void $this->classmap = array_merge($this->classmap, $classes); } + + /** + * Locates autoload information from Composer, if available. + * + * @deprecated No longer used. + */ + protected function discoverComposerNamespaces() + { + if (! is_file(COMPOSER_PATH)) { + return; + } + + /** + * @var ClassLoader $composer + */ + $composer = include COMPOSER_PATH; + $paths = $composer->getPrefixesPsr4(); + $classes = $composer->getClassMap(); + + unset($composer); + + // Get rid of CodeIgniter so we don't have duplicates + if (isset($paths['CodeIgniter\\'])) { + unset($paths['CodeIgniter\\']); + } + + $newPaths = []; + + foreach ($paths as $key => $value) { + // Composer stores namespaces with trailing slash. We don't. + $newPaths[rtrim($key, '\\ ')] = $value; + } + + $this->prefixes = array_merge($this->prefixes, $newPaths); + $this->classmap = array_merge($this->classmap, $classes); + } } From 577eefe25c4061e0a286b51969fc96ad177282b3 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 3 Apr 2022 08:03:15 +0900 Subject: [PATCH 0777/1246] refactor: make new methods private --- system/Autoloader/Autoloader.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/system/Autoloader/Autoloader.php b/system/Autoloader/Autoloader.php index 7152f160c652..520e669be685 100644 --- a/system/Autoloader/Autoloader.php +++ b/system/Autoloader/Autoloader.php @@ -111,7 +111,7 @@ public function initialize(Autoload $config, Modules $modules) return $this; } - protected function loadComposerInfo(Modules $modules): void + private function loadComposerInfo(Modules $modules): void { /** * @var ClassLoader $composer @@ -312,7 +312,7 @@ public function sanitizeFilename(string $filename): string return trim($filename, '.-_'); } - protected function loadComposerNamespaces(ClassLoader $composer): void + private function loadComposerNamespaces(ClassLoader $composer): void { $paths = $composer->getPrefixesPsr4(); @@ -331,7 +331,7 @@ protected function loadComposerNamespaces(ClassLoader $composer): void $this->prefixes = array_merge($this->prefixes, $newPaths); } - protected function loadComposerClassmap(ClassLoader $composer): void + private function loadComposerClassmap(ClassLoader $composer): void { $classes = $composer->getClassMap(); From c7e659fc367eefd76cb0680214880fb14eaa4585 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 3 Apr 2022 08:13:44 +0900 Subject: [PATCH 0778/1246] docs: add changelog --- user_guide_src/source/changelogs/v4.2.0.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/user_guide_src/source/changelogs/v4.2.0.rst b/user_guide_src/source/changelogs/v4.2.0.rst index 465054262b41..99f980d6b35e 100644 --- a/user_guide_src/source/changelogs/v4.2.0.rst +++ b/user_guide_src/source/changelogs/v4.2.0.rst @@ -17,6 +17,7 @@ BREAKING - ``public/index.php`` - ``spark`` - The method signature of ``CodeIgniter\CLI\CommandRunner::_remap()`` has been changed to fix a bug. +- The ``CodeIgniter\Autoloader\Autoloader::initialize()`` has changed the behavior to fix a bug. It used to use Composer classmap only when ``$modules->discoverInComposer`` is true. Now it always uses the Composer classmap if Composer is available. Enhancements ************ @@ -55,6 +56,7 @@ Deprecations - ``CodeIgniter\Log\Logger::cleanFilenames()`` and ``CodeIgniter\Test\TestLogger::cleanup()`` are both deprecated. Use the ``clean_path()`` function instead. - ``CodeIgniter\Router\Router::setDefaultController()`` is deprecated. - The constant ``SPARKED`` in **spark** is deprecated. Use the ``$context`` property in ``CodeIgniter\CodeIgniter`` instead. +- ``CodeIgniter\Autoloader\Autoloader::discoverComposerNamespaces()`` is deprecated, and no longer used. Bugs Fixed ********** From c03df2ea180af20c82ad94a8a96e55b2bab35b15 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 3 Apr 2022 09:10:11 +0900 Subject: [PATCH 0779/1246] docs: add missing `+` --- user_guide_src/source/outgoing/view_parser.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/outgoing/view_parser.rst b/user_guide_src/source/outgoing/view_parser.rst index 752dcc489590..b431b9979602 100644 --- a/user_guide_src/source/outgoing/view_parser.rst +++ b/user_guide_src/source/outgoing/view_parser.rst @@ -458,7 +458,7 @@ While plugins will often consist of tag pairs, like shown above, they can also b Opening tags can also contain parameters that can customize how the plugin works. The parameters are represented as key/value pairs:: - {+ foo bar=2 baz="x y" } + {+ foo bar=2 baz="x y" +} Parameters can also be single values:: From 53fb7ac06fd959077323bec40d9c4d596d21d853 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 3 Apr 2022 09:10:40 +0900 Subject: [PATCH 0780/1246] docs: remove unnecessary line breaks in sample code --- user_guide_src/source/installation/upgrade_view_parser/001.php | 3 +-- user_guide_src/source/outgoing/view_parser.rst | 3 +-- user_guide_src/source/outgoing/view_parser/003.php | 3 +-- user_guide_src/source/outgoing/view_parser/006.php | 3 +-- user_guide_src/source/outgoing/view_parser/007.php | 3 +-- user_guide_src/source/outgoing/view_parser/008.php | 3 +-- user_guide_src/source/outgoing/view_parser/018.php | 3 +-- user_guide_src/source/outgoing/view_parser/019.php | 3 +-- user_guide_src/source/outgoing/view_parser/020.php | 3 +-- user_guide_src/source/outgoing/view_parser/021.php | 3 +-- 10 files changed, 10 insertions(+), 20 deletions(-) diff --git a/user_guide_src/source/installation/upgrade_view_parser/001.php b/user_guide_src/source/installation/upgrade_view_parser/001.php index 6bef47ef69ec..27dc410b1708 100644 --- a/user_guide_src/source/installation/upgrade_view_parser/001.php +++ b/user_guide_src/source/installation/upgrade_view_parser/001.php @@ -7,5 +7,4 @@ 'blog_heading' => 'My Blog Heading', ]; -echo $parser->setData($data) - ->render('blog_template'); +echo $parser->setData($data)->render('blog_template'); diff --git a/user_guide_src/source/outgoing/view_parser.rst b/user_guide_src/source/outgoing/view_parser.rst index b431b9979602..6c6c2601b451 100644 --- a/user_guide_src/source/outgoing/view_parser.rst +++ b/user_guide_src/source/outgoing/view_parser.rst @@ -550,8 +550,7 @@ An example with the iteration controlled in the view:: ['title' => 'Second Link', 'link' => '/second'], ] ]; - echo $parser->setData($data) - ->renderString($template); + echo $parser->setData($data)->renderString($template); Result:: diff --git a/user_guide_src/source/outgoing/view_parser/003.php b/user_guide_src/source/outgoing/view_parser/003.php index 1ee48b997ae6..da4ef088f6bd 100644 --- a/user_guide_src/source/outgoing/view_parser/003.php +++ b/user_guide_src/source/outgoing/view_parser/003.php @@ -5,5 +5,4 @@ 'blog_heading' => 'My Blog Heading', ]; -echo $parser->setData($data) - ->render('blog_template'); +echo $parser->setData($data)->render('blog_template'); diff --git a/user_guide_src/source/outgoing/view_parser/006.php b/user_guide_src/source/outgoing/view_parser/006.php index 6b1409c46c1d..dfde61eec728 100644 --- a/user_guide_src/source/outgoing/view_parser/006.php +++ b/user_guide_src/source/outgoing/view_parser/006.php @@ -12,5 +12,4 @@ ], ]; -echo $parser->setData($data) - ->render('blog_template'); +echo $parser->setData($data)->render('blog_template'); diff --git a/user_guide_src/source/outgoing/view_parser/007.php b/user_guide_src/source/outgoing/view_parser/007.php index 032f9d55f268..b3ca937f711f 100644 --- a/user_guide_src/source/outgoing/view_parser/007.php +++ b/user_guide_src/source/outgoing/view_parser/007.php @@ -8,5 +8,4 @@ 'blog_entries' => $query->getResultArray(), ]; -echo $parser->setData($data) - ->render('blog_template'); +echo $parser->setData($data)->render('blog_template'); diff --git a/user_guide_src/source/outgoing/view_parser/008.php b/user_guide_src/source/outgoing/view_parser/008.php index 62be126a407d..4b0a6215830e 100644 --- a/user_guide_src/source/outgoing/view_parser/008.php +++ b/user_guide_src/source/outgoing/view_parser/008.php @@ -9,5 +9,4 @@ ], ]; -echo $parser->setData($data) - ->render('blog_template'); +echo $parser->setData($data)->render('blog_template'); diff --git a/user_guide_src/source/outgoing/view_parser/018.php b/user_guide_src/source/outgoing/view_parser/018.php index 4e039f02a08c..0bb60828d691 100644 --- a/user_guide_src/source/outgoing/view_parser/018.php +++ b/user_guide_src/source/outgoing/view_parser/018.php @@ -6,6 +6,5 @@ 'firstname' => 'John', 'lastname' => 'Doe', ]; -echo $parser->setData($data) - ->renderString($template); +echo $parser->setData($data)->renderString($template); // Result: Hello, John Doe diff --git a/user_guide_src/source/outgoing/view_parser/019.php b/user_guide_src/source/outgoing/view_parser/019.php index 16621ef2f190..a3cb80300299 100644 --- a/user_guide_src/source/outgoing/view_parser/019.php +++ b/user_guide_src/source/outgoing/view_parser/019.php @@ -6,6 +6,5 @@ 'firstname' => 'John', 'lastname' => 'Doe', ]; -echo $parser->setData($data) - ->renderString($template); +echo $parser->setData($data)->renderString($template); // Result: Hello, John {initials} Doe diff --git a/user_guide_src/source/outgoing/view_parser/020.php b/user_guide_src/source/outgoing/view_parser/020.php index 9226793f280d..62256192019d 100644 --- a/user_guide_src/source/outgoing/view_parser/020.php +++ b/user_guide_src/source/outgoing/view_parser/020.php @@ -10,6 +10,5 @@ ['degree' => 'PhD'], ], ]; -echo $parser->setData($data) - ->renderString($template); +echo $parser->setData($data)->renderString($template); // Result: Hello, John Doe (Mr{degree} {/degrees}) diff --git a/user_guide_src/source/outgoing/view_parser/021.php b/user_guide_src/source/outgoing/view_parser/021.php index 3c9982437a19..977b8b958140 100644 --- a/user_guide_src/source/outgoing/view_parser/021.php +++ b/user_guide_src/source/outgoing/view_parser/021.php @@ -15,5 +15,4 @@ $data = [ 'menuitems' => $temp, ]; -echo $parser->setData($data) - ->renderString($template2); +echo $parser->setData($data)->renderString($template2); From 71a7682d1eba5bad20109362e292479cf952f5b4 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 3 Apr 2022 09:13:15 +0900 Subject: [PATCH 0781/1246] docs: fix text decoration for variable --- user_guide_src/source/outgoing/view_parser.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/outgoing/view_parser.rst b/user_guide_src/source/outgoing/view_parser.rst index 6c6c2601b451..e3908ec0a391 100644 --- a/user_guide_src/source/outgoing/view_parser.rst +++ b/user_guide_src/source/outgoing/view_parser.rst @@ -491,7 +491,7 @@ Registering a Plugin -------------------- At its simplest, all you need to do to register a new plugin and make it ready for use is to add it to the -**app/Config/View.php**, under the **$plugins** array. The key is the name of the plugin that is +**app/Config/View.php**, under the ``$plugins`` array. The key is the name of the plugin that is used within the template file. The value is any valid PHP callable, including static class methods: .. literalinclude:: view_parser/014.php From 931c6f43a7724446b9fcf8dbd13b782e0dd352c6 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 3 Apr 2022 09:20:31 +0900 Subject: [PATCH 0782/1246] docs: remove unsupported options `leftDelimiter` and `rightDelimiter` --- user_guide_src/source/outgoing/view_parser.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/user_guide_src/source/outgoing/view_parser.rst b/user_guide_src/source/outgoing/view_parser.rst index e3908ec0a391..67ee0b7680eb 100644 --- a/user_guide_src/source/outgoing/view_parser.rst +++ b/user_guide_src/source/outgoing/view_parser.rst @@ -595,8 +595,6 @@ Class Reference - ``cache_name`` - the ID used to save/retrieve a cached view result; defaults to the viewpath - ``cascadeData`` - true if the data pairs in effect when a nested or loop substitution occurs should be propagated - ``saveData`` - true if the view data parameter should be retained for subsequent calls - - ``leftDelimiter`` - the left delimiter to use in pseudo-variable syntax - - ``rightDelimiter`` - the right delimiter to use in pseudo-variable syntax Any conditional substitutions are performed first, then remaining substitutions are performed for each data pair. From 20194690313be9d7e7f60165808376baf49a12f9 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 3 Apr 2022 09:24:59 +0900 Subject: [PATCH 0783/1246] docs: rename variable name in sample code Make the same name as other sample code. --- user_guide_src/source/outgoing/view_parser/024.php | 2 +- user_guide_src/source/outgoing/view_parser/025.php | 2 +- user_guide_src/source/outgoing/view_parser/026.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/user_guide_src/source/outgoing/view_parser/024.php b/user_guide_src/source/outgoing/view_parser/024.php index 42ddfa949331..17a0a477e756 100644 --- a/user_guide_src/source/outgoing/view_parser/024.php +++ b/user_guide_src/source/outgoing/view_parser/024.php @@ -1,3 +1,3 @@ setData(['name' => 'George', 'position' => 'Boss']); +$parser->setData(['name' => 'George', 'position' => 'Boss']); diff --git a/user_guide_src/source/outgoing/view_parser/025.php b/user_guide_src/source/outgoing/view_parser/025.php index 8fa85f4faa98..fe67fe17aeb4 100644 --- a/user_guide_src/source/outgoing/view_parser/025.php +++ b/user_guide_src/source/outgoing/view_parser/025.php @@ -1,3 +1,3 @@ setVar('name', 'Joe', 'html'); +$parser->setVar('name', 'Joe', 'html'); diff --git a/user_guide_src/source/outgoing/view_parser/026.php b/user_guide_src/source/outgoing/view_parser/026.php index 46cfd9afd818..a7efd14837f2 100644 --- a/user_guide_src/source/outgoing/view_parser/026.php +++ b/user_guide_src/source/outgoing/view_parser/026.php @@ -1,3 +1,3 @@ setDelimiters('[', ']'); +$parser->setDelimiters('[', ']'); From 08d4dbecccf14847f098804edfa2987120668efe Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 3 Apr 2022 09:29:10 +0900 Subject: [PATCH 0784/1246] docs: add setConditionalDelimiters() in Class Reference --- user_guide_src/source/outgoing/view_parser.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/user_guide_src/source/outgoing/view_parser.rst b/user_guide_src/source/outgoing/view_parser.rst index 67ee0b7680eb..c369e7a5a78b 100644 --- a/user_guide_src/source/outgoing/view_parser.rst +++ b/user_guide_src/source/outgoing/view_parser.rst @@ -652,3 +652,14 @@ Class Reference Override the substitution field delimiters: .. literalinclude:: view_parser/026.php + + .. php:method:: setConditionalDelimiters($leftDelimiter = '{', $rightDelimiter = '}') + + :param string $leftDelimiter: Left delimiter for conditionals + :param string $rightDelimiter: right delimiter for conditionals + :returns: The Renderer, for method chaining + :rtype: CodeIgniter\\View\\RendererInterface. + + Override the conditional delimiters: + + .. literalinclude:: view_parser/027.php From bbea1665c368b235086a7b3cbbc5f462431e26f3 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 3 Apr 2022 09:32:27 +0900 Subject: [PATCH 0785/1246] docs: remove parameters of methods in text No parameters make them easier to read. --- user_guide_src/source/outgoing/view_parser.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/user_guide_src/source/outgoing/view_parser.rst b/user_guide_src/source/outgoing/view_parser.rst index c369e7a5a78b..f4239b320207 100644 --- a/user_guide_src/source/outgoing/view_parser.rst +++ b/user_guide_src/source/outgoing/view_parser.rst @@ -53,9 +53,9 @@ can instantiate it directly: .. literalinclude:: view_parser/002.php Then you can use any of the three standard rendering methods that it provides: -``render(viewpath, options, save)``, ``setVar(name, value, context)`` and -``setData(data, context)``. You will also be able to specify delimiters directly, -through the ``setDelimiters(left, right)`` method. +``render()``, ``setVar()`` and +``setData()``. You will also be able to specify delimiters directly, +through the ``setDelimiters()`` method. Using the ``Parser``, your view templates are processed only by the Parser itself, and not like a conventional view PHP script. PHP code in such a script From faf39c2003bbb17c04957facf03d9300b0969424 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 3 Apr 2022 09:36:29 +0900 Subject: [PATCH 0786/1246] docs: make text as a important note --- user_guide_src/source/outgoing/view_parser.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/user_guide_src/source/outgoing/view_parser.rst b/user_guide_src/source/outgoing/view_parser.rst index f4239b320207..b72388486eb6 100644 --- a/user_guide_src/source/outgoing/view_parser.rst +++ b/user_guide_src/source/outgoing/view_parser.rst @@ -57,11 +57,11 @@ Then you can use any of the three standard rendering methods that it provides: ``setData()``. You will also be able to specify delimiters directly, through the ``setDelimiters()`` method. -Using the ``Parser``, your view templates are processed only by the Parser -itself, and not like a conventional view PHP script. PHP code in such a script -is ignored by the parser, and only substitutions are performed. +.. important:: Using the ``Parser``, your view templates are processed only by the Parser + itself, and not like a conventional view PHP script. PHP code in such a script + is ignored by the parser, and only substitutions are performed. -This is purposeful: view files with no PHP. + This is purposeful: view files with no PHP. What It Does ============ From d368c511299d7ca063e9cfa70f56761924129b7c Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 3 Apr 2022 09:44:45 +0900 Subject: [PATCH 0787/1246] docs: fix text decoration for filter --- user_guide_src/source/outgoing/view_parser.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/outgoing/view_parser.rst b/user_guide_src/source/outgoing/view_parser.rst index b72388486eb6..50b4b4376707 100644 --- a/user_guide_src/source/outgoing/view_parser.rst +++ b/user_guide_src/source/outgoing/view_parser.rst @@ -336,7 +336,7 @@ Filters Any single variable substitution can have one or more filters applied to it to modify the way it is presented. These are not intended to drastically change the output, but provide ways to reuse the same variable data but with different -presentations. The **esc** filter discussed above is one example. Dates are another common use case, where you might +presentations. The ``esc`` filter discussed above is one example. Dates are another common use case, where you might need to format the same data differently in several sections on the same page. Filters are commands that come after the pseudo-variable name, and are separated by the pipe symbol, ``|``:: From b5423cc15a7f8471cc14d32ea7da22bc3ca821d9 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 3 Apr 2022 09:45:05 +0900 Subject: [PATCH 0788/1246] docs: add space between tags --- user_guide_src/source/outgoing/view_parser.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/outgoing/view_parser.rst b/user_guide_src/source/outgoing/view_parser.rst index 50b4b4376707..961d8ea96c31 100644 --- a/user_guide_src/source/outgoing/view_parser.rst +++ b/user_guide_src/source/outgoing/view_parser.rst @@ -250,7 +250,7 @@ This example gives different results, depending on cascading: Preventing Parsing ================== -You can specify portions of the page to not be parsed with the ``{noparse}{/noparse}`` tag pair. Anything in this +You can specify portions of the page to not be parsed with the ``{noparse}`` ``{/noparse}`` tag pair. Anything in this section will stay exactly as it is, with no variable substitution, looping, etc, happening to the markup between the brackets. :: From cf4d83d1e5d7e144a44d49e19892ac819d908c6c Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 3 Apr 2022 10:25:57 +0900 Subject: [PATCH 0789/1246] docs: add links to reference --- user_guide_src/source/tutorial/conclusion.rst | 5 +++-- user_guide_src/source/tutorial/news_section.rst | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/user_guide_src/source/tutorial/conclusion.rst b/user_guide_src/source/tutorial/conclusion.rst index afb38465904b..2a4f66264784 100644 --- a/user_guide_src/source/tutorial/conclusion.rst +++ b/user_guide_src/source/tutorial/conclusion.rst @@ -10,8 +10,9 @@ design patterns, which you can expand upon. Now that you've completed this tutorial, we recommend you check out the rest of the documentation. CodeIgniter is often praised because of its comprehensive documentation. Use this to your advantage and read the -"Overview" and "General Topics" sections thoroughly. You should read -the class and helper references when needed. +:doc:`Overview ` and :doc:`/general/index` +sections thoroughly. You should read +the :doc:`Library ` and :doc:`/helpers/index` references when needed. Every intermediate PHP programmer should be able to get the hang of CodeIgniter within a few days. diff --git a/user_guide_src/source/tutorial/news_section.rst b/user_guide_src/source/tutorial/news_section.rst index a27902819265..aca19a25cad3 100644 --- a/user_guide_src/source/tutorial/news_section.rst +++ b/user_guide_src/source/tutorial/news_section.rst @@ -80,7 +80,7 @@ library. This will make the database class available through the Now that the database and a model have been set up, you'll need a method to get all of our posts from our database. To do this, the database abstraction layer that is included with CodeIgniter - -:doc:`Query Builder <../database/query_builder>` - is used. This makes it +:doc:`Query Builder <../database/query_builder>` - is used in the ``CodeIgnite\Model``. This makes it possible to write your 'queries' once and make them work on :doc:`all supported database systems <../intro/requirements>`. The Model class also allows you to easily work with the Query Builder and provides From 3f480d453479b17a6d75cc0abadf3ded39c65e34 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 3 Apr 2022 10:26:28 +0900 Subject: [PATCH 0790/1246] docs: update forum url and add slack url --- user_guide_src/source/tutorial/conclusion.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/user_guide_src/source/tutorial/conclusion.rst b/user_guide_src/source/tutorial/conclusion.rst index 2a4f66264784..94b8ba5e3f2d 100644 --- a/user_guide_src/source/tutorial/conclusion.rst +++ b/user_guide_src/source/tutorial/conclusion.rst @@ -20,4 +20,5 @@ CodeIgniter within a few days. If you still have questions about the framework or your own CodeIgniter code, you can: -- Check out our `forums `_ +- Check out our `Forum `_ +- Check out our `Slack `_ From f58bac1954d5c189bf635309eb2a1ec6e8d5ed84 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 3 Apr 2022 10:26:58 +0900 Subject: [PATCH 0791/1246] docs: remove unneeded `` --- user_guide_src/source/tutorial/create_news_items.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/tutorial/create_news_items.rst b/user_guide_src/source/tutorial/create_news_items.rst index 49ebc36c2bc3..a59124515a59 100644 --- a/user_guide_src/source/tutorial/create_news_items.rst +++ b/user_guide_src/source/tutorial/create_news_items.rst @@ -50,7 +50,7 @@ the slug from our title in the model. Create a new view at There are probably only three things here that look unfamiliar. -The ``getFlashdata('error') ?>`` function is used to report +The ``session()->getFlashdata('error')`` function is used to report errors related to CSRF protection. The ``service('validation')->listErrors()`` function is used to report From 54d80bcd0727c9f10c5f7ebf2f98548131732402 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 3 Apr 2022 10:27:26 +0900 Subject: [PATCH 0792/1246] docs: fix link to validation page --- user_guide_src/source/incoming/controllers.rst | 2 ++ user_guide_src/source/tutorial/create_news_items.rst | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/user_guide_src/source/incoming/controllers.rst b/user_guide_src/source/incoming/controllers.rst index 99c22b5a356d..c5a963c81fdd 100644 --- a/user_guide_src/source/incoming/controllers.rst +++ b/user_guide_src/source/incoming/controllers.rst @@ -61,6 +61,8 @@ modify this by passing the duration (in seconds) as the first parameter: .. note:: A number of :doc:`time-based constants ` are always available for you to use, including ``YEAR``, ``MONTH``, and more. +.. _controller-validate: + Validating data *************** diff --git a/user_guide_src/source/tutorial/create_news_items.rst b/user_guide_src/source/tutorial/create_news_items.rst index a59124515a59..99d28abf3cdb 100644 --- a/user_guide_src/source/tutorial/create_news_items.rst +++ b/user_guide_src/source/tutorial/create_news_items.rst @@ -60,8 +60,8 @@ The ``csrf_field()`` function creates a hidden input with a CSRF token that help Go back to your ``News`` controller. You're going to do two things here, check whether the form was submitted and whether the submitted data -passed the validation rules. You'll use the :doc:`form -validation <../libraries/validation>` library to do this. +passed the validation rules. +You'll use the :ref:`validation method in Controller ` to do this. .. literalinclude:: create_news_items/002.php From 149555ebd23d404ecf8684e52cb363365a7470ef Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 3 Apr 2022 13:47:18 +0900 Subject: [PATCH 0793/1246] docs: replace echo with return --- user_guide_src/source/tutorial/static_pages.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/tutorial/static_pages.rst b/user_guide_src/source/tutorial/static_pages.rst index 668683995231..6fde0a671da7 100644 --- a/user_guide_src/source/tutorial/static_pages.rst +++ b/user_guide_src/source/tutorial/static_pages.rst @@ -24,7 +24,7 @@ displays the CodeIgniter welcome page. .. note:: There are two ``view()`` functions referred to in this tutorial. One is the class method created with ``public function view($page = 'home')`` - and ``echo view('welcome_message')`` for displaying a view. + and ``return view('welcome_message')`` for displaying a view. Both are *technically* a function. But when you create a function in a class, it's called a method. From 977eb2561db4108b6ed3dfe97541de150e9b6429 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 4 Apr 2022 08:35:49 +0900 Subject: [PATCH 0794/1246] docs: remove unneeded $data for view() $saveData is true by default, so we don't need to pass $data more than once. --- user_guide_src/source/tutorial/news_section/004.php | 4 ++-- user_guide_src/source/tutorial/news_section/006.php | 4 ++-- user_guide_src/source/tutorial/static_pages/002.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/user_guide_src/source/tutorial/news_section/004.php b/user_guide_src/source/tutorial/news_section/004.php index b62562bfe351..9e823b6f7589 100644 --- a/user_guide_src/source/tutorial/news_section/004.php +++ b/user_guide_src/source/tutorial/news_section/004.php @@ -16,7 +16,7 @@ public function index() ]; return view('templates/header', $data) - . view('news/overview', $data) - . view('templates/footer', $data); + . view('news/overview') + . view('templates/footer'); } } diff --git a/user_guide_src/source/tutorial/news_section/006.php b/user_guide_src/source/tutorial/news_section/006.php index 8bfc123e43f7..94548ac9307f 100644 --- a/user_guide_src/source/tutorial/news_section/006.php +++ b/user_guide_src/source/tutorial/news_section/006.php @@ -19,7 +19,7 @@ public function view($slug = null) $data['title'] = $data['news']['title']; return view('templates/header', $data) - . view('news/view', $data) - . view('templates/footer', $data); + . view('news/view') + . view('templates/footer'); } } diff --git a/user_guide_src/source/tutorial/static_pages/002.php b/user_guide_src/source/tutorial/static_pages/002.php index 9f80c4556a58..5c8ec102a5a1 100644 --- a/user_guide_src/source/tutorial/static_pages/002.php +++ b/user_guide_src/source/tutorial/static_pages/002.php @@ -14,7 +14,7 @@ public function view($page = 'home') $data['title'] = ucfirst($page); // Capitalize the first letter return view('templates/header', $data) - . view('pages/' . $page, $data) - . view('templates/footer', $data); + . view('pages/' . $page) + . view('templates/footer'); } } From e0569f673f0c119b620f37981bf90dd19d8390a1 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 3 Apr 2022 14:19:58 +0900 Subject: [PATCH 0795/1246] docs: replace echo with return echo() has side effects, so return is better. --- user_guide_src/source/cli/cli/001.php | 2 +- user_guide_src/source/incoming/controllers/008.php | 2 +- user_guide_src/source/incoming/controllers/013.php | 4 ++-- user_guide_src/source/incoming/controllers/014.php | 4 ++-- .../source/installation/upgrade_controllers/001.php | 2 +- .../source/installation/upgrade_file_upload/001.php | 11 +++++------ .../source/installation/upgrade_pagination/001.php | 2 +- .../source/installation/upgrade_view_parser.rst | 2 +- .../source/installation/upgrade_view_parser/001.php | 2 +- user_guide_src/source/installation/upgrade_views.rst | 4 ++-- user_guide_src/source/libraries/pagination/002.php | 2 +- user_guide_src/source/libraries/validation/001.php | 6 +++--- user_guide_src/source/outgoing/view_layouts/001.php | 2 +- user_guide_src/source/outgoing/view_parser.rst | 3 ++- user_guide_src/source/outgoing/view_parser/003.php | 2 +- user_guide_src/source/outgoing/view_parser/004.php | 2 +- user_guide_src/source/outgoing/view_parser/005.php | 2 +- user_guide_src/source/outgoing/view_parser/006.php | 2 +- user_guide_src/source/outgoing/view_parser/007.php | 2 +- user_guide_src/source/outgoing/view_parser/008.php | 2 +- user_guide_src/source/outgoing/view_parser/009.php | 2 +- user_guide_src/source/outgoing/view_parser/010.php | 6 ++++-- user_guide_src/source/outgoing/view_parser/018.php | 3 ++- user_guide_src/source/outgoing/view_parser/019.php | 3 ++- user_guide_src/source/outgoing/view_parser/020.php | 3 ++- user_guide_src/source/outgoing/view_parser/021.php | 3 ++- user_guide_src/source/outgoing/view_parser/022.php | 2 +- user_guide_src/source/outgoing/view_parser/023.php | 2 +- user_guide_src/source/outgoing/views.rst | 3 --- user_guide_src/source/outgoing/views/001.php | 2 +- user_guide_src/source/outgoing/views/002.php | 2 +- user_guide_src/source/outgoing/views/003.php | 8 ++++---- user_guide_src/source/outgoing/views/004.php | 2 +- user_guide_src/source/outgoing/views/005.php | 2 +- user_guide_src/source/outgoing/views/006.php | 2 +- user_guide_src/source/outgoing/views/007.php | 2 +- user_guide_src/source/outgoing/views/008.php | 2 +- user_guide_src/source/outgoing/views/009.php | 2 +- user_guide_src/source/outgoing/views/010.php | 2 +- user_guide_src/source/outgoing/views/011.php | 2 +- 40 files changed, 59 insertions(+), 56 deletions(-) diff --git a/user_guide_src/source/cli/cli/001.php b/user_guide_src/source/cli/cli/001.php index b407ee50b145..999a5482e4d6 100644 --- a/user_guide_src/source/cli/cli/001.php +++ b/user_guide_src/source/cli/cli/001.php @@ -8,6 +8,6 @@ class Tools extends Controller { public function message($to = 'World') { - echo "Hello {$to}!" . PHP_EOL; + return "Hello {$to}!" . PHP_EOL; } } diff --git a/user_guide_src/source/incoming/controllers/008.php b/user_guide_src/source/incoming/controllers/008.php index 926de1e9fbdf..3aa859567c44 100644 --- a/user_guide_src/source/incoming/controllers/008.php +++ b/user_guide_src/source/incoming/controllers/008.php @@ -6,6 +6,6 @@ class Helloworld extends BaseController { public function index() { - echo 'Hello World!'; + return 'Hello World!'; } } diff --git a/user_guide_src/source/incoming/controllers/013.php b/user_guide_src/source/incoming/controllers/013.php index e43c3e4f2b34..68d4450d4e3a 100644 --- a/user_guide_src/source/incoming/controllers/013.php +++ b/user_guide_src/source/incoming/controllers/013.php @@ -6,11 +6,11 @@ class Helloworld extends BaseController { public function index() { - echo 'Hello World!'; + return 'Hello World!'; } public function comment() { - echo 'I am not flat!'; + return 'I am not flat!'; } } diff --git a/user_guide_src/source/incoming/controllers/014.php b/user_guide_src/source/incoming/controllers/014.php index 319fd8471a7b..da295eb61836 100644 --- a/user_guide_src/source/incoming/controllers/014.php +++ b/user_guide_src/source/incoming/controllers/014.php @@ -6,7 +6,7 @@ class Products extends BaseController { public function shoes($sandals, $id) { - echo $sandals; - echo $id; + return $sandals + . $id; } } diff --git a/user_guide_src/source/installation/upgrade_controllers/001.php b/user_guide_src/source/installation/upgrade_controllers/001.php index 5f292b54d1b8..b90fe63c538f 100644 --- a/user_guide_src/source/installation/upgrade_controllers/001.php +++ b/user_guide_src/source/installation/upgrade_controllers/001.php @@ -6,6 +6,6 @@ class Helloworld extends BaseController { public function index($name) { - echo 'Hello ' . esc($name) . '!'; + return 'Hello ' . esc($name) . '!'; } } diff --git a/user_guide_src/source/installation/upgrade_file_upload/001.php b/user_guide_src/source/installation/upgrade_file_upload/001.php index 6a4e6c88e250..a8b727c29745 100644 --- a/user_guide_src/source/installation/upgrade_file_upload/001.php +++ b/user_guide_src/source/installation/upgrade_file_upload/001.php @@ -6,7 +6,7 @@ class Upload extends BaseController { public function index() { - echo view('upload_form', ['error' => ' ']); + return view('upload_form', ['error' => ' ']); } public function do_upload() @@ -20,11 +20,10 @@ public function do_upload() $file = $this->request->getFile('userfile'); if (! $path = $file->store()) { - echo view('upload_form', ['error' => 'upload failed']); - } else { - $data = ['upload_file_path' => $path]; - - echo view('upload_success', $data); + return view('upload_form', ['error' => 'upload failed']); } + $data = ['upload_file_path' => $path]; + + return view('upload_success', $data); } } diff --git a/user_guide_src/source/installation/upgrade_pagination/001.php b/user_guide_src/source/installation/upgrade_pagination/001.php index fa1b373a5fc6..62710360fca9 100644 --- a/user_guide_src/source/installation/upgrade_pagination/001.php +++ b/user_guide_src/source/installation/upgrade_pagination/001.php @@ -7,4 +7,4 @@ 'pager' => $model->pager, ]; -echo view('users/index', $data); +return view('users/index', $data); diff --git a/user_guide_src/source/installation/upgrade_view_parser.rst b/user_guide_src/source/installation/upgrade_view_parser.rst index 55e86fb357a4..c58aeb8dd491 100644 --- a/user_guide_src/source/installation/upgrade_view_parser.rst +++ b/user_guide_src/source/installation/upgrade_view_parser.rst @@ -19,7 +19,7 @@ What has been changed Upgrade Guide ============= 1. Wherever you use the View Parser Library replace ``$this->load->library('parser');`` with ``$parser = service('parser');``. -2. You have to change the render part in your controller from ``$this->parser->parse('blog_template', $data);`` to ``echo $parser->setData($data)->render('blog_template');``. +2. You have to change the render part in your controller from ``$this->parser->parse('blog_template', $data);`` to ``return $parser->setData($data)->render('blog_template');``. Code Example ============ diff --git a/user_guide_src/source/installation/upgrade_view_parser/001.php b/user_guide_src/source/installation/upgrade_view_parser/001.php index 27dc410b1708..9acf5e9449d8 100644 --- a/user_guide_src/source/installation/upgrade_view_parser/001.php +++ b/user_guide_src/source/installation/upgrade_view_parser/001.php @@ -7,4 +7,4 @@ 'blog_heading' => 'My Blog Heading', ]; -echo $parser->setData($data)->render('blog_template'); +return $parser->setData($data)->render('blog_template'); diff --git a/user_guide_src/source/installation/upgrade_views.rst b/user_guide_src/source/installation/upgrade_views.rst index 8509705c76dc..29dcace6ee62 100644 --- a/user_guide_src/source/installation/upgrade_views.rst +++ b/user_guide_src/source/installation/upgrade_views.rst @@ -15,7 +15,7 @@ What has been changed ===================== - Your views look much like before, but they are invoked differently ... instead of CI3's - ``$this->load->view(x);``, you can use ``echo view(x);``. + ``$this->load->view(x);``, you can use ``return view(x);``. - CI4 supports *View Cells* to build your response in pieces, and *View Layouts* for page layout. - The template parser is still there, and substantially enhanced. @@ -24,7 +24,7 @@ Upgrade Guide 1. First, move all views to the folder **app/Views** 2. Change the loading syntax of views in every script where you load views: - - from ``$this->load->view('directory_name/file_name')`` to ``echo view('directory_name/file_name');`` + - from ``$this->load->view('directory_name/file_name')`` to ``return view('directory_name/file_name');`` - from ``$content = $this->load->view('file', $data, TRUE);`` to ``$content = view('file', $data);`` 3. (optional) You can change the echo syntax in views from ```` to ```` diff --git a/user_guide_src/source/libraries/pagination/002.php b/user_guide_src/source/libraries/pagination/002.php index baaa8471111f..c8cd31ebec5c 100644 --- a/user_guide_src/source/libraries/pagination/002.php +++ b/user_guide_src/source/libraries/pagination/002.php @@ -15,6 +15,6 @@ public function index() 'pager' => $model->pager, ]; - echo view('users/index', $data); + return view('users/index', $data); } } diff --git a/user_guide_src/source/libraries/validation/001.php b/user_guide_src/source/libraries/validation/001.php index e52362c46cea..41d51f1b8a25 100644 --- a/user_guide_src/source/libraries/validation/001.php +++ b/user_guide_src/source/libraries/validation/001.php @@ -11,11 +11,11 @@ public function index() helper(['form', 'url']); if (! $this->validate([])) { - echo view('Signup', [ + return view('Signup', [ 'validation' => $this->validator, ]); - } else { - echo view('Success'); } + + return view('Success'); } } diff --git a/user_guide_src/source/outgoing/view_layouts/001.php b/user_guide_src/source/outgoing/view_layouts/001.php index 2eed4c4f53dc..f6105365fa47 100644 --- a/user_guide_src/source/outgoing/view_layouts/001.php +++ b/user_guide_src/source/outgoing/view_layouts/001.php @@ -6,6 +6,6 @@ class MyController extends BaseController { public function index() { - echo view('some_view'); + return view('some_view'); } } diff --git a/user_guide_src/source/outgoing/view_parser.rst b/user_guide_src/source/outgoing/view_parser.rst index 961d8ea96c31..c0705e7fa257 100644 --- a/user_guide_src/source/outgoing/view_parser.rst +++ b/user_guide_src/source/outgoing/view_parser.rst @@ -550,7 +550,8 @@ An example with the iteration controlled in the view:: ['title' => 'Second Link', 'link' => '/second'], ] ]; - echo $parser->setData($data)->renderString($template); + + return $parser->setData($data)->renderString($template); Result:: diff --git a/user_guide_src/source/outgoing/view_parser/003.php b/user_guide_src/source/outgoing/view_parser/003.php index da4ef088f6bd..90f3c88273fc 100644 --- a/user_guide_src/source/outgoing/view_parser/003.php +++ b/user_guide_src/source/outgoing/view_parser/003.php @@ -5,4 +5,4 @@ 'blog_heading' => 'My Blog Heading', ]; -echo $parser->setData($data)->render('blog_template'); +return $parser->setData($data)->render('blog_template'); diff --git a/user_guide_src/source/outgoing/view_parser/004.php b/user_guide_src/source/outgoing/view_parser/004.php index 70862b585adc..643f541a5b3e 100644 --- a/user_guide_src/source/outgoing/view_parser/004.php +++ b/user_guide_src/source/outgoing/view_parser/004.php @@ -1,6 +1,6 @@ render('blog_template', [ +return $parser->render('blog_template', [ 'cache' => HOUR, 'cache_name' => 'something_unique', ]); diff --git a/user_guide_src/source/outgoing/view_parser/005.php b/user_guide_src/source/outgoing/view_parser/005.php index e77c54268648..e85e49db45a2 100644 --- a/user_guide_src/source/outgoing/view_parser/005.php +++ b/user_guide_src/source/outgoing/view_parser/005.php @@ -3,5 +3,5 @@ $template = '{blog_title}'; $data = ['blog_title' => 'My ramblings']; -echo $parser->setData($data)->renderString($template); +return $parser->setData($data)->renderString($template); // Result: My ramblings diff --git a/user_guide_src/source/outgoing/view_parser/006.php b/user_guide_src/source/outgoing/view_parser/006.php index dfde61eec728..40d379aec2ea 100644 --- a/user_guide_src/source/outgoing/view_parser/006.php +++ b/user_guide_src/source/outgoing/view_parser/006.php @@ -12,4 +12,4 @@ ], ]; -echo $parser->setData($data)->render('blog_template'); +return $parser->setData($data)->render('blog_template'); diff --git a/user_guide_src/source/outgoing/view_parser/007.php b/user_guide_src/source/outgoing/view_parser/007.php index b3ca937f711f..5128ed3cbe4a 100644 --- a/user_guide_src/source/outgoing/view_parser/007.php +++ b/user_guide_src/source/outgoing/view_parser/007.php @@ -8,4 +8,4 @@ 'blog_entries' => $query->getResultArray(), ]; -echo $parser->setData($data)->render('blog_template'); +return $parser->setData($data)->render('blog_template'); diff --git a/user_guide_src/source/outgoing/view_parser/008.php b/user_guide_src/source/outgoing/view_parser/008.php index 4b0a6215830e..8cac9bbbaa9d 100644 --- a/user_guide_src/source/outgoing/view_parser/008.php +++ b/user_guide_src/source/outgoing/view_parser/008.php @@ -9,4 +9,4 @@ ], ]; -echo $parser->setData($data)->render('blog_template'); +return $parser->setData($data)->render('blog_template'); diff --git a/user_guide_src/source/outgoing/view_parser/009.php b/user_guide_src/source/outgoing/view_parser/009.php index 6b112fdd6829..6f4b96e82274 100644 --- a/user_guide_src/source/outgoing/view_parser/009.php +++ b/user_guide_src/source/outgoing/view_parser/009.php @@ -7,5 +7,5 @@ 'location' => ['city' => 'Red City', 'planet' => 'Mars'], ]; -echo $parser->setData($data)->renderString($template); +return $parser->setData($data)->renderString($template); // Result: George lives in Red City on Mars. diff --git a/user_guide_src/source/outgoing/view_parser/010.php b/user_guide_src/source/outgoing/view_parser/010.php index 7fcd5bafbfec..4eb11fd6d908 100644 --- a/user_guide_src/source/outgoing/view_parser/010.php +++ b/user_guide_src/source/outgoing/view_parser/010.php @@ -7,8 +7,10 @@ 'location' => ['city' => 'Red City', 'planet' => 'Mars'], ]; -echo $parser->setData($data)->renderString($template, ['cascadeData' => false]); +return $parser->setData($data)->renderString($template, ['cascadeData' => false]); // Result: {name} lives in Red City on Mars. -echo $parser->setData($data)->renderString($template, ['cascadeData' => true]); +// or + +return $parser->setData($data)->renderString($template, ['cascadeData' => true]); // Result: George lives in Red City on Mars. diff --git a/user_guide_src/source/outgoing/view_parser/018.php b/user_guide_src/source/outgoing/view_parser/018.php index 0bb60828d691..5a88dd651c25 100644 --- a/user_guide_src/source/outgoing/view_parser/018.php +++ b/user_guide_src/source/outgoing/view_parser/018.php @@ -6,5 +6,6 @@ 'firstname' => 'John', 'lastname' => 'Doe', ]; -echo $parser->setData($data)->renderString($template); + +return $parser->setData($data)->renderString($template); // Result: Hello, John Doe diff --git a/user_guide_src/source/outgoing/view_parser/019.php b/user_guide_src/source/outgoing/view_parser/019.php index a3cb80300299..5f465be2296b 100644 --- a/user_guide_src/source/outgoing/view_parser/019.php +++ b/user_guide_src/source/outgoing/view_parser/019.php @@ -6,5 +6,6 @@ 'firstname' => 'John', 'lastname' => 'Doe', ]; -echo $parser->setData($data)->renderString($template); + +return $parser->setData($data)->renderString($template); // Result: Hello, John {initials} Doe diff --git a/user_guide_src/source/outgoing/view_parser/020.php b/user_guide_src/source/outgoing/view_parser/020.php index 62256192019d..fd072cbc0e5c 100644 --- a/user_guide_src/source/outgoing/view_parser/020.php +++ b/user_guide_src/source/outgoing/view_parser/020.php @@ -10,5 +10,6 @@ ['degree' => 'PhD'], ], ]; -echo $parser->setData($data)->renderString($template); + +return $parser->setData($data)->renderString($template); // Result: Hello, John Doe (Mr{degree} {/degrees}) diff --git a/user_guide_src/source/outgoing/view_parser/021.php b/user_guide_src/source/outgoing/view_parser/021.php index 977b8b958140..60fbb625da79 100644 --- a/user_guide_src/source/outgoing/view_parser/021.php +++ b/user_guide_src/source/outgoing/view_parser/021.php @@ -15,4 +15,5 @@ $data = [ 'menuitems' => $temp, ]; -echo $parser->setData($data)->renderString($template2); + +return $parser->setData($data)->renderString($template2); diff --git a/user_guide_src/source/outgoing/view_parser/022.php b/user_guide_src/source/outgoing/view_parser/022.php index 022450bb6fd6..1bdb256d92f1 100644 --- a/user_guide_src/source/outgoing/view_parser/022.php +++ b/user_guide_src/source/outgoing/view_parser/022.php @@ -1,3 +1,3 @@ render('myview'); +return $parser->render('myview'); diff --git a/user_guide_src/source/outgoing/view_parser/023.php b/user_guide_src/source/outgoing/view_parser/023.php index 022450bb6fd6..1bdb256d92f1 100644 --- a/user_guide_src/source/outgoing/view_parser/023.php +++ b/user_guide_src/source/outgoing/view_parser/023.php @@ -1,3 +1,3 @@ render('myview'); +return $parser->render('myview'); diff --git a/user_guide_src/source/outgoing/views.rst b/user_guide_src/source/outgoing/views.rst index 55da9ed98a22..56f736f23545 100644 --- a/user_guide_src/source/outgoing/views.rst +++ b/user_guide_src/source/outgoing/views.rst @@ -51,9 +51,6 @@ If you visit your site using the URL you did earlier you should see your new vie example.com/index.php/blog/ -.. note:: While all of the examples show echo the view directly, you can also return the output from the view, instead, - and it will be appended to any captured output. - Loading Multiple Views ====================== diff --git a/user_guide_src/source/outgoing/views/001.php b/user_guide_src/source/outgoing/views/001.php index 90c817235bf5..c1b1ff23a6dd 100644 --- a/user_guide_src/source/outgoing/views/001.php +++ b/user_guide_src/source/outgoing/views/001.php @@ -1,3 +1,3 @@ 'Your title', ]; - echo view('header'); - echo view('menu'); - echo view('content', $data); - echo view('footer'); + return view('header') + . view('menu') + . view('content', $data) + . view('footer'); } } diff --git a/user_guide_src/source/outgoing/views/004.php b/user_guide_src/source/outgoing/views/004.php index d77e328657f3..7c665c263391 100644 --- a/user_guide_src/source/outgoing/views/004.php +++ b/user_guide_src/source/outgoing/views/004.php @@ -1,3 +1,3 @@ 60]); +return view('file_name', $data, ['cache' => 60]); diff --git a/user_guide_src/source/outgoing/views/007.php b/user_guide_src/source/outgoing/views/007.php index b1d22eb55260..1b020abbc5a5 100644 --- a/user_guide_src/source/outgoing/views/007.php +++ b/user_guide_src/source/outgoing/views/007.php @@ -1,4 +1,4 @@ 60, 'cache_name' => 'my_cached_view']); +return view('file_name', $data, ['cache' => 60, 'cache_name' => 'my_cached_view']); diff --git a/user_guide_src/source/outgoing/views/008.php b/user_guide_src/source/outgoing/views/008.php index c9b2ab2f5bbd..8f3218c7029b 100644 --- a/user_guide_src/source/outgoing/views/008.php +++ b/user_guide_src/source/outgoing/views/008.php @@ -6,4 +6,4 @@ 'message' => 'My Message', ]; -echo view('blog_view', $data); +return view('blog_view', $data); diff --git a/user_guide_src/source/outgoing/views/009.php b/user_guide_src/source/outgoing/views/009.php index 61963a40bbb2..008d1cf85d26 100644 --- a/user_guide_src/source/outgoing/views/009.php +++ b/user_guide_src/source/outgoing/views/009.php @@ -11,6 +11,6 @@ public function index() $data['title'] = 'My Real Title'; $data['heading'] = 'My Real Heading'; - echo view('blog_view', $data); + return view('blog_view', $data); } } diff --git a/user_guide_src/source/outgoing/views/010.php b/user_guide_src/source/outgoing/views/010.php index c7dda333df20..189b5dc9f190 100644 --- a/user_guide_src/source/outgoing/views/010.php +++ b/user_guide_src/source/outgoing/views/010.php @@ -6,4 +6,4 @@ 'message' => 'My Message', ]; -echo view('blog_view', $data, ['saveData' => true]); +return view('blog_view', $data, ['saveData' => true]); diff --git a/user_guide_src/source/outgoing/views/011.php b/user_guide_src/source/outgoing/views/011.php index e3ddaeba2075..bb1a5fc21725 100644 --- a/user_guide_src/source/outgoing/views/011.php +++ b/user_guide_src/source/outgoing/views/011.php @@ -14,6 +14,6 @@ public function index() 'heading' => 'My Real Heading', ]; - echo view('blog_view', $data); + return view('blog_view', $data); } } From 76beb9d37b5f78ebcdc000ba00c9444a09cea72b Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 4 Apr 2022 09:55:59 +0900 Subject: [PATCH 0796/1246] docs: fix header level --- user_guide_src/source/concepts/services.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/user_guide_src/source/concepts/services.rst b/user_guide_src/source/concepts/services.rst index 84860e65f5c3..ea9b9712fd39 100644 --- a/user_guide_src/source/concepts/services.rst +++ b/user_guide_src/source/concepts/services.rst @@ -40,7 +40,7 @@ error-resistant. .. note:: It is recommended to only create services within controllers. Other files, like models and libraries should have the dependencies either passed into the constructor or through a setter method. Convenience Functions ---------------------- +===================== Two functions have been provided for getting a service. These functions are always available. @@ -110,7 +110,7 @@ within the class, and, if not, creates a new one. All of the factory methods pro .. literalinclude:: services/010.php Service Discovery ------------------ +================= CodeIgniter can automatically discover any Config\\Services.php files you may have created within any defined namespaces. This allows simple use of any module Services files. In order for custom Services files to be discovered, they must From 1944a69dad76ca7bfc925640ae664fcef396834f Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 4 Apr 2022 09:56:57 +0900 Subject: [PATCH 0797/1246] docs: use full classname in sample code Relative classname might not work. --- user_guide_src/source/concepts/services/012.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/concepts/services/012.php b/user_guide_src/source/concepts/services/012.php index cc4b63b4e20c..bd3c89f971ec 100644 --- a/user_guide_src/source/concepts/services/012.php +++ b/user_guide_src/source/concepts/services/012.php @@ -1,3 +1,3 @@ Date: Mon, 4 Apr 2022 09:58:24 +0900 Subject: [PATCH 0798/1246] docs: add / at the end of the path The default value ends with /. --- user_guide_src/source/concepts/services/009.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/concepts/services/009.php b/user_guide_src/source/concepts/services/009.php index 1bdf73954e16..78e4d7c74caf 100644 --- a/user_guide_src/source/concepts/services/009.php +++ b/user_guide_src/source/concepts/services/009.php @@ -1,3 +1,3 @@ Date: Mon, 4 Apr 2022 10:00:13 +0900 Subject: [PATCH 0799/1246] docs: fix text decoration, etc. --- user_guide_src/source/concepts/services.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/user_guide_src/source/concepts/services.rst b/user_guide_src/source/concepts/services.rst index ea9b9712fd39..b5678c024bc8 100644 --- a/user_guide_src/source/concepts/services.rst +++ b/user_guide_src/source/concepts/services.rst @@ -75,7 +75,7 @@ create a new class that implements the ``RouterCollectionInterface``: .. literalinclude:: services/006.php -Finally, modify **/app/Config/Services.php** to create a new instance of ``MyRouter`` +Finally, modify **app/Config/Services.php** to create a new instance of ``MyRouter`` instead of ``CodeIgniter\Router\RouterCollection``: .. literalinclude:: services/007.php @@ -87,7 +87,7 @@ In some instances, you will want the option to pass a setting to the class durin Since the services file is a very simple class, it is easy to make this work. A good example is the ``renderer`` service. By default, we want this class to be able -to find the views at ``APPPATH.views/``. We want the developer to have the option of +to find the views at ``APPPATH . views/``. We want the developer to have the option of changing that path, though, if their needs require it. So the class accepts the ``$viewPath`` as a constructor parameter. The service method looks like this: @@ -112,19 +112,19 @@ within the class, and, if not, creates a new one. All of the factory methods pro Service Discovery ================= -CodeIgniter can automatically discover any Config\\Services.php files you may have created within any defined namespaces. +CodeIgniter can automatically discover any **Config/Services.php** files you may have created within any defined namespaces. This allows simple use of any module Services files. In order for custom Services files to be discovered, they must meet these requirements: -- Its namespace must be defined in ``Config\Autoload.php`` -- Inside the namespace, the file must be found at ``Config\Services.php`` +- Its namespace must be defined in **app/Config/Autoload.php** +- Inside the namespace, the file must be found at **Config/Services.php** - It must extend ``CodeIgniter\Config\BaseService`` A small example should clarify this. -Imagine that you've created a new directory, ``Blog`` in your root directory. This will hold a **blog module** with controllers, +Imagine that you've created a new directory, **Blog** in your project root directory. This will hold a **Blog module** with controllers, models, etc, and you'd like to make some of the classes available as a service. The first step is to create a new file: -``Blog\Config\Services.php``. The skeleton of the file should be: +**Blog/Config/Services.php**. The skeleton of the file should be: .. literalinclude:: services/011.php From 31720766b8049ae7dee5471911334338fc81f7d5 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 4 Apr 2022 10:43:28 +0900 Subject: [PATCH 0800/1246] docs: add headings --- user_guide_src/source/concepts/services.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/user_guide_src/source/concepts/services.rst b/user_guide_src/source/concepts/services.rst index b5678c024bc8..3539c16c7420 100644 --- a/user_guide_src/source/concepts/services.rst +++ b/user_guide_src/source/concepts/services.rst @@ -44,6 +44,9 @@ Convenience Functions Two functions have been provided for getting a service. These functions are always available. +service() +--------- + The first is ``service()`` which returns a new instance of the requested service. The only required parameter is the service name. This is the same as the method name within the Services file always returns a SHARED instance of the class, so calling the function multiple times should @@ -55,6 +58,9 @@ If the creation method requires additional parameters, they can be passed after .. literalinclude:: services/004.php +single_service() +---------------- + The second function, ``single_service()`` works just like ``service()`` but returns a new instance of the class: From f00e952e346b47d827ecab149b70daf4b3e03e45 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 4 Apr 2022 10:52:07 +0900 Subject: [PATCH 0801/1246] docs: add sample code --- user_guide_src/source/concepts/services/003.php | 3 +++ user_guide_src/source/concepts/services/004.php | 3 +++ user_guide_src/source/concepts/services/005.php | 3 +++ 3 files changed, 9 insertions(+) diff --git a/user_guide_src/source/concepts/services/003.php b/user_guide_src/source/concepts/services/003.php index ebbd1d89c30d..a13e8ebf1696 100644 --- a/user_guide_src/source/concepts/services/003.php +++ b/user_guide_src/source/concepts/services/003.php @@ -1,3 +1,6 @@ Date: Mon, 4 Apr 2022 11:08:03 +0900 Subject: [PATCH 0802/1246] docs: add What is Services? and Why use Services? --- user_guide_src/source/concepts/services.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/user_guide_src/source/concepts/services.rst b/user_guide_src/source/concepts/services.rst index 3539c16c7420..b5747e4a913a 100644 --- a/user_guide_src/source/concepts/services.rst +++ b/user_guide_src/source/concepts/services.rst @@ -9,10 +9,19 @@ Services Introduction ============ +What is Services? +----------------- + +The **Services** in CodeIgniter 4 provide the functionality to create and share new class instances. +It is implemented as the ``Config\Services`` class. + All of the core classes within CodeIgniter are provided as "services". This simply means that, instead of hard-coding a class name to load, the classes to call are defined within a very simple configuration file. This file acts as a type of factory to create new instances of the required class. +Why use Services? +----------------- + A quick example will probably make things clearer, so imagine that you need to pull in an instance of the Timer class. The simplest method would simply be to create a new instance of that class: From 11e97ad12b8cd3c0181c90d1d9682d8b35f87b25 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 4 Apr 2022 11:10:44 +0900 Subject: [PATCH 0803/1246] docs: fix heading marks --- user_guide_src/source/concepts/services.rst | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/user_guide_src/source/concepts/services.rst b/user_guide_src/source/concepts/services.rst index b5747e4a913a..2ede82c668ac 100644 --- a/user_guide_src/source/concepts/services.rst +++ b/user_guide_src/source/concepts/services.rst @@ -7,10 +7,10 @@ Services :depth: 2 Introduction -============ +************ What is Services? ------------------ +================= The **Services** in CodeIgniter 4 provide the functionality to create and share new class instances. It is implemented as the ``Config\Services`` class. @@ -20,7 +20,7 @@ of hard-coding a class name to load, the classes to call are defined within a ve configuration file. This file acts as a type of factory to create new instances of the required class. Why use Services? ------------------ +================= A quick example will probably make things clearer, so imagine that you need to pull in an instance of the Timer class. The simplest method would simply be to create a new instance of that class: @@ -49,12 +49,12 @@ error-resistant. .. note:: It is recommended to only create services within controllers. Other files, like models and libraries should have the dependencies either passed into the constructor or through a setter method. Convenience Functions -===================== +********************* Two functions have been provided for getting a service. These functions are always available. service() ---------- +========= The first is ``service()`` which returns a new instance of the requested service. The only required parameter is the service name. This is the same as the method name within the Services @@ -68,7 +68,7 @@ If the creation method requires additional parameters, they can be passed after .. literalinclude:: services/004.php single_service() ----------------- +================ The second function, ``single_service()`` works just like ``service()`` but returns a new instance of the class: @@ -76,7 +76,7 @@ the class: .. literalinclude:: services/005.php Defining Services -================= +***************** To make services work well, you have to be able to rely on each class having a constant API, or `interface `_, to use. Almost all of @@ -96,7 +96,7 @@ instead of ``CodeIgniter\Router\RouterCollection``: .. literalinclude:: services/007.php Allowing Parameters -------------------- +=================== In some instances, you will want the option to pass a setting to the class during instantiation. Since the services file is a very simple class, it is easy to make this work. @@ -114,7 +114,7 @@ the path it uses: .. literalinclude:: services/009.php Shared Classes ------------------ +============== There are occasions where you need to require that only a single instance of a service is created. This is easily handled with the ``getSharedInstance()`` method that is called from within the @@ -125,7 +125,7 @@ within the class, and, if not, creates a new one. All of the factory methods pro .. literalinclude:: services/010.php Service Discovery -================= +***************** CodeIgniter can automatically discover any **Config/Services.php** files you may have created within any defined namespaces. This allows simple use of any module Services files. In order for custom Services files to be discovered, they must From 5fef49fe2ed5cf444e8d2c9dcb6ee0b2391a1db4 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 4 Apr 2022 11:26:26 +0900 Subject: [PATCH 0804/1246] docs: add How to Get a Service --- user_guide_src/source/concepts/services.rst | 19 ++++++++++++++++--- .../source/concepts/services/013.php | 3 +++ .../source/concepts/services/014.php | 3 +++ 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 user_guide_src/source/concepts/services/013.php create mode 100644 user_guide_src/source/concepts/services/014.php diff --git a/user_guide_src/source/concepts/services.rst b/user_guide_src/source/concepts/services.rst index 2ede82c668ac..b69a4e4c4f85 100644 --- a/user_guide_src/source/concepts/services.rst +++ b/user_guide_src/source/concepts/services.rst @@ -48,13 +48,26 @@ error-resistant. .. note:: It is recommended to only create services within controllers. Other files, like models and libraries should have the dependencies either passed into the constructor or through a setter method. +How to Get a Service +******************** + +As many CodeIgniter classes are provided as services, you can get them like the following: + +.. literalinclude:: services/013.php + +The ``$typography`` is an instance of the Typography class, and if you call ``\Config\Services::typography()`` again, you will get the exactly same instance. + +If you want to get a new instance of the Typography class, you need to pass ``false`` to the argument ``$getShared``: + +.. literalinclude:: services/014.php + Convenience Functions -********************* +===================== Two functions have been provided for getting a service. These functions are always available. service() -========= +--------- The first is ``service()`` which returns a new instance of the requested service. The only required parameter is the service name. This is the same as the method name within the Services @@ -68,7 +81,7 @@ If the creation method requires additional parameters, they can be passed after .. literalinclude:: services/004.php single_service() -================ +---------------- The second function, ``single_service()`` works just like ``service()`` but returns a new instance of the class: diff --git a/user_guide_src/source/concepts/services/013.php b/user_guide_src/source/concepts/services/013.php new file mode 100644 index 000000000000..0c82ed0e95fa --- /dev/null +++ b/user_guide_src/source/concepts/services/013.php @@ -0,0 +1,3 @@ + Date: Mon, 4 Apr 2022 12:36:06 +0900 Subject: [PATCH 0805/1246] docs: add Convenience Functions --- user_guide_src/source/concepts/factories.rst | 19 +++++++++++++++++++ .../source/concepts/factories/008.php | 6 ++++++ .../source/concepts/factories/009.php | 6 ++++++ 3 files changed, 31 insertions(+) create mode 100644 user_guide_src/source/concepts/factories/008.php create mode 100644 user_guide_src/source/concepts/factories/009.php diff --git a/user_guide_src/source/concepts/factories.rst b/user_guide_src/source/concepts/factories.rst index 2ddab73f2216..05dd7559da03 100644 --- a/user_guide_src/source/concepts/factories.rst +++ b/user_guide_src/source/concepts/factories.rst @@ -35,6 +35,25 @@ you get back the instance as before: .. literalinclude:: factories/003.php +Convenience Functions +===================== + +Two functions for short cut of the Factories have been provided. These functions are always available. + +config() +-------- + +The first is ``config()`` which returns a new instance of a Config class. The only required parameter is the class name: + +.. literalinclude:: factories/008.php + +model() +-------- + +The second function, ``model()`` returns a new instance of a Model class. The only required parameter is the class name: + +.. literalinclude:: factories/009.php + Factory Parameters ================== diff --git a/user_guide_src/source/concepts/factories/008.php b/user_guide_src/source/concepts/factories/008.php new file mode 100644 index 000000000000..866daa36acb2 --- /dev/null +++ b/user_guide_src/source/concepts/factories/008.php @@ -0,0 +1,6 @@ + Date: Mon, 4 Apr 2022 12:37:48 +0900 Subject: [PATCH 0806/1246] docs: add What is Factories? --- user_guide_src/source/concepts/factories.rst | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/user_guide_src/source/concepts/factories.rst b/user_guide_src/source/concepts/factories.rst index 05dd7559da03..f04317174273 100644 --- a/user_guide_src/source/concepts/factories.rst +++ b/user_guide_src/source/concepts/factories.rst @@ -9,8 +9,13 @@ Factories Introduction ============ -Like ``Services``, ``Factories`` are an extension of autoloading that helps keep your code -concise yet optimal, without having to pass around object instances between classes. At its +What is Factories? +------------------ + +Like :doc:`./services`, **Factories** are an extension of autoloading that helps keep your code +concise yet optimal, without having to pass around object instances between classes. + +At its simplest, Factories provide a common way to create a class instance and access it from anywhere. This is a great way to reuse object states and reduce memory load from keeping multiple instances loaded across your app. From c0884be3ff9b983318a2f9262cc3828f860f69b4 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 4 Apr 2022 13:44:20 +0900 Subject: [PATCH 0807/1246] docs: add explanation about Differences from Services and preferApp behavior --- user_guide_src/source/concepts/factories.rst | 46 +++++++++++++++---- .../source/concepts/factories/002.php | 2 +- .../source/concepts/factories/003.php | 2 +- .../source/concepts/factories/010.php | 3 ++ 4 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 user_guide_src/source/concepts/factories/010.php diff --git a/user_guide_src/source/concepts/factories.rst b/user_guide_src/source/concepts/factories.rst index f04317174273..2e23e448a8f9 100644 --- a/user_guide_src/source/concepts/factories.rst +++ b/user_guide_src/source/concepts/factories.rst @@ -20,14 +20,32 @@ simplest, Factories provide a common way to create a class instance and access i anywhere. This is a great way to reuse object states and reduce memory load from keeping multiple instances loaded across your app. -Anything can be loaded by Factories, but the best examples are those classes that are used +Any class can be loaded by Factories, but the best examples are those classes that are used to work on or transmit common data. The framework itself uses Factories internally, e.g., to make sure the correct configuration is loaded when using the ``Config`` class. -Take a look at ``Models`` as an example. You can access the Factory specific to ``Models`` -by using the magic static method of the Factories class, ``Factories::models()``. Because of -the common path structure for namespaces and folders, Factories know that the model files -and classes are found within **Models**, so you can request a model by its shorthand base name: +Differences from Services +------------------------- + +Factories require a concrete class name to instantiate, and do not have code to create instances. + +So Factories are not good for creating complex instance that needs many dependencies, +and cannot change the class of the instance to be returned. + +On the other hand, Services have code to create instances, so it can create a complex instance +that needs other services or class instances. When you get a service, Services require a service name, +not a class name, so the returned instance can be changed without changing the client code. + +Example +------- + +Take a look at **Models** as an example. You can access the Factory specific to Models +by using the magic static method of the Factories class, ``Factories::models()``. + +By default, Factories first searches in the ``App`` namespace for the path corresponding to the magic static method name. +``Factories::models()`` searches the path **Models/**. + +In the following code, if you have ``App\Models\UserModel``, the instance will be returned: .. literalinclude:: factories/001.php @@ -35,7 +53,17 @@ Or you could also request a specific class: .. literalinclude:: factories/002.php -Next time you ask for the same class anywhere in your code, ``Factories`` will be sure +If you have only ``Blog\Models\UserModel``, the instance will be returned. +But if you have both ``App\Models\UserModel`` and ``Blog\Models\UserModel``, +The instance of ``App\Models\UserModel`` will be returned. + +If you want to get ``Blog\Models\UserModel``, you need the option ``preferApp``: + +.. literalinclude:: factories/010.php + +See :ref:`factories-options` for the details. + +Next time you ask for the same class anywhere in your code, Factories will be sure you get back the instance as before: .. literalinclude:: factories/003.php @@ -112,13 +140,13 @@ Configurations To set default component options, create a new Config files at **app/Config/Factory.php** that supplies options as an array property that matches the name of the component. For example, -if you wanted to ensure that all Filters used by your app were valid framework instances, -your **Factory.php** file might look like this: +if you wanted to ensure that all **Filters** used by your app were valid framework instances, +your **app/Config/Factory.php** file might look like this: .. literalinclude:: factories/005.php This would prevent conflict of an unrelated third-party module which happened to have an -unrelated "Filters" path in its namespace. +unrelated ``Filters`` path in its namespace. setOptions Method ----------------- diff --git a/user_guide_src/source/concepts/factories/002.php b/user_guide_src/source/concepts/factories/002.php index cbc19d8b2730..6a56bbe7a374 100644 --- a/user_guide_src/source/concepts/factories/002.php +++ b/user_guide_src/source/concepts/factories/002.php @@ -1,3 +1,3 @@ false]); From 221d484dd012db99371b0d7819bded4dc043bccc Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 4 Apr 2022 09:23:08 +0900 Subject: [PATCH 0808/1246] docs: fix Parser saveData description The default value for $saveData is null, and Config\View::$saveData (true by default) will be set. --- user_guide_src/source/outgoing/view_parser.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/user_guide_src/source/outgoing/view_parser.rst b/user_guide_src/source/outgoing/view_parser.rst index c0705e7fa257..3cefd845de95 100644 --- a/user_guide_src/source/outgoing/view_parser.rst +++ b/user_guide_src/source/outgoing/view_parser.rst @@ -106,7 +106,7 @@ Several options can be passed to the ``render()`` or ``renderString()`` methods. - ``cache_name`` - the ID used to save/retrieve a cached view result; defaults to the viewpath; ignored for renderString() - ``saveData`` - true if the view data parameters should be retained for subsequent calls; - default is **false** + default is **true** - ``cascadeData`` - true if pseudo-variable settings should be passed on to nested substitutions; default is **true** @@ -578,7 +578,7 @@ Class Reference .. php:class:: CodeIgniter\\View\\Parser - .. php:method:: render($view[, $options[, $saveData = false]]) + .. php:method:: render($view[, $options[, $saveData]]) :param string $view: File name of the view source :param array $options: Array of options, as key/value pairs @@ -600,7 +600,7 @@ Class Reference Any conditional substitutions are performed first, then remaining substitutions are performed for each data pair. - .. php:method:: renderString($template[, $options[, $saveData = false]]) + .. php:method:: renderString($template[, $options[, $saveData]]) :param string $template: View source provided as a string :param array $options: Array of options, as key/value pairs From b95708ed0600e4eddff4dd849869594931930479 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 4 Apr 2022 09:28:30 +0900 Subject: [PATCH 0809/1246] docs: fix View saveData description The default is true. --- user_guide_src/source/outgoing/views.rst | 17 +++++++++++------ user_guide_src/source/outgoing/views/010.php | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/user_guide_src/source/outgoing/views.rst b/user_guide_src/source/outgoing/views.rst index 56f736f23545..903f1fef4727 100644 --- a/user_guide_src/source/outgoing/views.rst +++ b/user_guide_src/source/outgoing/views.rst @@ -123,15 +123,20 @@ Now open your view file and change the text to variables that correspond to the Then load the page at the URL you've been using and you should see the variables replaced. -The data passed in is only available during one call to `view`. If you call the function multiple times -in a single request, you will have to pass the desired data to each view. This keeps any data from "bleeding" into -other views, potentially causing issues. If you would prefer the data to persist, you can pass the `saveData` option -into the `$option` array in the third parameter. +The saveData Option +------------------- + +The data passed in is retained for subsequent calls to ``view()``. If you call the function multiple times +in a single request, you will not have to pass the desired data to each ``view()``. + +But this might not keep any data from "bleeding" into +other views, potentially causing issues. If you would prefer to clean the data after one call, you can pass the ``saveData`` option +into the ``$option`` array in the third parameter. .. literalinclude:: views/010.php -Additionally, if you would like the default functionality of the view function to be that it does save the data -between calls, you can set ``$saveData`` to **true** in **app/Config/Views.php**. +Additionally, if you would like the default functionality of the view function to be that it does clear the data +between calls, you can set ``$saveData`` to **false** in **app/Config/Views.php**. Creating Loops ============== diff --git a/user_guide_src/source/outgoing/views/010.php b/user_guide_src/source/outgoing/views/010.php index 189b5dc9f190..8411aa134e7b 100644 --- a/user_guide_src/source/outgoing/views/010.php +++ b/user_guide_src/source/outgoing/views/010.php @@ -6,4 +6,4 @@ 'message' => 'My Message', ]; -return view('blog_view', $data, ['saveData' => true]); +return view('blog_view', $data, ['saveData' => false]); From 510810c2b27a1a2adcb9f21d05fbdf057dce4a86 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 4 Apr 2022 09:31:00 +0900 Subject: [PATCH 0810/1246] docs: decorate view() function --- user_guide_src/source/outgoing/views.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/user_guide_src/source/outgoing/views.rst b/user_guide_src/source/outgoing/views.rst index 903f1fef4727..3eb80427fc2a 100644 --- a/user_guide_src/source/outgoing/views.rst +++ b/user_guide_src/source/outgoing/views.rst @@ -101,7 +101,7 @@ along ``cache_name`` and the cache ID you wish to use: Adding Dynamic Data to the View =============================== -Data is passed from the controller to the view by way of an array in the second parameter of the view function. +Data is passed from the controller to the view by way of an array in the second parameter of the ``view()`` function. Here's an example: .. literalinclude:: views/008.php @@ -135,7 +135,7 @@ into the ``$option`` array in the third parameter. .. literalinclude:: views/010.php -Additionally, if you would like the default functionality of the view function to be that it does clear the data +Additionally, if you would like the default functionality of the ``view()`` function to be that it does clear the data between calls, you can set ``$saveData`` to **false** in **app/Config/Views.php**. Creating Loops From 926fc6eeabdbc9553869b7b7fba466a1c15b41b7 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 4 Apr 2022 20:25:14 +0900 Subject: [PATCH 0811/1246] fix: Publisher::discover() may loads incorrect classname --- system/Publisher/Publisher.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/Publisher/Publisher.php b/system/Publisher/Publisher.php index 5cd392d921a8..01a3c62db657 100644 --- a/system/Publisher/Publisher.php +++ b/system/Publisher/Publisher.php @@ -111,9 +111,9 @@ final public static function discover(string $directory = 'Publishers'): array // Loop over each file checking to see if it is a Publisher foreach (array_unique($files) as $file) { - $className = $locator->findQualifiedNameFromPath($file); + $className = $locator->getClassname($file); - if (is_string($className) && class_exists($className) && is_a($className, self::class, true)) { + if ($className !== '' && class_exists($className) && is_a($className, self::class, true)) { self::$discovered[$directory][] = new $className(); } } From 74fb4fb8788bd419016e8bccc53f1825814a721e Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 5 Apr 2022 10:41:27 +0900 Subject: [PATCH 0812/1246] refactor: extract withErrors() method --- system/HTTP/RedirectResponse.php | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/system/HTTP/RedirectResponse.php b/system/HTTP/RedirectResponse.php index 54e1ae12f36d..b9cabbba6793 100644 --- a/system/HTTP/RedirectResponse.php +++ b/system/HTTP/RedirectResponse.php @@ -85,18 +85,35 @@ public function back(?int $code = null, string $method = 'auto') public function withInput() { $session = Services::session(); - $session->setFlashdata('_ci_old_input', [ 'get' => $_GET ?? [], 'post' => $_POST ?? [], ]); - // If the validation has any errors, transmit those back - // so they can be displayed when the validation is handled - // within a method different than displaying the form. + // @TODO Remove this in the future. + // See https://github.com/codeigniter4/CodeIgniter4/issues/5839#issuecomment-1086624600 + $this->withErrors(); + + return $this; + } + + /** + * Set validation errors in the session. + * + * If the validation has any errors, transmit those back + * so they can be displayed when the validation is handled + * within a method different than displaying the form. + * + * @TODO Make this method public when removing $this->withErrors() in withInput(). + * + * @return $this + */ + private function withErrors(): self + { $validation = Services::validation(); if ($validation->getErrors()) { + $session = Services::session(); $session->setFlashdata('_ci_validation_errors', serialize($validation->getErrors())); } From e4f1d8817af17b3106e6ea3fbe3a1e57870813c6 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 5 Apr 2022 11:10:01 +0900 Subject: [PATCH 0813/1246] fix: validation errors in model are not cleared when running validation again --- phpstan-baseline.neon.dist | 5 ----- system/BaseModel.php | 4 +++- tests/system/Models/ValidationModelTest.php | 23 +++++++++++++++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/phpstan-baseline.neon.dist b/phpstan-baseline.neon.dist index 1021eb445899..53d3710b7ea7 100644 --- a/phpstan-baseline.neon.dist +++ b/phpstan-baseline.neon.dist @@ -25,11 +25,6 @@ parameters: count: 1 path: system/Autoloader/Autoloader.php - - - message: "#^Method CodeIgniter\\\\Validation\\\\ValidationInterface\\:\\:run\\(\\) invoked with 3 parameters, 0\\-2 required\\.$#" - count: 1 - path: system/BaseModel.php - - message: "#^Property Config\\\\Cache\\:\\:\\$backupHandler \\(string\\) in isset\\(\\) is not nullable\\.$#" count: 1 diff --git a/system/BaseModel.php b/system/BaseModel.php index 64753be5b3e3..39bd9ce2cb4c 100644 --- a/system/BaseModel.php +++ b/system/BaseModel.php @@ -1344,7 +1344,9 @@ public function validate($data): bool return true; } - return $this->validation->setRules($rules, $this->validationMessages)->run($data, null, $this->DBGroup); + $this->validation->reset()->setRules($rules, $this->validationMessages); + + return $this->validation->run($data, null, $this->DBGroup); } /** diff --git a/tests/system/Models/ValidationModelTest.php b/tests/system/Models/ValidationModelTest.php index 0d60d36524ac..e7cc4a8d11e5 100644 --- a/tests/system/Models/ValidationModelTest.php +++ b/tests/system/Models/ValidationModelTest.php @@ -55,6 +55,29 @@ public function testValidationBasics(): void $this->assertSame('You forgot to name the baby.', $errors['name']); } + /** + * @see https://github.com/codeigniter4/CodeIgniter4/issues/5859 + */ + public function testValidationTwice(): void + { + $data = [ + 'name' => null, + 'description' => 'some great marketing stuff', + ]; + + $this->assertFalse($this->model->insert($data)); + + $errors = $this->model->errors(); + $this->assertSame('You forgot to name the baby.', $errors['name']); + + $data = [ + 'name' => 'some name', + 'description' => 'some great marketing stuff', + ]; + + $this->assertIsInt($this->model->insert($data)); + } + public function testValidationWithSetValidationRule(): void { $data = [ From 8f1ed45f1bb3d2df34665e80767d171bd4cef167 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 5 Apr 2022 11:42:31 +0900 Subject: [PATCH 0814/1246] feat: add $includeDir option to get_filenames() --- system/Helpers/filesystem_helper.php | 23 ++++++++++++------- tests/system/Helpers/FilesystemHelperTest.php | 16 +++++++++++++ .../source/helpers/filesystem_helper.rst | 7 +++--- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/system/Helpers/filesystem_helper.php b/system/Helpers/filesystem_helper.php index 89d4d507f961..4918e87e7bf2 100644 --- a/system/Helpers/filesystem_helper.php +++ b/system/Helpers/filesystem_helper.php @@ -194,9 +194,14 @@ function delete_files(string $path, bool $delDir = false, bool $htdocs = false, * @param string $sourceDir Path to source * @param bool|null $includePath Whether to include the path as part of the filename; false for no path, null for a relative path, true for full path * @param bool $hidden Whether to include hidden files (files beginning with a period) + * @param bool $includeDir Whether to include directories */ - function get_filenames(string $sourceDir, ?bool $includePath = false, bool $hidden = false): array - { + function get_filenames( + string $sourceDir, + ?bool $includePath = false, + bool $hidden = false, + bool $includeDir = true + ): array { $files = []; $sourceDir = realpath($sourceDir) ?: $sourceDir; @@ -212,12 +217,14 @@ function get_filenames(string $sourceDir, ?bool $includePath = false, bool $hidd continue; } - if ($includePath === false) { - $files[] = $basename; - } elseif ($includePath === null) { - $files[] = str_replace($sourceDir, '', $name); - } else { - $files[] = $name; + if ($includeDir || ! $object->isDir()) { + if ($includePath === false) { + $files[] = $basename; + } elseif ($includePath === null) { + $files[] = str_replace($sourceDir, '', $name); + } else { + $files[] = $name; + } } } } catch (Throwable $e) { diff --git a/tests/system/Helpers/FilesystemHelperTest.php b/tests/system/Helpers/FilesystemHelperTest.php index d20d93481e39..c9f5789a9d4c 100644 --- a/tests/system/Helpers/FilesystemHelperTest.php +++ b/tests/system/Helpers/FilesystemHelperTest.php @@ -305,6 +305,22 @@ public function testGetFilenames() $this->assertSame($expected, get_filenames($vfs->url(), false)); } + public function testGetFilenamesWithoutDirectories() + { + $vfs = vfsStream::setup('root', null, $this->structure); + + $filenames = get_filenames($vfs->url(), true, false, false); + + $expected = [ + 'vfs://root/boo/far', + 'vfs://root/boo/faz', + 'vfs://root/foo/bar', + 'vfs://root/foo/baz', + 'vfs://root/simpleFile', + ]; + $this->assertSame($expected, $filenames); + } + public function testGetFilenamesWithHidden() { $this->assertTrue(function_exists('get_filenames')); diff --git a/user_guide_src/source/helpers/filesystem_helper.rst b/user_guide_src/source/helpers/filesystem_helper.rst index 4cb00fb23188..017ee9a82149 100644 --- a/user_guide_src/source/helpers/filesystem_helper.rst +++ b/user_guide_src/source/helpers/filesystem_helper.rst @@ -150,11 +150,12 @@ The following functions are available: .. note:: The files must be writable or owned by the system in order to be deleted. -.. php:function:: get_filenames($source_dir[, $include_path = false]) +.. php:function:: get_filenames($sourceDir[, $includePath = false[, $hidden = false[, $includeDir = true]]]) - :param string $source_dir: Directory path - :param bool|null $include_path: Whether to include the path as part of the filename; false for no path, null for the path relative to $source_dir, true for the full path + :param string $sourceDir: Directory path + :param bool|null $includePath: Whether to include the path as part of the filename; false for no path, null for the path relative to ``$sourceDir``, true for the full path :param bool $hidden: Whether to include hidden files (files beginning with a period) + :param bool $includeDir: Whether to include directories :returns: An array of file names :rtype: array From 7b442c6a49fb469de6998531433be82cb1ce3345 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 5 Apr 2022 13:00:45 +0900 Subject: [PATCH 0815/1246] docs: fix function reference --- .../source/helpers/filesystem_helper.rst | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/user_guide_src/source/helpers/filesystem_helper.rst b/user_guide_src/source/helpers/filesystem_helper.rst index 4cb00fb23188..e45c7ce31565 100644 --- a/user_guide_src/source/helpers/filesystem_helper.rst +++ b/user_guide_src/source/helpers/filesystem_helper.rst @@ -21,10 +21,10 @@ Available Functions The following functions are available: -.. php:function:: directory_map($source_dir[, $directory_depth = 0[, $hidden = false]]) +.. php:function:: directory_map($sourceDir[, $directoryDepth = 0[, $hidden = false]]) - :param string $source_dir: Path to the source directory - :param int $directory_depth: Depth of directories to traverse (0 = fully recursive, 1 = current dir, etc) + :param string $sourceDir: Path to the source directory + :param int $directoryDepth: Depth of directories to traverse (0 = fully recursive, 1 = current dir, etc) :param bool $hidden: Whether to include hidden paths :returns: An array of files :rtype: array @@ -167,10 +167,10 @@ The following functions are available: .. literalinclude:: filesystem_helper/010.php -.. php:function:: get_dir_file_info($source_dir, $top_level_only) +.. php:function:: get_dir_file_info($sourceDir[, $topLevelOnly = true]) - :param string $source_dir: Directory path - :param bool $top_level_only: Whether to look only at the specified directory (excluding sub-directories) + :param string $sourceDir: Directory path + :param bool $topLevelOnly: Whether to look only at the specified directory (excluding sub-directories) :returns: An array containing info on the supplied directory's contents :rtype: array @@ -183,10 +183,10 @@ The following functions are available: .. literalinclude:: filesystem_helper/011.php -.. php:function:: get_file_info($file[, $returned_values = ['name', 'server_path', 'size', 'date']]) +.. php:function:: get_file_info($file[, $returnedValues = ['name', 'server_path', 'size', 'date']]) :param string $file: File path - :param array|string $returned_values: What type of info to return to be passed as array or comma separated string + :param array|string $returnedValues: What type of info to return to be passed as array or comma separated string :returns: An array containing info on the specified file or false on failure :rtype: array @@ -194,8 +194,8 @@ The following functions are available: 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`. + Valid ``$returnedValues`` options are: ``name``, ``size``, ``date``, ``readable``, ``writeable``, + ``executable`` and ``fileperms``. .. php:function:: symbolic_permissions($perms) @@ -230,10 +230,10 @@ The following functions are available: .. literalinclude:: filesystem_helper/014.php -.. php:function:: set_realpath($path[, $check_existence = false]) +.. php:function:: set_realpath($path[, $checkExistence = false]) :param string $path: Path - :param bool $check_existence: Whether to check if the path actually exists + :param bool $checkExistence: Whether to check if the path actually exists :returns: An absolute path :rtype: string From e19872ad2cc39b6f7142c1f024a7e2cd8f4020f6 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 5 Apr 2022 16:52:30 +0900 Subject: [PATCH 0816/1246] docs: remove HackerOne link CI4 does not use HackerOne. --- contributing/bug_report.md | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/contributing/bug_report.md b/contributing/bug_report.md index c564a9a734f4..43767cdd1766 100644 --- a/contributing/bug_report.md +++ b/contributing/bug_report.md @@ -27,15 +27,7 @@ have found a bug, again - please ask on the forums first. ## Security -Did you find a security issue in CodeIgniter? - -Please *don't* disclose it publicly, but e-mail us at -, or report it via our page on -[HackerOne](https://hackerone.com/codeigniter). - -If you've found a critical vulnerability, we'd be happy to credit you in -our -[ChangeLog](https://codeigniter4.github.io/CodeIgniter4/changelogs/index.html). +See [SECURITY.md](../SECURITY.md). ## Tips for a Good Issue Report From 70af24e461382a2c895a139f87e3c4960a111ba6 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 5 Apr 2022 17:21:12 +0900 Subject: [PATCH 0817/1246] chore: rename php-cs-fixer config files The php-cs-fixer configuration files are all in one place and easy to find. --- .github/workflows/test-coding-standards.yml | 4 ++-- .php-cs-fixer.dist.php | 4 ++-- ...r.php-cs-fixer.dist.php => .php-cs-fixer.no-header.php | 2 +- ....php-cs-fixer.dist.php => .php-cs-fixer.user-guide.php | 2 +- admin/pre-commit | 8 ++++---- 5 files changed, 10 insertions(+), 10 deletions(-) rename .no-header.php-cs-fixer.dist.php => .php-cs-fixer.no-header.php (95%) rename .user-guide.php-cs-fixer.dist.php => .php-cs-fixer.user-guide.php (95%) diff --git a/.github/workflows/test-coding-standards.yml b/.github/workflows/test-coding-standards.yml index e5b4a2043342..5fa13728b37d 100644 --- a/.github/workflows/test-coding-standards.yml +++ b/.github/workflows/test-coding-standards.yml @@ -52,10 +52,10 @@ jobs: run: composer update --ansi --no-interaction - name: Run lint on `app/`, `admin/`, `public/` - run: vendor/bin/php-cs-fixer fix --verbose --ansi --dry-run --config=.no-header.php-cs-fixer.dist.php --using-cache=no --diff + run: vendor/bin/php-cs-fixer fix --verbose --ansi --dry-run --config=.php-cs-fixer.no-header.php --using-cache=no --diff - name: Run lint on `system/`, `tests`, `utils/`, and root PHP files run: vendor/bin/php-cs-fixer fix --verbose --ansi --dry-run --using-cache=no --diff - name: Run lint on `user_guide_src/source/` - run: vendor/bin/php-cs-fixer fix --verbose --ansi --dry-run --config=.user-guide.php-cs-fixer.dist.php --using-cache=no --diff + run: vendor/bin/php-cs-fixer fix --verbose --ansi --dry-run --config=.php-cs-fixer.user-guide.php --using-cache=no --diff diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 7caeaec1035c..02c6549b2c03 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -29,8 +29,8 @@ ->notName('#Foobar.php$#') ->append([ __FILE__, - __DIR__ . '/.no-header.php-cs-fixer.dist.php', - __DIR__ . '/.user-guide.php-cs-fixer.dist.php', + __DIR__ . '/.php-cs-fixer.no-header.php', + __DIR__ . '/.php-cs-fixer.user-guide.php', __DIR__ . '/rector.php', __DIR__ . '/spark', __DIR__ . '/user_guide_src/renumerate.php', diff --git a/.no-header.php-cs-fixer.dist.php b/.php-cs-fixer.no-header.php similarity index 95% rename from .no-header.php-cs-fixer.dist.php rename to .php-cs-fixer.no-header.php index 153ac5bd1328..6c136cd4b164 100644 --- a/.no-header.php-cs-fixer.dist.php +++ b/.php-cs-fixer.no-header.php @@ -33,7 +33,7 @@ $overrides = []; $options = [ - 'cacheFile' => 'build/.no-header.php-cs-fixer.cache', + 'cacheFile' => 'build/.php-cs-fixer.no-header.cache', 'finder' => $finder, 'customFixers' => FixerGenerator::create('vendor/nexusphp/cs-config/src/Fixer', 'Nexus\\CsConfig\\Fixer'), 'customRules' => [ diff --git a/.user-guide.php-cs-fixer.dist.php b/.php-cs-fixer.user-guide.php similarity index 95% rename from .user-guide.php-cs-fixer.dist.php rename to .php-cs-fixer.user-guide.php index 900c26ec81e1..8081d73698ca 100644 --- a/.user-guide.php-cs-fixer.dist.php +++ b/.php-cs-fixer.user-guide.php @@ -37,7 +37,7 @@ ]; $options = [ - 'cacheFile' => 'build/.user-guide.php-cs-fixer.cache', + 'cacheFile' => 'build/.php-cs-fixer.user-guide.cache', 'finder' => $finder, 'customFixers' => FixerGenerator::create('vendor/nexusphp/cs-config/src/Fixer', 'Nexus\\CsConfig\\Fixer'), 'customRules' => [ diff --git a/admin/pre-commit b/admin/pre-commit index e8fdcff64499..1fa6b15e5984 100644 --- a/admin/pre-commit +++ b/admin/pre-commit @@ -42,9 +42,9 @@ if [ "$FILES" != "" ]; then # Run on whole codebase to skip on unnecessary filtering # Run first on app, admin, public if [ -d /proc/cygdrive ]; then - ./vendor/bin/php-cs-fixer fix --verbose --dry-run --diff --config=.no-header.php-cs-fixer.dist.php + ./vendor/bin/php-cs-fixer fix --verbose --dry-run --diff --config=.php-cs-fixer.no-header.php else - php ./vendor/bin/php-cs-fixer fix --verbose --dry-run --diff --config=.no-header.php-cs-fixer.dist.php + php ./vendor/bin/php-cs-fixer fix --verbose --dry-run --diff --config=.php-cs-fixer.no-header.php fi if [ $? != 0 ]; then @@ -66,9 +66,9 @@ if [ "$FILES" != "" ]; then # Next, run on user_guide_src/source PHP files if [ -d /proc/cygdrive ]; then - ./vendor/bin/php-cs-fixer fix --verbose --dry-run --diff --config=.user-guide.php-cs-fixer.dist.php + ./vendor/bin/php-cs-fixer fix --verbose --dry-run --diff --config=.php-cs-fixer.user-guide.php else - php ./vendor/bin/php-cs-fixer fix --verbose --dry-run --diff --config=.user-guide.php-cs-fixer.dist.php + php ./vendor/bin/php-cs-fixer fix --verbose --dry-run --diff --config=.php-cs-fixer.user-guide.php fi if [ $? != 0 ]; then From b71ed71595ff7e0828a6ad97a9e6e0e1082f5df1 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 6 Apr 2022 08:50:23 +0900 Subject: [PATCH 0818/1246] docs: fix by proofreading Co-authored-by: MGatner --- user_guide_src/source/concepts/factories.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/concepts/factories.rst b/user_guide_src/source/concepts/factories.rst index 2e23e448a8f9..ac9f562732b0 100644 --- a/user_guide_src/source/concepts/factories.rst +++ b/user_guide_src/source/concepts/factories.rst @@ -57,7 +57,7 @@ If you have only ``Blog\Models\UserModel``, the instance will be returned. But if you have both ``App\Models\UserModel`` and ``Blog\Models\UserModel``, The instance of ``App\Models\UserModel`` will be returned. -If you want to get ``Blog\Models\UserModel``, you need the option ``preferApp``: +If you want to get ``Blog\Models\UserModel``, you need to disable the option ``preferApp``: .. literalinclude:: factories/010.php From b1a77e71cff780d9079beaf3d291bdd715d4e2a9 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 6 Apr 2022 08:50:40 +0900 Subject: [PATCH 0819/1246] docs: fix by proofreading Co-authored-by: MGatner --- user_guide_src/source/concepts/factories.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/concepts/factories.rst b/user_guide_src/source/concepts/factories.rst index ac9f562732b0..ca1025168367 100644 --- a/user_guide_src/source/concepts/factories.rst +++ b/user_guide_src/source/concepts/factories.rst @@ -71,7 +71,7 @@ you get back the instance as before: Convenience Functions ===================== -Two functions for short cut of the Factories have been provided. These functions are always available. +Two shortcut functions for Factories have been provided. These functions are always available. config() -------- From 12aa1aaf21e651d93f6c102445e866c7fe849585 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 6 Apr 2022 08:51:14 +0900 Subject: [PATCH 0820/1246] docs: fix by proofreading Co-authored-by: MGatner --- user_guide_src/source/concepts/factories.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/concepts/factories.rst b/user_guide_src/source/concepts/factories.rst index ca1025168367..5f34b4a1bb5a 100644 --- a/user_guide_src/source/concepts/factories.rst +++ b/user_guide_src/source/concepts/factories.rst @@ -140,7 +140,7 @@ Configurations To set default component options, create a new Config files at **app/Config/Factory.php** that supplies options as an array property that matches the name of the component. For example, -if you wanted to ensure that all **Filters** used by your app were valid framework instances, +if you want to ensure that each ``Filter`` used by your app is an actual framework, your **app/Config/Factory.php** file might look like this: .. literalinclude:: factories/005.php From d41fbe26f89ef1d9df9158aaf305ba9b32fca3d1 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 6 Apr 2022 08:53:26 +0900 Subject: [PATCH 0821/1246] docs: remove duplicated "unrelated" --- user_guide_src/source/concepts/factories.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/concepts/factories.rst b/user_guide_src/source/concepts/factories.rst index 5f34b4a1bb5a..600a153d1a8c 100644 --- a/user_guide_src/source/concepts/factories.rst +++ b/user_guide_src/source/concepts/factories.rst @@ -145,7 +145,7 @@ your **app/Config/Factory.php** file might look like this: .. literalinclude:: factories/005.php -This would prevent conflict of an unrelated third-party module which happened to have an +This would prevent conflict of an third-party module which happened to have an unrelated ``Filters`` path in its namespace. setOptions Method From ac6a97d04c7345223427a7243dd11735672d3dba Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 6 Apr 2022 09:05:57 +0900 Subject: [PATCH 0822/1246] docs: add more explanation for filters component --- user_guide_src/source/concepts/factories.rst | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/user_guide_src/source/concepts/factories.rst b/user_guide_src/source/concepts/factories.rst index 600a153d1a8c..ff5ea4faf140 100644 --- a/user_guide_src/source/concepts/factories.rst +++ b/user_guide_src/source/concepts/factories.rst @@ -139,12 +139,17 @@ Configurations -------------- To set default component options, create a new Config files at **app/Config/Factory.php** -that supplies options as an array property that matches the name of the component. For example, -if you want to ensure that each ``Filter`` used by your app is an actual framework, +that supplies options as an array property that matches the name of the component. + +For example, if you want to create **Filters** by Factories, the component name wll be ``filters``. +And if you want to ensure that each filter is an instance of a class which implements CodeIgniter's ``FilterInterface``, your **app/Config/Factory.php** file might look like this: .. literalinclude:: factories/005.php +Now you can create a filter with code like ``Factories::filters('SomeFilter')``, +and the returned instance will surely be a CodeIgniter's filter. + This would prevent conflict of an third-party module which happened to have an unrelated ``Filters`` path in its namespace. From 6214ece43aaf6207bd3007822cf7ac0c3f6cefe8 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 6 Apr 2022 09:45:36 +0900 Subject: [PATCH 0823/1246] docs: revise the description to be more accurate The property $component does not exist. --- user_guide_src/source/concepts/factories.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/concepts/factories.rst b/user_guide_src/source/concepts/factories.rst index ff5ea4faf140..569fbaa7db1e 100644 --- a/user_guide_src/source/concepts/factories.rst +++ b/user_guide_src/source/concepts/factories.rst @@ -131,7 +131,7 @@ Factories Behavior Options can be applied in one of three ways (listed in ascending priority): -* A configuration class ``Config\Factory`` with a ``$component`` property. +* A configuration class ``Config\Factory`` with a property that matches the name of a component. * The static method ``Factories::setOptions()``. * Passing options directly at call time with a parameter. From ea781ab2351e1b74bfae71884f90cbf58e3eaa72 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 5 Apr 2022 17:58:37 +0900 Subject: [PATCH 0824/1246] chore: update composer scripts --- composer.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index 8d77bc48cde8..2a0329252a46 100644 --- a/composer.json +++ b/composer.json @@ -62,14 +62,14 @@ "analyze": "phpstan analyse", "test": "phpunit", "cs": [ - "php-cs-fixer fix --verbose --dry-run --diff --config=.user-guide.php-cs-fixer.dist.php", - "php-cs-fixer fix --verbose --dry-run --diff --config=.no-header.php-cs-fixer.dist.php", - "php-cs-fixer fix --verbose --dry-run --diff" + "php-cs-fixer fix --ansi --verbose --dry-run --diff --config=.php-cs-fixer.user-guide.php", + "php-cs-fixer fix --ansi --verbose --dry-run --diff --config=.php-cs-fixer.no-header.php", + "php-cs-fixer fix --ansi --verbose --dry-run --diff" ], "cs-fix": [ - "php-cs-fixer fix --verbose --diff --config=.user-guide.php-cs-fixer.dist.php", - "php-cs-fixer fix --verbose --diff --config=.no-header.php-cs-fixer.dist.php", - "php-cs-fixer fix --verbose --diff" + "php-cs-fixer fix --ansi --verbose --diff --config=.php-cs-fixer.user-guide.php", + "php-cs-fixer fix --ansi --verbose --diff --config=.php-cs-fixer.no-header.php", + "php-cs-fixer fix --ansi --verbose --diff" ] }, "scripts-descriptions": { From c01667dbe1eff42313cdf115003cd4a65eef2e5b Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 6 Apr 2022 17:28:08 +0900 Subject: [PATCH 0825/1246] docs: fix by proofreading Co-authored-by: John Paul E. Balandan, CPA <51850998+paulbalandan@users.noreply.github.com> --- user_guide_src/source/concepts/factories.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/concepts/factories.rst b/user_guide_src/source/concepts/factories.rst index 569fbaa7db1e..62d40b3352c9 100644 --- a/user_guide_src/source/concepts/factories.rst +++ b/user_guide_src/source/concepts/factories.rst @@ -9,7 +9,7 @@ Factories Introduction ============ -What is Factories? +What are Factories? ------------------ Like :doc:`./services`, **Factories** are an extension of autoloading that helps keep your code From cd2abe85e60626a26cfc5cbcbfc6517ef15515f7 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 6 Apr 2022 17:29:04 +0900 Subject: [PATCH 0826/1246] docs: fix by proofreading Co-authored-by: John Paul E. Balandan, CPA <51850998+paulbalandan@users.noreply.github.com> --- user_guide_src/source/concepts/factories.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/user_guide_src/source/concepts/factories.rst b/user_guide_src/source/concepts/factories.rst index 62d40b3352c9..d33c49e2398b 100644 --- a/user_guide_src/source/concepts/factories.rst +++ b/user_guide_src/source/concepts/factories.rst @@ -27,10 +27,10 @@ make sure the correct configuration is loaded when using the ``Config`` class. Differences from Services ------------------------- -Factories require a concrete class name to instantiate, and do not have code to create instances. +Factories require a concrete class name to instantiate and do not have code to create instances. -So Factories are not good for creating complex instance that needs many dependencies, -and cannot change the class of the instance to be returned. +So, Factories are not good for creating a complex instance that needs many dependencies, +and you cannot change the class of the instance to be returned. On the other hand, Services have code to create instances, so it can create a complex instance that needs other services or class instances. When you get a service, Services require a service name, From 9dd0e02d0feda051865e99383ab775da6937b762 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 6 Apr 2022 17:29:23 +0900 Subject: [PATCH 0827/1246] docs: fix by proofreading Co-authored-by: John Paul E. Balandan, CPA <51850998+paulbalandan@users.noreply.github.com> --- user_guide_src/source/concepts/factories.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/concepts/factories.rst b/user_guide_src/source/concepts/factories.rst index d33c49e2398b..138b73c1342e 100644 --- a/user_guide_src/source/concepts/factories.rst +++ b/user_guide_src/source/concepts/factories.rst @@ -55,7 +55,7 @@ Or you could also request a specific class: If you have only ``Blog\Models\UserModel``, the instance will be returned. But if you have both ``App\Models\UserModel`` and ``Blog\Models\UserModel``, -The instance of ``App\Models\UserModel`` will be returned. +the instance of ``App\Models\UserModel`` will be returned. If you want to get ``Blog\Models\UserModel``, you need to disable the option ``preferApp``: From 1b1d03c6363bb0db9b0a935440d791fce2f54859 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 6 Apr 2022 17:31:59 +0900 Subject: [PATCH 0828/1246] docs: fix by proofreading Co-authored-by: John Paul E. Balandan, CPA <51850998+paulbalandan@users.noreply.github.com> --- user_guide_src/source/concepts/services.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/concepts/services.rst b/user_guide_src/source/concepts/services.rst index b69a4e4c4f85..632ad10cedf0 100644 --- a/user_guide_src/source/concepts/services.rst +++ b/user_guide_src/source/concepts/services.rst @@ -115,7 +115,7 @@ In some instances, you will want the option to pass a setting to the class durin Since the services file is a very simple class, it is easy to make this work. A good example is the ``renderer`` service. By default, we want this class to be able -to find the views at ``APPPATH . views/``. We want the developer to have the option of +to find the views at ``APPPATH . 'views/'``. We want the developer to have the option of changing that path, though, if their needs require it. So the class accepts the ``$viewPath`` as a constructor parameter. The service method looks like this: From 606518ac686abfe275a40727f747199c8d921e60 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 6 Apr 2022 17:33:37 +0900 Subject: [PATCH 0829/1246] docs: fix by proofreading Co-authored-by: John Paul E. Balandan, CPA <51850998+paulbalandan@users.noreply.github.com> --- user_guide_src/source/helpers/filesystem_helper.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/helpers/filesystem_helper.rst b/user_guide_src/source/helpers/filesystem_helper.rst index 017ee9a82149..6d7618b9d783 100644 --- a/user_guide_src/source/helpers/filesystem_helper.rst +++ b/user_guide_src/source/helpers/filesystem_helper.rst @@ -155,7 +155,7 @@ The following functions are available: :param string $sourceDir: Directory path :param bool|null $includePath: Whether to include the path as part of the filename; false for no path, null for the path relative to ``$sourceDir``, true for the full path :param bool $hidden: Whether to include hidden files (files beginning with a period) - :param bool $includeDir: Whether to include directories + :param bool $includeDir: Whether to include directories in the array output :returns: An array of file names :rtype: array From 3fe7b8a45a2455a4cb3b2e7a1e2aa47072f883ba Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 6 Apr 2022 17:44:29 +0900 Subject: [PATCH 0830/1246] docs: add changelog --- user_guide_src/source/changelogs/v4.2.0.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/user_guide_src/source/changelogs/v4.2.0.rst b/user_guide_src/source/changelogs/v4.2.0.rst index 99f980d6b35e..0ed69ab0760a 100644 --- a/user_guide_src/source/changelogs/v4.2.0.rst +++ b/user_guide_src/source/changelogs/v4.2.0.rst @@ -37,6 +37,7 @@ Enhancements - Exception information logged through ``log_message()`` has now improved. It now includes the file and line where the exception originated. It also does not truncate the message anymore. - The log format has also changed. If users are depending on the log format in their apps, the new log format is "<1-based count> (): " - Added support for webp files to **app/Config/Mimes.php**. +- Added 4th parameter ``$includeDir`` to ``get_filenames()``. See :php:func:`get_filenames`. Changes ******* From 9f2d3ced709e1774128b03a9831424d90b26e29f Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 6 Apr 2022 20:23:33 +0900 Subject: [PATCH 0831/1246] docs: fix title underline factories.rst:13: WARNING: Title underline too short. --- user_guide_src/source/concepts/factories.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/concepts/factories.rst b/user_guide_src/source/concepts/factories.rst index 138b73c1342e..754f831257e3 100644 --- a/user_guide_src/source/concepts/factories.rst +++ b/user_guide_src/source/concepts/factories.rst @@ -10,7 +10,7 @@ Introduction ============ What are Factories? ------------------- +------------------- Like :doc:`./services`, **Factories** are an extension of autoloading that helps keep your code concise yet optimal, without having to pass around object instances between classes. From df954fae54dc76873b6a16e883aac791f9f0a48f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Apr 2022 15:05:18 +0000 Subject: [PATCH 0832/1246] chore(deps-dev): update rector/rector requirement Updates the requirements on [rector/rector](https://github.com/rectorphp/rector) to permit the latest version. - [Release notes](https://github.com/rectorphp/rector/releases) - [Commits](https://github.com/rectorphp/rector/compare/0.12.19...0.12.20) --- updated-dependencies: - dependency-name: rector/rector dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8d77bc48cde8..e21ae85ecff3 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "phpstan/phpstan": "^1.0", "phpunit/phpunit": "^9.1", "predis/predis": "^1.1", - "rector/rector": "0.12.19" + "rector/rector": "0.12.20" }, "suggest": { "ext-fileinfo": "Improves mime type detection for files" From 5ee5304c24cc96df3a2d6c3dcf0ca069454da40c Mon Sep 17 00:00:00 2001 From: kenjis Date: Thu, 7 Apr 2022 08:47:57 +0900 Subject: [PATCH 0833/1246] docs: update `spark migrate:status` output --- user_guide_src/source/dbmgmt/migration.rst | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/user_guide_src/source/dbmgmt/migration.rst b/user_guide_src/source/dbmgmt/migration.rst index cd5787328a96..ff81f4ff0708 100644 --- a/user_guide_src/source/dbmgmt/migration.rst +++ b/user_guide_src/source/dbmgmt/migration.rst @@ -162,8 +162,13 @@ You can use (refresh) with the following options: Displays a list of all migrations and the date and time they ran, or '--' if they have not been run:: > php spark migrate:status - Filename Migrated On - First_migration.php 2016-04-25 04:44:22 + +----------------------+-------------------+-----------------------+---------+---------------------+-------+ + | Namespace | Version | Filename | Group | Migrated On | Batch | + +----------------------+-------------------+-----------------------+---------+---------------------+-------+ + | App | 2022-04-06-234508 | CreateCiSessionsTable | default | 2022-04-06 18:45:14 | 2 | + | CodeIgniter\Settings | 2021-07-04-041948 | CreateSettingsTable | default | 2022-04-06 01:23:08 | 1 | + | CodeIgniter\Settings | 2021-11-14-143905 | AddContextColumn | default | 2022-04-06 01:23:08 | 1 | + +----------------------+-------------------+-----------------------+---------+---------------------+-------+ You can use (status) with the following options: From 180dca40ece4a328892bbdbf050f5d7394cec947 Mon Sep 17 00:00:00 2001 From: kenjis Date: Thu, 7 Apr 2022 08:48:31 +0900 Subject: [PATCH 0834/1246] docs: update deprecated command --- user_guide_src/source/libraries/sessions.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/user_guide_src/source/libraries/sessions.rst b/user_guide_src/source/libraries/sessions.rst index 59557db92cf8..11ac22f12add 100644 --- a/user_guide_src/source/libraries/sessions.rst +++ b/user_guide_src/source/libraries/sessions.rst @@ -569,10 +569,10 @@ You can choose the Database group to use by adding a new line to the .. literalinclude:: sessions/040.php -If you'd rather not do all of this by hand, you can use the ``session:migration`` command +If you'd rather not do all of this by hand, you can use the ``make:migration --session`` command from the cli to generate a migration file for you:: - > php spark session:migration + > php spark make:migration --session > php spark migrate This command will take the **sessionSavePath** and **sessionMatchIP** settings into account From 7b58b7217eb556d2e91edae5f8b5813abfb16f59 Mon Sep 17 00:00:00 2001 From: kenjis Date: Thu, 7 Apr 2022 13:27:54 +0900 Subject: [PATCH 0835/1246] chore: update gitattributes --- .gitattributes | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitattributes b/.gitattributes index 79c65323dade..de04ad191549 100644 --- a/.gitattributes +++ b/.gitattributes @@ -14,17 +14,23 @@ contributing/ export-ignore .editorconfig export-ignore .nojekyll export-ignore export-ignore CODE_OF_CONDUCT.md export-ignore +CONTRIBUTING.md export-ignore PULL_REQUEST_TEMPLATE.md export-ignore stale.yml export-ignore Vagrantfile.dist export-ignore # They don't want our test files +tests/AutoReview/ export-ignore tests/system/ export-ignore utils/ export-ignore +depfile.yaml export-ignore rector.php export-ignore phpunit.xml.dist export-ignore +phpstan-baseline.neon.dist export-ignore phpstan.neon.dist export-ignore .php-cs-fixer.dist.php export-ignore +.php-cs-fixer.no-header.php export-ignore +.php-cs-fixer.user-guide.php export-ignore # The source user guide, either user_guide_src/ export-ignore From 53cdb671b8b4e04b7d4a0752dd3b6046819abb52 Mon Sep 17 00:00:00 2001 From: "Michael R. Krisnadhi" Date: Fri, 8 Apr 2022 16:08:14 +0700 Subject: [PATCH 0836/1246] clarify Models user guide Inform the $useAutoIncrement default value (which is 'true'), so developers would be aware of that option if they don't use auto-incremented INT's on primary keys, especially when triggering an 'afterInsert' event which will eventually cause the $data['id'] value to be 0 instead of the actual primary key (see 'system/Model.php' line 254 : https://github.com/codeigniter4/CodeIgniter4/blob/622d50aa2976b85f7cb1479faec7558cd9ec2341/system/Model.php#L254) --- user_guide_src/source/models/model.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/user_guide_src/source/models/model.rst b/user_guide_src/source/models/model.rst index f55e60656c03..fa354d7c3aff 100644 --- a/user_guide_src/source/models/model.rst +++ b/user_guide_src/source/models/model.rst @@ -99,7 +99,8 @@ is used with methods like ``find()`` to know what column to match the specified Specifies if the table uses an auto-increment feature for ``$primaryKey``. If set to ``false`` then you are responsible for providing primary key value for every record in the table. This -feature may be handy when we want to implement 1:1 relation or use UUIDs for our model. +feature may be handy when we want to implement 1:1 relation or use UUIDs for our model. The +default value is ``true``. .. note:: If you set ``$useAutoIncrement`` to ``false``, then make sure to set your primary key in the database to ``unique``. This way you will make sure that all of Model's features From 3fc0c6b61bd318f73090cf1cc672ba303c7b09b2 Mon Sep 17 00:00:00 2001 From: Toto Prayogo Date: Fri, 8 Apr 2022 20:34:42 +0700 Subject: [PATCH 0837/1246] add `literalinclude` for curlrequest -> debug --- user_guide_src/source/libraries/curlrequest.rst | 2 +- user_guide_src/source/libraries/curlrequest/034.php | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 user_guide_src/source/libraries/curlrequest/034.php diff --git a/user_guide_src/source/libraries/curlrequest.rst b/user_guide_src/source/libraries/curlrequest.rst index 3d0b91b511fb..b77d41e6b088 100644 --- a/user_guide_src/source/libraries/curlrequest.rst +++ b/user_guide_src/source/libraries/curlrequest.rst @@ -219,7 +219,7 @@ script execution. This is done by passing CURLOPT_VERBOSE and echoing the output server via ``spark serve`` you will see the output in the console. Otherwise, the output will be written to the server's error log. - $response->request('GET', 'http://example.com', ['debug' => true]); +.. literalinclude:: curlrequest/034.php You can pass a filename as the value for debug to have the output written to a file: diff --git a/user_guide_src/source/libraries/curlrequest/034.php b/user_guide_src/source/libraries/curlrequest/034.php new file mode 100644 index 000000000000..1560cd589fec --- /dev/null +++ b/user_guide_src/source/libraries/curlrequest/034.php @@ -0,0 +1,3 @@ +request('GET', 'http://example.com', ['debug' => true]); From fc8946faf361a6571beccba1b054fd33ecae581a Mon Sep 17 00:00:00 2001 From: Toto Prayogo Date: Fri, 8 Apr 2022 20:44:35 +0700 Subject: [PATCH 0838/1246] fix parameters display for API response > `setResponseFormat($format)` method --- user_guide_src/source/outgoing/api_responses.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/outgoing/api_responses.rst b/user_guide_src/source/outgoing/api_responses.rst index 6d657e6bc765..bdb853563e2b 100644 --- a/user_guide_src/source/outgoing/api_responses.rst +++ b/user_guide_src/source/outgoing/api_responses.rst @@ -60,7 +60,7 @@ Class Reference *************** .. php:method:: setResponseFormat($format) - :param string $format The type of response to return, either ``json`` or ``xml`` + :param string $format: The type of response to return, either ``json`` or ``xml`` This defines the format to be used when formatting arrays in responses. If you provide a ``null`` value for ``$format``, it will be automatically determined through content negotiation. From 5161942e2c0211698ff7242f5df9d8e8aef1e757 Mon Sep 17 00:00:00 2001 From: Toto Prayogo Date: Fri, 8 Apr 2022 21:07:41 +0700 Subject: [PATCH 0839/1246] fix paths --- user_guide_src/source/general/managing_apps.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/general/managing_apps.rst b/user_guide_src/source/general/managing_apps.rst index 0681b1b534e6..fc00dcd06985 100644 --- a/user_guide_src/source/general/managing_apps.rst +++ b/user_guide_src/source/general/managing_apps.rst @@ -25,7 +25,7 @@ your main **app/Config/Paths.php** and set a *full server path* in the You will need to modify two additional files in your project root, so that they can find the **Paths** configuration file: -- **/spark** runs command line apps; the path is specified on or about line 35: +- **/spark** runs command line apps; the path is specified on or about line 49: .. literalinclude:: managing_apps/002.php From 571923915b7b431d055407f51c1201a1979f2da9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Apr 2022 15:03:24 +0000 Subject: [PATCH 0840/1246] chore(deps): bump actions/upload-artifact from 2 to 3 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 2 to 3. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/deploy-userguide-latest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-userguide-latest.yml b/.github/workflows/deploy-userguide-latest.yml index fb453f0c9694..8fc77b9f7698 100644 --- a/.github/workflows/deploy-userguide-latest.yml +++ b/.github/workflows/deploy-userguide-latest.yml @@ -29,7 +29,7 @@ jobs: # Create an artifact of the html output - name: Upload artifact - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: HTML Documentation path: user_guide_src/build/html/ From 022563377e7e995fc7b6845e4a8e026d545ee876 Mon Sep 17 00:00:00 2001 From: Toto Prayogo Date: Sat, 9 Apr 2022 03:44:19 +0700 Subject: [PATCH 0841/1246] change `$request->` to `$client->` --- user_guide_src/source/libraries/curlrequest/020.php | 2 +- user_guide_src/source/libraries/curlrequest/021.php | 2 +- user_guide_src/source/libraries/curlrequest/022.php | 2 +- user_guide_src/source/libraries/curlrequest/023.php | 2 +- user_guide_src/source/libraries/curlrequest/030.php | 2 +- user_guide_src/source/libraries/curlrequest/031.php | 2 +- user_guide_src/source/libraries/curlrequest/034.php | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/user_guide_src/source/libraries/curlrequest/020.php b/user_guide_src/source/libraries/curlrequest/020.php index 6e0b1e3726a7..14fad31cdea4 100644 --- a/user_guide_src/source/libraries/curlrequest/020.php +++ b/user_guide_src/source/libraries/curlrequest/020.php @@ -1,3 +1,3 @@ request('GET', 'http://example.com', ['connect_timeout' => 0]); +$client->request('GET', 'http://example.com', ['connect_timeout' => 0]); diff --git a/user_guide_src/source/libraries/curlrequest/021.php b/user_guide_src/source/libraries/curlrequest/021.php index 4acf82aa9e0b..051df32e1a37 100644 --- a/user_guide_src/source/libraries/curlrequest/021.php +++ b/user_guide_src/source/libraries/curlrequest/021.php @@ -1,3 +1,3 @@ request('GET', 'http://example.com', ['cookie' => WRITEPATH . 'CookieSaver.txt']); +$client->request('GET', 'http://example.com', ['cookie' => WRITEPATH . 'CookieSaver.txt']); diff --git a/user_guide_src/source/libraries/curlrequest/022.php b/user_guide_src/source/libraries/curlrequest/022.php index 6acbcf0a7784..69b0e4ed8bec 100644 --- a/user_guide_src/source/libraries/curlrequest/022.php +++ b/user_guide_src/source/libraries/curlrequest/022.php @@ -1,3 +1,3 @@ request('GET', 'http://example.com', ['debug' => '/usr/local/curl_log.txt']); +$client->request('GET', 'http://example.com', ['debug' => '/usr/local/curl_log.txt']); diff --git a/user_guide_src/source/libraries/curlrequest/023.php b/user_guide_src/source/libraries/curlrequest/023.php index b6846257ad83..61e6f6df5214 100644 --- a/user_guide_src/source/libraries/curlrequest/023.php +++ b/user_guide_src/source/libraries/curlrequest/023.php @@ -1,4 +1,4 @@ request('GET', 'http://example.com', ['delay' => 2000]); +$client->request('GET', 'http://example.com', ['delay' => 2000]); diff --git a/user_guide_src/source/libraries/curlrequest/030.php b/user_guide_src/source/libraries/curlrequest/030.php index 83bf718e33e4..16c0c6fd6c49 100644 --- a/user_guide_src/source/libraries/curlrequest/030.php +++ b/user_guide_src/source/libraries/curlrequest/030.php @@ -1,3 +1,3 @@ request('GET', 'http://example.com', ['timeout' => 5]); +$client->request('GET', 'http://example.com', ['timeout' => 5]); diff --git a/user_guide_src/source/libraries/curlrequest/031.php b/user_guide_src/source/libraries/curlrequest/031.php index 1709d6d90b9c..8023c84faa39 100644 --- a/user_guide_src/source/libraries/curlrequest/031.php +++ b/user_guide_src/source/libraries/curlrequest/031.php @@ -1,3 +1,3 @@ request('GET', 'http://example.com', ['user_agent' => 'CodeIgniter Framework v4']); +$client->request('GET', 'http://example.com', ['user_agent' => 'CodeIgniter Framework v4']); diff --git a/user_guide_src/source/libraries/curlrequest/034.php b/user_guide_src/source/libraries/curlrequest/034.php index 1560cd589fec..9e343aa9d9da 100644 --- a/user_guide_src/source/libraries/curlrequest/034.php +++ b/user_guide_src/source/libraries/curlrequest/034.php @@ -1,3 +1,3 @@ request('GET', 'http://example.com', ['debug' => true]); +$client->request('GET', 'http://example.com', ['debug' => true]); From 830750edd49d9fe5219ff2f581afdfec63e93c56 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 9 Apr 2022 09:04:37 +0900 Subject: [PATCH 0842/1246] feat: throws exception when controller name in routes contains `/` --- system/Language/en/Router.php | 1 + system/Router/Exceptions/RouterException.php | 10 ++++++++++ system/Router/Router.php | 5 +++++ tests/system/Router/RouterTest.php | 12 ++++++++++++ 4 files changed, 28 insertions(+) diff --git a/system/Language/en/Router.php b/system/Language/en/Router.php index 90aaa132b489..7d0b5cc99e25 100644 --- a/system/Language/en/Router.php +++ b/system/Language/en/Router.php @@ -14,4 +14,5 @@ 'invalidParameter' => 'A parameter does not match the expected type.', 'missingDefaultRoute' => 'Unable to determine what should be displayed. A default route has not been specified in the routing file.', 'invalidDynamicController' => 'A dynamic controller is not allowed for security reasons. Route handler: {0}', + 'invalidControllerName' => 'The namespace delimiter is a backslash (\), not a slash (/). Route handler: {0}', ]; diff --git a/system/Router/Exceptions/RouterException.php b/system/Router/Exceptions/RouterException.php index b50042b3421b..5a510e4716fe 100644 --- a/system/Router/Exceptions/RouterException.php +++ b/system/Router/Exceptions/RouterException.php @@ -68,4 +68,14 @@ public static function forDynamicController(string $handler) { return new static(lang('Router.invalidDynamicController', [$handler])); } + + /** + * Throw when controller name has `/`. + * + * @return RouterException + */ + public static function forInvalidControllerName(string $handler) + { + return new static(lang('Router.invalidControllerName', [$handler])); + } } diff --git a/system/Router/Router.php b/system/Router/Router.php index 42f2eb0c7a42..37c88114172e 100644 --- a/system/Router/Router.php +++ b/system/Router/Router.php @@ -426,6 +426,11 @@ protected function checkRoutes(string $uri): bool throw RouterException::forDynamicController($handler); } + // Checks `/` in controller name + if (strpos($controller, '/') !== false) { + throw RouterException::forInvalidControllerName($handler); + } + if (strpos($routeKey, '/') !== false) { $replacekey = str_replace('/(.*)', '', $routeKey); $handler = preg_replace('#^' . $routeKey . '$#u', $handler, $uri); diff --git a/tests/system/Router/RouterTest.php b/tests/system/Router/RouterTest.php index d3ca04422c41..38eb9b7ba48c 100644 --- a/tests/system/Router/RouterTest.php +++ b/tests/system/Router/RouterTest.php @@ -61,6 +61,7 @@ protected function setUp(): void 'closure/(:num)/(:alpha)' => static fn ($num, $str) => $num . '-' . $str, '{locale}/pages' => 'App\Pages::list_all', 'admin/admins' => 'App\Admin\Admins::list_all', + 'admin/admins/edit/(:any)' => 'App/Admin/Admins::edit_show/$1', '/some/slash' => 'App\Slash::index', 'objects/(:segment)/sort/(:segment)/([A-Z]{3,7})' => 'AdminList::objectsSortCreate/$1/$2/$3', '(:segment)/(:segment)/(:segment)' => '$2::$3/$1', @@ -402,6 +403,17 @@ public function testRouteResource() $this->assertSame('list_all', $router->methodName()); } + public function testRouteWithSlashInControllerName() + { + $this->expectExceptionMessage( + 'The namespace delimiter is a backslash (\), not a slash (/). Route handler: \App/Admin/Admins::edit_show/$1' + ); + + $router = new Router($this->collection, $this->request); + + $router->handle('admin/admins/edit/1'); + } + public function testRouteWithLeadingSlash() { $router = new Router($this->collection, $this->request); From 1640b8f89b069d66d1318768371ab0ed9cb554bf Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 9 Apr 2022 09:29:24 +0900 Subject: [PATCH 0843/1246] docs: fix heading level --- user_guide_src/source/outgoing/api_responses.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/user_guide_src/source/outgoing/api_responses.rst b/user_guide_src/source/outgoing/api_responses.rst index bdb853563e2b..0500a8ee92dd 100644 --- a/user_guide_src/source/outgoing/api_responses.rst +++ b/user_guide_src/source/outgoing/api_responses.rst @@ -56,8 +56,10 @@ So, if your request asks for JSON formatted data in an **Accept** header, the da ``respond*`` or ``fail*`` methods will be formatted by the ``CodeIgniter\Format\JSONFormatter`` class. The resulting JSON data will be sent back to the client. +*************** Class Reference *************** + .. php:method:: setResponseFormat($format) :param string $format: The type of response to return, either ``json`` or ``xml`` From 7c137dc250553cb118435d50a52b03e48beeab65 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 9 Apr 2022 09:46:23 +0900 Subject: [PATCH 0844/1246] docs: add TOC --- user_guide_src/source/installation/upgrade_4xx.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/user_guide_src/source/installation/upgrade_4xx.rst b/user_guide_src/source/installation/upgrade_4xx.rst index 03d72ac160eb..2166dda681a4 100644 --- a/user_guide_src/source/installation/upgrade_4xx.rst +++ b/user_guide_src/source/installation/upgrade_4xx.rst @@ -25,6 +25,10 @@ them one by one. **Do read the user guide** before embarking on a project conversion! +.. contents:: + :local: + :depth: 2 + General Adjustments =================== From fd6c6e5378c9358bd92713ee0d0f9d043e0fffcc Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 9 Apr 2022 09:46:45 +0900 Subject: [PATCH 0845/1246] docs: fix heading underlines --- .../source/installation/upgrade_4xx.rst | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/user_guide_src/source/installation/upgrade_4xx.rst b/user_guide_src/source/installation/upgrade_4xx.rst index 2166dda681a4..a97a2e339a29 100644 --- a/user_guide_src/source/installation/upgrade_4xx.rst +++ b/user_guide_src/source/installation/upgrade_4xx.rst @@ -30,18 +30,21 @@ them one by one. :depth: 2 General Adjustments -=================== +******************* -**Downloads** +Downloads +========= - CI4 is still available as a ready-to-run zip or tarball. - It can also be installed using Composer. -**Namespaces** +Namespaces +========== - CI4 is built for PHP 7.4+, and everything in the framework is namespaced, except for the helpers. -**Application Structure** +Application Structure +===================== - The **application** folder is renamed as **app** and the framework still has **system** folders, with the same interpretation as before. @@ -52,7 +55,8 @@ General Adjustments - There is no longer a nested **application/core** folder, as we have a different mechanism for extending framework components (see below). -**Model, View and Controller** +Model, View and Controller +========================== - CodeIgniter is based on the MVC concept. Thus, the changes on the Model, View and Controller are one of the most important things you have to handle. @@ -75,7 +79,8 @@ General Adjustments upgrade_views upgrade_controllers -**Class loading** +Class Loading +============= - There is no longer a CodeIgniter "superobject", with framework component references magically injected as properties of your controller. @@ -87,27 +92,31 @@ General Adjustments - You can configure the class loading to support whatever application structure you are most comfortable with, including the "HMVC" style. -**Libraries** +Libraries +========= - Your app classes can still go inside **app/Libraries**, but they don't have to. - Instead of CI3's ``$this->load->library(x);`` you can now use ``$this->x = new X();``, following namespaced conventions for your component. -**Helpers** +Helpers +======= - Helpers are pretty much the same as before, though some have been simplified. - In CI4, ``redirect()`` returns a ``RedirectResponse`` instance instead of redirecting and terminating script execution. You must return it. - `redirect() Documentation CodeIgniter 3.X `_ - `redirect() Documentation CodeIgniter 4.X <../general/common_functions.html#redirect>`_ -**Events** +Events +====== - Hooks have been replaced by Events. - Instead of CI3's ``$hook['post_controller_constructor']`` you now use ``Events::on('post_controller_constructor', ['MyClass', 'MyFunction']);``, with the namespace ``CodeIgniter\Events\Events;``. - Events are always enabled, and are available globally. -**Extending the framework** +Extending the Framework +======================= - You don't need a **core** folder to hold ``MY_...`` framework component extensions or replacements. @@ -118,7 +127,7 @@ General Adjustments your components instead of the default ones. Upgrading Libraries -=================== +******************* - Your app classes can still go inside **app/Libraries**, but they don't have to. - Instead of CI3's ``$this->load->library(x);`` you can now use ``$this->x = new X();``, From ab0d86b96726e89ce3a27b87d45190c7ea8b7968 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 9 Apr 2022 10:43:07 +0900 Subject: [PATCH 0846/1246] docs: add link to the detailed page --- user_guide_src/source/changelogs/v4.2.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/changelogs/v4.2.0.rst b/user_guide_src/source/changelogs/v4.2.0.rst index 0ed69ab0760a..c0081761ffd4 100644 --- a/user_guide_src/source/changelogs/v4.2.0.rst +++ b/user_guide_src/source/changelogs/v4.2.0.rst @@ -27,7 +27,7 @@ Enhancements - Added the config ``$autoNonce`` in ``Config\ContentSecurityPolicy`` to disable the CSP placeholder replacement - Added the functions ``csp_script_nonce()`` and ``csp_style_nonce()`` to get nonce attributes - See :ref:`content-security-policy` for details. -- New View Decorators allow modifying the generated HTML prior to caching. +- New :doc:`../outgoing/view_decorators` allow modifying the generated HTML prior to caching. - Added Subqueries in the FROM section. See :ref:`query-builder-from-subquery`. - Added Subqueries in the SELECT section. See :ref:`query-builder-select`. - Added Validation Strict Rules. See :ref:`validation-traditional-and-strict-rules`. From 7f595062e2111b39a10a5300eca45cf8076908e8 Mon Sep 17 00:00:00 2001 From: Chl Date: Fri, 8 Apr 2022 23:31:04 +0200 Subject: [PATCH 0847/1246] script_tag: cosmetic for value-less attributes Some attributes are usually written without values, for example : `'; + return $script . 'type="text/javascript">'; } } diff --git a/tests/system/Helpers/HTMLHelperTest.php b/tests/system/Helpers/HTMLHelperTest.php index b3ed47d0c3e6..74b087228fdd 100755 --- a/tests/system/Helpers/HTMLHelperTest.php +++ b/tests/system/Helpers/HTMLHelperTest.php @@ -248,6 +248,27 @@ public function testScriptTagWithIndexpage() $this->assertSame($expected, script_tag($target, true)); } + public function testScriptTagWithSrc() + { + $target = ['src' => 'http://site.com/js/mystyles.js']; + $expected = ''; + $this->assertSame($expected, script_tag($target)); + } + + public function testScriptTagWithSrcWithoutProtocol() + { + $target = ['src' => 'js/mystyles.js']; + $expected = ''; + $this->assertSame($expected, script_tag($target)); + } + + public function testScriptTagWithSrcAndAttributes() + { + $target = ['src' => 'js/mystyles.js', 'charset' => 'UTF-8', 'defer' => '', 'async' => null]; + $expected = ''; + $this->assertSame($expected, script_tag($target)); + } + public function testLinkTag() { $target = 'css/mystyles.css'; diff --git a/user_guide_src/source/helpers/html_helper/011.php b/user_guide_src/source/helpers/html_helper/011.php index 126fd86c4952..f47bb7053770 100644 --- a/user_guide_src/source/helpers/html_helper/011.php +++ b/user_guide_src/source/helpers/html_helper/011.php @@ -1,6 +1,6 @@ 'js/printer.js']; +$script = ['src' => 'js/printer.js', 'defer' => null]; echo script_tag($script); -// +// From a8d5b894c9ae17f1a8c8721eae44c0da22bec87c Mon Sep 17 00:00:00 2001 From: Chl Date: Sun, 10 Apr 2022 03:10:15 +0200 Subject: [PATCH 0848/1246] coding style: cs-fixer is_null() rule --- system/Helpers/html_helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/Helpers/html_helper.php b/system/Helpers/html_helper.php index 0fc2f110399f..a15b18ff47e8 100755 --- a/system/Helpers/html_helper.php +++ b/system/Helpers/html_helper.php @@ -208,7 +208,7 @@ function script_tag($src = '', bool $indexPage = false): string } } else { // for attributes without values, like async or defer, use NULL. - $script .= $k . (is_null($v) ? ' ' : '="' . $v . '" '); + $script .= $k . (null === $v ? ' ' : '="' . $v . '" '); } } From 16dde2391c09e725ea852685f41488d83d26f0d4 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 12 Apr 2022 18:16:27 +0900 Subject: [PATCH 0849/1246] fix: add Escaper Exception classes in $coreClassmap --- system/Config/AutoloadConfig.php | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/system/Config/AutoloadConfig.php b/system/Config/AutoloadConfig.php index 13a6721fd2e6..79cad2ab8d25 100644 --- a/system/Config/AutoloadConfig.php +++ b/system/Config/AutoloadConfig.php @@ -12,6 +12,9 @@ namespace CodeIgniter\Config; use Laminas\Escaper\Escaper; +use Laminas\Escaper\Exception\ExceptionInterface; +use Laminas\Escaper\Exception\InvalidArgumentException as EscaperInvalidArgumentException; +use Laminas\Escaper\Exception\RuntimeException; use Psr\Log\AbstractLogger; use Psr\Log\InvalidArgumentException; use Psr\Log\LoggerAwareInterface; @@ -103,15 +106,18 @@ class AutoloadConfig * @var array */ protected $coreClassmap = [ - AbstractLogger::class => SYSTEMPATH . 'ThirdParty/PSR/Log/AbstractLogger.php', - InvalidArgumentException::class => SYSTEMPATH . 'ThirdParty/PSR/Log/InvalidArgumentException.php', - LoggerAwareInterface::class => SYSTEMPATH . 'ThirdParty/PSR/Log/LoggerAwareInterface.php', - LoggerAwareTrait::class => SYSTEMPATH . 'ThirdParty/PSR/Log/LoggerAwareTrait.php', - LoggerInterface::class => SYSTEMPATH . 'ThirdParty/PSR/Log/LoggerInterface.php', - LoggerTrait::class => SYSTEMPATH . 'ThirdParty/PSR/Log/LoggerTrait.php', - LogLevel::class => SYSTEMPATH . 'ThirdParty/PSR/Log/LogLevel.php', - NullLogger::class => SYSTEMPATH . 'ThirdParty/PSR/Log/NullLogger.php', - Escaper::class => SYSTEMPATH . 'ThirdParty/Escaper/Escaper.php', + AbstractLogger::class => SYSTEMPATH . 'ThirdParty/PSR/Log/AbstractLogger.php', + InvalidArgumentException::class => SYSTEMPATH . 'ThirdParty/PSR/Log/InvalidArgumentException.php', + LoggerAwareInterface::class => SYSTEMPATH . 'ThirdParty/PSR/Log/LoggerAwareInterface.php', + LoggerAwareTrait::class => SYSTEMPATH . 'ThirdParty/PSR/Log/LoggerAwareTrait.php', + LoggerInterface::class => SYSTEMPATH . 'ThirdParty/PSR/Log/LoggerInterface.php', + LoggerTrait::class => SYSTEMPATH . 'ThirdParty/PSR/Log/LoggerTrait.php', + LogLevel::class => SYSTEMPATH . 'ThirdParty/PSR/Log/LogLevel.php', + NullLogger::class => SYSTEMPATH . 'ThirdParty/PSR/Log/NullLogger.php', + ExceptionInterface::class => SYSTEMPATH . 'ThirdParty/Escaper/Exception/ExceptionInterface.php', + EscaperInvalidArgumentException::class => SYSTEMPATH . 'ThirdParty/Escaper/Exception/InvalidArgumentException.php', + RuntimeException::class => SYSTEMPATH . 'ThirdParty/Escaper/Exception/RuntimeException.php', + Escaper::class => SYSTEMPATH . 'ThirdParty/Escaper/Escaper.php', ]; /** From 61999b0205bb76825027d394ce54e00bf72eac16 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 13 Apr 2022 11:57:03 +0900 Subject: [PATCH 0850/1246] fix: multiple CLI::color() inside CLI::write() change color of strings that shouldn't be affected --- system/CLI/CLI.php | 75 ++++++++++++++++++++++++------------ tests/system/CLI/CLITest.php | 22 ++++++++++- 2 files changed, 71 insertions(+), 26 deletions(-) diff --git a/system/CLI/CLI.php b/system/CLI/CLI.php index 347a894f7578..4a55d2f7ef00 100644 --- a/system/CLI/CLI.php +++ b/system/CLI/CLI.php @@ -473,6 +473,10 @@ public static function color(string $text, string $foreground, ?string $backgrou return $text; } + if ($text === '') { + return $text; + } + if (! array_key_exists($foreground, static::$foreground_colors)) { throw CLIException::forInvalidColor('foreground', $foreground); } @@ -481,6 +485,51 @@ public static function color(string $text, string $foreground, ?string $backgrou throw CLIException::forInvalidColor('background', $background); } + // Reset text + $newText = ''; + + // Detect if color method was already in use with this text + if (strpos($text, "\033[0m") !== false) { + $pattern = '/\\033\\[0;.+?\\033\\[0m/u'; + + preg_match_all($pattern, $text, $matches); + $coloredStrings = $matches[0]; + + // No colored string found. Invalid strings with no `\033[0;??`. + if ($coloredStrings === []) { + $newText .= self::getColoredText($text, $foreground, $background, $format); + + return $newText; + } + + $nonColoredText = preg_replace( + $pattern, + '<<__colored_string__>>', + $text + ); + $nonColoredChunks = preg_split( + '/<<__colored_string__>>/u', + $nonColoredText + ); + + foreach ($nonColoredChunks as $i => $chunk) { + if ($chunk !== '') { + $newText .= self::getColoredText($chunk, $foreground, $background, $format); + } + + if (isset($coloredStrings[$i])) { + $newText .= $coloredStrings[$i]; + } + } + } else { + $newText .= self::getColoredText($text, $foreground, $background, $format); + } + + return $newText; + } + + private static function getColoredText(string $text, string $foreground, ?string $background, ?string $format): string + { $string = "\033[" . static::$foreground_colors[$foreground] . 'm'; if ($background !== null) { @@ -491,31 +540,9 @@ public static function color(string $text, string $foreground, ?string $backgrou $string .= "\033[4m"; } - // Detect if color method was already in use with this text - if (strpos($text, "\033[0m") !== false) { - // Split the text into parts so that we can see - // if any part missing the color definition - $chunks = mb_split('\\033\\[0m', $text); - // Reset text - $text = ''; - - foreach ($chunks as $chunk) { - if ($chunk === '') { - continue; - } - - // If chunk doesn't have colors defined we need to add them - if (strpos($chunk, "\033[") === false) { - $chunk = static::color($chunk, $foreground, $background, $format); - // Add color reset before chunk and clear end of the string - $text .= rtrim("\033[0m" . $chunk, "\033[0m"); - } else { - $text .= $chunk; - } - } - } + $string .= $text . "\033[0m"; - return $string . $text . "\033[0m"; + return $string; } /** diff --git a/tests/system/CLI/CLITest.php b/tests/system/CLI/CLITest.php index 107ac1463e67..0c2b81c0b3e4 100644 --- a/tests/system/CLI/CLITest.php +++ b/tests/system/CLI/CLITest.php @@ -122,6 +122,7 @@ public function testColorSupportOnNoColor() CLI::init(); // force re-check on env $this->assertSame('test', CLI::color('test', 'white', 'green')); + putenv($nocolor ? "NO_COLOR={$nocolor}" : 'NO_COLOR'); } @@ -132,6 +133,7 @@ public function testColorSupportOnHyperTerminals() CLI::init(); // force re-check on env $this->assertSame("\033[1;37m\033[42m\033[4mtest\033[0m", CLI::color('test', 'white', 'green', 'underline')); + putenv($termProgram ? "TERM_PROGRAM={$termProgram}" : 'TERM_PROGRAM'); } @@ -190,14 +192,30 @@ public function testWriteForeground() public function testWriteForegroundWithColorBefore() { CLI::write(CLI::color('green', 'green') . ' red', 'red'); - $expected = "\033[0;31m\033[0;32mgreen\033[0m\033[0;31m red\033[0m" . PHP_EOL; + + $expected = "\033[0;32mgreen\033[0m\033[0;31m red\033[0m" . PHP_EOL; $this->assertSame($expected, CITestStreamFilter::$buffer); } public function testWriteForegroundWithColorAfter() { CLI::write('red ' . CLI::color('green', 'green'), 'red'); - $expected = "\033[0;31mred \033[0;32mgreen\033[0m" . PHP_EOL; + + $expected = "\033[0;31mred \033[0m\033[0;32mgreen\033[0m" . PHP_EOL; + $this->assertSame($expected, CITestStreamFilter::$buffer); + } + + /** + * @see https://github.com/codeigniter4/CodeIgniter4/issues/5892 + */ + public function testWriteForegroundWithColorTwice() + { + CLI::write( + CLI::color('green', 'green') . ' red ' . CLI::color('green', 'green'), + 'red' + ); + + $expected = "\033[0;32mgreen\033[0m\033[0;31m red \033[0m\033[0;32mgreen\033[0m" . PHP_EOL; $this->assertSame($expected, CITestStreamFilter::$buffer); } From f406f4aee220b3b85474219b3a4bf0397e914f48 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 13 Apr 2022 12:47:57 +0900 Subject: [PATCH 0851/1246] refactor: vendor/bin/rector process --- system/CLI/CLI.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/system/CLI/CLI.php b/system/CLI/CLI.php index 4a55d2f7ef00..b43d0005ff77 100644 --- a/system/CLI/CLI.php +++ b/system/CLI/CLI.php @@ -497,9 +497,7 @@ public static function color(string $text, string $foreground, ?string $backgrou // No colored string found. Invalid strings with no `\033[0;??`. if ($coloredStrings === []) { - $newText .= self::getColoredText($text, $foreground, $background, $format); - - return $newText; + return $newText . self::getColoredText($text, $foreground, $background, $format); } $nonColoredText = preg_replace( @@ -540,9 +538,7 @@ private static function getColoredText(string $text, string $foreground, ?string $string .= "\033[4m"; } - $string .= $text . "\033[0m"; - - return $string; + return $string . ($text . "\033[0m"); } /** From 7688add69c8b1e5e87daf04e173d937bd09e4f7f Mon Sep 17 00:00:00 2001 From: Pooya Parsa Dadashi Date: Wed, 13 Apr 2022 09:02:52 +0430 Subject: [PATCH 0852/1246] mailPath Alright! --- user_guide_src/source/libraries/email.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/libraries/email.rst b/user_guide_src/source/libraries/email.rst index b610e69a20df..1287f961713a 100644 --- a/user_guide_src/source/libraries/email.rst +++ b/user_guide_src/source/libraries/email.rst @@ -108,7 +108,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. **SMTPHost** No Default None SMTP Server Address. **SMTPUser** No Default None SMTP Username. **SMTPPass** No Default None SMTP Password. From 8995da98a74748cbca558f13addcc422b743cc05 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 13 Apr 2022 21:24:16 +0900 Subject: [PATCH 0853/1246] test: add line breaks --- tests/system/CLI/CLITest.php | 51 +++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/tests/system/CLI/CLITest.php b/tests/system/CLI/CLITest.php index 0c2b81c0b3e4..2f569e5c81c5 100644 --- a/tests/system/CLI/CLITest.php +++ b/tests/system/CLI/CLITest.php @@ -39,18 +39,21 @@ protected function tearDown(): void public function testNew() { $actual = new CLI(); + $this->assertInstanceOf(CLI::class, $actual); } public function testBeep() { $this->expectOutputString("\x07"); + CLI::beep(); } public function testBeep4() { $this->expectOutputString("\x07\x07\x07\x07"); + CLI::beep(4); } @@ -96,6 +99,7 @@ public function testIsWindows() public function testNewLine() { $this->expectOutputString(''); + CLI::newLine(); } @@ -119,8 +123,8 @@ public function testColorSupportOnNoColor() { $nocolor = getenv('NO_COLOR'); putenv('NO_COLOR=1'); - CLI::init(); // force re-check on env + $this->assertSame('test', CLI::color('test', 'white', 'green')); putenv($nocolor ? "NO_COLOR={$nocolor}" : 'NO_COLOR'); @@ -130,8 +134,8 @@ public function testColorSupportOnHyperTerminals() { $termProgram = getenv('TERM_PROGRAM'); putenv('TERM_PROGRAM=Hyper'); - CLI::init(); // force re-check on env + $this->assertSame("\033[1;37m\033[42m\033[4mtest\033[0m", CLI::color('test', 'white', 'green', 'underline')); putenv($termProgram ? "TERM_PROGRAM={$termProgram}" : 'TERM_PROGRAM'); @@ -148,36 +152,41 @@ public function testColor() // After the tests on NO_COLOR and TERM_PROGRAM above, // the $isColored variable is rigged. So we reset this. CLI::init(); - $this->assertSame("\033[1;37m\033[42m\033[4mtest\033[0m", CLI::color('test', 'white', 'green', 'underline')); + + $this->assertSame( + "\033[1;37m\033[42m\033[4mtest\033[0m", + CLI::color('test', 'white', 'green', 'underline') + ); } public function testPrint() { CLI::print('test'); - $expected = 'test'; + $expected = 'test'; $this->assertSame($expected, CITestStreamFilter::$buffer); } public function testPrintForeground() { CLI::print('test', 'red'); - $expected = "\033[0;31mtest\033[0m"; + $expected = "\033[0;31mtest\033[0m"; $this->assertSame($expected, CITestStreamFilter::$buffer); } public function testPrintBackground() { CLI::print('test', 'red', 'green'); - $expected = "\033[0;31m\033[42mtest\033[0m"; + $expected = "\033[0;31m\033[42mtest\033[0m"; $this->assertSame($expected, CITestStreamFilter::$buffer); } public function testWrite() { CLI::write('test'); + $expected = PHP_EOL . 'test' . PHP_EOL; $this->assertSame($expected, CITestStreamFilter::$buffer); } @@ -185,6 +194,7 @@ public function testWrite() public function testWriteForeground() { CLI::write('test', 'red'); + $expected = "\033[0;31mtest\033[0m" . PHP_EOL; $this->assertSame($expected, CITestStreamFilter::$buffer); } @@ -222,6 +232,7 @@ public function testWriteForegroundWithColorTwice() public function testWriteBackground() { CLI::write('test', 'red', 'green'); + $expected = "\033[0;31m\033[42mtest\033[0m" . PHP_EOL; $this->assertSame($expected, CITestStreamFilter::$buffer); } @@ -229,7 +240,9 @@ public function testWriteBackground() public function testError() { $this->stream_filter = stream_filter_append(STDERR, 'CITestStreamFilter'); + CLI::error('test'); + // red expected cuz stderr $expected = "\033[1;31mtest\033[0m" . PHP_EOL; $this->assertSame($expected, CITestStreamFilter::$buffer); @@ -238,7 +251,9 @@ public function testError() public function testErrorForeground() { $this->stream_filter = stream_filter_append(STDERR, 'CITestStreamFilter'); + CLI::error('test', 'purple'); + $expected = "\033[0;35mtest\033[0m" . PHP_EOL; $this->assertSame($expected, CITestStreamFilter::$buffer); } @@ -246,7 +261,9 @@ public function testErrorForeground() public function testErrorBackground() { $this->stream_filter = stream_filter_append(STDERR, 'CITestStreamFilter'); + CLI::error('test', 'purple', 'green'); + $expected = "\033[0;35m\033[42mtest\033[0m" . PHP_EOL; $this->assertSame($expected, CITestStreamFilter::$buffer); } @@ -291,9 +308,18 @@ public function testShowProgressWithoutBar() public function testWrap() { $this->assertSame('', CLI::wrap('')); - $this->assertSame('1234' . PHP_EOL . ' 5678' . PHP_EOL . ' 90' . PHP_EOL . ' abc' . PHP_EOL . ' de' . PHP_EOL . ' fghij' . PHP_EOL . ' 0987654321', CLI::wrap('1234 5678 90' . PHP_EOL . 'abc de fghij' . PHP_EOL . '0987654321', 5, 1)); - $this->assertSame('1234 5678 90' . PHP_EOL . ' abc de fghij' . PHP_EOL . ' 0987654321', CLI::wrap('1234 5678 90' . PHP_EOL . 'abc de fghij' . PHP_EOL . '0987654321', 999, 2)); - $this->assertSame('1234 5678 90' . PHP_EOL . 'abc de fghij' . PHP_EOL . '0987654321', CLI::wrap('1234 5678 90' . PHP_EOL . 'abc de fghij' . PHP_EOL . '0987654321')); + $this->assertSame( + '1234' . PHP_EOL . ' 5678' . PHP_EOL . ' 90' . PHP_EOL . ' abc' . PHP_EOL . ' de' . PHP_EOL . ' fghij' . PHP_EOL . ' 0987654321', + CLI::wrap('1234 5678 90' . PHP_EOL . 'abc de fghij' . PHP_EOL . '0987654321', 5, 1) + ); + $this->assertSame( + '1234 5678 90' . PHP_EOL . ' abc de fghij' . PHP_EOL . ' 0987654321', + CLI::wrap('1234 5678 90' . PHP_EOL . 'abc de fghij' . PHP_EOL . '0987654321', 999, 2) + ); + $this->assertSame( + '1234 5678 90' . PHP_EOL . 'abc de fghij' . PHP_EOL . '0987654321', + CLI::wrap('1234 5678 90' . PHP_EOL . 'abc de fghij' . PHP_EOL . '0987654321') + ); } public function testParseCommand() @@ -305,6 +331,7 @@ public function testParseCommand() ]; $_SERVER['argc'] = 3; CLI::init(); + $this->assertNull(CLI::getSegment(3)); $this->assertSame('b', CLI::getSegment(1)); $this->assertSame('c', CLI::getSegment(2)); @@ -330,6 +357,7 @@ public function testParseCommandMixed() 'sure', ]; CLI::init(); + $this->assertNull(CLI::getSegment(7)); $this->assertSame('b', CLI::getSegment(1)); $this->assertSame('c', CLI::getSegment(2)); @@ -353,6 +381,7 @@ public function testParseCommandOption() 'd', ]; CLI::init(); + $this->assertSame(['parm' => 'pvalue'], CLI::getOptions()); $this->assertSame('pvalue', CLI::getOption('parm')); $this->assertSame('-parm pvalue ', CLI::getOptionString()); @@ -377,6 +406,7 @@ public function testParseCommandMultipleOptions() 'value 3', ]; CLI::init(); + $this->assertSame(['parm' => 'pvalue', 'p2' => null, 'p3' => 'value 3'], CLI::getOptions()); $this->assertSame('pvalue', CLI::getOption('parm')); $this->assertSame('-parm pvalue -p2 -p3 "value 3" ', CLI::getOptionString()); @@ -391,11 +421,13 @@ public function testWindow() $height = new ReflectionProperty(CLI::class, 'height'); $height->setAccessible(true); $height->setValue(null); + $this->assertIsInt(CLI::getHeight()); $width = new ReflectionProperty(CLI::class, 'width'); $width->setAccessible(true); $width->setValue(null); + $this->assertIsInt(CLI::getWidth()); } @@ -409,6 +441,7 @@ public function testWindow() public function testTable($tbody, $thead, $expected) { CLI::table($tbody, $thead); + $this->assertSame(CITestStreamFilter::$buffer, $expected); } From 1b26129b2443f7a083968b9bcf8f111e093878a5 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 13 Apr 2022 21:28:55 +0900 Subject: [PATCH 0854/1246] test: add test --- tests/system/CLI/CLITest.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/system/CLI/CLITest.php b/tests/system/CLI/CLITest.php index 2f569e5c81c5..a8452cdfa7a6 100644 --- a/tests/system/CLI/CLITest.php +++ b/tests/system/CLI/CLITest.php @@ -159,6 +159,14 @@ public function testColor() ); } + public function testColorEmtpyString() + { + $this->assertSame( + '', + CLI::color('', 'white', 'green', 'underline') + ); + } + public function testPrint() { CLI::print('test'); From 768dd238f5eb85a516668f89bde8fc620e0a8022 Mon Sep 17 00:00:00 2001 From: kenjis Date: Thu, 14 Apr 2022 17:05:07 +0900 Subject: [PATCH 0855/1246] docs: improve Managing your Applications - add note for composer.json autoload.psr-4 - change example from Zip install to Composer install --- .../source/general/managing_apps.rst | 72 ++++++++++++++----- .../source/general/managing_apps/001.php | 2 + .../source/general/managing_apps/005.php | 12 ++++ 3 files changed, 67 insertions(+), 19 deletions(-) create mode 100644 user_guide_src/source/general/managing_apps/005.php diff --git a/user_guide_src/source/general/managing_apps.rst b/user_guide_src/source/general/managing_apps.rst index fc00dcd06985..ddba276825d2 100644 --- a/user_guide_src/source/general/managing_apps.rst +++ b/user_guide_src/source/general/managing_apps.rst @@ -8,10 +8,27 @@ directory. It is possible, however, to have multiple sets of applications that share a single CodeIgniter installation, or even to rename or relocate your application directory. +.. important:: When you installed CodeIgniter v4.1.9 or before, and if there are ``App\\`` and ``Config\\`` namespaces in your ``/composer.json``'s ``autoload.psr-4`` like the following, you need to remove these lines, and run ``composer dump-autolod``. + + .. code-block:: text + + { + ... + "autoload": { + "psr-4": { + "App\\": "app", <-- Remove this line + "Config\\": "app/Config" <-- Remove this line + } + }, + ... + } + .. contents:: :local: :depth: 2 +.. _renaming-app-directory: + Renaming or Relocating the Application Directory ================================================ @@ -46,32 +63,49 @@ and **bar**. You could structure your application project directories like this: .. code-block:: text - /foo - /app - /public - /tests - /writable + foo/ + app/ + public/ + tests/ + writable/ + env + phpunit.xml.dist spark - /bar - /app - /public - /tests - /writable + bar/ + app/ + public/ + tests/ + writable/ + env + phpunit.xml.dist spark - /codeigniter - /system + vendor/ + autoload.php + codeigniter4/framework/ + composer.json + composer.lock + +.. note:: If you install CodeIgniter from the Zip file, the directory structure would be following: + + .. code-block:: text + + foo/ + bar/ + codeigniter4/system/ This would have two apps, **foo** and **bar**, both having standard application directories -and a **public** folder, and sharing a common **codeigniter** framework. +and a **public** folder, and sharing a common **codeigniter4/framework**. -The **index.php** inside each application would refer to its own configuration, -``../app/Config/Paths.php``, and the ``$systemDirectory`` variable in **app/Config/Paths.php** inside each -of those would be set to refer to the shared common **system** folder. +The ``$systemDirectory`` variable in **app/Config/Paths.php** inside each +of those would be set to refer to the shared common **codeigniter4/framework** folder: -If either of the applications had a command-line component, then you would also -modify **spark** inside each application's project folder, as directed above. +.. literalinclude:: managing_apps/005.php -When you use Composer autoloader, fix the ``COMPOSER_PATH`` constant in **app/Config/Constants.php** inside each +.. note:: If you install CodeIgniter from the Zip file, the ``$systemDirectory`` would be ``__DIR__ . '/../../../codeigniter4/system'``. + +And modify the ``COMPOSER_PATH`` constant in **app/Config/Constants.php** inside each of those: .. literalinclude:: managing_apps/004.php + +Only when you change the Application Directory, see :ref:`renaming-app-directory` and modify the paths in the **index.php** and **spark**. diff --git a/user_guide_src/source/general/managing_apps/001.php b/user_guide_src/source/general/managing_apps/001.php index c116317678be..da4991fd738d 100644 --- a/user_guide_src/source/general/managing_apps/001.php +++ b/user_guide_src/source/general/managing_apps/001.php @@ -4,6 +4,8 @@ class Paths { + // ... + public $appDirectory = '/path/to/your/app'; // ... diff --git a/user_guide_src/source/general/managing_apps/005.php b/user_guide_src/source/general/managing_apps/005.php new file mode 100644 index 000000000000..4f5cbf47244c --- /dev/null +++ b/user_guide_src/source/general/managing_apps/005.php @@ -0,0 +1,12 @@ + Date: Fri, 15 Apr 2022 11:16:07 +0900 Subject: [PATCH 0856/1246] docs: replace /app/ with app/ Because there are more places listed as app/. --- user_guide_src/source/cli/cli_commands.rst | 4 ++-- user_guide_src/source/concepts/autoloader.rst | 4 ++-- user_guide_src/source/concepts/mvc.rst | 8 ++++---- user_guide_src/source/general/configuration.rst | 6 +++--- user_guide_src/source/incoming/controllers.rst | 2 +- user_guide_src/source/libraries/throttler.rst | 2 +- user_guide_src/source/libraries/validation.rst | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/user_guide_src/source/cli/cli_commands.rst b/user_guide_src/source/cli/cli_commands.rst index 30d92a195390..524ab80f3644 100644 --- a/user_guide_src/source/cli/cli_commands.rst +++ b/user_guide_src/source/cli/cli_commands.rst @@ -88,7 +88,7 @@ File Location ============= Commands must be stored within a directory named **Commands**. However, that directory can be located anywhere -that the :doc:`Autoloader ` can locate it. This could be in **/app/Commands**, or +that the :doc:`Autoloader ` can locate it. This could be in **app/Commands**, or a directory that you keep commands in to use in all of your project development, like **Acme/Commands**. .. note:: When the commands are executed, the full CodeIgniter CLI environment has been loaded, making it @@ -98,7 +98,7 @@ An Example Command ================== Let's step through an example command whose only function is to report basic information about the application -itself, for demonstration purposes. Start by creating a new file at **/app/Commands/AppInfo.php**. It +itself, for demonstration purposes. Start by creating a new file at **app/Commands/AppInfo.php**. It should contain the following code: .. literalinclude:: cli_commands/002.php diff --git a/user_guide_src/source/concepts/autoloader.rst b/user_guide_src/source/concepts/autoloader.rst index b748e520fd98..06f6fa45025c 100644 --- a/user_guide_src/source/concepts/autoloader.rst +++ b/user_guide_src/source/concepts/autoloader.rst @@ -28,7 +28,7 @@ beginning of the framework's execution. Configuration ============= -Initial configuration is done in **/app/Config/Autoload.php**. This file contains two primary +Initial configuration is done in **app/Config/Autoload.php**. This file contains two primary arrays: one for the classmap, and one for PSR-4 compatible namespaces. Namespaces @@ -48,7 +48,7 @@ have a trailing slash. By default, the application folder is namespace to the ``App`` namespace. While you are not forced to namespace the controllers, libraries, or models in the application directory, if you do, they will be found under the ``App`` namespace. -You may change this namespace by editing the **/app/Config/Constants.php** file and setting the +You may change this namespace by editing the **app/Config/Constants.php** file and setting the new namespace value under the ``APP_NAMESPACE`` setting: .. literalinclude:: autoloader/002.php diff --git a/user_guide_src/source/concepts/mvc.rst b/user_guide_src/source/concepts/mvc.rst index 11aa8efcd0af..1338290cc8b0 100644 --- a/user_guide_src/source/concepts/mvc.rst +++ b/user_guide_src/source/concepts/mvc.rst @@ -37,11 +37,11 @@ Views get the data to display from the controllers, who pass it to the views as with simple ``echo`` calls. You can also display other views within a view, making it pretty simple to display a common header or footer on every page. -Views are generally stored in **/app/Views**, but can quickly become unwieldy if not organized in some fashion. +Views are generally stored in **app/Views**, but can quickly become unwieldy if not organized in some fashion. CodeIgniter does not enforce any type of organization, but a good rule of thumb would be to create a new directory in the **Views** directory for each controller. Then, name views by the method name. This makes them very easy to find later on. For example, a user's profile might be displayed in a controller named ``User``, and a method named ``profile``. -You might store the view file for this method in **/app/Views/User/Profile.php**. +You might store the view file for this method in **app/Views/User/Profile.php**. That type of organization works great as a base habit to get into. At times you might need to organize it differently. That's not a problem. As long as CodeIgniter can find the file, it can display it. @@ -61,7 +61,7 @@ it's saved to meet company standards, or formatting a column in a certain way be By keeping these business requirements in the model, you won't repeat code throughout several controllers and accidentally miss updating an area. -Models are typically stored in **/app/Models**, though they can use a namespace to be grouped however you need. +Models are typically stored in **app/Models**, though they can use a namespace to be grouped however you need. :doc:`Find out more about models ` @@ -77,7 +77,7 @@ The other responsibility of the controller is to handle everything that pertains authentication, web safety, encoding, etc. In short, the controller is where you make sure that people are allowed to be there, and they get the data they need in a format they can use. -Controllers are typically stored in **/app/Controllers**, though they can use a namespace to be grouped however +Controllers are typically stored in **app/Controllers**, though they can use a namespace to be grouped however you need. :doc:`Find out more about controllers ` diff --git a/user_guide_src/source/general/configuration.rst b/user_guide_src/source/general/configuration.rst index 85bdc91fe62c..88d389c456a2 100644 --- a/user_guide_src/source/general/configuration.rst +++ b/user_guide_src/source/general/configuration.rst @@ -9,7 +9,7 @@ the required settings are public properties. Unlike many other frameworks, CodeIgniter configurable items aren't contained in a single file. Instead, each class that needs configurable items will have a configuration file with the same name as the class that uses it. You will find -the application configuration files in the **/app/Config** folder. +the application configuration files in the **app/Config** folder. .. contents:: :local: @@ -33,7 +33,7 @@ All configuration object properties are public, so you access the settings like .. literalinclude:: configuration/003.php If no namespace is provided, it will look for the file in all defined namespaces -as well as **/app/Config/**. +as well as **app/Config/**. All of the configuration files that ship with CodeIgniter are namespaced with ``Config``. Using this namespace in your application will provide the best @@ -48,7 +48,7 @@ Creating Configuration Files ============================ When you need a new configuration, first you create a new file at your desired location. -The default file location (recommended for most cases) is **/app/Config**. +The default file location (recommended for most cases) is **app/Config**. The class should use the appropriate namespace, and it should extend ``CodeIgniter\Config\BaseConfig`` to ensure that it can receive environment-specific settings. diff --git a/user_guide_src/source/incoming/controllers.rst b/user_guide_src/source/incoming/controllers.rst index c5a963c81fdd..9074bf18046f 100644 --- a/user_guide_src/source/incoming/controllers.rst +++ b/user_guide_src/source/incoming/controllers.rst @@ -146,7 +146,7 @@ For security reasons be sure to declare any new utility methods as ``protected`` .. literalinclude:: controllers/008.php -Then save the file to your **/app/Controllers/** directory. +Then save the file to your **app/Controllers/** directory. .. important:: The file must be called **Helloworld.php**, with a capital ``H``. diff --git a/user_guide_src/source/libraries/throttler.rst b/user_guide_src/source/libraries/throttler.rst index df0dfeb29d37..27a3283dae6e 100644 --- a/user_guide_src/source/libraries/throttler.rst +++ b/user_guide_src/source/libraries/throttler.rst @@ -64,7 +64,7 @@ Applying the Filter We don't necessarily need to throttle every page on the site. For many web applications, this makes the most sense to apply only to POST requests, though API's might want to limit every request made by a user. In order to apply -this to incoming requests, you need to edit **/app/Config/Filters.php** and first add an alias to the +this to incoming requests, you need to edit **app/Config/Filters.php** and first add an alias to the filter: .. literalinclude:: throttler/003.php diff --git a/user_guide_src/source/libraries/validation.rst b/user_guide_src/source/libraries/validation.rst index 8d3204804e92..641058b29a87 100644 --- a/user_guide_src/source/libraries/validation.rst +++ b/user_guide_src/source/libraries/validation.rst @@ -498,7 +498,7 @@ Creating the Views The first step is to create custom views. These can be placed anywhere that the ``view()`` method can locate them, which means the standard View directory, or any namespaced View folder will work. For example, you could create -a new view at **/app/Views/_errors_list.php**: +a new view at **app/Views/_errors_list.php**: .. literalinclude:: validation/030.php From 33ef2742a96880e7eb1819305c7737f2ec59e94f Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 15 Apr 2022 11:29:10 +0900 Subject: [PATCH 0857/1246] docs: small improvement --- user_guide_src/source/intro/requirements.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/user_guide_src/source/intro/requirements.rst b/user_guide_src/source/intro/requirements.rst index a55b8c46d0d9..974cf108c406 100644 --- a/user_guide_src/source/intro/requirements.rst +++ b/user_guide_src/source/intro/requirements.rst @@ -7,7 +7,10 @@ Server Requirements installed. The following PHP extensions should be enabled on your server: -``php-json``, ``php-mysqlnd``, ``php-xml`` + + - ``php-json`` + - ``php-mysqlnd`` (if you use MySQL) + - ``php-xml`` In order to use the :doc:`CURLRequest `, you will need `libcurl `_ installed. @@ -15,7 +18,7 @@ In order to use the :doc:`CURLRequest `, you will need A database is required for most web application programming. Currently supported databases are: - - MySQL (5.1+) via the *MySQLi* driver + - MySQL via the *MySQLi* driver (version 5.1 and above only) - PostgreSQL via the *Postgre* driver - SQLite3 via the *SQLite3* driver - MSSQL via the *SQLSRV* driver (version 2005 and above only) From 6c01476b8323b18c8838d3371cddaf643e44b4b8 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 15 Apr 2022 11:56:03 +0900 Subject: [PATCH 0858/1246] docs: add TOC --- user_guide_src/source/concepts/autoloader.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/user_guide_src/source/concepts/autoloader.rst b/user_guide_src/source/concepts/autoloader.rst index b748e520fd98..ecd4428a0cfa 100644 --- a/user_guide_src/source/concepts/autoloader.rst +++ b/user_guide_src/source/concepts/autoloader.rst @@ -2,6 +2,10 @@ Autoloading Files ################# +.. contents:: + :local: + :depth: 2 + Every application consists of a large number of classes in many different locations. The framework provides classes for core functionality. Your application will have a number of libraries, models, and other entities to make it work. You might have third-party From a5c8c50cae82cb1acefcc83447eefc89c363eb68 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 15 Apr 2022 11:56:18 +0900 Subject: [PATCH 0859/1246] docs: remove out of dated description The core classes are not added to the classmap. --- user_guide_src/source/concepts/autoloader.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/user_guide_src/source/concepts/autoloader.rst b/user_guide_src/source/concepts/autoloader.rst index ecd4428a0cfa..577a70bf2430 100644 --- a/user_guide_src/source/concepts/autoloader.rst +++ b/user_guide_src/source/concepts/autoloader.rst @@ -18,8 +18,6 @@ It can locate individual namespaced classes that adhere to `PSR-4 `_ autoloading directory structures. -For performance improvement, the core CodeIgniter components have been added to the classmap. - The autoloader works great by itself, but can also work with other autoloaders, like `Composer `_, or even your own custom autoloaders, if needed. Because they're all registered through From 5d737089b8e90fb6665404a1881fdf83cb944956 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 15 Apr 2022 11:58:10 +0900 Subject: [PATCH 0860/1246] docs: remove unneeded description We don't need a trailing back slash, so escaping back slashes is not needed. Double-quotes have nothing to do with escaping. --- user_guide_src/source/concepts/autoloader.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/user_guide_src/source/concepts/autoloader.rst b/user_guide_src/source/concepts/autoloader.rst index 577a70bf2430..7e931c677995 100644 --- a/user_guide_src/source/concepts/autoloader.rst +++ b/user_guide_src/source/concepts/autoloader.rst @@ -43,9 +43,8 @@ those classes can be found in: .. literalinclude:: autoloader/001.php -The key of each row is the namespace itself. This does not need a trailing slash. If you use double-quotes -to define the array, be sure to escape the backward slash. That means that it would be ``My\\App``, -not ``My\App``. The value is the location to the directory the classes can be found in. They should +The key of each row is the namespace itself. This does not need a trailing slash. +The value is the location to the directory the classes can be found in. They should have a trailing slash. By default, the application folder is namespace to the ``App`` namespace. While you are not forced to namespace the controllers, From 43fb2fc9b94ca90f8b7a52f8b48582cb20992273 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 15 Apr 2022 12:04:00 +0900 Subject: [PATCH 0861/1246] docs: add `back` --- user_guide_src/source/concepts/autoloader.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/concepts/autoloader.rst b/user_guide_src/source/concepts/autoloader.rst index 7e931c677995..5dd349065860 100644 --- a/user_guide_src/source/concepts/autoloader.rst +++ b/user_guide_src/source/concepts/autoloader.rst @@ -43,7 +43,7 @@ those classes can be found in: .. literalinclude:: autoloader/001.php -The key of each row is the namespace itself. This does not need a trailing slash. +The key of each row is the namespace itself. This does not need a trailing back slash. The value is the location to the directory the classes can be found in. They should have a trailing slash. From c2bb64594ada1e76b3ad862f3d0f1909a0e24f5e Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 15 Apr 2022 12:04:26 +0900 Subject: [PATCH 0862/1246] docs: fix the file path text decration --- user_guide_src/source/concepts/autoloader.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/concepts/autoloader.rst b/user_guide_src/source/concepts/autoloader.rst index 5dd349065860..3c68567486da 100644 --- a/user_guide_src/source/concepts/autoloader.rst +++ b/user_guide_src/source/concepts/autoloader.rst @@ -76,7 +76,7 @@ Composer Support Composer support is automatically initialized by default. By default, it looks for Composer's autoload file at ``ROOTPATH . 'vendor/autoload.php'``. If you need to change the location of that file for any reason, you can modify -the value defined in ``Config\Constants.php``. +the value defined in **app/Config/Constants.php**. .. note:: If the same namespace is defined in both CodeIgniter and Composer, CodeIgniter's autoloader will be the first one to get a chance to locate the file. From 0208c720f256ee0b3257f1b9c6efd9fdb65548fd Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 15 Apr 2022 14:00:25 +0900 Subject: [PATCH 0863/1246] fix: Composer PSR-4 overwrites Config\Autoload::$psr4 --- system/Autoloader/Autoloader.php | 2 +- tests/system/Autoloader/AutoloaderTest.php | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/system/Autoloader/Autoloader.php b/system/Autoloader/Autoloader.php index 520e669be685..311428fe4165 100644 --- a/system/Autoloader/Autoloader.php +++ b/system/Autoloader/Autoloader.php @@ -328,7 +328,7 @@ private function loadComposerNamespaces(ClassLoader $composer): void $newPaths[rtrim($key, '\\ ')] = $value; } - $this->prefixes = array_merge($this->prefixes, $newPaths); + $this->addNamespace($newPaths); } private function loadComposerClassmap(ClassLoader $composer): void diff --git a/tests/system/Autoloader/AutoloaderTest.php b/tests/system/Autoloader/AutoloaderTest.php index 82e0307affad..1279910d2289 100644 --- a/tests/system/Autoloader/AutoloaderTest.php +++ b/tests/system/Autoloader/AutoloaderTest.php @@ -233,6 +233,23 @@ public function testFindsComposerRoutes() $this->assertArrayHasKey('Laminas\\Escaper', $namespaces); } + public function testComposerNamespaceDoesNotOverwriteConfigAutoloadPsr4() + { + $config = new Autoload(); + $config->psr4 = [ + 'Psr\Log' => '/Config/Autoload/Psr/Log/', + ]; + $modules = new Modules(); + $modules->discoverInComposer = true; + + $this->loader = new Autoloader(); + $this->loader->initialize($config, $modules); + + $namespaces = $this->loader->getNamespace(); + $this->assertSame('/Config/Autoload/Psr/Log/', $namespaces['Psr\Log'][0]); + $this->assertStringContainsString(VENDORPATH, $namespaces['Psr\Log'][1]); + } + public function testFindsComposerRoutesWithComposerPathNotFound() { $composerPath = COMPOSER_PATH; From c3ecc1971d1b6b1bbacfe67372c48b6eb07f15d7 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Fri, 8 Apr 2022 01:12:00 +0700 Subject: [PATCH 0864/1246] [PHPStan] Prepare for PHPStan 1.6.x-dev --- composer.json | 2 +- phpstan.neon.dist | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 578156bd017c..e6935404bae9 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "mikey179/vfsstream": "^1.6", "nexusphp/cs-config": "^3.3", "nexusphp/tachycardia": "^1.0", - "phpstan/phpstan": "^1.0", + "phpstan/phpstan": "1.6.x-dev", "phpunit/phpunit": "^9.1", "predis/predis": "^1.1", "rector/rector": "0.12.20" diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 8aa28016ca33..cbacdfb82745 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -7,6 +7,10 @@ services: class: Utils\PHPStan\CheckFrameworkExceptionInstantiationViaNamedConstructorRule tags: - phpstan.rules.rule + - + class: PhpParser\NodeVisitor\NodeConnectingVisitor + tags: + - phpstan.parser.richParserNodeVisitor includes: - phpstan-baseline.neon.dist From fc9a7b8fbd6274768069fa2da42d2ffd316fd213 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Fri, 15 Apr 2022 20:36:37 +0700 Subject: [PATCH 0865/1246] set conditional tag --- composer.json | 2 +- phpstan.neon.dist | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index e6935404bae9..d3e0b85bdee8 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "mikey179/vfsstream": "^1.6", "nexusphp/cs-config": "^3.3", "nexusphp/tachycardia": "^1.0", - "phpstan/phpstan": "1.6.x-dev", + "phpstan/phpstan": "^1.5.6", "phpunit/phpunit": "^9.1", "predis/predis": "^1.1", "rector/rector": "0.12.20" diff --git a/phpstan.neon.dist b/phpstan.neon.dist index cbacdfb82745..e4832b125ae2 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,3 +1,7 @@ +conditionalTags: + PhpParser\NodeVisitor\NodeConnectingVisitor: + phpstan.parser.richParserNodeVisitor: true + services: - class: Utils\PHPStan\CheckUseStatementsAfterLicenseRule @@ -7,10 +11,6 @@ services: class: Utils\PHPStan\CheckFrameworkExceptionInstantiationViaNamedConstructorRule tags: - phpstan.rules.rule - - - class: PhpParser\NodeVisitor\NodeConnectingVisitor - tags: - - phpstan.parser.richParserNodeVisitor includes: - phpstan-baseline.neon.dist From 9a60eb3d57671ffe2d69413136c8bcd2aba4c775 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Dadashi Date: Sun, 17 Apr 2022 01:18:58 +0330 Subject: [PATCH 0866/1246] docs:Correction due to 404 Not Found --- tests/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/README.md b/tests/README.md index 0df329864c6b..80f9439d1e6d 100644 --- a/tests/README.md +++ b/tests/README.md @@ -18,7 +18,7 @@ If running under OS X or Linux, you can create a symbolic link to make running t > ln -s ./vendor/bin/phpunit ./phpunit -You also need to install [XDebug](https://xdebug.org/index.php) in order +You also need to install [XDebug](https://xdebug.org/docs/install) in order for code coverage to be calculated successfully. ## Setting Up From ae56d6c66260064b4d1c71629c3fb12d81d79d77 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 18 Apr 2022 08:15:27 +0900 Subject: [PATCH 0867/1246] docs: remove out of dated comment --- system/CLI/CLI.php | 1 - 1 file changed, 1 deletion(-) diff --git a/system/CLI/CLI.php b/system/CLI/CLI.php index b43d0005ff77..f017346604a7 100644 --- a/system/CLI/CLI.php +++ b/system/CLI/CLI.php @@ -485,7 +485,6 @@ public static function color(string $text, string $foreground, ?string $backgrou throw CLIException::forInvalidColor('background', $background); } - // Reset text $newText = ''; // Detect if color method was already in use with this text From 63207331448887c8ff81e675b7ac80b34cac15ed Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 18 Apr 2022 08:17:48 +0900 Subject: [PATCH 0868/1246] refactor: combine if statements --- system/CLI/CLI.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/system/CLI/CLI.php b/system/CLI/CLI.php index f017346604a7..ae61d50e41d4 100644 --- a/system/CLI/CLI.php +++ b/system/CLI/CLI.php @@ -469,11 +469,7 @@ public static function clearScreen() */ public static function color(string $text, string $foreground, ?string $background = null, ?string $format = null): string { - if (! static::$isColored) { - return $text; - } - - if ($text === '') { + if (! static::$isColored || $text === '') { return $text; } From 9dcb39cb1e2d87bffb0cdc8c85be55253af2041d Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 18 Apr 2022 08:18:18 +0900 Subject: [PATCH 0869/1246] refacter: remove unneeded parentheses --- system/CLI/CLI.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/CLI/CLI.php b/system/CLI/CLI.php index ae61d50e41d4..d88374e80944 100644 --- a/system/CLI/CLI.php +++ b/system/CLI/CLI.php @@ -533,7 +533,7 @@ private static function getColoredText(string $text, string $foreground, ?string $string .= "\033[4m"; } - return $string . ($text . "\033[0m"); + return $string . $text . "\033[0m"; } /** From 2aa93487f2d22365eb18237b48e2fdbea3ddce44 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 18 Apr 2022 08:27:32 +0900 Subject: [PATCH 0870/1246] docs: fix heading underlines --- user_guide_src/source/cli/cli_library.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/user_guide_src/source/cli/cli_library.rst b/user_guide_src/source/cli/cli_library.rst index 4ea8e71e4996..8d269aeead09 100644 --- a/user_guide_src/source/cli/cli_library.rst +++ b/user_guide_src/source/cli/cli_library.rst @@ -15,7 +15,7 @@ CodeIgniter's CLI library makes creating interactive command-line scripts simple :depth: 2 Initializing the Class -====================== +********************** You do not need to create an instance of the CLI library, since all of it's methods are static. Instead, you simply need to ensure your controller can locate it via a ``use`` statement above your class: @@ -25,7 +25,7 @@ need to ensure your controller can locate it via a ``use`` statement above your The class is automatically initialized when the file is loaded the first time. Getting Input from the User -=========================== +*************************** Sometimes you need to ask the user for more information. They might not have provided optional command-line arguments, or the script may have encountered an existing file and needs confirmation before overwriting. This is @@ -66,7 +66,7 @@ Named keys are also possible: Finally, you can pass :ref:`validation ` rules to the answer input as the third parameter, the acceptable answers are automatically restricted to the passed options. Providing Feedback -================== +****************** **write()** From 85670436edbc7a605f85d8898d61dec374455481 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 18 Apr 2022 08:31:59 +0900 Subject: [PATCH 0871/1246] docs: change method names to headings Otherwise, I can't link to it. --- user_guide_src/source/cli/cli_library.rst | 33 +++++++++++++++-------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/user_guide_src/source/cli/cli_library.rst b/user_guide_src/source/cli/cli_library.rst index 8d269aeead09..bfb3a2479903 100644 --- a/user_guide_src/source/cli/cli_library.rst +++ b/user_guide_src/source/cli/cli_library.rst @@ -52,7 +52,8 @@ Validation rules can also be written in the array syntax: .. literalinclude:: cli_library/006.php -**promptByKey()** +promptByKey() +============= Predefined answers (options) for prompt sometimes need to be described or are too complex to select via their value. ``promptByKey()`` allows the user to select an option by its key instead of its value: @@ -68,7 +69,8 @@ Finally, you can pass :ref:`validation ` rules to the answer input a Providing Feedback ****************** -**write()** +write() +======= Several methods are provided for you to provide feedback to your users. This can be as simple as a single status update or a complex table of information that wraps to the user's terminal window. At the core of this is the ``write()`` @@ -116,7 +118,8 @@ And a smaller number are available as background colors: * light_gray * magenta -**print()** +print() +======= Print functions identically to the ``write()`` method, except that it does not force a newline either before or after. Instead it prints it to the screen wherever the cursor is currently. This allows you to print multiple items all on @@ -125,7 +128,8 @@ print "Done" on the same line: .. literalinclude:: cli_library/012.php -**color()** +color() +======= While the ``write()`` command will write a single line to the terminal, ending it with a EOL character, you can use the ``color()`` method to make a string fragment that can be used in the same way, except that it will not force @@ -137,7 +141,8 @@ it inside of a ``write()`` method to create a string of a different color inside This example would write a single line to the window, with ``fileA`` in yellow, followed by a tab, and then ``/path/to/file`` in white text. -**error()** +error() +======= If you need to output errors, you should use the appropriately named ``error()`` method. This writes light-red text to STDERR, instead of STDOUT, like ``write()`` and ``color()`` do. This can be useful if you have scripts watching @@ -146,7 +151,8 @@ exactly as you would the ``write()`` method: .. literalinclude:: cli_library/014.php -**wrap()** +wrap() +====== This command will take a string, start printing it on the current line, and wrap it to a set length on new lines. This might be useful when displaying a list of options with descriptions that you want to wrap in the current @@ -179,13 +185,15 @@ Would create something like this: industry's standard dummy text ever since the -**newLine()** +newLine() +========= The ``newLine()`` method displays a blank line to the user. It does not take any parameters: .. literalinclude:: cli_library/018.php -**clearScreen()** +clearScreen() +============= You can clear the current terminal window with the ``clearScreen()`` method. In most versions of Windows, this will simply insert 40 blank lines since Windows doesn't support this feature. Windows 10 bash integration should change @@ -193,7 +201,8 @@ this: .. literalinclude:: cli_library/019.php -**showProgress()** +showProgress() +============== If you have a long-running task that you would like to keep the user updated with the progress, you can use the ``showProgress()`` method which displays something like the following: @@ -210,7 +219,8 @@ pass ``false`` as the first parameter and the progress bar will be removed. .. literalinclude:: cli_library/020.php -**table()** +table() +======= .. literalinclude:: cli_library/021.php @@ -223,7 +233,8 @@ pass ``false`` as the first parameter and the progress bar will be removed. | 8 | Another great item title | 2017-11-16 13:46:54 | 0 | +----+--------------------------+---------------------+--------+ -**wait()** +wait() +====== Waits a certain number of seconds, optionally showing a wait message and waiting for a key press. From c0ca99f51475e25d3fb87d9a7ed02dd74baf4725 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 18 Apr 2022 08:38:10 +0900 Subject: [PATCH 0872/1246] docs: add changelog --- user_guide_src/source/changelogs/v4.2.0.rst | 1 + user_guide_src/source/cli/cli_library.rst | 2 ++ 2 files changed, 3 insertions(+) diff --git a/user_guide_src/source/changelogs/v4.2.0.rst b/user_guide_src/source/changelogs/v4.2.0.rst index c0081761ffd4..449ad50f970d 100644 --- a/user_guide_src/source/changelogs/v4.2.0.rst +++ b/user_guide_src/source/changelogs/v4.2.0.rst @@ -18,6 +18,7 @@ BREAKING - ``spark`` - The method signature of ``CodeIgniter\CLI\CommandRunner::_remap()`` has been changed to fix a bug. - The ``CodeIgniter\Autoloader\Autoloader::initialize()`` has changed the behavior to fix a bug. It used to use Composer classmap only when ``$modules->discoverInComposer`` is true. Now it always uses the Composer classmap if Composer is available. +- The color code output by :ref:`CLI::color() ` has been changed to fix a bug. Enhancements ************ diff --git a/user_guide_src/source/cli/cli_library.rst b/user_guide_src/source/cli/cli_library.rst index bfb3a2479903..29bc6b252f88 100644 --- a/user_guide_src/source/cli/cli_library.rst +++ b/user_guide_src/source/cli/cli_library.rst @@ -128,6 +128,8 @@ print "Done" on the same line: .. literalinclude:: cli_library/012.php +.. _cli-library-color: + color() ======= From 4ad1edfdbb16ec7fc7dc903f832dd975e2063b4b Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 18 Apr 2022 13:07:27 +0900 Subject: [PATCH 0873/1246] docs: fix heading underline level --- user_guide_src/source/models/model.rst | 46 +++++++++++++------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/user_guide_src/source/models/model.rst b/user_guide_src/source/models/model.rst index fa354d7c3aff..e626662bef2d 100644 --- a/user_guide_src/source/models/model.rst +++ b/user_guide_src/source/models/model.rst @@ -7,7 +7,7 @@ Using CodeIgniter's Model :depth: 2 Models -====== +****** The CodeIgniter's Model provides convenience features and additional functionality that people commonly use to make working with a **single table** in your database more convenient. @@ -17,7 +17,7 @@ methods for much of the standard ways you would need to interact with a database updating records, deleting records, and more. Accessing Models -================ +**************** Models are typically stored in the ``app/Models`` directory. They should have a namespace that matches their location within the directory, like ``namespace App\Models``. @@ -27,7 +27,7 @@ You can access models within your classes by creating a new instance or using th .. literalinclude:: model/001.php CodeIgniter's Model -=================== +******************* CodeIgniter does provide a model class that provides a few nice features, including: @@ -41,7 +41,7 @@ This class provides a solid base from which to build your own models, allowing y rapidly build out your application's model layer. Creating Your Model -=================== +******************* To take advantage of CodeIgniter's model, you would simply create a new model class that extends ``CodeIgniter\Model``: @@ -58,7 +58,7 @@ extra steps without repeating the constructor parameters, for example extending .. literalinclude:: model/003.php Connecting to the Database --------------------------- +========================== When the class is first instantiated, if no database connection instance is passed to the constructor, it will automatically connect to the default database group, as set in the configuration. You can @@ -72,7 +72,7 @@ You would replace "group_name" with the name of a defined database group from th configuration file. Configuring Your Model ----------------------- +====================== The model class has a few configuration options that can be set to allow the class' methods to work seamlessly for you. The first two are used by all of the CRUD methods to determine @@ -190,10 +190,10 @@ time specified in the property name. Whether the callbacks defined above should be used. Working With Data -================= +***************** Finding Data ------------- +============ Several functions are provided for doing basic CRUD work on your tables, including ``find()``, ``insert()``, ``update()``, ``delete()`` and more. @@ -258,7 +258,7 @@ the next **find*()** methods to return only soft deleted rows: .. literalinclude:: model/014.php Saving Data ------------ +=========== **insert()** @@ -316,7 +316,7 @@ model's ``save()`` method to inspect the class, grab any public and private prop that provides several handy features that make developing Entities simpler. Deleting Data -------------- +============= **delete()** @@ -343,7 +343,7 @@ Cleans out the database table by permanently removing all rows that have 'delete .. literalinclude:: model/026.php Validating Data ---------------- +=============== For many people, validating data in the model is the preferred way to ensure the data is kept to a single standard, without duplicating code. The Model class provides a way to automatically have all data validated @@ -416,7 +416,7 @@ and simply set ``$validationRules`` to the name of the validation rule group you .. literalinclude:: model/034.php Retrieving Validation Rules ---------------------------- +=========================== You can retrieve a model's validation rules by accessing its ``validationRules`` property: @@ -435,7 +435,7 @@ value an array of fieldnames of interest: .. literalinclude:: model/037.php Validation Placeholders ------------------------ +======================= The model provides a simple method to replace parts of your rules based on data that's being passed into it. This sounds fairly obscure but can be especially handy with the ``is_unique`` validation rule. Placeholders are simply @@ -459,7 +459,7 @@ This can also be used to create more dynamic rules at runtime, as long as you ta keys passed in don't conflict with your form data. Protecting Fields ------------------ +================= To help protect against Mass Assignment Attacks, the Model class **requires** that you list all of the field names that can be changed during inserts and updates in the ``$allowedFields`` class property. Any data provided @@ -474,7 +474,7 @@ testing, migrations, or seeds. In these cases, you can turn the protection on or .. literalinclude:: model/042.php Working With Query Builder --------------------------- +========================== You can get access to a shared instance of the Query Builder for that model's database connection any time you need it: @@ -501,7 +501,7 @@ very elegant use: .. literalinclude:: model/046.php Runtime Return Type Changes ----------------------------- +=========================== You can specify the format that data should be returned as when using the **find*()** methods as the class property, ``$returnType``. There may be times that you would like the data back in a different format, though. The Model @@ -523,7 +523,7 @@ Returns data from the next **find*()** method as standard objects or custom clas .. literalinclude:: model/048.php Processing Large Amounts of Data --------------------------------- +================================ Sometimes, you need to process large amounts of data and would run the risk of running out of memory. To make this simpler, you may use the chunk() method to get smaller chunks of data that you can then @@ -535,7 +535,7 @@ This is best used during cronjobs, data exports, or other large tasks. .. literalinclude:: model/049.php Model Events -============ +************ There are several points within the model's execution that you can specify multiple callback methods to run. These methods can be used to normalize data, hash passwords, save related entities, and much more. The following @@ -543,7 +543,7 @@ points in the model's execution can be affected, each through a class property: ``$beforeUpdate``, ``$afterUpdate``, ``$afterFind``, and ``$afterDelete``. Defining Callbacks ------------------- +================== You specify the callbacks by first creating a new class method in your model to use. This class will always receive a ``$data`` array as its only parameter. The exact contents of the ``$data`` array will vary between events, but @@ -555,7 +555,7 @@ must return the original $data array so other callbacks have the full informatio .. literalinclude:: model/050.php Specifying Callbacks To Run ---------------------------- +=========================== You specify when to run the callbacks by adding the method name to the appropriate class property (``$beforeInsert``, ``$afterUpdate``, etc). Multiple callbacks can be added to a single event and they will be processed one after the other. You can @@ -572,7 +572,7 @@ You may also change this setting temporarily for a single model call sing the `` .. literalinclude:: model/053.php Event Parameters ----------------- +================ Since the exact data passed to each callback varies a bit, here are the details on what is in the ``$data`` parameter passed to each event: @@ -607,7 +607,7 @@ afterDelete **id** = primary key of row being deleted. ================ ========================================================================================================= Modifying Find* Data --------------------- +==================== The ``beforeFind`` and ``afterFind`` methods can both return a modified set of data to override the normal response from the model. For ``afterFind`` any changes made to ``data`` in the return array will automatically be passed back @@ -617,7 +617,7 @@ boolean, ``returnData``: .. literalinclude:: model/054.php Manual Model Creation -===================== +********************* You do not need to extend any special class to create a model for your application. All you need is to get an instance of the database connection and you're good to go. This allows you to bypass the features CodeIgniter's From f3a34f72ff38fe9fb9ebfe95beb84daf512b043c Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 18 Apr 2022 13:08:21 +0900 Subject: [PATCH 0874/1246] docs: change **foo** to headings You can link to headings, but cannot link to `**foo**`. --- user_guide_src/source/models/model.rst | 101 ++++++++++++++++--------- 1 file changed, 67 insertions(+), 34 deletions(-) diff --git a/user_guide_src/source/models/model.rst b/user_guide_src/source/models/model.rst index e626662bef2d..84fdbf4be249 100644 --- a/user_guide_src/source/models/model.rst +++ b/user_guide_src/source/models/model.rst @@ -80,13 +80,15 @@ what table to use and how we can find the required records: .. literalinclude:: model/005.php -**$table** +$table +------ Specifies the database table that this model primarily works with. This only applies to the built-in CRUD methods. You are not restricted to using only this table in your own queries. -**$primaryKey** +$primaryKey +----------- This is the name of the column that uniquely identifies the records in this table. This does not necessarily have to match the primary key that is specified in the database, but @@ -95,7 +97,8 @@ is used with methods like ``find()`` to know what column to match the specified .. note:: All Models must have a primaryKey specified to allow all of the features to work as expected. -**$useAutoIncrement** +$useAutoIncrement +----------------- Specifies if the table uses an auto-increment feature for ``$primaryKey``. If set to ``false`` then you are responsible for providing primary key value for every record in the table. This @@ -106,7 +109,8 @@ default value is ``true``. key in the database to ``unique``. This way you will make sure that all of Model's features will still work the same as before. -**$returnType** +$returnType +----------- The Model's CRUD methods will take a step of work away from you and automatically return the resulting data, instead of the Result object. This setting allows you to define @@ -114,7 +118,8 @@ the type of data that is returned. Valid values are '**array**' (the default), ' qualified name of a class** that can be used with the Result object's ``getCustomResultObject()`` method. -**$useSoftDeletes** +$useSoftDeletes +--------------- If true, then any ``delete()`` method calls will set ``deleted_at`` in the database, instead of actually deleting the row. This can preserve data when it might be referenced elsewhere, or @@ -126,66 +131,81 @@ This requires either a DATETIME or INTEGER field in the database as per the mode ``$dateFormat`` setting. The default field name is ``deleted_at`` however this name can be configured to any name of your choice by using ``$deletedField`` property. -**$allowedFields** +$allowedFields +-------------- This array should be updated with the field names that can be set during ``save()``, ``insert()``, or ``update()`` methods. Any field names other than these will be discarded. This helps to protect against just taking input from a form and throwing it all at the model, resulting in potential mass assignment vulnerabilities. -**$useTimestamps** +$useTimestamps +-------------- This boolean value determines whether the current date is automatically added to all inserts and updates. If true, will set the current time in the format specified by ``$dateFormat``. This requires that the table have columns named **created_at** and **updated_at** in the appropriate data type. -**$createdField** +$createdField +------------- Specifies which database field to use for data record create timestamp. Leave it empty to avoid updating it (even if ``$useTimestamps`` is enabled). -**$updatedField** +$updatedField +------------- Specifies which database field should use for keep data record update timestamp. Leave it empty to avoid update it (even ``$useTimestamps`` is enabled). -**$dateFormat** +$dateFormat +----------- This value works with ``$useTimestamps`` and ``$useSoftDeletes`` to ensure that the correct type of date value gets inserted into the database. By default, this creates DATETIME values, but valid options are: ``'datetime'``, ``'date'``, or ``'int'`` (a PHP timestamp). Using **useSoftDeletes** or -**useTimestamps** with an invalid or missing dateFormat will cause an exception. +useTimestamps with an invalid or missing dateFormat will cause an exception. -**$validationRules** +$validationRules +---------------- Contains either an array of validation rules as described in :ref:`validation-array` or a string containing the name of a validation group, as described in the same section. Described in more detail below. -**$validationMessages** +$validationMessages +------------------- Contains an array of custom error messages that should be used during validation, as described in :ref:`validation-custom-errors`. Described in more detail below. -**$skipValidation** +$skipValidation +--------------- Whether validation should be skipped during all **inserts** and **updates**. The default value is false, meaning that data will always attempt to be validated. This is primarily used by the ``skipValidation()`` method, but may be changed to ``true`` so this model will never validate. -**$beforeInsert** -**$afterInsert** -**$beforeUpdate** -**$afterUpdate** -**$afterFind** -**$afterDelete** +$beforeInsert +------------- +$afterInsert +------------ +$beforeUpdate +------------- +$afterUpdate +------------ +$afterFind +---------- +$afterDelete +------------ These arrays allow you to specify callback methods that will be run on the data at the time specified in the property name. -**$allowCallbacks** +$allowCallbacks +--------------- Whether the callbacks defined above should be used. @@ -198,7 +218,8 @@ Finding Data Several functions are provided for doing basic CRUD work on your tables, including ``find()``, ``insert()``, ``update()``, ``delete()`` and more. -**find()** +find() +------ Returns a single row where the primary key matches the value passed in as the first parameter: @@ -214,7 +235,8 @@ of just one: If no parameters are passed in, will return all rows in that model's table, effectively acting like ``findAll()``, though less explicit. -**findColumn()** +findColumn() +------------ Returns null or an indexed array of column values: @@ -222,7 +244,8 @@ Returns null or an indexed array of column values: ``$column_name`` should be a name of single column else you will get the DataException. -**findAll()** +findAll() +--------- Returns all results: @@ -237,20 +260,23 @@ parameters, respectively: .. literalinclude:: model/011.php -**first()** +first() +------- Returns the first row in the result set. This is best used in combination with the query builder. .. literalinclude:: model/012.php -**withDeleted()** +withDeleted() +------------- If ``$useSoftDeletes`` is true, then the **find*()** methods will not return any rows where 'deleted_at IS NOT NULL'. To temporarily override this, you can use the ``withDeleted()`` method prior to calling the **find*()** method. .. literalinclude:: model/013.php -**onlyDeleted()** +onlyDeleted() +------------- Whereas ``withDeleted()`` will return both deleted and not-deleted rows, this method modifies the next **find*()** methods to return only soft deleted rows: @@ -260,7 +286,8 @@ the next **find*()** methods to return only soft deleted rows: Saving Data =========== -**insert()** +insert() +-------- An associative array of data is passed into this method as the only parameter to create a new row of data in the database. The array's keys must match the name of the columns in a ``$table``, while @@ -268,7 +295,8 @@ the array's values are the values to save for that key: .. literalinclude:: model/015.php -**update()** +update() +-------- Updates an existing record in the database. The first parameter is the ``$primaryKey`` of the record to update. An associative array of data is passed into this method as the second parameter. The array's keys must match the name @@ -285,7 +313,8 @@ update command, with the added benefit of validation, events, etc: .. literalinclude:: model/018.php -**save()** +save() +------ This is a wrapper around the ``insert()`` and ``update()`` methods that handle inserting or updating the record automatically, based on whether it finds an array key matching the **primary key** value: @@ -318,7 +347,8 @@ model's ``save()`` method to inspect the class, grab any public and private prop Deleting Data ============= -**delete()** +delete() +-------- Takes a primary key value as the first parameter and deletes the matching record from the model's table: @@ -336,7 +366,8 @@ previously: .. literalinclude:: model/025.php -**purgeDeleted()** +purgeDeleted() +-------------- Cleans out the database table by permanently removing all rows that have 'deleted_at IS NOT NULL'. @@ -510,13 +541,15 @@ provides methods that allow you to do just that. .. note:: These methods only change the return type for the next **find*()** method call. After that, it is reset to its default value. -**asArray()** +asArray() +--------- Returns data from the next **find*()** method as associative arrays: .. literalinclude:: model/047.php -**asObject()** +asObject() +---------- Returns data from the next **find*()** method as standard objects or custom class intances: From 8f1b0c80f73745abfeb9354e491391cdb41a0863 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Apr 2022 15:02:55 +0000 Subject: [PATCH 0875/1246] chore(deps-dev): update rector/rector requirement Updates the requirements on [rector/rector](https://github.com/rectorphp/rector) to permit the latest version. - [Release notes](https://github.com/rectorphp/rector/releases) - [Commits](https://github.com/rectorphp/rector/compare/0.12.20...0.12.21) --- updated-dependencies: - dependency-name: rector/rector dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index d3e0b85bdee8..9c1ee4adb46e 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "phpstan/phpstan": "^1.5.6", "phpunit/phpunit": "^9.1", "predis/predis": "^1.1", - "rector/rector": "0.12.20" + "rector/rector": "0.12.21" }, "suggest": { "ext-fileinfo": "Improves mime type detection for files" From 185754ed87b80dc846810097bd38e147a9bac4fb Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Mon, 18 Apr 2022 22:15:59 +0700 Subject: [PATCH 0876/1246] clean up removed service and updated to use new RectorConfig --- rector.php | 98 ++++++++++++++++++++++++++---------------------------- 1 file changed, 47 insertions(+), 51 deletions(-) diff --git a/rector.php b/rector.php index 9ee8a4217d21..79aa188aa94f 100644 --- a/rector.php +++ b/rector.php @@ -21,12 +21,11 @@ use Rector\CodeQuality\Rector\If_\ShortenElseIfRector; use Rector\CodeQuality\Rector\If_\SimplifyIfElseToTernaryRector; use Rector\CodeQuality\Rector\If_\SimplifyIfReturnBoolRector; -use Rector\CodeQuality\Rector\Return_\SimplifyUselessVariableRector; use Rector\CodeQuality\Rector\Ternary\UnnecessaryTernaryExpressionRector; use Rector\CodingStyle\Rector\ClassMethod\FuncGetArgsToVariadicParamRector; use Rector\CodingStyle\Rector\ClassMethod\MakeInheritedMethodVisibilitySameAsParentRector; use Rector\CodingStyle\Rector\FuncCall\CountArrayToEmptyArrayComparisonRector; -use Rector\Core\Configuration\Option; +use Rector\Config\RectorConfig; use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector; use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPromotedPropertyRector; use Rector\DeadCode\Rector\If_\UnwrapFutureCompatibleIfPhpVersionRector; @@ -45,31 +44,31 @@ use Rector\PSR4\Rector\FileWithoutNamespace\NormalizeNamespaceByPSR4ComposerAutoloadRector; use Rector\Set\ValueObject\LevelSetList; use Rector\Set\ValueObject\SetList; -use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Utils\Rector\PassStrictParameterToFunctionParameterRector; use Utils\Rector\RemoveErrorSuppressInTryCatchStmtsRector; use Utils\Rector\RemoveVarTagFromClassConstantRector; use Utils\Rector\UnderscoreToCamelCaseVariableNameRector; -return static function (ContainerConfigurator $containerConfigurator): void { - $containerConfigurator->import(SetList::DEAD_CODE); - $containerConfigurator->import(LevelSetList::UP_TO_PHP_74); - $containerConfigurator->import(PHPUnitSetList::PHPUNIT_SPECIFIC_METHOD); - $containerConfigurator->import(PHPUnitSetList::PHPUNIT_80); +return static function (RectorConfig $rectorConfig): void { + $rectorConfig->sets([ + SetList::DEAD_CODE, + LevelSetList::UP_TO_PHP_74, + PHPUnitSetList::PHPUNIT_SPECIFIC_METHOD, + PHPUnitSetList::PHPUNIT_80, + ]); - $parameters = $containerConfigurator->parameters(); + $rectorConfig->parallel(); - $parameters->set(Option::PARALLEL, true); // paths to refactor; solid alternative to CLI arguments - $parameters->set(Option::PATHS, [__DIR__ . '/app', __DIR__ . '/system', __DIR__ . '/tests', __DIR__ . '/utils/Rector']); + $rectorConfig->paths([__DIR__ . '/app', __DIR__ . '/system', __DIR__ . '/tests', __DIR__ . '/utils/Rector']); // do you need to include constants, class aliases or custom autoloader? files listed will be executed - $parameters->set(Option::BOOTSTRAP_FILES, [ + $rectorConfig->bootstrapFiles([ __DIR__ . '/system/Test/bootstrap.php', ]); // is there a file you need to skip? - $parameters->set(Option::SKIP, [ + $rectorConfig->skip([ __DIR__ . '/app/Views', __DIR__ . '/system/Debug/Toolbar/Views/toolbar.tpl.php', __DIR__ . '/system/ThirdParty', @@ -124,42 +123,39 @@ ]); // auto import fully qualified class names - $parameters->set(Option::AUTO_IMPORT_NAMES, true); - - $services = $containerConfigurator->services(); - $services->set(UnderscoreToCamelCaseVariableNameRector::class); - $services->set(SimplifyUselessVariableRector::class); - $services->set(RemoveAlwaysElseRector::class); - $services->set(PassStrictParameterToFunctionParameterRector::class); - $services->set(CountArrayToEmptyArrayComparisonRector::class); - $services->set(ForToForeachRector::class); - $services->set(ChangeNestedForeachIfsToEarlyContinueRector::class); - $services->set(ChangeIfElseValueAssignToEarlyReturnRector::class); - $services->set(SimplifyStrposLowerRector::class); - $services->set(CombineIfRector::class); - $services->set(SimplifyIfReturnBoolRector::class); - $services->set(InlineIfToExplicitIfRector::class); - $services->set(PreparedValueToEarlyReturnRector::class); - $services->set(ShortenElseIfRector::class); - $services->set(SimplifyIfElseToTernaryRector::class); - $services->set(UnusedForeachValueToArrayKeysRector::class); - $services->set(ChangeArrayPushToArrayAssignRector::class); - $services->set(UnnecessaryTernaryExpressionRector::class); - $services->set(RemoveErrorSuppressInTryCatchStmtsRector::class); - $services->set(RemoveVarTagFromClassConstantRector::class); - $services->set(AddPregQuoteDelimiterRector::class); - $services->set(SimplifyRegexPatternRector::class); - $services->set(FuncGetArgsToVariadicParamRector::class); - $services->set(MakeInheritedMethodVisibilitySameAsParentRector::class); - $services->set(SimplifyEmptyArrayCheckRector::class); - $services->set(NormalizeNamespaceByPSR4ComposerAutoloadRector::class); - $services->set(StringClassNameToClassConstantRector::class) - ->configure([ - 'Error', - 'Exception', - 'InvalidArgumentException', - 'Closure', - 'stdClass', - 'SQLite3', - ]); + $rectorConfig->importNames(); + + $rectorConfig->rule(UnderscoreToCamelCaseVariableNameRector::class); + $rectorConfig->rule(RemoveAlwaysElseRector::class); + $rectorConfig->rule(PassStrictParameterToFunctionParameterRector::class); + $rectorConfig->rule(CountArrayToEmptyArrayComparisonRector::class); + $rectorConfig->rule(ForToForeachRector::class); + $rectorConfig->rule(ChangeNestedForeachIfsToEarlyContinueRector::class); + $rectorConfig->rule(ChangeIfElseValueAssignToEarlyReturnRector::class); + $rectorConfig->rule(SimplifyStrposLowerRector::class); + $rectorConfig->rule(CombineIfRector::class); + $rectorConfig->rule(SimplifyIfReturnBoolRector::class); + $rectorConfig->rule(InlineIfToExplicitIfRector::class); + $rectorConfig->rule(PreparedValueToEarlyReturnRector::class); + $rectorConfig->rule(ShortenElseIfRector::class); + $rectorConfig->rule(SimplifyIfElseToTernaryRector::class); + $rectorConfig->rule(UnusedForeachValueToArrayKeysRector::class); + $rectorConfig->rule(ChangeArrayPushToArrayAssignRector::class); + $rectorConfig->rule(UnnecessaryTernaryExpressionRector::class); + $rectorConfig->rule(RemoveErrorSuppressInTryCatchStmtsRector::class); + $rectorConfig->rule(RemoveVarTagFromClassConstantRector::class); + $rectorConfig->rule(AddPregQuoteDelimiterRector::class); + $rectorConfig->rule(SimplifyRegexPatternRector::class); + $rectorConfig->rule(FuncGetArgsToVariadicParamRector::class); + $rectorConfig->rule(MakeInheritedMethodVisibilitySameAsParentRector::class); + $rectorConfig->rule(SimplifyEmptyArrayCheckRector::class); + $rectorConfig->rule(NormalizeNamespaceByPSR4ComposerAutoloadRector::class); + $rectorConfig->ruleWithConfiguration(StringClassNameToClassConstantRector::class, [ + 'Error', + 'Exception', + 'InvalidArgumentException', + 'Closure', + 'stdClass', + 'SQLite3', + ]); }; From 4fd7ac58307590112e6bdb6add99c1d9d085e57f Mon Sep 17 00:00:00 2001 From: Chl Date: Mon, 18 Apr 2022 16:43:20 +0200 Subject: [PATCH 0877/1246] script_tag: changelog, doc + test with default arg --- system/Helpers/html_helper.php | 4 ++-- tests/system/Helpers/HTMLHelperTest.php | 10 ++++++++++ user_guide_src/source/changelogs/v4.2.0.rst | 1 + user_guide_src/source/helpers/html_helper.rst | 4 ++-- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/system/Helpers/html_helper.php b/system/Helpers/html_helper.php index a15b18ff47e8..c2e48d890fef 100755 --- a/system/Helpers/html_helper.php +++ b/system/Helpers/html_helper.php @@ -189,8 +189,8 @@ function doctype(string $type = 'html5'): string * * Generates link to a JS file * - * @param mixed $src Script source or an array - * @param bool $indexPage Should indexPage be added to the JS path + * @param array|string $src Script source or an array of attributes + * @param bool $indexPage Should indexPage be added to the JS path */ function script_tag($src = '', bool $indexPage = false): string { diff --git a/tests/system/Helpers/HTMLHelperTest.php b/tests/system/Helpers/HTMLHelperTest.php index 74b087228fdd..d539d7421be6 100755 --- a/tests/system/Helpers/HTMLHelperTest.php +++ b/tests/system/Helpers/HTMLHelperTest.php @@ -269,6 +269,16 @@ public function testScriptTagWithSrcAndAttributes() $this->assertSame($expected, script_tag($target)); } + /** + * This test has probably no real-world value but may help detecting + * a change in the default behaviour. + */ + public function testScriptTagWithoutAnyArg() + { + $expected = ''; + $this->assertSame($expected, script_tag()); + } + public function testLinkTag() { $target = 'css/mystyles.css'; diff --git a/user_guide_src/source/changelogs/v4.2.0.rst b/user_guide_src/source/changelogs/v4.2.0.rst index 0ed69ab0760a..fa88608dc355 100644 --- a/user_guide_src/source/changelogs/v4.2.0.rst +++ b/user_guide_src/source/changelogs/v4.2.0.rst @@ -38,6 +38,7 @@ Enhancements - The log format has also changed. If users are depending on the log format in their apps, the new log format is "<1-based count> (): " - Added support for webp files to **app/Config/Mimes.php**. - Added 4th parameter ``$includeDir`` to ``get_filenames()``. See :php:func:`get_filenames`. +- HTML helper ``script_tag()`` now uses ``null`` values to write boolean attributes in minimized form: `` + - -
    -
    -

    getCode() ? ' #' . $exception->getCode() : '') ?>

    -

    - getMessage())) ?> - getMessage())) ?>" - rel="noreferrer" target="_blank">search → -

    -
    -
    - - -
    -

    at line

    - - -
    - -
    - -
    - -
    - - - -
    - - -
    - -
      - $row) : ?> - -
    1. -

      - - - +

      +
      +

      getCode() ? ' #' . $exception->getCode() : '') ?>

      +

      + getMessage())) ?> + getMessage())) ?>" + rel="noreferrer" target="_blank">search → +

      +
      +
      + + +
      +

      at line

      + + +
      + +
      + +
      + +
      + + + +
      + + +
      + +
        + $row) : ?> + +
      1. +

        + + + - - {PHP internal code} - - - - -   —   - - - ( arguments ) -

        -
    - - + {PHP internal code} + + + + +   —   + + + ( arguments ) +
    +
    + + $value) : ?> - - - - - - -
    name : "#{$key}") ?>
    - - - () - - - - -   —   () - -

    - - - -
    - -
    - - - - - - - - - -
    - - + name : "#{$key}") ?> +
    + + + + +
    + + () + + + + +   —   () + +

    + + + +
    + +
    + + + + + + + + + +
    + + -

    $

    - - - - - - - - - - $value) : ?> - - - - - - -
    KeyValue
    - - - -
    - -
    - - - - - - -

    Constants

    - - - - - - - - - - $value) : ?> - - - - - - -
    KeyValue
    - - - -
    - -
    - -
    - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    PathgetUri()) ?>
    HTTP MethodgetMethod())) ?>
    IP AddressgetIPAddress()) ?>
    Is AJAX Request?isAJAX() ? 'yes' : 'no' ?>
    Is CLI Request?isCLI() ? 'yes' : 'no' ?>
    Is Secure Request?isSecure() ? 'yes' : 'no' ?>
    User AgentgetUserAgent()->getAgentString()) ?>
    - - - - - $ + + + + + + + + + + $value) : ?> + + + + + + +
    KeyValue
    + + + +
    + +
    + + + + + + +

    Constants

    + + + + + + + + + + $value) : ?> + + + + + + +
    KeyValue
    + + + +
    + +
    + +
    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    PathgetUri()) ?>
    HTTP MethodgetMethod())) ?>
    IP AddressgetIPAddress()) ?>
    Is AJAX Request?isAJAX() ? 'yes' : 'no' ?>
    Is CLI Request?isCLI() ? 'yes' : 'no' ?>
    Is Secure Request?isSecure() ? 'yes' : 'no' ?>
    User AgentgetUserAgent()->getAgentString()) ?>
    + + + + + - - -

    $

    - - - - - - - - - - $value) : ?> - - - - - - -
    KeyValue
    - - - -
    - -
    - - - - - -
    - No $_GET, $_POST, or $_COOKIE Information to show. -
    - - - - getHeaders(); ?> - - -

    Headers

    - - - - - - - - - - - + +

    $

    + +
    HeaderValue
    + + + + + + + + $value) : ?> + + + + + + +
    KeyValue
    + + + +
    + +
    + + + + + +
    + No $_GET, $_POST, or $_COOKIE Information to show. +
    + + + + getHeaders(); ?> + + +

    Headers

    + + + + + + + + + + + - - - - - - - - -
    HeaderValue
    getName(), 'html') ?>getValueLine(), 'html') ?>
    - - -
    - - - + + getName(), 'html') ?> + getValueLine(), 'html') ?> + + + + + + + + + + + setStatusCode(http_response_code()); ?> -
    - - - - - -
    Response StatusgetStatusCode() . ' - ' . $response->getReasonPhrase()) ?>
    - - getHeaders(); ?> - - - -

    Headers

    - - - - - - - - - - $value) : ?> - - - - - - -
    HeaderValue
    getHeaderLine($name), 'html') ?>
    - - -
    - - -
    - - -
      - -
    1. - -
    -
    - - -
    - - - - - - - - - - - - - - - - -
    Memory Usage
    Peak Memory Usage:
    Memory Limit:
    - -
    - - - - - - +
    + + + + + +
    Response StatusgetStatusCode() . ' - ' . $response->getReasonPhrase()) ?>
    + + getHeaders(); ?> + + + +

    Headers

    + + + + + + + + + + $value) : ?> + + + + + + +
    HeaderValue
    getHeaderLine($name), 'html') ?>
    + + +
    + + +
    + + +
      + +
    1. + +
    +
    + + +
    + + + + + + + + + + + + + + + + +
    Memory Usage
    Peak Memory Usage:
    Memory Limit:
    + +
    + + + + + + diff --git a/app/Views/errors/html/production.php b/app/Views/errors/html/production.php index cca49c2ed9c3..9faa4a15b783 100644 --- a/app/Views/errors/html/production.php +++ b/app/Views/errors/html/production.php @@ -1,24 +1,24 @@ - - + + - Whoops! + Whoops! - + -
    +
    -

    Whoops!

    +

    Whoops!

    -

    We seem to have hit a snag. Please try again later...

    +

    We seem to have hit a snag. Please try again later...

    -
    +
    diff --git a/app/Views/welcome_message.php b/app/Views/welcome_message.php index b982f58aa158..c66a9615c6be 100644 --- a/app/Views/welcome_message.php +++ b/app/Views/welcome_message.php @@ -1,229 +1,229 @@ - - Welcome to CodeIgniter 4! - - - - - - - + + Welcome to CodeIgniter 4! + + + + + + +
    - - -
    - -

    Welcome to CodeIgniter

    - -

    The small framework with powerful features

    - -
    + + +
    + +

    Welcome to CodeIgniter

    + +

    The small framework with powerful features

    + +
    @@ -231,91 +231,91 @@
    -

    About this page

    +

    About this page

    -

    The page you are looking at is being generated dynamically by CodeIgniter.

    +

    The page you are looking at is being generated dynamically by CodeIgniter.

    -

    If you would like to edit this page you will find it located at:

    +

    If you would like to edit this page you will find it located at:

    -
    app/Views/welcome_message.php
    +
    app/Views/welcome_message.php
    -

    The corresponding controller for this page can be found at:

    +

    The corresponding controller for this page can be found at:

    -
    app/Controllers/Home.php
    +
    app/Controllers/Home.php
    -
    +
    -

    Go further

    +

    Go further

    -

    - - Learn -

    +

    + + Learn +

    -

    The User Guide contains an introduction, tutorial, a number of "how to" - guides, and then reference documentation for the components that make up - the framework. Check the User Guide !

    +

    The User Guide contains an introduction, tutorial, a number of "how to" + guides, and then reference documentation for the components that make up + the framework. Check the User Guide !

    -

    - - Discuss -

    +

    + + Discuss +

    -

    CodeIgniter is a community-developed open source project, with several - venues for the community members to gather and exchange ideas. View all - the threads on CodeIgniter's forum, or chat on Slack !

    +

    CodeIgniter is a community-developed open source project, with several + venues for the community members to gather and exchange ideas. View all + the threads on CodeIgniter's forum, or chat on Slack !

    -

    - - Contribute -

    +

    + + Contribute +

    -

    CodeIgniter is a community driven project and accepts contributions - of code and documentation from the community. Why not - - join us ?

    +

    CodeIgniter is a community driven project and accepts contributions + of code and documentation from the community. Why not + + join us ?

    -
    +
    -
    +
    -

    Page rendered in {elapsed_time} seconds

    +

    Page rendered in {elapsed_time} seconds

    -

    Environment:

    +

    Environment:

    -
    +
    -
    +
    -

    © CodeIgniter Foundation. CodeIgniter is open source project released under the MIT - open source licence.

    +

    © CodeIgniter Foundation. CodeIgniter is open source project released under the MIT + open source licence.

    -
    +
    diff --git a/app/index.html b/app/index.html index b702fbc3967b..69df4e1dff68 100644 --- a/app/index.html +++ b/app/index.html @@ -1,7 +1,7 @@ - 403 Forbidden + 403 Forbidden diff --git a/system/Debug/Toolbar/Views/_config.tpl b/system/Debug/Toolbar/Views/_config.tpl index 3934cf62ebee..b6c7e0c3d86f 100644 --- a/system/Debug/Toolbar/Views/_config.tpl +++ b/system/Debug/Toolbar/Views/_config.tpl @@ -1,48 +1,48 @@

    - Read the CodeIgniter docs... + Read the CodeIgniter docs...

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CodeIgniter Version:{ ciVersion }
    PHP Version:{ phpVersion }
    PHP SAPI:{ phpSAPI }
    Environment:{ environment }
    Base URL: - { if $baseURL == '' } -
    - The $baseURL should always be set manually to prevent possible URL personification from external parties. -
    - { else } - { baseURL } - { endif } -
    Timezone:{ timezone }
    Locale:{ locale }
    Content Security Policy Enabled:{ if $cspEnabled } Yes { else } No { endif }
    CodeIgniter Version:{ ciVersion }
    PHP Version:{ phpVersion }
    PHP SAPI:{ phpSAPI }
    Environment:{ environment }
    Base URL: + { if $baseURL == '' } +
    + The $baseURL should always be set manually to prevent possible URL personification from external parties. +
    + { else } + { baseURL } + { endif } +
    Timezone:{ timezone }
    Locale:{ locale }
    Content Security Policy Enabled:{ if $cspEnabled } Yes { else } No { endif }
    diff --git a/system/Debug/Toolbar/Views/toolbar.js b/system/Debug/Toolbar/Views/toolbar.js index 3bd05d5e9592..7805a99dda05 100644 --- a/system/Debug/Toolbar/Views/toolbar.js +++ b/system/Debug/Toolbar/Views/toolbar.js @@ -4,684 +4,684 @@ var ciDebugBar = { - toolbarContainer : null, - toolbar : null, - icon : null, - - init : function () { - this.toolbarContainer = document.getElementById('toolbarContainer'); - this.toolbar = document.getElementById('debug-bar'); - this.icon = document.getElementById('debug-icon'); - - ciDebugBar.createListeners(); - ciDebugBar.setToolbarState(); - ciDebugBar.setToolbarPosition(); - ciDebugBar.setToolbarTheme(); - ciDebugBar.toggleViewsHints(); - ciDebugBar.routerLink(); - - document.getElementById('debug-bar-link').addEventListener('click', ciDebugBar.toggleToolbar, true); - document.getElementById('debug-icon-link').addEventListener('click', ciDebugBar.toggleToolbar, true); - - // Allows to highlight the row of the current history request - var btn = this.toolbar.querySelector('button[data-time="' + localStorage.getItem('debugbar-time') + '"]'); - ciDebugBar.addClass(btn.parentNode.parentNode, 'current'); - - historyLoad = this.toolbar.getElementsByClassName('ci-history-load'); - - for (var i = 0; i < historyLoad.length; i++) - { - historyLoad[i].addEventListener('click', function () { - loadDoc(this.getAttribute('data-time')); - }, true); - } - - // Display the active Tab on page load - var tab = ciDebugBar.readCookie('debug-bar-tab'); - if (document.getElementById(tab)) - { - var el = document.getElementById(tab); - el.style.display = 'block'; - ciDebugBar.addClass(el, 'active'); - tab = document.querySelector('[data-tab=' + tab + ']'); - if (tab) - { - ciDebugBar.addClass(tab.parentNode, 'active'); - } - } - }, - - createListeners : function () { - var buttons = [].slice.call(this.toolbar.querySelectorAll('.ci-label a')); - - for (var i = 0; i < buttons.length; i++) - { - buttons[i].addEventListener('click', ciDebugBar.showTab, true); - } - - // Hook up generic toggle via data attributes `data-toggle="foo"` - var links = this.toolbar.querySelectorAll('[data-toggle]'); - for (var i = 0; i < links.length; i++) - { - links[i].addEventListener('click', ciDebugBar.toggleRows, true); - } - }, - - showTab: function () { - // Get the target tab, if any - var tab = document.getElementById(this.getAttribute('data-tab')); - - // If the label have not a tab stops here - if (! tab) - { - return; - } - - // Remove debug-bar-tab cookie - ciDebugBar.createCookie('debug-bar-tab', '', -1); - - // Check our current state. - var state = tab.style.display; - - // Hide all tabs - var tabs = document.querySelectorAll('#debug-bar .tab'); - - for (var i = 0; i < tabs.length; i++) - { - tabs[i].style.display = 'none'; - } - - // Mark all labels as inactive - var labels = document.querySelectorAll('#debug-bar .ci-label'); - - for (var i = 0; i < labels.length; i++) - { - ciDebugBar.removeClass(labels[i], 'active'); - } - - // Show/hide the selected tab - if (state != 'block') - { - tab.style.display = 'block'; - ciDebugBar.addClass(this.parentNode, 'active'); - // Create debug-bar-tab cookie to persistent state - ciDebugBar.createCookie('debug-bar-tab', this.getAttribute('data-tab'), 365); - } - }, - - addClass : function (el, className) { - if (el.classList) - { - el.classList.add(className); - } - else - { - el.className += ' ' + className; - } - }, - - removeClass : function (el, className) { - if (el.classList) - { - el.classList.remove(className); - } - else - { - el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); - } - }, - - /** - * Toggle display of another object based on - * the data-toggle value of this object - * - * @param event - */ - toggleRows : function(event) { - if(event.target) - { - let row = event.target.closest('tr'); - let target = document.getElementById(row.getAttribute('data-toggle')); - target.style.display = target.style.display === 'none' ? 'table-row' : 'none'; - } - }, - - /** - * Toggle display of a data table - * - * @param obj - */ - toggleDataTable : function (obj) { - if (typeof obj == 'string') - { - obj = document.getElementById(obj + '_table'); - } - - if (obj) - { - obj.style.display = obj.style.display === 'none' ? 'block' : 'none'; - } - }, - - /** - * Toggle display of timeline child elements - * - * @param obj - */ - toggleChildRows : function (obj) { - if (typeof obj == 'string') - { - par = document.getElementById(obj + '_parent') - obj = document.getElementById(obj + '_children'); - } - - if (par && obj) - { - obj.style.display = obj.style.display === 'none' ? '' : 'none'; - par.classList.toggle('timeline-parent-open'); - } - }, - - - //-------------------------------------------------------------------- - - /** - * Toggle tool bar from full to icon and icon to full - */ - toggleToolbar : function () { - var open = ciDebugBar.toolbar.style.display != 'none'; - - ciDebugBar.icon.style.display = open == true ? 'inline-block' : 'none'; - ciDebugBar.toolbar.style.display = open == false ? 'inline-block' : 'none'; - - // Remember it for other page loads on this site - ciDebugBar.createCookie('debug-bar-state', '', -1); - ciDebugBar.createCookie('debug-bar-state', open == true ? 'minimized' : 'open' , 365); - }, - - /** - * Sets the initial state of the toolbar (open or minimized) when - * the page is first loaded to allow it to remember the state between refreshes. - */ - setToolbarState: function () { - var open = ciDebugBar.readCookie('debug-bar-state'); - - ciDebugBar.icon.style.display = open != 'open' ? 'inline-block' : 'none'; - ciDebugBar.toolbar.style.display = open == 'open' ? 'inline-block' : 'none'; - }, - - toggleViewsHints: function () { - // Avoid toggle hints on history requests that are not the initial - if (localStorage.getItem('debugbar-time') != localStorage.getItem('debugbar-time-new')) - { - var a = document.querySelector('a[data-tab="ci-views"]'); - a.href = '#'; - return; - } - - var nodeList = []; // [ Element, NewElement( 1 )/OldElement( 0 ) ] - var sortedComments = []; - var comments = []; - - var getComments = function () { - var nodes = []; - var result = []; - var xpathResults = document.evaluate( "//comment()[starts-with(., ' DEBUG-VIEW')]", document, null, XPathResult.ANY_TYPE, null); - var nextNode = xpathResults.iterateNext(); - while ( nextNode ) - { - nodes.push( nextNode ); - nextNode = xpathResults.iterateNext(); - } - - // sort comment by opening and closing tags - for (var i = 0; i < nodes.length; ++i) - { - // get file path + name to use as key - var path = nodes[i].nodeValue.substring( 18, nodes[i].nodeValue.length - 1 ); - - if ( nodes[i].nodeValue[12] === 'S' ) // simple check for start comment - { - // create new entry - result[path] = [ nodes[i], null ]; - } - else if (result[path]) - { - // add to existing entry - result[path][1] = nodes[i]; - } - } - - return result; - }; - - // find node that has TargetNode as parentNode - var getParentNode = function ( node, targetNode ) { - if ( node.parentNode === null ) - { - return null; - } - - if ( node.parentNode !== targetNode ) - { - return getParentNode( node.parentNode, targetNode ); - } - - return node; - }; - - // define invalid & outer ( also invalid ) elements - const INVALID_ELEMENTS = [ 'NOSCRIPT', 'SCRIPT', 'STYLE' ]; - const OUTER_ELEMENTS = [ 'HTML', 'BODY', 'HEAD' ]; - - var getValidElementInner = function ( node, reverse ) { - // handle invalid tags - if ( OUTER_ELEMENTS.indexOf( node.nodeName ) !== -1 ) - { - for (var i = 0; i < document.body.children.length; ++i) - { - var index = reverse ? document.body.children.length - ( i + 1 ) : i; - var element = document.body.children[index]; - - // skip invalid tags - if ( INVALID_ELEMENTS.indexOf( element.nodeName ) !== -1 ) - { - continue; - } - - return [ element, reverse ]; - } - - return null; - } - - // get to next valid element - while ( node !== null && INVALID_ELEMENTS.indexOf( node.nodeName ) !== -1 ) - { - node = reverse ? node.previousElementSibling : node.nextElementSibling; - } - - // return non array if we couldnt find something - if ( node === null ) - { - return null; - } - - return [ node, reverse ]; - }; - - // get next valid element ( to be safe to add divs ) - // @return [ element, skip element ] or null if we couldnt find a valid place - var getValidElement = function ( nodeElement ) { - if (nodeElement) - { - if ( nodeElement.nextElementSibling !== null ) - { - return getValidElementInner( nodeElement.nextElementSibling, false ) - || getValidElementInner( nodeElement.previousElementSibling, true ); - } - if ( nodeElement.previousElementSibling !== null ) - { - return getValidElementInner( nodeElement.previousElementSibling, true ); - } - } - - // something went wrong! -> element is not in DOM - return null; - }; - - function showHints() - { - // Had AJAX? Reset view blocks - sortedComments = getComments(); - - for (var key in sortedComments) - { - var startElement = getValidElement( sortedComments[key][0] ); - var endElement = getValidElement( sortedComments[key][1] ); - - // skip if we couldnt get a valid element - if ( startElement === null || endElement === null ) - { - continue; - } - - // find element which has same parent as startelement - var jointParent = getParentNode( endElement[0], startElement[0].parentNode ); - if ( jointParent === null ) - { - // find element which has same parent as endelement - jointParent = getParentNode( startElement[0], endElement[0].parentNode ); - if ( jointParent === null ) - { - // both tries failed - continue; - } - else - { - startElement[0] = jointParent; - } - } - else - { - endElement[0] = jointParent; - } - - var debugDiv = document.createElement( 'div' ); // holder - var debugPath = document.createElement( 'div' ); // path - var childArray = startElement[0].parentNode.childNodes; // target child array - var parent = startElement[0].parentNode; - var start, end; - - // setup container - debugDiv.classList.add( 'debug-view' ); - debugDiv.classList.add( 'show-view' ); - debugPath.classList.add( 'debug-view-path' ); - debugPath.innerText = key; - debugDiv.appendChild( debugPath ); - - // calc distance between them - // start - for (var i = 0; i < childArray.length; ++i) - { - // check for comment ( start & end ) -> if its before valid start element - if ( childArray[i] === sortedComments[key][1] || - childArray[i] === sortedComments[key][0] || - childArray[i] === startElement[0] ) - { - start = i; - if ( childArray[i] === sortedComments[key][0] ) - { - start++; // increase to skip the start comment - } - break; - } - } - // adjust if we want to skip the start element - if ( startElement[1] ) - { - start++; - } - - // end - for (var i = start; i < childArray.length; ++i) - { - if ( childArray[i] === endElement[0] ) - { - end = i; - // dont break to check for end comment after end valid element - } - else if ( childArray[i] === sortedComments[key][1] ) - { - // if we found the end comment, we can break - end = i; - break; - } - } - - // move elements - var number = end - start; - if ( endElement[1] ) - { - number++; - } - for (var i = 0; i < number; ++i) - { - if ( INVALID_ELEMENTS.indexOf( childArray[start] ) !== -1 ) - { - // skip invalid childs that can cause problems if moved - start++; - continue; - } - debugDiv.appendChild( childArray[start] ); - } - - // add container to DOM - nodeList.push( parent.insertBefore( debugDiv, childArray[start] ) ); - } - - ciDebugBar.createCookie('debug-view', 'show', 365); - ciDebugBar.addClass(btn, 'active'); - } - - function hideHints() - { - for (var i = 0; i < nodeList.length; ++i) - { - var index; - - // find index - for (var j = 0; j < nodeList[i].parentNode.childNodes.length; ++j) - { - if ( nodeList[i].parentNode.childNodes[j] === nodeList[i] ) - { - index = j; - break; - } - } - - // move child back - while ( nodeList[i].childNodes.length !== 1 ) - { - nodeList[i].parentNode.insertBefore( nodeList[i].childNodes[1], nodeList[i].parentNode.childNodes[index].nextSibling ); - index++; - } - - nodeList[i].parentNode.removeChild( nodeList[i] ); - } - nodeList.length = 0; - - ciDebugBar.createCookie('debug-view', '', -1); - ciDebugBar.removeClass(btn, 'active'); - } - - var btn = document.querySelector('[data-tab=ci-views]'); - - // If the Views Collector is inactive stops here - if (! btn) - { - return; - } - - btn.parentNode.onclick = function () { - if (ciDebugBar.readCookie('debug-view')) - { - hideHints(); - } - else - { - showHints(); - } - }; - - // Determine Hints state on page load - if (ciDebugBar.readCookie('debug-view')) - { - showHints(); - } - }, - - setToolbarPosition: function () { - var btnPosition = this.toolbar.querySelector('#toolbar-position'); - - if (ciDebugBar.readCookie('debug-bar-position') === 'top') - { - ciDebugBar.addClass(ciDebugBar.icon, 'fixed-top'); - ciDebugBar.addClass(ciDebugBar.toolbar, 'fixed-top'); - } - - btnPosition.addEventListener('click', function () { - var position = ciDebugBar.readCookie('debug-bar-position'); - - ciDebugBar.createCookie('debug-bar-position', '', -1); - - if (!position || position === 'bottom') - { - ciDebugBar.createCookie('debug-bar-position', 'top', 365); - ciDebugBar.addClass(ciDebugBar.icon, 'fixed-top'); - ciDebugBar.addClass(ciDebugBar.toolbar, 'fixed-top'); - } - else - { - ciDebugBar.createCookie('debug-bar-position', 'bottom', 365); - ciDebugBar.removeClass(ciDebugBar.icon, 'fixed-top'); - ciDebugBar.removeClass(ciDebugBar.toolbar, 'fixed-top'); - } - }, true); - }, - - setToolbarTheme: function () { - var btnTheme = this.toolbar.querySelector('#toolbar-theme'); - var isDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches; - var isLightMode = window.matchMedia("(prefers-color-scheme: light)").matches; - - // If a cookie is set with a value, we force the color scheme - if (ciDebugBar.readCookie('debug-bar-theme') === 'dark') - { - ciDebugBar.removeClass(ciDebugBar.toolbarContainer, 'light'); - ciDebugBar.addClass(ciDebugBar.toolbarContainer, 'dark'); - } - else if (ciDebugBar.readCookie('debug-bar-theme') === 'light') - { - ciDebugBar.removeClass(ciDebugBar.toolbarContainer, 'dark'); - ciDebugBar.addClass(ciDebugBar.toolbarContainer, 'light'); - } - - btnTheme.addEventListener('click', function () { - var theme = ciDebugBar.readCookie('debug-bar-theme'); - - if (!theme && window.matchMedia("(prefers-color-scheme: dark)").matches) - { - // If there is no cookie, and "prefers-color-scheme" is set to "dark" - // It means that the user wants to switch to light mode - ciDebugBar.createCookie('debug-bar-theme', 'light', 365); - ciDebugBar.removeClass(ciDebugBar.toolbarContainer, 'dark'); - ciDebugBar.addClass(ciDebugBar.toolbarContainer, 'light'); - } - else - { - if (theme === 'dark') - { - ciDebugBar.createCookie('debug-bar-theme', 'light', 365); - ciDebugBar.removeClass(ciDebugBar.toolbarContainer, 'dark'); - ciDebugBar.addClass(ciDebugBar.toolbarContainer, 'light'); - } - else - { - // In any other cases: if there is no cookie, or the cookie is set to - // "light", or the "prefers-color-scheme" is "light"... - ciDebugBar.createCookie('debug-bar-theme', 'dark', 365); - ciDebugBar.removeClass(ciDebugBar.toolbarContainer, 'light'); - ciDebugBar.addClass(ciDebugBar.toolbarContainer, 'dark'); - } - } - }, true); - }, - - /** - * Helper to create a cookie. - * - * @param name - * @param value - * @param days - */ - createCookie : function (name,value,days) { - if (days) - { - var date = new Date(); - - date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); - - var expires = "; expires=" + date.toGMTString(); - } - else - { - var expires = ""; - } - - document.cookie = name + "=" + value + expires + "; path=/; samesite=Lax"; - }, - - readCookie : function (name) { - var nameEQ = name + "="; - var ca = document.cookie.split(';'); - - for (var i = 0; i < ca.length; i++) - { - var c = ca[i]; - while (c.charAt(0) == ' ') - { - c = c.substring(1,c.length); - } - if (c.indexOf(nameEQ) == 0) - { - return c.substring(nameEQ.length,c.length); - } - } - return null; - }, - - trimSlash: function (text) { - return text.replace(/^\/|\/$/g, ''); - }, - - routerLink: function () { - var row, _location; - var rowGet = this.toolbar.querySelectorAll('td[data-debugbar-route="GET"]'); - var patt = /\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)/; - - for (var i = 0; i < rowGet.length; i++) - { - row = rowGet[i]; - if (!/\/\(.+?\)/.test(rowGet[i].innerText)) - { - row.style = 'cursor: pointer;'; - row.setAttribute('title', location.origin + '/' + ciDebugBar.trimSlash(row.innerText)); - row.addEventListener('click', function (ev) { - _location = location.origin + '/' + ciDebugBar.trimSlash(ev.target.innerText); - var redirectWindow = window.open(_location, '_blank'); - redirectWindow.location; - }); - } - else - { - row.innerHTML = '
    ' + row.innerText + '
    ' - + '
    ' - + row.innerText.replace(patt, '') - + '' - + '
    '; - } - } - - rowGet = this.toolbar.querySelectorAll('td[data-debugbar-route="GET"] form'); - for (var i = 0; i < rowGet.length; i++) - { - row = rowGet[i]; - - row.addEventListener('submit', function (event) { - event.preventDefault() - var inputArray = [], t = 0; - var input = event.target.querySelectorAll('input[type=text]'); - var tpl = event.target.getAttribute('data-debugbar-route-tpl'); - - for (var n = 0; n < input.length; n++) - { - if (input[n].value.length > 0) - { - inputArray.push(input[n].value); - } - } - - if (inputArray.length > 0) - { - _location = location.origin + '/' + tpl.replace(/\?/g, function () { - return inputArray[t++] - }); - - var redirectWindow = window.open(_location, '_blank'); - redirectWindow.location; - } - }) - } - } + toolbarContainer : null, + toolbar : null, + icon : null, + + init : function () { + this.toolbarContainer = document.getElementById('toolbarContainer'); + this.toolbar = document.getElementById('debug-bar'); + this.icon = document.getElementById('debug-icon'); + + ciDebugBar.createListeners(); + ciDebugBar.setToolbarState(); + ciDebugBar.setToolbarPosition(); + ciDebugBar.setToolbarTheme(); + ciDebugBar.toggleViewsHints(); + ciDebugBar.routerLink(); + + document.getElementById('debug-bar-link').addEventListener('click', ciDebugBar.toggleToolbar, true); + document.getElementById('debug-icon-link').addEventListener('click', ciDebugBar.toggleToolbar, true); + + // Allows to highlight the row of the current history request + var btn = this.toolbar.querySelector('button[data-time="' + localStorage.getItem('debugbar-time') + '"]'); + ciDebugBar.addClass(btn.parentNode.parentNode, 'current'); + + historyLoad = this.toolbar.getElementsByClassName('ci-history-load'); + + for (var i = 0; i < historyLoad.length; i++) + { + historyLoad[i].addEventListener('click', function () { + loadDoc(this.getAttribute('data-time')); + }, true); + } + + // Display the active Tab on page load + var tab = ciDebugBar.readCookie('debug-bar-tab'); + if (document.getElementById(tab)) + { + var el = document.getElementById(tab); + el.style.display = 'block'; + ciDebugBar.addClass(el, 'active'); + tab = document.querySelector('[data-tab=' + tab + ']'); + if (tab) + { + ciDebugBar.addClass(tab.parentNode, 'active'); + } + } + }, + + createListeners : function () { + var buttons = [].slice.call(this.toolbar.querySelectorAll('.ci-label a')); + + for (var i = 0; i < buttons.length; i++) + { + buttons[i].addEventListener('click', ciDebugBar.showTab, true); + } + + // Hook up generic toggle via data attributes `data-toggle="foo"` + var links = this.toolbar.querySelectorAll('[data-toggle]'); + for (var i = 0; i < links.length; i++) + { + links[i].addEventListener('click', ciDebugBar.toggleRows, true); + } + }, + + showTab: function () { + // Get the target tab, if any + var tab = document.getElementById(this.getAttribute('data-tab')); + + // If the label have not a tab stops here + if (! tab) + { + return; + } + + // Remove debug-bar-tab cookie + ciDebugBar.createCookie('debug-bar-tab', '', -1); + + // Check our current state. + var state = tab.style.display; + + // Hide all tabs + var tabs = document.querySelectorAll('#debug-bar .tab'); + + for (var i = 0; i < tabs.length; i++) + { + tabs[i].style.display = 'none'; + } + + // Mark all labels as inactive + var labels = document.querySelectorAll('#debug-bar .ci-label'); + + for (var i = 0; i < labels.length; i++) + { + ciDebugBar.removeClass(labels[i], 'active'); + } + + // Show/hide the selected tab + if (state != 'block') + { + tab.style.display = 'block'; + ciDebugBar.addClass(this.parentNode, 'active'); + // Create debug-bar-tab cookie to persistent state + ciDebugBar.createCookie('debug-bar-tab', this.getAttribute('data-tab'), 365); + } + }, + + addClass : function (el, className) { + if (el.classList) + { + el.classList.add(className); + } + else + { + el.className += ' ' + className; + } + }, + + removeClass : function (el, className) { + if (el.classList) + { + el.classList.remove(className); + } + else + { + el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); + } + }, + + /** + * Toggle display of another object based on + * the data-toggle value of this object + * + * @param event + */ + toggleRows : function(event) { + if(event.target) + { + let row = event.target.closest('tr'); + let target = document.getElementById(row.getAttribute('data-toggle')); + target.style.display = target.style.display === 'none' ? 'table-row' : 'none'; + } + }, + + /** + * Toggle display of a data table + * + * @param obj + */ + toggleDataTable : function (obj) { + if (typeof obj == 'string') + { + obj = document.getElementById(obj + '_table'); + } + + if (obj) + { + obj.style.display = obj.style.display === 'none' ? 'block' : 'none'; + } + }, + + /** + * Toggle display of timeline child elements + * + * @param obj + */ + toggleChildRows : function (obj) { + if (typeof obj == 'string') + { + par = document.getElementById(obj + '_parent') + obj = document.getElementById(obj + '_children'); + } + + if (par && obj) + { + obj.style.display = obj.style.display === 'none' ? '' : 'none'; + par.classList.toggle('timeline-parent-open'); + } + }, + + + //-------------------------------------------------------------------- + + /** + * Toggle tool bar from full to icon and icon to full + */ + toggleToolbar : function () { + var open = ciDebugBar.toolbar.style.display != 'none'; + + ciDebugBar.icon.style.display = open == true ? 'inline-block' : 'none'; + ciDebugBar.toolbar.style.display = open == false ? 'inline-block' : 'none'; + + // Remember it for other page loads on this site + ciDebugBar.createCookie('debug-bar-state', '', -1); + ciDebugBar.createCookie('debug-bar-state', open == true ? 'minimized' : 'open' , 365); + }, + + /** + * Sets the initial state of the toolbar (open or minimized) when + * the page is first loaded to allow it to remember the state between refreshes. + */ + setToolbarState: function () { + var open = ciDebugBar.readCookie('debug-bar-state'); + + ciDebugBar.icon.style.display = open != 'open' ? 'inline-block' : 'none'; + ciDebugBar.toolbar.style.display = open == 'open' ? 'inline-block' : 'none'; + }, + + toggleViewsHints: function () { + // Avoid toggle hints on history requests that are not the initial + if (localStorage.getItem('debugbar-time') != localStorage.getItem('debugbar-time-new')) + { + var a = document.querySelector('a[data-tab="ci-views"]'); + a.href = '#'; + return; + } + + var nodeList = []; // [ Element, NewElement( 1 )/OldElement( 0 ) ] + var sortedComments = []; + var comments = []; + + var getComments = function () { + var nodes = []; + var result = []; + var xpathResults = document.evaluate( "//comment()[starts-with(., ' DEBUG-VIEW')]", document, null, XPathResult.ANY_TYPE, null); + var nextNode = xpathResults.iterateNext(); + while ( nextNode ) + { + nodes.push( nextNode ); + nextNode = xpathResults.iterateNext(); + } + + // sort comment by opening and closing tags + for (var i = 0; i < nodes.length; ++i) + { + // get file path + name to use as key + var path = nodes[i].nodeValue.substring( 18, nodes[i].nodeValue.length - 1 ); + + if ( nodes[i].nodeValue[12] === 'S' ) // simple check for start comment + { + // create new entry + result[path] = [ nodes[i], null ]; + } + else if (result[path]) + { + // add to existing entry + result[path][1] = nodes[i]; + } + } + + return result; + }; + + // find node that has TargetNode as parentNode + var getParentNode = function ( node, targetNode ) { + if ( node.parentNode === null ) + { + return null; + } + + if ( node.parentNode !== targetNode ) + { + return getParentNode( node.parentNode, targetNode ); + } + + return node; + }; + + // define invalid & outer ( also invalid ) elements + const INVALID_ELEMENTS = [ 'NOSCRIPT', 'SCRIPT', 'STYLE' ]; + const OUTER_ELEMENTS = [ 'HTML', 'BODY', 'HEAD' ]; + + var getValidElementInner = function ( node, reverse ) { + // handle invalid tags + if ( OUTER_ELEMENTS.indexOf( node.nodeName ) !== -1 ) + { + for (var i = 0; i < document.body.children.length; ++i) + { + var index = reverse ? document.body.children.length - ( i + 1 ) : i; + var element = document.body.children[index]; + + // skip invalid tags + if ( INVALID_ELEMENTS.indexOf( element.nodeName ) !== -1 ) + { + continue; + } + + return [ element, reverse ]; + } + + return null; + } + + // get to next valid element + while ( node !== null && INVALID_ELEMENTS.indexOf( node.nodeName ) !== -1 ) + { + node = reverse ? node.previousElementSibling : node.nextElementSibling; + } + + // return non array if we couldnt find something + if ( node === null ) + { + return null; + } + + return [ node, reverse ]; + }; + + // get next valid element ( to be safe to add divs ) + // @return [ element, skip element ] or null if we couldnt find a valid place + var getValidElement = function ( nodeElement ) { + if (nodeElement) + { + if ( nodeElement.nextElementSibling !== null ) + { + return getValidElementInner( nodeElement.nextElementSibling, false ) + || getValidElementInner( nodeElement.previousElementSibling, true ); + } + if ( nodeElement.previousElementSibling !== null ) + { + return getValidElementInner( nodeElement.previousElementSibling, true ); + } + } + + // something went wrong! -> element is not in DOM + return null; + }; + + function showHints() + { + // Had AJAX? Reset view blocks + sortedComments = getComments(); + + for (var key in sortedComments) + { + var startElement = getValidElement( sortedComments[key][0] ); + var endElement = getValidElement( sortedComments[key][1] ); + + // skip if we couldnt get a valid element + if ( startElement === null || endElement === null ) + { + continue; + } + + // find element which has same parent as startelement + var jointParent = getParentNode( endElement[0], startElement[0].parentNode ); + if ( jointParent === null ) + { + // find element which has same parent as endelement + jointParent = getParentNode( startElement[0], endElement[0].parentNode ); + if ( jointParent === null ) + { + // both tries failed + continue; + } + else + { + startElement[0] = jointParent; + } + } + else + { + endElement[0] = jointParent; + } + + var debugDiv = document.createElement( 'div' ); // holder + var debugPath = document.createElement( 'div' ); // path + var childArray = startElement[0].parentNode.childNodes; // target child array + var parent = startElement[0].parentNode; + var start, end; + + // setup container + debugDiv.classList.add( 'debug-view' ); + debugDiv.classList.add( 'show-view' ); + debugPath.classList.add( 'debug-view-path' ); + debugPath.innerText = key; + debugDiv.appendChild( debugPath ); + + // calc distance between them + // start + for (var i = 0; i < childArray.length; ++i) + { + // check for comment ( start & end ) -> if its before valid start element + if ( childArray[i] === sortedComments[key][1] || + childArray[i] === sortedComments[key][0] || + childArray[i] === startElement[0] ) + { + start = i; + if ( childArray[i] === sortedComments[key][0] ) + { + start++; // increase to skip the start comment + } + break; + } + } + // adjust if we want to skip the start element + if ( startElement[1] ) + { + start++; + } + + // end + for (var i = start; i < childArray.length; ++i) + { + if ( childArray[i] === endElement[0] ) + { + end = i; + // dont break to check for end comment after end valid element + } + else if ( childArray[i] === sortedComments[key][1] ) + { + // if we found the end comment, we can break + end = i; + break; + } + } + + // move elements + var number = end - start; + if ( endElement[1] ) + { + number++; + } + for (var i = 0; i < number; ++i) + { + if ( INVALID_ELEMENTS.indexOf( childArray[start] ) !== -1 ) + { + // skip invalid childs that can cause problems if moved + start++; + continue; + } + debugDiv.appendChild( childArray[start] ); + } + + // add container to DOM + nodeList.push( parent.insertBefore( debugDiv, childArray[start] ) ); + } + + ciDebugBar.createCookie('debug-view', 'show', 365); + ciDebugBar.addClass(btn, 'active'); + } + + function hideHints() + { + for (var i = 0; i < nodeList.length; ++i) + { + var index; + + // find index + for (var j = 0; j < nodeList[i].parentNode.childNodes.length; ++j) + { + if ( nodeList[i].parentNode.childNodes[j] === nodeList[i] ) + { + index = j; + break; + } + } + + // move child back + while ( nodeList[i].childNodes.length !== 1 ) + { + nodeList[i].parentNode.insertBefore( nodeList[i].childNodes[1], nodeList[i].parentNode.childNodes[index].nextSibling ); + index++; + } + + nodeList[i].parentNode.removeChild( nodeList[i] ); + } + nodeList.length = 0; + + ciDebugBar.createCookie('debug-view', '', -1); + ciDebugBar.removeClass(btn, 'active'); + } + + var btn = document.querySelector('[data-tab=ci-views]'); + + // If the Views Collector is inactive stops here + if (! btn) + { + return; + } + + btn.parentNode.onclick = function () { + if (ciDebugBar.readCookie('debug-view')) + { + hideHints(); + } + else + { + showHints(); + } + }; + + // Determine Hints state on page load + if (ciDebugBar.readCookie('debug-view')) + { + showHints(); + } + }, + + setToolbarPosition: function () { + var btnPosition = this.toolbar.querySelector('#toolbar-position'); + + if (ciDebugBar.readCookie('debug-bar-position') === 'top') + { + ciDebugBar.addClass(ciDebugBar.icon, 'fixed-top'); + ciDebugBar.addClass(ciDebugBar.toolbar, 'fixed-top'); + } + + btnPosition.addEventListener('click', function () { + var position = ciDebugBar.readCookie('debug-bar-position'); + + ciDebugBar.createCookie('debug-bar-position', '', -1); + + if (!position || position === 'bottom') + { + ciDebugBar.createCookie('debug-bar-position', 'top', 365); + ciDebugBar.addClass(ciDebugBar.icon, 'fixed-top'); + ciDebugBar.addClass(ciDebugBar.toolbar, 'fixed-top'); + } + else + { + ciDebugBar.createCookie('debug-bar-position', 'bottom', 365); + ciDebugBar.removeClass(ciDebugBar.icon, 'fixed-top'); + ciDebugBar.removeClass(ciDebugBar.toolbar, 'fixed-top'); + } + }, true); + }, + + setToolbarTheme: function () { + var btnTheme = this.toolbar.querySelector('#toolbar-theme'); + var isDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches; + var isLightMode = window.matchMedia("(prefers-color-scheme: light)").matches; + + // If a cookie is set with a value, we force the color scheme + if (ciDebugBar.readCookie('debug-bar-theme') === 'dark') + { + ciDebugBar.removeClass(ciDebugBar.toolbarContainer, 'light'); + ciDebugBar.addClass(ciDebugBar.toolbarContainer, 'dark'); + } + else if (ciDebugBar.readCookie('debug-bar-theme') === 'light') + { + ciDebugBar.removeClass(ciDebugBar.toolbarContainer, 'dark'); + ciDebugBar.addClass(ciDebugBar.toolbarContainer, 'light'); + } + + btnTheme.addEventListener('click', function () { + var theme = ciDebugBar.readCookie('debug-bar-theme'); + + if (!theme && window.matchMedia("(prefers-color-scheme: dark)").matches) + { + // If there is no cookie, and "prefers-color-scheme" is set to "dark" + // It means that the user wants to switch to light mode + ciDebugBar.createCookie('debug-bar-theme', 'light', 365); + ciDebugBar.removeClass(ciDebugBar.toolbarContainer, 'dark'); + ciDebugBar.addClass(ciDebugBar.toolbarContainer, 'light'); + } + else + { + if (theme === 'dark') + { + ciDebugBar.createCookie('debug-bar-theme', 'light', 365); + ciDebugBar.removeClass(ciDebugBar.toolbarContainer, 'dark'); + ciDebugBar.addClass(ciDebugBar.toolbarContainer, 'light'); + } + else + { + // In any other cases: if there is no cookie, or the cookie is set to + // "light", or the "prefers-color-scheme" is "light"... + ciDebugBar.createCookie('debug-bar-theme', 'dark', 365); + ciDebugBar.removeClass(ciDebugBar.toolbarContainer, 'light'); + ciDebugBar.addClass(ciDebugBar.toolbarContainer, 'dark'); + } + } + }, true); + }, + + /** + * Helper to create a cookie. + * + * @param name + * @param value + * @param days + */ + createCookie : function (name,value,days) { + if (days) + { + var date = new Date(); + + date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); + + var expires = "; expires=" + date.toGMTString(); + } + else + { + var expires = ""; + } + + document.cookie = name + "=" + value + expires + "; path=/; samesite=Lax"; + }, + + readCookie : function (name) { + var nameEQ = name + "="; + var ca = document.cookie.split(';'); + + for (var i = 0; i < ca.length; i++) + { + var c = ca[i]; + while (c.charAt(0) == ' ') + { + c = c.substring(1,c.length); + } + if (c.indexOf(nameEQ) == 0) + { + return c.substring(nameEQ.length,c.length); + } + } + return null; + }, + + trimSlash: function (text) { + return text.replace(/^\/|\/$/g, ''); + }, + + routerLink: function () { + var row, _location; + var rowGet = this.toolbar.querySelectorAll('td[data-debugbar-route="GET"]'); + var patt = /\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)/; + + for (var i = 0; i < rowGet.length; i++) + { + row = rowGet[i]; + if (!/\/\(.+?\)/.test(rowGet[i].innerText)) + { + row.style = 'cursor: pointer;'; + row.setAttribute('title', location.origin + '/' + ciDebugBar.trimSlash(row.innerText)); + row.addEventListener('click', function (ev) { + _location = location.origin + '/' + ciDebugBar.trimSlash(ev.target.innerText); + var redirectWindow = window.open(_location, '_blank'); + redirectWindow.location; + }); + } + else + { + row.innerHTML = '
    ' + row.innerText + '
    ' + + '
    ' + + row.innerText.replace(patt, '') + + '' + + '
    '; + } + } + + rowGet = this.toolbar.querySelectorAll('td[data-debugbar-route="GET"] form'); + for (var i = 0; i < rowGet.length; i++) + { + row = rowGet[i]; + + row.addEventListener('submit', function (event) { + event.preventDefault() + var inputArray = [], t = 0; + var input = event.target.querySelectorAll('input[type=text]'); + var tpl = event.target.getAttribute('data-debugbar-route-tpl'); + + for (var n = 0; n < input.length; n++) + { + if (input[n].value.length > 0) + { + inputArray.push(input[n].value); + } + } + + if (inputArray.length > 0) + { + _location = location.origin + '/' + tpl.replace(/\?/g, function () { + return inputArray[t++] + }); + + var redirectWindow = window.open(_location, '_blank'); + redirectWindow.location; + } + }) + } + } }; diff --git a/system/Debug/Toolbar/Views/toolbar.tpl.php b/system/Debug/Toolbar/Views/toolbar.tpl.php index 077fc9f070ba..0e73076f0e02 100644 --- a/system/Debug/Toolbar/Views/toolbar.tpl.php +++ b/system/Debug/Toolbar/Views/toolbar.tpl.php @@ -19,250 +19,250 @@ */ ?>
    -
    - - 🔅 - - - - ms   MB - - +
    + + 🔅 + + + + ms   MB + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - Vars - - + + + + Vars + + -

    - - - - - - -

    +

    + + + + + + +

    - - - - -
    + + + + +
    - -
    - - - - - - - - - - - - - renderTimeline($collectors, $startTime, $segmentCount, $segmentDuration, $styles) ?> - -
    NAMECOMPONENTDURATION ms
    -
    + +
    + + + + + + + + + + + + + renderTimeline($collectors, $startTime, $segmentCount, $segmentDuration, $styles) ?> + +
    NAMECOMPONENTDURATION ms
    +
    - - - - -
    -

    + + + + +
    +

    - setData($c['display'])->render("_{$c['titleSafe']}.tpl") ?> -
    - - - + setData($c['display'])->render("_{$c['titleSafe']}.tpl") ?> +
    + + + - -
    + +
    - - - $items) : ?> + + + $items) : ?> - -

    -
    + +

    +
    - + - - - $value) : ?> - - - - - - -
    + + + $value) : ?> + + + + + + +
    - -

    No data to display.

    - - - + +

    No data to display.

    + + + - - -

    Session User Data

    -
    + + +

    Session User Data

    +
    - - - - - $value) : ?> - - - - - - -
    - -

    No data to display.

    - - -

    Session doesn't seem to be active.

    - + + + + + $value) : ?> + + + + + + +
    + +

    No data to display.

    + + +

    Session doesn't seem to be active.

    + -

    Request ( )

    +

    Request ( )

    - - -

    $_GET

    -
    + + +

    $_GET

    +
    - - - $value) : ?> - - - - - - -
    - + + + $value) : ?> + + + + + + +
    + - - -

    $_POST

    -
    + + +

    $_POST

    +
    - - - $value) : ?> - - - - - - -
    - + + + $value) : ?> + + + + + + +
    + - - -

    Headers

    -
    + + +

    Headers

    +
    - - - $value) : ?> - - - - - - -
    - + + + $value) : ?> + + + + + + +
    + - - -

    Cookies

    -
    + + +

    Cookies

    +
    - - - $value) : ?> - - - - - - - - + + + $value) : ?> + + + + + + + + -

    Response - ( ) -

    +

    Response + ( ) +

    - - -

    Headers

    -
    + + +

    Headers

    +
    - - - $value) : ?> - - - - - - -
    - -
    + + + $value) : ?> + + + + + + +
    + +
    - -
    -

    System Configuration

    + +
    +

    System Configuration

    - setData($config)->render('_config.tpl') ?> -
    + setData($config)->render('_config.tpl') ?> +