ExtraFields. Дополнительные поля для ресурса (modResource) и пользователя (modUserProfile).
Привет, друзья!
Представляю компонент, который предназначен для добавления новых полей в ресурсе и профиле пользователя. Работает в MODx 2 / 3.
При создании поля добавляется соответствующая колонка в таблице site_content (modResource).
При обновлении можно изменить все, кроме название самого поля в таблице.
При удалении удаляется колонка в таблице.
Для создание дополнительных вкладок нужно перейти в панель администрирования (кнопка справа вверху).
При создании поля добавляется соответствующая колонка в таблице user_attributes (modUserProfile).
Таблица возможных типов полей. Для редактирование нужно перейти в панель администрирования.
Доступные поля:
Компонент совместим с MODx 3 благодаря алиасам. В комментарии файла пишут, что в будущем, в версии 3.3 или 3.4, данный файл не будет автоматически подключаться. Я уверен, что это будущее не наступит в ближайшее пол года, поэтому можно спокойно делать компоненты совместимые с обоими версиями. Но, это чисто мое мнение, авторы сами решают как делать свои компоненты.
А вот с какими проблемами столкнулся я.
1. Карта классов
Все помнят статью Васи Наумкина Расширение любых таблиц MODX
Вот код для MODx 2:
Но в MODx 3 такое не работает, из-за того, что $modx->map — это уже не массив, а объект, который реализован через интерфейс ArrayAccess. Спасибо @Сергей Шлоков
Вот сам класс — github.com/modxcms/xpdo/blob/3.x/src/xPDO/xPDOMap.php
Он позволяет работать с объектом как с одномерным массивом, поэтому решение для MODx 3 такое:
2. getService
Решил это, думал, что уже все, но нет! @Павел Бигель написал в телеграмм чате, что метод getService будет удален в версии 3.1, а это уже не за горами. Поэтому пришлось переделывать, подключать автозагрузку класса и заменить
вот это
3. Текстовый редактор.
Следующая проблема была с текстовым редактором, дело в том, что если добавить данное поле (richtext) в ресурс то при сохранении ресурса будет ошибка связана с экранированием символов, хотя все поля будут сохранены.
Начинаем изучать код процессора update для ресурса и видим, что проблема в этом:
То есть все стандартные поля и TV вырезаются, поэтому TV c типом richtext работает без ошибок. Этот метод вызывается после сохранения объекта, значит нужно чтобы эти поля не участвовали в формирование массива $returnArray.
Первое что в голову пришло, это очистить новые поля с типом richtext после сохранения ресурса:
И да, это сработало! Но, если указать парный тег в простом поле, то снова получим ошибку((
Тогда, посмотрев внимательно, нашел решение:
Вот и все, проблема решена. Если у кого-то есть другое решение, то пишите в комментарии.
Компонент можно скачать бесплатно с официального репозитория или модстора.
Если компонент был вам полезен, то вы можете угостить меня чашечкой кофе.
Представляю компонент, который предназначен для добавления новых полей в ресурсе и профиле пользователя. Работает в MODx 2 / 3.
Ресурс (modResource)
При создании поля добавляется соответствующая колонка в таблице site_content (modResource).
При обновлении можно изменить все, кроме название самого поля в таблице.
При удалении удаляется колонка в таблице.
Настройка поля
- Имя поля — название колонки в таблице.
- Название поля — заголовок поля, которое отображается над полем.
- Расположение — место где будет вставлено поле. Главная вкладка ресурса имеет 2 колонки: левая (modx-resource-main-left) и правая (modx-resource-main-right). Вы можете разместить поле в любую колонку или в свою вкладку.
- Индекс — позиция поля по отношению к другим полям. Если 0, то поле будет отображаться в самом вверху, выше всех других полей в этой колонке или вкладке.
- Тип поля — тип отображаемого поля. Это может быть текстовое или числовое поле, может быть чекбокс и т.д. Смотрите в разделе **Поля**.
- Обязательное поле — не дает ресурсу сохраниться, если поле будет не заполнено.
- Включено — показывать поле в ресурсе или нет.
Вкладки ресурса
Для создание дополнительных вкладок нужно перейти в панель администрирования (кнопка справа вверху).
Настройка вкладки
- Название — название вкладки
- Позиция — позиция вкладки по отношению к другим вкладкам. 0 — будет отображено в самом начале, а 99 — в самом конце.
- Включено — показывать вкладку в ресурсе или нет.
Профиль пользователя (modUserProfile)
При создании поля добавляется соответствующая колонка в таблице user_attributes (modUserProfile).
Настройка поля
- Имя поля — название колонки в таблице.
- Название поля — заголовок поля, которое отображается над полем.
- Расположение — место где будет добавлено поле на главной вкладке профиля пользователя.
- Индекс — позиция поля по отношению к другим полям. Если 0, то поле будет отображаться в самом вверху, выше всех других полей в этой колонке или вкладке.
- Тип поля — тип отображаемого поля. Это может быть текстовое или числовое поле, может быть чекбокс и т.д. Смотрите в разделе **Поля**.
- Обязательное поле — не дает пользователю сохраниться, если поле будет не заполнено.
- Включено — показывать поле в профиле или нет.
Поля
Таблица возможных типов полей. Для редактирование нужно перейти в панель администрирования.
Доступные поля:
- textfield
- textarea
- richtext (textarea + editor)
- numberfield
- xcheckbox
- combo-boolean
- datefield
- timefield
- xdatetime (datefield + timefield)
- displayfield
- readonly (textfield + readOnly true)
Настройка поля
- Название — xtype поле
- dbtype — тип поля в базе данных
- precision — размер поля
- phptype — тип переменной в php
- null — может ли поле иметь значение null или нет.
- default — значение по умолчанию
Совместимость
Компонент совместим с MODx 3 благодаря алиасам. В комментарии файла пишут, что в будущем, в версии 3.3 или 3.4, данный файл не будет автоматически подключаться. Я уверен, что это будущее не наступит в ближайшее пол года, поэтому можно спокойно делать компоненты совместимые с обоими версиями. Но, это чисто мое мнение, авторы сами решают как делать свои компоненты.
Проблемы
А вот с какими проблемами столкнулся я.
1. Карта классов
Все помнят статью Васи Наумкина Расширение любых таблиц MODX
Вот код для MODx 2:
<?php
switch ($modx->event->name) {
case 'OnMODXInit':
$modx->loadClass('modResource');
$modx->map['modResource']['fields']['manager_id'] = 0;
$modx->map['modResource']['fieldMeta']['manager_id'] = array(
'dbtype' => 'int',
'precision' => 10,
'attributes' => 'unsigned',
'phptype' => 'integer',
'null' => true,
'default' => 0,
);
break;
}
Но в MODx 3 такое не работает, из-за того, что $modx->map — это уже не массив, а объект, который реализован через интерфейс ArrayAccess. Спасибо @Сергей Шлоков
Вот сам класс — github.com/modxcms/xpdo/blob/3.x/src/xPDO/xPDOMap.php
Он позволяет работать с объектом как с одномерным массивом, поэтому решение для MODx 3 такое:
<?php
use MODX\Revolution\modResource;
switch ($modx->event->name) {
case 'OnMODXInit':
// Сохраняем карту класса в переменную
$map = $modx->map[modResource:class];
// Теперь работаем с данной переменной
$map['fields']['manager_id'] = 0;
$map['fieldMeta']['manager_id'] = array(
'dbtype' => 'int',
'precision' => 10,
'attributes' => 'unsigned',
'phptype' => 'integer',
'null' => true,
'default' => 0,
);
// Обновляем нашу карту класса.
$modx->map[modResource:class] = $map;
break;
}
2. getService
Решил это, думал, что уже все, но нет! @Павел Бигель написал в телеграмм чате, что метод getService будет удален в версии 3.1, а это уже не за горами. Поэтому пришлось переделывать, подключать автозагрузку класса и заменить
вот это
$extrafields = $modx->getService('extrafields', 'ExtraFields', MODX_CORE_PATH . 'components/extrafields/model/');
на это:if ($modx->services instanceof Psr\Http\Client\ClientInterface) {
$extrafields = $modx->services->get('extrafields');
} else {
$extrafields = $modx->getService('extrafields', 'ExtraFields', MODX_CORE_PATH . 'components/extrafields/model/');
}
Таким образом, для MODx 3 мы используем контейнер зависимости, а во 2 версии метод getService.3. Текстовый редактор.
Следующая проблема была с текстовым редактором, дело в том, что если добавить данное поле (richtext) в ресурс то при сохранении ресурса будет ошибка связана с экранированием символов, хотя все поля будут сохранены.
Начинаем изучать код процессора update для ресурса и видим, что проблема в этом:
$returnArray = $this->object->get(array_diff(array_keys($this->object->_fields), array('content','ta','introtext','description','link_attributes','pagetitle','longtitle','menutitle', 'properties', 'resource_groups')));
foreach ($returnArray as $k => $v) {
if (strpos($k,'tv') === 0) {
unset($returnArray[$k]);
}
}
...
return $this->success('',$returnArray);
То есть все стандартные поля и TV вырезаются, поэтому TV c типом richtext работает без ошибок. Этот метод вызывается после сохранения объекта, значит нужно чтобы эти поля не участвовали в формирование массива $returnArray.
Первое что в голову пришло, это очистить новые поля с типом richtext после сохранения ресурса:
if ($modx->event->name == 'OnDocFormSave') {
$resource->set('customfield', '');
}
И да, это сработало! Но, если указать парный тег в простом поле, то снова получим ошибку((
Тогда, посмотрев внимательно, нашел решение:
if ($modx->event->name == 'OnDocFormSave') {
unset($resource->_fields['customfield']);
}
Вот и все, проблема решена. Если у кого-то есть другое решение, то пишите в комментарии.
Buy me a coffee
Компонент можно скачать бесплатно с официального репозитория или модстора.
Если компонент был вам полезен, то вы можете угостить меня чашечкой кофе.
Поблагодарить автора
Отправить деньги
Комментарии: 38
Добрый! Подскажите, а в чем преимущество создания дополнительных полей ресурса через данный плагин перед стандартными TV?
Как минимум в скорости выборки.
TV к modUserProfile как представляешь себе?)
С юзерами понятно, я конкретно про ресурс спрашивал.
Добрый!
1. Нет лишних запросов в БД.
2. Фильтровать по родному полю быстрее чем по TV.
3. Удобство при создании/обновлении ресурса через API.
1. Нет лишних запросов в БД.
2. Фильтровать по родному полю быстрее чем по TV.
3. Удобство при создании/обновлении ресурса через API.
ну в фильтрации может и поможет, но как быть указанием данных, т.е. тут не хватает списков, а это оч печально.
Не, все сразу. Будет еще улучшение компонента.
Здравствуйте, спасибо за компонент!
А можете скрин добавить, как заполненные поля и вкладки в админке выглядят? Не в ресурсе/профиле, а именно сам список добавленных полей.
А можете скрин добавить, как заполненные поля и вкладки в админке выглядят? Не в ресурсе/профиле, а именно сам список добавленных полей.
Огонь, пасиб!
В будущих версиях стоит в сетку еще и «Вкладку» отображать, чтоб проще фильтровать.
В будущих версиях стоит в сетку еще и «Вкладку» отображать, чтоб проще фильтровать.
Данный компонент делает поля для всех шаблонов? Т.е. разделять по шаблонам нельзя?
К товарам в MS не применимо?
К товарам в MS не применимо?
Данный компонент делает поля для всех шаблонов? Т.е. разделять по шаблонам нельзя?Это будет в след. версии.
К товарам в MS не применимо?
К свойствам товара нет.
К свойствам понятно почему не применимо, они в другой таблице, но почему когда я работаю с товарами как с обычными ресурсами, т.е.
И у товаров добавленные через этот компонент поля не отображаются на вкладке Документ. Это можно как-то исправить или надо создавать аналогичные поля но уже в таблице ms2_products?
$resource = $modx->getObject('modResource', 66);
$resource->set('customfield', 'abcd');
$resource->save();
customfield остаётся пустым?
Для минишопа нет поддержки. Не отображается, потому что там другой js
Понятно. Ок. Вопросов больше нет.
К товарам в MS не применимо?Для расширения полей минишопа и так есть 2 компонента — msFieldsManager и msAddField
Данный компонент делает поля для всех шаблонов? Т.е. разделять по шаблонам нельзя?Можно поля разделить по вкладкам. В настройках форм добавить области, которые скрыть нужно для конкретного шаблона. Ну и скрываем их соответственно.
В настройках форм id области указываем modx-resource-extrafields-[id вкладки созданной в настройках ExtraFields]. Например modx-resource-extrafields-2
Это просто бомба! А тем более бесплатно, вообще огонь! Спасибо.
Как добавить выпадающий список и какой phptype, dbtype должен быть для выпадающего списка, чтобы в профиле пользователя он был, такой как пол или страна?
Попробовал добавить тип modx-combo в профиль пользователя, но не могу понять какой тип указывать, так как он trigger, то phptype вроде бы должен быть twintrigger, пробовал json, так он объект в объекте показывает, нет выпадашки, точнее как добавить Ext, в сам компонент. В какой файл?
Попробовал добавить тип modx-combo в профиль пользователя, но не могу понять какой тип указывать, так как он trigger, то phptype вроде бы должен быть twintrigger, пробовал json, так он объект в объекте показывает, нет выпадашки, точнее как добавить Ext, в сам компонент. В какой файл?
Сам спросил, сам ответил: dbtype:varchar, phptype:string, что там такого, а в Ext.form.ComboBox пишешь store: new Ext.data.ArrayStore
Подскажи пожалуйста, куда именно добавить в js список значений?
Ну я в плагин добавил на событие OnUserFormPrerender и всё хорошо.
Покажи код, пожалуйста )
Ребята, подскажите как задать свои значения для поля combo-boolean в профиле?
Мне нужно что бы там был выбор из 3-х значений: нет, оплачено, волонтер.
Создал поле combo-boolean, а там только да/нет
Мне нужно что бы там был выбор из 3-х значений: нет, оплачено, волонтер.
Создал поле combo-boolean, а там только да/нет
попробуйте combo-box или listbox. Возможно что-то сработает, но не уверен — не пробовал.
а в dbtype и phptype что у казать?
Подскажите пожалуйста как добавить поле в этот блок disk.yandex.ru/i/JO2k8V_j5WY9TQ
В выборе блока, только две колонки ресурса
disk.yandex.ru/i/FHSxVIv6LIil3Q
В пхп нашел куда добавить выбор поля
disk.yandex.ru/i/j00S9ujOIs3v0Q
Но в js к сожалению не пойму
disk.yandex.ru/i/r4yH_MMEsU0FxA
В выборе блока, только две колонки ресурса
disk.yandex.ru/i/FHSxVIv6LIil3Q
В пхп нашел куда добавить выбор поля
disk.yandex.ru/i/j00S9ujOIs3v0Q
Но в js к сожалению не пойму
disk.yandex.ru/i/r4yH_MMEsU0FxA
Спасибо, плагин отлично работает. Единственное, сильно не хватает возможности создать поле типа Файл.
Тоже интересует вопрос, как созданные поля перемещать по форме ресурса…
И также вопрос как отключать созданные поля для отдельных шаблонов?
И также вопрос как отключать созданные поля для отдельных шаблонов?
не могу понять как вывисти в шаблон поля?
Как [[+pice_1]] не отображается почему?
Как [[+pice_1]] не отображается почему?
Не отображаются добавленные поля в редактировании пользователя.
Добавил одно поле в «общую информацию», для другого создал вкладку, в ней ещё вкладку и в ней уже поле.
Созданные вкладки отображаются, а вот поля — нет.
Что я делаю не так?
В датабазе добавленные поля есть, я им даже напрямую задал значения у одного пользователя, всё равно не отображаются.
Добавил одно поле в «общую информацию», для другого создал вкладку, в ней ещё вкладку и в ней уже поле.
Созданные вкладки отображаются, а вот поля — нет.
Что я делаю не так?
В датабазе добавленные поля есть, я им даже напрямую задал значения у одного пользователя, всё равно не отображаются.
MODX Revolution 2.8.3-pl
Ace 1.9.4-pl
При выборе ACE ошибка:
Ace 1.9.4-pl
При выборе ACE ошибка:
Uncaught TypeError: Cannot read properties of null (reading 'match')
at a.$detectNewLine (ace.min.js?v=2.9.3-pl:1:120718)
at a.insert (ace.min.js?v=2.9.3-pl:1:122464)
at a.setValue (ace.min.js?v=2.9.3-pl:1:120356)
at p.setValue (ace.min.js?v=2.9.3-pl:1:153026)
at S.setValue (modx.texteditor.js?v=2.9.3-pl:185:38)
at constructor.setValues (ext-all.js:21:603600)
at miniShop2.panel.UpdateCategory.setup (modx.panel.resource.js?v=2.9.3-pl:57:28)
at h.Event.fire (ext-all.js:21:3699)
at miniShop2.panel.UpdateCategory.fireEvent (ext-all.js:21:687)
at MODx.FormPanel [as constructor] (modx.panel.js:62:14)
Как выбрать текстовый редактор?
Установил компонент. PHP 7.4, Modx 2.8.4. Созданные кастомные поля юзера не отображаются, в логе ошибка:
No foreign key definition for parentClass: efFieldAbs using relation alias: Tab
После обновления компонента на последнюю версию — пропали ранее созданные поля.
Кто знает как вернуть?
Кто знает как вернуть?
начиная со 2й версии на modx 2.8.7 компонент валит админку в 500…
53-й плагин — это плагин ExtraFields
2024/09/03 14:28:11 [error] 1762146#1762146: *32171 FastCGI sent in stderr: "PHP message: PHP Fatal error: Uncaught Error: Call to undefined method ExtraFields::getTableFields() in /var/www/site_user/data/www/site.ru/core/cache/includes/elements/modplugin/53.include.cache.php:44
Stack trace:
#0 /var/www/site_user/data/www/site.ru/core/model/modx/modscript.class.php(76): include()
#1 /var/www/site_user/data/www/site.ru/core/model/modx/modx.class.php(1674): modScript->process(NULL)
#2 /var/www/site_user/data/www/site.ru/core/model/modx/modx.class.php(570): modX->invokeEvent('OnMODXInit', Array)
#3 /var/www/site_user/data/www/site.ru/manager/index.php(53): modX->initialize('mgr')
#4 {main}
thrown in /var/www/site_user/data/www/site.ru/core/cache/includes/elements/modplugin/53.include.cache.php on line 44" while reading response header from upstream, client: 10.10.10.10, server: site.ru, request: "GET /manager/?a=workspaces HTTP/2.0", upstream: "fastcgi://unix:/var/run/site.ru.sock:", host: "site.ru", referrer: "https://site.ru/manager/?"
53-й плагин — это плагин ExtraFields
Уже исправлено. Спасибо @Михаил
Спасибо, Александр. В целом, удаление 1-й версии перед установкой 2-й помогает, но теряются все заполненные поля соответственно.
Всем привет. Снес старую версию компонента ExtraFields, установил новую.
Пытаюсь создать поле: получаю ошибку: «Ошибка при сохранении поля.»
И в логах:
Пытаюсь создать поле: получаю ошибку: «Ошибка при сохранении поля.»
И в логах:
Error 42S22 executing statement:
INSERT INTO `modx_ef_fields` (`class_name`, `field_name`, `field_type`, `field_null`, `field_index`, `field_default`, `menuindex`, `active`) VALUES ('modUserProfile', 'agreed', 'xcheckbox', 0, 0, '0', 0, 1)
Array
(
[0] => 42S22
[1] => 1054
[2] => Unknown column 'field_index' in 'field list'
)
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.