четверг, 3 сентября 2015 г.

MIGX DB - Как создать свои объекты с таблицами БД в MODX

В MODX есть удобная возможность создавать свои классы, ассоциировать их с таблицами в базе данных и хранить там коллекции данных оперируя ими как объектами в ООП.
К тому-же ими можно удобно управлять контент менеджерам сайта с помощью MIGX DB через странички админки, которые можно довольно быстро создать:

Для этого в MODX нужно создать свой пакет(package), добавить туда схему модели в xml файле, спарсить эту схему, создать таблицу в БД и подключить этот пакет для работы. На самом деле в ручную все это делать довольно долго и есть возможность допустить кучу ошибок, поэтому лучше воспользоваться менеджером пакетов MIGX:


Первым делом создаем новый пакет(package), после создания мы сможем его увидеть в списке папок внутри core->components.  После создания пакета нужно написать свою XML схему(или взять мой пример), которая представляет из себя один класс(<object>) или набор классов внутри модели(<model>) с полями(<field>). Именно с этими полями мы сможем потом работать в сниппете или плагине примерно таким образом:

$student = $modx->getObject('myStudent',array('id'=>2));
$name = $student->get('name');

В схеме прописываем:
model package - имя пакета, то-же самое что написали в "Package Name" наверху;
object class - имя класса нашего объекта;
object table - имя таблички в БД, где будут храниться наши объекты;
field key - имя поля нашего объекта;
field dbtype - тип поля(int, varchar, text, datetime и т.д.);
field default - значение по умолчанию для поля;
aggregate alias - имя связи(например University), которую мы сможем использовать подобным образом:
$university = $student->getOne('University');
aggregate class - класс объекта связи;
aggregate local - имя локального id поля для связи с объектом;
aggregate foreign - имя id объекта связи(в большинстве случаев то поле, которое хранит id-шник нашего объекта для связи);
aggregate cardinality - вид связи(one, many);
aggregate owner - указание объекту: кто тут главный(в случае связи Университет - Студенты: главный университет);

Я рекомендую не писать заново схему, а скопировать уже существующую(например из моего примера) и изменить на свой лад.
Кстати благодаря object extends="xPDOSimpleObject", а не xPDOObject в объект автоматически добавляется поле id. Вообще наследовать объект можно от любого класса, благодаря чему в объект попадут все поля от наследуемого класса.

Когда сохраняем XML схему, да и когда проводим другие операции над нашим пакетом в менеджере MIGX нужно следить за тем, чтобы в поле "Package Name" было написано имя именно того пакета, над которым мы проводим операции.
Следующим шагом будет parse Schema на соответствующей вкладке:

После этого нам остается только создать таблицу в БД:

Теперь можно заглянуть в PHPMyAdmin и проверить наличие наших табличек в БД:


Вот и все, необходимый минимум выполнен, теперь мы из кода можем добавить в любую из табличек объект, сохранить его там, а после, в нужный момент получить с помощью подобного кода:

$modx->addPackage('mypackage', MODX_BASE_PATH . 'core/components/mypackage/model/', 'modx_');

$university = $modx->newObject('myUniversity');
$university->set('name', 'Тихоокеанский Государтсвенный университет');
$university->set('abb', 'ТОГУ');
$university->save();

$petrov = $modx->newObject('myStudent');
$petrov->set('fullname', 'Иванов Иван');
$petrov->set('university', $university->get('id'));
$petrov->save();

$ivanov = $modx->newObject('myStudent');
$ivanov->set('fullname', 'Петров Петр');
$ivanov->set('university', $university->get('id'));
$ivanov->save();

Этот код можно, например, выполнить в консоле.
После выполнения записи добавятся в БД:
Вы наверно заметили ту некрасивую строчку($modx->addPackage) в начале нашего кода, она нужна для подключения нашего пакета со всеми его классами. Можно организовать автоматическое подключение пакета, если в настройках системы прописать для extension_packages:
[{...здесь уже что-то есть...},{"mypackage":{"path":"[[++core_path]]components/mypackage/model/"}}]
Более подробнее тут.
После этого строчка $modx->addPackage будет не нужна и мы будет использовать наши новык классы как родные MODX-овские (типа modResource или modUser) без лишних манипуляций.

Теперь, когда мы проверили что все работает как надо, можно создать страницы для работы с этими табличками в админке MODX. Для этого заходим в Меню:
Примечание: в старой версии MODX пункт "Меню" назывался "Действия".

На странице "Меню" выбираем родителя, куда мы добавим новый пункт меню - "Верхнее меню" и добавляем пункт students-and-universities, прописывая указанные параметры:

После сохранения в MIGX в верхней меню появляется новый пункт students-and-universities (позже можно зайти в управление словарями и присвоить этому ключу в пространстве migx и языке ru подходящее значение для вывода):

Пункт меню будет направлять нас на страничку по адресу, оканчивающемуся на &configs=students||universities (потому-что именно это мы и прописали при создании), по нему очевидно что на странице должно что-то отображаться с помощью каких-то конфигов. Все встает на свои места когда мы заходим в MIGX(или Приложения->MIGX) на вкладку MIGX:


Именно здесь должны располагаться наши конфиги, которые наша страница для работы с БД будет использовать для отображения и вообще работы в целом. Я описывал в своей прошлой статье по MIGX создание этих конфигов и использование их как TV в ресурсах, но конфиги для MIGX DB будут отличаться дополнительными настройками для связи с БД и дополнительным описанием.
Здесь подготовлен конфиг по модели Студента, если экспортируете его и зайдете посмотрите через GUI менеджер то увидете на вкладке Migxdb-Settings настройки для подключения к нашему классу myStudent:

А на вкладке CMP-Settings можно настроить надписи для нашей странички управления записями БД:

Так-же в колонках(Columns) нужно добавлять id,deleted и published для корректной работы редактирования, удаления в корзину и публикации.
Конфигурацию для университетов попробуйте создать сами, можно на основе конфигурации Студентов заменив класс и надписи в настройках и убрав лишние поля оставив только name.
Так-же при создании конфигураций стоит прописывать им unique MIGX ID: поле которого находится в первой вкладке Settings, и который должен быть уникален у каждой конфигураций(я прописываю таким-же как и имя у конфигурации).
Теперь когда мы создали наши конфигурации, присовили им имена, unique MIGX ID и настроили MIGX DB у каждой из них, можно зайти на страничку students-and-universities и посмотреть список наших студентов:
Вывод имени университета обеспечивается с помощью настроек Joins на вкладке Migxdb-Settings в менеджере MIGX:
И колонки с Field: University_name, где University - это alias связи <aggregate> в xml схеме нашей модели, а name - это поле внутри object myUniversity.
Если вы попробуйте зайти в редактирование студента, то увидите что выбор университета так-же работает:
Он работает с помощью input TV type: listbox и @SELECT в Input Option Values:
Для сравнения я добавил так-же поле mod_user, которое берет inputTV: select-user(вам следует его создать как новый TV у себя в MODX если хотите протестировать), который так-же обеспечивает выбор из обьектов БД по принципу, который я описывал в этой статье.
В отличие от выбора университета, выбор пользователя работает со строкой поиска что часто очень полезно при работе с БД. К сожалению я не смог найти как добиться такой-же функции у input TV type: listbox.

Теперь когда объекты лежат в Базе Данных и ждут своего часа мы можем выводить их на страницах нашего сайта с помощью migxLoopCollection , который уже находится в пакете MIGX. Примеры использования можно посмотреть здесь и здесь.
Или самостоятельно получать через сниппеты с помощью $collection = $modx->getCollection('myUniversity', array('deleted'=>0));

Обяснение почему нужно наследоваться от xPDOSimpleObject
Документация MIGX по созданию такой-же странички для управления записями в БД "Doodles Manager"
Документация по созданию модели xpdo обьектов MODX
Примеры моделей и запросов xpdo обьектов MODX
Видео туториал по созданию подобной странички
Инструкция по добавлению пользовательских обьектов в MODX
Примеры использования Joins 
Конфигурация MIGX CMP для One to Many схемы

1 комментарий:

  1. Спасибо за детально изложенный материал! Информация очень ценна!!! Еще раз спасибо!

    ОтветитьУдалить