Добавляем новые поля в стандартную вкладку профиля «Общая информация»
Результат
1. Добавление новых полей в базе данных сайта
- столбец new_checkbox в таблице modx_users:
ALTER TABLE `modx_users` ADD `new_checkbox` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1' ;
- столбец new_field в таблице modx_user_attributes:
ALTER TABLE `modx_user_attributes` ADD `new_field` VARCHAR(255) NOT NULL ;
2. Создание плагина на события OnMODXInit и OnUserFormPrerender:
<?php
switch ($modx->event->name) {
case "OnMODXInit":
$map = array(
'modUser' => array(
'fields' => array(
'new_checkbox' => 1,
),
'fieldMeta' => array(
'new_checkbox' => array(
'dbtype' => 'tinyint',
'precision' => '1',
'phptype' => 'boolean',
'attributes' => 'unsigned',
'null' => false,
'default' => 1,
),
),
),
'modUserProfile' => array(
'fields' => array(
'new_field' => '',
),
'fieldMeta' => array(
'new_field' => array(
'dbtype' => 'varchar',
'precision' => '255',
'phptype' => 'string',
'null' => false,
),
),
),
);
foreach ($map as $class => $data) {
$modx->loadClass($class);
foreach ($data as $tmp => $fields) {
if ($tmp == 'fields') {
foreach ($fields as $field => $value) {
foreach (array('fields', 'fieldMeta', 'indexes') as $key) {
if (isset($data[$key][$field])) {
$modx->map[$class][$key][$field] = $data[$key][$field];
}
}
}
} elseif ($tmp == 'composites' || $tmp == 'aggregates') {
foreach ($fields as $alias => $relation) {
if (!isset($modx->map[$class][$tmp][$alias])) {
$modx->map[$class][$tmp][$alias] = $relation;
}
}
}
}
}
break;
case "OnUserFormPrerender":
if (!isset($user) || $user->get('id') < 1) {
return;
}
if (!$modx->getCount('modPlugin', array('name' => 'AjaxManager', 'disabled' => false))) {
$data['new_checkbox'] = $user->new_checkbox ? 'true' : 'false';
$data['new_field'] = htmlspecialchars($user->Profile->new_field);
$modx->controller->addHtml("
<script type='text/javascript'>
Ext.ComponentMgr.onAvailable('modx-user-tabs', function() {
this.on('beforerender', function() {
// Получаем колонки первой вкладки
var leftCol = this.items.items[0].items.items[0].items.items[0];
var rightCol = this.items.items[0].items.items[0].items.items[1];
// Добавляем новое поле в левую колонку 4ым по счёту полем (перед полем 'Email')
leftCol.items.insert(4, 'modx-user-new-field', new Ext.form.TextField({
id: 'modx-user-new-field',
name: 'new_field',
fieldLabel: 'Новое поле профиля',
xtype: 'textfield',
anchor: '100%',
maxLength: 255,
value: '{$data['new_field']}',
}));
// Добавляем чекбокс первым по счёту полем (перед чекбоксом 'Активный')
rightCol.items.insert(0, 'modx-user-new-checkbox', new Ext.form.Checkbox({
id: 'modx-user-new-checkbox',
name: 'new_checkbox',
hideLabel: true,
boxLabel: 'Новый чекбокс юзера',
description: 'Описание нового чекбокса...',
xtype: 'xcheckbox',
inputValue: 1,
listeners: {
beforerender: function(that) {
that.hiddenField = new Ext.Element(document.createElement('input')).set({
type: 'hidden',
name: that.name,
value: 0,
});
},
afterrender: function(that) {
that.el.insertHtml('beforeBegin', that.hiddenField.dom.outerHTML);
},
},
checked: {$data['new_checkbox']},
}));
});
});
</script>
");
}
break;
}
В первом событии (OnMODXInit) происходит расширение модели классов системы нашими дополнительными полями.
Во втором событии (OnUserFormPrerender) мы, перед рендерингом формы юзера, встраиваем наши поля среди уже имеющихся полей профиля.
Интересный момент в том, что эти поля можно вызывать во фронтенде, как обычные поля юзера:
[[+modx.user.id:userinfo=`new_checkbox`]]
[[+modx.user.id:userinfo=`new_field`]]
или
{0 | user : 'new_checkbox'}
{0 | user : 'new_field'}
Итого, получаем свои дополнительные поля данных, встроенные в стандартный MODX, без использования JSON.