Как правильно отнаследоваться от User?

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Neophyte
Сообщения: 3
Зарегистрирован: 2018.11.08, 21:58

Как правильно отнаследоваться от User?

Сообщение Neophyte » 2018.11.08, 22:04

Ситуация следующая. Есть модель которая наследуется от ActiveRecord и реализует Identity Interface

Код: Выделить всё

<?php
namespace common\models;

use Yii;
use yii\base\NotSupportedException;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
use backend\models\LegalRepresentative;

/**
 * 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 integer $created_at
 * @property integer $updated_at
 * @property string $password write-only password
 */
class User extends ActiveRecord implements IdentityInterface
{
    const STATUS_DELETED = 0;
    const STATUS_ACTIVE = 10;
    const ROLE_USER = 1;
    const ROLE_MODERATOR = 5;
    const ROLE_ADMINISTRATOR = 10;

    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return '{{%user}}';
    }

    /**
     * {@inheritdoc}
     */
    public function behaviors()
    {
        return [
            TimestampBehavior::className(),
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            ['status', 'default', 'value' => self::STATUS_ACTIVE],
            ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],
            [['surname','patronymic','name'], 'string', 'max' => 50],
            ['live_place', 'string', 'max' => 100],
            [['date_of_birth'], 'safe'],
            [['level_education_id','position_id','organization_id', 'organization_study_id', 'organization_inn', 'flat'], 'integer']
        ];
    }

    /**
     * {@inheritdoc}
     */
    public static function findIdentity($id)
    {
        return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
    }

    /**
     * {@inheritdoc}
     */
    public static function findIdentityByAccessToken($token, $type = null)
    {
        throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
    }

    /**
     * Finds user by username
     *
     * @param string $username
     * @return static|null
     */
    public static function findByUsername($username)
    {
        return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);
    }

    /**
     * Finds user by password reset token
     *
     * @param string $token password reset token
     * @return static|null
     */
    public static function findByPasswordResetToken($token)
    {
        if (!static::isPasswordResetTokenValid($token)) {
            return null;
        }

        return static::findOne([
            'password_reset_token' => $token,
            'status' => self::STATUS_ACTIVE,
        ]);
    }

    /**
     * Finds out if password reset token is valid
     *
     * @param string $token password reset token
     * @return bool
     */
    public static function isPasswordResetTokenValid($token)
    {
        if (empty($token)) {
            return false;
        }

        $timestamp = (int) substr($token, strrpos($token, '_') + 1);
        $expire = Yii::$app->params['user.passwordResetTokenExpire'];
        return $timestamp + $expire >= time();
    }

    /**
     * {@inheritdoc}
     */
    public function getId()
    {
        return $this->getPrimaryKey();
    }

    /**
     * {@inheritdoc}
     */
    public function getAuthKey()
    {
        return $this->auth_key;
    }

    public function getLegalRepresentative()
    {
        return $this->hasOne(LegalRepresentative::className(), ['id' => 'legal_representative_id']);
    }

    /**
     * {@inheritdoc}
     */
    public function validateAuthKey($authKey)
    {
        return $this->getAuthKey() === $authKey;
    }

    /**
     * Validates password
     *
     * @param string $password password to validate
     * @return bool if password provided is valid for current user
     */
    public function validatePassword($password)
    {
       return Yii::$app->security->validatePassword($password, $this->password_hash);
    }

    /**
     * Generates password hash from password and sets it to the model
     *
     * @param string $password
     */
    public function setPassword($password)
    {
        $this->password_hash = Yii::$app->security->generatePasswordHash($password);
    }

    /**
     * Generates "remember me" authentication key
     */
    public function generateAuthKey()
    {
        $this->auth_key = Yii::$app->security->generateRandomString();
    }

    /**
     * Generates new password reset token
     */
    public function generatePasswordResetToken()
    {
        $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();
    }

    /**
     * Removes password reset token
     */
    public function removePasswordResetToken()
    {
        $this->password_reset_token = null;
    }


}
От него необходимо отнаследовать модель и использовать ее для других целей
Собственно модель

Код: Выделить всё

<?php
/**
 * Created by PhpStorm.
 * User: user
 * Date: 08.11.2018
 * Time: 14:08
 */

namespace frontend\models;

use Yii;

use common\models\User;
use yii\web\IdentityInterface;

class UserPersonalArea extends User implements IdentityInterface
{
    public $phone;
    public $password;

    public static function tableName()
    {
        return 'user';
    }


    public function rules()
    {
        return [
            //ВАЛИДАЦИЯ ТИПОВ ДАННЫХ--------------------------------------------------------
            [['phone', 'password'], 'string'],
            //ВАЛИДАЦИЯ ТИПОВ ДАННЫХ--------------------------------------------------------

            ['password', 'validatePassword'],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public static function findIdentity($id)
    {
        parent::findIdentity($id);
    }

    /**
     * {@inheritdoc}
     */
    public static function findIdentityByAccessToken($token, $type = null)
    {
        parent::findIdentityByAccessToken($token, $type);
    }

    /**
     * {@inheritdoc}
     */
    public function getId()
    {
        parent::getId();
    }

    /**
     * {@inheritdoc}
     */
    public function getAuthKey()
    {
        parent::getAuthKey();
    }
    /**
     * {@inheritdoc}
     */
    public function validateAuthKey($authKey)
    {
        parent::validateAuthKey();
    }


    public function login()
    {
        if ($this->validate()) {

            $result = Yii::$app->user->login($this->userExists(), 0);

            return $result;
        }
        return false;
    }

    public function userExists()
    {
        $user = User::findByUsername($this->phone);
        //var_dump($user);

        if (!$user)
            return false;
        else {
            return $user;
        }
    }

    public function validatePassword($password)
    {
        parent::validatePassword($password);
    }


    public function setPassword($password)
    {
        $this->password_hash = Yii::$app->security->generatePasswordHash($password);
    }

    /**
     * Generates "remember me" authentication key
     */
    public function generateAuthKey()
    {
        parent::generateAuthKey();
    }

    /**
     * Generates new password reset token
     */
    public function generatePasswordResetToken()
    {
        parent::generatePasswordResetToken();
    }

    /**
     * Removes password reset token
     */
    public function removePasswordResetToken()
    {
        parent::removePasswordResetToken();
    }
}
Но при вызове Yii::$app->user->login($this->userExists(), 0); ругается на первый аргумент и что мол класс не реализует Identity Interface, хотя он реализован делегированием ключевых методов родителю. Нужна помощь, не понимаю что ему надо от меня

slo_nik
Сообщения: 259
Зарегистрирован: 2013.10.07, 19:08

Re: Как правильно отнаследоваться от User?

Сообщение slo_nik » 2018.11.08, 23:59

Добрый вечер.
implements IdentityInterface лишнее во второй модели.

Neophyte
Сообщения: 3
Зарегистрирован: 2018.11.08, 21:58

Re: Как правильно отнаследоваться от User?

Сообщение Neophyte » 2018.11.09, 06:06

Без него ровно та же ошибка возникает, уже не знаю что и делать

Аватара пользователя
proctoleha
Сообщения: 198
Зарегистрирован: 2016.07.10, 19:00

Re: Как правильно отнаследоваться от User?

Сообщение proctoleha » 2018.11.09, 07:28

Код: Выделить всё

    public function userExists()
    {
        $user = User::findByUsername($this->phone);
        //var_dump($user);

        if (!$user)
            return false;
        else {
            return $user;
        }
    }
$this->phone? Или все-таки должно быть username?
Выбрасывайте лучше исключение вместо return false; Или введите дополнительную проверку, что в методе логин вам не пришло false (что скорей всего и происходит)

Код: Выделить всё

    public function userExists()
    {
    	// если ищете все таки по телефону то реализуйте метод findByUserPhone
        if (!$user = User::findByUserPhone($this->phone)) {
        	throw new \DomainException('User not found');
        }
	return $user;
    }
Вот за что я не люблю линукс, так это за свои кривые, временами, руки

slo_nik
Сообщения: 259
Зарегистрирован: 2013.10.07, 19:08

Re: Как правильно отнаследоваться от User?

Сообщение slo_nik » 2018.11.10, 21:07

Neophyte писал(а):
2018.11.09, 06:06
Без него ровно та же ошибка возникает, уже не знаю что и делать
Так же удалите необходимые методы для IdentityInterface во второй модели.

Ответить