Using Afterlogin To Save User Login Time

Hi,

I’m trying to extend the built-in afterLogin method from \Web\User.php to save the user’s last login time.

I’ve put this code in my User model, but it is not called:




protected function afterLogin($identity, $cookieBased) {

	if(parent::afterLogin($identity, $cookieBased)) {

		$this->scenario = 'login';

		$this->last_login_timestamp = time();

		$this->save();

		return true;

	}

	return false;

}



My User class extends \yii\db\ActiveRecord and implements IdentityInterface.

Any clue what I am doing wrong?

I suppose parent::afterLogin does not return true, so your code block is not executed.

I also considered that, so I moved my code above the if block, but this also did not work…

My bad. It is not the identity event, it’s user component’s.

You can subscribe to it somewhere in app (for example, in module init() or wherever you like), like this:


Yii::$app->user->on('afterLogin', function($event) {

    echo 'testing event'; 

    exit;

});

I imagine that it’s failing validation and thus not saving. Have you checked if it actually reaches that code block?

I’m not sure. By now I have reverted to another approach: I moved this code into the LoginForm model as part of the login method.

Why? Better start debugging, maybe it’s a bug in Yii. There’s only a few methods involved anyway, just follow the flow in LoginForm::login(), User::login(), User::beforeLogin() and User::afterLogin(). And maybe Component::trigger() itself.

It’s not a bug.

As I’ve said before, it’s just an event of different object.

If you subscribe to user component instead of user identity - overything works as expected.

Btw I wonder where’s the best place for subscribing to events. Any idea?

init()? class itself? some external file?..

I managed to implement this by setting my configuration file for the user component as follows


'user' => [

            'identityClass' => 'common\models\User',

            'enableAutoLogin' => true,

            'on afterLogin' => function($event)

            {

                Yii::$app->user->identity->afterLogin($event);

            }

        ],

I also added a field LastLoginDate to the database,

and in my User model (which implemented the IdentityInterface), I added this function:


public function afterLogin($event)

    {

        $this->LastLoginDate = gmdate("Y-m-d H:i:s");

        $this->save();

    }

I think this is the right case to use behavior:




<?php


use yii\db\Expression;


class User extends ActiveRecord implements IdentityInterface

{

    public function behaviors()

    {

        return [

            'timestamp' => [

                'class' => 'yii\behaviors\TimestampBehavior',

                'attributes' => [

                    \yii\web\User::EVENT_AFTER_LOGIN => ['last_login_timestamp'],

                ],

                'value' => new Expression('NOW()'),

            ],

        ];

    }

}



instead of extending afterLogin().

Same question here!

Best solutions is here, follow this wiki -

How to get & store Last Login DateTime in database

http://www.yiiframework.com/wiki/742/how-to-get-store-last-login-datetime-in-database/