Reputation: 482
I have login form, and after the user successfully logs in, I want an event to fire. The event must have two functions sendMail
and notification
. To achieve this I have done the following steps:
EVENT_NEW_USER
constant.sendMail
and notification
functions.init
function, in which I try to attach my functions to the event.Here is how my model code looks like:
<?php
namespace app\models;
use yii\base\Component;
class User extends \yii\db\ActiveRecord implements \yii\web\IdentityInterface
{
const EVENT_NEW_USER='new_user';
public function sendMail($event){
echo 'mail sent to admin';
}
public function notification($event){
echo 'notification created';
}
public function init(){
$this->on(self::EVENT_NEW_USER, [$this, 'sendMail']);
$this->on(self::EVENT_NEW_USER, [$this, 'notification']);
parent::init();
}
}
Inside my actionLogin
function of my controller I check if the user has logged in and try to make the event work with trigger
:
public function actionLogin()
{
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
$model->trigger(User::EVENT_NEW_USER);
}
else{
return $this->render('login',['model' => $model]);
}
}
But I am getting a blank page. What is not correct in my code and how can I fix it?
Upvotes: 0
Views: 620
Reputation: 23738
What looks like you are trying to create an event for the afterLogin
, I would attach it to the controller rather than the model, and I would use a conventional approach to do that so you keep your code separate and clean.
Add a constant in the controller where you have the login action
const EVENT_AFTER_LOGIN = 'afterLogin';
Create an event handler class and add a handler function that would send the email
<?php
namespace common\components\handlers;
class LoginHandler
{
/**
* Handles the after login event process to send emails
*
* @param FormEvent $event Event object form
*
* @return null
*/
public static function handleAfterLogin(\common\components\events\FormEvent $event)
{
///.. your code to send emails
}
}
Create a FormEvent
class
<?php
namespace common\components\events;
use yii\base\Event;
use yii\base\Model;
class FormEvent extends Event
{
/**
* @var Model
*/
private $_form;
/**
* @return Model
*/
public function getForm()
{
return $this->_form;
}
/**
* @param Model $form
*/
public function setForm(Model $form)
{
$this->_form = $form;
}
}
Create the init
function in your controller like below
public function init()
{
parent::init();
//bind after confirmation event
$this->on(
self::EVENT_AFTER_LOGIN,
[
new \common\components\handlers\LoginHandler(),
'handleAfterLogin',
]
);
}
Now add the following method in your controller
/**
* Return the FormEvent
*
* @param FormEvent $form the form model object
*
* @return FormEvent
* @throws \yii\base\InvalidConfigException
*/
protected function getFormEvent(\common\components\events\FormEvent $form)
{
return \Yii::createObject(['class' => \common\components\events\FormEvent::class, 'form' => $form]);
}
And then in your login action
public function actionLogin()
{
$model = Yii::createObject(LoginForm::class);
//get the event
$event = $this->getFormEvent($model);
if ($model->load(Yii::$app->request->post()) && $model->login()) {
//trigger the after login handler
$this->trigger(self::EVENT_AFTER_LOGIN, $event);
}
else{
return $this->render('login',['model' => $model]);
}
}
Now if you add print_r($event)
inside you handleAfterLogin
method you will see the object and its properties loaded with the user added info you can get the email using $event->username
or whatever field name you have and add your code to send email in the handleAfterLogin
.
Upvotes: 1