I've been through the documentation and all the articles on Yii2 events
found using Google. Can someone provide me a good example of how events can be used in Yii2 and where it may seem logical?
I can explain events by a simple example. Let's say, you want to do few things when a user first registers to the site like:
You may try to call a few methods after a user object is successfully saved. Maybe like this:
if($model->save()){
$mailObj->sendNewUserMail($model);
$notification->setNotification($model);
}
So far it may seem fine but what if the number of requirements grows with time? Say 10 things must happen after a user registers himself? Events come handy in situations like this.
Basics of events
Events are composed of the following cycle.
User
model. Like const EVENT_NEW_USER='new_user';
. This is used to add handlers and to trigger an event.$event
parameter. We call this method a handler.model
using its a method called on()
. You can call this method many times you wish - simply you can attach more than one handler to a single event.trigger()
.Note that, all the methods mentioned above are part of Component
class. Almost all classes in Yii2 have inherited form this class. Yes ActiveRecord
too.
Let's code
To solve above mentioned problem we may have User.php
model. I'll not write all the code here.
// in User.php i've declared constant that stores event name
const EVENT_NEW_USER = 'new-user';
// say, whenever new user registers, below method will send an email.
public function sendMail($event){
echo 'mail sent to admin';
// you code
}
// one more hanlder.
public function notification($event){
echo 'notification created';
}
One thing to remember here is that you're not bound to create methods in the class that creates an event. You can add any static, non static method from any class.
I need to attach above handlers to the event . The basic way I did is to use AR's init()
method. So here is how:
// this should be inside User.php class.
public function init(){
$this->on(self::EVENT_NEW_USER, [$this, 'sendMail']);
$this->on(self::EVENT_NEW_USER, [$this, 'notification']);
// first parameter is the name of the event and second is the handler.
// For handlers I use methods sendMail and notification
// from $this class.
parent::init(); // DON'T Forget to call the parent method.
}
The final thing is to trigger an event. Now you don't need to explicitly call all the required methods as we did before. You can replace it by following:
if($model->save()){
$model->trigger(User::EVENT_NEW_USER);
}
All the handlers will be automatically called.
For "global" events.
Optionally you can create a specialized event class
namespace your\handler\Event\Namespace;
class EventUser extends Event {
const EVENT_NEW_USER = 'new-user';
}
define at least one handler class:
namespace your\handler\Event\Namespace;
class handlerClass{
// public AND static
public static function handleNewUser(EventUser $event)
{
// $event->user contain the "input" object
echo 'mail sent to admin for'. $event->user->username;
}
}
Inside the component part of the config under (in this case) the user component insert you event:
'components' => [
'user' => [
...
'on new-user' => ['your\handler\Event\Namespace\handlerClass', 'handleNewUser'],
],
...
]
Then in your code you can trigger the event:
Yii::$app->user->trigger(EventUser::EVENT_NEW_USER, new EventUser($user));
ADD
You can also use a closure:
example:
'components' => [
'user' => [
...
'on new-user' => function($param){ your\handler\Event\Namespace\handlerClass::handleNewUser($param);},
'on increment' => function($param){ \Yii::$app->count += $param->value;},
],
...
]
By default Yii2 already provide some event declaration, You can read more about explanation on BaseActiveRecord.
You can use this variable as same as declaring it manually.
public function init()
{
parent::init();
$this->on(self::EVENT_AFTER_INSERT, [$this, 'exampleMethodHere']);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With