Yii2 - 使用了错误的用户模型 class

Yii2 - Wrong User model class being used

我的应用程序建立在 'advanced' Yii2 应用程序模板上,我的 User class 建立在 Yii2-user 模块上。

该应用程序似乎使用自定义 User 模型 class dektrium\user\Module 来处理注册,因为我添加的自定义字段在注册时存储在数据库中,使用register() 供应商的方法 User class 来执行数据库持久化操作。

当我访问帐户设置页面时,使用操作 /user/settings/account 用于显示 User 数据的模型 class 实际上是 common/model/User,如下所示使用 get_class() 并且我无法使用自定义模型 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 class 其中 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 <dmeroff@gmail.com>
 */
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 对象都应该是自定义的 class,这样我就可以访问新的 properties/methods?

目前,我已将 common/models/User class 更改为简单的 extend dektrium/user/models/User 中的 User,公共 [=] 中没有实际代码14=] class。

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 用户模块使用的每个模型都有一个条目。