X

Yii2: Не работает afterLogin событие.

Столкнулся с необходимостью обновлять дату последнего логина пользователя. Задача вроде бы простая, тем более событие EVENT_AFTER_LOGIN существует из коробки. Но, по какой-то причине подписка на него в моей модели, не заработала..

Обработка логина тут: /vendor/yiisoft/yii2/web/User.php [method: login]
Само событие находится вот тут: /vendor/yiisoft/yii2/web/User.php [method: afterLogin]

    protected function afterLogin($identity, $cookieBased, $duration)
    {
        $this->trigger(self::EVENT_AFTER_LOGIN, new UserEvent([
            'identity' => $identity,
            'cookieBased' => $cookieBased,
            'duration' => $duration,
        ]));
    }

Я пытался подписаться в моей модели, вот так

Файл: /models/User.php

class User extends ActiveRecord implements IdentityInterface {
...
   public function init()
   {
      $this->on(Yii\web\User::EVENT_AFTER_LOGIN, [$this, 'updateLastLogin']);
      parent::init();
   }

   public function updateLastLogin()
   {
      $this->last_logged_at = time();
      $this->save(); 
   }
...
}

но, метод updateLastLogin() по какой-то причине так и не вызывался, хотя init() отрабатывал..

Дебажить было лень, поэтому я расчехлил костылемет, и пофиксил это вот так:

В модели оставляем только метод updateLastLogin, файл: /models/User.php

class User extends ActiveRecord implements IdentityInterface {
...
   public function updateLastLogin()
   {
      $this->last_logged_at = time();
      $this->save(); 
   }
...
}

а вызов события описываем в конфигурации, в файле: /config/web.php

<?php

$params = require __DIR__ . '/params.php';
$db = require __DIR__ . '/db.php';

$config = [
    ...
    'components' => [
        ...
        'user' => [
            'identityClass' => 'app\models\User',
            'enableAutoLogin' => true,
            'on '.\yii\web\User::EVENT_AFTER_LOGIN => function (\yii\web\UserEvent $event) {
                /** @var \app\models\User $identity */                $identity = $event->identity;
                $identity->updateLastLogin();
            },
        ],
....
];

** обратите внимание, что после "on" должен стоять пробел, это не опечатка.

После такого знатного костыля все стало работать как надо 🙂

--[добавлено позже]--

Для тех кто использует Advanced темплейт проекта, есть вариант пофиксить через bootstrap.php

use yii\base\Event;
use yii\web\User;

Event::on(User::className(), User::EVENT_AFTER_LOGIN, function(\yii\web\UserEvent $event) {
    /** @var \app\models\User $identity */    $identity = $event->identity;
    $identity->updateLastLogin();
});
Категории: Yii