首页 > 解决方案 > Yii2 : 创建自定义全局事件

问题描述

我有登录表单,在用户成功登录后,我希望触发一个事件。事件必须有两个函数sendMailnotification。为此,我执行了以下步骤:

  1. 在我的用户模型中创建一个EVENT_NEW_USER常量。
  2. 创建sendMailnotification功能。
  3. 创建一个init函数,在其中我尝试将我的函数附加到事件中。

这是我的模型代码的样子:

<?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(); 
    }
}

在我actionLogin的控制器功能中,我检查用户是否已登录并尝试使事件与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]);
    }
}

但我得到一个空白页。我的代码中有什么不正确的地方,我该如何解决?

标签: phpeventsyii2

解决方案


看起来您正在尝试为afterLogin.

在具有登录操作的控制器中添加一个常量

const EVENT_AFTER_LOGIN = 'afterLogin';

创建一个事件处理程序类并添加一个将发送电子邮件的处理程序函数

<?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 
    }
}

创建一个FormEvent

<?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;
    }
}

在您的控制器中创建init函数,如下所示

public function init()
{
        parent::init();

        //bind after confirmation event
        $this->on(
            self::EVENT_AFTER_LOGIN,
            [
                new \common\components\handlers\LoginHandler(),
                'handleAfterLogin',
            ]
        );
}

现在在您的控制器中添加以下方法

 /**
 * 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]);
}

然后在您的登录操作中

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]);
    }
}

现在,如果您print_r($event)handleAfterLogin方法中添加,您将看到加载了用户添加信息的对象及其属性,您可以使用$event->username或您拥有的任何字段名称获取电子邮件,并添加代码以在handleAfterLogin.


推荐阅读