Skip to content

Commit 4456d13

Browse files
authored
Add PHP 8 type hints to event and validation callback examples (#8208)
* Add PHP 8 type hints to event listener and validation callback examples. Add EventInterface parameter types and void return types to event listener callbacks in the Events System documentation. Add typed parameters (mixed $value, array $context) and return types to validation callback examples. * Fix broken BelongsToMany through example in associations docs. Fix invalid valueField 'studentFirstName' to 'first_name' matching actual database column conventions. Fix indentation of find() arguments. Add context comment clarifying where the code runs.
1 parent d5af999 commit 4456d13

File tree

3 files changed

+33
-24
lines changed

3 files changed

+33
-24
lines changed

docs/en/core-libraries/events.md

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,10 @@ response has been sent, such as logging or sending emails.
165165
You can listen to this event using an event manager instance:
166166

167167
``` php
168+
use Cake\Event\EventInterface;
168169
use Cake\Event\EventManager;
169170

170-
EventManager::instance()->on('Server.terminate', function ($event) {
171+
EventManager::instance()->on('Server.terminate', function (EventInterface $event) {
171172
// Perform tasks that should be done after the response has been
172173
// sent to the client.
173174
});
@@ -176,11 +177,12 @@ EventManager::instance()->on('Server.terminate', function ($event) {
176177
Or using the `events` hook in your Application/Plugin class:
177178

178179
``` php
180+
use Cake\Event\EventInterface;
179181
use Cake\Event\EventManagerInterface;
180182

181183
public function events(EventManagerInterface $eventManager): EventManagerInterface
182184
{
183-
$eventManager->on('Server.terminate', function ($event) {
185+
$eventManager->on('Server.terminate', function (EventInterface $event) {
184186
// Perform tasks that should be done after the response has been
185187
// sent to the client.
186188
});
@@ -209,14 +211,15 @@ and the `afterExecute` event also contains the `exitCode` which is returned by t
209211
You can listen to this event using an event manager instance:
210212

211213
``` php
214+
use Cake\Event\EventInterface;
212215
use Cake\Event\EventManager;
213216

214-
EventManager::instance()->on('Command.beforeExecute', function ($event, $args) {
217+
EventManager::instance()->on('Command.beforeExecute', function (EventInterface $event, $args) {
215218
$command = $event->getSubject();
216219
// Do stuff here
217220
});
218221

219-
EventManager::instance()->on('Command.afterExecute', function ($event, $args, $result) {
222+
EventManager::instance()->on('Command.afterExecute', function (EventInterface $event, $args, $result) {
220223
$command = $event->getSubject();
221224
// Do stuff here
222225
});
@@ -225,16 +228,17 @@ EventManager::instance()->on('Command.afterExecute', function ($event, $args, $r
225228
Or using the `events` hook in your Application/Plugin class:
226229

227230
``` php
231+
use Cake\Event\EventInterface;
228232
use Cake\Event\EventManagerInterface;
229233

230234
public function events(EventManagerInterface $eventManager): EventManagerInterface
231235
{
232-
$eventManager->on('Command.beforeExecute', function ($event, $args) {
236+
$eventManager->on('Command.beforeExecute', function (EventInterface $event, $args) {
233237
$command = $event->getSubject();
234238
// Do stuff here
235239
});
236240

237-
$eventManager->on('Command.afterExecute', function ($event, $args, $result) {
241+
$eventManager->on('Command.afterExecute', function (EventInterface $event, $args, $result) {
238242
$command = $event->getSubject();
239243
// Do stuff here
240244
});
@@ -262,6 +266,7 @@ as necessary. Our `UserStatistics` listener might start out like:
262266
``` php
263267
namespace App\Event;
264268

269+
use Cake\Event\EventInterface;
265270
use Cake\Event\EventListenerInterface;
266271

267272
class UserStatistic implements EventListenerInterface
@@ -275,7 +280,7 @@ class UserStatistic implements EventListenerInterface
275280
];
276281
}
277282

278-
public function updateBuyStatistic($event)
283+
public function updateBuyStatistic(EventInterface $event): void
279284
{
280285
// Code to update statistics
281286
}
@@ -325,10 +330,11 @@ wanted to put any orders into the log files, we could use a simple anonymous
325330
function to do so:
326331

327332
``` php
333+
use Cake\Event\EventInterface;
328334
use Cake\Log\Log;
329335

330336
// From within a controller, or during application bootstrap.
331-
$this->Orders->getEventManager()->on('Order.afterPlace', function ($event) {
337+
$this->Orders->getEventManager()->on('Order.afterPlace', function (EventInterface $event) {
332338
Log::write(
333339
'info',
334340
'A new order was placed with id: ' . $event->getSubject()->id,
@@ -360,12 +366,13 @@ a more direct approach and only listen to the event you really need:
360366
// You can create the following before the
361367
// save operation, ie. config/bootstrap.php
362368
use Cake\Datasource\FactoryLocator;
369+
use Cake\Event\EventInterface;
363370
// If sending emails
364371
use Cake\Mailer\Email;
365372

366373
FactoryLocator::get('Table')->get('ThirdPartyPlugin.Feedbacks')
367374
->getEventManager()
368-
->on('Model.afterSave', function($event, $entity)
375+
->on('Model.afterSave', function(EventInterface $event, $entity)
369376
{
370377
// For example we can send an email to the admin
371378
$email = new Email('default');
@@ -533,13 +540,13 @@ In order to stop events you can either return `false` in your callbacks or
533540
call the `stopPropagation()` method on the event object:
534541

535542
``` php
536-
public function doSomething($event)
543+
public function doSomething(EventInterface $event)
537544
{
538545
// ...
539546
return false; // Stops the event
540547
}
541548

542-
public function updateBuyStatistic($event)
549+
public function updateBuyStatistic(EventInterface $event): void
543550
{
544551
// ...
545552
$event->stopPropagation();
@@ -585,7 +592,7 @@ directly or returning the value in the callback itself:
585592

586593
``` php
587594
// A listener callback
588-
public function doSomething($event)
595+
public function doSomething(EventInterface $event)
589596
{
590597
// ...
591598
$alteredData = $event->getData('order') + $moreData;
@@ -594,7 +601,7 @@ public function doSomething($event)
594601
}
595602

596603
// Another listener callback
597-
public function doSomethingElse($event)
604+
public function doSomethingElse(EventInterface $event): void
598605
{
599606
// ...
600607
$event->setResult(['order' => $alteredData] + $this->result());
@@ -634,7 +641,7 @@ $this->getEventManager()->on('My.event', [$this, 'doSomething']);
634641
$this->getEventManager()->off('My.event', [$this, 'doSomething']);
635642

636643
// Attaching an anonymous function.
637-
$myFunction = function ($event) { ... };
644+
$myFunction = function (EventInterface $event) { ... };
638645
$this->getEventManager()->on('My.event', $myFunction);
639646

640647
// Detaching the anonymous function

docs/en/core-libraries/validation.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ $validator->add('title', 'custom', [
175175
// Use a closure
176176
$extra = 'Some additional value needed inside the closure';
177177
$validator->add('title', 'custom', [
178-
'rule' => function ($value, $context) use ($extra) {
178+
'rule' => function (mixed $value, array $context) use ($extra) {
179179
// Custom logic that returns true/false
180180
},
181181
'message' => 'The title is not valid',
@@ -225,7 +225,7 @@ overwritten by the ones returned from the validation rule method:
225225

226226
``` php
227227
$validator->add('length', 'custom', [
228-
'rule' => function ($value, $context) {
228+
'rule' => function (mixed $value, array $context) {
229229
if (!$value) {
230230
return false;
231231
}
@@ -259,7 +259,7 @@ not a particular rule should be applied:
259259
``` php
260260
$validator->add('picture', 'file', [
261261
'rule' => ['mimeType', ['image/jpeg', 'image/png']],
262-
'on' => function ($context) {
262+
'on' => function (array $context): bool {
263263
return !empty($context['data']['show_profile_picture']);
264264
}
265265
]);
@@ -282,7 +282,7 @@ determines whether or not the rule should be applied. For example, a field is
282282
sometimes allowed to be empty:
283283

284284
``` php
285-
$validator->allowEmptyString('tax', 'This field is required', function ($context) {
285+
$validator->allowEmptyString('tax', 'This field is required', function (array $context): bool {
286286
return !$context['data']['is_taxable'];
287287
});
288288
```
@@ -291,7 +291,7 @@ Likewise, a field can be required to be populated when certain conditions are
291291
met:
292292

293293
``` php
294-
$validator->notEmptyString('email_frequency', 'This field is required', function ($context) {
294+
$validator->notEmptyString('email_frequency', 'This field is required', function (array $context): bool {
295295
return !empty($context['data']['wants_newsletter']);
296296
});
297297
```
@@ -303,7 +303,7 @@ Further it's also possible to require a field to be present under certain
303303
conditions only:
304304

305305
``` php
306-
$validator->requirePresence('full_name', function ($context) {
306+
$validator->requirePresence('full_name', function (array $context): bool {
307307
if (isset($context['data']['action'])) {
308308
return $context['data']['action'] === 'subscribe';
309309
}

docs/en/orm/associations.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -727,10 +727,12 @@ such as a where condition by designating the through table name before the field
727727
you are filtering on:
728728

729729
``` php
730-
$query = $this->find(
731-
'list',
732-
valueField: 'studentFirstName', order: 'students.id',
733-
)
730+
// In a StudentsTable method or controller action.
731+
$query = $this->Students->find(
732+
'list',
733+
valueField: 'first_name',
734+
order: 'Students.id',
735+
)
734736
->contain(['Courses'])
735737
->matching('Courses')
736738
->where(['CoursesMemberships.grade' => 'B']);

0 commit comments

Comments
 (0)