Как я расширил стандартную таблицу пользователей
В последнее время довольно часто приходится делать различные стартапы на заказ, суть которых сводится к платному сервису, с регистрацией, личным кабинетом, ну и как следствие каталогом пользователей, представляющих ту или иную услугу.
Обычно использую office, который обеспечивает готовый личный кабинет из коробки с минимальными усилиями, он же позволяет сохранять все в базу, пользователей. Но вот беда, полей катастрофически не хватает. Логичным решением было создавать страницы для каждого пользователя, и добавлять сколько угодно TV. Так я и делал, но решил заморочиться и не дублировать страницы, а расширить таблицу пользователей и работать с ней напрямую, как с ресурсом.
Вот что я сделал:
Шаг первый.
Добавил в таблицу modx_user_attributes дополнительное поле company_name (varchar 255 Utf-8 general-ci). Ничего не обычного. Если кто не понял этот пункт, то наверное еще рано читать эту статью
Шаг второй.
Далее воспользовался этой методикой, любезно рекомендованной Василием.
У меня получился вот такой вот плагин
К этому моменту MODX уже распознал наше новое поле и может работать с ним как с родным.
Мы можем получить значение этого поля используя следующий сниппет
В принципе этого УЖЕ достаточно для работы, но хотелось бы еще и в админке этими данными управлять. Это значит, что нам нужно на странице с полями пользователя добавить новое поле.
За это отвечает JS фреймворк extJS.
Открываем для редактирования файл manager/assets/modext/widgets/security/modx.panel.user.js
Здесь как раз лежат все поля, написанные на JavaScript.
Я хочу чтобы мое новое поле находилось после поля Fullname, нахожу в файле где у нас выводится это поле (ищем в коде строку name: 'fullname').
Мы видим, что за вывод данного поля у нас отвечает следующий блок
name — это название поля в базе данных
fieldLabel — это строка записываемая в label, новую строку user_company_name добавляем в лексикон
xtype: 'textfield' — обычное текстовое поле
maxLength — доступное количество символов.
Скопировав этот блок и немного подредактировав данные я получаю такой код
Почему не использовать extended поле?
В комментариях возник вопрос, почему бы не использовать специальное поле extended, которое позволяет без проблем хранить большой массив дополнительных полей.
Суть в том, что я хочу использовать свои дополнительные поля в расширенной таблице для того, чтобы на их основе можно было сортировать моих пользователей (страна, город, вид деятельности и т.п.)
Василий Наумкин (сто лет ему успешных разработок) предусмотрел такую возможность в своем компоненте mFilter2, но там можно использовать только отдельные поля. В extended же вся информация лежит в одном большом массиве, закодированном в формете JSON. Сортировать по нему не получится. Можно конечно написать велосипед, но будут проблемы со скоростью.
Обычно использую office, который обеспечивает готовый личный кабинет из коробки с минимальными усилиями, он же позволяет сохранять все в базу, пользователей. Но вот беда, полей катастрофически не хватает. Логичным решением было создавать страницы для каждого пользователя, и добавлять сколько угодно TV. Так я и делал, но решил заморочиться и не дублировать страницы, а расширить таблицу пользователей и работать с ней напрямую, как с ресурсом.
Вот что я сделал:
Шаг первый.
Добавил в таблицу modx_user_attributes дополнительное поле company_name (varchar 255 Utf-8 general-ci). Ничего не обычного. Если кто не понял этот пункт, то наверное еще рано читать эту статью
Шаг второй.
Далее воспользовался этой методикой, любезно рекомендованной Василием.
У меня получился вот такой вот плагин
<?php
switch ($modx->event->name) {
case 'OnMODXInit':
$modx->loadClass('modUserProfile');
$modx->map['modUserProfile']['fields']['company_name'] = 0;
$modx->map['modUserProfile']['fieldMeta']['company_name'] = array(
'dbtype' => 'varchar',
'precision' => 255,
'phptype' => 'string',
'null' => true,
);
break;
}Плагин активируется при наступлении события OnMODXInit, который срабатывает сразу же при запуске MODX. К этому моменту MODX уже распознал наше новое поле и может работать с ним как с родным.
Мы можем получить значение этого поля используя следующий сниппет
if ($modx->user->isAuthenticated()) {
// Сохранить название компании
$modx->user->Profile->set('company_name', $companyName);
$modx->user->save();
// Получить название компании
return $modx->user->Profile->get('company_name');
}Шаг третий.В принципе этого УЖЕ достаточно для работы, но хотелось бы еще и в админке этими данными управлять. Это значит, что нам нужно на странице с полями пользователя добавить новое поле.
За это отвечает JS фреймворк extJS.
Открываем для редактирования файл manager/assets/modext/widgets/security/modx.panel.user.js
Здесь как раз лежат все поля, написанные на JavaScript.
Я хочу чтобы мое новое поле находилось после поля Fullname, нахожу в файле где у нас выводится это поле (ищем в коде строку name: 'fullname').
Мы видим, что за вывод данного поля у нас отвечает следующий блок
{
id: 'modx-user-fullname'
,name: 'fullname'
,fieldLabel: _('user_full_name')
,xtype: 'textfield'
,anchor: '100%'
,maxLength: 255
},Насколько я понимаю id у нас отвечает за labelname — это название поля в базе данных
fieldLabel — это строка записываемая в label, новую строку user_company_name добавляем в лексикон
xtype: 'textfield' — обычное текстовое поле
maxLength — доступное количество символов.
Скопировав этот блок и немного подредактировав данные я получаю такой код
{
id: 'modx-user-company_name'
,name: 'company_name'
,fieldLabel: _('user_company_name')
,xtype: 'textfield'
,anchor: '100%'
,maxLength: 255
}Сохраняем, обновляем, и по идее вы должны увидеть в таблице новое текстовое поле. Если в базе это поле уже заполнено, данные должны погрузиться.Почему не использовать extended поле?
В комментариях возник вопрос, почему бы не использовать специальное поле extended, которое позволяет без проблем хранить большой массив дополнительных полей.
Суть в том, что я хочу использовать свои дополнительные поля в расширенной таблице для того, чтобы на их основе можно было сортировать моих пользователей (страна, город, вид деятельности и т.п.)
Василий Наумкин (сто лет ему успешных разработок) предусмотрел такую возможность в своем компоненте mFilter2, но там можно использовать только отдельные поля. В extended же вся информация лежит в одном большом массиве, закодированном в формете JSON. Сортировать по нему не получится. Можно конечно написать велосипед, но будут проблемы со скоростью.
Комментарии: 17
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Дальше уже пишешь логику для вставки поля. (На верность решения не претендую буду рад услышать, как это можно сделать лучше, без вмешательства в код modx).
UPD. Там же есть комментарий, что то я туплю.
Спасибо за решение. Вырисовывается неплохой комплексный подход к задаче. Коллективный разум творит чудеса.
Можно, кстати, лишние поля удалить, чтобы не мешались
Сначала, думаю, надо удалять, а потом добавлять.
Конкретно это решение недоработанное. Вы про проблемы с обновлением помните?
Про обновление я конечно помню. У нас по идее перезаписаться должен только extJS файл. Наверное правильно просто его сохранить и потом заменить.
К сожалению, других доступных для меня пошаговых материалов я не нашел, сделал, как сумел.
С радостью изучу предложенную Вами пошаговую альтернативу по расширению системных таблиц, с возможностью будущей фильтрации и безопасным обновлением.
Конечно предложенный вариант расширения таблицы пользователей гораздо лучше, чем TV или extended.
Правка ExtJs исходников решает задачу до первого обновления. Лучше сделать свой скрипт и подключать его используя вариант Григория.
Тогда это будет готовое решение.
Что касается вашего варианта сниппета… Ну тоже самое же написано, только запись сокращенная. Ровно ничего не изменится, кроме размера записи. Это как использовать тернарный оператор, вместо классического условия.
Но все равно спасибо, я о таком варианте записи не знал.
{private message}
Проблема только в том, что источников знаний для Junior разработчиков маловато.
Разве что документация, которая не всегда помогает. Все же кто поопытнее только свысока смотрят и посмеиваются, вместо того чтобы помочь разобраться, что да как.
В любом случае спасибо, парочку новых мыслей от Вас я узнал.
Ну по крайней мере я предложил решение, которое хоть как-то отвечает моим требованиям. Когда мне понадобилось решить эту задачу, ЗДЕСЬ пошагового решения не было. Пришлось убить на него несколько дней. Я надеюсь следующему разработчику, который решит также решить задачу будет проще с этой заметкой.
Так, что пусть читают и те кому , смотришь — у них появятся вопросы, а за ними и найдутся ответы :)
Если у кого то появляются вопросы — что ж, пусть задают. Я подскажу какой материал нужно изучить по данной тематике.