Commit 94b414fa by Alexander Makarov

Completed events doc

parent 855b913d
Events
======
TBD, see also [Component.md](../api/base/Component.md).
Event is a way to "inject" custom code into existing code at certain places. For example, a comment object can trigger
an "add" event when the user adds a comment. We can write custom code and attach it to this event so that when the event
is triggered (i.e. comment will be added), our custom code will be executed.
[[ADD INTRODUCTION]]
Events are very useful both to make your components flexible and to hook into framework and extensions workflow.
Creating Event Handlers
-----------------------
Triggering events
-----------------
In Yii 1, events were defined using the `onEventName` method syntax, such as `onBeforeSave`. This is no longer necessary in Yii 2, as event handling is now assigned using the `on` method. The method's first argument is the name of the event to watch for; the second is the handling method to be called when that event occurs:
Any component can trigger events using `trigger` method:
```php
$component->on($eventName, $handler);
$this->trigger('myEvent');
// or
$event = new CreateUserEvent(); // extended from yii\base\Event
$event->userName = 'Alexander';
$this->trigger('createUserEvent', $event);
```
[[LINK TO LIST OF EVENTS]]
Event name should be unique within the class it is defined at. Event names are *case-sensitive*. It is a good practice
to define event names using class constants:
```php
class Mailer extends Component
{
const EVENT_SEND_EMAIL = 'sendEmail';
public function send()
{
// ...
$this->trigger(self::EVENT_SEND_EMAIL);
}
}
```
Attaching event handlers
------------------------
One or multiple PHP callbacks, called *event handlers*, can be attached to an event. When an event is raised, the event
handlers will be invoked automatically in the order they were attached.
There are two main methods of attaching event handlers. It can be done either via code or via application config.
> Tip: In order to get up to date list of framework and extension events search code for `->trigger`.
### Attaching event handlers via code
You can assign event handlers using `on` method of the component instance. The method's first argument is the name of
the event to watch for; the second is the handler to be called when that event occurs:
```php
$component->on($eventName, $handler);
```
The handler must be a valid PHP callback. This could be represented as:
* The name of a global function
* An array consisting of a model name and method name
* An array consisting of an object and a method name
* An anonymous function
- The name of a global function.
- An array consisting of a model name and method name.
- An array consisting of an object and a method name.
- An anonymous function.
```php
// Global function:
......@@ -34,7 +75,7 @@ $component->on($eventName, ['Modelname', 'functionName']);
$component->on($eventName, [$obj, 'functionName']);
// Anonymous function:
$component->on($eventName, function($event) {
$component->on($eventName, function ($event) {
// Use $event.
});
```
......@@ -42,6 +83,31 @@ $component->on($eventName, function($event) {
As shown in the anonymous function example, the event handling function must be defined so that it takes one argument.
This will be an [[yii\base\Event]] object.
In order to pass extra data supply it via third argument:
```php
$component->on($eventName, function ($event) {
// the extra data can be accessed via $event->data
}, $extraData);
```
### Attaching event handlers via config
It is possible to use application config to attach event hanelers:
```php
return [
// ...
'components' => [
'db' => [
// ...
'on afterOpen' => function ($event) {
// do something right after connected to database
}
],
],
];
```
Removing Event Handlers
-----------------------
......@@ -52,7 +118,8 @@ The correspondoing `off` method removes an event handler:
// $component->off($eventName);
```
Yii supports the ability to associate multiple handlers with the same event. When using `off` as in the above, every handler is removed. To remove only a specific handler, provide that as the second argument to `off`:
Yii supports the ability to associate multiple handlers with the same event. When using `off` as in the above,
every handler is removed. To remove only a specific handler, provide that as the second argument to `off`:
```php
// $component->off($eventName, $handler);
......@@ -60,39 +127,27 @@ Yii supports the ability to associate multiple handlers with the same event. Whe
The `$handler` should be presented in the `off` method in the same way as was presented in `on` in order to remove it.
Event Parameters
----------------
You can make your event handlers easier to work with and more powerful by passing additional values as parameters.
```php
$component->on($eventName, $handler, $params);
```
The passed parameters will be available in the event handler through `$event->data`, which will be an array.
[[NEED TO CONFIRM THE ABOVE]]
Global Events
-------------
Thanks to the change in Yii 2 as to how event handlers are created, you can now use "global" events. To create a global event, simply attach handlers to an event on the application instance:
You can use "global" events instead of per-component ones. To trigger a global event use an application instance instead
of specific component:
```php
Yii::$app->on($eventName, $handler);
Yii::$app->trigger($eventName);
```
You can use the `trigger` method to trigger these events manually:
In order to attach a handler to it use the following:
```php
// this will trigger the event and cause $handler to be invoked:
Yii::$app->trigger($eventName);
Yii::$app->on($eventName, $handler);
```
Class Events
------------
You can also attach event handlers to all instances of a class instead of individual instances. To do so, use the static `Event::on` method:
It is possible to attach event handlers to all instances of a class instead of individual instances. To do so, use
the static `Event::on` method:
```php
Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment