diff --git a/.github/.markdownlint-cli2.jsonc b/.github/.markdownlint-cli2.jsonc
new file mode 100644
index 0000000000..c1a37a8ee1
--- /dev/null
+++ b/.github/.markdownlint-cli2.jsonc
@@ -0,0 +1,83 @@
+{
+ "config": {
+ "default": true,
+ "heading-increment": true,
+ "no-hard-tabs": true,
+ "no-multiple-blanks": true,
+ "line-length": false,
+ "commands-show-output": true,
+ "blanks-around-headings": true,
+ "heading-start-left": true,
+ "no-duplicate-heading": false,
+ "single-h1": false,
+ "no-trailing-punctuation": false,
+ "no-blanks-blockquote": false,
+ "list-marker-space": true,
+ "blanks-around-fences": true,
+ "blanks-around-lists": true,
+ "no-inline-html": {
+ "allowed_elements": [
+ "Badge",
+ "div",
+ "span",
+ "br",
+ "style",
+ "details",
+ "summary",
+ "table",
+ "thead",
+ "tbody",
+ "tr",
+ "th",
+ "td",
+ "img",
+ "a",
+ "svg",
+ "path",
+ "figure",
+ "p",
+ "colgroup",
+ "col",
+ "strong",
+ "sup",
+ "section",
+ "hr",
+ "ol",
+ "ul",
+ "li",
+ "em",
+ "code"
+ ]
+ },
+ "no-bare-urls": true,
+ "fenced-code-language": true,
+ "first-line-heading": false,
+ "code-block-style": false,
+ "code-fence-style": {
+ "style": "backtick"
+ },
+ "emphasis-style": {
+ "style": "asterisk"
+ },
+ "strong-style": {
+ "style": "asterisk"
+ },
+ "spaces-after-emphasis-marker": true,
+ "spaces-after-code-fence-info": true,
+ "spaces-inside-emphasis-markers": true,
+ "spaces-inside-code-span-elements": true,
+ "single-trailing-newline": true,
+ "link-fragments": false,
+ "table-pipe-style": "leading_and_trailing",
+ "table-column-count": false,
+ "table-column-style": false,
+ "descriptive-link-text": false,
+ "no-emphasis-as-heading": false
+ },
+ "customRules": [
+ "./markdownlint-rules/no-space-after-fence.js"
+ ],
+ "ignores": [
+ "node_modules/**"
+ ]
+}
diff --git a/.github/markdownlint-rules/no-space-after-fence.js b/.github/markdownlint-rules/no-space-after-fence.js
new file mode 100644
index 0000000000..b6b0f479a7
--- /dev/null
+++ b/.github/markdownlint-rules/no-space-after-fence.js
@@ -0,0 +1,35 @@
+"use strict";
+
+module.exports = {
+ names: ["no-space-after-fence"],
+ description: "Disallow spaces between a fence and the info string.",
+ tags: ["code", "fences", "whitespace"],
+ function: function noSpaceAfterFence(params, onError) {
+ const lines = params.lines || [];
+
+ (params.tokens || []).forEach((token) => {
+ if (token.type !== "fence") {
+ return;
+ }
+
+ if (!token.markup || token.markup[0] !== "`") {
+ return;
+ }
+
+ if (!token.map || token.map.length === 0) {
+ return;
+ }
+
+ const lineNumber = token.map[0] + 1;
+ const line = lines[lineNumber - 1] || "";
+
+ if (/^\s*`{3,}[ \t]+\S/.test(line)) {
+ onError({
+ lineNumber,
+ detail: "Remove the space between the fence and the info string.",
+ context: line.trim()
+ });
+ }
+ });
+ }
+};
diff --git a/.github/markdownlint.json b/.github/markdownlint.json
deleted file mode 100644
index ddc76bcfea..0000000000
--- a/.github/markdownlint.json
+++ /dev/null
@@ -1,75 +0,0 @@
-{
- "default": true,
- "heading-increment": true,
- "no-hard-tabs": true,
- "no-multiple-blanks": true,
- "line-length": false,
- "commands-show-output": true,
- "blanks-around-headings": true,
- "heading-start-left": true,
- "no-duplicate-heading": false,
- "single-h1": false,
- "no-trailing-punctuation": false,
- "no-blanks-blockquote": false,
- "list-marker-space": true,
- "blanks-around-fences": true,
- "blanks-around-lists": true,
- "no-inline-html": {
- "allowed_elements": [
- "Badge",
- "div",
- "span",
- "br",
- "style",
- "details",
- "summary",
- "table",
- "thead",
- "tbody",
- "tr",
- "th",
- "td",
- "img",
- "a",
- "svg",
- "path",
- "figure",
- "p",
- "colgroup",
- "col",
- "strong",
- "sup",
- "section",
- "hr",
- "ol",
- "ul",
- "li",
- "em",
- "code"
- ]
- },
- "no-bare-urls": true,
- "fenced-code-language": true,
- "first-line-heading": false,
- "code-block-style": false,
- "code-fence-style": {
- "style": "backtick"
- },
- "emphasis-style": {
- "style": "asterisk"
- },
- "strong-style": {
- "style": "asterisk"
- },
- "spaces-after-emphasis-marker": true,
- "spaces-after-code-fence-info": true,
- "spaces-inside-emphasis-markers": true,
- "spaces-inside-code-span-elements": true,
- "single-trailing-newline": true,
- "link-fragments": false,
- "table-pipe-style": "leading_and_trailing",
- "table-column-count": false,
- "table-column-style": false,
- "descriptive-link-text": false,
- "no-emphasis-as-heading": false
-}
diff --git a/.github/workflows/docs-validation.yml b/.github/workflows/docs-validation.yml
index 7070721dd7..91911bf2f6 100644
--- a/.github/workflows/docs-validation.yml
+++ b/.github/workflows/docs-validation.yml
@@ -57,11 +57,10 @@ jobs:
uses: actions/checkout@v6
- name: Lint markdown files
- uses: articulate/actions-markdownlint@v1
+ uses: DavidAnson/markdownlint-cli2-action@v22
with:
- config: .github/markdownlint.json
- files: 'docs/**/*.md'
- ignore: 'node_modules'
+ config: './.github/.markdownlint-cli2.jsonc'
+ globs: 'docs/**/*.md'
spell-check:
name: Spell Check
diff --git a/docs/en/appendices/5-0-migration-guide.md b/docs/en/appendices/5-0-migration-guide.md
index 316e412112..4492d6eec4 100644
--- a/docs/en/appendices/5-0-migration-guide.md
+++ b/docs/en/appendices/5-0-migration-guide.md
@@ -225,7 +225,7 @@ high memory usage due to the entire result set being buffered in memory.
You can work around this issue by disabling results buffering for the query:
-``` php
+```php
$results = $articles->find()
->disableBufferedResults()
->all();
@@ -233,7 +233,7 @@ $results = $articles->find()
Depending on your use case, you may also consider using disabling hydration:
-``` php
+```php
$results = $articles->find()
->disableHydration()
->all();
@@ -350,7 +350,7 @@ properties more strictly. The new behavior is called 'required fields'. When
enabled, accessing properties that are not defined in the entity will raise
exceptions. This impacts the following usage:
-``` php
+```php
$entity->get();
$entity->has();
$entity->getOriginal();
@@ -368,7 +368,7 @@ this the default behavior in the future.
Table finders can now have typed arguments as required instead of an options array.
For e.g. a finder for fetching posts by category or user:
-``` php
+```php
public function findByCategoryOrUser(SelectQuery $query, array $options): SelectQuery
{
if (isset($options['categoryId'])) {
@@ -384,7 +384,7 @@ public function findByCategoryOrUser(SelectQuery $query, array $options): Select
can now be written as:
-``` php
+```php
public function findByCategoryOrUser(SelectQuery $query, ?int $categoryId = null, ?int $userId = null): SelectQuery
{
if ($categoryId) {
@@ -404,7 +404,7 @@ You can even include the special named arguments for setting query clauses.
A similar change has been applied to the `RepositoryInterface::get()` method:
-``` php
+```php
public function view(int $id)
{
$author = $this->Authors->get($id, [
@@ -416,7 +416,7 @@ public function view(int $id)
can now be written as:
-``` php
+```php
public function view(int $id)
{
$author = $this->Authors->get($id, contain: ['Books'], finder: 'latest');
diff --git a/docs/en/appendices/5-0-upgrade-guide.md b/docs/en/appendices/5-0-upgrade-guide.md
index 77d1fc9d48..7c458f713b 100644
--- a/docs/en/appendices/5-0-upgrade-guide.md
+++ b/docs/en/appendices/5-0-upgrade-guide.md
@@ -11,7 +11,7 @@ First, check that your application is running on latest CakePHP 4.x version.
Once your application is running on latest CakePHP 4.x, enable deprecation warnings in **config/app.php**:
-``` php
+```php
'Error' => [
'errorLevel' => E_ALL,
],
@@ -43,7 +43,7 @@ Because CakePHP 5 leverages union types and `mixed`, there are many
backwards incompatible changes concerning method signatures and file renames.
To help expedite fixing these tedious changes there is an upgrade CLI tool:
-``` bash
+```bash
# Install the upgrade tool
git clone https://github.com/cakephp/upgrade
cd upgrade
@@ -54,7 +54,7 @@ composer install --no-dev
With the upgrade tool installed you can now run it on your application or
plugin:
-``` bash
+```bash
bin/cake upgrade rector --rules cakephp50
bin/cake upgrade rector --rules chronos3
```
diff --git a/docs/en/appendices/5-1-migration-guide.md b/docs/en/appendices/5-1-migration-guide.md
index e99f6aae07..dadebc3e70 100644
--- a/docs/en/appendices/5-1-migration-guide.md
+++ b/docs/en/appendices/5-1-migration-guide.md
@@ -15,7 +15,7 @@ The [upgrade tool](../appendices/migration-guides) provides rector rules for
automating some of the migration work. Run rector before updating your
`composer.json` dependencies:
-``` bash
+```bash
bin/cake upgrade rector --rules cakephp51
```
diff --git a/docs/en/appendices/5-2-migration-guide.md b/docs/en/appendices/5-2-migration-guide.md
index a720a3a5bd..277ac03aa5 100644
--- a/docs/en/appendices/5-2-migration-guide.md
+++ b/docs/en/appendices/5-2-migration-guide.md
@@ -15,7 +15,7 @@ The [upgrade tool](../appendices/migration-guides) provides rector rules for
automating some of the migration work. Run rector before updating your
`composer.json` dependencies:
-``` bash
+```bash
bin/cake upgrade rector --rules cakephp52
```
diff --git a/docs/en/appendices/5-3-migration-guide.md b/docs/en/appendices/5-3-migration-guide.md
index 6458e19b2f..ba29464945 100644
--- a/docs/en/appendices/5-3-migration-guide.md
+++ b/docs/en/appendices/5-3-migration-guide.md
@@ -15,7 +15,7 @@ The [upgrade tool](../appendices/migration-guides) provides rector rules for
automating some of the migration work. Run rector before updating your
`composer.json` dependencies:
-``` bash
+```bash
bin/cake upgrade rector --rules cakephp53
```
diff --git a/docs/en/appendices/glossary.md b/docs/en/appendices/glossary.md
index 6ae9138c3a..63fb7895e5 100644
--- a/docs/en/appendices/glossary.md
+++ b/docs/en/appendices/glossary.md
@@ -6,29 +6,35 @@ description: "CakePHP terminology reference: understand common abbreviations, te
# Glossary
## CDN
+
Content Delivery Network. A 3rd party vendor you can pay to help
distribute your content to data centers around the world. This helps
put your static assets closer to geographically distributed users.
## columns
+
Used in the ORM when referring to the table columns in an database
table.
## CSRF
+
Cross Site Request Forgery. Prevents replay attacks, double
submissions and forged requests from other domains.
## DI Container
+
In `Application::services()` you can configure application services
and their dependencies. Application services are automatically injected
into Controller actions, and Command Constructors. See
[Dependency Injection](../development/dependency-injection).
## DSN
+
Data Source Name. A connection string format that is formed like a URI.
CakePHP supports DSNs for Cache, Database, Log and Email connections.
## dot notation
+
Dot notation defines an array path, by separating nested levels with `.`
For example:
@@ -36,7 +42,7 @@ For example:
Would point to the following value:
-``` php
+```php
[
'Cache' => [
'default' => [
@@ -47,19 +53,22 @@ Would point to the following value:
```
## DRY
+
Don't repeat yourself. Is a principle of software development aimed at
reducing repetition of information of all kinds. In CakePHP DRY is used
to allow you to code things once and re-use them across your
application.
## fields
+
A generic term used to describe both entity properties, or database
columns. Often used in conjunction with the FormHelper.
## HTML attributes
+
An array of key => values that are composed into HTML attributes. For example:
-``` php
+```php
// Given
['class' => 'my-class', 'target' => '_blank']
@@ -70,7 +79,7 @@ class="my-class" target="_blank"
If an option can be minimized or accepts its name as the value, then `true`
can be used:
-``` php
+```php
// Given
['checked' => true]
@@ -79,18 +88,21 @@ checked="checked"
```
## PaaS
+
Platform as a Service. Platform as a Service providers will provide
cloud based hosting, database and caching resources. Some popular
providers include Heroku, EngineYard and PagodaBox
## properties
+
Used when referencing columns mapped onto an ORM entity.
## plugin syntax
+
Plugin syntax refers to the dot separated class name indicating classes
are part of a plugin:
-``` php
+```php
// The plugin is "DebugKit", and the class name is "Toolbar".
'DebugKit.Toolbar'
@@ -99,15 +111,17 @@ are part of a plugin:
```
## routes.php
+
A file in the `config/` directory that contains routing configuration.
This file is included before each request is processed.
It should connect all the routes your application needs so
requests can be routed to the correct controller + action.
## routing array
+
An array of attributes that are passed to `Router::url()`.
They typically look like:
-``` php
+```php
['controller' => 'Posts', 'action' => 'view', 5]
```
diff --git a/docs/en/appendices/migration-guides.md b/docs/en/appendices/migration-guides.md
index 28185f8820..5e4b034630 100644
--- a/docs/en/appendices/migration-guides.md
+++ b/docs/en/appendices/migration-guides.md
@@ -17,7 +17,7 @@ method renames and signature updates.
To use the upgrade tool:
-``` bash
+```bash
# Install the upgrade tool
git clone https://github.com/cakephp/upgrade
cd upgrade
diff --git a/docs/en/appendices/phpunit-upgrade.md b/docs/en/appendices/phpunit-upgrade.md
index 6cb5897ecc..8b374913c8 100644
--- a/docs/en/appendices/phpunit-upgrade.md
+++ b/docs/en/appendices/phpunit-upgrade.md
@@ -34,7 +34,7 @@ With this command out of the way your `phpunit.xml` already has most of the reco
PHPUnit 10 removed the old hook system and introduced a new [Event system](https://docs.phpunit.de/en/10.5/extending-phpunit.html#extending-the-test-runner)
which requires the following code in your `phpunit.xml` to be adjusted from:
-``` xml
+```xml
@@ -42,7 +42,7 @@ which requires the following code in your `phpunit.xml` to be adjusted from:
to:
-``` xml
+```xml
@@ -55,13 +55,13 @@ to:
You can convert the removed `->withConsecutive()` method to a
working interim solution like you can see here:
-``` php
+```php
->withConsecutive(['firstCallArg'], ['secondCallArg'])
```
should be converted to:
-``` php
+```php
->with(
...self::withConsecutive(['firstCallArg'], ['secondCallArg']),
)
@@ -75,13 +75,13 @@ to the base `Cake\TestSuite\TestCase` class so you don't have to manually add th
If your test cases leverage the data provider feature of PHPUnit then
you have to adjust your data providers to be static:
-``` php
+```php
public function myProvider(): array
```
should be converted to:
-``` php
+```php
public static function myProvider(): array
```
@@ -93,7 +93,7 @@ PHPUnit 11 requires PHP 8.2 or later.
PHPUnit 11 deprecates annotations in docblocks. You should migrate to PHP 8 attributes:
-``` php
+```php
// Before (deprecated)
/**
* @dataProvider myProvider
@@ -125,7 +125,7 @@ Methods for creating mock objects for abstract classes and traits are hard-depre
Configuring expectations on an object created with `createStub()` triggers a deprecation warning:
-``` php
+```php
// Avoid - will warn in PHPUnit 11
$stub = $this->createStub(SomeClass::class);
$stub->expects($this->once())->method('foo');
@@ -159,7 +159,7 @@ Configuring expectations on objects created with `createStub()` no longer works.
[Rector](https://getrector.com/) can automate many of these changes:
-``` bash
+```bash
composer require --dev rector/rector rector/rector-phpunit
# Create rector.php config
diff --git a/docs/en/console-commands.md b/docs/en/console-commands.md
index c30a883e1c..47212fcc07 100644
--- a/docs/en/console-commands.md
+++ b/docs/en/console-commands.md
@@ -23,7 +23,7 @@ bash the CakePHP console is compatible with any *nix shell and windows.
A CakePHP application contains **src/Command** directory that contain its commands.
It also comes with an executable in the **bin** directory:
-``` bash
+```bash
cd /path/to/app
bin/cake
```
@@ -34,7 +34,7 @@ bin/cake
Running the Console with no arguments will list out available commands. You
could then run the any of the listed commands by using its name:
-``` bash
+```bash
# run server command
bin/cake server
@@ -59,7 +59,7 @@ commands, when building standalone console applications. You can use your
`Application`'s `console()` hook to limit which commands are exposed and
rename commands that are exposed:
-``` php
+```php
// in src/Application.php
namespace App;
@@ -99,7 +99,7 @@ do this, you can register your commands to create any desired naming.
You can customize the command names by defining each command in your plugin:
-``` php
+```php
public function console(CommandCollection $commands): CommandCollection
{
// Add commands with nested naming
@@ -158,7 +158,7 @@ bootstrap or config, for example.
For sending emails, you should provide Email class with the host you want to
send the email with:
-``` php
+```php
use Cake\Mailer\Email;
$email = new Email();
diff --git a/docs/en/console-commands/cache.md b/docs/en/console-commands/cache.md
index f8a367411a..7fe52dc2bb 100644
--- a/docs/en/console-commands/cache.md
+++ b/docs/en/console-commands/cache.md
@@ -8,7 +8,7 @@ description: "Manage cache from CLI in CakePHP: clear all caches, specific cache
To help you better manage cached data from a CLI environment, a console command
is available for clearing cached data your application has:
-``` bash
+```bash
// Clear one cache config
bin/cake cache clear
diff --git a/docs/en/console-commands/commands.md b/docs/en/console-commands/commands.md
index 88e9b7140d..55cb26ebd8 100644
--- a/docs/en/console-commands/commands.md
+++ b/docs/en/console-commands/commands.md
@@ -17,7 +17,7 @@ Let's create our first Command. For this example, we'll create a
simple Hello world command. In your application's **src/Command** directory create
**HelloCommand.php**. Put the following code inside it:
-``` php
+```php
fetchTable()` since command use the `LocatorAwareTrait`:
-``` php
+```php
getArgument('name');
@@ -253,7 +253,7 @@ You can pass any desired exit code into `abort()`.
You may need to call other commands from your command. You can use
`executeCommand` to do that:
-``` php
+```php
// You can pass an array of CLI options and arguments.
$this->executeCommand(OtherCommand::class, ['--verbose', 'deploy']);
@@ -271,7 +271,7 @@ $this->executeCommand($command, ['--verbose', 'deploy']);
You may want to set a command description via:
-``` php
+```php
class UserCommand extends Command
{
public static function getDescription(): string
@@ -283,11 +283,11 @@ class UserCommand extends Command
This will show your description in the Cake CLI:
-``` bash
+```bash
bin/cake
```
-```
+```text
App:
- user
└─── My custom description
@@ -295,11 +295,11 @@ App:
As well as in the help section of your command:
-``` bash
+```bash
cake user --help
```
-```
+```text
My custom description
Usage:
@@ -312,7 +312,7 @@ By default, in the help output CakePHP will group commands into core, app, and
plugin groups. You can customize the grouping of commands by implementing
`getGroup()`:
-``` php
+```php
class CleanupCommand extends Command
{
public static function getGroup(): string
@@ -333,7 +333,7 @@ collection without needing to remove and re-add it. This is particularly useful
when using `autoDiscover` and you want to replace a command with a customized
version:
-``` php
+```php
// In your Application::console() method
public function console(CommandCollection $commands): CommandCollection
{
@@ -353,7 +353,7 @@ public function console(CommandCollection $commands): CommandCollection
The `TreeHelper` outputs an array as a tree structure. This is useful for
displaying filesystem directories or any hierarchical data:
-``` php
+```php
public function execute(Arguments $args, ConsoleIo $io): int
{
$helper = $io->helper('Tree');
@@ -392,7 +392,7 @@ you would use in the CLI to this method.
Let's start with a very simple command, located in
**src/Command/UpdateTableCommand.php**:
-``` php
+```php
namespace App\Command;
use Cake\Command\Command;
@@ -416,7 +416,7 @@ To write an integration test for this command, we would create a test case in
`Cake\TestSuite\ConsoleIntegrationTestTrait` trait. This command doesn't do much at the
moment, but let's just test that our command's description is displayed in `stdout`:
-``` php
+```php
namespace App\Test\TestCase\Command;
use Cake\TestSuite\ConsoleIntegrationTestTrait;
@@ -438,7 +438,7 @@ Our test passes! While this is very trivial example, it shows that creating an
integration test case for console applications can follow command line
conventions. Let's continue by adding more logic to our command:
-``` php
+```php
namespace App\Command;
use Cake\Command\Command;
@@ -478,7 +478,7 @@ class UpdateTableCommand extends Command
This is a more complete command that has required options and relevant logic.
Modify your test case to the following snippet of code:
-``` php
+```php
namespace Cake\Test\TestCase\Command;
use Cake\Command\Command;
@@ -538,7 +538,7 @@ included as an array in the order that you expect them.
Continuing with our example command, let's add an interactive confirmation.
Update the command class to the following:
-``` php
+```php
namespace App\Command;
use Cake\Command\Command;
@@ -584,7 +584,7 @@ that we receive the proper response, and one that tests that we receive an
incorrect response. Remove the `testUpdateModified` method and, add the following methods to
**tests/TestCase/Command/UpdateTableCommandTest.php**:
-``` php
+```php
public function testUpdateModifiedSure()
{
$now = new DateTime('2017-01-01 00:00:00');
@@ -624,7 +624,7 @@ our error message was written to `stderr`.
The `Cake\TestSuite\ConsoleIntegrationTestTrait` trait provides a number of
assertion methods that make help assert against console output:
-``` php
+```php
// assert that the command exited as success
$this->assertExitSuccess();
@@ -652,7 +652,7 @@ $this->assertErrorRegExp($expected);
You can use `debugOutput()` to output the exit code, stdout and stderr of the
last run command:
-``` php
+```php
$this->exec('update_table Users');
$this->assertExitCode(Command::CODE_SUCCESS);
$this->debugOutput();
@@ -687,7 +687,7 @@ The `beforeExecute()` and `afterExecute()` hook methods were added.
Called before the `execute()` method runs. Useful for initialization and
validation:
-``` php
+```php
use Cake\Event\EventInterface;
class MyCommand extends Command
@@ -712,7 +712,7 @@ class MyCommand extends Command
Called after the `execute()` method completes. Useful for cleanup and
logging:
-``` php
+```php
public function afterExecute(EventInterface $event, Arguments $args, ConsoleIo $io, mixed $result): void
{
parent::afterExecute($event);
diff --git a/docs/en/console-commands/completion.md b/docs/en/console-commands/completion.md
index 66a808c736..3d87f5edaf 100644
--- a/docs/en/console-commands/completion.md
+++ b/docs/en/console-commands/completion.md
@@ -82,7 +82,7 @@ Save the file, then restart your console.
This is the code you need to put inside the **cake** file in the correct location
in order to get autocompletion when using the CakePHP console:
-``` bash
+```bash
#
# Bash completion file for CakePHP console
#
@@ -146,7 +146,7 @@ Three type of autocompletion are provided. The following output are from a fresh
Sample output for commands autocompletion:
-``` bash
+```bash
$ bin/cake
bake i18n schema_cache routes
console migrations plugin server
@@ -156,7 +156,7 @@ console migrations plugin server
Sample output for subcommands autocompletion:
-``` bash
+```bash
$ bin/cake bake
behavior helper command
cell mailer command_helper
@@ -170,7 +170,7 @@ form plugin
Sample output for subcommands options autocompletion:
-``` bash
+```bash
$ bin/cake bake -
-c --everything --force --help --plugin -q -t -v
--connection -f -h -p --prefix --quiet --theme --verbose
diff --git a/docs/en/console-commands/counter-cache.md b/docs/en/console-commands/counter-cache.md
index 6abfcb2b75..34e2762360 100644
--- a/docs/en/console-commands/counter-cache.md
+++ b/docs/en/console-commands/counter-cache.md
@@ -10,7 +10,7 @@ in your application and plugin models. It can be used in maintenance and
recovery operations, or to populate new counter caches added to your
application.
-``` bash
+```bash
bin/cake counter_cache Comments --assoc Articles
```
@@ -18,7 +18,7 @@ This would rebuild the `Comments` related counters on the `Articles` table.
For very large tables you may need to rebuild counters in batches. You can use
the `--limit` and `--page` options to incrementally rebuild counter state.
-``` bash
+```bash
bin/cake counter_cache Comments --assoc Articles --limit 100 --page 2
```
diff --git a/docs/en/console-commands/cron-jobs.md b/docs/en/console-commands/cron-jobs.md
index 359444fb0c..0316a76eaf 100644
--- a/docs/en/console-commands/cron-jobs.md
+++ b/docs/en/console-commands/cron-jobs.md
@@ -9,7 +9,7 @@ A common thing to do with a shell is making it run as a cronjob to
clean up the database once in a while or send newsletters. This is
trivial to setup, for example:
-``` text
+```text
*/5 * * * * cd /full/path/to/root && bin/cake myshell myparam
# * * * * * command to execute
# │ │ │ │ │
diff --git a/docs/en/console-commands/i18n.md b/docs/en/console-commands/i18n.md
index 74ce6c8f8d..a62ef336e8 100644
--- a/docs/en/console-commands/i18n.md
+++ b/docs/en/console-commands/i18n.md
@@ -21,7 +21,7 @@ command. This command will scan your entire application for `__()` style
function calls, and extract the message string. Each unique string in your
application will be combined into a single POT file:
-``` bash
+```bash
bin/cake i18n extract
```
@@ -34,7 +34,7 @@ correctly set the `Plural-Forms` header line.
You can generate a POT file for a specific plugin using:
-``` bash
+```bash
bin/cake i18n extract --plugin
```
@@ -49,7 +49,7 @@ from this directory as well as from the `src/` directory. You can do it by
using the `--paths` option. It takes a comma-separated list of absolute paths
to extract:
-``` bash
+```bash
bin/cake i18n extract --paths /var/www/app/config,/var/www/app/src
```
@@ -58,7 +58,7 @@ bin/cake i18n extract --paths /var/www/app/config,/var/www/app/src
You can pass a comma separated list of folders that you wish to be excluded.
Any path containing a path segment with the provided values will be ignored:
-``` bash
+```bash
bin/cake i18n extract --exclude vendor,tests
```
@@ -67,7 +67,7 @@ bin/cake i18n extract --exclude vendor,tests
By adding `--overwrite`, the shell script will no longer warn you if a POT
file already exists and will overwrite by default:
-``` bash
+```bash
bin/cake i18n extract --overwrite
```
@@ -77,7 +77,7 @@ By default, the extract shell script will ask you if you like to extract
the messages used in the CakePHP core libraries. Set `--extract-core` to yes
or no to set the default behavior:
-``` bash
+```bash
bin/cake i18n extract --extract-core yes
// or
diff --git a/docs/en/console-commands/input-output.md b/docs/en/console-commands/input-output.md
index ffe62286da..c49b16bc7f 100644
--- a/docs/en/console-commands/input-output.md
+++ b/docs/en/console-commands/input-output.md
@@ -17,7 +17,7 @@ enable better re-use and testability of console formatting code, CakePHP command
helpers provide 'macros' for console formatting logic. Command Helpers can be
accessed and used from any command:
-``` php
+```php
// Output some data as a table.
$io->helper('Table')->output($data);
@@ -28,7 +28,7 @@ $io->helper('Plugin.HelperName')->output($data);
You can also get instances of helpers and call any public methods, to manipulate
state and generate updated output:
-``` php
+```php
// Get and use the Progress Helper.
$progress = $io->helper('Progress');
$progress->increment(10);
@@ -42,7 +42,7 @@ application or plugins. As an example, we'll create a simple helper to generate
fancy headings. First create the **src/Command/Helper/HeadingHelper.php** and put
the following in it:
-``` php
+```php
helper('Heading')->output(['It works!']);
@@ -83,7 +83,7 @@ implement additional methods that take any form of arguments.
The TableHelper assists in making well formatted ASCII art tables. Using it is
pretty simple:
-``` php
+```php
$data = [
['Header 1', 'Header', 'Long Header'],
['short', 'Longish thing', 'short'],
@@ -103,7 +103,7 @@ $io->helper('Table')->output($data);
You can use the `` formatting tag in tables to right align
content:
-``` php
+```php
$data = [
['Name', 'Total Price'],
['Cake Mix', '1.50'],
@@ -123,7 +123,7 @@ $io->helper('Table')->output($data);
The ProgressHelper can be used in two different ways. The simple mode lets you
provide a callback that is invoked until the progress is complete:
-``` php
+```php
$io->helper('Progress')->output(['callback' => function ($progress) {
// Do work here.
$progress->increment(20);
@@ -141,7 +141,7 @@ You can control the progress bar more by providing additional options:
An example of all the options in use would be:
-``` php
+```php
$io->helper('Progress')->output([
'total' => 10,
'width' => 20,
@@ -155,7 +155,7 @@ $io->helper('Progress')->output([
The progress helper can also be used manually to increment and re-render the
progress bar as necessary:
-``` php
+```php
$progress = $io->helper('Progress');
$progress->init([
'total' => 10,
@@ -171,7 +171,7 @@ $progress->draw();
The `BannerHelper` can be used to format one or more lines of text into
a banner with a background and horizontal padding:
-``` php
+```php
$io->helper('Banner')
->withPadding(5)
->withStyle('success.bg')
@@ -189,7 +189,7 @@ The `BannerHelper` was added in 5.1
When building interactive console applications you'll need to get user input.
CakePHP provides a way to do this:
-``` php
+```php
// Get arbitrary text from the user.
$color = $io->ask('What color do you like?');
@@ -207,7 +207,7 @@ Creating files is often important part of many console commands that help
automate development and deployment. The `createFile()` method gives you
a simple interface for creating files with interactive confirmation:
-``` php
+```php
// Create a file with confirmation on overwrite
$io->createFile('bower.json', $stuff);
@@ -221,7 +221,7 @@ $io->createFile('bower.json', $stuff, true);
Writing to `stdout` is done using the `out()` method:
-``` php
+```php
// Write to stdout
$io->out('Normal message');
```
@@ -230,7 +230,7 @@ $io->out('Normal message');
Writing to `stderr` is done using the `err()` method:
-``` php
+```php
// Write to stderr
$io->err('Error message');
```
@@ -238,7 +238,7 @@ $io->err('Error message');
In addition to vanilla output methods, CakePHP provides wrapper methods that
style output with appropriate ANSI colors:
-``` php
+```php
// Green text on stdout
$io->success('Success message');
@@ -260,7 +260,7 @@ true, or if the `NO_COLOR` environment variable is set.
`ConsoleIo` provides two convenience methods regarding the output level:
-``` php
+```php
// Would only appear when verbose output is enabled (-v)
$io->verbose('Verbose message');
@@ -270,7 +270,7 @@ $io->quiet('Quiet message');
You can also create blank lines or draw lines of dashes:
-``` php
+```php
// Output 2 newlines
$io->out($io->nl(2));
@@ -280,7 +280,7 @@ $io->hr();
Lastly, you can update the current line of text on the screen:
-``` php
+```php
$io->out('Counting down');
$io->out('10', 0);
for ($i = 9; $i > 0; $i--) {
@@ -311,7 +311,7 @@ command. There are 3 levels:
You can mark output as follows:
-``` php
+```php
// Would appear at all levels.
$io->out('Quiet message', 1, ConsoleIo::QUIET);
$io->quiet('Quiet message');
@@ -357,7 +357,7 @@ are several built-in styles, and you can create more. The built-in ones are
You can create additional styles using `$io->setStyle()`. To declare a
new output style you could do:
-``` php
+```php
$io->setStyle('flashy', ['text' => 'magenta', 'blink' => true]);
```
@@ -396,7 +396,7 @@ The `info.bg`, `warning.bg`, `error.bg`, and `success.bg` were added.
Although coloring is pretty, there may be times when you want to turn it off,
or force it on:
-``` php
+```php
$io->outputAs(ConsoleOutput::RAW);
```
diff --git a/docs/en/console-commands/option-parsers.md b/docs/en/console-commands/option-parsers.md
index e1aa2bbca5..87d84a4e01 100644
--- a/docs/en/console-commands/option-parsers.md
+++ b/docs/en/console-commands/option-parsers.md
@@ -15,7 +15,7 @@ get information from the terminal into your commands.
Commands and Shells provide a `buildOptionParser($parser)` hook method that
you can use to define the options and arguments for your commands:
-``` php
+```php
protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser
{
// Define your options and arguments.
@@ -28,7 +28,7 @@ protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOption
Shell classes use the `getOptionParser()` hook method to define their option
parser:
-``` php
+```php
public function getOptionParser()
{
// Get an empty parser from the framework.
@@ -51,7 +51,7 @@ arguments as well as make them required. You can add arguments
one at a time with `$parser->addArgument();` or multiple at once
with `$parser->addArguments();`:
-``` php
+```php
$parser->addArgument('model', ['help' => 'The model to bake']);
```
@@ -83,7 +83,7 @@ The `separator` option was added.
If you have an array with multiple arguments you can use
`$parser->addArguments()` to add multiple arguments at once.
-``` php
+```php
$parser->addArguments([
'node' => ['help' => 'The node to create', 'required' => true],
'parent' => ['help' => 'The parent node', 'required' => true],
@@ -100,7 +100,7 @@ indicate that an argument must be present when a shell is called.
Additionally, you can use `choices` to force an argument to be from a list of
valid choices:
-``` php
+```php
$parser->addArgument('type', [
'help' => 'The type of node to interact with.',
'required' => true,
@@ -121,7 +121,7 @@ arguments for your commands. Options can define both verbose and short aliases.
They can accept a value (e.g `--connection=default`) or be boolean options
(e.g `--verbose`). Options are defined with the `addOption()` method:
-``` php
+```php
$parser->addOption('connection', [
'short' => 'c',
'help' => 'connection',
@@ -136,7 +136,7 @@ when invoking the shell.
Boolean switches do not accept or consume values, and their presence just
enables them in the parsed parameters:
-``` php
+```php
$parser->addOption('no-commit', ['boolean' => true]);
```
@@ -174,7 +174,7 @@ The `separator` option was added.
If you have an array with multiple options you can use `$parser->addOptions()`
to add multiple options at once.
-``` php
+```php
$parser->addOptions([
'node' => ['short' => 'n', 'help' => 'The node to create'],
'parent' => ['short' => 'p', 'help' => 'The parent node'],
@@ -190,7 +190,7 @@ Options can be provided with a set of choices much like positional arguments
can be. When an option has defined choices, those are the only valid choices
for an option. All other values will raise an `InvalidArgumentException`:
-``` php
+```php
$parser->addOption('accept', [
'help' => 'What version to accept.',
'choices' => ['working', 'theirs', 'mine'],
@@ -204,7 +204,7 @@ create some flag options. Like options with defaults, boolean options always
include themselves into the parsed parameters. When the flags are present they
are set to `true`, when they are absent they are set to `false`:
-``` php
+```php
$parser->addOption('verbose', [
'help' => 'Enable verbose output.',
'boolean' => true,
@@ -226,7 +226,7 @@ for arguments, and options, should follow the format that
`Cake\Console\ConsoleOptionParser::addOptions()` use. You can also
use `buildFromArray` on its own, to build an option parser:
-``` php
+```php
public function getOptionParser()
{
return ConsoleOptionParser::buildFromArray([
@@ -251,7 +251,7 @@ public function getOptionParser()
When building a group command, you maybe want to combine several parsers for
this:
-``` php
+```php
$parser->merge($anotherParser);
```
@@ -266,7 +266,7 @@ automatically generate rudimentary help information and add a `--help` and
`-h` to each of your commands. Using one of these options will allow you to
see the generated help content:
-``` bash
+```bash
bin/cake bake --help
bin/cake bake -h
```
@@ -274,7 +274,7 @@ bin/cake bake -h
Would both generate the help for bake. You can also get help for nested
commands:
-``` bash
+```bash
bin/cake bake model --help
bin/cake bake model -h
```
@@ -288,7 +288,7 @@ CakePHP shell commands, it's nice to have help available in a machine parse-able
By providing the `xml` option when requesting help you can have help content
returned as XML:
-``` bash
+```bash
cake bake --help xml
cake bake -h xml
```
@@ -297,7 +297,7 @@ The above would return an XML document with the generated help, options, and
arguments for the selected shell. A sample XML document would
look like:
-``` xml
+```xml
bake fixture
@@ -358,7 +358,7 @@ epilog.
The description displays above the argument and option information. By passing
in either an array or a string, you can set the value of the description:
-``` php
+```php
// Set multiple lines at once
$parser->setDescription(['line one', 'line two']);
@@ -374,7 +374,7 @@ Gets or sets the epilog for the option parser. The epilog is displayed after the
argument and option information. By passing in either an array or a string, you
can set the value of the epilog:
-``` php
+```php
// Set multiple lines at once
$parser->setEpilog(['line one', 'line two']);
diff --git a/docs/en/console-commands/plugin.md b/docs/en/console-commands/plugin.md
index 5ae23f0441..3a1f97a252 100644
--- a/docs/en/console-commands/plugin.md
+++ b/docs/en/console-commands/plugin.md
@@ -10,7 +10,7 @@ description: "Manage plugins via CLI in CakePHP: load/unload plugins, configure
The plugin tool allows you to load and unload plugins via the command prompt.
If you need help, run:
-``` bash
+```bash
bin/cake plugin --help
```
@@ -19,13 +19,13 @@ bin/cake plugin --help
Via the `Load` task you are able to load plugins in your
**config/bootstrap.php**. You can do this by running:
-``` bash
+```bash
bin/cake plugin load MyPlugin
```
This will add the following to your **src/Application.php**:
-``` php
+```php
// In the bootstrap method add:
$this->addPlugin('MyPlugin');
```
@@ -34,7 +34,7 @@ $this->addPlugin('MyPlugin');
You can unload a plugin by specifying its name:
-``` bash
+```bash
bin/cake plugin unload MyPlugin
```
@@ -48,7 +48,7 @@ While this is a good convenience, it is recommended to symlink / copy
the plugin assets under app's webroot so that they can be directly served by the
web server without invoking PHP. You can do this by running:
-``` bash
+```bash
bin/cake plugin assets symlink
```
@@ -58,6 +58,6 @@ respective folders instead of being symlinked.
You can symlink assets of one particular plugin by specifying its name:
-``` bash
+```bash
bin/cake plugin assets symlink MyPlugin
```
diff --git a/docs/en/console-commands/repl.md b/docs/en/console-commands/repl.md
index f7e06d90b0..664fffa596 100644
--- a/docs/en/console-commands/repl.md
+++ b/docs/en/console-commands/repl.md
@@ -14,7 +14,7 @@ you explore some CakePHP and your application in an interactive console.
You can start the interactive console using:
-``` bash
+```bash
bin/cake console
```
@@ -22,7 +22,7 @@ This will bootstrap your application and start an interactive console. At this
point you can interact with your application code and execute queries using your
application's models:
-``` bash
+```bash
bin/cake console
>>> $articles = Cake\Datasource\FactoryLocator::get('Table')->get('Articles');
@@ -35,7 +35,7 @@ bin/cake console
Since your application has been bootstrapped you can also test routing using the
REPL:
-``` php
+```php
>>> Cake\Routing\Router::parse('/articles/view/1');
// [
// 'controller' => 'Articles',
@@ -49,7 +49,7 @@ REPL:
You can also test generating URLs:
-``` php
+```php
>>> Cake\Routing\Router::url(['controller' => 'Articles', 'action' => 'edit', 99]);
// '/articles/edit/99'
```
diff --git a/docs/en/console-commands/routes.md b/docs/en/console-commands/routes.md
index 8739ba65e8..d2493bfd61 100644
--- a/docs/en/console-commands/routes.md
+++ b/docs/en/console-commands/routes.md
@@ -11,7 +11,7 @@ parameters will generate.
## Getting a List of all Routes
-``` bash
+```bash
bin/cake routes
```
@@ -19,14 +19,14 @@ bin/cake routes
You can quickly see how a URL will be parsed using the `check` method:
-``` bash
+```bash
bin/cake routes check /articles/edit/1
```
If your route contains any query string parameters remember to surround the URL
in quotes:
-``` bash
+```bash
bin/cake routes check "/articles/?page=1&sort=title&direction=desc"
```
@@ -35,6 +35,6 @@ bin/cake routes check "/articles/?page=1&sort=title&direction=desc"
You can see the URL a `routing array` will generate using the
`generate` method:
-``` bash
+```bash
bin/cake routes generate controller:Articles action:edit 1
```
diff --git a/docs/en/console-commands/schema-cache.md b/docs/en/console-commands/schema-cache.md
index e826bc71ec..96485b3837 100644
--- a/docs/en/console-commands/schema-cache.md
+++ b/docs/en/console-commands/schema-cache.md
@@ -10,7 +10,7 @@ metadata caches. In deployment situations it is helpful to rebuild the metadata
cache in-place without clearing the existing cache data. You can do this by
running:
-``` bash
+```bash
bin/cake schema_cache build --connection default
```
@@ -18,14 +18,14 @@ This will rebuild the metadata cache for all tables on the `default`
connection. If you only need to rebuild a single table you can do that by
providing its name:
-``` bash
+```bash
bin/cake schema_cache build --connection default articles
```
In addition to building cached data, you can use the SchemaCacheShell to remove
cached metadata as well:
-``` bash
+```bash
# Clear all metadata
bin/cake schema_cache clear
diff --git a/docs/en/console-commands/server.md b/docs/en/console-commands/server.md
index e69a9d1998..2364d6dbb7 100644
--- a/docs/en/console-commands/server.md
+++ b/docs/en/console-commands/server.md
@@ -10,7 +10,7 @@ webserver. While this server is *not* intended for production use it can
be handy in development when you want to quickly try an idea out and don't want
to spend time configuring Apache or Nginx. You can start the server command with:
-``` bash
+```bash
bin/cake server
```
@@ -26,6 +26,6 @@ terminal.
You can customize the port and document root using options:
-``` bash
+```bash
bin/cake server --port 8080 --document_root path/to/app
```
diff --git a/docs/en/contributing/backwards-compatibility.md b/docs/en/contributing/backwards-compatibility.md
index 3168fb1ab3..cc2231dbba 100644
--- a/docs/en/contributing/backwards-compatibility.md
+++ b/docs/en/contributing/backwards-compatibility.md
@@ -277,7 +277,7 @@ locate code that needs to be updated before it breaks. If you wish to disable
runtime warnings you can do so using the `Error.errorLevel` configuration
value:
-``` php
+```php
// in config/app.php
// ...
'Error' => [
diff --git a/docs/en/contributing/cakephp-coding-conventions.md b/docs/en/contributing/cakephp-coding-conventions.md
index 08564b7253..12f63ad3d2 100644
--- a/docs/en/contributing/cakephp-coding-conventions.md
+++ b/docs/en/contributing/cakephp-coding-conventions.md
@@ -37,7 +37,7 @@ Four spaces will be used for indentation.
So, indentation should look like this:
-``` php
+```php
// base level
// level 1
// level 2
@@ -47,7 +47,7 @@ So, indentation should look like this:
Or:
-``` php
+```php
$booleanVariable = true;
$stringVariable = 'moose';
if ($booleanVariable) {
@@ -68,7 +68,7 @@ guidelines:
As an example, instead of using the following formatting:
-``` php
+```php
$matches = array_intersect_key($this->_listeners,
array_flip(preg_grep($matchPattern,
array_keys($this->_listeners), 0)));
@@ -76,7 +76,7 @@ $matches = array_intersect_key($this->_listeners,
Use this instead:
-``` php
+```php
$matches = array_intersect_key(
$this->_listeners,
array_flip(
@@ -103,7 +103,7 @@ In short:
Control structures are for example "`if`", "`for`", "`foreach`",
"`while`", "`switch`" etc. Below, an example with "`if`":
-``` php
+```php
if ((expr_1) || (expr_2)) {
// action_1;
} elseif (!(expr_3) && (expr_4)) {
@@ -126,7 +126,7 @@ if ((expr_1) || (expr_2)) {
within it should gain a new level of indentation.
- Inline assignments should not be used inside of the control structures.
-``` php
+```php
// wrong = no brackets, badly placed statement
if (expr) statement;
@@ -158,7 +158,7 @@ line. Longer ternaries should be split into `if else` statements. Ternary
operators should not ever be nested. Optionally parentheses can be used around
the condition check of the ternary for clarity:
-``` php
+```php
// Good, simple and readable
$variable = isset($options['variable']) ? $options['variable'] : true;
@@ -173,7 +173,7 @@ Keyword control structures are easier to read in complex template files. Control
structures can either be contained in a larger PHP block, or in separate PHP
tags:
-``` php
+```php
You are the admin user.
';
@@ -192,7 +192,7 @@ might be wise to comment it as such to avoid confusing it for a mistake.
For testing if a variable is null, it is recommended to use a strict check:
-``` php
+```php
if ($value === null) {
// ...
}
@@ -200,7 +200,7 @@ if ($value === null) {
The value to check against should be placed on the right side:
-``` php
+```php
// not recommended
if (null === $this->foo()) {
// ...
@@ -218,7 +218,7 @@ Functions should be called without space between function's name and starting
parenthesis. There should be one space between every parameter of a function
call:
-``` php
+```php
$var = foo($bar, $bar2, $bar3);
```
@@ -228,7 +228,7 @@ As you can see above there should be one space on both sides of equals sign (=).
Example of a method definition:
-``` php
+```php
public function someFunction(string $arg1, string $arg2 = ''): mixed
{
if (expr) {
@@ -243,7 +243,7 @@ Parameters with a default value, should be placed last in function definition.
Try to make your functions return something, at least `true` or `false`, so
it can be determined whether the function call was successful:
-``` php
+```php
public function connection(string|array $dns, bool $persistent = false): bool
{
if (is_array($dns)) {
@@ -266,7 +266,7 @@ There are spaces on both side of the equals sign.
Try to avoid unnecessary nesting by bailing early:
-``` php
+```php
public function run(array $data): bool
{
...
@@ -295,7 +295,7 @@ This helps to keep the logic sequential which improves readability.
Arguments that expect objects, arrays or callbacks (callable) can be typehinted.
We only typehint public methods, though, as typehinting is not cost-free:
-``` php
+```php
/**
* Some method description.
*
@@ -316,7 +316,7 @@ Note that if you want to allow `$array` to be also an instance of
`\ArrayObject` you should not typehint as `array` accepts only the primitive
type:
-``` php
+```php
/**
* Some method description.
*
@@ -333,7 +333,7 @@ Defining anonymous functions follows the [PSR-12](https://www.php-fig.org/psr/ps
declared with a space after the `function` keyword, and a space before and after
the `use` keyword:
-``` php
+```php
$closure = function ($arg1, $arg2) use ($var1, $var2) {
// code
};
@@ -344,7 +344,7 @@ $closure = function ($arg1, $arg2) use ($var1, $var2) {
Method chaining should have multiple methods spread across separate lines, and
indented with four spaces:
-``` php
+```php
$email->from('foo@example.com')
->to('bar@example.com')
->subject('A great message')
@@ -373,7 +373,7 @@ tags:
PhpDoc tags are very much like JavaDoc tags in Java. Tags are only processed if
they are the first thing in a DocBlock line, for example:
-``` php
+```php
/**
* Tag example.
*
@@ -382,7 +382,7 @@ they are the first thing in a DocBlock line, for example:
*/
```
-``` php
+```php
/**
* Example of inline phpDoc tags.
*
@@ -455,7 +455,7 @@ For more than two types it is usually best to just use `mixed`.
When returning the object itself (for example, for chaining), one should use `$this`
instead:
-``` php
+```php
/**
* Foo function.
*
@@ -472,7 +472,7 @@ public function foo(): static
`include`, `require`, `include_once` and `require_once` do not have
parentheses:
-``` php
+```php
// wrong = parentheses
require_once('ClassFileName.php');
require_once ($class);
@@ -496,7 +496,7 @@ The short echo should be used in template files in place of `=$name;?>
@@ -512,7 +512,7 @@ The short echo tag (`=`) is always available regardless of the `short_open_tag
Write all functions in camelBack:
-``` php
+```php
function longFunctionName()
{
}
@@ -522,7 +522,7 @@ function longFunctionName()
Class names should be written in CamelCase, for example:
-``` php
+```php
class ExampleClass
{
}
@@ -536,7 +536,7 @@ written in camelBack in case of multiple words. Variables referencing objects
should in some way associate to the class the variable is an object of.
Example:
-``` php
+```php
$user = 'John';
$users = ['John', 'Hans', 'Arne'];
@@ -598,14 +598,14 @@ of `floatval($var)` when applicable.
Constants should be defined in capital letters:
-``` php
+```php
define('CONSTANT', 1);
```
If a constant name consists of multiple words, they should be separated by an
underscore character, for example:
-``` php
+```php
define('LONG_NAMED_CONSTANT', 2);
```
@@ -613,7 +613,7 @@ define('LONG_NAMED_CONSTANT', 2);
Enum cases are defined in `CamelCase` style:
-``` php
+```php
enum ArticleStatus: string
{
case Published = 'Y';
@@ -629,7 +629,7 @@ properties are already defined, the usage of `empty()` is not recommended.
When working with variables, it is better to rely on type-coercion to boolean
instead of `empty()`:
-``` php
+```php
function manipulate($var)
{
// Not recommended, $var is already defined in the scope
@@ -650,7 +650,7 @@ function manipulate($var)
When dealing with defined properties you should favour `null` checks over
`empty()`/`isset()` checks:
-``` php
+```php
class Thing
{
private $property; // Defined
@@ -673,7 +673,7 @@ When working with arrays, it is better to merge in defaults over using
`empty()` checks. By merging in defaults, you can ensure that required keys
are defined:
-``` php
+```php
function doWork(array $array)
{
// Merge defaults to remove need for empty checks.
diff --git a/docs/en/contributing/code.md b/docs/en/contributing/code.md
index 8fe0b19b53..9d04dd4879 100644
--- a/docs/en/contributing/code.md
+++ b/docs/en/contributing/code.md
@@ -57,7 +57,7 @@ is for. For example if you are fixing a bug in `3.x` you would want to use the
`master` branch as the base for your branch. If your change is a bug fix for
the 2.x release series, you should use the `2.x` branch:
-``` bash
+```bash
# fixing a bug on 3.x
git fetch upstream
git checkout -b ticket-1234 upstream/master
@@ -85,7 +85,7 @@ following:
Once your changes are done and you're ready for them to be merged into CakePHP,
you'll want to update your branch:
-``` bash
+```bash
# Rebase fix on top of master
git checkout master
git fetch upstream
@@ -100,20 +100,20 @@ code. You might encounter a conflict during the `rebase`. If the rebase quits
early you can see which files are conflicted/un-merged with `git status`.
Resolve each conflict, and then continue the rebase:
-``` bash
+```bash
git add # do this for each conflicted file.
git rebase --continue
```
Check that all your tests continue to pass. Then push your branch to your fork:
-``` bash
+```bash
git push origin
```
If you've rebased after pushing your branch, you'll need to use force push:
-``` bash
+```bash
git push --force origin
```
diff --git a/docs/en/controllers.md b/docs/en/controllers.md
index 897d5b256e..01976a3892 100644
--- a/docs/en/controllers.md
+++ b/docs/en/controllers.md
@@ -44,7 +44,7 @@ to all of your application's controllers. `AppController` itself extends the
`AppController` is defined in **src/Controller/AppController.php** as
follows:
-``` php
+```php
namespace App\Controller;
use Cake\Controller\Controller;
@@ -63,7 +63,7 @@ You can use your `AppController` to load components that will be used in every
controller in your application. CakePHP provides a `initialize()` method that
is invoked at the end of a Controller's constructor for this kind of use:
-``` php
+```php
namespace App\Controller;
use Cake\Controller\Controller;
@@ -100,7 +100,7 @@ name. Returning to our online bakery example, our RecipesController might contai
`view()`, `share()`, and `search()` actions. The controller would be found
in **src/Controller/RecipesController.php** and contain:
-``` php
+```php
// src/Controller/RecipesController.php
class RecipesController extends AppController
@@ -158,7 +158,7 @@ The `Controller::set()` method is the main way to send data from your
controller to your view. Once you've used `Controller::set()`, the variable
can be accessed in your view:
-``` php
+```php
// First you pass data from the controller:
$this->set('color', 'pink');
@@ -173,7 +173,7 @@ The `Controller::set()` method also takes an
associative array as its first parameter. This can often be a quick way to
assign a set of information to the view:
-``` php
+```php
$data = [
'color' => 'pink',
'type' => 'sugar',
@@ -197,7 +197,7 @@ theme that will be used when rendering the view, you can use the
`viewBuilder()` method to get a builder. This builder can be used to define
properties of the view before it is created:
-``` php
+```php
$this->viewBuilder()
->addHelper('MyCustom')
->setTheme('Modern')
@@ -213,7 +213,7 @@ By default, view options set via `ViewBuilder` are deep-merged with the View
class's default configuration. You can control this behavior using
`setConfigMergeStrategy()`:
-``` php
+```php
use Cake\View\ViewBuilder;
$this->viewBuilder()
@@ -245,7 +245,7 @@ The default view file used by render is determined by convention.
If the `search()` action of the RecipesController is requested,
the view file in **templates/Recipes/search.php** will be rendered:
-``` php
+```php
namespace App\Controller;
class RecipesController extends AppController
@@ -269,7 +269,7 @@ If `$view` starts with '/', it is assumed to be a view or
element file relative to the **templates** folder. This allows
direct rendering of elements, very useful in AJAX calls:
-``` php
+```php
// Render the element in templates/element/ajaxreturn.php
$this->render('/element/ajaxreturn');
```
@@ -283,7 +283,7 @@ In your controller, you may want to render a different view than the
conventional one. You can do this by calling `Controller::render()` directly. Once you
have called `Controller::render()`, CakePHP will not try to re-render the view:
-``` php
+```php
namespace App\Controller;
class PostsController extends AppController
@@ -302,7 +302,7 @@ You can also render views inside plugins using the following syntax:
`$this->render('PluginName.PluginController/custom_file')`.
For example:
-``` php
+```php
namespace App\Controller;
class PostsController extends AppController
@@ -330,7 +330,7 @@ render an HTML view or render a JSON or XML response. To define the list of
supported view classes for a controller is done with the `addViewClasses()`
method:
-``` php
+```php
namespace App\Controller;
use Cake\View\JsonView;
@@ -352,7 +352,7 @@ other view can be selected based on the request's `Accept` header or routing
extension. If your application only supports content types for a specific
actions, you can call `addClasses()` within your action too:
-``` php
+```php
public function export(): void
{
// Use a custom CSV view for data exports.
@@ -366,7 +366,7 @@ If within your controller actions you need to process the request or load data
differently based on the content type you can use
[Check The Request](controllers/request-response#check-the-request):
-``` php
+```php
// In a controller action
// Load additional data when preparing JSON responses
@@ -390,7 +390,7 @@ will use the base `View` class. If you want to require content-type
negotiation, you can use the `NegotiationRequiredView` which sets a `406` status
code:
-``` php
+```php
public function initialize(): void
{
parent::initialize();
@@ -403,7 +403,7 @@ public function initialize(): void
You can use the `TYPE_MATCH_ALL` content type value to build your own fallback
view logic:
-``` php
+```php
namespace App\View;
use Cake\View\View;
@@ -427,7 +427,7 @@ In applications that use hypermedia or AJAX clients, you often need to render
view contents without the wrapping layout. You can use the `AjaxView` that
is bundled with the application skeleton:
-``` php
+```php
// In a controller action, or in beforeRender.
if ($this->request->is('ajax')) {
$this->viewBuilder()->setClassName('Ajax');
@@ -450,7 +450,7 @@ controller action and rendering a view.
You can redirect using `routing array` values:
-``` php
+```php
return $this->redirect([
'controller' => 'Orders',
'action' => 'confirm',
@@ -465,7 +465,7 @@ return $this->redirect([
Or using a relative or absolute URL:
-``` php
+```php
return $this->redirect('/orders/confirm');
return $this->redirect('https://www.example.com');
@@ -473,13 +473,13 @@ return $this->redirect('https://www.example.com');
Or to the referer page:
-``` php
+```php
return $this->redirect($this->referer());
```
By using the second parameter you can define a status code for your redirect:
-``` php
+```php
// Do a 301 (moved permanently)
return $this->redirect('/order/confirm', 301);
@@ -497,7 +497,7 @@ a life-cycle handler.
The `fetchTable()` method comes handy when you need to use an ORM table that is not
the controller's default one:
-``` php
+```php
// In a controller method.
$recentArticles = $this->fetchTable('Articles')->find('all',
limit: 5,
@@ -512,7 +512,7 @@ $recentArticles = $this->fetchTable('Articles')->find('all',
The `fetchModel()` method is useful to load non ORM models or ORM tables that
are not the controller's default:
-``` php
+```php
// ModelAwareTrait need to be explicitly added to your controller first for fetchModel() to work.
use ModelAwareTrait;
@@ -541,7 +541,7 @@ how to use `paginate()`.
The `$paginate` attribute gives you a way to customize how `paginate()`
behaves:
-``` php
+```php
class ArticlesController extends AppController
{
protected array $paginate = [
@@ -559,7 +559,7 @@ class ArticlesController extends AppController
In your Controller's `initialize()` method you can define any components you
want loaded, and any configuration data for them:
-``` php
+```php
public function initialize(): void
{
parent::initialize();
@@ -606,7 +606,7 @@ also provide a similar set of callbacks.
Remember to call `AppController`'s callbacks within child controller callbacks
for best results:
-``` php
+```php
//use Cake\Event\EventInterface;
public function beforeFilter(EventInterface $event): void
{
@@ -620,7 +620,7 @@ public function beforeFilter(EventInterface $event): void
To redirect from within a controller callback method you can use the following:
-``` php
+```php
public function beforeFilter(EventInterface $event): void
{
if (...) {
@@ -648,7 +648,7 @@ a routing scope or within a controller. To define middleware for a specific
controller use the `middleware()` method from your controller's
`initialize()` method:
-``` php
+```php
public function initialize(): void
{
parent::initialize();
diff --git a/docs/en/controllers/components.md b/docs/en/controllers/components.md
index 1b9a7a10c5..2d9647f85d 100644
--- a/docs/en/controllers/components.md
+++ b/docs/en/controllers/components.md
@@ -27,7 +27,7 @@ the [Form Protection Component](../controllers/components/form-protection). Conf
and for components in general, is usually done via `loadComponent()` in your
Controller's `initialize()` method or via the `$components` array:
-``` php
+```php
class PostsController extends AppController
{
public function initialize(): void
@@ -45,7 +45,7 @@ You can configure components at runtime using the `setConfig()` method. Often,
this is done in your controller's `beforeFilter()` method. The above could
also be expressed as:
-``` php
+```php
public function beforeFilter(EventInterface $event): void
{
$this->FormProtection->setConfig('unlockedActions', ['index']);
@@ -55,7 +55,7 @@ public function beforeFilter(EventInterface $event): void
Like helpers, components implement `getConfig()` and `setConfig()` methods
to read and write configuration data:
-``` php
+```php
// Read config data.
$this->FormProtection->getConfig('unlockedActions');
@@ -74,7 +74,7 @@ alias components. This feature is useful when you want to
replace `$this->Flash` or another common Component reference with a custom
implementation:
-``` php
+```php
// src/Controller/PostsController.php
class PostsController extends AppController
{
@@ -108,7 +108,7 @@ You might not need all of your components available on every controller
action. In situations like this you can load a component at runtime using the
`loadComponent()` method in your controller:
-``` php
+```php
// In a controller action
$this->loadComponent('OneTimer');
$time = $this->OneTimer->getTime();
@@ -127,7 +127,7 @@ simple. Each component you use is exposed as a property on your controller. If
you had loaded up the `Cake\Controller\Component\FlashComponent`
in your controller, you could access it like so:
-``` php
+```php
class PostsController extends AppController
{
public function initialize(): void
@@ -165,7 +165,7 @@ The first step is to create a new component file and class. Create the file in
**src/Controller/Component/MathComponent.php**. The basic structure for the
component would look something like this:
-``` php
+```php
namespace App\Controller\Component;
use Cake\Controller\Component;
@@ -186,7 +186,7 @@ class MathComponent extends Component
Components can use [Dependency Injection](../development/dependency-injection) to receive services
as constructor parameters:
-``` php
+```php
namespace App\Controller\Component;
use Cake\Controller\Component;
@@ -214,7 +214,7 @@ controllers by loading it during the controller's `initialize()` method.
Once loaded, the controller will be given a new attribute named after the
component, through which we can access an instance of it:
-``` php
+```php
// In a controller
// Make the new component available at $this->Math,
// as well as the standard $this->Flash
@@ -231,7 +231,7 @@ set of parameters that will be passed on to the Component's
constructor. These parameters can then be handled by
the Component:
-``` php
+```php
// In your controller.
public function initialize(): void
{
@@ -252,7 +252,7 @@ The above would pass the array containing precision and randomGenerator to
Sometimes one of your components may need to use another component.
You can load other components by adding them to the `$components` property:
-``` php
+```php
// src/Controller/Component/CustomComponent.php
namespace App\Controller\Component;
@@ -298,7 +298,7 @@ class ExistingComponent extends Component
From within a Component you can access the current controller through the
registry:
-``` php
+```php
$controller = $this->getController();
```
@@ -323,7 +323,7 @@ augment the request cycle.
To redirect from within a component callback method you can use the following:
-``` php
+```php
public function beforeFilter(EventInterface $event): void
{
if (...) {
@@ -341,7 +341,7 @@ component callbacks to run, and that the controller should not handle the action
any further. As of 4.1.0 you can raise a `RedirectException` to signal
a redirect:
-``` php
+```php
use Cake\Http\Exception\RedirectException;
use Cake\Routing\Router;
@@ -355,7 +355,7 @@ Raising an exception will halt all other event listeners and create a new
response that doesn't retain or inherit any of the current response's headers.
When raising a `RedirectException` you can include additional headers:
-``` php
+```php
throw new RedirectException(Router::url('/'), 302, [
'Header-Key' => 'value',
]);
diff --git a/docs/en/controllers/components/check-http-cache.md b/docs/en/controllers/components/check-http-cache.md
index ca3a3cb736..416f9a8f3a 100644
--- a/docs/en/controllers/components/check-http-cache.md
+++ b/docs/en/controllers/components/check-http-cache.md
@@ -13,7 +13,7 @@ a response to the client. Under this model, you mostly save bandwidth, but when
used correctly you can also save some CPU processing, reducing response
times:
-``` php
+```php
// in a Controller
public function initialize(): void
{
diff --git a/docs/en/controllers/components/flash.md b/docs/en/controllers/components/flash.md
index bcf122001a..6529f0b024 100644
--- a/docs/en/controllers/components/flash.md
+++ b/docs/en/controllers/components/flash.md
@@ -22,7 +22,7 @@ maps to an element located under the **templates/element/flash** directory.
By convention, camelcased methods will map to the lowercased and underscored
element name:
-``` php
+```php
// Uses templates/element/flash/success.php
$this->Flash->success('This was successful');
@@ -33,7 +33,7 @@ $this->Flash->greatSuccess('This was greatly successful');
Alternatively, to set a plain-text message without rendering an element, you can
use the `set()` method:
-``` php
+```php
$this->Flash->set('This is a message');
```
@@ -56,7 +56,7 @@ parameter, an array of options:
An example of using these options:
-``` php
+```php
// In your Controller
$this->Flash->success('The user has been saved', [
'key' => 'positive',
@@ -80,7 +80,7 @@ Note that the parameter `element` will be always overridden while using
`__call()`. In order to retrieve a specific element from a plugin, you should
set the `plugin` parameter. For example:
-``` php
+```php
// In your Controller
$this->Flash->warning('My message', ['plugin' => 'PluginName']);
```
@@ -101,7 +101,7 @@ message.
It is possible to output HTML in flash messages by using the `'escape'` option
key:
-``` php
+```php
$this->Flash->info(sprintf('%s %s', h($highlight), h($message)), ['escape' => false]);
```
diff --git a/docs/en/controllers/components/form-protection.md b/docs/en/controllers/components/form-protection.md
index 6f276aa6ec..7aa0e76c00 100644
--- a/docs/en/controllers/components/form-protection.md
+++ b/docs/en/controllers/components/form-protection.md
@@ -57,10 +57,12 @@ Configuring the form protection component is generally done in the controller's
Available options are:
### validate
+
Set to `false` to completely skip the validation of POST
requests, essentially turning off form validation.
### unlockedFields
+
Set to a list of form fields to exclude from POST validation. Fields can be
unlocked either in the Component, or with
`FormHelper::unlockField()`. Fields that have been unlocked are
@@ -68,15 +70,17 @@ not required to be part of the POST and hidden unlocked fields do not have
their values checked.
### unlockedActions
+
Actions to exclude from POST validation checks.
### validationFailureCallback
+
Callback to call in case of validation failure. Must be a valid Closure.
Unset by default in which case exception is thrown on validation failure.
## Disabling form tampering checks
-``` php
+```php
namespace App\Controller;
use App\Controller\AppController;
@@ -111,7 +115,7 @@ There may be cases where you want to disable form tampering prevention for an
action (ex. AJAX requests). You may "unlock" these actions by listing them in
`$this->FormProtection->setConfig('unlockedActions', ['edit']);` in your `beforeFilter()`:
-``` php
+```php
namespace App\Controller;
use App\Controller\AppController;
@@ -145,7 +149,7 @@ configuration option to a callback function in the controller.
By configuring a callback method you can customize how the failure handling process
works:
-``` php
+```php
use Cake\Controller\Exception\FormProtectionException;
public function beforeFilter(EventInterface $event): void
diff --git a/docs/en/controllers/middleware.md b/docs/en/controllers/middleware.md
index e98b3d0f54..f2d5547b49 100644
--- a/docs/en/controllers/middleware.md
+++ b/docs/en/controllers/middleware.md
@@ -74,7 +74,7 @@ To apply middleware to all requests, use the `middleware` method of your
called at the beginning of the request process, you can use the
`MiddlewareQueue` object to attach middleware:
-``` php
+```php
namespace App;
use Cake\Core\Configure;
@@ -103,7 +103,7 @@ class Application extends BaseApplication
In addition to adding to the end of the `MiddlewareQueue` you can do
a variety of operations:
-``` php
+```php
$layer = new \App\Middleware\CustomMiddleware;
// Added middleware will be last in line.
@@ -142,7 +142,7 @@ or [Controller middleware](../controllers#controller-middleware).
Plugins can use their `middleware` hook method to apply any middleware they
have to the application's middleware queue:
-``` php
+```php
// in plugins/ContactManager/src/Plugin.php
namespace ContactManager;
@@ -177,7 +177,7 @@ for smaller tasks they make testing harder, and can create a complicated
Middleware can return a response either by calling `$handler->handle()` or by
creating their own response. We can see both options in our simple middleware:
-``` php
+```php
// In src/Middleware/TrackingCookieMiddleware.php
namespace App\Middleware;
@@ -216,7 +216,7 @@ class TrackingCookieMiddleware implements MiddlewareInterface
Now that we've made a very simple middleware, let's attach it to our
application:
-``` php
+```php
// In src/Application.php
namespace App;
@@ -242,7 +242,7 @@ class Application
Routing middleware is responsible for applying your application's routes and
resolving the plugin, controller, and action a request is going to:
-``` php
+```php
// In Application.php
public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
{
@@ -258,7 +258,7 @@ protect against user tampering, you can use CakePHP's encrypted cookie
middleware to transparently encrypt and decrypt cookie data via middleware.
Cookie data is encrypted via OpenSSL using AES:
-``` php
+```php
use Cake\Http\Middleware\EncryptedCookieMiddleware;
$cookies = new EncryptedCookieMiddleware(
@@ -285,7 +285,7 @@ is available via `$request->getParsedData()` and `$request->getData()`. By
default only `json` bodies will be parsed, but XML parsing can be enabled with
an option. You can also define your own parsers:
-``` php
+```php
use Cake\Http\Middleware\BodyParserMiddleware;
// only JSON will be parsed.
diff --git a/docs/en/controllers/middleware/rate-limit.md b/docs/en/controllers/middleware/rate-limit.md
index 6a6f3d625b..218a0e48f3 100644
--- a/docs/en/controllers/middleware/rate-limit.md
+++ b/docs/en/controllers/middleware/rate-limit.md
@@ -11,7 +11,7 @@ application to protect against abuse and ensure fair usage of resources.
To use rate limiting in your application, add the middleware to your
middleware queue:
-``` php
+```php
// In src/Application.php
use Cake\Http\Middleware\RateLimitMiddleware;
@@ -79,7 +79,7 @@ The middleware accepts the following configuration options:
The default identifier type tracks requests by IP address:
-``` php
+```php
use Cake\Http\Middleware\RateLimitMiddleware;
new RateLimitMiddleware([
@@ -92,7 +92,7 @@ new RateLimitMiddleware([
The middleware automatically handles proxy headers. You can configure
which headers to check using the `ipHeader` option:
-``` php
+```php
new RateLimitMiddleware([
'identifier' => RateLimitMiddleware::IDENTIFIER_IP,
'ipHeader' => ['CF-Connecting-IP', 'X-Forwarded-For'],
@@ -103,7 +103,7 @@ new RateLimitMiddleware([
Track requests per authenticated user:
-``` php
+```php
new RateLimitMiddleware([
'identifier' => RateLimitMiddleware::IDENTIFIER_USER,
'limit' => 1000,
@@ -118,7 +118,7 @@ The middleware checks for users implementing `Authentication\IdentityInterface`.
Apply different limits to different routes:
-``` php
+```php
new RateLimitMiddleware([
'identifier' => RateLimitMiddleware::IDENTIFIER_ROUTE,
'limit' => 10,
@@ -132,7 +132,7 @@ This creates separate limits for each controller/action combination.
Track requests by API key or token:
-``` php
+```php
new RateLimitMiddleware([
'identifier' => RateLimitMiddleware::IDENTIFIER_API_KEY,
'limit' => 5000,
@@ -143,7 +143,7 @@ new RateLimitMiddleware([
By default, the middleware looks for tokens in the `Authorization` and
`X-API-Key` headers. You can customize which headers to check:
-``` php
+```php
new RateLimitMiddleware([
'identifier' => RateLimitMiddleware::IDENTIFIER_TOKEN,
'tokenHeaders' => ['Authorization', 'X-API-Key', 'X-Auth-Token'],
@@ -154,7 +154,7 @@ new RateLimitMiddleware([
You can create custom identifiers using a callback:
-``` php
+```php
new RateLimitMiddleware([
'identifierCallback' => function ($request) {
// Custom logic to identify the client
@@ -171,7 +171,7 @@ new RateLimitMiddleware([
The default strategy that provides smooth rate limiting by continuously
adjusting the window based on request timing:
-``` php
+```php
new RateLimitMiddleware([
'strategy' => RateLimitMiddleware::STRATEGY_SLIDING_WINDOW,
])
@@ -181,7 +181,7 @@ new RateLimitMiddleware([
Resets the counter at fixed intervals:
-``` php
+```php
new RateLimitMiddleware([
'strategy' => RateLimitMiddleware::STRATEGY_FIXED_WINDOW,
])
@@ -191,7 +191,7 @@ new RateLimitMiddleware([
Allows for burst capacity while maintaining an average rate:
-``` php
+```php
new RateLimitMiddleware([
'strategy' => RateLimitMiddleware::STRATEGY_TOKEN_BUCKET,
'limit' => 100, // bucket capacity
@@ -204,7 +204,7 @@ new RateLimitMiddleware([
You can use a custom rate limiter strategy by specifying the `strategyClass`
option. Your class must implement `Cake\Http\RateLimiter\RateLimiterInterface`:
-``` php
+```php
new RateLimitMiddleware([
'strategyClass' => App\RateLimiter\MyCustomRateLimiter::class,
])
@@ -217,7 +217,7 @@ The `strategyClass` option takes precedence over the `strategy` option.
For complex applications, you can define named limiter configurations
and resolve them dynamically per request:
-``` php
+```php
new RateLimitMiddleware([
'limiters' => [
'default' => [
@@ -252,7 +252,7 @@ new RateLimitMiddleware([
Skip rate limiting for certain requests:
-``` php
+```php
new RateLimitMiddleware([
'skipCheck' => function ($request) {
// Skip rate limiting for health checks
@@ -265,7 +265,7 @@ new RateLimitMiddleware([
Assign different costs to different types of requests:
-``` php
+```php
new RateLimitMiddleware([
'costCallback' => function ($request) {
// POST requests cost 5x more
@@ -278,7 +278,7 @@ new RateLimitMiddleware([
Set different limits for different users or plans:
-``` php
+```php
new RateLimitMiddleware([
'limitCallback' => function ($request, $identifier) {
$user = $request->getAttribute('identity');
@@ -294,7 +294,7 @@ new RateLimitMiddleware([
Customize how cache keys are generated:
-``` php
+```php
new RateLimitMiddleware([
'keyGenerator' => function ($request, $identifier) {
// Include the HTTP method in the key for per-method limits
@@ -312,7 +312,7 @@ To programmatically reset a rate limit for a specific identifier, use the
- Resetting limits when a user upgrades their plan
- Clearing state between tests
-``` php
+```php
use Cake\Cache\Cache;
use Cake\Http\RateLimit\SlidingWindowRateLimiter;
@@ -343,7 +343,7 @@ When a client exceeds the limit, a `Retry-After` header is also included
You can apply multiple rate limiters with different configurations:
-``` php
+```php
// Strict limit for login attempts
$middlewareQueue->add(new RateLimitMiddleware([
'identifier' => RateLimitMiddleware::IDENTIFIER_IP,
@@ -367,7 +367,7 @@ $middlewareQueue->add(new RateLimitMiddleware([
The rate limiter stores its data in cache. Make sure you have a persistent
cache configured:
-``` php
+```php
// In config/app.php
'Cache' => [
'rate_limit' => [
@@ -380,7 +380,7 @@ cache configured:
Then use it in the middleware:
-``` php
+```php
new RateLimitMiddleware([
'cache' => 'rate_limit',
])
diff --git a/docs/en/controllers/pagination.md b/docs/en/controllers/pagination.md
index 3e09624447..1251d99db8 100644
--- a/docs/en/controllers/pagination.md
+++ b/docs/en/controllers/pagination.md
@@ -24,7 +24,7 @@ to generate pagination controls.
You can call `paginate()` using an ORM table instance or `Query` object:
-``` php
+```php
public function index()
{
// Paginate the ORM table.
@@ -44,7 +44,7 @@ conditions serve as the basis for you pagination queries. They are augmented
by the `sort`, `direction`, `limit`, and `page` parameters passed in
from the URL:
-``` php
+```php
class ArticlesController extends AppController
{
protected array $paginate = [
@@ -61,7 +61,7 @@ class ArticlesController extends AppController
You can also use [Custom Find Methods](../orm/retrieving-data-and-resultsets#custom-find-methods) in pagination by using the `finder` option:
-``` php
+```php
class ArticlesController extends AppController
{
protected array $paginate = [
@@ -75,7 +75,7 @@ Note: This only works with Table as string input in `$this->paginate('MyTable')`
If your finder method requires additional options you can pass those
as values for the finder:
-``` php
+```php
class ArticlesController extends AppController
{
// find articles by tag
@@ -108,7 +108,7 @@ In addition to defining general pagination values, you can define more than one
set of pagination defaults in the controller. The name of each model can be used
as a key in the `$paginate` property:
-``` php
+```php
class ArticlesController extends AppController
{
protected array $paginate = [
@@ -134,7 +134,7 @@ that page number links can be rendered. On very large datasets this count query
can be very expensive. In situations where you only want to show 'Next' and 'Previous'
links you can use the 'simple' paginator which does not do a count query:
-``` php
+```php
class ArticlesController extends AppController
{
protected array $paginate = [
@@ -152,7 +152,7 @@ You can paginate multiple models in a single controller action, using the
`scope` option both in the controller's `$paginate` property and in the
call to the `paginate()` method:
-``` php
+```php
// Paginate property
protected array $paginate = [
'Articles' => ['scope' => 'article'],
@@ -179,7 +179,7 @@ elements and URLs for pagination.
To paginate the same model multiple times within a single controller action you
need to define an alias for the model.
-``` php
+```php
// In a controller action
$this->paginate = [
'Articles' => [
@@ -225,7 +225,7 @@ using the `sortableFields` option. This option is required when you want to
sort on any associated data, or computed fields that may be part of your
pagination query:
-``` php
+```php
protected array $paginate = [
'sortableFields' => [
'id', 'title', 'Users.username', 'created',
@@ -248,7 +248,7 @@ multi-column support and direction control.
You can configure sortable fields using a callable that receives a
`SortableFieldsBuilder` instance:
-``` php
+```php
use Cake\Datasource\Paging\SortField;
use Cake\Datasource\Paging\SortableFieldsBuilder;
@@ -271,7 +271,7 @@ The builder supports mapping a single sort key to multiple database fields with
independent direction control. Use the `SortField` class to define complex
sorting:
-``` php
+```php
use Cake\Datasource\Paging\SortField;
protected array $paginate = [
@@ -299,7 +299,7 @@ price becomes DESC.
You can lock a sort direction to prevent users from toggling it. This is useful
when a field should always be sorted in a specific direction:
-``` php
+```php
protected array $paginate = [
'sortableFields' => function ($builder) {
return $builder
@@ -317,7 +317,7 @@ regardless of the `direction` parameter in the URL.
In addition to the traditional `?sort=field&direction=asc` format, you can use
combined sorting keys in URLs:
-``` text
+```text
// These are equivalent
?sort=title&direction=asc
?sort=title-asc
@@ -335,7 +335,7 @@ For basic use cases where you just need to allow sorting on specific fields
without mapping or multi-column support, you can still use the simple array
format:
-``` php
+```php
protected array $paginate = [
'sortableFields' => [
'id', 'title', 'Users.username', 'created',
@@ -353,7 +353,7 @@ number of rows that can be fetched to 100. If this default is not appropriate
for your application, you can adjust it as part of the pagination options, for
example reducing it to `10`:
-``` php
+```php
protected array $paginate = [
// Other keys here.
'maxLimit' => 10,
@@ -372,7 +372,7 @@ page count.
So you could either let the normal error page be rendered or use a try catch
block and take appropriate action when a `NotFoundException` is caught:
-``` php
+```php
use Cake\Http\Exception\NotFoundException;
public function index()
@@ -390,7 +390,7 @@ public function index()
You can also use a paginator directly.
-``` php
+```php
// Create a paginator
$paginator = new \Cake\Datasource\Paginator\NumericPaginator();
diff --git a/docs/en/controllers/request-response.md b/docs/en/controllers/request-response.md
index 9a349640af..94bc8debce 100644
--- a/docs/en/controllers/request-response.md
+++ b/docs/en/controllers/request-response.md
@@ -46,13 +46,13 @@ use libraries from outside of CakePHP.
The request exposes routing parameters through the `getParam()` method:
-``` php
+```php
$controllerName = $this->request->getParam('controller');
```
To get all routing parameters as an array use `getAttribute()`:
-``` php
+```php
$parameters = $this->request->getAttribute('params');
```
@@ -62,7 +62,7 @@ In addition to [Route Elements](../development/routing#route-elements), you also
[Passed Arguments](../development/routing#passed-arguments). These are both available on the request object as
well:
-``` php
+```php
// Passed arguments
$passedArgs = $this->request->getParam('pass');
```
@@ -84,7 +84,7 @@ are also all found in the routing parameters:
Query string parameters can be read using the `getQuery()` method:
-``` php
+```php
// URL is /posts/index?page=1&sort=title
$page = $this->request->getQuery('page');
```
@@ -93,7 +93,7 @@ You can either directly access the query property, or you can use
`getQuery()` method to read the URL query array in an error-free manner.
Any keys that do not exist will return `null`:
-``` php
+```php
$foo = $this->request->getQuery('value_that_does_not_exist');
// $foo === null
@@ -104,14 +104,14 @@ $foo = $this->request->getQuery('does_not_exist', 'default val');
If you want to access all the query parameters you can use
`getQueryParams()`:
-``` php
+```php
$query = $this->request->getQueryParams();
```
You can use the casting utility functions to provide typesafe access to request
data and other input:
-``` php
+```php
use function Cake\Core\toBool;
use function Cake\Core\toInt;
use function Cake\Core\toString;
@@ -145,20 +145,20 @@ Casting functions were added.
All POST data normally available through PHP's `$_POST` global variable can be
accessed using `Cake\Http\ServerRequest::getData()`. For example:
-``` php
+```php
// An input with a name attribute equal to 'title' is accessible at
$title = $this->request->getData('title');
```
You can use a dot separated names to access nested data. For example:
-``` php
+```php
$value = $this->request->getData('address.street_name');
```
For non-existent names the `$default` value will be returned:
-``` php
+```php
$foo = $this->request->getData('value.that.does.not.exist');
// $foo == null
```
@@ -169,7 +169,7 @@ content types into an array, so that it's accessible through `ServerRequest::get
If you want to access all the data parameters you can use
`getParsedBody()`:
-``` php
+```php
$data = $this->request->getParsedBody();
```
@@ -181,7 +181,7 @@ Uploaded files can be accessed through the request body data, using the `Cake\Ht
method described above. For example, a file from an input element with a name attribute of `attachment`, can
be accessed like this:
-``` php
+```php
$attachment = $this->request->getData('attachment');
```
@@ -193,7 +193,7 @@ implementation, the `$attachment` variable in the above example would by default
Accessing the uploaded file details is fairly simple, here's how you can obtain the same data as provided by the old
style file upload array:
-``` php
+```php
$name = $attachment->getClientFilename();
$type = $attachment->getClientMediaType();
$size = $attachment->getSize();
@@ -205,7 +205,7 @@ Moving the uploaded file from its temporary location to the desired target
location, doesn't require manually accessing the temporary file, instead it can
be easily done by using the objects `moveTo()` method:
-``` php
+```php
$attachment->moveTo($targetPath);
```
@@ -220,7 +220,7 @@ origins, which makes testing file uploads possible.
Returns the uploaded file at a specific path. The path uses the same dot syntax as the
`Cake\Http\ServerRequest::getData()` method:
-``` php
+```php
$attachment = $this->request->getUploadedFile('attachment');
```
@@ -233,7 +233,7 @@ present at the given path, then this method will return `null`, just like it wou
Returns all uploaded files in a normalized array structure. For the above example with the file input name of
`attachment`, the structure would look like:
-``` php
+```php
[
'attachment' => object(Laminas\Diactoros\UploadedFile) {
// ...
@@ -247,7 +247,7 @@ This method sets the uploaded files of the request object, it accepts an array o
[\Psr\Http\Message\UploadedFileInterface](https://www.php-fig.org/psr/psr-7/#16-uploaded-files). It will
replace all possibly existing uploaded files:
-``` php
+```php
$files = [
'MyModel' => [
'attachment' => new \Laminas\Diactoros\UploadedFile(
@@ -286,7 +286,7 @@ will automatically be parsed and available via `$request->getData()` for `PUT` a
`DELETE` requests. If you are accepting JSON or XML data, you can
access the raw data with `getBody()`:
-``` php
+```php
// Get the stream wrapper on the request body
$body = $request->getBody();
@@ -306,13 +306,13 @@ types making the parsed data available in `$request->getData()` and
`ServerRequest::getEnv()` is a wrapper for `getenv()` global function and acts as
a getter for environment variables without possible undefined keys:
-``` php
+```php
$host = $this->request->getEnv('HTTP_HOST');
```
To access all the environment variables in a request use `getServerParams()`:
-``` php
+```php
$env = $this->request->getServerParams();
```
@@ -322,7 +322,7 @@ $env = $this->request->getServerParams();
a setter for environment variables without having to modify globals
`$_SERVER` and `$_ENV`:
-``` php
+```php
// Set a value, generally helpful in testing.
$this->request->withEnv('REQUEST_METHOD', 'POST');
```
@@ -334,7 +334,7 @@ non-URL-encoded post bodies. You can read input data in any format using
`Cake\Http\ServerRequest::input()`. By providing a decoding function,
you can receive the content in a deserialized format:
-``` php
+```php
// Get JSON encoded data submitted to a PUT/POST action
$jsonData = $this->request->input('json_decode');
```
@@ -344,7 +344,7 @@ the 'as array' parameter on `json_decode`. If you want XML converted into a
DOMDocument object, `Cake\Http\ServerRequest::input()` supports
passing in additional parameters as well:
-``` php
+```php
// Get XML encoded data submitted to a PUT/POST action
$data = $this->request->input('Cake\Utility\Xml::build', ['return' => 'domdocument']);
```
@@ -356,7 +356,7 @@ application. The `base` and `webroot` attributes are useful for
generating URLs, and determining whether or not your application is in a
subdirectory. The attributes you can use are:
-``` php
+```php
// Assume the current request URL is /subdir/articles/edit/1?page=1
// Holds /subdir/articles/edit/1?page=1
@@ -379,7 +379,7 @@ The request object provides a way to inspect certain conditions in a given
request. By using the `is()` method you can check a number of common
conditions, as well as inspect other application specific request criteria:
-``` php
+```php
$isPost = $this->request->is('post');
```
@@ -404,7 +404,7 @@ detectors. There are different types of detectors that you can create:
Some examples would be:
-``` php
+```php
// Add an environment detector.
$this->request->addDetector(
'post',
@@ -485,7 +485,7 @@ subdomains simpler.
To access the session for a given request use the `getSession()` method or use the `session` attribute:
-``` php
+```php
$session = $this->request->getSession();
$session = $this->request->getAttribute('session');
@@ -501,7 +501,7 @@ to use the session object.
Returns the domain name your application is running on:
-``` php
+```php
// Prints 'example.org'
echo $request->domain();
```
@@ -510,7 +510,7 @@ echo $request->domain();
Returns the subdomains your application is running on as an array:
-``` php
+```php
// Returns ['my', 'dev'] for 'my.dev.example.org'
$subdomains = $request->subdomains();
```
@@ -519,7 +519,7 @@ $subdomains = $request->subdomains();
Returns the host your application is on:
-``` php
+```php
// Prints 'my.dev.example.org'
echo $request->host();
```
@@ -530,7 +530,7 @@ echo $request->host();
Returns the HTTP method the request was made with:
-``` php
+```php
// Output POST
echo $request->getMethod();
```
@@ -543,7 +543,7 @@ Set allowed HTTP methods. If not matched, will throw
`MethodNotAllowedException`. The 405 response will include the required
`Allow` header with the passed methods:
-``` php
+```php
public function delete()
{
// Only accept POST and DELETE requests
@@ -557,7 +557,7 @@ public function delete()
Allows you to access any of the `HTTP_*` headers that were used
for the request. For example:
-``` php
+```php
// Get the header as a string
$userAgent = $this->request->getHeaderLine('User-Agent');
@@ -588,7 +588,7 @@ values. The forwarded headers will not be used by CakePHP out of the box. To
have the request object use these headers set the `trustProxy` property to
`true`:
-``` php
+```php
$this->request->trustProxy = true;
// These methods will now use the proxied headers.
@@ -603,7 +603,7 @@ address in the `X-Forwarded-For` header. If your application is behind
multiple proxies, you can use `setTrustedProxies()` to define the IP addresses
of proxies in your control:
-``` php
+```php
$request->setTrustedProxies(['127.1.1.1', '127.8.1.3']);
```
@@ -620,13 +620,13 @@ particular type of content.
Get all types:
-``` php
+```php
$accepts = $this->request->accepts();
```
Check for a single type:
-``` php
+```php
$acceptsJson = $this->request->accepts('application/json');
```
@@ -637,13 +637,13 @@ or check whether a specific language is accepted.
Get the list of accepted languages:
-``` php
+```php
$acceptsLanguages = $this->request->acceptLanguage();
```
Check whether a specific language is accepted:
-``` php
+```php
$acceptsSpanish = $this->request->acceptLanguage('es-es');
```
@@ -653,7 +653,7 @@ $acceptsSpanish = $this->request->acceptLanguage('es-es');
Request cookies can be read through a number of methods:
-``` php
+```php
// Get the cookie value, or null if the cookie is missing.
$rememberMe = $this->request->getCookie('remember_me');
@@ -675,7 +675,7 @@ to work with cookie collection.
Requests expose the uploaded file data in `getData()` or
`getUploadedFiles()` as `UploadedFileInterface` objects:
-``` php
+```php
// Get a list of UploadedFile objects
$files = $request->getUploadedFiles();
@@ -693,7 +693,7 @@ $files[0]->moveTo($targetPath);
Requests contain a URI object, which contains methods for interacting with the
requested URI:
-``` php
+```php
// Get the URI
$uri = $request->getUri();
@@ -729,7 +729,7 @@ You can control the Content-Type of your application's responses with
with content types that are not built into Response, you can map them with
`setTypeMap()` as well:
-``` php
+```php
// Add a vCard type
$this->response->setTypeMap('vcf', ['text/v-card']);
@@ -750,7 +750,7 @@ automatic view switching provided by [Controller Viewclasses](../controllers#con
There are times when you want to send files as responses for your requests.
You can accomplish that by using `Cake\Http\Response::withFile()`:
-``` php
+```php
public function sendFile($id)
{
$file = $this->Attachments->getFile($id);
@@ -770,7 +770,7 @@ in `Cake\Http\Response::$_mimeTypes`. You can add new types prior to calling
If you want, you can also force a file to be downloaded instead of displayed in
the browser by specifying the options:
-``` php
+```php
$response = $this->response->withFile(
$file['path'],
['download' => true, 'name' => 'foo'],
@@ -792,7 +792,7 @@ download.
You can respond with a file that does not exist on the disk, such as a pdf or an
ics generated on the fly from a string:
-``` php
+```php
public function sendIcs()
{
$icsString = $this->Calendars->generateIcs();
@@ -820,7 +820,7 @@ Setting headers is done with the `Cake\Http\Response::withHeader()`
method. Like all the PSR-7 interface methods, this method returns a *new*
instance with the new header:
-``` php
+```php
// Add/replace a header
$response = $response->withHeader('X-Extra', 'My header');
@@ -845,7 +845,7 @@ redirect location header.
To set a string as the response body, do the following:
-``` php
+```php
// Set a string into the body
$response = $response->withStringBody('My Body');
@@ -859,7 +859,7 @@ $response = $response->withType('application/json')
To set the response body, use the `withBody()` method, which is provided by the
`Laminas\Diactoros\MessageTrait`:
-``` php
+```php
$response = $response->withBody($stream);
```
@@ -868,7 +868,7 @@ See below on how to create a new stream.
You can also stream responses from files using `Laminas\Diactoros\Stream` streams:
-``` php
+```php
// To stream from a file
use Laminas\Diactoros\Stream;
@@ -880,7 +880,7 @@ You can also stream responses from a callback using the `CallbackStream`. This
is useful when you have resources like images, CSV files or PDFs you need to
stream to the client:
-``` php
+```php
// Streaming from a callback
use Cake\Http\CallbackStream;
@@ -900,7 +900,7 @@ $response = $response->withBody($stream);
Sets the charset that will be used in the response:
-``` php
+```php
$this->response = $this->response->withCharset('UTF-8');
```
@@ -912,7 +912,7 @@ You sometimes need to force browsers not to cache the results of a controller
action. `Cake\Http\Response::withDisabledCache()` is intended for just
that:
-``` php
+```php
public function index()
{
// Disable caching
@@ -929,7 +929,7 @@ public function index()
You can also tell clients that you want them to cache responses. By using
`Cake\Http\Response::withCache()`:
-``` php
+```php
public function index()
{
// Enable caching
@@ -982,7 +982,7 @@ The second parameter of this method is used to specify a `max-age` for the
cache, which is the number of seconds after which the response is no longer
considered fresh:
-``` php
+```php
public function view()
{
// ...
@@ -1009,7 +1009,7 @@ You can set the `Expires` header to a date and time after which the response
is no longer considered fresh. This header can be set using the
`withExpires()` method:
-``` php
+```php
public function view()
{
$this->response = $this->response->withExpires('+5 days');
@@ -1038,7 +1038,7 @@ To take advantage of this header, you must either call the
`isNotModified()` method manually or include the
[Checking HTTP Cache](../controllers/components/check-http-cache) in your controller:
-``` php
+```php
public function index()
{
$articles = $this->Articles->find('all')->all();
@@ -1075,7 +1075,7 @@ To take advantage of this header, you must either call the
`isNotModified()` method manually or include the
[Checking HTTP Cache](../controllers/components/check-http-cache) in your controller:
-``` php
+```php
public function view()
{
$article = $this->Articles->find()->first();
@@ -1097,7 +1097,7 @@ This is often the case if you have a multilingual page or respond with different
HTML depending on the browser. Under such circumstances you can use the `Vary`
header:
-``` php
+```php
$response = $this->response->withVary('User-Agent');
$response = $this->response->withVary('Accept-Encoding', 'User-Agent');
$response = $this->response->withVary('Accept-Language');
@@ -1111,7 +1111,7 @@ Compares the cache headers for the request object with the cache header from the
response and determines whether it can still be considered fresh. If so, deletes
the response content, and sends the `304 Not Modified` header:
-``` php
+```php
// In a controller action.
if ($this->response->isNotModified($this->request)) {
return $this->response;
@@ -1125,7 +1125,7 @@ if ($this->response->isNotModified($this->request)) {
Cookies can be added to response using either an array or a `Cake\Http\Cookie\Cookie`
object:
-``` php
+```php
use Cake\Http\Cookie\Cookie;
use DateTime;
@@ -1149,7 +1149,7 @@ See the [Creating Cookies](#creating-cookies) section for how to use the cookie
can use `withExpiredCookie()` to send an expired cookie in the response. This
will make the browser remove its local cookie:
-``` php
+```php
$this->response = $this->response->withExpiredCookie(new Cookie('remember_me'));
```
@@ -1161,7 +1161,7 @@ The `cors()` method returns a `CorsBuilder` instance which provides a fluent
interface for defining [HTTP Access Control](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS)
related headers:
-``` php
+```php
$this->response = $this->response->cors($this->request)
->allowOrigin(['*.cakephp.org'])
->allowMethods(['GET', 'POST'])
@@ -1204,7 +1204,7 @@ Here are some common CORS configurations:
**API accepting requests from a SPA frontend**:
-``` php
+```php
// In your controller
public function beforeFilter(EventInterface $event)
{
@@ -1238,7 +1238,7 @@ public function index()
**Public API with relaxed CORS**:
-``` php
+```php
$this->response = $this->response->cors($this->request)
->allowOrigin('*')
->allowMethods(['GET'])
@@ -1251,7 +1251,7 @@ $this->response = $this->response->cors($this->request)
For consistent CORS handling across your application, create a middleware:
-``` php
+```php
// src/Middleware/CorsMiddleware.php
namespace App\Middleware;
@@ -1293,7 +1293,7 @@ class CorsMiddleware implements MiddlewareInterface
Then add it to your application middleware stack in `src/Application.php`:
-``` php
+```php
public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
{
$middlewareQueue
@@ -1336,7 +1336,7 @@ immutable objects can take some getting used to. Any method that starts with
return a **new** instance. Forgetting to retain the modified instance is the most
frequent mistake people make when working with immutable objects:
-``` php
+```php
$this->response->withHeader('X-CakePHP', 'yes!');
```
@@ -1344,7 +1344,7 @@ In the above code, the response will be lacking the `X-CakePHP` header, as the
return value of the `withHeader()` method was not retained. To correct the
above code you would write:
-``` php
+```php
$this->response = $this->response->withHeader('X-CakePHP', 'yes!');
```
@@ -1363,7 +1363,7 @@ allow the immutability of the request and response to be preserved.
`Cookie` objects can be defined through constructor objects, or by using the
fluent interface that follows immutable patterns:
-``` php
+```php
use Cake\Http\Cookie\Cookie;
// All arguments in the constructor
@@ -1390,7 +1390,7 @@ $cookie = (new Cookie('remember_me'))
Once you have created a cookie, you can add it to a new or existing
`CookieCollection`:
-``` php
+```php
use Cake\Http\Cookie\CookieCollection;
// Create a new collection
@@ -1409,7 +1409,7 @@ $cookies = $cookies->remove('remember_me');
Cookie objects can be added to responses:
-``` php
+```php
// Add one cookie
$response = $this->response->withCookie($cookie);
@@ -1427,7 +1427,7 @@ Cookies set to responses can be encrypted using the
Once you have a `CookieCollection` instance, you can access the cookies it
contains:
-``` php
+```php
// Check if a cookie exists
$cookies->has('remember_me');
@@ -1448,7 +1448,7 @@ Once you have a `Cookie` object you can interact with its state and modify
it. Keep in mind that cookies are immutable, so you'll need to update the
collection if you modify a cookie:
-``` php
+```php
// Get the value
$value = $cookie->getValue()
diff --git a/docs/en/core-libraries/app.md b/docs/en/core-libraries/app.md
index 2a3e65c862..1efd452cea 100644
--- a/docs/en/core-libraries/app.md
+++ b/docs/en/core-libraries/app.md
@@ -18,7 +18,7 @@ The App class is responsible for resource location and path management.
This method is used to resolve class names throughout CakePHP. It resolves
the short form names CakePHP uses and returns the fully resolved class name:
-``` php
+```php
// Resolve a short class name with the namespace + suffix.
App::className('Flash', 'Controller/Component', 'Component');
// Returns Cake\Controller\Component\FlashComponent
@@ -44,7 +44,7 @@ class names do not exist, `false` will be returned.
The method returns paths set using `App.paths` app config:
-``` php
+```php
// Get the templates path set using ``App.paths.templates`` app config.
App::path('templates');
```
@@ -59,7 +59,7 @@ The same way you can retrieve paths for `locales` and `plugins`.
Used to get locations for paths based on conventions:
-``` php
+```php
// Get the path to Controller/ in your application
App::classPath('Controller');
```
@@ -76,7 +76,7 @@ for.
Used for finding the path to a package inside CakePHP:
-``` php
+```php
// Get the path to Cache engines.
App::core('Cache/Engine');
```
@@ -99,7 +99,7 @@ If you had a library called AcmeLib, you could install it into
you could autoload the classes within it using `classmap` in your
application's `composer.json`:
-``` json
+```json
"autoload": {
"psr-4": {
"App\\": "src/",
@@ -115,7 +115,7 @@ If your vendor library does not use classes, and instead provides functions, you
can configure Composer to load these files at the beginning of each request
using the `files` autoloading strategy:
-``` json
+```json
"autoload": {
"psr-4": {
"App\\": "src/",
@@ -130,7 +130,7 @@ using the `files` autoloading strategy:
After configuring the vendor libraries you will need to regenerate your
application's autoloader using:
-``` bash
+```bash
php composer.phar dump-autoload
```
diff --git a/docs/en/core-libraries/caching.md b/docs/en/core-libraries/caching.md
index 10a9e5e667..904a99c17a 100644
--- a/docs/en/core-libraries/caching.md
+++ b/docs/en/core-libraries/caching.md
@@ -62,7 +62,7 @@ Using multiple engine configurations also lets you incrementally change the
storage as needed. For example in your **config/app.php** you could put the
following:
-``` php
+```php
// ...
'Cache' => [
'short' => [
@@ -85,7 +85,7 @@ following:
Configuration options can also be provided as a `DSN` string. This is
useful when working with environment variables or `PaaS` providers:
-``` php
+```php
Cache::setConfig('short', [
'url' => 'memcached://user:password@cache-host/?timeout=3600&prefix=myapp_',
]);
@@ -96,7 +96,7 @@ query string arguments.
You can also configure Cache engines at runtime:
-``` php
+```php
// Using a short name
Cache::setConfig('short', [
'className' => 'File',
@@ -123,7 +123,7 @@ parameter for `Cake\Cache\Cache::write()` and
`Cake\Cache\Cache::read()`. When configuring cache engines you can
refer to the class name using the following syntaxes:
-``` php
+```php
// Short name (in App\ or Cake namespaces)
Cache::setConfig('long', ['className' => 'File']);
@@ -194,7 +194,7 @@ Redis Cluster support was added in 5.3
To use Redis Cluster, configure the `cluster` option with an array of server addresses:
-``` php
+```php
Cache::setConfig('redis_cluster', [
'className' => 'Redis',
'duration' => '+1 hours',
@@ -240,7 +240,7 @@ cache failure.
You can configure Cache configurations to fall back to a specified config using
the `fallback` configuration key:
-``` php
+```php
Cache::setConfig('redis', [
'className' => 'Redis',
'duration' => '+1 hours',
@@ -259,7 +259,7 @@ from throwing an uncaught exception.
You can turn off cache fallbacks with `false`:
-``` php
+```php
Cache::setConfig('redis', [
'className' => 'Redis',
'duration' => '+1 hours',
@@ -294,7 +294,7 @@ no `$config` is specified, default will be used. `Cache::write()`
can store any type of object and is ideal for storing results of
model finds:
-``` php
+```php
$posts = Cache::read('posts');
if ($posts === null) {
$posts = $someService->getAllPosts();
@@ -319,7 +319,7 @@ can use multiple calls to `write()`, `writeMany()` allows CakePHP to use
more efficient storage APIs where available. For example using `writeMany()`
save multiple network connections when using Memcached:
-``` php
+```php
$result = Cache::writeMany([
'article-' . $slug => $article,
'article-' . $slug . '-comments' => $comments,
@@ -337,7 +337,7 @@ Using `Cache::add()` will let you atomically set a key to a value if the key
does not already exist in the cache. If the key already exists in the cache
backend or the write fails, `add()` will return `false`:
-``` php
+```php
// Set a key to act as a lock
$result = Cache::add($lockKey, true);
if (!$result) {
@@ -363,7 +363,7 @@ and the results stored in the cache at the provided key.
For example, you often want to cache remote service call results. You could use
`remember()` to make this simple:
-``` php
+```php
class IssueService
{
public function allIssues(string $repo): mixed
@@ -390,7 +390,7 @@ to check the success of the `Cache::read()` operation.
For example:
-``` php
+```php
$cloud = Cache::read('cloud');
if ($cloud !== null) {
return $cloud;
@@ -408,7 +408,7 @@ return $cloud;
Or if you are using another cache configuration called `short`, you can
specify it in `Cache::read()` and `Cache::write()` calls as below:
-``` php
+```php
// Read key "cloud", but from short configuration instead of default
$cloud = Cache::read('cloud', 'short');
if ($cloud === null) {
@@ -431,7 +431,7 @@ well. While you could use multiple calls to `read()`, `readMany()` allows
CakePHP to use more efficient storage APIs where available. For example using
`readMany()` save multiple network connections when using Memcached:
-``` php
+```php
$result = Cache::readMany([
'article-' . $slug,
'article-' . $slug . '-comments',
@@ -449,7 +449,7 @@ $result = Cache::readMany([
`Cache::delete()` will allow you to completely remove a cached
object from the store:
-``` php
+```php
// Remove a key
Cache::delete('my_key');
```
@@ -457,7 +457,7 @@ Cache::delete('my_key');
As of 4.4.0, the `RedisEngine` also provides a `deleteAsync()` method
which uses the `UNLINK` operation to remove cache keys:
-``` php
+```php
Cache::pool('redis')->deleteAsync('my_key');
```
@@ -470,7 +470,7 @@ you could use multiple calls to `delete()`, `deleteMany()` allows CakePHP to use
more efficient storage APIs where available. For example using `deleteMany()`
save multiple network connections when using Memcached:
-``` php
+```php
$result = Cache::deleteMany([
'article-' . $slug,
'article-' . $slug . '-comments',
@@ -490,7 +490,7 @@ Memcached, the cache configuration's prefix is used to remove
cache entries. Make sure that different cache configurations have different
prefixes:
-``` php
+```php
// Will clear all keys.
Cache::clear();
```
@@ -498,7 +498,7 @@ Cache::clear();
As of 4.4.0, the `RedisEngine` also provides a `clearBlocking()` method
which uses the `UNLINK` operation to remove cache keys:
-``` php
+```php
Cache::pool('redis')->clearBlocking();
```
@@ -526,7 +526,7 @@ lower the value by one, resulting in an incorrect value.
After setting an integer value you can manipulate it using `increment()` and
`decrement()`:
-``` php
+```php
Cache::write('initial_count', 10);
// Later on
@@ -558,7 +558,7 @@ group or namespace. This is a common requirement for mass-invalidating keys
whenever some information changes that is shared among all entries in the same
group. This is possible by declaring the groups in cache configuration:
-``` php
+```php
Cache::setConfig('site_home', [
'className' => 'Redis',
'duration' => '+999 days',
@@ -579,7 +579,7 @@ both group names.
For instance, whenever a new post is added, we could tell the Cache engine to
remove all entries associated to the `article` group:
-``` php
+```php
// src/Model/Table/ArticlesTable.php
public function afterSave(EventInterface $event, EntityInterface $entity, ArrayObject $options): void
{
@@ -596,7 +596,7 @@ public function afterSave(EventInterface $event, EntityInterface $entity, ArrayO
`groupConfigs()` can be used to retrieve mapping between group and
configurations, i.e.: having the same group:
-``` php
+```php
// src/Model/Table/ArticlesTable.php
/**
@@ -628,7 +628,7 @@ You may need to disable all Cache read & writes when trying to figure out cache
expiration related issues. You can do this using `enable()` and
`disable()`:
-``` php
+```php
// Disable all cache reads, and cache writes.
Cache::disable();
```
@@ -641,7 +641,7 @@ Once disabled, all reads and writes will return `null`.
Once disabled, you can use `enable()` to re-enable caching:
-``` php
+```php
// Re-enable all cache reads, and cache writes.
Cache::enable();
```
@@ -662,7 +662,7 @@ Or in **plugins/MyPlugin/src/Cache/Engine/MyCustomCacheEngine.php** as
part of a plugin. Cache configs from plugins need to use the plugin
dot syntax:
-``` php
+```php
Cache::setConfig('custom', [
'className' => 'MyPlugin.MyCustomCache',
// ...
@@ -715,7 +715,7 @@ You can add event listeners to the following events:
an example listener in your `src/Application.php` or plugin class would be:
-``` php
+```php
public function events(EventManagerInterface $eventManager): EventManagerInterface
{
$eventManager->on(CacheAfterGetEvent::NAME, function (CacheAfterGetEvent $event): void {
diff --git a/docs/en/core-libraries/collections.md b/docs/en/core-libraries/collections.md
index 0f6a661836..acad10a442 100644
--- a/docs/en/core-libraries/collections.md
+++ b/docs/en/core-libraries/collections.md
@@ -21,7 +21,7 @@ Collections can be created using an array or `Traversable` object. You'll also
interact with collections every time you interact with the ORM in CakePHP.
A simple use of a Collection would be:
-``` php
+```php
use Cake\Collection\Collection;
$items = ['a' => 1, 'b' => 2, 'c' => 3];
@@ -36,7 +36,7 @@ $overOne = $collection->filter(function ($value, $key, $iterator) {
You can also use the `collection()` helper function instead of `new Collection()`:
-``` php
+```php
$items = ['a' => 1, 'b' => 2, 'c' => 3];
// These both make a Collection instance.
@@ -81,7 +81,7 @@ Collections can be iterated and/or transformed into new collections with the
`each()` and `map()` methods. The `each()` method will not create a new
collection, but will allow you to modify any objects within the collection:
-``` php
+```php
$collection = new Collection($items);
$collection = $collection->each(function ($value, $key) {
echo "Element $key: $value";
@@ -98,7 +98,7 @@ collection immediately applying the callback to each value in the collection.
The `map()` method will create a new collection based on the output of the
callback being applied to each object in the original collection:
-``` php
+```php
$items = ['a' => 1, 'b' => 2, 'c' => 3];
$collection = new Collection($items);
@@ -125,7 +125,7 @@ column from a collection. If you are looking to build a list of elements
containing the values for a particular property, you can use the `extract()`
method:
-``` php
+```php
$collection = new Collection($people);
$names = $collection->extract('name');
@@ -137,7 +137,7 @@ As with many other functions in the collection class, you are allowed to specify
a dot-separated path for extracting columns. This example will return
a collection containing the author names from a list of articles:
-``` php
+```php
$collection = new Collection($articles);
$names = $collection->extract('author.name');
@@ -148,7 +148,7 @@ $result = $names->toList();
Finally, if the property you are looking after cannot be expressed as a path,
you can use a callback function to return it:
-``` php
+```php
$collection = new Collection($articles);
$names = $collection->extract(function ($article) {
return $article->author->name . ', ' . $article->author->last_name;
@@ -160,7 +160,7 @@ arrays or objects that are deeply nested inside other structures. For those
cases you can use the `{*}` matcher in the path key. This matcher is often
helpful when matching HasMany and BelongsToMany association data:
-``` php
+```php
$data = [
[
'name' => 'James',
@@ -199,7 +199,7 @@ Collections allow you to create a new collection made from keys and values in
an existing collection. Both the key and value paths can be specified with
dot notation paths:
-``` php
+```php
$items = [
['id' => 1, 'name' => 'foo', 'parent' => 'a'],
['id' => 2, 'name' => 'bar', 'parent' => 'b'],
@@ -218,7 +218,7 @@ $result = $combined->toArray();
You can also optionally use a `groupPath` to group results based on a path:
-``` php
+```php
$combined = (new Collection($items))->combine('id', 'name', 'parent');
$result = $combined->toArray();
@@ -233,7 +233,7 @@ Finally you can use *closures* to build keys/values/groups paths dynamically,
for example when working with entities and dates (converted to `I18n\DateTime`
instances by the ORM) you may want to group results by date:
-``` php
+```php
$combined = (new Collection($entities))->combine(
'id',
function ($entity) { return $entity; },
@@ -256,7 +256,7 @@ You can stop the iteration at any point using the `stopWhen()` method. Calling
it in a collection will create a new one that will stop yielding results if the
passed callable returns true for one of the elements:
-``` php
+```php
$items = [10, 20, 50, 1, 2];
$collection = new Collection($items);
@@ -278,7 +278,7 @@ with more items. If you wish to flatten the internal structure to iterate once
over all elements you can use the `unfold()` method. It will create a new
collection that will yield every single element nested in the collection:
-``` php
+```php
$items = [[1, 2, 3], [4, 5]];
$collection = new Collection($items);
$new = $collection->unfold();
@@ -291,7 +291,7 @@ When passing a callable to `unfold()` you can control what elements will be
unfolded from each item in the original collection. This is useful for returning
data from paginated services:
-``` php
+```php
$pages = [1, 2, 3, 4];
$collection = new Collection($pages);
$items = $collection->unfold(function ($page, $key) {
@@ -305,7 +305,7 @@ $allPagesItems = $items->toList();
You can use the `yield` keyword inside `unfold()` to return as
many elements for each item in the collection as you may need:
-``` php
+```php
$oddNumbers = [1, 3, 5, 7];
$collection = new Collection($oddNumbers);
$new = $collection->unfold(function ($oddNumber) {
@@ -326,7 +326,7 @@ process the elements in batches instead of one by one. For splitting
a collection into multiple arrays of a certain size, you can use the `chunk()`
function:
-``` php
+```php
$items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
$collection = new Collection($items);
$chunked = $collection->chunk(2);
@@ -336,7 +336,7 @@ $chunked->toList(); // [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11]]
The `chunk` function is particularly useful when doing batch processing, for
example with a database result:
-``` php
+```php
$collection = new Collection($articles);
$collection->map(function ($article) {
// Change a property in the article
@@ -356,7 +356,7 @@ Much like `chunk()`, `chunkWithKeys()` allows you to slice up
a collection into smaller batches but with keys preserved. This is useful when
chunking associative arrays:
-``` php
+```php
$collection = new Collection([
'a' => 1,
'b' => 2,
@@ -383,7 +383,7 @@ Collections allow you to filter and create new collections based on
the result of callback functions. You can use `filter()` to create a new
collection of elements matching a criteria callback:
-``` php
+```php
$collection = new Collection($people);
$ladies = $collection->filter(function ($person, $key) {
return $person->gender === 'female';
@@ -400,7 +400,7 @@ $guys = $collection->filter(function ($person, $key) {
The inverse of `filter()` is `reject()`. This method does a negative filter,
removing elements that match the filter function:
-``` php
+```php
$collection = new Collection($people);
$ladies = $collection->reject(function ($person, $key) {
return $person->gender === 'male';
@@ -414,7 +414,7 @@ $ladies = $collection->reject(function ($person, $key) {
You can do truth tests with filter functions. To see if every element in
a collection matches a test you can use `every()`:
-``` php
+```php
$collection = new Collection($people);
$allYoungPeople = $collection->every(function ($person) {
return $person->age < 21;
@@ -432,7 +432,7 @@ $allYoungPeople = $collection->every(function ($person) {
You can see if the collection contains at least one element matching a filter
function using the `any()` method:
-``` php
+```php
$collection = new Collection($people);
$hasYoungPeople = $collection->any(function ($person) {
return $person->age < 21;
@@ -449,7 +449,7 @@ $hasYoungPeople = $collection->any(function ($person) {
If you need to extract a new collection containing only the elements that
contain a given set of properties, you should use the `match()` method:
-``` php
+```php
$collection = new Collection($comments);
$commentsFromMark = $collection->match(['user.name' => 'Mark']);
```
@@ -462,7 +462,7 @@ The property name can be a dot-separated path. You can traverse into nested
entities and match the values they contain. When you only need the first
matching element from a collection, you can use `firstMatch()`:
-``` php
+```php
$collection = new Collection($comments);
$comment = $collection->firstMatch([
'user.name' => 'Mark',
@@ -485,7 +485,7 @@ The counterpart of a `map()` operation is usually a `reduce`. This
function will help you build a single result out of all the elements in a
collection:
-``` php
+```php
$totalPrice = $collection->reduce(function ($accumulated, $orderLine) {
return $accumulated + $orderLine->price;
}, 0);
@@ -496,7 +496,7 @@ contained in the collection. Note the second argument for the `reduce()`
function takes the initial value for the reduce operation you are
performing:
-``` php
+```php
$allTags = $collection->reduce(function ($accumulated, $article) {
return array_merge($accumulated, $article->tags);
}, []);
@@ -510,7 +510,7 @@ To extract the minimum value for a collection based on a property, just use the
`min()` function. This will return the full element from the collection and
not just the smallest value found:
-``` php
+```php
$collection = new Collection($people);
$youngest = $collection->min('age');
@@ -520,7 +520,7 @@ echo $youngest->name;
You are also able to express the property to compare by providing a path or a
callback function:
-``` php
+```php
$collection = new Collection($people);
$personYoungestChild = $collection->min(function ($person) {
return $person->child->age;
@@ -536,7 +536,7 @@ $personWithYoungestDad = $collection->min('dad.age');
The same can be applied to the `max()` function, which will return a single
element from the collection having the highest property value:
-``` php
+```php
$collection = new Collection($people);
$oldest = $collection->max('age');
@@ -554,7 +554,7 @@ $personWithOldestDad = $collection->max('dad.age');
Finally, the `sumOf()` method will return the sum of a property of all
elements:
-``` php
+```php
$collection = new Collection($people);
$sumOfAges = $collection->sumOf('age');
@@ -573,7 +573,7 @@ Calculate the average value of the elements in the collection. Optionally
provide a matcher path, or function to extract values to generate the average
for:
-``` php
+```php
$items = [
['invoice' => ['total' => 100]],
['invoice' => ['total' => 200]],
@@ -590,7 +590,7 @@ $average = (new Collection($items))->avg('invoice.total');
Calculate the median value of a set of elements. Optionally provide a matcher
path, or function to extract values to generate the median for:
-``` php
+```php
$items = [
['invoice' => ['total' => 400]],
['invoice' => ['total' => 500]],
@@ -612,7 +612,7 @@ $median = (new Collection($items))->median('invoice.total');
Collection values can be grouped by different keys in a new collection when they
share the same value for a property:
-``` php
+```php
$students = [
['name' => 'Mark', 'grade' => 9],
['name' => 'Andrew', 'grade' => 10],
@@ -639,7 +639,7 @@ $result = $studentsByGrade->toArray();
As usual, it is possible to provide either a dot-separated path for nested
properties or your own callback function to generate the groups dynamically:
-``` php
+```php
$commentsByUserId = $comments->groupBy('user.id');
$classResults = $students->groupBy(function ($student) {
@@ -655,7 +655,7 @@ If you only wish to know the number of occurrences per group, you can do so by
using the `countBy()` method. It takes the same arguments as `groupBy` so it
should be already familiar to you:
-``` php
+```php
$classResults = $students->countBy(function ($student) {
return $student->grade > 6 ? 'approved' : 'denied';
});
@@ -672,7 +672,7 @@ There will be certain cases where you know an element is unique for the property
you want to group by. If you wish a single result per group, you can use the
function `indexBy()`:
-``` php
+```php
$usersById = $users->indexBy('id');
// When converted to array result could look like
@@ -686,7 +686,7 @@ $usersById = $users->indexBy('id');
As with the `groupBy()` function you can also use a property path or
a callback:
-``` php
+```php
$articlesByAuthorId = $articles->indexBy('author.id');
$filesByHash = $files->indexBy(function ($file) {
@@ -702,7 +702,7 @@ The elements of different collections can be grouped together using the
`zip()` method. It will return a new collection containing an array grouping
the elements from each collection that are placed at the same position:
-``` php
+```php
$odds = new Collection([1, 3, 5]);
$pairs = new Collection([2, 4, 6]);
$combined = $odds->zip($pairs)->toList(); // [[1, 2], [3, 4], [5, 6]]
@@ -710,7 +710,7 @@ $combined = $odds->zip($pairs)->toList(); // [[1, 2], [3, 4], [5, 6]]
You can also zip multiple collections at once:
-``` php
+```php
$years = new Collection([2013, 2014, 2015, 2016]);
$salaries = [1000, 1500, 2000, 2300];
$increments = [0, 500, 500, 300];
@@ -730,7 +730,7 @@ $result = $rows->toList();
As you can already see, the `zip()` method is very useful for transposing
multidimensional arrays:
-``` php
+```php
$data = [
2014 => ['jan' => 100, 'feb' => 200],
2015 => ['jan' => 300, 'feb' => 500],
@@ -761,7 +761,7 @@ Collection values can be sorted in ascending or descending order based on
a column or custom function. To create a new sorted collection out of the values
of another one, you can use `sortBy`:
-``` php
+```php
$collection = new Collection($people);
$sorted = $collection->sortBy('age');
```
@@ -771,7 +771,7 @@ is present in the collection values. You are also able to specify a property
path instead using the dot notation. The next example will sort articles by
their author's name:
-``` php
+```php
$collection = new Collection($articles);
$sorted = $collection->sortBy('author.name');
```
@@ -780,7 +780,7 @@ The `sortBy()` method is flexible enough to let you specify an extractor
function that will let you dynamically select the value to use for comparing two
different values in the collection:
-``` php
+```php
$collection = new Collection($articles);
$sorted = $collection->sortBy(function ($article) {
return $article->author->name . '-' . $article->title;
@@ -792,7 +792,7 @@ to provide either `SORT_ASC` or `SORT_DESC` as the second parameter for
sorting in ascending or descending direction respectively. By default,
collections are sorted in descending direction:
-``` php
+```php
$collection = new Collection($people);
$sorted = $collection->sortBy('age', SORT_ASC);
```
@@ -809,7 +809,7 @@ argument in the `sortBy()` function with one of the following constants:
By default, `SORT_NUMERIC` is used:
-``` php
+```php
$collection = new Collection($articles);
$sorted = $collection->sortBy('title', SORT_ASC, SORT_NATURAL);
```
@@ -834,7 +834,7 @@ Two parameters are required for this function. The first one is the property
representing the item identifier. The second parameter is the name of the
property representing the identifier for the parent item:
-``` php
+```php
$collection = new Collection([
['id' => 1, 'parent_id' => null, 'name' => 'Birds'],
['id' => 2, 'parent_id' => 1, 'name' => 'Land Birds'],
@@ -886,7 +886,7 @@ collection.
Taking the input the nested collection built in the previous example, we can
flatten it:
-``` php
+```php
$result = $nested->listNested()->toList();
// $result contains
@@ -903,7 +903,7 @@ $result = $nested->listNested()->toList();
By default, the tree is traversed from the root to the leaves. You can also
instruct it to only return the leaf elements in the tree:
-``` php
+```php
$result = $nested->listNested('leaves')->toList();
// $result contains
@@ -918,7 +918,7 @@ $result = $nested->listNested('leaves')->toList();
Once you have converted a tree into a nested list, you can use the `printer()`
method to configure how the list output should be formatted:
-``` php
+```php
$result = $nested->listNested()->printer('name', 'id', '--')->toArray();
// $result contains
@@ -935,7 +935,7 @@ $result = $nested->listNested()->printer('name', 'id', '--')->toArray();
The `printer()` method also lets you use a callback to generate the keys and
or values:
-``` php
+```php
$nested->listNested()->printer(
function ($el) {
return $el->name;
@@ -954,7 +954,7 @@ $nested->listNested()->printer(
Allows you to see if a collection contains any elements:
-``` php
+```php
$collection = new Collection([]);
// Returns true
$collection->isEmpty();
@@ -971,7 +971,7 @@ $collection->isEmpty();
Collections allow you to quickly check if they contain one particular
value: by using the `contains()` method:
-``` php
+```php
$items = ['a' => 1, 'b' => 2, 'c' => 3];
$collection = new Collection($items);
$hasThree = $collection->contains(3);
@@ -988,7 +988,7 @@ Sometimes you may wish to show a collection of values in a random order. In
order to create a new collection that will return each value in a randomized
position, use the `shuffle`:
-``` php
+```php
$collection = new Collection(['a' => 1, 'b' => 2, 'c' => 3]);
// This could return [2, 3, 1]
@@ -1002,7 +1002,7 @@ $collection->shuffle()->toList();
When you transpose a collection, you get a new collection containing a row made
of the each of the original columns:
-``` php
+```php
$items = [
['Products', '2012', '2013', '2014'],
['Product A', '200', '100', '50'],
@@ -1033,7 +1033,7 @@ random values out of a collection so that more tests can be performed on those.
For example, if you wanted to select 5 random users to which you'd like to apply
some A/B tests to, you can use the `sample()` function:
-``` php
+```php
$collection = new Collection($people);
// Withdraw maximum 20 random users from this collection
@@ -1052,7 +1052,7 @@ Whenever you want to take a slice of a collection use the `take()` function,
it will create a new collection with at most the number of values you specify in
the first argument, starting from the position passed in the second argument:
-``` php
+```php
$topFive = $collection->sortBy('age')->take(5);
// Take 5 people from the collection starting from position 4
@@ -1069,7 +1069,7 @@ While the second argument of `take()` can help you skip some elements before
getting them from the collection, you can also use `skip()` for the same
purpose as a way to take the rest of the elements after a certain position:
-``` php
+```php
$collection = new Collection([1, 2, 3, 4]);
$allExceptFirstTwo = $collection->skip(2)->toList(); // [3, 4]
```
@@ -1082,7 +1082,7 @@ One of the most common uses of `take()` is getting the first element in the
collection. A shortcut method for achieving the same goal is using the
`first()` method:
-``` php
+```php
$collection = new Collection([5, 4, 3, 2]);
$collection->first(); // Returns 5
```
@@ -1094,7 +1094,7 @@ $collection->first(); // Returns 5
Similarly, you can get the last element of a collection using the `last()`
method:
-``` php
+```php
$collection = new Collection([5, 4, 3, 2]);
$collection->last(); // Returns 2
```
@@ -1110,7 +1110,7 @@ gather data from various sources, concatenate it, and apply other collection
functions to it very smoothly. The `append()` method will return a new
collection containing the values from both sources:
-``` php
+```php
$cakephpTweets = new Collection($tweets);
$myTimeline = $cakephpTweets->append($phpTweets);
@@ -1128,7 +1128,7 @@ Allows you to append an item with an optional key to the collection. If you
specify a key that already exists in the collection, the value will not be
overwritten:
-``` php
+```php
$cakephpTweets = new Collection($tweets);
$myTimeline = $cakephpTweets->appendItem($newTweet, 99);
```
@@ -1140,7 +1140,7 @@ $myTimeline = $cakephpTweets->appendItem($newTweet, 99);
The `prepend()` method will return a new collection containing the values from
both sources:
-``` php
+```php
$cakephpTweets = new Collection($tweets);
$myTimeline = $cakephpTweets->prepend($phpTweets);
```
@@ -1153,7 +1153,7 @@ Allows you to prepend an item with an optional key to the collection. If you
specify a key that already exists in the collection, the value will not be
overwritten:
-``` php
+```php
$cakephpTweets = new Collection($tweets);
$myTimeline = $cakephpTweets->prependItem($newTweet, 99);
```
@@ -1181,7 +1181,7 @@ Collections offer an `insert()` method that will allow you to insert each of
the elements in one collection into a property inside each of the elements of
another collection:
-``` php
+```php
$users = [
['username' => 'mark'],
['username' => 'juan'],
@@ -1216,7 +1216,7 @@ element of the first collection.
If there are not enough elements in the second collection to insert into the
first one, then the target property will not be present:
-``` php
+```php
$languages = [
['PHP', 'Python', 'Ruby'],
['Bash', 'PHP', 'Javascript'],
@@ -1248,7 +1248,7 @@ reused in multiple parts of your application. It is recommended that you
consider extracting complex collection logic to separate classes. For example,
imagine a lengthy closure like this one:
-``` php
+```php
$collection
->map(function ($row, $key) {
if (!empty($row['items'])) {
@@ -1267,7 +1267,7 @@ $collection
This can be refactored by creating another class:
-``` php
+```php
class TotalOrderCalculator
{
public function __invoke(array $row, string $key): array
@@ -1299,7 +1299,7 @@ of your application, but only if they are called in that specific order. In
those cases you can use `through()` in combination with a class implementing
`__invoke` to distribute your handy data processing calls:
-``` php
+```php
$collection
->map(new ShippingCostCalculator)
->map(new TotalOrderCalculator)
@@ -1311,7 +1311,7 @@ $collection
The above method calls can be extracted into a new class so they don't need to
be repeated every time:
-``` php
+```php
class FinalCheckOutRowProcessor
{
public function __invoke(CollectionInterface $collection): CollectionInterface
@@ -1346,7 +1346,7 @@ early.
Additionally, lazy evaluation helps speed up some operations. Consider the
following example:
-``` php
+```php
$collection = new Collection($oneMillionItems);
$collection = $collection->map(function ($item) {
return $item * 2;
@@ -1365,7 +1365,7 @@ Lazy evaluation comes with its downside too. You could be doing the same
operations more than once if you optimize a collection prematurely. Consider
this example:
-``` php
+```php
$ages = $collection->extract('age');
$youngerThan30 = $ages->filter(function ($item) {
@@ -1386,7 +1386,7 @@ Luckily we can overcome this issue with a single function. If you plan to reuse
the values from certain operations more than once, you can compile the results
into another collection using the `buffered()` function:
-``` php
+```php
$ages = $collection->extract('age')->buffered();
$youngerThan30 = ...
$olderThan30 = ...
@@ -1400,7 +1400,7 @@ extracting operation once.
The `buffered()` method is also useful for converting non-rewindable iterators
into collections that can be iterated more than once:
-``` php
+```php
public function results(): Generator
{
...
@@ -1422,7 +1422,7 @@ collection. This is useful when you need to iterate the same set from different
places at the same time. In order to clone a collection out of another use the
`compile()` method:
-``` php
+```php
$ages = $collection->extract('age')->compile();
foreach ($ages as $age) {
diff --git a/docs/en/core-libraries/email.md b/docs/en/core-libraries/email.md
index b5aee863ca..8d26de55e8 100644
--- a/docs/en/core-libraries/email.md
+++ b/docs/en/core-libraries/email.md
@@ -14,13 +14,13 @@ email from any place inside of your application.
First of all, you should ensure the class is loaded:
-``` php
+```php
use Cake\Mailer\Mailer;
```
After you've loaded `Mailer`, you can send an email with the following:
-``` php
+```php
$mailer = new Mailer('default');
$mailer->setFrom(['me@example.com' => 'My Site'])
->setTo('you@example.com')
@@ -36,7 +36,7 @@ to set its properties with method chaining.
that the first three will overwrite what was already set and the latter will just
add more recipients to their respective field:
-``` php
+```php
$mailer = new Mailer();
$mailer->setTo('to@example.com', 'To Example');
$mailer->addTo('to2@example.com', 'To2 Example');
@@ -50,7 +50,7 @@ $mailer->setTo('test@example.com', 'ToTest Example');
When sending email on behalf of other people, it's often a good idea to define the
original sender using the Sender header. You can do so using `setSender()`:
-``` php
+```php
$mailer = new Mailer();
$mailer->setSender('app@example.com', 'MyApp emailer');
```
@@ -76,7 +76,7 @@ more difficult.
To load a predefined configuration, you can use the `setProfile()` method or
pass it to the constructor of `Mailer`:
-``` php
+```php
$mailer = new Mailer();
$mailer->setProfile('default');
@@ -87,7 +87,7 @@ $mailer = new Mailer('default');
Instead of passing a string which matches a preset configuration name, you can
also just load an array of options:
-``` php
+```php
$mailer = new Mailer();
$mailer->setProfile(['from' => 'me@example.org', 'transport' => 'my_custom']);
@@ -160,7 +160,7 @@ to facilitate that, CakePHP provides a way to send emails using CakePHP's
The templates for emails reside in a special folder `templates/email/` of your
application. Mailer views can also use layouts and elements just like normal views:
-``` php
+```php
$mailer = new Mailer();
$mailer
->setEmailFormat('html')
@@ -177,7 +177,7 @@ The above would use **templates/email/html/welcome.php** for the view
and **templates/layout/email/html/fancy.php** for the layout. You can
send multipart templated email messages as well:
-``` php
+```php
$mailer = new Mailer();
$mailer
->setEmailFormat('both')
@@ -205,7 +205,7 @@ You can set all view related config using the view builder instance got by
You can set view variables with `Mailer::setViewVars()`:
-``` php
+```php
$mailer = new Mailer('templated');
$mailer->setViewVars(['value' => 12345]);
```
@@ -215,7 +215,7 @@ Or you can use the view builder methods `ViewBuilder::setVar()` and
In your email templates you can use these with:
-``` html
+```html
Here is your value: = $value ?>
```
@@ -223,7 +223,7 @@ You can use helpers in emails as well, much like you can in normal template file
By default, only the `HtmlHelper` is loaded. You can load additional
helpers using the `ViewBuilder::addHelpers()` method:
-``` php
+```php
$mailer->viewBuilder()->addHelpers(['Html', 'Custom', 'Text']);
```
@@ -236,7 +236,7 @@ helpers loaded in your email template.
If you want to send email using templates in a plugin you can use the familiar
`plugin syntax` to do so:
-``` php
+```php
$mailer = new Mailer();
$mailer->viewBuilder()->setTemplate('Blog.new_comment');
```
@@ -246,7 +246,7 @@ The above would use template and layout from the Blog plugin as an example.
In some cases, you might need to override the default template provided by plugins.
You can do this using themes:
-``` php
+```php
$mailer->viewBuilder()
->setTemplate('Blog.new_comment')
->setLayout('Blog.auto_message')
@@ -278,7 +278,7 @@ you want the filenames to appear in the recipient's mail client:
3. Nested arrays:
- ``` php
+ ```php
$mailer->setAttachments([
'photo.png' => [
'file' => '/full/some_hash.png',
@@ -321,7 +321,7 @@ If you are having validation issues when sending to non-compliant addresses, you
can relax the pattern used to validate email addresses. This is sometimes
necessary when dealing with some ISPs:
-``` php
+```php
$mailer = new Mailer('default');
// Relax the email pattern, so you can send
@@ -335,7 +335,7 @@ When sending emails within a CLI script (Shells, Tasks, ...) you should manually
set the domain name for Mailer to use. It will serve as the host name for the
message id (since there is no host name in a CLI environment):
-``` php
+```php
$mailer->setDomain('www.example.org');
// Results in message ids like ```` (valid)
// Instead of ``` (invalid)
@@ -356,7 +356,7 @@ emails. To create our `UserMailer`, create the file
**src/Mailer/UserMailer.php**. The contents of the file should look like the
following:
-``` php
+```php
namespace App\Mailer;
use Cake\Mailer\Mailer;
@@ -390,7 +390,7 @@ We are now able to use our `UserMailer` to send out our user-related emails
from anywhere in our application. For example, if we wanted to send our welcome
email we could do the following:
-``` php
+```php
namespace App\Controller;
use Cake\Mailer\MailerAwareTrait;
@@ -419,7 +419,7 @@ application's code, we can have our `UserMailer` subscribe to the
application's user-related classes completely free of email-related logic and
instructions. For example, we could add the following to our `UserMailer`:
-``` php
+```php
public function implementedEvents(): array
{
return [
@@ -439,7 +439,7 @@ You can now register the mailer as an event listener and the
`onRegistration()` method will be invoked every time the `Model.afterSave`
event is fired:
-``` php
+```php
// attach to Users event manager
$this->Users->getEventManager()->on($this->getMailer('User'));
```
@@ -458,7 +458,7 @@ is useful for debugging. Configuring transports allows you to keep configuration
data out of your application code and makes deployment simpler as you can simply
change the configuration data. An example transport configuration looks like:
-``` php
+```php
// In config/app.php
'EmailTransport' => [
// Sample Mail configuration
@@ -480,7 +480,7 @@ change the configuration data. An example transport configuration looks like:
Transports can also be configured at runtime using
`TransportFactory::setConfig()`:
-``` php
+```php
use Cake\Mailer\TransportFactory;
// Define an SMTP transport
@@ -497,7 +497,7 @@ You can configure SSL SMTP servers, like Gmail. To do so, put the `ssl://`
prefix in the host and configure the port value accordingly. You can also
enable TLS SMTP using the `tls` option:
-``` php
+```php
use Cake\Mailer\TransportFactory;
TransportFactory::setConfig('gmail', [
@@ -516,7 +516,7 @@ To configure your mailer to use a specific transport you can use
`Cake\Mailer\Mailer::setTransport()` method or have the transport
in your configuration:
-``` php
+```php
// Use a named transport already configured using TransportFactory::setConfig()
$mailer->setTransport('gmail');
@@ -540,7 +540,7 @@ $mailer->setTransport(new \Cake\Mailer\Transport\DebugTransport());
Configuration options can also be provided as a `DSN` string. This is
useful when working with environment variables or `PaaS` providers:
-``` php
+```php
TransportFactory::setConfig('default', [
'url' => 'smtp://my@gmail.com:secret@smtp.gmail.com:587?tls=true',
]);
@@ -563,7 +563,7 @@ like SendGrid, MailGun or Postmark. To create your transport, first create the f
**src/Mailer/Transport/ExampleTransport.php** (where Example is the name of your
transport). To start, your file should look like:
-``` php
+```php
namespace App\Mailer\Transport;
use Cake\Mailer\AbstractTransport;
@@ -590,7 +590,7 @@ If you want you can use these classes directly with the `Mailer` too.
For example:
-``` php
+```php
$render = new \Cake\Mailer\Renderer();
$render->viewBuilder()
->setTemplate('custom')
@@ -621,7 +621,7 @@ on the mail that would be delivered.
Add the trait to your test case to start testing emails, and load routes if your
emails need to generate URLs:
-``` php
+```php
namespace App\Test\TestCase\Mailer;
use App\Mailer\WelcomeMailer;
@@ -645,7 +645,7 @@ class WelcomeMailerTestCase extends TestCase
Let's assume we have a mailer that delivers welcome emails when a new user
registers. We want to check that the subject and body contain the user's name:
-``` php
+```php
// in our WelcomeMailerTestCase class.
public function testName()
{
@@ -666,7 +666,7 @@ public function testName()
The `Cake\TestSuite\EmailTrait` trait provides the following assertions:
-``` php
+```php
// Asserts an expected number of emails were sent
$this->assertMailCount($count);
diff --git a/docs/en/core-libraries/events.md b/docs/en/core-libraries/events.md
index 2ca8ed37f6..24885525bc 100644
--- a/docs/en/core-libraries/events.md
+++ b/docs/en/core-libraries/events.md
@@ -52,7 +52,7 @@ For example, in your Cart plugin you have an Orders model that deals with
creating orders. You'd like to notify the rest of the application that an order
has been created. To keep your Orders model clean you could use events:
-``` php
+```php
// Cart/Model/Table/OrdersTable.php
namespace Cart\Model\Table;
@@ -88,7 +88,7 @@ objects that focus on those concerns.
In CakePHP events are triggered against event managers. Event managers are
available in every Table, View and Controller using `getEventManager()`:
-``` php
+```php
$events = $this->getEventManager();
```
@@ -106,7 +106,7 @@ difficult. The global manager is a singleton instance of
dispatcher will be fired before instance listeners at the same priority. You can
access the global manager using a static method:
-``` php
+```php
// In any configuration file or piece of code that executes before the event
use Cake\Event\EventManager;
@@ -135,13 +135,13 @@ To keep a list of events that are fired on a particular `EventManager`, you
can enable event tracking. To do so, simply attach an
`Cake\Event\EventList` to the manager:
-``` php
+```php
EventManager::instance()->setEventList(new EventList());
```
After firing an event on the manager, you can retrieve it from the event list:
-``` php
+```php
$eventsFired = EventManager::instance()->getEventList();
$firstEvent = $eventsFired[0];
```
@@ -167,7 +167,7 @@ response has been sent, such as logging or sending emails.
You can listen to this event using an event manager instance:
-``` php
+```php
use Cake\Event\EventInterface;
use Cake\Event\EventManager;
@@ -179,7 +179,7 @@ EventManager::instance()->on('Server.terminate', function (EventInterface $event
Or using the `events` hook in your Application/Plugin class:
-``` php
+```php
use Cake\Event\EventInterface;
use Cake\Event\EventManagerInterface;
@@ -213,7 +213,7 @@ and the `afterExecute` event also contains the `exitCode` which is returned by t
You can listen to this event using an event manager instance:
-``` php
+```php
use Cake\Event\EventInterface;
use Cake\Event\EventManager;
@@ -230,7 +230,7 @@ EventManager::instance()->on('Command.afterExecute', function (EventInterface $e
Or using the `events` hook in your Application/Plugin class:
-``` php
+```php
use Cake\Event\EventInterface;
use Cake\Event\EventManagerInterface;
@@ -266,7 +266,7 @@ global site statistics. This is a great place to use a listener class. Doing so
allows you to concentrate the statistics logic in one place and react to events
as necessary. Our `UserStatistics` listener might start out like:
-``` php
+```php
namespace App\Event;
use Cake\Event\EventInterface;
@@ -304,7 +304,7 @@ The `events` hook was added to the `BaseApplication` as well as the `BasePlugin`
As of CakePHP 5.1 it is recommended to register event listeners by adding them via the `events` hook in your application or plugin class:
-``` php
+```php
namespace App;
use App\Event\UserStatistic;
@@ -332,7 +332,7 @@ you can also bind any `callable` as an event listener. For example if we
wanted to put any orders into the log files, we could use a simple anonymous
function to do so:
-``` php
+```php
use Cake\Event\EventInterface;
use Cake\Log\Log;
@@ -348,7 +348,7 @@ $this->Orders->getEventManager()->on('Order.afterPlace', function (EventInterfac
In addition to anonymous functions you can use any other callable type that PHP
supports:
-``` php
+```php
$events = [
'email-sending' => 'EmailSender::sendBuyEmail',
'inventory' => [$this->InventoryManager, 'decrement'],
@@ -365,7 +365,7 @@ like to know when a Feedback record has been saved and ultimately act on it. You
can listen to the global `Model.afterSave` event. However, you can take
a more direct approach and only listen to the event you really need:
-``` php
+```php
// You can create the following before the
// save operation, i.e. config/bootstrap.php
use Cake\Datasource\FactoryLocator;
@@ -393,7 +393,7 @@ You can use this same approach to bind listener objects.
Assuming several event listeners have been registered the presence or absence
of a particular event pattern can be used as the basis of some action.
-``` php
+```php
// Attach listeners to EventManager.
$this->getEventManager()->on('User.Registration', [$this, 'userRegistration']);
$this->getEventManager()->on('User.Verification', [$this, 'userVerification']);
@@ -436,7 +436,7 @@ with a the order they were attached. You set priorities using the `on()`
method for callbacks, and declaring it in the `implementedEvents()` function
for event listeners:
-``` php
+```php
// Setting priority for a callback
$callback = [$this, 'doSomething'];
$this->getEventManager()->on(
@@ -471,7 +471,7 @@ When events have data provided in their constructor, the provided data is
converted into arguments for the listeners. An example from the View layer is
the afterRender callback:
-``` php
+```php
$this->getEventManager()
->dispatch(new Event('View.afterRender', $this, ['view' => $viewFileName]));
```
@@ -479,7 +479,7 @@ $this->getEventManager()
The listeners of the `View.afterRender` callback should have the following
signature:
-``` php
+```php
function (EventInterface $event, string $fileName)
```
@@ -499,7 +499,7 @@ using `Cake\Event\EventManager::dispatch()`. This method takes an
instance of the `Cake\Event\Event` class. Let's look at dispatching
an event:
-``` php
+```php
// An event listener has to be instantiated before dispatching an event.
// Create a new event and dispatch it.
$event = new Event('Order.afterPlace', $this, [
@@ -540,7 +540,7 @@ the code detects it cannot proceed any further.
In order to stop events you can either return `false` in your callbacks or
call the `stopPropagation()` method on the event object:
-``` php
+```php
public function doSomething(EventInterface $event): bool
{
// ...
@@ -563,7 +563,7 @@ operation from occurring.
To check if an event was stopped, you call the `isStopped()` method in the
event object:
-``` php
+```php
public function place(Order $order): bool
{
$event = new Event('Order.beforePlace', $this, ['order' => $order]);
@@ -591,7 +591,7 @@ example and let callbacks modify the `$order` data.
Event results can be altered either using the event object result property
directly or returning the value in the callback itself:
-``` php
+```php
// A listener callback
public function doSomething(EventInterface $event): mixed
{
@@ -634,7 +634,7 @@ If for any reason you want to remove any callback from the event manager just
call the `Cake\Event\EventManager::off()` method using as
arguments the first two parameters you used for attaching it:
-``` php
+```php
// Attaching a function
$this->getEventManager()->on('My.event', [$this, 'doSomething']);
diff --git a/docs/en/core-libraries/form.md b/docs/en/core-libraries/form.md
index 83997544cf..52b22c09d6 100644
--- a/docs/en/core-libraries/form.md
+++ b/docs/en/core-libraries/form.md
@@ -19,7 +19,7 @@ form. This makes testing easier, and lets you re-use your form. Forms are put
into **src/Form** and usually have `Form` as a class suffix. For example,
a simple contact form would look like:
-``` php
+```php
// in src/Form/ContactForm.php
namespace App\Form;
@@ -74,7 +74,7 @@ The `_execute` method was deprecated, and replaced by `process`.
Once you've defined your form, you can use it in your controller to process
and validate request data:
-``` php
+```php
// In a controller
namespace App\Controller;
@@ -103,7 +103,7 @@ In the above example, we use the `execute()` method to run our form's
accordingly. If we want to use a non-default validation set we can use the
`validate` option:
-``` php
+```php
if ($contact->execute($this->request->getData(), 'update')) {
// Handle form success.
}
@@ -114,7 +114,7 @@ This option can also be set to `false` to disable validation.
We could have also used the `validate()` method to only validate
the request data:
-``` php
+```php
$isValid = $form->validate($this->request->getData());
// You can also use other validation sets. The following
@@ -127,7 +127,7 @@ $isValid = $form->validate($this->request->getData(), 'update');
You can set default values for modelless forms using the `setData()` method.
Values set with this method will overwrite existing data in the form object:
-``` php
+```php
// In a controller
namespace App\Controller;
@@ -164,7 +164,7 @@ you will overwrite your previous POST Data which might have validation errors
that need corrections. You can use `set()` to add or replace individual fields
or a subset of fields:
-``` php
+```php
// Set one field.
$contact->set('name', 'John Doe');
@@ -179,7 +179,7 @@ $contact->set([
Once a form has been validated you can retrieve the errors from it:
-``` php
+```php
$errors = $form->getErrors();
/* $errors contains
[
@@ -203,7 +203,7 @@ use of the Validator class. The most common use case for this is when the
validation is done on a remote server. In such case, you must manually
invalidate the fields accordingly to the feedback from the remote server:
-``` php
+```php
// in src/Form/ContactForm.php
public function setErrors(array $errors): void
{
@@ -214,14 +214,14 @@ public function setErrors(array $errors): void
According to how the validator class would have returned the errors, `$errors`
must be in this format:
-``` php
+```php
['fieldName' => ['validatorName' => 'The error message to display']]
```
Now you will be able to invalidate form fields by setting the fieldName, then
set the error messages:
-``` php
+```php
// In a controller
$contact = new ContactForm();
$contact->setErrors(['email' => ['_required' => 'Your email is required']]);
@@ -234,7 +234,7 @@ Proceed to Creating HTML with FormHelper to see the results.
Once you've created a Form class, you'll likely want to create an HTML form for
it. FormHelper understands Form objects just like ORM entities:
-``` php
+```php
echo $this->Form->create($contact);
echo $this->Form->control('name');
echo $this->Form->control('email');
diff --git a/docs/en/core-libraries/global-constants-and-functions.md b/docs/en/core-libraries/global-constants-and-functions.md
index 557ebac43c..61b6f930e9 100644
--- a/docs/en/core-libraries/global-constants-and-functions.md
+++ b/docs/en/core-libraries/global-constants-and-functions.md
@@ -22,7 +22,7 @@ convenience wrappers for other CakePHP functionality, such as debugging and
translating content. By default, only namespaced functions are autoloaded,
however you can optionally load global aliases by adding:
-``` php
+```php
require CAKE . 'functions.php';
```
@@ -37,13 +37,13 @@ This function handles localization in CakePHP applications. The
`$string_id` identifies the ID for a translation. You can supply
additional arguments to replace placeholders in your string:
-``` php
+```php
__('You have {0} unread messages', $number);
```
You can also provide a name-indexed array of replacements:
-``` php
+```php
__('You have {unread} unread messages', ['unread' => $number]);
```
diff --git a/docs/en/core-libraries/hash.md b/docs/en/core-libraries/hash.md
index 28f5cc653e..2be82fdf94 100644
--- a/docs/en/core-libraries/hash.md
+++ b/docs/en/core-libraries/hash.md
@@ -69,7 +69,7 @@ or object implementing `ArrayAccess` interface, along arbitrary paths
quickly without having to loop through the data structures. Instead you
use path expressions to qualify which elements you want returned:
-``` php
+```php
// Common Usage:
$users = [
['id' => 1, 'name' => 'mark'],
@@ -88,7 +88,7 @@ $results = Hash::extract($users, '{n}.id');
Inserts `$values` into an array as defined by `$path`:
-``` php
+```php
$a = [
'pages' => ['name' => 'page'],
];
@@ -107,13 +107,13 @@ $result = Hash::insert($a, 'files', ['name' => 'files']);
You can use paths using `{n}`, `{s}` and `{*}` to insert data into multiple
points:
-``` php
+```php
$users = Hash::insert($users, '{n}.new', 'value');
```
Attribute matchers work with `insert()` as well:
-``` php
+```php
$data = [
0 => ['up' => true, 'Item' => ['id' => 1, 'title' => 'first']],
1 => ['Item' => ['id' => 2, 'title' => 'second']],
@@ -139,7 +139,7 @@ $result = Hash::insert($data, '{n}[up].Item[id=4].new', 9);
Removes all elements from an array that match `$path`:
-``` php
+```php
$a = [
'pages' => ['name' => 'page'],
'files' => ['name' => 'files'],
@@ -158,7 +158,7 @@ $result = Hash::remove($a, 'files');
Using `{n}`, `{s}` and `{*}` will allow you to remove multiple values at once.
You can also use attribute matchers with `remove()`:
-``` php
+```php
$data = [
0 => ['clear' => true, 'Item' => ['id' => 1, 'title' => 'first']],
1 => ['Item' => ['id' => 2, 'title' => 'second']],
@@ -188,7 +188,7 @@ specified, or doesn't match anything, values will be initialized to null.
You can optionally group the values by what is obtained when following the
path specified in `$groupPath`:
-``` php
+```php
$a = [
[
'User' => [
@@ -294,7 +294,7 @@ You can provide arrays for both `$keyPath` and `$valuePath`. If you do this,
the first value will be used as a format string, for values extracted by the
other paths:
-``` php
+```php
$result = Hash::combine(
$a,
'{n}.User.id',
@@ -332,7 +332,7 @@ $result = Hash::combine(
Returns a series of values extracted from an array, formatted with a
format string:
-``` php
+```php
$data = [
[
'Person' => [
@@ -389,7 +389,7 @@ $res = Hash::format($data, ['{n}.Person.first_name', '{n}.Person.something'], '%
Determines if one Hash or array contains the exact keys and values
of another:
-``` php
+```php
$a = [
0 => ['name' => 'main'],
1 => ['name' => 'about'],
@@ -415,7 +415,7 @@ $result = Hash::contains($b, $a);
Checks if a particular path is set in an array:
-``` php
+```php
$set = [
'My Index 1' => ['First' => 'The first item'],
];
@@ -457,7 +457,7 @@ Filters empty elements out of array, excluding '0'. You can also supply a
custom `$callback` to filter the array elements. The callback should
return `false` to remove elements from the resulting array:
-``` php
+```php
$data = [
'0',
false,
@@ -487,7 +487,7 @@ $res = Hash::filter($data);
Collapses a multi-dimensional array into a single dimension:
-``` php
+```php
$arr = [
[
'Post' => ['id' => '1', 'title' => 'First Post'],
@@ -520,7 +520,7 @@ $res = Hash::flatten($arr);
Expands an array that was previously flattened with
`Hash::flatten()`:
-``` php
+```php
$data = [
'0.Post.id' => 1,
'0.Post.title' => First Post,
@@ -560,7 +560,7 @@ containing strings (unlike `array_merge_recursive`).
> This function will work with an unlimited amount of arguments and
> typecasts non-array parameters into arrays.
-``` php
+```php
$array = [
[
'id' => '48c2570e-dfa8-4c32-a35e-0d71cbdd56cb',
@@ -605,7 +605,7 @@ $res = Hash::merge($array, $arrayB, $arrayC, $arrayD);
Checks to see if all the values in the array are numeric:
-``` php
+```php
$data = ['one'];
$res = Hash::numeric(array_keys($data));
// $res is true
@@ -622,7 +622,7 @@ $res = Hash::numeric($data);
Counts the dimensions of an array. This method will only
consider the dimension of the first element in the array:
-``` php
+```php
$data = ['one', '2', 'three'];
$result = Hash::dimensions($data);
// $result == 1
@@ -651,7 +651,7 @@ $result = Hash::dimensions($data);
Similar to `~Hash::dimensions()`, however this method returns,
the deepest number of dimensions of any element in the array:
-``` php
+```php
$data = ['1' => '1.1', '2', '3' => ['3.1' => '3.1.1']];
$result = Hash::maxDimensions($data);
// $result == 2
@@ -669,7 +669,7 @@ Creates a new array, by extracting `$path`, and mapping `$function`
across the results. You can use both expression and matching elements with
this method:
-``` php
+```php
// Call the noop function $this->noop() on every element of $data
$result = Hash::map($data, "{n}", [$this, 'noop']);
@@ -695,7 +695,7 @@ with this method.
Apply a callback to a set of extracted values using `$function`. The function
will get the extracted values as the first argument:
-``` php
+```php
$data = [
['date' => '01-01-2016', 'booked' => true],
['date' => '01-01-2016', 'booked' => false],
@@ -717,7 +717,7 @@ $result = Hash::apply($data, '{n}[booked=true].date', 'array_count_values');
Sorts an array by any value, determined by a [Hash Path Syntax](#hash-path-syntax)
Only expression elements are supported by this method:
-``` php
+```php
$a = [
0 => ['Person' => ['name' => 'Jeff']],
1 => ['Shirt' => ['color' => 'black']],
@@ -754,7 +754,7 @@ can be one of the following values:
Computes the difference between two arrays:
-``` php
+```php
$a = [
0 => ['name' => 'main'],
1 => ['name' => 'about'],
@@ -784,7 +784,7 @@ data to the bottom of the resultant array.
**Example 1:**
-``` php
+```php
$array1 = ['ModelOne' => ['id' => 1001, 'field_one' => 'a1.m1.f1', 'field_two' => 'a1.m1.f2']];
$array2 = ['ModelOne' => ['id' => 1003, 'field_one' => 'a3.m1.f1', 'field_two' => 'a3.m1.f2', 'field_three' => 'a3.m1.f3']];
$res = Hash::mergeDiff($array1, $array2);
@@ -803,7 +803,7 @@ $res = Hash::mergeDiff($array1, $array2);
**Example 2:**
-``` php
+```php
$array1 = ["a" => "b", 1 => 20938, "c" => "string"];
$array2 = ["b" => "b", 3 => 238, "c" => "string", ["extra_field"]];
$res = Hash::mergeDiff($array1, $array2);
@@ -830,7 +830,7 @@ normalized to be an associative array. Numeric keys with values, will be
converted to string keys with `$default` values. Normalizing an array,
makes using the results with `Hash::merge()` easier:
-``` php
+```php
$a = ['Tree', 'CounterCache',
'Upload' => [
'folder' => 'products',
@@ -896,7 +896,7 @@ Takes a flat array set, and creates a nested, or threaded data structure.
For example, if you had the following array of data:
-``` php
+```php
$data = [
['ThreadPost' => ['id' => 1, 'parent_id' => null]],
['ThreadPost' => ['id' => 2, 'parent_id' => 1]],
diff --git a/docs/en/core-libraries/httpclient.md b/docs/en/core-libraries/httpclient.md
index 9176c43e84..3c4c13083f 100644
--- a/docs/en/core-libraries/httpclient.md
+++ b/docs/en/core-libraries/httpclient.md
@@ -15,7 +15,7 @@ remote APIs.
Doing requests is simple and straight forward. Doing a GET request looks like:
-``` php
+```php
use Cake\Http\Client;
$http = new Client();
@@ -34,7 +34,7 @@ $response = $http->get('https://example.com/search', ['q' => 'widget'], [
Doing POST and PUT requests is equally simple:
-``` php
+```php
// Send a POST request with application/x-www-form-urlencoded encoded data
$http = new Client();
$response = $http->post('https://example.com/posts/add', [
@@ -57,7 +57,7 @@ $http->patch(/* ... */);
If you have created a PSR-7 request object you can send it using
`sendRequest()`:
-``` php
+```php
use Cake\Http\Client;
use Cake\Http\Client\Request as ClientRequest;
@@ -73,7 +73,7 @@ $response = $http->sendRequest($request);
You can include files in request bodies by including a filehandle in the array:
-``` php
+```php
$http = new Client();
$response = $http->post('https://example.com/api', [
'image' => fopen('/path/to/a/file', 'r'),
@@ -88,7 +88,7 @@ There may be times when you need to build a request body in a very specific way.
In these situations you can often use `Cake\Http\Client\FormData` to craft
the specific multipart HTTP request you want:
-``` php
+```php
use Cake\Http\Client\FormData;
$data = new FormData();
@@ -118,7 +118,7 @@ $response = $http->post(
When dealing with REST APIs you often need to send request bodies that are not
form encoded. Http\Client exposes this through the type option:
-``` php
+```php
// Send a JSON request body.
$http = new Client();
$response = $http->post(
@@ -133,7 +133,7 @@ When using the `type` option, you should provide the data as a string. If you're
doing a GET request that needs both querystring parameters and a request body
you can do the following:
-``` php
+```php
// Send a JSON body in a GET request with query string parameters.
$http = new Client();
$response = $http->get(
@@ -185,7 +185,7 @@ context.
An example of basic authentication:
-``` php
+```php
$http = new Client();
$response = $http->get('https://example.com/profile/1', [], [
'auth' => ['username' => 'mark', 'password' => 'secret'],
@@ -199,7 +199,7 @@ By default, `Cake\Http\Client` will use basic authentication if there is no
An example of basic authentication:
-``` php
+```php
$http = new Client();
$response = $http->get('https://example.com/profile/1', [], [
'auth' => [
@@ -233,7 +233,7 @@ Many modern web-services require OAuth authentication to access their APIs.
The included OAuth authentication assumes that you already have your consumer
key and consumer secret:
-``` php
+```php
$http = new Client();
$response = $http->get('https://example.com/profile/1', [], [
'auth' => [
@@ -252,7 +252,7 @@ $response = $http->get('https://example.com/profile/1', [], [
Because OAuth2 is often a single header, there is not a specialized
authentication adapter. Instead you can create a client with the access token:
-``` php
+```php
$http = new Client([
'headers' => ['Authorization' => 'Bearer ' . $accessToken],
]);
@@ -265,7 +265,7 @@ Some proxies require authentication to use them. Generally this authentication
is Basic, but it can be implemented by any authentication adapter. By default
Http\Client will assume Basic authentication, unless the type key is set:
-``` php
+```php
$http = new Client();
$response = $http->get('https://example.com/test.php', [], [
'proxy' => [
@@ -289,7 +289,7 @@ Having to re-type the domain name, authentication and proxy settings can become
tedious & error prone. To reduce the chance for mistake and relieve some of the
tedium, you can create scoped clients:
-``` php
+```php
// Create a scoped client.
$http = new Client([
'host' => 'api.example.com',
@@ -304,7 +304,7 @@ $response = $http->get('/test.php');
If your scoped client only needs information from the URL you can use
`createFromUrl()`:
-``` php
+```php
$http = Client::createFromUrl('https://api.example.com/v1/test');
```
@@ -328,7 +328,7 @@ The following information can be used when creating a scoped client:
Any of these options can be overridden by specifying them when doing requests.
host, scheme, proxy, port are overridden in the request URL:
-``` php
+```php
// Using the scoped client we created earlier.
$response = $http->get('http://foo.com/test.php');
```
@@ -347,7 +347,7 @@ instance of Http\Client. The cookies stored in a Client instance are
automatically included in future requests to domain + path combinations that
match:
-``` php
+```php
$http = new Client([
'host' => 'cakephp.org',
]);
@@ -363,7 +363,7 @@ $response2 = $http->get('/changelogs');
You can always override the auto-included cookies by setting them in the
request's `$options` parameters:
-``` php
+```php
// Replace a stored cookie with a custom value.
$response = $http->get('/changelogs', [], [
'cookies' => ['sessionid' => '123abc'],
@@ -373,7 +373,7 @@ $response = $http->get('/changelogs', [], [
You can add cookie objects to the client after creating it using the `addCookie()`
method:
-``` php
+```php
use Cake\Http\Cookie\Cookie;
$http = new Client([
@@ -403,14 +403,14 @@ Response objects have a number of methods for inspecting the response data.
You read the entire response body as a string:
-``` php
+```php
// Read the entire response as a string.
$response->getStringBody();
```
You can also access the stream object for the response and use its methods:
-``` php
+```php
// Get a Psr\Http\Message\StreamInterface containing the response body
$stream = $response->getBody();
@@ -428,7 +428,7 @@ Since JSON and XML responses are commonly used, response objects provide a way
to use accessors to read decoded data. JSON data is decoded into an array, while
XML data is decoded into a `SimpleXMLElement` tree:
-``` php
+```php
// Get some XML
$http = new Client();
$response = $http->get('https://example.com/test.xml');
@@ -448,7 +448,7 @@ multiple times has no additional cost.
You can access headers through a few different methods. Header names are always
treated as case-insensitive values when accessing them through methods:
-``` php
+```php
// Get all the headers as an associative array.
$response->getHeaders();
@@ -467,7 +467,7 @@ $response->getEncoding();
You can read cookies with a few different methods depending on how much
data you need about the cookies:
-``` php
+```php
// Get all cookies (full data)
$response->getCookies();
@@ -483,7 +483,7 @@ $response->getCookieData('session_id');
Response objects provide a few methods for checking status codes:
-``` php
+```php
// Was the response a 20x
$response->isOk();
@@ -500,7 +500,7 @@ By default, `Http\Client` will prefer using a `curl` based transport adapter.
If the curl extension is not available a stream based adapter will be used
instead. You can force select a transport adapter using a constructor option:
-``` php
+```php
use Cake\Http\Client\Adapter\Stream;
$http = new Client(['adapter' => Stream::class]);
@@ -514,7 +514,7 @@ caching, logging etc.
### HttpClient.beforeSend
-``` php
+```php
// Somewhere before calling one of the HTTP client's methods which makes a request
$http->getEventManager()->on(
'HttpClient.beforeSend',
@@ -538,7 +538,7 @@ $http->getEventManager()->on(
### HttpClient.afterSend
-``` php
+```php
// Somewhere before calling one of the HTTP client's methods which makes a request
$http->getEventManager()->on(
'HttpClient.afterSend',
@@ -568,7 +568,7 @@ In tests you will often want to create mock responses to external APIs. You can
use the `HttpClientTrait` to define responses to the requests your application
is making:
-``` php
+```php
use Cake\Http\TestSuite\HttpClientTrait;
use Cake\TestSuite\TestCase;
@@ -591,7 +591,7 @@ class CartControllerTests extends TestCase
There are methods to mock the most commonly used HTTP methods:
-``` php
+```php
$this->mockClientGet(/* ... */);
$this->mockClientPatch(/* ... */);
$this->mockClientPost(/* ... */);
@@ -607,7 +607,7 @@ As seen above you can use the `newClientResponse()` method to create responses
for the requests your application will make. The headers need to be a list of
strings:
-``` php
+```php
$headers = [
'Content-Type: application/json',
'Connection: close',
diff --git a/docs/en/core-libraries/inflector.md b/docs/en/core-libraries/inflector.md
index 2b1b16c187..91d76bd23a 100644
--- a/docs/en/core-libraries/inflector.md
+++ b/docs/en/core-libraries/inflector.md
@@ -133,7 +133,7 @@ Both `pluralize` and `singularize()` work on most English nouns. If you need
to support other languages, you can use [Inflection Configuration](#inflection-configuration) to
customize the rules used:
-``` php
+```php
// Apples
echo Inflector::pluralize('Apple');
```
@@ -141,7 +141,7 @@ echo Inflector::pluralize('Apple');
> [!NOTE]
> `pluralize()` should not be used on a noun that is already in its plural form.
-``` php
+```php
// Person
echo Inflector::singularize('People');
```
@@ -161,7 +161,7 @@ echo Inflector::singularize('People');
These methods are useful when creating class names, or property names:
-``` php
+```php
// ApplePie
Inflector::camelize('Apple_pie')
@@ -182,7 +182,7 @@ underscore.
This method is useful when converting underscored forms into "Title Case" forms
for human readable values:
-``` php
+```php
// Apple Pie
Inflector::humanize('apple_pie');
```
@@ -204,7 +204,7 @@ Inflector::humanize('apple_pie');
When generating code, or using CakePHP's conventions you may need to inflect
table names or class names:
-``` php
+```php
// UserProfileSetting
Inflector::classify('user_profile_settings');
@@ -224,7 +224,7 @@ Inflector::tableize('UserProfileSetting');
Variable names are often useful when doing meta-programming tasks that involve
generating code or doing work based on conventions:
-``` php
+```php
// applePie
Inflector::variable('apple_pie');
```
@@ -252,7 +252,7 @@ special cases.
Define new inflection and transliteration rules for Inflector to use. Often,
this method is used in your **config/bootstrap.php**:
-``` php
+```php
Inflector::rules('singular', ['/^(bil)er$/i' => '\1', '/^(inflec|contribu)tors$/i' => '\1ta']);
Inflector::rules('uninflected', ['singulars']);
Inflector::rules('irregular', ['phylum' => 'phyla']); // The key is singular form, value is plural form
diff --git a/docs/en/core-libraries/internationalization-and-localization.md b/docs/en/core-libraries/internationalization-and-localization.md
index 5abb9214e7..f4b2c66c86 100644
--- a/docs/en/core-libraries/internationalization-and-localization.md
+++ b/docs/en/core-libraries/internationalization-and-localization.md
@@ -23,14 +23,14 @@ multilingual application, the first of which is to make use of the
`__()` function in your code. Below is an example of some code for a
single-language application:
-``` html
+```html
Popular Articles
```
To internationalize your code, all you need to do is to wrap strings in
`__()` like so:
-``` html
+```html
= __('Popular Articles') ?>
```
@@ -95,7 +95,7 @@ As of 4.5.0 plugins can contain multiple translation domains. Use `MyPlugin.addi
An example translation file could look like this:
-``` pot
+```pot
msgid "My name is {0}"
msgstr "Je m'appelle {0}"
@@ -122,7 +122,7 @@ learn more.
The default locale can be set in your **config/app.php** file by setting
`App.defaultLocale`:
-``` php
+```php
'App' => [
...
'defaultLocale' => env('APP_DEFAULT_LOCALE', 'en_US'),
@@ -138,7 +138,7 @@ of those is displayed using the localization libraries that CakePHP provides.
To change the language for translated strings you can call this method:
-``` php
+```php
use Cake\I18n\I18n;
I18n::setLocale('de_DE');
@@ -154,7 +154,7 @@ application. The most frequently used one is `__()`. This function
is used to retrieve a single translation message or return the same string if no
translation was found:
-``` php
+```php
echo __('Popular Articles');
```
@@ -162,7 +162,7 @@ If you need to group your messages, for example, translations inside a plugin,
you can use the `__d()` function to fetch messages from another
domain:
-``` php
+```php
echo __d('my_plugin', 'Trending right now');
```
@@ -177,7 +177,7 @@ This can happen if two strings are identical but refer to different things. For
example, 'letter' has multiple meanings in English. To solve that problem, you
can use the `__x()` function:
-``` php
+```php
echo __x('written communication', 'He read the first letter');
echo __x('alphabet learning', 'He read the first letter');
@@ -186,7 +186,7 @@ echo __x('alphabet learning', 'He read the first letter');
The first argument is the context of the message and the second is the message
to be translated.
-``` pot
+```pot
msgctxt "written communication"
msgid "He read the first letter"
msgstr "Er las den ersten Brief"
@@ -197,20 +197,20 @@ msgstr "Er las den ersten Brief"
Translation functions allow you to interpolate variables into the messages using
special markers defined in the message itself or in the translated string:
-``` php
+```php
echo __("Hello, my name is {0}, I'm {1} years old", ['Sara', 12]);
```
Markers are numeric, and correspond to the keys in the passed array. You can
also pass variables as independent arguments to the function:
-``` php
+```php
echo __("Small step for {0}, Big leap for {1}", 'Man', 'Humanity');
```
All translation functions support placeholder replacements:
-``` php
+```php
__d('validation', 'The field {0} cannot be left empty', 'Name');
__x('alphabet', 'He read the letter {0}', 'Z');
@@ -220,13 +220,13 @@ The `'` (single quote) character acts as an escape code in translation
messages. Any variables between single quotes will not be replaced and is
treated as literal text. For example:
-``` php
+```php
__("This variable '{0}' be replaced.", 'will not');
```
By using two adjacent quotes your variables will be replaced properly:
-``` php
+```php
__("This variable ''{0}'' be replaced.", 'will');
```
@@ -235,7 +235,7 @@ These functions take advantage of the
so you can translate messages and localize dates, numbers and currency at the
same time:
-``` php
+```php
echo __(
'Hi {0}, your balance on the {1,date} is {2,number,currency}',
['Charles', new DateTime('2014-01-13 11:12:00'), 1354.37],
@@ -248,7 +248,7 @@ Hi Charles, your balance on the Jan 13, 2014, 11:12 AM is $ 1,354.37
Numbers in placeholders can be formatted as well with fine grain control of the
output:
-``` php
+```php
echo __(
'You have traveled {0,number} kilometers in {1,number,integer} weeks',
[5423.344, 5.1],
@@ -284,7 +284,7 @@ You can also use named placeholders like `{name}` in the message strings.
When using named placeholders, pass the placeholder and replacement in an array using key/value pairs,
for example:
-``` php
+```php
// echos: Hi. My name is Sara. I'm 12 years old.
echo __("Hi. My name is {name}. I'm {age} years old.", ['name' => 'Sara', 'age' => 12]);
```
@@ -301,7 +301,7 @@ The first one is taking advantage of the `ICU` message format that comes by
default in the translation functions. In the translations file you could have
the following strings
-``` pot
+```pot
msgid "{0,plural,=0{No records found} =1{Found 1 record} other{Found # records}}"
msgstr "{0,plural,=0{Ningún resultado} =1{1 resultado} other{# resultados}}"
@@ -312,7 +312,7 @@ msgstr "{placeholder,plural,=0{Ningún resultado} =1{1 resultado} other{{1} resu
And in the application use the following code to output either of the
translations for such string:
-``` php
+```php
__('{0,plural,=0{No records found }=1{Found 1 record} other{Found # records}}', [0]);
// Returns "Ningún resultado" as the argument {0} is 0
@@ -330,7 +330,7 @@ __('{placeholder,plural,=0{No records found} =1{Found 1 record} other{Found {1}
A closer look to the format we just used will make it evident how messages are
built:
-``` text
+```text
{ [count placeholder],plural, case1{message} case2{message} case3{...} ... }
```
@@ -344,14 +344,14 @@ use `#`.
You can of course use simpler message ids if you don't want to type the full
plural selection sequence in your code
-``` pot
+```pot
msgid "search.results"
msgstr "{0,plural,=0{Ningún resultado} =1{1 resultado} other{{1} resultados}}"
```
Then use the new string in your code:
-``` php
+```php
__('search.results', [2, 2]);
// Returns: "2 resultados"
@@ -367,13 +367,13 @@ languages like Arabic require a different plural when you refer
to few things and other plural form for many things. In those cases you can
use the ICU matching aliases. Instead of writing:
-``` text
+```text
=0{No results} =1{...} other{...}
```
You can do:
-``` text
+```text
zero{No Results} one{One result} few{...} many{...} other{...}
```
@@ -387,7 +387,7 @@ The second plural selection format accepted is using the built-in capabilities
of Gettext. In this case, plurals will be stored in the `.po`
file by creating a separate message translation line per plural form:
-``` pot
+```pot
# One message identifier for singular
msgid "One file removed"
# Another one for plural
@@ -401,7 +401,7 @@ msgstr[1] "{0} ficheros eliminados"
When using this other format, you are required to use another translation
function:
-``` php
+```php
// Returns: "10 ficheros eliminados"
$count = 10;
__n('One file removed', '{0} files removed', $count, $count);
@@ -414,7 +414,7 @@ The number inside `msgstr[]` is the number assigned by Gettext for the plural
form of the language. Some languages have more than two plural forms, for
example Croatian:
-``` pot
+```pot
msgid "One file removed"
msgid_plural "{0} files removed"
msgstr[0] "{0} datoteka je uklonjena"
@@ -432,7 +432,7 @@ translation messages are stored, you can create your own translation message
loader. The easiest way to create your own translator is by defining a loader
for a single domain and locale:
-``` php
+```php
use Cake\I18n\Package;
// Prior to 4.2 you need to use Aura\Intl\Package
@@ -458,7 +458,7 @@ minimum that is required for creating a translator is that the loader function
should return a `Cake\I18n\Package` object (prior to 4.2 it should be an `Aura\Intl\Package` object).
Once the code is in place you can use the translation functions as usual:
-``` php
+```php
I18n::setLocale('fr_FR');
__d('animals', 'Dog'); // Returns "Chien"
```
@@ -469,7 +469,7 @@ another file, calling another function, etc. CakePHP provides a few loader
functions you can reuse if you just need to change where messages are loaded.
For example, you can still use **.po** files, but loaded from another location:
-``` php
+```php
use Cake\I18n\MessagesFileLoader as Loader;
// Load messages from resources/locales/folder/sub_folder/filename.po
@@ -487,7 +487,7 @@ a message parser other than `PoFileParser`. For example, if you wanted to load
translation messages using `YAML`, you will first need to create the parser
class:
-``` php
+```php
namespace App\I18n\Parser;
class YamlFileParser
@@ -503,7 +503,7 @@ The file should be created in the **src/I18n/Parser** directory of your
application. Next, create the translations file under
**resources/locales/fr_FR/animals.yaml**
-``` yaml
+```yaml
Dog: Chien
Cat: Chat
Bird: Oiseau
@@ -511,7 +511,7 @@ Bird: Oiseau
And finally, configure the translation loader for the domain and locale:
-``` php
+```php
use Cake\I18n\MessagesFileLoader as Loader;
I18n::setTranslator(
@@ -531,7 +531,7 @@ generic translator loaders for each domain.
Imagine that you wanted to load all translations for the default domain and for
any language from an external service:
-``` php
+```php
use Cake\I18n\Package;
// Prior to 4.2 you need to use Aura\Intl\Package
@@ -556,7 +556,7 @@ If you'd like to change how packages are loaded for all packages, that don't
have specific loaders set you can replace the fallback package loader by using
the `_fallback` package:
-``` php
+```php
I18n::config('_fallback', function ($domain, $locale) {
// Custom code that yields a package here.
});
@@ -569,7 +569,7 @@ to store messages under different domains or to trigger Gettext-style plural
selection. The following is an example of storing translations for the same key
in different contexts:
-``` php
+```php
[
'He reads the letter {0}' => [
'alphabet' => 'Él lee la letra {0}',
@@ -581,7 +581,7 @@ in different contexts:
Similarly, you can express Gettext-style plurals using the messages array by
having a nested array key per plural form:
-``` php
+```php
[
'I have read one book' => 'He leído un libro',
'I have read {0} books' => [
@@ -601,14 +601,14 @@ variables in translation messages and selecting the correct plural form.
If you're dealing with a legacy application, or you don't need the power offered
by the ICU message formatting, CakePHP also provides the `sprintf` formatter:
-``` php
+```php
return Package('sprintf', 'fallback_domain', $messages);
```
The messages to be translated will be passed to the `sprintf()` function for
interpolating the variables:
-``` php
+```php
__('Hello, my name is %s and I am %d years old', 'José', 29);
```
@@ -616,7 +616,7 @@ It is possible to set the default formatter for all translators created by
CakePHP before they are used for the first time. This does not include manually
created translators using the `setTranslator()` and `config()` methods:
-``` php
+```php
I18n::setDefaultFormatter('sprintf');
```
@@ -629,7 +629,7 @@ that you wish your page to be displayed.
In order to change how dates and numbers are displayed you just need to change
the current locale setting and use the right classes:
-``` php
+```php
use Cake\I18n\I18n;
use Cake\I18n\DateTime;
use Cake\I18n\Number;
@@ -659,7 +659,7 @@ information in a user's localized format. In a controller, or
[Middleware](../controllers/middleware) you can configure the Date, Time, and
DateTime types to parse localized formats:
-``` php
+```php
use Cake\Database\TypeFactory;
// Enable default locale format parsing.
@@ -684,7 +684,7 @@ the datetimes in request data into your application's timezone. You can use
`setUserTimezone()` from a controller or [Middleware](../controllers/middleware) to
make this process simpler:
-``` php
+```php
// Set the user's timezone
TypeFactory::build('datetime')->setUserTimezone($user->timezone);
```
@@ -697,7 +697,7 @@ working in the timezone defined in `App.defaultTimezone`.
If your application handles datetime information in a number of actions you can
use a middleware to define both timezone conversion and locale parsing:
-``` php
+```php
namespace App\Middleware;
use Cake\Database\TypeFactory;
@@ -731,7 +731,7 @@ class DatetimeMiddleware implements MiddlewareInterface
By using the `LocaleSelectorMiddleware` in your application, CakePHP will
automatically set the locale based on the current user:
-``` php
+```php
// in src/Application.php
use Cake\I18n\Middleware\LocaleSelectorMiddleware;
diff --git a/docs/en/core-libraries/logging.md b/docs/en/core-libraries/logging.md
index 2bcda64d8a..5d2dce83c3 100644
--- a/docs/en/core-libraries/logging.md
+++ b/docs/en/core-libraries/logging.md
@@ -30,7 +30,7 @@ The **config/app.php** file is intended for just this. You can define
as many or as few loggers as your application needs. Loggers should be
configured using `Cake\Log\Log`. An example would be:
-``` php
+```php
use Cake\Log\Engine\FileLog;
use Cake\Log\Log;
@@ -73,7 +73,7 @@ It is also possible to create loggers by providing a closure. This is useful
when you need full control over how the logger object is built. The closure
has to return the constructed logger instance. For example:
-``` php
+```php
Log::setConfig('special', function () {
return new \Cake\Log\Engine\FileLog(['path' => LOGS, 'file' => 'log']);
});
@@ -82,7 +82,7 @@ Log::setConfig('special', function () {
Configuration options can also be provided as a `DSN` string. This is
useful when working with environment variables or `PaaS` providers:
-``` php
+```php
Log::setConfig('error', [
'url' => 'file:///full/path/to/logs/?levels[]=warning&levels[]=error&file=error',
]);
@@ -104,7 +104,7 @@ information.
Writing to the log files can be done in two different ways. The first
is to use the static `Cake\Log\Log::write()` method:
-``` php
+```php
Log::write('debug', 'Something did not work');
```
@@ -112,7 +112,7 @@ The second is to use the `log()` shortcut function available on any
class using the `LogTrait`. Calling `log()` will internally call
`Log::write()`:
-``` php
+```php
// Executing this inside a class using LogTrait
$this->log('Something did not work!', 'debug');
```
@@ -128,7 +128,7 @@ If you need to log dynamically defined data, you can use placeholders in your
log messages and provide an array of key/value pairs in the `$context`
parameter:
-``` php
+```php
// Will log `Could not process for userid=1`
Log::write('error', 'Could not process for userid={user}', ['user' => $user->id]);
```
@@ -136,7 +136,7 @@ Log::write('error', 'Could not process for userid={user}', ['user' => $user->id]
Placeholders that do not have keys defined will not be replaced. If you need to
use a literal braced word, you must escape the placeholder:
-``` php
+```php
// Will log `No {replace}`
Log::write('error', 'No \\{replace}', ['replace' => 'no']);
```
@@ -185,7 +185,7 @@ CakePHP exposes this concept as logging scopes. When log messages are written
you can include a scope name. If there is a configured logger for that scope,
the log messages will be directed to those loggers. For example:
-``` php
+```php
use Cake\Log\Engine\FileLog;
// Configure logs/shops.log to receive all levels, but only
@@ -215,7 +215,7 @@ Log::warning('this gets written to both shops.log and payments.log', ['scope' =>
Scopes can also be passed as a single string or a numerically indexed array.
Note that using this form will limit the ability to pass more data as context:
-``` php
+```php
Log::warning('This is a warning', ['orders']);
Log::warning('This is a warning', 'payments');
```
@@ -234,7 +234,7 @@ message being written determines the name of the file the message is stored in.
If a level is not supplied, `LOG_ERR` is used which writes to the
error log. The default log location is **logs/`$level.log`**:
-``` php
+```php
// Executing this inside a CakePHP class
$this->log("Something didn't work!");
@@ -249,7 +249,7 @@ You can configure additional/alternate FileLog locations when configuring
a logger. FileLog accepts a `path` which allows for
custom paths to be used:
-``` php
+```php
Log::setConfig('custom_path', [
'className' => 'File',
'path' => '/path/to/custom/place/',
@@ -286,7 +286,7 @@ to specify `Syslog` as the engine to be used for logging. The following
configuration snippet will replace the default logger with syslog, this should
be done in the **config/bootstrap.php** file:
-``` php
+```php
Log::setConfig('default', [
'engine' => 'Syslog',
]);
@@ -319,7 +319,7 @@ plugins. If for example you had a database logger called
engine you should use `Cake\Log\Log::setConfig()`. For example
configuring our DatabaseLog would look like:
-``` php
+```php
// For src/Log
Log::setConfig('otherFile', [
'className' => 'Database',
@@ -339,7 +339,7 @@ When configuring a log engine the `className` parameter is used to
locate and load the log handler. All of the other configuration
properties are passed to the log engine's constructor as an array.
-``` php
+```php
namespace App\Log\Engine;
use Cake\Log\Engine\BaseLog;
@@ -370,7 +370,7 @@ a formatter configured to maintain backwards compatible output. However, you can
adjust the formatters to fit your requirements. Formatters are configured
alongside the logging engine:
-``` php
+```php
use Cake\Log\Engine\SyslogLog;
use App\Log\Formatter\CustomFormatter;
@@ -404,7 +404,7 @@ To test logging, add `Cake\TestSuite\LogTestTrait` to your test case. The
messages your application is making. Once you have captured logs you can perform
assertions on log messages your application is emitting. For example:
-``` php
+```php
namespace App\Test\TestCase\Controller;
use Cake\TestSuite\LogTestTrait;
@@ -549,7 +549,7 @@ logger.
After installing Monolog using composer, configure the logger using the
`Log::setConfig()` method:
-``` php
+```php
// config/bootstrap.php
use Monolog\Logger;
@@ -569,7 +569,7 @@ Log::drop('error');
Use similar methods if you want to configure a different logger for your console:
-``` php
+```php
// config/bootstrap_cli.php
use Monolog\Logger;
diff --git a/docs/en/core-libraries/number.md b/docs/en/core-libraries/number.md
index 6cb4601e24..3c1a774628 100644
--- a/docs/en/core-libraries/number.md
+++ b/docs/en/core-libraries/number.md
@@ -10,7 +10,7 @@ description: "Format numbers in CakePHP: display currency, percentages, file siz
If you need `NumberHelper` functionalities outside of a `View`,
use the `Number` class:
-``` php
+```php
namespace App\Controller;
use Cake\I18n\Number;
@@ -49,7 +49,7 @@ automatically echo the output into the view.
This method is used to display a number in common currency formats
(EUR, GBP, USD), based on the 3-letter ISO 4217 currency code. Usage in a view looks like:
-``` php
+```php
// Called as NumberHelper
echo $this->Number->currency($value, $currency);
@@ -88,7 +88,7 @@ If `$currency` value is `null`, the default currency will be retrieved from
`Cake\I18n\Number::defaultCurrency()`. To format currencies in an
accounting format you should set the currency format:
-``` php
+```php
Number::setDefaultCurrencyFormat(Number::FORMAT_CURRENCY_ACCOUNTING);
```
@@ -123,7 +123,7 @@ This method displays a number with the specified amount of
precision (decimal places). It will round in order to maintain the
level of precision defined.
-``` php
+```php
// Called as NumberHelper
echo $this->Number->precision(456.91873645, 2);
@@ -149,7 +149,7 @@ according to the supplied precision (where numbers are rounded to meet the
given precision). This method also expresses the number as a percentage
and appends the output with a percent sign.
-``` php
+```php
// Called as NumberHelper. Output: 45.69%
echo $this->Number->toPercentage(45.691873645);
@@ -174,7 +174,7 @@ displayed with a two-digit precision level, according to the size
of data supplied (i.e. higher sizes are expressed in larger
terms):
-``` php
+```php
// Called as NumberHelper
echo $this->Number->toReadableSize(0); // 0 Byte
echo $this->Number->toReadableSize(1024); // 1 KB
@@ -199,7 +199,7 @@ numbers for use in your views (and is used as the main method by
most of the other NumberHelper methods). Using this method might
looks like:
-``` php
+```php
// Called as NumberHelper
$this->Number->format($value, $options);
@@ -230,7 +230,7 @@ resides.
Example:
-``` php
+```php
// Called as NumberHelper
echo $this->Number->format('123456.7890', [
'places' => 2,
@@ -266,7 +266,7 @@ This method will output an ordinal number.
Examples:
-``` php
+```php
echo Number::ordinal(1);
// Output '1st'
@@ -290,7 +290,7 @@ echo Number::ordinal(410);
This method displays differences in value as a signed number:
-``` php
+```php
// Called as NumberHelper
$this->Number->formatDelta($value, $options);
@@ -315,7 +315,7 @@ The `$options` parameter takes the same keys as `Number::format()` itself:
Example:
-``` php
+```php
// Called as NumberHelper
echo $this->Number->formatDelta('123456.7890', [
'places' => 2,
@@ -346,7 +346,7 @@ to various methods.
Example:
-``` php
+```php
Number::config('en_IN', \NumberFormatter::CURRENCY, [
'pattern' => '#,##,##0',
]);
diff --git a/docs/en/core-libraries/plugin.md b/docs/en/core-libraries/plugin.md
index bdc2903ade..3f1dd0f5b5 100644
--- a/docs/en/core-libraries/plugin.md
+++ b/docs/en/core-libraries/plugin.md
@@ -18,7 +18,7 @@ The Plugin class is responsible for resource location and path management of plu
Plugins can be located with Plugin. Using `Plugin::path('DebugKit');`
for example, will give you the full path to the DebugKit plugin:
-``` php
+```php
$path = Plugin::path('DebugKit');
```
@@ -26,7 +26,7 @@ $path = Plugin::path('DebugKit');
You can check dynamically inside your code if a specific plugin has been loaded:
-``` php
+```php
$isLoaded = Plugin::isLoaded('DebugKit');
```
@@ -40,7 +40,7 @@ Use `Plugin::loaded()` if you want to get a list of all currently loaded plugins
Used to get the location of the plugin's class files:
-``` php
+```php
$path = App::classPath('DebugKit');
```
@@ -52,12 +52,12 @@ $path = App::classPath('DebugKit');
The method returns the path to the plugins' templates:
-``` php
+```php
$path = Plugin::templatePath('DebugKit');
```
The same goes for the config path:
-``` php
+```php
$path = Plugin::configPath('DebugKit');
```
diff --git a/docs/en/core-libraries/registry-objects.md b/docs/en/core-libraries/registry-objects.md
index 6f7ff98ff6..0f4ef89dda 100644
--- a/docs/en/core-libraries/registry-objects.md
+++ b/docs/en/core-libraries/registry-objects.md
@@ -17,7 +17,7 @@ for Helpers, Behaviors, and Tasks in addition to Components.
Objects can be loaded on-the-fly using `add()`
Example:
-``` php
+```php
$this->loadComponent('Acl.Acl');
$this->addHelper('Flash')
```
@@ -25,7 +25,7 @@ $this->addHelper('Flash')
This will result in the `Acl` property and `Flash` helper being loaded.
Configuration can also be set on-the-fly. Example:
-``` php
+```php
$this->loadComponent('Cookie', ['name' => 'sweet']);
```
@@ -35,7 +35,7 @@ used to alias objects in a registry. This allows you to have component names
that do not reflect the classnames, which can be helpful when extending core
components:
-``` php
+```php
$this->Flash = $this->loadComponent('Flash', ['className' => 'MyCustomFlash']);
$this->Flash->error(); // Actually using MyCustomFlash::error();
```
@@ -53,7 +53,7 @@ objects from receiving callbacks. You should use the features in the events syst
accomplish this now. For example, you could disable component callbacks in the
following way:
-``` php
+```php
// Remove MyComponent from callbacks.
$this->getEventManager()->off($this->MyComponent);
diff --git a/docs/en/core-libraries/security.md b/docs/en/core-libraries/security.md
index a163895584..6c7eb774e8 100644
--- a/docs/en/core-libraries/security.md
+++ b/docs/en/core-libraries/security.md
@@ -29,7 +29,7 @@ The [openssl](https://php.net/openssl) extension is required for encrypting/decr
An example use would be:
-``` php
+```php
// Assuming key is stored somewhere it can be re-used for
// decryption later.
$key = 'wt1U5MACWJFTXGenFoZoiLwQGrLgdbHA';
@@ -46,7 +46,7 @@ Decrypt a previously encrypted value. The `$key` and `$hmacSalt`
parameters must match the values used to encrypt or decryption will fail. An
example use would be:
-``` php
+```php
// Assuming the key is stored somewhere it can be re-used for
// Decryption later.
$key = 'wt1U5MACWJFTXGenFoZoiLwQGrLgdbHA';
@@ -68,7 +68,7 @@ Create a hash from string using given method. Fallback on next
available method. If `$salt` is set to `true`, the application's salt
value will be used:
-``` php
+```php
// Using the application's salt value
$sha1 = Security::hash('CakePHP Framework', 'sha1', true);
diff --git a/docs/en/core-libraries/text.md b/docs/en/core-libraries/text.md
index 27f18e9649..9aa39ac0d9 100644
--- a/docs/en/core-libraries/text.md
+++ b/docs/en/core-libraries/text.md
@@ -14,7 +14,7 @@ strings and is normally accessed statically. Example:
If you need `Cake\View\Helper\TextHelper` functionalities outside
of a `View`, use the `Text` class:
-``` php
+```php
namespace App\Controller;
use Cake\Utility\Text;
@@ -57,7 +57,7 @@ multiple conversion pairs separated by `;`. You can find more info about
transliterator identifiers
[here](https://unicode-org.github.io/icu/userguide/transforms/general/#transliterator-identifiers):
-``` php
+```php
// apple puree
Text::transliterate('apple purée');
@@ -87,7 +87,7 @@ options are:
- `preserve` Specific non-word character to preserve. Defaults to `null`.
For example, this option can be set to '.' to generate clean file names:
- ``` php
+ ```php
// apple-puree
Text::slug('apple purée');
@@ -108,7 +108,7 @@ The UUID method is used to generate unique identifiers as per `4122`. The
UUID is a 128-bit string in the format of
`485fc381-e790-47a3-9794-1337c0a8fe68`.
-``` php
+```php
Text::uuid(); // 485fc381-e790-47a3-9794-1337c0a8fe68
```
@@ -119,7 +119,7 @@ You can now configure a custom UUID generator using dependency injection.
Starting from CakePHP 5.3.0, you can configure a custom UUID generator by
setting a closure in your configuration:
-``` php
+```php
// In your config/app.php or config/bootstrap.php
use Cake\Core\Configure;
@@ -145,7 +145,7 @@ that appears between `$leftBound` and `$rightBound`.
This method can be useful when splitting up data that has regular formatting
such as tag lists:
-``` php
+```php
$data = "cakephp 'great framework' php";
$result = Text::tokenize($data, ' ', "'", "'");
// Result contains
@@ -159,7 +159,7 @@ $result = Text::tokenize($data, ' ', "'", "'");
This method unformats a number from a human-readable byte size to an integer
number of bytes:
-``` php
+```php
$int = Text::parseFileSize('2GB');
```
@@ -172,7 +172,7 @@ $int = Text::parseFileSize('2GB');
The insert method is used to create string templates and to allow for key/value
replacements:
-``` php
+```php
Text::insert(
'My name is :name and I am :age years old.',
['name' => 'Bob', 'age' => '65'],
@@ -192,7 +192,7 @@ unneeded markup around placeholders that did not get replaced by
You can use the following options in the options array:
-``` php
+```php
$options = [
'clean' => [
'method' => 'text', // or html
@@ -211,7 +211,7 @@ $options = [
Wraps a block of text to a set width and indents blocks as well.
Can intelligently wrap text so words are not sliced across lines:
-``` php
+```php
$text = 'This is the song that never ends.';
$result = Text::wrap($text, 22);
@@ -237,7 +237,7 @@ exceed a certain length even with internal indentation, you need to use
`wrapBlock()` instead of `wrap()`. This is particularly useful to generate
text for the console for example. It accepts the same options as `wrap()`:
-``` php
+```php
$text = 'This is the song that never ends. This is the song that never ends.';
$result = Text::wrapBlock($text, [
'width' => 22,
@@ -272,7 +272,7 @@ Options:
Example:
-``` php
+```php
// Called as TextHelper
echo $this->Text->highlight(
$lastSentence,
@@ -310,7 +310,7 @@ HTML tags will be respected and will not be cut off.
`$options` is used to pass all extra parameters, and has the following
possible keys by default, all of which are optional:
-``` php
+```php
[
'ellipsis' => '...',
'exact' => true,
@@ -320,7 +320,7 @@ possible keys by default, all of which are optional:
Example:
-``` php
+```php
// Called as TextHelper
echo $this->Text->truncate(
'The killer crept forward and tripped on the rug.',
@@ -363,7 +363,7 @@ truncation would otherwise take place.
`$options` is used to pass all extra parameters, and has the following
possible keys by default, all of which are optional:
-``` php
+```php
[
'ellipsis' => '...',
'exact' => true,
@@ -372,7 +372,7 @@ possible keys by default, all of which are optional:
Example:
-``` php
+```php
$sampleText = 'I packed my bag and in it I put a PSP, a PS3, a TV, ' .
'a C# program that can divide by zero, death metal t-shirts'
@@ -414,7 +414,7 @@ of characters on each side determined by `$radius`, and prefix/suffix with
`$ellipsis`. This method is especially handy for search results. The query
string or keywords can be shown within the resulting document.
-``` php
+```php
// Called as TextHelper
echo $this->Text->excerpt($lastParagraph, 'method', 50, '...');
@@ -437,7 +437,7 @@ Output:
Creates a comma-separated list where the last two items are joined with 'and':
-``` php
+```php
$colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'];
// Called as TextHelper
diff --git a/docs/en/core-libraries/time.md b/docs/en/core-libraries/time.md
index 8598157bd8..ddfe0f13fb 100644
--- a/docs/en/core-libraries/time.md
+++ b/docs/en/core-libraries/time.md
@@ -10,7 +10,7 @@ description: "Manipulate dates and times in CakePHP: parse, format, compare, mod
If you need `TimeHelper` functionalities outside of a `View`,
use the `DateTime` class:
-``` php
+```php
use Cake\I18n\DateTime;
class UsersController extends AppController
@@ -48,7 +48,7 @@ to data, and avoids order based dependency issues.
There are a few ways to create `DateTime` instances:
-``` php
+```php
use Cake\I18n\DateTime;
// Create from a string datetime.
@@ -76,7 +76,7 @@ as a UNIX timestamp.
In test cases, you can mock out `now()` using `setTestNow()`:
-``` php
+```php
// Fixate time.
$time = new DateTime('2021-01-31 22:11:30');
DateTime::setTestNow($time);
@@ -95,7 +95,7 @@ echo $now->i18nFormat('yyyy-MM-dd HH:mm:ss');
Remember, `DateTime` instance always return a new instance from setters
instead of modifying itself:
-``` php
+```php
$time = DateTime::now();
// Create and reassign a new instance
@@ -108,14 +108,14 @@ echo $newTime->i18nFormat('yyyy-MM-dd HH:mm:ss');
You can also use the methods provided by PHP's built-in `DateTime` class:
-``` php
+```php
$time = $time->setDate(2013, 10, 31);
```
Failing to reassign the new `DateTime` instances will result in the
original, unmodified instance being used:
-``` php
+```php
$time->year(2013)
->month(10)
->day(31);
@@ -126,7 +126,7 @@ echo $time->i18nFormat('yyyy-MM-dd HH:mm:ss');
You can create another instance with modified dates, through subtraction and
addition of their components:
-``` php
+```php
$time = DateTime::create(2021, 1, 31, 22, 11, 30);
$newTime = $time->subDays(5)
->addHours(-2)
@@ -142,7 +142,7 @@ echo $newTime;
You can get the internal components of a date by accessing its properties:
-``` php
+```php
$time = DateTime::create(2021, 1, 31, 22, 11, 30);
echo $time->year; // 2021
echo $time->month; // 1
@@ -158,7 +158,7 @@ echo $time->timezoneName; // America/New_York
This method sets the default format used when converting an object to json:
-``` php
+```php
DateTime::setJsonEncodeFormat('yyyy-MM-dd HH:mm:ss'); // For any immutable DateTime
Date::setJsonEncodeFormat('yyyy-MM-dd HH:mm:ss'); // For any mutable Date
@@ -189,7 +189,7 @@ The `callable` parameter type was added.
A very common thing to do with `Time` instances is to print out formatted
dates. CakePHP makes this a snap:
-``` php
+```php
$time = DateTime::parse('2021-01-31 22:11:30');
// Prints a localized datetime stamp. Outputs '1/31/21, 10:11 PM'
@@ -216,7 +216,7 @@ specified in the following resource:
You can also format dates with non-gregorian calendars:
-``` php
+```php
// On ICU version 66.1
$time = DateTime::create(2021, 1, 31, 22, 11, 30);
@@ -256,7 +256,7 @@ The following calendar types are supported:
Print out a predefined 'nice' format:
-``` php
+```php
$time = DateTime::parse('2021-01-31 22:11:30', new \DateTimeZone('America/New_York'));
// Outputs 'Jan 31, 2021, 10:11 PM' in en-US
@@ -267,7 +267,7 @@ You can alter the timezone in which the date is displayed without altering the
`DateTime` object itself. This is useful when you store dates in one timezone, but
want to display them in a user's own timezone:
-``` php
+```php
// Outputs 'Monday, February 1, 2021 at 4:11:30 AM Central European Standard Time'
echo $time->i18nFormat(\IntlDateFormatter::FULL, 'Europe/Paris');
@@ -280,14 +280,14 @@ echo $time->timezoneName;
Leaving the first parameter as `null` will use the default formatting string:
-``` php
+```php
// Outputs '2/1/21, 4:11 AM'
echo $time->i18nFormat(null, 'Europe/Paris');
```
Finally, it is possible to use a different locale for displaying a date:
-``` php
+```php
// Outputs 'lundi 1 février 2021 à 04:11:30 heure normale d’Europe centrale'
echo $time->i18nFormat(\IntlDateFormatter::FULL, 'Europe/Paris', 'fr-FR');
@@ -302,7 +302,7 @@ The default locale in which dates are displayed when using `nice`
[intl.default_locale](https://www.php.net/manual/en/intl.configuration.php#ini.intl.default-locale).
You can, however, modify this default at runtime:
-``` php
+```php
DateTime::setDefaultLocale('es-ES');
Date::setDefaultLocale('es-ES');
@@ -316,7 +316,7 @@ a different locale is specified directly in the formatting method.
Likewise, it is possible to alter the default formatting string to be used for
`i18nFormat`:
-``` php
+```php
DateTime::setToStringFormat(\IntlDateFormatter::SHORT); // For any DateTime
Date::setToStringFormat(\IntlDateFormatter::SHORT); // For any Date
@@ -350,7 +350,7 @@ format string.
Often it is useful to print times relative to the present:
-``` php
+```php
$time = new DateTime('Jan 31, 2021');
// On June 12, 2021, this would output '4 months, 1 week, 6 days ago'
echo $time->timeAgoInWords(
@@ -362,7 +362,7 @@ The `end` option lets you define at which point after which relative times
should be formatted using the `format` option. The `accuracy` option lets
us control what level of detail should be used for each interval range:
-``` php
+```php
// Outputs '4 months ago'
echo $time->timeAgoInWords([
'accuracy' => ['month' => 'month'],
@@ -373,7 +373,7 @@ echo $time->timeAgoInWords([
By setting `accuracy` to a string, you can specify what is the maximum level
of detail you want output:
-``` php
+```php
$time = new DateTime('+23 hours');
// Outputs 'in about a day'
echo $time->timeAgoInWords([
@@ -394,7 +394,7 @@ echo $time->timeAgoInWords([
Once created, you can convert `DateTime` instances into timestamps or quarter
values:
-``` php
+```php
$time = new DateTime('2021-01-31');
echo $time->toQuarter(); // Outputs '1'
echo $time->toUnixString(); // Outputs '1612069200'
@@ -406,7 +406,7 @@ The `toQuarterRange()` method was added.
You can also get the date range for a quarter:
-``` php
+```php
$time = new DateTime('2021-01-31');
$range = $time->toQuarterRange();
// Outputs ['2021-01-01', '2021-03-31']
@@ -436,7 +436,7 @@ $range = $time->toQuarterRange();
You can compare a `DateTime` instance with the present in a variety of ways:
-``` php
+```php
$time = new DateTime('+3 days');
debug($time->isYesterday());
@@ -457,7 +457,7 @@ not the `DateTime` instance matches the present.
You can see if a `DateTime` instance falls within a given range using
`wasWithinLast()` and `isWithinNext()`:
-``` php
+```php
$time = new DateTime('+3 days');
// Within 2 days. Outputs 'false'
@@ -473,7 +473,7 @@ debug($time->isWithinNext('2 weeks'));
You can also compare a `DateTime` instance within a range in the past:
-``` php
+```php
$time = new DateTime('-72 hours');
// Within past 2 days. Outputs 'false'
@@ -506,7 +506,7 @@ time and timezones. The `Date` class wraps the `Cake\Chronos\ChronosDate` class.
Returns an integer timestamp for the date:
-``` php
+```php
$date = new Date('2021-01-31');
echo $date->getTimestamp();
```
@@ -525,7 +525,7 @@ CakePHP provides `DateTimePeriod` and `DatePeriod` classes that wrap PHP's
`DatePeriod`. When iterating, `DateTimePeriod` returns `DateTime` instances
and `DatePeriod` returns `Date` instances:
-``` php
+```php
use Cake\I18n\DateTime;
use Cake\I18n\DateTimePeriod;
diff --git a/docs/en/core-libraries/validation.md b/docs/en/core-libraries/validation.md
index 9ca0823a2b..2a7e343016 100644
--- a/docs/en/core-libraries/validation.md
+++ b/docs/en/core-libraries/validation.md
@@ -18,7 +18,7 @@ Validator objects contain a mapping between fields and validation sets. In
turn, the validation sets contain a collection of rules that apply to the field
they are attached to. Creating a validator is simple:
-``` php
+```php
use Cake\Validation\Validator;
$validator = new Validator();
@@ -27,7 +27,7 @@ $validator = new Validator();
Once created, you can start defining sets of rules for the fields you want to
validate:
-``` php
+```php
$validator
->requirePresence('title')
->notEmptyString('title', 'Please fill this field')
@@ -72,13 +72,13 @@ By default, `true` is used. Key presence is checked by using
`array_key_exists()` so that null values will count as present. You can set
the mode using the second parameter:
-``` php
+```php
$validator->requirePresence('author_id', 'create');
```
If you have multiple fields that are required, you can define them as a list:
-``` php
+```php
// Define multiple fields for create
$validator->requirePresence(['author_id', 'title'], 'create');
@@ -130,7 +130,7 @@ when a field can or cannot be empty:
An example of these methods in action is:
-``` php
+```php
$validator->allowEmptyDateTime('published')
->allowEmptyString('title', 'Title cannot be empty', false)
->allowEmptyString('body', 'Body cannot be empty', 'update')
@@ -144,7 +144,7 @@ The `Validator` class provides methods that make building validators simple
and expressive. For example adding validation rules to a username could look
like:
-``` php
+```php
$validator = new Validator();
$validator
->email('username')
@@ -162,7 +162,7 @@ full set of validator methods.
In addition to using methods on the `Validator`, and coming from providers, you
can also use any callable, including anonymous functions, as validation rules:
-``` php
+```php
// Use a global function
$validator->add('title', 'custom', [
'rule' => 'validate_title',
@@ -226,7 +226,7 @@ should be used as the error message.
Possible existing error messages defined via the `message` option will be
overwritten by the ones returned from the validation rule method:
-``` php
+```php
$validator->add('length', 'custom', [
'rule' => function (mixed $value, array $context) {
if (!$value) {
@@ -257,7 +257,7 @@ values will make the rule apply to only create or update operations.
Additionally, you can provide a callable function that will determine whether or
not a particular rule should be applied:
-``` php
+```php
$validator->add('picture', 'file', [
'rule' => ['mimeType', ['image/jpeg', 'image/png']],
'on' => function (array $context): bool {
@@ -271,7 +271,7 @@ array. The above example will make the rule for 'picture' optional depending on
whether the value for `show_profile_picture` is empty. You could also use the
`uploadedFile` validation rule to create optional file upload inputs:
-``` php
+```php
$validator->add('picture', 'file', [
'rule' => ['uploadedFile', ['optional' => true]],
]);
@@ -282,7 +282,7 @@ accept a callback function as their last argument. If present, the callback
determines whether or not the rule should be applied. For example, a field is
sometimes allowed to be empty:
-``` php
+```php
$validator->allowEmptyString('tax', 'This field is required', function (array $context): bool {
return !$context['data']['is_taxable'];
});
@@ -291,7 +291,7 @@ $validator->allowEmptyString('tax', 'This field is required', function (array $c
Likewise, a field can be required to be populated when certain conditions are
met:
-``` php
+```php
$validator->notEmptyString('email_frequency', 'This field is required', function (array $context): bool {
return !empty($context['data']['wants_newsletter']);
});
@@ -303,7 +303,7 @@ the user wants to receive the newsletter.
Further it's also possible to require a field to be present under certain
conditions only:
-``` php
+```php
$validator->requirePresence('full_name', function (array $context): bool {
if (isset($context['data']['action'])) {
return $context['data']['action'] === 'subscribe';
@@ -334,7 +334,7 @@ previous one has failed. This allows you to collect as many validation errors as
you can in a single pass. If you want to stop execution after
a specific rule has failed, you can set the `last` option to `true`:
-``` php
+```php
$validator = new Validator();
$validator
->add('body', [
@@ -358,7 +358,7 @@ run.
You can have the `last` option automatically applied to each rule you can use
the `setStopOnFailure()` method to enable this behavior:
-``` php
+```php
public function validationDefault(Validator $validator): Validator
{
$validator
@@ -387,7 +387,7 @@ rules. When using Validators and the ORM together, additional providers are
configured for the table and entity objects. You can use the `setProvider()`
method to add any additional providers your application needs:
-``` php
+```php
$validator = new Validator();
// Use an object instance.
@@ -401,7 +401,7 @@ Validation providers can be objects, or class names. If a class name is used the
methods must be static. To use a provider other than 'default', be sure to set
the `provider` key in your rule:
-``` php
+```php
// Use a rule from the table provider
$validator->add('title', 'custom', [
'rule' => 'customTableMethod',
@@ -412,7 +412,7 @@ $validator->add('title', 'custom', [
If you wish to add a `provider` to all `Validator` objects that are created
in the future, you can use the `addDefaultProvider()` method as follows:
-``` php
+```php
use Cake\Validation\Validator;
// Use an object instance.
@@ -431,7 +431,7 @@ You can use the [Localized plugin](https://github.com/cakephp/localized) to
get providers based on countries. With this plugin, you'll be able to validate
model fields, depending on a country, ie:
-``` php
+```php
namespace App\Model\Table;
use Cake\ORM\Table;
@@ -460,7 +460,7 @@ validation, like en, fr, de.
There are a few methods that are common to all classes, defined through the
[ValidationInterface interface](https://github.com/cakephp/localized/blob/master/src/Validation/ValidationInterface.php):
-``` text
+```text
phone() to check a phone number
postal() to check a postal code
personId() to check a country specific person ID
@@ -474,7 +474,7 @@ nested data you have. CakePHP makes it simple to add validators to specific
attributes. For example, assume you are working with a non-relational database
and need to store an article and its comments:
-``` php
+```php
$data = [
'title' => 'Best article',
'comments' => [
@@ -485,7 +485,7 @@ $data = [
To validate the comments you would use a nested validator:
-``` php
+```php
$validator = new Validator();
$validator->add('title', 'not-blank', ['rule' => 'notBlank']);
@@ -505,7 +505,7 @@ contribute to the parent validator's errors and influence the final result.
Like other validator features, nested validators support error messages and
conditional application:
-``` php
+```php
$validator->addNestedMany(
'comments',
$commentValidator,
@@ -524,7 +524,7 @@ While defining validators inline where they are used makes for good example
code, it doesn't lead to maintainable applications. Instead, you should
create `Validator` sub-classes for your reusable validation logic:
-``` php
+```php
// In src/Model/Validation/ContactValidator.php
namespace App\Model\Validation;
@@ -547,7 +547,7 @@ start using it to validate data. Validators are able to validate array
data. For example, if you wanted to validate a contact form before creating and
sending an email you could do the following:
-``` php
+```php
use Cake\Validation\Validator;
$validator = new Validator();
@@ -571,7 +571,7 @@ if (!$errors) {
The `getErrors()` method will return a non-empty array when there are validation
failures. The returned array of errors will be structured like:
-``` php
+```php
$errors = [
'email' => ['E-mail must be valid'],
];
@@ -582,7 +582,7 @@ be returned per field. By default, the `getErrors()` method applies rules for
the 'create' mode. If you'd like to apply 'update' rules you can do the
following:
-``` php
+```php
$errors = $validator->validate($this->request->getData(), false);
if (!$errors) {
// Send an email.
@@ -605,7 +605,7 @@ interfaces used to populate the entities.
The request data is validated automatically when using the `newEntity()`,
`newEntities()`, `patchEntity()` or `patchEntities()` methods of `Table` class:
-``` php
+```php
// In the ArticlesController class
$article = $this->Articles->newEntity($this->request->getData());
if ($article->getErrors()) {
@@ -616,7 +616,7 @@ if ($article->getErrors()) {
Similarly, when you need to validate multiple entities at a time, you can
use the `newEntities()` method:
-``` php
+```php
// In the ArticlesController class
$entities = $this->Articles->newEntities($this->request->getData());
foreach ($entities as $entity) {
@@ -630,7 +630,7 @@ The `newEntity()`, `patchEntity()`, `newEntities()` and `patchEntities()`
methods allow you to specify which associations are validated, and which
validation sets to apply using the `options` parameter:
-``` php
+```php
$valid = $this->Articles->newEntity($article, [
'associated' => [
'Comments' => [
@@ -660,7 +660,7 @@ Some of the validation methods accept additional parameters to define boundary
conditions or valid options. You can provide these boundary conditions and
options as follows:
-``` php
+```php
$validator = new Validator();
$validator
->add('title', 'minLength', [
@@ -680,7 +680,7 @@ parameters as the remaining parameters.
You can validate that a value is a valid IP address or an IP range (subnet)
using the `ipOrRange()` rule:
-``` php
+```php
$validator->add('ip_address', 'validRange', [
'rule' => 'ipOrRange',
'message' => 'Please provide a valid IP or IP range.',
diff --git a/docs/en/core-libraries/xml.md b/docs/en/core-libraries/xml.md
index 050915f3e0..1e112e3fd8 100644
--- a/docs/en/core-libraries/xml.md
+++ b/docs/en/core-libraries/xml.md
@@ -22,7 +22,7 @@ or DOMDocument object. You can use `Xml::build()` to build XML
objects from a variety of sources. For example, you can load XML from
strings:
-``` php
+```php
$text = '
1
@@ -34,14 +34,14 @@ $xml = Xml::build($text);
You can also build Xml objects from local files by overriding the default option:
-``` php
+```php
// Local file
$xml = Xml::build('/home/awesome/unicorns.xml', ['readFile' => true]);
```
You can also build Xml objects using an array:
-``` php
+```php
$data = [
'post' => [
'id' => 1,
@@ -54,7 +54,7 @@ $xml = Xml::build($data);
If your input is invalid, the Xml class will throw an exception:
-``` php
+```php
$xmlString = 'What is XML?';
try {
$xmlObject = Xml::build($xmlString); // Here will throw an exception
@@ -73,7 +73,7 @@ try {
HTML documents can be parsed into `SimpleXmlElement` or `DOMDocument`
objects with `loadHtml()`:
-``` php
+```php
$html = Xml::loadHtml($htmlString, ['return' => 'domdocument']);
```
@@ -89,7 +89,7 @@ can be enabled with the `loadEntities` and `parseHuge` options respectively.
Converting XML strings into arrays is simple with the Xml class as well. By
default you'll get a SimpleXml object back:
-``` php
+```php
$xmlString = 'value';
$xmlArray = Xml::toArray(Xml::build($xmlString));
```
@@ -98,7 +98,7 @@ If your XML is invalid a `Cake\Utility\Exception\XmlException` will be raised.
## Transforming an Array into a String of XML
-``` php
+```php
$xmlArray = ['root' => ['child' => 'value']];
// You can use Xml::build() too.
$xmlObject = Xml::fromArray($xmlArray, ['format' => 'tags']);
@@ -109,7 +109,7 @@ Your array must have only one element in the "top level" and it can not be
numeric. If the array is not in this format, Xml will throw an exception.
Examples of invalid arrays:
-``` php
+```php
// Top level with numeric key
[
['key' => 'value'],
@@ -126,7 +126,7 @@ By default, array values will be output as XML tags. If you want to define
attributes or text values you can prefix the keys that are supposed to be
attributes with `@`. For value text, use `@` as the key:
-``` php
+```php
$xmlArray = [
'project' => [
'@id' => 1,
@@ -140,7 +140,7 @@ $xmlString = $xmlObject->asXML();
The content of `$xmlString` will be:
-``` php
+```php
Value of projectName of project, as tag
```
@@ -151,7 +151,7 @@ To use XML Namespaces, create a key in your array with the name `xmlns:`
in a generic namespace or input the prefix `xmlns:` in a custom namespace. See
the samples:
-``` php
+```php
$xmlArray = [
'root' => [
'xmlns:' => 'https://cakephp.org',
@@ -176,7 +176,7 @@ $xml2 = Xml::fromArray($xmlArray);
The value of `$xml1` and `$xml2` will be, respectively:
-``` php
+```php
value
@@ -189,7 +189,7 @@ The value of `$xml1` and `$xml2` will be, respectively:
After you have created your XML document, you just use the native interfaces for
your document type to add, remove, or manipulate child nodes:
-``` php
+```php
// Using SimpleXML
$myXmlOriginal = 'value';
$xml = Xml::build($myXmlOriginal);
diff --git a/docs/en/deployment.md b/docs/en/deployment.md
index 19e3b4a84e..c2aff09f7a 100644
--- a/docs/en/deployment.md
+++ b/docs/en/deployment.md
@@ -51,7 +51,7 @@ For example, you can set an environment variable in your Apache configuration:
And then you can set the debug level dynamically in **app_local.php**:
-``` php
+```php
$debug = (bool)getenv('CAKEPHP_DEBUG');
return [
@@ -124,7 +124,7 @@ CakePHP uses `assert()` internally to provide runtime type checking and
provide better error messages during development. You can have PHP skip these
assertions by updating your `php.ini` to include:
-``` ini
+```ini
; Turn off assert() code generation.
zend.assertions = -1
```
diff --git a/docs/en/development/application.md b/docs/en/development/application.md
index ebda15ce17..1b65cbebd4 100644
--- a/docs/en/development/application.md
+++ b/docs/en/development/application.md
@@ -52,7 +52,7 @@ configure low-level concerns of your application, you can also use the
`Application::bootstrap()` hook method to load/initialize plugins, and attach
global event listeners:
-``` php
+```php
// in src/Application.php
namespace App;
diff --git a/docs/en/development/configuration.md b/docs/en/development/configuration.md
index 3d63c5bbef..41368515db 100644
--- a/docs/en/development/configuration.md
+++ b/docs/en/development/configuration.md
@@ -34,7 +34,7 @@ If your application has many configuration options it can be helpful to split
configuration into multiple files. After creating each of the files in your
**config/** directory you can load them in **bootstrap.php**:
-``` php
+```php
use Cake\Core\Configure;
use Cake\Core\Configure\Engine\PhpConfig;
@@ -74,7 +74,7 @@ should go in each one.
Once your environment variables have been set, you can use `env()` to read
data from the environment:
-``` php
+```php
$debug = env('APP_DEBUG', false);
```
@@ -236,7 +236,7 @@ Additional class paths are setup through the autoloaders your application uses.
When using `composer` to generate your autoloader, you could do the following,
to provide fallback paths for controllers in your application:
-``` json
+```json
"autoload": {
"psr-4": {
"App\\Controller\\": "/path/to/directory/with/controller/folders/",
@@ -250,7 +250,7 @@ namespace. The first key will be searched, and if that path does not contain the
class/file the second key will be searched. You can also map a single namespace
to multiple directories with the following:
-``` json
+```json
"autoload": {
"psr-4": {
"App\\": ["src/", "/path/to/directory/"]
@@ -264,7 +264,7 @@ Since plugins, view templates and locales are not classes, they cannot have an
autoloader configured. CakePHP provides three Configure variables to setup additional
paths for these resources. In your **config/app.php** you can set these variables:
-``` php
+```php
return [
// More configuration
'App' => [
@@ -310,7 +310,7 @@ won't end up breaking the MVC structure CakePHP provides.
Use `write()` to store data in the application's configuration:
-``` php
+```php
Configure::write('Company.name', 'Pizza, Inc.');
Configure::write('Company.slogan', 'Pizza for your body and soul');
```
@@ -321,7 +321,7 @@ Configure::write('Company.slogan', 'Pizza for your body and soul');
The above example could also be written in a single call:
-``` php
+```php
Configure::write('Company', [
'name' => 'Pizza, Inc.',
'slogan' => 'Pizza for your body and soul',
@@ -343,7 +343,7 @@ Used to read configuration data from the application. If a key is supplied, the
data is returned. Using our examples from write() above, we can read that data
back:
-``` php
+```php
// Returns 'Pizza Inc.'
Configure::read('Company.name');
@@ -366,7 +366,7 @@ Reads configuration data just like `Cake\Core\Configure::read()`
but expects to find a key/value pair. In case the requested pair does not
exist, a `RuntimeException` will be thrown:
-``` php
+```php
Configure::readOrFail('Company.name'); // Yields: 'Pizza, Inc.'
Configure::readOrFail('Company.geolocation'); // Will throw an exception
@@ -382,7 +382,7 @@ Configure::readOrFail('Company');
Used to check if a key/path exists and has non-null value:
-``` php
+```php
$exists = Configure::check('Company.name');
```
@@ -392,7 +392,7 @@ $exists = Configure::check('Company.name');
Used to delete information from the application's configuration:
-``` php
+```php
Configure::delete('Company.name');
```
@@ -409,7 +409,7 @@ Consumes configuration data just like `Cake\Core\Configure::consume()`
but expects to find a key/value pair. In case the requested pair does not
exist, a `RuntimeException` will be thrown:
-``` php
+```php
Configure::consumeOrFail('Company.name'); // Yields: 'Pizza, Inc.'
Configure::consumeOrFail('Company.geolocation'); // Will throw an exception
@@ -431,7 +431,7 @@ files. See the [PHP documentation](https://php.net/parse_ini_file) for more
information on the specifics of ini files. To use a core config engine, you'll
need to attach it to Configure using `Configure::config()`:
-``` php
+```php
use Cake\Core\Configure\Engine\PhpConfig;
// Read config files from config
@@ -446,7 +446,7 @@ kinds or sources of configuration files. You can interact with attached engines
using a few other methods on Configure. To check which engine aliases are
attached you can use `Configure::configured()`:
-``` php
+```php
// Get the array of aliases for attached engines.
Configure::configured();
@@ -460,7 +460,7 @@ You can also remove attached engines. `Configure::drop('default')`
would remove the default engine alias. Any future attempts to load configuration
files with that engine would fail:
-``` php
+```php
Configure::drop('default');
```
@@ -471,7 +471,7 @@ Configure::drop('default');
Once you've attached a config engine to Configure you can load configuration
files:
-``` php
+```php
// Load my_file.php using the 'default' engine object.
Configure::load('my_file', 'default');
```
@@ -519,13 +519,13 @@ a PHP configuration file loadable by the
Given that the 'default' engine is an instance of PhpConfig.
Save all data in Configure to the file `my_config.php`:
-``` php
+```php
Configure::dump('my_config', 'default');
```
Save only the error handling configuration:
-``` php
+```php
Configure::dump('error', 'default', ['Error', 'Exception']);
```
@@ -541,7 +541,7 @@ Since configure only remembers values for the current request, you will
need to store any modified configuration information if you want to
use it in subsequent requests:
-``` php
+```php
// Store the current configuration in the 'user_1234' key in the 'default' cache.
Configure::store('user_1234', 'default');
```
@@ -556,7 +556,7 @@ Stored configuration data is persisted in the named cache configuration. See the
Once you've stored runtime configuration, you'll probably need to restore it
so you can access it again. `Configure::restore()` does exactly that:
-``` php
+```php
// Restore runtime configuration from the cache.
Configure::restore('user_1234', 'default');
```
diff --git a/docs/en/development/debugging.md b/docs/en/development/debugging.md
index 736a2d5614..2209f9b8d8 100644
--- a/docs/en/development/debugging.md
+++ b/docs/en/development/debugging.md
@@ -39,7 +39,7 @@ If you have [Psysh](https://psysh.org/) installed you can use this
function in CLI environments to open an interactive console with the current
local scope:
-``` php
+```php
// Some code
eval(breakpoint());
```
@@ -79,7 +79,7 @@ The `Debugger.editorBasePath` configure option was added.
Dump prints out the contents of a variable. It will print out all
properties and methods (if any) of the supplied variable:
-``` php
+```php
$foo = [1,2,3];
Debugger::dump($foo);
@@ -111,7 +111,7 @@ When dumping data with `Debugger` or rendering error pages, you may want to
hide sensitive keys like passwords or API keys. In your **config/bootstrap.php**
you can mask specific keys:
-``` php
+```php
Debugger::setOutputMask([
'password' => 'xxxxx',
'awsKey' => 'yyyyy',
@@ -139,7 +139,7 @@ Returns the current stack trace. Each line of the trace includes
the calling method, including which file and line the call
originated from:
-``` php
+```php
// In PostsController::index()
pr(Debugger::trace());
@@ -162,7 +162,7 @@ Grab an excerpt from the file at `$path` (which is an absolute
filepath), highlights line number `$line` with `$context` number of
lines around it.
-``` php
+```php
pr(Debugger::excerpt(ROOT . DS . LIBS . 'debugger.php', 321, 2));
// Will output the following.
@@ -191,7 +191,7 @@ Exception and error pages can contain URLs that directly open in your editor or
IDE. CakePHP ships with URL formats for several popular editors, and you can add
additional editor formats if required during application bootstrap:
-``` php
+```php
// Generate links for vscode.
Debugger::setEditor('vscode');
@@ -213,7 +213,7 @@ Logging messages is another good way to debug applications, and you can use
use `LogTrait` have an instance method `log()` which can be used
to log messages:
-``` php
+```php
$this->log('Got here', 'debug');
```
@@ -222,7 +222,7 @@ to help debug methods that involve redirects or complicated loops. You can also
use `Cake\Log\Log::write()` to write log messages. This method can be called
statically anywhere in your application one Log has been loaded:
-``` php
+```php
// At the top of the file you want to log in.
use Cake\Log\Log;
diff --git a/docs/en/development/dependency-injection.md b/docs/en/development/dependency-injection.md
index cccda1d1c4..0de78be3f6 100644
--- a/docs/en/development/dependency-injection.md
+++ b/docs/en/development/dependency-injection.md
@@ -397,7 +397,7 @@ public function services(ContainerInterface $container): void
## Controller Example
-``` php
+```php
// In src/Controller/UsersController.php
class UsersController extends AppController
{
@@ -427,7 +427,7 @@ testing.
## Command Example
-``` php
+```php
// In src/Command/CheckUsersCommand.php
use Cake\Console\CommandFactoryInterface;
@@ -464,7 +464,7 @@ of the command.
## Component Example
-``` php
+```php
// In src/Controller/Component/SearchComponent.php
class SearchComponent extends Component
{
@@ -501,7 +501,7 @@ In order to have services created by the container, you need to tell it which
classes it can create and how to build those classes. The
simplest definition is via a class name:
-``` php
+```php
// Add a class by its name.
$container->add(BillingService::class);
```
@@ -509,7 +509,7 @@ $container->add(BillingService::class);
Your application and plugins define the services they have in the
`services()` hook method:
-``` php
+```php
// in src/Application.php
namespace App;
@@ -528,7 +528,7 @@ class Application extends BaseApplication
You can define implementations for interfaces that your application uses:
-``` php
+```php
use App\Service\AuditLogServiceInterface;
use App\Service\AuditLogService;
@@ -540,7 +540,7 @@ $container->add(AuditLogServiceInterface::class, AuditLogService::class);
The container can leverage factory functions to create objects if necessary:
-``` php
+```php
$container->add(AuditLogServiceInterface::class, function (...$args) {
return new AuditLogService(...$args);
});
@@ -552,7 +552,7 @@ as arguments.
Once you've defined a class, you also need to define the dependencies it
requires. Those dependencies can be either objects or primitive values:
-``` php
+```php
// Add a primitive value like a string, array or number.
$container->add('apiKey', 'abc123');
@@ -572,7 +572,7 @@ By default, services are not shared. Every object (and dependencies) is created
each time it is fetched from the container. If you want to re-use a single
instance, often referred to as a singleton, you can mark a service as 'shared':
-``` php
+```php
// in your Application::services() method.
$container->addShared(BillingService::class);
@@ -583,7 +583,7 @@ $container->addShared(BillingService::class);
If you want to have ORM Tables injected as a dependency to a service, you can
add `TableContainer` to your application's service container:
-``` php
+```php
use Cake\ORM\Locator\TableContainer;
// In your Application::services() method.
@@ -601,7 +601,7 @@ Once a service is defined you can modify or update the service definition by
extending them. This allows you to add additional arguments to services defined
elsewhere:
-``` php
+```php
// Add an argument to a partially defined service elsewhere.
$container->extend(BillingService::class)
->addArgument('logLevel');
@@ -613,7 +613,7 @@ By tagging services you can get all of those services resolved at the same
time. This can be used to build services that combine collections of other
services like in a reporting system:
-``` php
+```php
$container->add(BillingReport::class)->addTag('reports');
$container->add(UsageReport::class)->addTag('reports');
@@ -630,7 +630,7 @@ Often you'll need configuration data in your services. If you need a specific va
you can inject it as a constructor argument using the `Cake\Core\Attribute\Configure`
attribute:
-``` php
+```php
use Cake\Core\Attribute\Configure;
class InjectedService
@@ -647,7 +647,7 @@ class InjectedService
If you want to inject a copy of all configuration data, CakePHP includes
an injectable configuration reader:
-``` php
+```php
use Cake\Core\ServiceConfig;
// Use a shared instance
@@ -669,7 +669,7 @@ their first use.
An example ServiceProvider would look like:
-``` php
+```php
namespace App\ServiceProvider;
use Cake\Core\ContainerInterface;
@@ -701,7 +701,7 @@ in it not be loadable from the container.
To load a service provider add it into the container using the
`addServiceProvider()` method:
-``` php
+```php
// in your Application::services() method.
$container->addServiceProvider(new BillingServiceProvider());
```
@@ -714,7 +714,7 @@ service provider needs to load additional configuration files, load additional
service providers or modify a service defined elsewhere in your application. An
example of a bootable service would be:
-``` php
+```php
namespace App\ServiceProvider;
use Cake\Core\ServiceProvider;
@@ -1234,7 +1234,7 @@ class ArticlesController extends AppController
Auto Wiring is turned off by default. To enable it:
-``` php
+```php
// In src/Application.php
use League\Container\ReflectionContainer;
@@ -1250,7 +1250,7 @@ While your dependencies will now be resolved automatically, this approach will
not cache resolutions which can be detrimental to performance. To enable
caching:
-``` php
+```php
use League\Container\ReflectionContainer;
$container->delegate(
diff --git a/docs/en/development/errors.md b/docs/en/development/errors.md
index 5bb912796c..8b0b4974b1 100644
--- a/docs/en/development/errors.md
+++ b/docs/en/development/errors.md
@@ -62,7 +62,7 @@ deprecated. We also recommend this system for use in your plugins and
application code when useful. You can trigger deprecation warnings with
`deprecationWarning()`:
-``` php
+```php
deprecationWarning('5.0', 'The example() method is deprecated. Use getExample() instead.');
```
@@ -75,7 +75,7 @@ You can temporarily disable deprecation warnings in one of a few ways:
2. Using the `Error.ignoredDeprecationPaths` configuration option to ignore
deprecations with glob compatible expressions. For example:
- ``` php
+ ```php
'Error' => [
'ignoredDeprecationPaths' => [
'vendors/company/contacts/*',
@@ -113,7 +113,7 @@ when they handle errors. You can listen to the `Error.beforeRender` event to be
notified of PHP errors. The `Exception.beforeRender` event is dispatched when an
exception is handled:
-``` php
+```php
$errorTrap = new ErrorTrap(Configure::read('Error'));
$errorTrap->getEventManager()->on(
'Error.beforeRender',
@@ -166,7 +166,7 @@ data returned by `getAttributes()` will be exposed as view variables as well.
By default, error templates use **templates/layout/error.php** for a layout.
You can use the `layout` property to pick a different layout:
-``` php
+```php
// inside templates/Error/error400.php
$this->layout = 'my_error';
```
@@ -189,7 +189,7 @@ If your application uses [Prefix Routing](../development/routing#prefix-routing)
controllers for each routing prefix. For example, if you had an `Admin`
prefix. You could create the following class:
-``` php
+```php
namespace App\Controller\Admin;
use App\Controller\AppController;
@@ -220,7 +220,7 @@ application errors. For example a `MissingWidgetException` would be handled by
a `missingWidget()` controller method, and CakePHP would use
`templates/Error/missing_widget.php` as the template. For example:
-``` php
+```php
namespace App\Controller\Admin;
use App\Controller\AppController;
@@ -252,7 +252,7 @@ assume our application uses `App\Exception\MissingWidgetException` to indicate
a missing widget. We could create an exception renderer that renders specific
error pages when this error is handled:
-``` php
+```php
// In src/Error/AppExceptionRenderer.php
namespace App\Error;
@@ -284,7 +284,7 @@ Exception rendering methods receive the handled exception as an argument, and
should return a `Response` object. You can also implement methods to add
additional logic when handling CakePHP errors:
-``` php
+```php
// In src/Error/AppExceptionRenderer.php
namespace App\Error;
@@ -305,7 +305,7 @@ The exception renderer dictates which controller is used for exception
rendering. If you want to change which controller is used to render exceptions,
override the `_getController()` method in your exception renderer:
-``` php
+```php
// in src/Error/AppExceptionRenderer
namespace App\Error;
@@ -336,7 +336,7 @@ exceptions](https://php.net/manual/en/spl.exceptions.php), `Exception`
itself, or `Cake\Core\Exception\Exception`.
If your application contained the following exception:
-``` php
+```php
use Cake\Core\Exception\CakeException;
class MissingWidgetException extends CakeException
@@ -357,7 +357,7 @@ pass in additional data. This additional data is interpolated into the
`_messageTemplate`. This allows you to create data rich exceptions, that
provide more context around your errors:
-``` php
+```php
use Cake\Core\Exception\CakeException;
class MissingWidgetException extends CakeException
@@ -444,7 +444,7 @@ You can throw these exceptions from your controllers to indicate failure states,
or HTTP errors. An example use of the HTTP exceptions could be rendering 404
pages for items that have not been found:
-``` php
+```php
use Cake\Http\Exception\NotFoundException;
public function view($id = null)
@@ -466,7 +466,7 @@ RESTful responses to client applications and users.
You can throw any of the HTTP related exceptions from your controller actions
to indicate failure states. For example:
-``` php
+```php
use Cake\Http\Exception\NotFoundException;
public function view($id = null)
@@ -581,7 +581,7 @@ log messages and log them to the appropriate place. You can replace the error
logger using the `Error.logger` configure value. An example error
logger:
-``` php
+```php
namespace App\Error;
use Cake\Error\ErrorLoggerInterface;
@@ -623,7 +623,7 @@ CakePHP includes error renderers for both web and console environments. If
however, you would like to replace the logic that renders errors you can create
a class:
-``` php
+```php
// src/Error/CustomErrorRenderer.php
namespace App\Error;
diff --git a/docs/en/development/rest.md b/docs/en/development/rest.md
index 7557509cc9..4ffe3413d0 100644
--- a/docs/en/development/rest.md
+++ b/docs/en/development/rest.md
@@ -21,7 +21,7 @@ To get started with adding a REST API to your application, we'll first need
a controller containing actions that we want to expose as an API. A basic
controller might look something like this:
-``` php
+```php
// src/Controller/RecipesController.php
use Cake\View\JsonView;
@@ -99,7 +99,7 @@ the `serialize` option to tell CakePHP which view variables should be
serialized when making API responses. We'll connect our controller to the
application URLs with [Resource Routes](../development/routing#resource-routes):
-``` php
+```php
// in config/routes.php
$routes->scope('/', function (RouteBuilder $routes): void {
$routes->setExtensions(['json']);
@@ -139,7 +139,7 @@ contained the JSON representation.
In our `Application` class ensure the following is present:
-``` php
+```php
$middlewareQueue->add(new BodyParserMiddleware());
```
diff --git a/docs/en/development/routing.md b/docs/en/development/routing.md
index 78bc126c00..208cdf46a9 100644
--- a/docs/en/development/routing.md
+++ b/docs/en/development/routing.md
@@ -22,7 +22,7 @@ This section will teach you by example the most common uses of the CakePHP
Router. Typically you want to display something as a landing page, so you add
this to your **config/routes.php** file:
-``` php
+```php
/** @var \Cake\Routing\RouteBuilder $routes */
$routes->connect('/', ['controller' => 'Articles', 'action' => 'index']);
```
@@ -32,7 +32,7 @@ homepage of your site is visited. Sometimes you need dynamic routes that will
accept multiple parameters, this would be the case, for example of a route for
viewing an article's content:
-``` php
+```php
$routes->connect('/articles/*', ['controller' => 'Articles', 'action' => 'view']);
```
@@ -41,7 +41,7 @@ method `view(15)` in the `ArticlesController`. This will not, though,
prevent people from trying to access URLs looking like `/articles/foobar`. If
you wish, you can restrict some parameters to conform to a regular expression:
-``` php
+```php
// Using fluent interface
$routes->connect(
'/articles/{id}',
@@ -68,7 +68,7 @@ option later.
The CakePHP Router can also reverse match routes. That means that from an
array containing matching parameters, it is capable of generating a URL string:
-``` php
+```php
use Cake\Routing\Router;
echo Router::url(['controller' => 'Articles', 'action' => 'view', 'id' => 15]);
@@ -80,7 +80,7 @@ Routes can also be labelled with a unique name, this allows you to quickly
reference them when building links instead of specifying each of the routing
parameters:
-``` php
+```php
// In routes.php
$routes->connect(
'/upgrade',
@@ -100,7 +100,7 @@ A scope defines a common path segment, and optionally route defaults. Any routes
connected inside a scope will inherit the path/defaults from their wrapping
scopes:
-``` php
+```php
$routes->scope('/blog', ['plugin' => 'Blog'], function (RouteBuilder $routes) {
$routes->connect('/', ['controller' => 'Articles']);
});
@@ -123,7 +123,7 @@ scopes not only let you keep your code DRY, they also help Router optimize its
operation. This method defaults to the `/` scope. To create a scope and connect
some routes we'll use the `scope()` method:
-``` php
+```php
// In config/routes.php
use Cake\Routing\RouteBuilder;
use Cake\Routing\Route\DashedRoute;
@@ -141,7 +141,7 @@ match elements in the URL.
The basic format for a route definition is:
-``` php
+```php
$routes->connect(
'/url/template',
['targetKey' => 'targetValue'],
@@ -153,14 +153,14 @@ The first parameter is used to tell the router what sort of URL you're trying to
control. The URL is a normal slash delimited string, but can also contain
a wildcard (*) or [Route Elements](#route-elements). Using a wildcard tells the router
that you are willing to accept any additional arguments supplied. Routes without
-a * only match the exact template pattern supplied.
+a `*` only match the exact template pattern supplied.
Once you've specified a URL, you use the last two parameters of `connect()` to
tell CakePHP what to do with a request once it has been matched. The second
parameter defines the route 'target'. This can be defined either as an array, or
as a destination string. A few examples of route targets are:
-``` php
+```php
// Array target to an application controller
$routes->connect(
'/users/view/*',
@@ -185,13 +185,13 @@ The above example also illustrates string targets. String targets provide
a compact way to define a route's destination. String targets have the following
syntax:
-``` text
+```text
[Plugin].[Prefix]/[Controller]::[action]
```
Some example string targets are:
-``` text
+```text
// Application controller
'Articles::view'
@@ -210,7 +210,7 @@ there is also the trailing star (`/**`). Using a trailing double star,
will capture the remainder of a URL as a single passed argument. This is useful
when you want to use an argument that included a `/` in it:
-``` php
+```php
$routes->connect(
'/pages/**',
['controller' => 'Pages', 'action' => 'show']
@@ -223,7 +223,7 @@ passed argument of `the-example-/-and-proof`.
The second parameter of `connect()` can define any parameters that
compose the default route parameters:
-``` php
+```php
$routes->connect(
'/government',
['controller' => 'Pages', 'action' => 'display', 5],
@@ -240,7 +240,7 @@ accessing our users controller at `/users/some-action/5`, we'd like to be able
to access it through `/cooks/some-action/5`. The following route takes care of
that:
-``` php
+```php
$routes->connect(
'/cooks/{action}/*', ['controller' => 'Users']
);
@@ -264,7 +264,7 @@ a REST API you'll often want to map HTTP actions to different controller methods
The `RouteBuilder` provides helper methods that make defining routes for
specific HTTP verbs simpler:
-``` php
+```php
// Create a route that only responds to GET requests.
$routes->get(
'/cooks/{id}',
@@ -306,7 +306,7 @@ expression - this tells CakePHP how to know if the URL is correctly formed or
not. If you choose to not provide a regular expression, any non `/` character
will be treated as part of the parameter:
-``` php
+```php
$routes->connect(
'/{controller}/{id}',
['action' => 'view'],
@@ -332,7 +332,7 @@ CakePHP does not automatically produce lowercased and dashed URLs when using the
`{controller}` parameter. If you need this, the above example could be
rewritten like so:
-``` php
+```php
use Cake\Routing\Route\DashedRoute;
// Create a builder with a different route class.
@@ -366,14 +366,14 @@ controller. For example, to map all URLs to actions of the `home` controller,
e.g have URLs like `/demo` instead of `/home/demo`, you can do the
following:
-``` php
+```php
$routes->connect('/{action}', ['controller' => 'Home']);
```
If you would like to provide a case insensitive URL, you can use regular
expression inline modifiers:
-``` php
+```php
$routes->connect(
'/{userShortcut}',
['controller' => 'Teachers', 'action' => 'profile', 1],
@@ -382,7 +382,7 @@ $routes->connect(
One more example, and you'll be a routing pro:
-``` php
+```php
$routes->connect(
'/{controller}/{year}/{month}/{day}',
['action' => 'index'],
@@ -446,7 +446,7 @@ connecting a route you can use its fluent builder methods to further configure
the route. These methods replace many of the keys in the `$options` parameter
of `connect()`:
-``` php
+```php
$routes->connect(
'/{lang}/articles/{slug}',
['controller' => 'Articles', 'action' => 'view'],
@@ -480,7 +480,7 @@ using the `setOptions()` method. This is useful when you want to apply the
same options (like `_host`, `_https`, or `_port`) to multiple routes
without repeating them:
-``` php
+```php
$routes->scope('/api', function (RouteBuilder $routes) {
// Set default options for all routes in this scope
$routes->setOptions([
@@ -502,7 +502,7 @@ Options set via `setOptions()` are:
Example with nested scopes and overrides:
-``` php
+```php
$routes->scope('/api', function (RouteBuilder $routes) {
$routes->setOptions(['_host' => 'api.example.com']);
@@ -537,7 +537,7 @@ elements be passed arguments instead. The `pass` option indicates which route
elements should also be made available as arguments passed into the controller
functions:
-``` php
+```php
// src/Controller/BlogsController.php
public function view($articleId = null, $slug = null)
{
@@ -566,7 +566,7 @@ $routes->scope('/', function (RouteBuilder $routes) {
Now thanks to the reverse routing capabilities, you can pass in the URL array
like below and CakePHP will know how to form the URL as defined in the routes:
-``` php
+```php
// view.php
// This will return a link to /blog/3-CakePHP_Rocks
echo $this->Html->link('CakePHP Rocks', [
@@ -592,7 +592,7 @@ echo $this->Html->link('CakePHP Rocks', [
We talked about string targets above. The same also works for URL generation using
`Router::pathUrl()`:
-``` php
+```php
echo Router::pathUrl('Articles::index');
// outputs: /articles
@@ -612,7 +612,7 @@ or you'd like to take advantage of the performance improvements that named
routes have. When connecting routes you can specify a `_name` option, this
option can be used in reverse routing to identify the route you want to use:
-``` php
+```php
// Connect a route with a name.
$routes->connect(
'/login',
@@ -647,7 +647,7 @@ When building named routes, you will probably want to stick to some conventions
for the route names. CakePHP makes building up route names easier by allowing
you to define name prefixes in each scope:
-``` php
+```php
$routes->scope('/api', ['_namePrefix' => 'api:'], function (RouteBuilder $routes) {
// This route's name will be `api:ping`
$routes->get('/ping', ['controller' => 'Pings'], 'ping');
@@ -669,7 +669,7 @@ $routes->prefix('Admin', ['_namePrefix' => 'admin:'], function (RouteBuilder $ro
You can also use the `_namePrefix` option inside nested scopes and it works as
you'd expect:
-``` php
+```php
$routes->plugin('Contacts', ['_namePrefix' => 'contacts:'], function (RouteBuilder $routes) {
$routes->scope('/api', ['_namePrefix' => 'api:'], function (RouteBuilder $routes) {
// This route's name will be `contacts:api:ping`
@@ -693,7 +693,7 @@ privileged users can make changes. This is often done through a
special URL such as `/admin/users/edit/5`. In CakePHP, prefix routing
can be enabled by using the `prefix` scope method:
-``` php
+```php
use Cake\Routing\Route\DashedRoute;
$routes->prefix('Admin', function (RouteBuilder $routes) {
@@ -716,7 +716,7 @@ The view file used would be **templates/Admin/Users/edit.php**
You can map the URL /admin to your `index()` action of pages controller using
following route:
-``` php
+```php
$routes->prefix('Admin', function (RouteBuilder $routes) {
// Because you are in the admin scope,
// you do not need to include the /admin prefix
@@ -728,7 +728,7 @@ $routes->prefix('Admin', function (RouteBuilder $routes) {
When creating prefix routes, you can set additional route parameters using
the `$options` argument:
-``` php
+```php
$routes->prefix('Admin', ['param' => 'value'], function (RouteBuilder $routes) {
// Routes connected here are prefixed with '/admin' and
// have the 'param' routing key set.
@@ -744,7 +744,7 @@ Multi word prefixes are by default converted using dasherize inflection, ie `MyP
would be mapped to `my-prefix` in the URL. Make sure to set a path for such prefixes
if you want to use a different format like for example underscoring:
-``` php
+```php
$routes->prefix('MyPrefix', ['path' => '/my_prefix'], function (RouteBuilder $routes) {
// Routes connected here are prefixed with '/my_prefix'
$routes->connect('/{controller}');
@@ -753,7 +753,7 @@ $routes->prefix('MyPrefix', ['path' => '/my_prefix'], function (RouteBuilder $ro
You can define prefixes inside plugin scopes as well:
-``` php
+```php
$routes->plugin('DebugKit', function (RouteBuilder $routes) {
$routes->prefix('Admin', function (RouteBuilder $routes) {
$routes->connect('/{controller}');
@@ -766,7 +766,7 @@ The connected route would have the `plugin` and `prefix` route elements set.
When defining prefixes, you can nest multiple prefixes if necessary:
-``` php
+```php
$routes->prefix('Manager', function (RouteBuilder $routes) {
$routes->prefix('Admin', function (RouteBuilder $routes) {
$routes->connect('/{controller}/{action}');
@@ -785,7 +785,7 @@ When using prefix routes it's important to set the `prefix` option, and to
use the same CamelCased format that is used in the `prefix()` method. Here's
how to build this link using the HTML helper:
-``` php
+```php
// Go into a prefixed route.
echo $this->Html->link(
'Manage articles',
@@ -804,7 +804,7 @@ echo $this->Html->link(
You can create links that point to a prefix, by adding the prefix key to your
URL array:
-``` php
+```php
echo $this->Html->link(
'New admin todo',
['prefix' => 'Admin', 'controller' => 'TodoItems', 'action' => 'create'],
@@ -813,7 +813,7 @@ echo $this->Html->link(
When using nesting, you need to chain them together:
-``` php
+```php
echo $this->Html->link(
'New todo',
['prefix' => 'Admin/MyPrefix', 'controller' => 'TodoItems', 'action' => 'create'],
@@ -834,7 +834,7 @@ This would link to a controller with the namespace `App\Controller\Admin\MyPrefi
Routes for [Plugins](../plugins) should be created using the `plugin()`
method. This method creates a new routing scope for the plugin's routes:
-``` php
+```php
$routes->plugin('DebugKit', function (RouteBuilder $routes) {
// Routes connected here are prefixed with '/debug-kit' and
// have the plugin route element set to 'DebugKit'.
@@ -845,7 +845,7 @@ $routes->plugin('DebugKit', function (RouteBuilder $routes) {
When creating plugin scopes, you can customize the path element used with the
`path` option:
-``` php
+```php
$routes->plugin('DebugKit', ['path' => '/debugger'], function (RouteBuilder $routes) {
// Routes connected here are prefixed with '/debugger' and
// have the plugin route element set to 'DebugKit'.
@@ -855,7 +855,7 @@ $routes->plugin('DebugKit', ['path' => '/debugger'], function (RouteBuilder $rou
When using scopes you can nest plugin scopes within prefix scopes:
-``` php
+```php
$routes->prefix('Admin', function (RouteBuilder $routes) {
$routes->plugin('DebugKit', function (RouteBuilder $routes) {
$routes->connect('/{controller}');
@@ -872,7 +872,7 @@ It would have the `prefix`, and `plugin` route elements set. The
You can create links that point to a plugin, by adding the plugin key to your
URL array:
-``` php
+```php
echo $this->Html->link(
'New todo',
['plugin' => 'Todo', 'controller' => 'TodoItems', 'action' => 'create'],
@@ -882,7 +882,7 @@ echo $this->Html->link(
Conversely if the active request is a plugin request and you want to create
a link that has no plugin you can do the following:
-``` php
+```php
echo $this->Html->link(
'New todo',
['plugin' => null, 'controller' => 'Users', 'action' => 'profile'],
@@ -903,7 +903,7 @@ For example, if we had a `ToDo` plugin, with a `TodoItems` controller, and a
`showItems()` action, it could be accessed at `/to-do/todo-items/show-items`
with the following router connection:
-``` php
+```php
use Cake\Routing\Route\DashedRoute;
$routes->plugin('ToDo', ['path' => 'to-do'], function (RouteBuilder $routes) {
@@ -915,7 +915,7 @@ $routes->plugin('ToDo', ['path' => 'to-do'], function (RouteBuilder $routes) {
Routes can match specific HTTP methods using the HTTP verb helper methods:
-``` php
+```php
$routes->scope('/', function (RouteBuilder $routes) {
// This route only matches on POST requests.
$routes->post(
@@ -939,7 +939,7 @@ parameter is a routing key, it participates in both URL parsing and URL
generation. To generate URLs for method specific routes you'll need to include
the `_method` key when generating the URL:
-``` php
+```php
$url = Router::url([
'controller' => 'Reviews',
'action' => 'start',
@@ -952,7 +952,7 @@ $url = Router::url([
Routes can use the `_host` option to only match specific hosts. You can use
the `*.` wildcard to match any subdomain:
-``` php
+```php
$routes->scope('/', function (RouteBuilder $routes) {
// This route only matches on http://images.example.com
$routes->connect(
@@ -973,7 +973,7 @@ specifies an exact domain, that domain will be included in the generated URL.
However, if you use a wildcard, then you will need to provide the `_host`
parameter when generating URLs:
-``` php
+```php
// If you have this route
$routes->connect(
'/images/old-logo.png',
@@ -997,7 +997,7 @@ echo Router::url([
To handle different file extensions in your URLs, you can define the extensions
using the `Cake\Routing\RouteBuilder::setExtensions()` method:
-``` php
+```php
$routes->scope('/', function (RouteBuilder $routes) {
$routes->setExtensions(['json', 'xml']);
});
@@ -1019,7 +1019,7 @@ By using extensions, you tell the router to remove any matching file extensions
from the URL, and then parse what remains. If you want to create a URL such as
/page/title-of-page.html you would create your route using:
-``` php
+```php
$routes->scope('/page', function (RouteBuilder $routes) {
$routes->setExtensions(['json', 'xml', 'html']);
$routes->connect(
@@ -1031,7 +1031,7 @@ $routes->scope('/page', function (RouteBuilder $routes) {
Then to create links which map back to the routes simply use:
-``` php
+```php
$this->Html->link(
'Link title',
['controller' => 'Pages', 'action' => 'view', 'title' => 'super-article', '_ext' => 'html'],
@@ -1052,7 +1052,7 @@ how/where it is being applied.
Before middleware can be applied to a scope, it needs to be
registered into the route collection:
-``` php
+```php
// in config/routes.php
use Cake\Http\Middleware\CsrfProtectionMiddleware;
use Cake\Http\Middleware\EncryptedCookieMiddleware;
@@ -1064,7 +1064,7 @@ $routes->registerMiddleware('cookies', new EncryptedCookieMiddleware());
Once registered, scoped middleware can be applied to specific
scopes:
-``` php
+```php
$routes->scope('/cms', function (RouteBuilder $routes) {
// Enable CSRF & cookies middleware
$routes->applyMiddleware('csrf', 'cookies');
@@ -1075,7 +1075,7 @@ $routes->scope('/cms', function (RouteBuilder $routes) {
In situations where you have nested scopes, inner scopes will inherit the
middleware applied in the containing scope:
-``` php
+```php
$routes->scope('/api', function (RouteBuilder $routes) {
$routes->applyMiddleware('ratelimit', 'auth.api');
$routes->scope('/v1', function (RouteBuilder $routes) {
@@ -1089,7 +1089,7 @@ In the above example, the routes defined in `/v1` will have 'ratelimit',
'auth.api', and 'v1compat' middleware applied. If you re-open a scope, the
middleware applied to routes in each scope will be isolated:
-``` php
+```php
$routes->scope('/blog', function (RouteBuilder $routes) {
$routes->applyMiddleware('auth');
// Connect the authenticated actions for the blog here.
@@ -1109,7 +1109,7 @@ To help keep your route code `DRY (Do not Repeat Yourself)` middleware can
be combined into groups. Once combined groups can be applied like middleware
can:
-``` php
+```php
$routes->registerMiddleware('cookie', new EncryptedCookieMiddleware());
$routes->registerMiddleware('auth', new AuthenticationMiddleware());
$routes->registerMiddleware('csrf', new CsrfProtectionMiddleware());
@@ -1127,7 +1127,7 @@ Router helps generate RESTful routes for your controllers. RESTful routes are
helpful when you are creating API endpoints for your application. If we wanted
to allow REST access to a recipe controller, we'd do something like this:
-``` php
+```php
// In config/routes.php...
$routes->scope('/', function (RouteBuilder $routes) {
@@ -1172,7 +1172,7 @@ Once you have connected resources in a scope, you can connect routes for
sub-resources as well. Sub-resource routes will be prepended by the original
resource name and a id parameter. For example:
-``` php
+```php
$routes->scope('/api', function (RouteBuilder $routes) {
$routes->resources('Articles', function (RouteBuilder $routes) {
$routes->resources('Comments');
@@ -1183,14 +1183,14 @@ $routes->scope('/api', function (RouteBuilder $routes) {
Will generate resource routes for both `articles` and `comments`. The
comments routes will look like:
-``` text
+```text
/api/articles/{article_id}/comments
/api/articles/{article_id}/comments/{id}
```
You can get the `article_id` in `CommentsController` by:
-``` php
+```php
$this->request->getParam('article_id');
```
@@ -1198,7 +1198,7 @@ By default, resource routes map to the same prefix as the containing scope. If
you have both nested and non-nested resource controllers you can use a different
controller in each context by using prefixes:
-``` php
+```php
$routes->scope('/api', function (RouteBuilder $routes) {
$routes->resources('Articles', function (RouteBuilder $routes) {
$routes->resources('Comments', ['prefix' => 'Articles']);
@@ -1220,7 +1220,7 @@ compatible with [Prefix Routing](#prefix-routing).
By default, CakePHP will connect 6 routes for each resource. If you'd like to
only connect specific resource routes you can use the `only` option:
-``` php
+```php
$routes->resources('Articles', [
'only' => ['index', 'view'],
]);
@@ -1245,7 +1245,7 @@ You may need to change the controller action names that are used when connecting
routes. For example, if your `edit()` action is called `put()` you can
use the `actions` key to rename the actions used:
-``` php
+```php
$routes->resources('Articles', [
'actions' => ['update' => 'put', 'create' => 'add'],
]);
@@ -1258,7 +1258,7 @@ instead of `create()`.
You can map additional resource methods using the `map` option:
-``` php
+```php
$routes->resources('Articles', [
'map' => [
'deleteAll' => [
@@ -1275,7 +1275,7 @@ In addition to the default routes, this would also connect a route for
can use the 'path' key inside the resource definition to customize the path
name:
-``` php
+```php
$routes->resources('Articles', [
'map' => [
'updateAll' => [
@@ -1296,7 +1296,7 @@ the 'only' list.
Resource routes can be connected to controllers in routing prefixes by
connecting routes within a prefixed scope or by using the `prefix` option:
-``` php
+```php
$routes->resources('Articles', [
'prefix' => 'Api',
]);
@@ -1309,7 +1309,7 @@ $routes->resources('Articles', [
You can provide `connectOptions` key in the `$options` array for
`resources()` to provide custom setting used by `connect()`:
-``` php
+```php
$routes->scope('/', function (RouteBuilder $routes) {
$routes->resources('Books', [
'connectOptions' => [
@@ -1327,7 +1327,7 @@ would be **/blog-posts**.
You can specify an alternative inflection type using the `inflect` option:
-``` php
+```php
$routes->scope('/', function (RouteBuilder $routes) {
$routes->resources('BlogPosts', [
'inflect' => 'underscore', // Will use ``Inflector::underscore()``
@@ -1342,7 +1342,7 @@ The above will generate URLs styled like: **/blog_posts**.
By default, resource routes use an inflected form of the resource name for the
URL segment. You can set a custom URL segment with the `path` option:
-``` php
+```php
$routes->scope('/', function (RouteBuilder $routes) {
$routes->resources('BlogPosts', ['path' => 'posts']);
});
@@ -1366,7 +1366,7 @@ the passed arguments as well.
If you were to visit the previously mentioned URL, and you
had a controller action that looked like:
-``` php
+```php
class CalendarsController extends AppController
{
public function view($arg1, $arg2)
@@ -1378,7 +1378,7 @@ class CalendarsController extends AppController
You would get the following output:
-``` text
+```text
Array
(
[0] => recent
@@ -1390,13 +1390,13 @@ This same data is also available at `$this->request->getParam('pass')` in your
controllers, views, and helpers. The values in the pass array are numerically
indexed based on the order they appear in the called URL:
-``` php
+```php
debug($this->request->getParam('pass'));
```
Either of the above would output:
-``` text
+```text
Array
(
[0] => recent
@@ -1407,7 +1407,7 @@ Array
When generating URLs, using a `routing array` you add passed
arguments as values without string keys in the array:
-``` php
+```php
['controller' => 'Articles', 'action' => 'view', 5]
```
@@ -1424,7 +1424,7 @@ allow you to change your URL structure without having to modify all your code.
If you create URLs using strings like:
-``` php
+```php
$this->Html->link('View', '/articles/view/' . $id);
```
@@ -1432,7 +1432,7 @@ And then later decide that `/articles` should really be called
'posts' instead, you would have to go through your entire
application renaming URLs. However, if you defined your link like:
-``` php
+```php
//`link()` uses Router::url() internally and accepts a routing array
$this->Html->link(
@@ -1443,7 +1443,7 @@ $this->Html->link(
or:
-``` php
+```php
//'Router::reverse()' operates on the request parameters array
//and will produce a url string, valid input for `link()`
@@ -1465,7 +1465,7 @@ situations where the array elements required are fixed or easily deduced.
It will provide reverse routing when the destination url is well defined:
-``` php
+```php
$this->Html->link(
'View',
['controller' => 'Articles', 'action' => 'view', $id],
@@ -1475,7 +1475,7 @@ $this->Html->link(
It is also useful when the destination is unknown but follows a well
defined pattern:
-``` php
+```php
$this->Html->link(
'View',
['controller' => $controller, 'action' => 'view', $id],
@@ -1487,7 +1487,7 @@ Elements with numeric keys are treated as [Passed Arguments](#passed-arguments).
When using routing arrays, you can define both query string parameters and
document fragments using special keys:
-``` php
+```php
$routes->url([
'controller' => 'Articles',
'action' => 'index',
@@ -1540,7 +1540,7 @@ or draft only.
To keep the code DRY, it would be best to include the links through
an element:
-``` php
+```php
// element/filter_published.php
$params = $this->getRequest()->getAttribute('params');
@@ -1570,7 +1570,7 @@ reverse routing methods is in the way they include pass parameters.
Routing arrays include pass parameters as un-keyed values in the array:
-``` php
+```php
$url = [
'controller' => 'Articles',
'action' => 'View',
@@ -1581,7 +1581,7 @@ $url = [
Request parameters include pass parameters on the 'pass' key of the array:
-``` php
+```php
$url = [
'controller' => 'Articles',
'action' => 'View',
@@ -1600,7 +1600,7 @@ a routing array or vice versa.
The `Asset` class provides methods for generating URLs to your application's
css, javascript, images and other static asset files:
-``` php
+```php
use Cake\Routing\Asset;
// Generate a URL to APP/webroot/js/app.js
@@ -1627,7 +1627,7 @@ The above methods also accept an array of options as their second parameter:
when debug is true. Set to `'force'` to always enable timestamping
regardless of debug value.
-``` php
+```php
// Generates https://example.com/img/logo.png
$img = Asset::url('logo.png', ['fullBase' => true]);
@@ -1638,7 +1638,7 @@ $img = Asset::url('logo.png', ['timestamp' => true]);
To generate asset URLs for files in plugins use `plugin syntax`:
-``` php
+```php
// Generates `/debug_kit/img/cake.png`
$img = Asset::imageUrl('DebugKit.cake.png');
```
@@ -1654,7 +1654,7 @@ Redirection routes are different from normal routes as they perform an actual
header redirection if a match is found. The redirection can occur to
a destination within your application or an outside location:
-``` php
+```php
$routes->scope('/', function (RouteBuilder $routes) {
$routes->redirect(
'/home/*',
@@ -1672,7 +1672,7 @@ you to use other routes to define where a URL string should be
redirected to. You can redirect to external locations using
string URLs as the destination:
-``` php
+```php
$routes->scope('/', function (RouteBuilder $routes) {
$routes->redirect('/articles/*', 'http://google.com', ['status' => 302]);
});
@@ -1688,7 +1688,7 @@ Entity routing allows you to use an entity, an array or object implement
routes more easily, and generate URLs with less code. For example, if you start
off with a route that looks like:
-``` php
+```php
$routes->get(
'/view/{id}',
['controller' => 'Articles', 'action' => 'view'],
@@ -1698,7 +1698,7 @@ $routes->get(
You can generate URLs to this route using:
-``` php
+```php
// $article is an entity in the local scope.
Router::url(['_name' => 'articles:view', 'id' => $article->id]);
```
@@ -1709,7 +1709,7 @@ the `articles:view` route, which could take some time. If we use entity routes
we pass the entire article entity into URL generation allowing us to skip any
rework when URLs require more parameters:
-``` php
+```php
use Cake\Routing\Route\EntityRoute;
// Create entity routes for the rest of this scope.
@@ -1725,7 +1725,7 @@ $routes->get(
Now we can generate URLs using the `_entity` key:
-``` php
+```php
Router::url(['_name' => 'articles:view', '_entity' => $article]);
```
@@ -1738,7 +1738,7 @@ CakePHP provides a `RedirectTrait` that can be used to create custom redirect
route classes. If you need redirect behavior with custom logic, you can create
a route class that uses this trait:
-``` php
+```php
namespace App\Routing\Route;
use Cake\Routing\Route\RedirectTrait;
@@ -1775,7 +1775,7 @@ returned.
You can use a custom route class when making a route by using the `routeClass`
option:
-``` php
+```php
$routes->connect(
'/{slug}',
['controller' => 'Articles', 'action' => 'view'],
@@ -1805,7 +1805,7 @@ default `Route`, you can do so by calling `RouteBuilder::setRouteClass()`
before setting up any routes and avoid having to specify the `routeClass`
option for each route. For example using:
-``` php
+```php
use Cake\Routing\Route\DashedRoute;
$routes->setRouteClass(DashedRoute::class);
@@ -1824,7 +1824,7 @@ provided the class returned by `RouteBuilder::setRouteClass()` is used.
Calling fallbacks like so:
-``` php
+```php
use Cake\Routing\Route\DashedRoute;
$routes->fallbacks(DashedRoute::class);
@@ -1832,7 +1832,7 @@ $routes->fallbacks(DashedRoute::class);
Is equivalent to the following explicit calls:
-``` php
+```php
use Cake\Routing\Route\DashedRoute;
$routes->connect('/{controller}', ['action' => 'index'], ['routeClass' => DashedRoute::class]);
@@ -1867,7 +1867,7 @@ The URL filter function should *always* return the parameters even if unmodified
URL filters allow you to implement features like persistent parameters:
-``` php
+```php
Router::addUrlFilter(function (array $params, ServerRequest $request) {
if ($request->getParam('lang') && !isset($params['lang'])) {
$params['lang'] = $request->getParam('lang');
@@ -1882,7 +1882,7 @@ Filter functions are applied in the order they are connected.
Another use case is changing a certain route on runtime (plugin routes for
example):
-``` php
+```php
Router::addUrlFilter(function (array $params, ServerRequest $request) {
if (empty($params['plugin']) || $params['plugin'] !== 'MyPlugin' || empty($params['controller'])) {
return $params;
@@ -1900,13 +1900,13 @@ Router::addUrlFilter(function (array $params, ServerRequest $request) {
This will alter the following route:
-``` php
+```php
Router::url(['plugin' => 'MyPlugin', 'controller' => 'Languages', 'action' => 'view', 'es']);
```
into this:
-``` php
+```php
Router::url(['plugin' => 'MyPlugin', 'controller' => 'Locations', 'action' => 'index', 'language' => 'es']);
```
diff --git a/docs/en/development/sessions.md b/docs/en/development/sessions.md
index 0a70ec1933..08c4104a1e 100644
--- a/docs/en/development/sessions.md
+++ b/docs/en/development/sessions.md
@@ -40,7 +40,7 @@ protocols, then you might have problems with sessions being lost. If you need
access to the session on both SSL and non-SSL domains you will want to disable
this:
-``` php
+```php
Configure::write('Session', [
'defaults' => 'php',
'ini' => [
@@ -53,7 +53,7 @@ CakePHP also sets the [SameSite](https://owasp.org/www-community/SameSite) attri
by default for session cookies, which helps protect against CSRF attacks.
You can change the default value by setting `session.cookie_samesite` php.ini config:
-``` php
+```php
Configure::write('Session', [
'defaults' => 'php',
'ini' => [
@@ -66,7 +66,7 @@ The session cookie path defaults to app's base path. To change this you can use
the `session.cookie_path` ini value. For example if you want your session to
persist across all subdomains you can do:
-``` php
+```php
Configure::write('Session', [
'defaults' => 'php',
'ini' => [
@@ -81,7 +81,7 @@ closed, regardless of the configured `Session.timeout` value. The cookie
timeout is controlled by the `session.cookie_lifetime` ini value and can be
configured using:
-``` php
+```php
Configure::write('Session', [
'defaults' => 'php',
'ini' => [
@@ -109,7 +109,7 @@ custom solution. To use defaults, simply set the 'defaults' key to the name of
the default you want to use. You can then override any sub setting by declaring
it in your Session config:
-``` php
+```php
Configure::write('Session', [
'defaults' => 'php',
]);
@@ -118,7 +118,7 @@ Configure::write('Session', [
The above will use the built-in 'php' session configuration. You could augment
part or all of it by doing the following:
-``` php
+```php
Configure::write('Session', [
'defaults' => 'php',
'cookie' => 'my_app',
@@ -148,7 +148,7 @@ Cache and Database session handlers use this method for saving sessions.
Additional settings for the handler should be placed inside the handler array.
You can then read those values out from inside your handler:
-``` php
+```php
'Session' => [
'handler' => [
'engine' => 'DatabaseSession',
@@ -169,7 +169,7 @@ from inside plugins. By setting the engine to `MyPlugin.PluginSessionHandler`.
If you need to use a database to store your session data, configure as follows:
-``` php
+```php
'Session' => [
'defaults' => 'database',
]
@@ -177,7 +177,7 @@ If you need to use a database to store your session data, configure as follows:
This configuration requires a database table, having this schema:
-``` sql
+```sql
CREATE TABLE `sessions` (
`id` char(40) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
`created` datetime DEFAULT CURRENT_TIMESTAMP, -- Optional
@@ -192,7 +192,7 @@ You can find a copy of the schema for the sessions table in the [application ske
You can also use your own `Table` class to handle the saving of the sessions:
-``` php
+```php
'Session' => [
'defaults' => 'database',
'handler' => [
@@ -217,7 +217,7 @@ start to expire as records are evicted.
To use Cache based sessions you can configure you Session config like:
-``` php
+```php
Configure::write('Session', [
'defaults' => 'cache',
'handler' => [
@@ -234,7 +234,7 @@ configuration to use. The default cache configuration is `'default'`.
The app skeleton comes preconfigured with a session config like this:
-``` php
+```php
'Session' => [
'defaults' => 'php',
],
@@ -265,7 +265,7 @@ configurations, as well as custom ones. The `ini` key in the session settings,
allows you to specify individual configuration values. For example you can use
it to control settings like `session.gc_divisor`:
-``` php
+```php
Configure::write('Session', [
'defaults' => 'php',
'ini' => [
@@ -288,7 +288,7 @@ First we'll need to create our custom class and put it in
**src/Http/Session/ComboSession.php**. The class should look
something like:
-``` php
+```php
namespace App\Http\Session;
use Cake\Cache\Cache;
@@ -346,7 +346,7 @@ a `Cake\Cache\Cache` operation. This lets us fetch sessions from
the fast cache, and not have to worry about what happens when we fill the cache.
In **config/app.php** make the session block look like:
-``` php
+```php
'Session' => [
'defaults' => 'database',
'handler' => [
@@ -381,7 +381,7 @@ This means the session is accessible from:
A basic example of session usage in controllers, views and cells would be:
-``` php
+```php
$name = $this->request->getSession()->read('User.name');
// If you are accessing the session multiple times,
@@ -400,7 +400,7 @@ In components, use `$this->getController()->getRequest()`.
You can read values from the session using `Hash::extract()`
compatible syntax:
-``` php
+```php
$session->read('Config.language', 'en');
```
@@ -408,7 +408,7 @@ $session->read('Config.language', 'en');
The same as convenience wrapper around non-nullable return value:
-``` php
+```php
$session->readOrFail('Config.language');
```
@@ -419,13 +419,13 @@ for the existence in code itself.
`$key` should be the dot separated path you wish to write `$value` to:
-``` php
+```php
$session->write('Config.language', 'en');
```
You may also specify one or multiple hashes like so:
-``` php
+```php
$session->write([
'Config.theme' => 'blue',
'Config.language' => 'en',
@@ -436,7 +436,7 @@ $session->write([
When you need to delete data from the session, you can use `delete()`:
-``` php
+```php
$session->delete('Some.value');
```
@@ -449,7 +449,7 @@ $session->delete('Some.value');
When you need to read and delete data from the session, you can use
`consume()`:
-``` php
+```php
$session->consume('Some.value');
```
@@ -457,7 +457,7 @@ $session->consume('Some.value');
If you want to see if data exists in the session, you can use `check()`:
-``` php
+```php
if ($session->check('Config.language')) {
// Config.language exists and is not null.
}
@@ -470,7 +470,7 @@ if ($session->check('Config.language')) {
Destroying the session is useful when users log out. To destroy a session, use
the `destroy()` method:
-``` php
+```php
$session->destroy();
```
@@ -485,7 +485,7 @@ While the `Authentication Plugin` automatically renews the session id when users
logout, you may need to rotate the session id's manually. To do this use the
`renew()` method:
-``` php
+```php
$session->renew();
```
diff --git a/docs/en/development/testing.md b/docs/en/development/testing.md
index 7062cb987f..4acde5c865 100644
--- a/docs/en/development/testing.md
+++ b/docs/en/development/testing.md
@@ -23,7 +23,7 @@ through using either a [PHAR package](https://phpunit.de/#download) or
To install PHPUnit with Composer:
-``` bash
+```bash
php composer.phar require --dev phpunit/phpunit:"^11.5.3"
```
@@ -32,7 +32,7 @@ This will add the dependency to the `require-dev` section of your
You can now run PHPUnit using:
-``` bash
+```bash
vendor/bin/phpunit
```
@@ -41,7 +41,7 @@ vendor/bin/phpunit
After you have downloaded the **phpunit.phar** file, you can use it to run your
tests:
-``` bash
+```bash
php phpunit.phar
```
@@ -65,7 +65,7 @@ any tests. Before running any tests you should be sure to add a `test`
datasource configuration to **config/app_local.php**. This configuration is used by
CakePHP for fixture tables and data:
-``` php
+```php
'Datasources' => [
'test' => [
'datasource' => 'Cake\Database\Driver\Mysql',
@@ -88,7 +88,7 @@ After installing PHPUnit and setting up your `test` datasource configuration
you can make sure you're ready to write and run your own tests by running your
application's tests:
-``` bash
+```bash
# For phpunit.phar
php phpunit.phar
@@ -101,7 +101,7 @@ To run a specific test you can supply the path to the test as a parameter to
PHPUnit. For example, if you had a test case for ArticlesTable class you could
run it with:
-``` bash
+```bash
vendor/bin/phpunit tests/TestCase/Model/Table/ArticlesTableTest
```
@@ -134,7 +134,7 @@ In the following example, we'll create a test case for a very simple helper
method. The helper we're going to test will be formatting progress bar HTML.
Our helper looks like:
-``` php
+```php
namespace App\View\Helper;
use Cake\View\Helper;
@@ -158,7 +158,7 @@ a simple test case. After creating and saving our helper, we'll create the test
case file in **tests/TestCase/View/Helper/ProgressHelperTest.php**. In that file
we'll start with the following:
-``` php
+```php
namespace App\Test\TestCase\View\Helper;
use App\View\Helper\ProgressHelper;
@@ -183,7 +183,7 @@ in a test case class. Setup methods should initialize the objects needed for the
test, and do any configuration needed. In our setup method we'll add the
following:
-``` php
+```php
public function setUp(): void
{
parent::setUp();
@@ -200,7 +200,7 @@ does a number things like backing up the values in
Next, we'll fill out the test method. We'll use some assertions to ensure that
our code creates the output we expect:
-``` php
+```php
public function testBar(): void
{
$result = $this->Progress->bar(90);
@@ -239,7 +239,7 @@ any changes to help ensure you haven't broken anything.
By using `phpunit` you can run your application tests. To run your
application's tests you can simply run:
-``` bash
+```bash
vendor/bin/phpunit
php phpunit.phar
@@ -249,7 +249,7 @@ If you have cloned the [CakePHP source from GitHub](https://github.com/cakephp/c
and wish to run CakePHP's unit-tests don't forget to execute the following `Composer`
command prior to running `phpunit` so that any dependencies are installed:
-``` bash
+```bash
composer install
```
@@ -257,7 +257,7 @@ From your application's root directory. To run tests for a plugin that is part
of your application source, first `cd` into the plugin directory, then use
`phpunit` command that matches how you installed phpunit:
-``` bash
+```bash
cd plugins
../vendor/bin/phpunit
@@ -268,7 +268,7 @@ php ../phpunit.phar
To run tests on a standalone plugin, you should first install the project in
a separate directory and install its dependencies:
-``` bash
+```bash
git clone git://github.com/cakephp/debug_kit.git
cd debug_kit
php ~/composer.phar install
@@ -281,7 +281,7 @@ When you have larger test cases, you will often want to run a subset of the test
methods when you are trying to work on a single failing case. With the
CLI runner you can use an option to filter test methods:
-``` bash
+```bash
phpunit --filter testSave tests/TestCase/Model/Table/ArticlesTableTest
```
@@ -295,7 +295,7 @@ built-in code coverage tools. PHPUnit will generate a set of static HTML files
containing the coverage results. You can generate coverage for a test case by
doing the following:
-``` bash
+```bash
phpunit --coverage-html webroot/coverage tests/TestCase/Model/Table/ArticlesTableTest
```
@@ -306,7 +306,7 @@ should be able to view the results by going to
You can also use `phpdbg` to generate coverage instead of xdebug.
`phpdbg` is generally faster at generating coverage:
-``` bash
+```bash
phpdbg -qrr phpunit --coverage-html webroot/coverage tests/TestCase/Model/Table/ArticlesTableTest
```
@@ -318,7 +318,7 @@ running tests for each of the plugins that compose your application by adding
additional `` sections to your application's **phpunit.xml.dist**
file:
-``` xml
+```xml
tests/TestCase/
@@ -338,7 +338,7 @@ If you are using `` to use fixtures from plugins that you have
installed with composer, the plugin's `composer.json` file should add the
fixture namespace to the autoload section. Example:
-``` json
+```json
"autoload-dev": {
"psr-4": {
"PluginName\\Test\\Fixture\\": "tests/Fixture/"
@@ -403,7 +403,7 @@ will attempt to use 'test_replica'.
Before you can use fixtures you should double check that your `phpunit.xml`
contains the fixture extension:
-``` xml
+```xml
@@ -428,7 +428,7 @@ If you use CakePHP's [migrations plugin](https://book.cakephp.org/migrations) to
application's schema, you can reuse those migrations to generate your test
database schema as well:
-``` php
+```php
// in tests/bootstrap.php
use Migrations\TestSuite\Migrator;
@@ -446,7 +446,7 @@ $migrator->run(['plugin' => 'Documents', 'connection' => 'test_docs']);
If you need to run multiple sets of migrations, those can be run as follows:
-``` php
+```php
$migrator->runMany([
// Run app migrations on test connection.
['connection' => 'test'],
@@ -476,7 +476,7 @@ time-consuming to maintain.
Each table can define `columns`, `constraints`, and `indexes`.
An example table would be:
-``` php
+```php
return [
'articles' => [
'columns' => [
@@ -517,7 +517,7 @@ created incrementally and you must take care to ensure that tables are created
before foreign key references are made. Once you have created your schema file
you can load it in your `tests/bootstrap.php` with:
-``` php
+```php
$loader = new SchemaLoader();
$loader->loadInternalFile($pathToSchemaFile);
```
@@ -526,7 +526,7 @@ $loader->loadInternalFile($pathToSchemaFile);
To load a SQL dump file you can use the following:
-``` php
+```php
// in tests/bootstrap.php
use Cake\TestSuite\Fixture\SchemaLoader;
@@ -544,7 +544,7 @@ beginning of each test. Let's create our first fixture, that will be
used to test our own Article model. Create a file named **ArticlesFixture.php**
in your **tests/Fixture** directory, with the following content:
-``` php
+```php
namespace App\Test\Fixture;
use Cake\TestSuite\Fixture\TestFixture;
@@ -615,7 +615,7 @@ As you evolve your schema your fixture records may accumulate unused or
unsupported fields. You can enable `strictFields` on a fixture to have errors
raised when a record contains fields that are not defined in the schema:
-``` php
+```php
namespace App\Test\Fixture;
use Cake\TestSuite\Fixture\TestFixture;
@@ -640,7 +640,7 @@ enforce stricter maintenance of test data.
To use functions or other dynamic data in your fixture records you can define
your records in the fixture's `init()` method:
-``` php
+```php
namespace App\Test\Fixture;
use Cake\TestSuite\Fixture\TestFixture;
@@ -673,7 +673,7 @@ In each test case you should load the fixtures you will need. You should load a
fixture for every model that will have a query run against it. To load fixtures
you define the `$fixtures` property in your model:
-``` php
+```php
class ArticlesTest extends TestCase
{
protected array $fixtures =['app.Articles', 'app.Comments'];
@@ -683,7 +683,7 @@ class ArticlesTest extends TestCase
As of 4.1.0 you can use `getFixtures()` to define your fixture list with
a method:
-``` php
+```php
public function getFixtures(): array
{
return [
@@ -696,7 +696,7 @@ public function getFixtures(): array
The above will load the Article and Comment fixtures from the application's
Fixture directory. You can also load fixtures from CakePHP core, or plugins:
-``` php
+```php
class ArticlesTest extends TestCase
{
protected array $fixtures =[
@@ -715,7 +715,7 @@ easier to organize your fixtures if you have a larger application. To load
fixtures in subdirectories, simply include the subdirectory name in the fixture
name:
-``` php
+```php
class ArticlesTest extends CakeTestCase
{
protected array $fixtures =['app.Blog/Articles', 'app.Blog/Comments'];
@@ -727,7 +727,7 @@ In the above example, both fixtures would be loaded from
You can also directly include fixtures by FQCN:
-``` php
+```php
public function getFixtures(): array
{
return [
@@ -750,7 +750,7 @@ data, as auto-increment values are not reset before each test.
The fixture state management strategy can be defined within the test case:
-``` php
+```php
use Cake\TestSuite\TestCase;
use Cake\TestSuite\Fixture\FixtureStrategyInterface;
use Cake\TestSuite\Fixture\TransactionStrategy;
@@ -770,7 +770,7 @@ class ArticlesTableTest extends TestCase
To switch out the general default strategy, use Configure key `TestSuite.fixtureStrategy` in your `app.php`:
-``` php
+```php
'TestSuite' => [
'fixtureStrategy' => \Cake\TestSuite\Fixture\TransactionStrategy::class,
],
@@ -800,13 +800,13 @@ Unnecessary interaction with the database will slow down your tests as well as
your application. You can create test fixtures without persisting them which can
be useful for testing methods without DB interaction:
-``` php
+```php
$article = ArticleFactory::make()->getEntity();
```
In order to persist:
-``` php
+```php
$article = ArticleFactory::make()->persist();
```
@@ -814,7 +814,7 @@ The factories help creating associated fixtures too.
Assuming that articles belongs to many authors, we can now, for example,
create 5 articles each with 2 authors:
-``` php
+```php
$articles = ArticleFactory::make(5)->with('Authors', 2)->getEntities();
```
@@ -829,7 +829,7 @@ routes and resolving URLs, you will need to load routes. During
the `setUp()` of a class or during individual test methods you can use
`loadRoutes()` to ensure your application routes are loaded:
-``` php
+```php
public function setUp(): void
{
parent::setUp();
@@ -849,7 +849,7 @@ when developing plugins, or applications that are extensible.
Just like loading existing application routes, this can be done during `setup()`
of a test method, and/or in the individual test methods themselves:
-``` php
+```php
use Cake\Routing\Route\DashedRoute;
use Cake\Routing\RouteBuilder;
use Cake\Routing\Router;
@@ -887,7 +887,7 @@ may already exist, or are yet to be created in the environment.
If your application would dynamically load plugins, you can use
`loadPlugins()` to load one or more plugins during tests:
-``` php
+```php
public function testMethodUsingPluginResources()
{
$this->loadPlugins(['Company/Cms']);
@@ -900,7 +900,7 @@ public function testMethodUsingPluginResources()
Let's say we already have our Articles Table class defined in
**src/Model/Table/ArticlesTable.php**, and it looks like:
-``` php
+```php
namespace App\Model\Table;
use Cake\ORM\Table;
@@ -923,7 +923,7 @@ We now want to set up a test that will test this table class. Let's now create
a file named **ArticlesTableTest.php** in your **tests/TestCase/Model/Table** directory,
with the following contents:
-``` php
+```php
namespace App\Test\TestCase\Model\Table;
use App\Model\Table\ArticlesTable;
@@ -945,7 +945,7 @@ Let's now add a method to test the function `published()` in the Articles
table. Edit the file **tests/TestCase/Model/Table/ArticlesTableTest.php** so it
now looks like this:
-``` php
+```php
namespace App\Test\TestCase\Model\Table;
use App\Model\Table\ArticlesTable;
@@ -987,7 +987,7 @@ section for more information on how to run your test case.
Using the fixture factories, the test would now look like this:
-``` php
+```php
namespace App\Test\TestCase\Model\Table;
use App\Test\Factory\ArticleFactory;
@@ -1025,7 +1025,7 @@ There will be times you'll want to mock methods on models when testing them. You
should use `getMockForModel` to create testing mocks of table classes. It
avoids issues with reflected properties that normal mocks have:
-``` php
+```php
public function testSendingEmails(): void
{
$model = $this->getMockForModel('EmailVerification', ['send']);
@@ -1039,7 +1039,7 @@ public function testSendingEmails(): void
In your `tearDown()` method be sure to remove the mock with:
-``` php
+```php
$this->getTableLocator()->clear();
```
@@ -1062,7 +1062,7 @@ more high level test of your application and all its working parts.
Say you have a typical ArticlesController, and its corresponding model. The
controller code looks like:
-``` php
+```php
namespace App\Controller;
use App\Controller\AppController;
@@ -1095,7 +1095,7 @@ class ArticlesController extends AppController
Create a file named **ArticlesControllerTest.php** in your
**tests/TestCase/Controller** directory and put the following inside:
-``` php
+```php
namespace App\Test\TestCase\Controller;
use Cake\TestSuite\IntegrationTestTrait;
@@ -1174,7 +1174,7 @@ ensure your request had the correct side-effects.
The `IntegrationTestTrait` trait comes with a number of helpers to
to configure the requests you will send to your application under test:
-``` php
+```php
// Set cookies
$this->cookie('name', 'Uncle Bob');
@@ -1204,7 +1204,7 @@ When testing actions protected by either `CsrfProtectionMiddleware` or `FormProt
can enable automatic token generation to ensure your tests won't fail due to
token mismatches:
-``` php
+```php
public function testAdd(): void
{
$this->enableCsrfToken();
@@ -1218,7 +1218,7 @@ It is also important to enable debug in tests that use tokens to prevent the
environment. When testing with other methods like `requireSecure()` you
can use `configRequest()` to set the correct environment variables:
-``` php
+```php
// Fake out SSL connections.
$this->configRequest([
'environment' => ['HTTPS' => 'on'],
@@ -1228,7 +1228,7 @@ $this->configRequest([
If your action requires unlocked fields you can declare them with
`setUnlockedFields()`:
-``` php
+```php
$this->setUnlockedFields(['dynamic_field']);
```
@@ -1242,7 +1242,7 @@ enable integration testing of your Application.
You can customize the application class name used, and the constructor
arguments, by using the `configApplication()` method:
-``` php
+```php
public function setUp(): void
{
$this->configApplication('App\App', [CONFIG]);
@@ -1260,7 +1260,7 @@ If you use the [Encrypted Cookie Middleware](../controllers/middleware#encrypted
application, there are helper methods for setting encrypted cookies in your
test cases:
-``` php
+```php
// Set a cookie using AES and the default key.
$this->cookieEncrypted('my_cookie', 'Some secret values');
@@ -1276,7 +1276,7 @@ If you want to assert the presence of flash messages in the session and not the
rendered HTML, you can use `enableRetainFlashMessages()` in your tests to
retain flash messages in the session so you can write assertions:
-``` php
+```php
// Enable retention of flash messages instead of consuming them.
$this->enableRetainFlashMessages();
$this->get('/articles/delete/9999');
@@ -1315,7 +1315,7 @@ JSON is a friendly and common format to use when building a web service.
Testing the endpoints of your web service is very simple with CakePHP. Let us
begin with a simple example controller that responds in JSON:
-``` php
+```php
use Cake\View\JsonView;
class MarkersController extends AppController
@@ -1337,7 +1337,7 @@ class MarkersController extends AppController
Now we create the file **tests/TestCase/Controller/MarkersControllerTest.php**
and make sure our web service is returning the proper response:
-``` php
+```php
class MarkersControllerTest extends TestCase
{
use IntegrationTestTrait;
@@ -1387,7 +1387,7 @@ Let's assume articles have a teaser image, and a `Articles hasMany Attachments`
association, the form would look like something like this accordingly, where one
image file, and multiple attachments/files would be accepted:
-``` php
+```php
= $this->Form->create($article, ['type' => 'file']) ?>
= $this->Form->control('title') ?>
= $this->Form->control('teaser_image', ['type' => 'file']) ?>
@@ -1401,7 +1401,7 @@ image file, and multiple attachments/files would be accepted:
The test that would simulate the corresponding request could look like this:
-``` php
+```php
public function testAddWithUploads(): void
{
$teaserImage = new \Laminas\Diactoros\UploadedFile(
@@ -1476,7 +1476,7 @@ public function testAddWithUploads(): void
Likewise you can simulate [upload errors](https://www.php.net/manual/en/features.file-upload.errors.php)
or otherwise invalid files that do not pass validation:
-``` php
+```php
public function testAddWithInvalidUploads(): void
{
$missingTeaserImageUpload = new \Laminas\Diactoros\UploadedFile(
@@ -1551,7 +1551,7 @@ errors it can be helpful to temporarily disable the error handling middleware to
allow the underlying error to bubble up. You can use
`disableErrorHandlerMiddleware()` to do this:
-``` php
+```php
public function testGetMissing(): void
{
$this->disableErrorHandlerMiddleware();
@@ -1569,7 +1569,7 @@ checked.
The `IntegrationTestTrait` trait provides a number of assertion methods that
make testing responses much simpler. Some examples are:
-``` php
+```php
// Check for a 2xx response code
$this->assertResponseOk();
@@ -1666,7 +1666,7 @@ The `StringCompareTrait` adds a simple assert method for this purpose.
Usage involves using the trait, setting the comparison base path and calling
`assertSameAsFile`:
-``` php
+```php
use Cake\TestSuite\StringCompareTrait;
use Cake\TestSuite\TestCase;
@@ -1695,7 +1695,7 @@ A mechanism is provided to write/update test files, by setting the environment
variable `UPDATE_TEST_COMPARISON_FILES`, which will create and/or update test
comparison files as they are referenced:
-``` bash
+```bash
phpunit
...
FAILURES!
@@ -1744,7 +1744,7 @@ This component helps us set the pagination limit value across all the
controllers that use it. Here is our example component located in
**src/Controller/Component/PagematronComponent.php**:
-``` php
+```php
class PagematronComponent extends Component
{
public ?Controller $controller = null;
@@ -1784,7 +1784,7 @@ Now we can write tests to ensure our paginate `limit` parameter is being set
correctly by the `adjust()` method in our component. We create the file
**tests/TestCase/Controller/Component/PagematronComponentTest.php**:
-``` php
+```php
namespace App\Test\TestCase\Controller\Component;
use App\Controller\Component\PagematronComponent;
@@ -1846,7 +1846,7 @@ First we create an example helper to test. The `CurrencyRendererHelper` will
help us display currencies in our views and for simplicity only has one method
`usd()`:
-``` php
+```php
// src/View/Helper/CurrencyRendererHelper.php
namespace App\View\Helper;
@@ -1866,7 +1866,7 @@ separator to comma, and prefix the formatted number with 'USD' string.
Now we create our tests:
-``` php
+```php
// tests/TestCase/View/Helper/CurrencyRendererHelperTest.php
namespace App\Test\TestCase\View\Helper;
@@ -1924,7 +1924,7 @@ instead.
Expanding on the Orders example, say we have the following tables:
-``` php
+```php
class OrdersTable extends Table
{
public function place($order): bool
@@ -1972,7 +1972,7 @@ To test the `OrdersTable` above, we enable tracking in `setUp()` then assert
that the event was fired, and assert that the `$order` entity was passed in
the event data:
-``` php
+```php
namespace App\Test\TestCase\Model\Table;
use App\Model\Table\OrdersTable;
@@ -2010,7 +2010,7 @@ class OrdersTableTest extends TestCase
By default, the global `EventManager` is used for assertions, so testing
global events does not require passing the event manager:
-``` php
+```php
$this->assertEventFired('My.Global.Event');
$this->assertEventFiredWith('My.Global.Event', 'user', 1);
```
@@ -2030,7 +2030,7 @@ suite. A test suite is composed of several test cases. You can either create
test suites in your application's **phpunit.xml** file. A simple example
would be:
-``` xml
+```xml
src/Model
@@ -2058,7 +2058,7 @@ for the `BlogPost` model from the plugins chapter of this manual. A difference
from other tests is in the first line where 'Blog.BlogPost' is imported. You
also need to prefix your plugin fixtures with `plugin.Blog.BlogPosts`:
-``` php
+```php
namespace Blog\Test\TestCase\Model\Table;
use Blog\Model\Table\BlogPostsTable;
@@ -2086,7 +2086,7 @@ listener](#fixture-phpunit-configuration) configured in your `phpunit.xml`
file. You should also ensure that your fixtures are loadable. Ensure the
following is present in your **composer.json** file:
-``` json
+```json
"autoload-dev": {
"psr-4": {
"MyPlugin\\Test\\": "plugins/MyPlugin/tests/"
@@ -2105,7 +2105,7 @@ generate scaffolding, it will also generate test stubs. If you need to
re-generate test case skeletons, or if you want to generate test skeletons for
code you wrote, you can use `bake`:
-``` bash
+```bash
bin/cake bake test
```
diff --git a/docs/en/intro.md b/docs/en/intro.md
index c18ccaf7b7..bd75cadd0c 100644
--- a/docs/en/intro.md
+++ b/docs/en/intro.md
@@ -35,7 +35,7 @@ and retrieving user photos, finding suggestions for new friends, etc.
The model objects can be thought of as "Friend", "User", "Comment", or
"Photo". If we wanted to load some data from our `users` table we could do:
-``` php
+```php
use Cake\ORM\Locator\LocatorAwareTrait;
$users = $this->fetchTable('Users');
@@ -52,7 +52,7 @@ for table and entity classes that have not yet been defined.
If we wanted to make a new user and save it (with validation) we would do
something like:
-``` php
+```php
use Cake\ORM\Locator\LocatorAwareTrait;
$users = $this->fetchTable('Users');
@@ -69,7 +69,7 @@ to produce any presentational interface your application might need.
For example, the view could use model data to render an HTML view template containing it,
or a XML formatted result for others to consume:
-``` php
+```php
// In a view template file, we'll render an 'element' for each user.
@@ -98,7 +98,7 @@ presentational data that the clients are accepting, and finally delegates the
rendering process to the View layer. An example of a user registration
controller would be:
-``` php
+```php
public function add()
{
$user = $this->Users->newEmptyEntity();
diff --git a/docs/en/orm.md b/docs/en/orm.md
index 8fc77753b2..76a74f0e96 100644
--- a/docs/en/orm.md
+++ b/docs/en/orm.md
@@ -35,7 +35,7 @@ if we wanted to load some data from our `articles` table we would start off
creating our `Articles` table class. Create
**src/Model/Table/ArticlesTable.php** with the following code:
-``` php
+```php
fetchTable('Articles')->find()->all();
@@ -61,7 +61,7 @@ public function someMethod()
In other contexts, you can use the `LocatorAwareTrait` which add accessor methods for ORM tables:
-``` php
+```php
use Cake\ORM\Locator\LocatorAwareTrait;
public function someMethod()
@@ -74,7 +74,7 @@ public function someMethod()
Within a static method you can use the `Cake\Datasource\FactoryLocator`
to get the table locator:
-``` php
+```php
$articles = TableRegistry::getTableLocator()->get('Articles');
```
@@ -84,7 +84,7 @@ mutator methods, define custom logic for individual records and much more. We'll
start off by adding the following to **src/Model/Entity/Article.php** after the
`fetchTable('Articles');
diff --git a/docs/en/orm/associations.md b/docs/en/orm/associations.md
index 24af8b0c4e..5afefd6dd2 100644
--- a/docs/en/orm/associations.md
+++ b/docs/en/orm/associations.md
@@ -22,7 +22,7 @@ object. Methods matching the association type allow you to define the
associations in your application. For example if we wanted to define a belongsTo
association in our ArticlesTable:
-``` php
+```php
namespace App\Model\Table;
use Cake\ORM\Table;
@@ -41,7 +41,7 @@ associate with. By default, all the details of an association will use the
CakePHP conventions. If you want to customize how your associations are handled
you can modify them with setters:
-``` php
+```php
class ArticlesTable extends Table
{
public function initialize(array $config): void
@@ -57,13 +57,13 @@ class ArticlesTable extends Table
The property name will be the property key (of the associated entity) on the entity object, in this case:
-``` php
+```php
$authorEntity = $articleEntity->author;
```
You can also use arrays to customize your associations:
-``` php
+```php
$this->belongsTo('Authors', [
'className' => 'Publishing.Authors',
'foreignKey' => 'author_id',
@@ -77,7 +77,7 @@ The same table can be used multiple times to define different types of
associations. For example consider a case where you want to separate
approved comments and those that have not been moderated yet:
-``` php
+```php
class ArticlesTable extends Table
{
public function initialize(array $config): void
@@ -98,7 +98,7 @@ As you can see, by specifying the `className` key, it is possible to use the
same table as different associations for the same table. You can even create
self-associated tables to create parent-child relationships:
-``` php
+```php
class CategoriesTable extends Table
{
public function initialize(array $config): void
@@ -118,7 +118,7 @@ You can also setup associations in mass by making a single call to
`Table::addAssociations()` which accepts an array containing a set of
table names indexed by association type as an argument:
-``` php
+```php
class PostsTable extends Table
{
public function initialize(array $config): void
@@ -165,7 +165,7 @@ called 'user_id'. The basic pattern is:
Once you create the `UsersTable` and `AddressesTable` classes, you can make
the association with the following code:
-``` php
+```php
class UsersTable extends Table
{
public function initialize(array $config): void
@@ -179,7 +179,7 @@ If you need more control, you can define your associations using the setters.
For example, you might want to limit the association to include only certain
records:
-``` php
+```php
class UsersTable extends Table
{
public function initialize(array $config): void
@@ -194,7 +194,7 @@ class UsersTable extends Table
If you want to break different addresses into multiple associations, you can do something like:
-``` php
+```php
class UsersTable extends Table
{
public function initialize(array $config): void
@@ -254,7 +254,7 @@ Possible keys for hasOne association arrays include:
Once this association has been defined, find operations on the Users table can
contain the Address record if it exists:
-``` php
+```php
// In a controller or table method.
$query = $users->find('all')->contain(['Addresses'])->all();
foreach ($query as $user) {
@@ -264,7 +264,7 @@ foreach ($query as $user) {
The above would emit SQL that is similar to:
-``` sql
+```sql
SELECT * FROM users INNER JOIN addresses ON addresses.user_id = users.id;
```
@@ -293,7 +293,7 @@ convention:
We can define the belongsTo association in our Addresses table as follows:
-``` php
+```php
class AddressesTable extends Table
{
public function initialize(array $config): void
@@ -305,7 +305,7 @@ class AddressesTable extends Table
We can also define a more specific relationship using the setters:
-``` php
+```php
class AddressesTable extends Table
{
public function initialize(array $config): void
@@ -344,7 +344,7 @@ Possible keys for belongsTo association arrays include:
Once this association has been defined, find operations on the Addresses table can
contain the User record if it exists:
-``` php
+```php
// In a controller or table method.
$query = $addresses->find('all')->contain(['Users'])->all();
foreach ($query as $address) {
@@ -354,7 +354,7 @@ foreach ($query as $address) {
The above would output SQL similar to:
-``` sql
+```sql
SELECT * FROM addresses LEFT JOIN users ON addresses.user_id = users.id;
```
@@ -379,7 +379,7 @@ convention:
We can define the hasMany association in our Articles model as follows:
-``` php
+```php
class ArticlesTable extends Table
{
public function initialize(array $config): void
@@ -391,7 +391,7 @@ class ArticlesTable extends Table
We can also define a more specific relationship using the setters:
-``` php
+```php
class ArticlesTable extends Table
{
public function initialize(array $config): void
@@ -405,7 +405,7 @@ class ArticlesTable extends Table
Sometimes you may want to configure composite keys in your associations:
-``` php
+```php
// Within ArticlesTable::initialize() call
$this->hasMany('Comments')
->setForeignKey([
@@ -420,7 +420,7 @@ automatically defined as `id` and `hash` respectively, but let's assume that
you need to specify different binding fields than the defaults. You can setup it
manually with `setBindingKey()`:
-``` php
+```php
// Within ArticlesTable::initialize() call
$this->hasMany('Comments')
->setForeignKey([
@@ -475,7 +475,7 @@ Possible keys for hasMany association arrays include:
Once this association has been defined, find operations on the Articles table
can contain the Comment records if they exist:
-``` php
+```php
// In a controller or table method.
$query = $articles->find('all')->contain(['Comments'])->all();
foreach ($query as $article) {
@@ -485,7 +485,7 @@ foreach ($query as $article) {
The above would output SQL similar to:
-``` sql
+```sql
SELECT * FROM articles;
SELECT * FROM comments WHERE article_id IN (1, 2, 3, 4, 5);
```
@@ -493,7 +493,7 @@ SELECT * FROM comments WHERE article_id IN (1, 2, 3, 4, 5);
When the subquery strategy is used, SQL similar to the following will be
generated:
-``` sql
+```sql
SELECT * FROM articles;
SELECT * FROM comments WHERE article_id IN (SELECT id FROM articles);
```
@@ -542,7 +542,7 @@ names.
We can define the belongsToMany association in both our models as follows:
-``` php
+```php
// In src/Model/Table/ArticlesTable.php
class ArticlesTable extends Table
{
@@ -564,7 +564,7 @@ class TagsTable extends Table
We can also define a more specific relationship using configuration:
-``` php
+```php
// In src/Model/Table/TagsTable.php
class TagsTable extends Table
{
@@ -630,7 +630,7 @@ Possible keys for belongsToMany association arrays include:
Once this association has been defined, find operations on the Articles table can
contain the Tag records if they exist:
-``` php
+```php
// In a controller or table method.
$query = $articles->find('all')->contain(['Tags'])->all();
foreach ($query as $article) {
@@ -640,7 +640,7 @@ foreach ($query as $article) {
The above would output SQL similar to:
-``` sql
+```sql
SELECT * FROM articles;
SELECT * FROM tags
INNER JOIN articles_tags ON (
@@ -652,7 +652,7 @@ INNER JOIN articles_tags ON (
When the subquery strategy is used, SQL similar to the following will be
generated:
-``` sql
+```sql
SELECT * FROM articles;
SELECT * FROM tags
INNER JOIN articles_tags ON (
@@ -689,7 +689,7 @@ as a **hasMany through** association. That is, the association is a model
itself. So, we can create a new model CoursesMemberships. Take a look at the
following models:
-``` php
+```php
class StudentsTable extends Table
{
public function initialize(array $config): void
@@ -729,7 +729,7 @@ your query object. The `through` table can then be referenced in other condition
such as a where condition by designating the through table name before the field
you are filtering on:
-``` php
+```php
// In a StudentsTable method or controller action.
$query = $this->Students->find(
'list',
@@ -768,20 +768,20 @@ above restrictions and can also use result formatters or map/reduce functions.
By default, associations should be configured and referenced using the CamelCase style.
This enables property chains to related tables in the following way:
-``` php
+```php
$this->MyTableOne->MyTableTwo->find()->...;
```
Association properties on entities do not use CamelCase conventions though. Instead for a hasOne/belongsTo relation like "User belongsTo Roles", you would get a `role` property instead of `Role` or `Roles`:
-``` php
+```php
// A single entity (or null if not available)
$role = $user->role;
```
Whereas for the other direction "Roles hasMany Users" it would be:
-``` php
+```php
// Collection of user entities (or null if not available)
$users = $role->users;
```
diff --git a/docs/en/orm/behaviors.md b/docs/en/orm/behaviors.md
index b69f0f1525..f6b576c6f5 100644
--- a/docs/en/orm/behaviors.md
+++ b/docs/en/orm/behaviors.md
@@ -46,7 +46,7 @@ behaviors:
To create our sluggable behavior. Put the following into
**src/Model/Behavior/SluggableBehavior.php**:
-``` php
+```php
namespace App\Model\Behavior;
use Cake\ORM\Behavior;
@@ -59,7 +59,7 @@ class SluggableBehavior extends Behavior
Similar to tables, behaviors also have an `initialize()` hook where you can
put your behavior's initialization code, if required:
-``` php
+```php
public function initialize(array $config): void
{
// Some initialization code here
@@ -70,7 +70,7 @@ We can now add this behavior to one of our table classes. In this example we'll
use an `ArticlesTable`, as articles often have slug properties for creating
friendly URLs:
-``` php
+```php
namespace App\Model\Table;
use Cake\ORM\Table;
@@ -92,7 +92,7 @@ slug a field.
Public methods on behaviors can be called as normal methods:
-``` php
+```php
$articles->getBehavior('Sluggable')->slug($value);
```
@@ -104,7 +104,7 @@ Behavior mixin methods will receive the exact same arguments that are provided
to the table. For example, if our SluggableBehavior defined the following
method:
-``` php
+```php
public function slug(string $value): string
{
return Text::slug($value, $this->_config['replacement']);
@@ -113,7 +113,7 @@ public function slug(string $value): string
It could be invoked using:
-``` php
+```php
$slug = $articles->slug('My article');
```
@@ -128,7 +128,7 @@ public methods as mixin methods. In these cases you can use the
`implementedMethods` configuration key to rename or exclude mixin methods. For
example if we wanted to prefix our slug() method we could do the following:
-``` php
+```php
protected array $_defaultConfig = [
'implementedMethods' => [
'superSlug' => 'slug',
@@ -144,7 +144,7 @@ methods with the above configuration.
Since the exposed methods are decided by configuration you can also
rename/remove mixin methods when adding a behavior to a table. For example:
-``` php
+```php
// In a table's initialize() method.
$this->addBehavior('Sluggable', [
'implementedMethods' => [
@@ -160,7 +160,7 @@ a callback listener to automatically slug a field when entities are saved. We'll
also modify our slug method to accept an entity instead of just a plain value. Our
behavior should now look like:
-``` php
+```php
namespace App\Model\Behavior;
use ArrayObject;
@@ -203,7 +203,7 @@ The above code shows a few interesting features of behaviors:
To prevent the save from continuing, simply stop event propagation in your callback:
-``` php
+```php
public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options): void
{
if (...) {
@@ -225,7 +225,7 @@ a finder method so we can fetch articles by their slug. Behavior finder
methods, use the same conventions as [Custom Find Methods](../orm/retrieving-data-and-resultsets#custom-find-methods) do. Our
`find('slug')` method would look like:
-``` php
+```php
public function findSlug(SelectQuery $query, string $slug): SelectQuery
{
return $query->where(['slug' => $slug]);
@@ -234,7 +234,7 @@ public function findSlug(SelectQuery $query, string $slug): SelectQuery
Once our behavior has the above method we can call it:
-``` php
+```php
$article = $articles->find('slug', slug: $value)->first();
```
@@ -246,7 +246,7 @@ these cases you can use the `implementedFinders` configuration key to rename
or exclude finder methods. For example if we wanted to rename our `find(slug)`
method we could do the following:
-``` php
+```php
protected array $_defaultConfig = [
'implementedFinders' => [
'slugged' => 'findSlug',
@@ -262,7 +262,7 @@ in the configuration.
Since the exposed methods are decided by configuration you can also
rename/remove finder methods when adding a behavior to a table. For example:
-``` php
+```php
// In a table's initialize() method.
$this->addBehavior('Sluggable', [
'implementedFinders' => [
@@ -277,7 +277,7 @@ Behaviors can define logic for how the custom fields they provide are
marshalled by implementing the `Cake\ORM\PropertyMarshalInterface`. This
interface requires a single method to be implemented:
-``` php
+```php
public function buildMarshalMap(Marshaller $marshaller, array $map, array $options): array
{
return [
@@ -296,7 +296,7 @@ that you might want to refer to.
To remove a behavior from your table you can call the `removeBehavior()` method:
-``` php
+```php
// Remove the loaded behavior
$this->removeBehavior('Sluggable');
```
@@ -306,7 +306,7 @@ $this->removeBehavior('Sluggable');
Once you've attached behaviors to your Table instance you can introspect the
loaded behaviors, or access specific behaviors using the `BehaviorRegistry`:
-``` php
+```php
// See which behaviors are loaded
$table->behaviors()->loaded();
@@ -330,7 +330,7 @@ behavior you could do the following to add, modify or remove the configurations
for the behavior. In this case, we will add an event we want Timestamp to
respond to:
-``` php
+```php
namespace App\Model\Table;
use App\Model\Table\AppTable; // similar to AppController
diff --git a/docs/en/orm/behaviors/counter-cache.md b/docs/en/orm/behaviors/counter-cache.md
index bfffadaecc..f1304b008b 100644
--- a/docs/en/orm/behaviors/counter-cache.md
+++ b/docs/en/orm/behaviors/counter-cache.md
@@ -22,7 +22,7 @@ anything until you configure some relations and the field counts that should be
stored on each of them. Using our example below, we could cache the comment
count for each article with the following:
-``` php
+```php
class CommentsTable extends Table
{
public function initialize(array $config): void
@@ -59,7 +59,7 @@ If you need to keep a cached counter for less than all the related records,
you can supply additional conditions or finder methods to generate a
counter value:
-``` php
+```php
// Use a specific find method.
// In this case find(published)
$this->addBehavior('CounterCache', [
@@ -74,7 +74,7 @@ $this->addBehavior('CounterCache', [
If you don't have a custom finder method you can provide an array of conditions
to find records instead:
-``` php
+```php
$this->addBehavior('CounterCache', [
'Articles' => [
'comment_count' => [
@@ -87,7 +87,7 @@ $this->addBehavior('CounterCache', [
If you want CounterCache to update multiple fields, for example both showing a
conditional count and a basic count you can add these fields in the array:
-``` php
+```php
$this->addBehavior('CounterCache', [
'Articles' => ['comment_count',
'published_comment_count' => [
@@ -102,7 +102,7 @@ the `ignoreDirty` option to `true`.
This will prevent the field from being recalculated if you've set it dirty
before:
-``` php
+```php
$this->addBehavior('CounterCache', [
'Articles' => [
'comment_count' => [
@@ -115,7 +115,7 @@ $this->addBehavior('CounterCache', [
Lastly, if a custom finder and conditions are not suitable you can provide
a callback function. Your function must return the count value to be stored:
-``` php
+```php
$this->addBehavior('CounterCache', [
'Articles' => [
'rating_avg' => function ($event, $entity, $table, $original) {
@@ -150,7 +150,7 @@ It is possible to use the CounterCache behavior in a `belongsToMany` association
First, you need to add the `through` and `cascadeCallbacks` options to the
`belongsToMany` association:
-``` php
+```php
'through' => 'CommentsArticles',
'cascadeCallbacks' => true,
```
@@ -163,7 +163,7 @@ If you don't have it you should create it with the bake CLI tool.
In this `src/Model/Table/CommentsArticlesTable.php` you then need to add the behavior
with the same code as described above.
-``` php
+```php
$this->addBehavior('CounterCache', [
'Articles' => ['comments_count'],
]);
@@ -179,7 +179,7 @@ The `updateCounterCache()` method allows you to update the counter cache values
for all records of one or all configured associations in batches. This can be useful,
for example, to update the counter cache after importing data directly into the database.
-``` php
+```php
// Update the counter cache for all configured associations
$table->getBehavior('CounterCache')->updateCounterCache();
diff --git a/docs/en/orm/behaviors/timestamp.md b/docs/en/orm/behaviors/timestamp.md
index a0bb97186a..df9ed2f754 100644
--- a/docs/en/orm/behaviors/timestamp.md
+++ b/docs/en/orm/behaviors/timestamp.md
@@ -17,7 +17,7 @@ publishes.
You enable the timestamp behavior like any other behavior:
-``` php
+```php
class ArticlesTable extends Table
{
public function initialize(array $config): void
@@ -38,7 +38,7 @@ The default configuration will do the following:
If you need to modify fields with different names, or want to update additional
timestamp fields on custom events you can use some additional configuration:
-``` php
+```php
class OrdersTable extends Table
{
public function initialize(array $config): void
@@ -67,7 +67,7 @@ Sometimes you'll want to update just the timestamps on an entity without
changing any other properties. This is sometimes referred to as 'touching'
a record. In CakePHP you can use the `touch()` method to do exactly this:
-``` php
+```php
// Touch based on the Model.beforeSave event.
$articles->getBehavior('Timestamp')->touch($article);
@@ -86,7 +86,7 @@ article when a new comment is added.
To disable the automatic modification of the `updated` timestamp column when
saving an entity you can mark the attribute as 'dirty':
-``` php
+```php
// Mark the modified column as dirty making
// the current value be set on update.
$order->setDirty('modified', true);
diff --git a/docs/en/orm/behaviors/translate.md b/docs/en/orm/behaviors/translate.md
index ad4739b17e..b2fb709f83 100644
--- a/docs/en/orm/behaviors/translate.md
+++ b/docs/en/orm/behaviors/translate.md
@@ -29,7 +29,7 @@ The behavior offers two strategies for how the translations are stored.
Let's assume we have an `articles` table and we want it's `title` and `body`
fields to be translated. For that we create a shadow table `articles_translations`:
-``` sql
+```sql
CREATE TABLE `articles_translations` (
`id` int(11) NOT NULL,
`locale` varchar(5) NOT NULL,
@@ -65,7 +65,7 @@ In order to use the Eav strategy, you need to create a `i18n` table with the
correct schema. Currently the only way of loading the `i18n` table is by
manually running the following SQL script in your database:
-``` sql
+```sql
CREATE TABLE i18n (
id int NOT NULL auto_increment,
locale varchar(6) NOT NULL,
@@ -86,7 +86,7 @@ The schema is also available as sql file in **/config/schema/i18n.sql**.
Attaching the behavior can be done in the `initialize()` method in your Table
class:
-``` php
+```php
class ArticlesTable extends Table
{
public function initialize(array $config): void
@@ -103,7 +103,7 @@ behavior can infer the fields from the shadow table columns.
If you want to use the `EavStrategy` then you can configure the behavior
as:
-``` php
+```php
class ArticlesTable extends Table
{
public function initialize(array $config): void
@@ -124,7 +124,7 @@ By default, the locale specified in `App.defaultLocale` config is used as defaul
locale for the `TranslateBehavior`. You can override that by setting `defaultLocale`
config of the behavior:
-``` php
+```php
class ArticlesTable extends Table
{
public function initialize(array $config): void
@@ -144,28 +144,28 @@ same API to manage translations.
Now, select a language to be used for retrieving entities by changing
the application language, which will affect all translations:
-``` php
+```php
// In the Articles controller. Change the locale to Spanish, for example
I18n::setLocale('es');
```
Then, get an existing entity:
-``` php
+```php
$article = $this->Articles->get(12);
echo $article->title; // Echoes 'A title', not translated yet
```
Next, translate your entity:
-``` php
+```php
$article->title = 'Un Artículo';
$this->Articles->save($article);
```
You can try now getting your entity again:
-``` php
+```php
$article = $this->Articles->get(12);
echo $article->title; // Echoes 'Un Artículo', yay piece of cake!
```
@@ -173,7 +173,7 @@ echo $article->title; // Echoes 'Un Artículo', yay piece of cake!
Working with multiple translations can be done by using a special trait
in your Entity class:
-``` php
+```php
use Cake\ORM\Behavior\Translate\TranslateTrait;
use Cake\ORM\Entity;
@@ -185,7 +185,7 @@ class Article extends Entity
Now you can find all translations for a single entity:
-``` php
+```php
$article = $this->Articles->find('translations')->first();
echo $article->translation('es')->title; // 'Un Artículo'
@@ -194,7 +194,7 @@ echo $article->translation('en')->title; // 'An Article';
And save multiple translations at once:
-``` php
+```php
$article->translation('es')->title = 'Otro Título';
$article->translation('fr')->title = 'Un autre Titre';
$this->Articles->save($article);
@@ -211,7 +211,7 @@ table in the behavior's configuration. This is common when you have multiple
tables to translate and you want a cleaner separation of the data that is stored
for each different table:
-``` php
+```php
class ArticlesTable extends Table
{
public function initialize(array $config): void
@@ -232,7 +232,7 @@ You need to make sure that any custom table you use has the columns `field`,
As shown above you can use the `setLocale()` method to choose the active
translation for entities that are loaded:
-``` php
+```php
// Load I18n core functions at the beginning of your Articles Controller:
use Cake\I18n\I18n;
@@ -246,7 +246,7 @@ $results = $this->Articles->find()->all();
This method works with any finder in your tables. For example, you can
use TranslateBehavior with `find('list')`:
-``` php
+```php
I18n::setLocale('es');
$data = $this->Articles->find('list')->toArray();
@@ -263,7 +263,7 @@ When building interfaces for updating translated content, it is often helpful to
show one or more translation(s) at the same time. You can use the
`translations` finder for this:
-``` php
+```php
// Find the first article with all corresponding translations
$article = $this->Articles->find('translations')->first();
```
@@ -272,7 +272,7 @@ In the example above you will get a list of entities back that have a
`_translations` property set. This property will contain a list of translation
data entities. For example the following properties would be accessible:
-``` php
+```php
// Outputs 'en'
echo $article->_translations['en']->locale;
@@ -286,7 +286,7 @@ echo $article->_translations['en']->body;
A more elegant way for dealing with this data is by adding a trait to the entity
class that is used for your table:
-``` php
+```php
use Cake\ORM\Behavior\Translate\TranslateTrait;
use Cake\ORM\Entity;
@@ -299,7 +299,7 @@ class Article extends Entity
This trait contains a single method called `translation`, which lets you
access or create new translation entities on the fly:
-``` php
+```php
// Outputs 'title'
echo $article->translation('en')->title;
@@ -312,7 +312,7 @@ $article->translation('de')->title = 'Wunderbar';
You can limit the languages that are fetched from the database for a particular
set of records:
-``` php
+```php
$results = $this->Articles->find('translations', locales: ['en', 'es']);
$article = $results->first();
$spanishTranslation = $article->translation('es');
@@ -328,7 +328,7 @@ this to overwrite the original field value.
If this is undesired, you can ignore translations which are empty using the
`allowEmptyTranslations` config key:
-``` php
+```php
class ArticlesTable extends Table
{
public function initialize(array $config): void
@@ -348,7 +348,7 @@ The above would only load translated data that had content.
It is also possible to find translations for any association in a single find
operation:
-``` php
+```php
$article = $this->Articles->find('translations')->contain([
'Categories' => function ($query) {
return $query->find('translations');
@@ -384,7 +384,7 @@ Note that this only changes the locale of the Articles table, it would not
affect the language of associated data. To affect associated data it's necessary
to call the method on each table, for example:
-``` php
+```php
I18n::setLocale('en'); // reset for illustration
$this->Articles->getBehavior('Translate')->setLocale('es');
@@ -401,7 +401,7 @@ to it.
TranslateBehavior does not substitute find conditions by default. You need to use
`translationField()` method to compose find conditions on translated fields:
-``` php
+```php
$this->Articles->getBehavior('Translate')->setLocale('es');
$query = $this->Articles->find()->where([
$this->Articles->getBehavior('Translate')->translationField('title') => 'Otro Título',
@@ -415,7 +415,7 @@ representing the default language, and multiple translations that can override
certain fields in such entity. Keeping this in mind, you can intuitively save
translations for any given entity. For example, given the following setup:
-``` php
+```php
// in src/Model/Table/ArticlesTable.php
class ArticlesTable extends Table
{
@@ -445,7 +445,7 @@ So, after you save your first article, you can now save a translation for it,
there are a couple ways to do it. The first one is setting the language directly
into the entity:
-``` php
+```php
$article->_locale = 'es';
$article->title = 'Mi primer Artículo';
@@ -456,7 +456,7 @@ After the entity has been saved, the translated field will be persisted as well,
one thing to note is that values from the default language that were not
overridden will be preserved:
-``` php
+```php
// Outputs 'This is the content'
echo $article->body;
@@ -467,7 +467,7 @@ echo $article->title;
Once you override the value, the translation for that field will be saved and
can be retrieved as usual:
-``` php
+```php
$article->body = 'El contendio';
$this->Articles->save($article);
```
@@ -475,7 +475,7 @@ $this->Articles->save($article);
The second way to use for saving entities in another language is to set the
default language directly to the table:
-``` php
+```php
$article->title = 'Mi Primer Artículo';
$this->Articles->getBehavior('Translate')->setLocale('es');
@@ -492,7 +492,7 @@ It is a common requirement to be able to add or edit multiple translations to
any database record at the same time. This can be done using the
`TranslateTrait`:
-``` php
+```php
use Cake\ORM\Behavior\Translate\TranslateTrait;
use Cake\ORM\Entity;
@@ -504,7 +504,7 @@ class Article extends Entity
Now, You can populate translations before saving them:
-``` php
+```php
$translations = [
'fr' => ['title' => "Un article"],
'es' => ['title' => 'Un artículo'],
@@ -519,7 +519,7 @@ $this->Articles->save($article);
And create form controls for your translated fields:
-``` php
+```php
// In a view template.
= $this->Form->create($article); ?>