From eaf5ed712338619579e4f591c7beb34a20f35836 Mon Sep 17 00:00:00 2001 From: mscherer Date: Mon, 23 Jun 2025 15:20:21 +0200 Subject: [PATCH] Document 5.x redirecting and add void return types. --- en/controllers.rst | 2 +- en/controllers/components.rst | 14 +++++++++----- en/controllers/components/form-protection.rst | 6 +++--- en/core-libraries/email.rst | 4 ++-- en/core-libraries/events.rst | 2 +- en/development/errors.rst | 2 +- en/development/testing.rst | 4 ++-- en/orm/behaviors.rst | 4 ++-- en/orm/saving-data.rst | 6 +++--- en/orm/table-objects.rst | 8 ++++---- .../cms/articles-controller.rst | 2 +- en/tutorials-and-examples/cms/authentication.rst | 4 ++-- en/tutorials-and-examples/cms/tags-and-users.rst | 2 +- en/views/helpers.rst | 4 ++-- en/views/helpers/form.rst | 2 +- en/views/themes.rst | 4 ++-- 16 files changed, 37 insertions(+), 33 deletions(-) diff --git a/en/controllers.rst b/en/controllers.rst index 117dfbb245..0f3c1ad469 100644 --- a/en/controllers.rst +++ b/en/controllers.rst @@ -564,7 +564,7 @@ Remember to call ``AppController``'s callbacks within child controller callbacks for best results:: //use Cake\Event\EventInterface; - public function beforeFilter(EventInterface $event) + public function beforeFilter(EventInterface $event): void { parent::beforeFilter($event); } diff --git a/en/controllers/components.rst b/en/controllers/components.rst index 44ec1be50a..e2f2ef4ef3 100644 --- a/en/controllers/components.rst +++ b/en/controllers/components.rst @@ -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:: - public function beforeFilter(EventInterface $event) + public function beforeFilter(EventInterface $event): void { $this->FormProtection->setConfig('unlockedActions', ['index']); } @@ -335,11 +335,15 @@ Using Redirects in Component Events To redirect from within a component callback method you can use the following:: - public function beforeFilter(EventInterface $event) + public function beforeFilter(EventInterface $event): void { - $event->stopPropagation(); + if (...) { + $event->setResult($this->getController()->redirect('/')); - return $this->getController()->redirect('/'); + return; + } + + ... } By stopping the event you let CakePHP know that you don't want any other @@ -350,7 +354,7 @@ a redirect:: use Cake\Http\Exception\RedirectException; use Cake\Routing\Router; - public function beforeFilter(EventInterface $event) + public function beforeFilter(EventInterface $event): void { throw new RedirectException(Router::url('/')) } diff --git a/en/controllers/components/form-protection.rst b/en/controllers/components/form-protection.rst index b8fca5945b..943ff92494 100644 --- a/en/controllers/components/form-protection.rst +++ b/en/controllers/components/form-protection.rst @@ -93,7 +93,7 @@ Disabling form tampering checks $this->loadComponent('FormProtection'); } - public function beforeFilter(EventInterface $event) + public function beforeFilter(EventInterface $event): void { parent::beforeFilter($event); @@ -126,7 +126,7 @@ action (ex. AJAX requests). You may "unlock" these actions by listing them in $this->loadComponent('FormProtection'); } - public function beforeFilter(EventInterface $event) + public function beforeFilter(EventInterface $event): void { parent::beforeFilter($event); @@ -148,7 +148,7 @@ works:: use Cake\Controller\Exception\FormProtectionException; - public function beforeFilter(EventInterface $event) + public function beforeFilter(EventInterface $event): void { parent::beforeFilter($event); diff --git a/en/core-libraries/email.rst b/en/core-libraries/email.rst index 2256268e8d..42b00141c2 100644 --- a/en/core-libraries/email.rst +++ b/en/core-libraries/email.rst @@ -379,14 +379,14 @@ 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``:: - public function implementedEvents() + public function implementedEvents(): array { return [ 'Model.afterSave' => 'onRegistration', ]; } - public function onRegistration(EventInterface $event, EntityInterface $entity, ArrayObject $options) + public function onRegistration(EventInterface $event, EntityInterface $entity, ArrayObject $options): void { if ($entity->isNew()) { $this->send('welcome', [$entity]); diff --git a/en/core-libraries/events.rst b/en/core-libraries/events.rst index 889f040074..50edcad393 100644 --- a/en/core-libraries/events.rst +++ b/en/core-libraries/events.rst @@ -375,7 +375,7 @@ for event listeners:: // Setting priority for a listener class UserStatistic implements EventListenerInterface { - public function implementedEvents() + public function implementedEvents(): array { return [ 'Order.afterPlace' => [ diff --git a/en/development/errors.rst b/en/development/errors.rst index d7308b2a59..94772cdb5e 100644 --- a/en/development/errors.rst +++ b/en/development/errors.rst @@ -201,7 +201,7 @@ prefix. You could create the following class:: * @param \Cake\Event\EventInterface $event Event. * @return void */ - public function beforeRender(EventInterface $event) + public function beforeRender(EventInterface $event): void { $this->viewBuilder()->setTemplatePath('Error'); } diff --git a/en/development/testing.rst b/en/development/testing.rst index 4e11e505a3..a43df5435c 100644 --- a/en/development/testing.rst +++ b/en/development/testing.rst @@ -1688,12 +1688,12 @@ controllers that use it. Here is our example component located in } } - public function startup(EventInterface $event) + public function startup(EventInterface $event): void { $this->setController($event->getSubject()); } - public function adjust($length = 'short'): void + public function adjust(string $length = 'short'): void { switch ($length) { case 'long': diff --git a/en/orm/behaviors.rst b/en/orm/behaviors.rst index c3c3aa8ea5..71d0fd029d 100644 --- a/en/orm/behaviors.rst +++ b/en/orm/behaviors.rst @@ -168,7 +168,7 @@ behavior should now look like:: $entity->set($config['slug'], Text::slug($value, $config['replacement'])); } - public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options) + public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options): void { $this->slug($entity); } @@ -184,7 +184,7 @@ The above code shows a few interesting features of behaviors: To prevent the save from continuing, simply stop event propagation in your callback:: - public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options) + public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options): void { if (...) { $event->stopPropagation(); diff --git a/en/orm/saving-data.rst b/en/orm/saving-data.rst index 3c23a11fc9..80fa6d69cd 100644 --- a/en/orm/saving-data.rst +++ b/en/orm/saving-data.rst @@ -595,7 +595,7 @@ request data just before entities are created:: use ArrayObject; // In a table or behavior class - public function beforeMarshal(EventInterface $event, ArrayObject $data, ArrayObject $options) + public function beforeMarshal(EventInterface $event, ArrayObject $data, ArrayObject $options): void { if (isset($data['username'])) { $data['username'] = mb_strtolower($data['username']); @@ -620,7 +620,7 @@ changing the data before it is validated is trimming all fields before saving:: use ArrayObject; // In a table or behavior class - public function beforeMarshal(EventInterface $event, ArrayObject $data, ArrayObject $options) + public function beforeMarshal(EventInterface $event, ArrayObject $data, ArrayObject $options): void { foreach ($data as $key => $value) { if (is_string($value)) { @@ -656,7 +656,7 @@ validation logic that you cannot easily express through Validator methods:: EntityInterface $entity, ArrayObject $data, ArrayObject $options - ) { + ): void { // Don't accept people who have a name starting with J on the 20th // of each month. if (mb_substr($entity->name, 1) === 'J' && (int)date('d') === 20) { diff --git a/en/orm/table-objects.rst b/en/orm/table-objects.rst index 57ffd049cc..f5fe88e1bc 100644 --- a/en/orm/table-objects.rst +++ b/en/orm/table-objects.rst @@ -183,7 +183,7 @@ which implements ``EventListenerInterface``:: use Cake\Event\EventListenerInterface; class ModelInitializeListener implements EventListenerInterface { - public function implementedEvents() + public function implementedEvents(): array { return [ 'Model.initialize' => 'initializeEvent', @@ -231,7 +231,7 @@ The ``Model.beforeFind`` event is fired before each find operation. By stopping the event, and feeding the query with a custom result set, you can bypass the find operation entirely:: - public function beforeFind(EventInterface $event, SelectQuery $query, ArrayObject $options, $primary) + public function beforeFind(EventInterface $event, SelectQuery $query, ArrayObject $options, $primary): void { if (/* ... */) { $event->stopPropagation(); @@ -350,7 +350,7 @@ Stopping Table Events --------------------- To prevent the save from continuing, simply stop event propagation in your callback:: - public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options) + public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options): void { if (...) { $event->stopPropagation(); @@ -394,7 +394,7 @@ You can manage event priorities in one of a few ways: priority per callback-function:: // In a Table class. - public function implementedEvents() + public function implementedEvents(): array { $events = parent::implementedEvents(); $events['Model.beforeDelete'] = [ diff --git a/en/tutorials-and-examples/cms/articles-controller.rst b/en/tutorials-and-examples/cms/articles-controller.rst index 4bddf4e56a..872668024a 100644 --- a/en/tutorials-and-examples/cms/articles-controller.rst +++ b/en/tutorials-and-examples/cms/articles-controller.rst @@ -316,7 +316,7 @@ typically a URL-safe version of an article's title. We can use the // Add the following method. - public function beforeSave(EventInterface $event, $entity, $options) + public function beforeSave(EventInterface $event, $entity, $options): void { if ($entity->isNew() && !$entity->slug) { $sluggedTitle = Text::slug($entity->title); diff --git a/en/tutorials-and-examples/cms/authentication.rst b/en/tutorials-and-examples/cms/authentication.rst index 5c9a27ba0e..234e4ef54c 100644 --- a/en/tutorials-and-examples/cms/authentication.rst +++ b/en/tutorials-and-examples/cms/authentication.rst @@ -201,7 +201,7 @@ If you visit your site, you'll get an "infinite redirect loop" so let's fix that In your ``UsersController``, add the following code:: - public function beforeFilter(\Cake\Event\EventInterface $event) + public function beforeFilter(\Cake\Event\EventInterface $event): void { parent::beforeFilter($event); // Configure the login action to not require authentication, preventing @@ -258,7 +258,7 @@ We want all ``view`` and ``index`` pages accessible without logging in so we'll configuration in AppController:: // in src/Controller/AppController.php - public function beforeFilter(\Cake\Event\EventInterface $event) + public function beforeFilter(\Cake\Event\EventInterface $event): void { parent::beforeFilter($event); // for all controllers in our application, make index and view diff --git a/en/tutorials-and-examples/cms/tags-and-users.rst b/en/tutorials-and-examples/cms/tags-and-users.rst index be51a717cf..fed181f406 100644 --- a/en/tutorials-and-examples/cms/tags-and-users.rst +++ b/en/tutorials-and-examples/cms/tags-and-users.rst @@ -402,7 +402,7 @@ data from the request into our entity. We can use a ``beforeSave()`` hook method to parse the tag string and find/build the related entities. Add the following to **src/Model/Table/ArticlesTable.php**:: - public function beforeSave(EventInterface $event, $entity, $options) + public function beforeSave(EventInterface $event, $entity, $options): void { if ($entity->tag_string) { $entity->tags = $this->_buildTags($entity->tag_string); diff --git a/en/views/helpers.rst b/en/views/helpers.rst index ed0d243b89..f25e4de1b9 100644 --- a/en/views/helpers.rst +++ b/en/views/helpers.rst @@ -80,7 +80,7 @@ You can also use your controller's ``beforeRender`` method to add helpers:: class ArticlesController extends AppController { - public function beforeRender(EventInterface $event) + public function beforeRender(EventInterface $event): void { parent::beforeRender($event); $this->viewBuilder()->addHelper('MyHelper'); @@ -143,7 +143,7 @@ you can set those in your controller's beforeRender callback:: class PostsController extends AppController { - public function beforeRender(EventInterface $event) + public function beforeRender(EventInterface $event): void { parent::beforeRender($event); $builder = $this->viewBuilder(); diff --git a/en/views/helpers/form.rst b/en/views/helpers/form.rst index 9a16b06c78..d180f8e250 100644 --- a/en/views/helpers/form.rst +++ b/en/views/helpers/form.rst @@ -1567,7 +1567,7 @@ To prevent the ``submittedfile`` from being over-written as blank, remove it from ``$_accessible``. Alternatively, you can unset the index by using ``beforeMarshal``:: - public function beforeMarshal(\Cake\Event\EventInterface $event, \ArrayObject $data, \ArrayObject $options) + public function beforeMarshal(\Cake\Event\EventInterface $event, \ArrayObject $data, \ArrayObject $options): void { if ($data['submittedfile'] === '') { unset($data['submittedfile']); diff --git a/en/views/themes.rst b/en/views/themes.rst index 75fcec0925..9d4d25c755 100644 --- a/en/views/themes.rst +++ b/en/views/themes.rst @@ -19,7 +19,7 @@ To use themes, set the theme name in your controller's action or class ExamplesController extends AppController { - public function beforeRender(\Cake\Event\EventInterface $event) + public function beforeRender(\Cake\Event\EventInterface $event): void { $this->viewBuilder()->setTheme('Modern'); } @@ -50,7 +50,7 @@ Because themes are standard CakePHP plugins, they can include any necessary assets in their webroot directory. This allows for packaging and distribution of themes. Whilst in development, requests for theme assets will be handled by :php:class:`Cake\Routing\Middleware\AssetMiddleware` (which is loaded -by default in cakephp/app ``Application::middleware()``). To improve +by default in cakephp/app ``Application::middleware()``). To improve performance for production environments, it's recommended that you :ref:`symlink-assets`. All of CakePHP's built-in helpers are aware of themes and will create the