Yii2 - используется неправильный класс модели пользователя

Мое приложение построено на «расширенном» шаблоне приложения Yii2, а мой класс User построен на пользователе Yii2 модуль.

Похоже, что приложение использует пользовательский User класс модели dektrium\user\Module для обработки регистрации, поскольку настраиваемые поля, которые я добавил, сохраняются в базе данных при регистрации, используя метод register() класса поставщика User для выполнения операций сохранения базы данных.

Когда я получаю доступ к странице настроек учетной записи, используя действие /user/settings/account, класс модели, используемый для отображения данных User, на самом деле является common/model/User, как показано с помощью get_class(), и я не могу использовать ни один из новых методов, определенных в пользовательском классе модели.

Основной файл конфигурации.

return [
   'components' => [
       'db' => [
           'class' => 'yii\db\Connection',
           'dsn' => 'mysql:host=localhost;dbname=DBNAME',
           'username' => 'DBUSER',
           'password' => 'DBPASS',
           'charset' => 'utf8',
       ],
       'mailer' => [
           'class' => 'yii\swiftmailer\Mailer',
           'viewPath' => '@common/mail',
           // send all mails to a file by default. You have to set
           // 'useFileTransport' to false and configure a transport
           // for the mailer to send real emails.
           'useFileTransport' => false,
       ],
   ],
   'modules' => [
       'user' => [
           'class' => 'dektrium\user\Module',
       ],
       'rbac' => [
           'class' => 'dektrium\rbac\Module'
       ],
   ],
];

И класс SettingsForm, который имеет свойство User.

<?php

/*
 * This file is part of the Dektrium project.
 *
 * (c) Dektrium project <http://github.com/dektrium/>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace dektrium\user\models;

use dektrium\user\helpers\Password;
use dektrium\user\Mailer;
use dektrium\user\Module;
use yii\base\Model;
use yii\base\NotSupportedException;

/**
 * SettingsForm gets user's username, email and password and changes them.
 *
 * @property User $user
 *
 * @author Dmitry Erofeev <[email protected]>
 */
class SettingsForm extends Model
{
    /** @var string */
    public $email;

    /** @var string */
   // public $username;

    /** @var string */
    public $new_password;

    /** @var string */
    public $current_password;

    /** @var Module */
    protected $module;

    /** @var Mailer */
    protected $mailer;

    /** @var User */
    private $_user;

    /** @return User */
    public function getUser()
    {
        if ($this->_user == null) {
            $this->_user = \Yii::$app->user->identity;
        }
        return $this->_user;
    }

    /** @inheritdoc */
    public function __construct(Mailer $mailer, $config = [])
    {
        $this->mailer = $mailer;
        $this->module = \Yii::$app->getModule('user');
        $this->setAttributes([
            //'username' => $this->user->username,
            'email'    => $this->user->unconfirmed_email ?: $this->user->email
        ], false);
        parent::__construct($config);
    }

    /** @inheritdoc */
    public function rules()
    {
        return [
          //  'usernameRequired' => ['username', 'required'],
          //  'usernameTrim' => ['username', 'filter', 'filter' => 'trim'],
          //  'usernameLenth' => ['username', 'string', 'min' => 3, 'max' => 20],
          //  'usernamePattern' => ['username', 'match', 'pattern' => '/^[-a-zA-Z0-9_\.@]+$/'],
            'emailRequired' => ['email', 'required'],
            'emailTrim' => ['email', 'filter', 'filter' => 'trim'],
            'emailPattern' => ['email', 'email'],
           // 'emailUsernameUnique' => [['email', 'username'], 'unique', 'when' => function ($model, $attribute) {
           //     return $this->user->$attribute != $model->$attribute;
           // }, 'targetClass' => $this->module->modelMap['User']],
            'newPasswordLength' => ['new_password', 'string', 'min' => 6],
            'currentPasswordRequired' => ['current_password', 'required'],
            'currentPasswordValidate' => ['current_password', function ($attr) {
                if (!Password::validate($this->$attr, $this->user->password_hash)) {
                    $this->addError($attr, \Yii::t('user', 'Current password is not valid'));
                }
            }]
        ];
    }

    /** @inheritdoc */
    public function attributeLabels()
    {
        return [
            'email'            => \Yii::t('user', 'Email'),
            'username'         => \Yii::t('user', 'Username'),
            'new_password'     => \Yii::t('user', 'New password'),
            'current_password' => \Yii::t('user', 'Current password')
        ];
    }

    /** @inheritdoc */
    public function formName()
    {
        return 'settings-form';
    }

    /**
     * Saves new account settings.
     *
     * @return bool
     */
    public function save()
    {
        if ($this->validate()) {
          //  $this->user->scenario = 'settings';
         //   $this->user->username = $this->username;
            $this->user->password = $this->new_password;
            if ($this->email == $this->user->email && $this->user->unconfirmed_email != null) {
                $this->user->unconfirmed_email = null;
            } else if ($this->email != $this->user->email) {
                switch ($this->module->emailChangeStrategy) {
                    case Module::STRATEGY_INSECURE:
                        $this->insecureEmailChange(); break;
                    case Module::STRATEGY_DEFAULT:
                        $this->defaultEmailChange(); break;
                    case Module::STRATEGY_SECURE:
                        $this->secureEmailChange(); break;
                    default:
                        throw new \OutOfBoundsException('Invalid email changing strategy');
                }
            }
            return $this->user->save();
        }

        return false;
    }

    /**
     * Changes user's email address to given without any confirmation.
     */
    protected function insecureEmailChange()
    {
        $this->user->email = $this->email;
        \Yii::$app->session->setFlash('success', \Yii::t('user', 'Your email address has been changed'));
    }

    /**
     * Sends a confirmation message to user's email address with link to confirm changing of email.
     */
    protected function defaultEmailChange()
    {
        $this->user->unconfirmed_email = $this->email;
        /** @var Token $token */
        $token = \Yii::createObject([
            'class'   => Token::className(),
            'user_id' => $this->user->id,
            'type'    => Token::TYPE_CONFIRM_NEW_EMAIL
        ]);
        $token->save(false);
        $this->mailer->sendReconfirmationMessage($this->user, $token);
        \Yii::$app->session->setFlash('info', \Yii::t('user', 'A confirmation message has been sent to your new email address'));
    }

    /**
     * Sends a confirmation message to both old and new email addresses with link to confirm changing of email.
     * @throws \yii\base\InvalidConfigException
     */
    protected function secureEmailChange()
    {
        $this->defaultEmailChange();
        /** @var Token $token */
        $token = \Yii::createObject([
            'class'   => Token::className(),
            'user_id' => $this->user->id,
            'type'    => Token::TYPE_CONFIRM_OLD_EMAIL
        ]);
        $token->save(false);
        $this->mailer->sendReconfirmationMessage($this->user, $token);

        // unset flags if they exist
        $this->user->flags &= ~User::NEW_EMAIL_CONFIRMED;
        $this->user->flags &= ~User::OLD_EMAIL_CONFIRMED;
        $this->user->save(false);

        \Yii::$app->session->setFlash('info', \Yii::t('user', 'We have sent confirmation links to both old and new email addresses. You must click both links to complete your request'));
    }
}

Свойство module показывает, что тип является пользовательским User, но _user взят из /common/models/User.

Я что-то пропустил, чтобы сказать, что любые объекты User должны относиться к пользовательскому классу, чтобы я мог получить доступ к новым свойствам/методам?


person Pedro del Sol    schedule 17.04.2015    source источник
comment
Есть разница между компонентом User и моделью User. Первый обрабатывает задачи аутентификации и т. д., а второй представляет собой базу данных ActiveRecord. (то есть: Yii::$app->user - это модуль, Yii::$app->user->getIdentity() возвращает модель. Расширенный шаблон создает базовую модель пользовательского шаблона в /common/models/User, вы можете отредактировать ее, если необходимо. Возможно, вы также могли бы расширить ее и настроить компонент User для использования вместо этого расширенного класса.   -  person Pomme.Verte    schedule 17.04.2015


Ответы (1)


На данный момент я изменил класс common/models/User на просто extend User в dektrium/user/models/User без фактического кода в общем классе User.

class User extends \dektrium\user\models\User {}

На данный момент это решило мою проблему, но похоже на действительно плохое решение. Любой дополнительный вклад будет принят с благодарностью...

Редактировать:

Я и забыл про этот вопрос-ответ...

в моем common/config/main.php, где объявлен модуль user, в modelMap я могу указать использовать свою собственную модель пользователя, что-то вроде следующего.

'modules' => [
    'user' => [
        'class' => 'dektrium\user\Module',

        'modelMap' => [
            'User'                => 'common\models\User',
        ],

Где есть запись для каждой модели, используемой пользовательским модулем dektrium.

person Pedro del Sol    schedule 20.04.2015