[Unsolved - Delete]AttributeBehavior - Save attributes after user login (not working)

Hi.

I want to add a functionality to the user login.

After the user successfully logged in then the logged in time and logged in ip address have to be saved.

So I created an AttributeBehavior for handle this situation:


<?php


namespace common\components\behaviors;


use Yii;

use yii\behaviors\AttributeBehavior;

use yii\web\User;


/**

 * Class LoginBehavior

 * @package common\components\behaviours

 */

class LoginBehavior extends AttributeBehavior

{

    /**

     * @var string the attribute that will receive ip address

     */

    public $loggedInIpAttribute = 'logged_in_ip';


    /**

     * @var integer the attribute that will receive timestamp value.

     */

    public $loggedInAtAttribute = 'logged_in_at';


    /**

     * @var string|integer

     */

    public $value;


    /**

     * @inheritdoc

     */

    public function init()

    {

        parent::init();

        if (empty($this->attributes)) {

            $this->attributes = [

                User::EVENT_AFTER_LOGIN => [$this->loggedInIpAttribute, $this->loggedInAtAttribute],

            ];

        }


        /* @var $owner \yii\db\BaseActiveRecord */

        $owner = $this->owner;


        if ($owner !== null) {

            $owner->updateAttributes([

                'logged_in_ip' => $this->getLoggedInIpAttribute(),

                'logged_in_at' => $this->getLoggedInAtAttribute()

            ]);

        }

    }


    /**

     * @return string of logged in ip of user

     */

    public function getLoggedInIpAttribute()

    {

        if ($this->getLoggedInIpAttribute() === null) {

            $this->setLoggedInIpAttribute(Yii::$app->request->userIP);

        }

        return $this->loggedInIpAttribute;

    }


    /**

     * Set logged in ip of current user.

     * @param $loggedInIpAttribute string

     */

    public function setLoggedInIpAttribute($loggedInIpAttribute)

    {

        $this->loggedInIpAttribute = $loggedInIpAttribute;

    }


    /**

     * @return integer timestamp of logged in

     */

    public function getLoggedInAtAttribute()

    {

        if ($this->getLoggedInAtAttribute() === null) {

            $this->setLoggedInAtAttribute(time());

        }

        return $this->loggedInAtAttribute;

    }


    /**

     * Set logged in time of current user

     * @param $loggedInAtAttribute integer timestamp

     */

    public function setLoggedInAtAttribute($loggedInAtAttribute)

    {

        $this->loggedInAtAttribute = $loggedInAtAttribute;

    }

}

And I added this behavior to the user model:


/**

 * User model

 *

 * @property integer $id

 * @property string $username

 * @property string $password_hash

 * @property string $password_reset_token

 * @property string $email

 * @property string $auth_key

 * @property integer $status

 * @property string $signed_in_ip

 * @property string $logged_in_ip

 * @property integer $logged_in_at

 * @property integer $created_at

 * @property integer $updated_at

 * @property string $password write-only password

 */

class User extends ActiveRecord implements IdentityInterface

{

    /**

     * @inheritdoc

     */

    public function behaviors()

    {

        return [

            TimestampBehavior::className(),

            LoginBehavior::className(),

        ];

    }

But this is not work, because after the login the logged_in_at and logged_in_ip records are empty in the database.

Does somebody can help me how to save these records?

(I tried to "copy" the TimestampBehavior, but I do not understand how does it can save the attributes)

This is the function which is included in the Yii-advanced package inside the SiteController.php




    public function actionLogin()

    {

        if (!\Yii::$app->user->isGuest) {

            return $this->goHome();

        }


        $model = new LoginForm();

        if ($model->load(Yii::$app->request->post()) && $model->login()) {

            return $this->goBack();

        } else {

            return $this->render('login', [

                'model' => $model,

            ]);

        }

    }




if you modify this slightly as follows:




    public function actionLogin()

    {

        if (!\Yii::$app->user->isGuest) {

            return $this->goHome();

        }


        $model = new LoginForm();

        if ($model->load(Yii::$app->request->post()) && $model->login()) {

            LoginForm::saveIp($bla, $bla);//You can use either $_SERVER variables or request parameters provided by Yii

            return $this->goBack();

        } else {

            return $this->render('login', [

                'model' => $model,

            ]);

        }

    }




A simple way to do it is to extend yii\web\User and override afterLogin()




protected function afterLogin($identity, $cookieBased, $duration)

{

  parent::afterLogin($identity, $cookieBased, $duration);

  \app\models\User::updateAll(['logged_in_at' => '...', 'logged_in_ip' => '...'], ['id' => $identity->getId()]);

}



Can be implemented as a reusable behavior, too, but I’m not sure it’s worth the effort because of the differences in user data storage (table schemas, etc.) between applications.