Edited at

HumHubの新規ユーザー登録画面のカスタマイズ

More than 1 year has passed since last update.


概要

HumHubの新規ユーザー登録画面の、登録項目のカスタマイズ方法


関連


対象ページ

確認メール本文のリンクをクリックした後のページ


URL

/index.php?r=user%2Fregistration&token=xxxxxxxxxxxx

Screen Shot 2018-02-12 at 18.05.50.png


debug

こちらのページは、パラメータのtokenが有効でないと閲覧出来ないページだが、

protected/humhub/modules/user/controllers/RegistrationController.php

61 - 69行目をコメントアウトすることで、閲覧できるようになる。


RegistrationController.php

 45     /**

46 * Registration Form
47 *
48 * @return type
49 * @throws HttpException
50 */

51 public function actionIndex()
52 {
53 $registration = new Registration();
54
55 /**
56 * @var \yii\authclient\BaseClient
57 */

58 $authClient = null;
59 $inviteToken = Yii::$app->request->get('token', '');
60
61 //if ($inviteToken != '') {
62 // $this->handleInviteRegistration($inviteToken, $registration);
63 //} elseif (Yii::$app->session->has('authClient')) {
64 // $authClient = Yii::$app->session->get('authClient');
65 // $this->handleAuthClientRegistration($authClient, $registration);
66 //} else {
67 // Yii::$app->session->setFlash('error', 'Registration failed.');
68 // return $this->redirect(['/user/auth/login']);
69 //}


表示項目変更方法

DBのprofile_fieldテーブルに、プロフィール情報の項目が登録されており、

show_at_registration1のもののみ、新規ユーザー登録画面に表示される。


例:Genderを新規ユーザー登録画面に表示させる

Genderはデフォルトで非表示になっている。

該当のレコードは以下のようになっている。

mysql> select * from profile_field where internal_name = 'gender'\G;

*************************** 1. row ***************************
id: 4
profile_field_category_id: 1
module_id: NULL
field_type_class: humhub\modules\user\models\fieldtype\Select
field_type_config: {"options":"male=>Male\nfemale=>Female\ncustom=>Custom","fieldTypes":[]}
internal_name: gender
title: Gender
description: NULL
sort_order: 300
required: NULL
show_at_registration: NULL
editable: 1
visible: 1
created_at: 2018-02-04 15:02:46
created_by: NULL
updated_at: 2018-02-04 15:02:46
updated_by: NULL
ldap_attribute: NULL
translation_category: NULL
is_system: 1
searchable: 1
1 row in set (0.00 sec)

Genderを表示させたい場合は、以下のようにshow_at_registration1に変更することで対応可能。

mysql> update profile_field set show_at_registration = 1 where internal_name = 'gender';

Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

これでGenderが表示されるようになった。

Screen Shot 2018-02-12 at 17.47.09.png

さらに、必須項目、編集不可にする場合は、以下で実現できる。

mysql> update

profile_field
set
show_at_registration = 1,
required = 1,
editable = 0
where
internal_name = 'gender'
;


ソースを追ってみる

簡単なメモですが、ソースを追ってみると、以下の箇所が関係しているようです。


protected/humhub/modules/user/models/forms/Registration.php

メソッド

setFormDefinition()

このメソッドで、表示項目がセットされる


Registration.php

 93     protected function setFormDefinition()

94 {
95 $this->definition = [];
96 $this->definition['elements'] = [];
97 $this->definition['elements']['User'] = $this->getUserFormDefinition();
98 $this->definition['elements']['GroupUser'] = $this->getGroupFormDefinition();
99 if ($this->enablePasswordForm) {
100 $this->definition['elements']['Password'] = $this->getPasswordFormDefinition();
101 }
102 $this->definition['elements']['Profile'] = array_merge(array('type' => 'form'), $this->getProfile()->getFormDefinition());
103 $this->definition['buttons'] = array(
104 'save' => array(
105 'type' => 'submit',
106 'class' => 'btn btn-primary',
107 'label' => Yii::t('UserModule.controllers_AuthController', 'Create account'),
108 ),
109 );
110 }
208 // Dont allow editing of ldap syned fields - will be overwritten on next ldap sync.
209 if (in_array($profileField->internal_name, $syncAttributes)) {
210 $profileField->editable = false;
211 }
212
213 $fieldDefinition = $profileField->fieldType->getFieldFormDefinition();
214 $category['elements'] = array_merge($category['elements'], $fieldDefinition);
215
216 $profileField->fieldType->loadDefaults($this);
217 }
218
219 $definition['elements']['category_' . $profileFieldCategory->id] = $category;
220 }
221
222 return $definition;
223 }


protected/humhub/modules/user/models/Profile.php

メソッド

getFormDefinition()

186行目の$safeAttributesに、表示項目の定義が入っている

176     public function getFormDefinition()

177 {
178 $definition = array();
179 $definition['elements'] = array();
180
181 $syncAttributes = [];
182 if ($this->user !== null) {
183 $syncAttributes = \humhub\modules\user\authclient\AuthClientHelpers::getSyncAttributesByUser($this->user);
184 }
185
186 $safeAttributes = $this->safeAttributes();
187
188 foreach (ProfileFieldCategory::find()->orderBy('sort_order')->all() as $profileFieldCategory) {
189
190 $category = array(
191 'type' => 'form',
192 'title' => Yii::t($profileFieldCategory->getTranslationCategory(), $profileFieldCategory->title),
193 'elements' => array(),
194 );
195
196 foreach (ProfileField::find()->orderBy('sort_order')->where(['profile_field_category_id' => $profileFieldCategory->id])->all() as $profileField) {
197 /** @var ProfileField $profileField */
198 $profileField->editable = true;
199
200 if (!in_array($profileField->internal_name, $safeAttributes)) {
201 if ($profileField->visible && $this->scenario != 'registration') {
202 $profileField->editable = false;
203 } else {
204 continue;
205 }
206 }
207


protected/vendor/yiisoft/yii2/base/Model.php

メソッド

safeAttributes()

protected/humhub/modules/user/models/Profile.phpの

getFormDefinition()で呼ばれるsafeAttributesは、このメソッドで作られる

 748     public function safeAttributes()

749 {
750 $scenario = $this->getScenario();
751 $scenarios = $this->scenarios();
752 if (!isset($scenarios[$scenario])) {
753 return [];
754 }
755 $attributes = [];
756 foreach ($scenarios[$scenario] as $attribute) {
757 if ($attribute[0] !== '!' && !in_array('!' . $attribute, $scenarios[$scenario])) {
758 $attributes[] = $attribute;
759 }
760 }
761
762 return $attributes;
763 }


protected/vendor/yiisoft/yii2/base/Model.php

メソッド

scenarios()

このメソッドで、表示項目をグループ化するscenariosが作られる

 184     public function scenarios()

185 {
186 $scenarios = [self::SCENARIO_DEFAULT => []];
187 foreach ($this->getValidators() as $validator) {
188 foreach ($validator->on as $scenario) {
189 $scenarios[$scenario] = [];
190 }
191 foreach ($validator->except as $scenario) {
192 $scenarios[$scenario] = [];
193 }
194 }
195 $names = array_keys($scenarios);
196
197 foreach ($this->getValidators() as $validator) {
198 if (empty($validator->on) && empty($validator->except)) {
199 foreach ($names as $name) {
200 foreach ($validator->attributes as $attribute) {
201 $scenarios[$name][$attribute] = true;
202 }
203 }
204 } elseif (empty($validator->on)) {
205 foreach ($names as $name) {
206 if (!in_array($name, $validator->except, true)) {
207 foreach ($validator->attributes as $attribute) {
208 $scenarios[$name][$attribute] = true;
209 }
210 }
211 }
212 } else {
213 foreach ($validator->on as $name) {
214 foreach ($validator->attributes as $attribute) {
215 $scenarios[$name][$attribute] = true;
216 }
217 }
218 }
219 }
220
221 foreach ($scenarios as $scenario => $attributes) {
222 if (!empty($attributes)) {
223 $scenarios[$scenario] = array_keys($attributes);
224 }
225 }
226
227 return $scenarios;
228 }


protected/humhub/modules/user/models/Profile.php

メソッド

scenarios()

以下のメソッドで、Profilescenariosがセットされる

101行目で、新規ユーザー登録画面に表示される項目がセットされる

 79     public function scenarios()

80 {
81 $scenarios = parent::scenarios();
82 $scenarios['editAdmin'] = [];
83 $scenarios['registration'] = [];
84 $scenarios['editProfile'] = [];
85
86 // Get synced attributes if user is set
87 $syncAttributes = [];
88 if ($this->user !== null) {
89 $syncAttributes = \humhub\modules\user\authclient\AuthClientHelpers::getSyncAttributesByUser($this->user);
90 }
91
92 foreach (ProfileField::find()->all() as $profileField) {
93 // Some fields consist of multiple field definitions (e.g. Birthday)
94 foreach ($profileField->fieldType->getFieldFormDefinition() as $fieldName => $definition) {
95 $scenarios['editAdmin'][] = $fieldName;
96
97 if ($profileField->editable && !in_array($profileField->internal_name, $syncAttributes)) {
98 $scenarios['editProfile'][] = $fieldName;
99 }
100
101 if ($profileField->show_at_registration) {
102 $scenarios['registration'][] = $fieldName;
103 }
104 }
105 }
106
107 return $scenarios;
108 }

以上