Listening for logout event in Yii 2

情到浓时终转凉″ 提交于 2019-12-10 17:38:12

问题


So I know that Yii::$app->user triggers these events in the logout process.

const EVENT_BEFORE_LOGIN = 'beforeLogin';
const EVENT_AFTER_LOGIN = 'afterLogin';

But where is the right place to add a listener at the beginning of each request?


回答1:


The best place would be in the class which handles the identity of yii/web/User; usually, this is common/models/User.

In that class, you can have the following initialization.

public function registerLogoutHook()
{
    $this->on(\yii\web\User::EVENT_AFTER_LOGOUT, function ($e) {
        Yii::$app->controller->goHome();
    });
}

You may choose to register this on the web User object [of identity `common/models/User] who successfully logged in. The logic could be as follows

// [ ... omitted code ... ]
// $model is an instance of LoginForm
if ($model->load(Yii::$app->request->post()) && $model->login()) {
    Yii::$app->user->identity->registerLogoutHook();
    return $this->redirect(['customers/view', 'id' => Yii::$app->user->identity->id]);
}
// [ ... omitted code ... ]

EDIT (:

Another way to get this working as of now ("yiisoft/yii2":"2.0.7") is to add the event handler to your config file. This way all handlers are setup early on in the application life cycle.

So in your main.php you would be returning...

[
    // ... some other things ...
    'components' => [
        // ... some other components ...
        'user' => [
            // ... some configuration for yii\web\User ...
            'on beforeLogout' => function ($e) {
                Yii::trace('Logout events are working!!!');
            },
            // ... more configurations for yii\web\User ...
        ],
        // ... some more components ...
    ],
    // ... some more things
]

For the handler, you could either use a callback, the name of a function or an array specifying the object and its method to be called. These methods of registering an event are enumerated here.

beforeLogout can be changed to any of the events raised by yii\web\User




回答2:


After a lot of digging through the code, I finally found whats the problem. You might think that since you are passing your User model as an identity to the logout function and assigning events to it it will work, but actually the events of current Component are being triggered.

So that means, if you do what was suggested above and assign the event to your User model, it will not get triggered. Instead you need to assign the event to the User component itself.

My solution (that actually works)

In your User model:

public static function beforeLogoutHook(){
    // Do whatever
}

Somewhere in your code I recommend doing this in some global place In my case my master controller that is being extended by other controllers.

public function auth(){
    $user = new User();
    $user->setAttributes($attributes,false);

    Yii::$app->user->login($user);

    Yii::$app->user->on(\yii\web\User::EVENT_BEFORE_LOGOUT,function($e){
        User::beforeLogout();
    });
}

Now you can simply call Yii::$app->user->logout(); whereever you need and the beforeLogout event will get executed.

I have chosen to declare the function that does the work before logout in my User model to make it easier to find and edit.



来源:https://stackoverflow.com/questions/28384168/listening-for-logout-event-in-yii-2

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!