yii2 dektrium с phundamental - добавление дополнительных полей в профиль пользователя

Обновлено и работает нормально после ответа Виталия :)

Я работаю в проекте с открытым исходным кодом: https://github.com/open-ecommerce/helptext

И я пытаюсь добавить поля в модуль dektrium Yii2-user. В репозитории есть пример добавления дополнительных полей в таблицу пользователей: https://github.com/dektrium/yii2-user/blob/master/docs/adding-new-field-to-user-model.md но я не могу заставить его работать с таблицей профилей, которая поставляется с модулем.

Я использую следующие репозитории, которые входят в метапакет dmstr/yii2-cms:

"dektrium/yii2-user": "^0.9.6",
"dektrium/yii2-rbac": "~0.2",

Например, я хочу, чтобы новое поле вызывало «навыки» в форме профиля в админке, поэтому

Сначала я выполнил миграцию, чтобы добавить поле в таблицу.

затем определил путь к моему собственному классу в main.php (я использую расширенный шаблон, но упрощаю по сути)

    Yii::setAlias('@app', dirname(__DIR__).'/..');
    Yii::setAlias('@runtime', dirname(__DIR__).'/../../runtime');
    Yii::setAlias('@web', dirname(__DIR__).'/../web');
    Yii::setAlias('@webroot', dirname(__DIR__).'/web');
    Yii::setAlias('@root', '@app');

    $common = [
        'id' => 'app',
        'language' => '',
        'basePath' => dirname(__DIR__),
        'vendorPath' => '@app/../vendor',
        'runtimePath' => '@app/../runtime',
        'bootstrap' => [
            'log',
        ],
        'aliases' => [
            '@frontmedia' => '@app/media',        
            '@admin-views' => '@app/modules/backend/views',
        ],
        'components' => [
            'assetManager' => [
                // Note: For using mounted volumes or shared folders
                'dirMode' => YII_ENV_PROD ? 0777 : null,
                'bundles' => getenv('APP_ASSET_USE_BUNDLED') ?
                    require(__DIR__.'/gen/bundle-prod.php') :
                    [
                        // Note: if your asset bundle includes bootstrap, you can disable the default asset
                        #'yii\bootstrap\BootstrapAsset' => false,
                    ],
                'basePath' => '@app/../web/assets',
            ],
            'authManager' => [
                'class' => 'yii\rbac\DbManager',
            ],
            'cache' => [
                'class' => 'yii\caching\FileCache',
            ],
            'db' => [
                'class' => 'yii\db\Connection',
                'dsn' => getenv('DATABASE_DSN'),
                'username' => getenv('DATABASE_USER'),
                'password' => getenv('DATABASE_PASSWORD'),
                'charset' => 'utf8',
                'tablePrefix' => getenv('DATABASE_TABLE_PREFIX'),
                'enableSchemaCache' => YII_ENV_PROD ? true : false,
            ],
            'i18n' => [
                'translations' => [
                    '*' => [
                        'class' => 'yii\i18n\DbMessageSource',
                        'db' => 'db',
                        'sourceLanguage' => 'en',
                        'sourceMessageTable' => '{{%language_source}}',
                        'messageTable' => '{{%language_translate}}',
                        'cachingDuration' => 86400,
                        'enableCaching' => YII_DEBUG ? false : true,
                    ],
                ],
            ],
            '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' => YII_ENV_PROD ? false : true,
            ],
            // Note: enable db sessions, if multiple containers are running
            #'session' => [
            #    'class' => 'yii\web\DbSession'
            #],
            'settings' => [
                'class' => 'pheme\settings\components\Settings',
            ],
            'urlManager' => [
                'class' => 'codemix\localeurls\UrlManager',
                'enablePrettyUrl' => getenv('APP_PRETTY_URLS') ? true : false,
                'showScriptName' => getenv('YII_ENV_TEST') ? true : false,
                'enableDefaultLanguageUrlCode' => true,
                'baseUrl' => '/',
                'rules' => [
                    'docs/<file:[a-zA-Z0-9_\-\./]+>' => 'docs',
                    #'docs' => 'docs/default/index',
                ],
                'languages' => explode(',', getenv('APP_LANGUAGES')),
            ],
            'user' => [
                'class' => 'app\components\User',
                'enableAutoLogin' => true,
                'loginUrl' => ['/user/security/login'],
                'identityClass' => 'dektrium\user\models\User',
                'rootUsers' => ['admin'],
            ],
            'view' => [
                'theme' => [
                    'pathMap' => [
                        '@vendor/dektrium/yii2-user/views/admin' => '@app/views/user/admin',
                        '@yii/gii/views/layouts' => '@admin-views/layouts',
                    ],
                ],
            ],

        ],
        'modules' => [
            'backend' => [
                'class' => 'app\modules\backend\Module',
                'layout' => '@admin-views/layouts/main',
            ],
            'pages' => [
                'class' => 'dmstr\modules\pages\Module',
                'layout' => '@admin-views/layouts/main',
                'availableRoutes' => [
                    '/site/index' => '/site/index',
                ],
            ],
            'prototype' => [
                'class' => 'dmstr\modules\prototype\Module',
                'layout' => '@admin-views/layouts/box',
            ],
            'user' => [
                'class' => 'dektrium\user\Module',
                'modelMap' => [
                    'profile' => 'app\models\Profile',
                ],
                'layout' => '@app/views/layouts/container',
                'defaultRoute' => 'profile',
                'adminPermission' => 'user-module',
                'enableFlashMessages' => false,
            ],
            'rbac' => [
                'class' => 'dektrium\rbac\Module',
                'layout' => '@admin-views/layouts/box',
                'enableFlashMessages' => false,
            ],
            'settings' => [
                'class' => 'pheme\settings\Module',
                'layout' => '@admin-views/layouts/box',
                'accessRoles' => ['settings-module'],
            ],
            'translatemanager' => [
                'class' => 'lajax\translatemanager\Module',
                'root' => '@app/views',
                'layout' => '@admin-views/layouts/box',
                'allowedIPs' => ['*'],
                'roles' => ['translate-module'],
            ],
            'gridview' => [
                'class' => '\kartik\grid\Module',
                // enter optional module parameters below - only if you need to  
                // use your own export download action or custom translation 
                // message source
                'downloadAction' => 'gridview/export/download',
            //'i18n' => [],           
            ],        
            'treemanager' => [
                'class' => '\kartik\tree\Module',
                'layout' => '@admin-views/layouts/main',
                'treeViewSettings' => [
                    'nodeView' => '@vendor/dmstr/yii2-pages-module/views/treeview/_form',
                    'fontAwesome' => true,
                ],
            ],
        ],
        'params' => [
            'adminEmail' => getenv('APP_ADMIN_EMAIL'),
            'yii.migrations' => [
                getenv('APP_MIGRATION_LOOKUP'),
                '@yii/rbac/migrations',
                '@dektrium/user/migrations',
                '@vendor/lajax/yii2-translate-manager/migrations',
                '@vendor/pheme/yii2-settings/migrations',
                '@vendor/dmstr/yii2-prototype-module/src/migrations',
            ],
        ],

    ];

    $web = [
        'components' => [
            'errorHandler' => [
                'errorAction' => 'site/error',
            ],
            // Logging
            'log' => [
                'targets' => [
                    // writes to php-fpm output stream
                    [
                        'class' => 'codemix\streamlog\Target',
                        'url' => 'php://stdout',
                        'levels' => ['info', 'trace'],
                        'logVars' => [],
                        'enabled' => YII_DEBUG,
                    ],
                    [
                        'class' => 'codemix\streamlog\Target',
                        'url' => 'php://stderr',
                        'levels' => ['error', 'warning'],
                        'logVars' => [],
                    ],
                ],
            ],
            'request' => [
                // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
                'cookieValidationKey' => getenv('APP_COOKIE_VALIDATION_KEY'),
            ],
            'user' => [
                'identityClass' => 'dektrium\user\models\User',
                //'admins' => ['admin'],
            ],
        ],
    ];

    $console = [
        'controllerNamespace' => 'app\commands',
        'controllerMap' => [
            'db' => 'dmstr\console\controllers\MysqlController',
            'migrate' => 'dmstr\console\controllers\MigrateController',
            'translate' => '\lajax\translatemanager\commands\TranslatemanagerController',
        ],
        'components' => [

        ],
    ];

    $allowedIPs = [
        '127.0.0.1',
        '::1',
        '192.168.*',
        '172.17.*',
    ];

// detecting current application type based on `php_sapi_name()` since we've no application ready yet.
if (php_sapi_name() == 'cli') {
    // Console application
    $config = \yii\helpers\ArrayHelper::merge($common, $console);
} else {
    // Web application
    if (YII_ENV_DEV) {
        // configuration adjustments for web 'dev' environment
        $common['bootstrap'][] = 'debug';
        $common['modules']['debug'] = [
            'class' => 'yii\debug\Module',
            'allowedIPs' => $allowedIPs,
        ];
    }
    $config = \yii\helpers\ArrayHelper::merge($common, $web);
}

if (YII_ENV_DEV || YII_ENV_TEST) {
    // configuration adjustments for 'dev' environment
    $config['bootstrap'][] = 'gii';
    $config['modules']['gii'] = [
        'class' => 'yii\gii\Module',
        'allowedIPs' => $allowedIPs,
    ];

    $giiant = require __DIR__.'/giiant.php';
    $config = \yii\helpers\ArrayHelper::merge($config, $giiant);
}

if (file_exists(getenv('APP_CONFIG_FILE'))) {
    // Local configuration, if available
    $local = require getenv('APP_CONFIG_FILE');
    $config = \yii\helpers\ArrayHelper::merge($config, $local);
}

return $config;

Это вызов класса models/Profile.php

namespace app\models;

use Yii;

use dektrium\user\models\Profile as BaseProfile;

class Profile extends BaseProfile
{

    public function scenarios()
    {
        $scenarios = parent::scenarios();

        // add skils to scenarios
        $scenarios['create'][]   = 'skills';
        $scenarios['update'][]   = 'skills';
        $scenarios['register'][] = 'skills';


        return $scenarios;
    }

    public function rules()
    {
        $rules = parent::rules();

        // add skills rules
        $rules['skillsRequired'] = ['skills', 'required'];
        $rules['skillsLength']   = ['skills', 'string', 'max' => 255];

        return $rules;
    }

    /** @inheritdoc */
    public function attributeLabels()
    {
        return [
            'skills' => Yii::t('userextended', 'This are the skills'),
        ];
    }

    /**
     * @return \yii\db\ActiveQueryInterface
     */
    public function getAccount()
    {
        return $this->hasOne($this->module->modelMap['Account'], ['user_id' => 'user_id']);
    }

    /**
     * @return \yii\db\ActiveQueryInterface
     */
    public function getAccountAttributes()
    {
        return $this->hasOne($this->module->modelMap['Account'], ['user_id' => 'user_id'])->asArray()->one();
    }

}

Затем в представлениях/user/admin/_profile.php

<?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.md
 * file that was distributed with this source code.
 */

use yii\bootstrap\ActiveForm;
use yii\helpers\Html;

/**
 * @var yii\web\View                    $this
 * @var dektrium\user\models\User       $user
 * @var dektrium\user\models\Profile    $profile
 */

?>

<?php $this->beginContent('@dektrium/user/views/admin/update.php', ['user' => $user]) ?>

<?php $form = ActiveForm::begin([
    'layout' => 'horizontal',
    'enableAjaxValidation' => true,
    'enableClientValidation' => false,
    'fieldConfig' => [
        'horizontalCssClasses' => [
            'wrapper' => 'col-sm-9',
        ],
    ],
]); ?>

<?= $form->field($profile, 'name') ?>
<?= $form->field($profile, 'public_email') ?>
<?= $form->field($profile, 'website') ?>
<?= $form->field($profile, 'location') ?>
<?= $form->field($profile, 'gravatar_email') ?>
<?= $form->field($profile, 'bio')->textarea() ?>
<?= $form->field($profile, 'skills')->textarea() ?>


<div class="form-group">
    <div class="col-lg-offset-3 col-lg-9">
        <?= Html::submitButton(Yii::t('user', 'Update'), ['class' => 'btn btn-block btn-success']) ?>
    </div>
</div>

<?php ActiveForm::end(); ?>

<?php $this->endContent() ?>

Я не получаю ошибку, но поле не обновляет таблицу.

Если я заполняю поле непосредственно в БД, я вижу значение в форме, но оно не меняется при обновлении.

Любая помощь более чем приветствуется


person open-ecommerce.org    schedule 23.06.2016    source источник


Ответы (1)


Измените это 'User' => 'app\models\Profile' на 'Profile' => 'app\models\Profile'

person Vitaly    schedule 24.06.2016
comment
Это первое, что я сделал - person open-ecommerce.org; 24.06.2016
comment
Возможно, это ошибка 'User' => 'app\models\Profile', а должно быть 'Profile' => 'app\models\Profile' - person Vitaly; 24.06.2016
comment
Я думал об этом во сне :) Сейчас проверю, спасибо. Сегодня печальный день в Великобритании - person open-ecommerce.org; 24.06.2016
comment
Да, но чтобы сначала проверить - person open-ecommerce.org; 24.06.2016
comment
Что произошло в Великобритании? Референдум? - person Vitaly; 24.06.2016
comment
Давайте продолжим обсуждение в чате. - person open-ecommerce.org; 24.06.2016
comment
Спасибо, Виталий, что указал мне на правильную ошибку, были и другие ошибки, но главная проблема заключалась в том, что вы упоминаете «Профиль» вместо «Пользователь». - person open-ecommerce.org; 24.06.2016
comment
Он отлично сохраняет, можете ли вы отредактировать свой ответ на Mayby error this 'User' => 'app\models\Profile', и должно быть 'Profile' => 'app\models\Profile', чтобы сделать его понятным для других людей - person open-ecommerce.org; 24.06.2016