[modHelpers] Загрузка моделей для кастомных таблиц

Ночами не сплю, думаю как бы ещё облегчить жизнь разработчикам. :) И вот надумалось упростить загрузку моделей для своих таблиц. Это нужно когда вы создаёте таблицу и хотите использовать методы MODX для доступа к ней. Для разработчиков компонентов пока этот вариант не подойдёт. Может в будущем что придумается. А вот для расширения своего сайта поможет новая функция load_model(), которая загружает модель.

Обычно разработчики пользуются компонентом CMPGenerator. Он генерирует необходимые файлы. Для использования модели в коде нужно загрузить её через addPackage(). В моём варианте модель загружается при загрузке страницы. Поэтому она доступа сразу.

Последовательность такая.
Шаг 1. Как обычно создаём таблицу для объектов (для примера modx_objects) через phpMyAdmin.

Шаг 2. Создаём файл для загрузки модели. Например, файл объектов и разместим его в папке core/models/objects.php.
<?php 
// Класс у нашей модели будет называться 'Object'
if (!class_exists('Object')) {
    class Object extends xPDOObject{}
    class Object_mysql extends Object{}
    // Указываем класс и имя таблицы без префикса
    load_model('Object', 'objects', function ($model) {
        /** @var modHelperModelBuilder $model */
        $model->id('id')->pk(); // тип поля unsigned integer и указываем, что это первичный ключ.
        $model->varchar('name', 100)->setDefault('string')->rulePregMatch('invalid','/^[a-zA-Z\s]+$/','Нельзя использовать цифры в названии!');
        $model->text('description')->null()->alias('desc');
        $model->arr('properties')->null(); // array phptype
        $model->int('rid',true)->aggregate('Resource',array('class'=>'modResource','foreign'=>'id','cardinality'=>'one', 'owner'=>'foreign'))->index();
        $model->int('createdby')->unsigned()->aggOneForeign('CreateUser','modUser','id')->index(); 
        $model->int('createdby', true)->aggOneForeign('EditUser','modUser','id')->index(); 
        $model->datetime('createdon'); // Если дата храниться в БД с типом datetime
        $model->bigint('editedon',true)->phpType('datetime');// Если дата храниться в базе в UNIX формате.
    });
}
В этом же файле можно расширить и базовые классы, например, ресурсов и пользователей.

Шаг 3. В плагине загружаем файл.
switch ($modx->event->name) {
	case 'OnMODXInit':
		include_once MODX_CORE_PATH . 'models/objects.php';
		break;
}

Теперь можно спокойно пользоваться xPDO.
$object = $modx->getObject('Object', 1);
$Creater = $object->CreateUser->username;
// Валидация
$obj->set('name', 'Супер 777');
if (!$obj->validate()) {
    $validator = $obj->getValidator();
    return $validator->getMessages()[0]['message'];
}
$obj->save();

Можно добавлять индексы, связи aggregate и composite, rule для валидации. Всего несколько строчек и дверь xPDO открыта.

В целях оптимизации модель кэшируется. Так что, если вы поменяли модель в файле, нужно удалить файл с кэшированной версией в core/cache/default/название_модели_map.php.

Ещё в этой версии библиотеки добавлены несколько методов в класс коллекции
  • joinGroup — для ресурсов и пользователей.
  • // Добавим первых 10 пользователей в группу Manager
    users()->whereIn('id',range(1,10))->joinGroup('Manager');
  • leaveGroup — для ресурсов и пользователей.
  • whereIn
  • whereNotIn
  • whereLike
  • resources()->whereLike('pagetitle', '%продукт%')->get();
  • whereNotLike
  • whereIsNull
  • whereIsNotNull
А также добавлен класс modHelperMailer для функции email(). Позволяет использовать цепочки методов. Его можно использовать и отдельно от функции.
email()
	->to('user1@mail.ru')
	->toUser(5)
	->cc('user2@mail.ru') 
	->subject('Тема письма')
	->content('тело сообщения')
	->from('Администратор')
	->replyTo('admin@gmail.com')
	->attach('file1.jpg')
	->send();

Вроде ничего не забыл. В ближайшее время обновлю документацию.
Сергей Шлоков
23 января 2017, 15:16
modx.pro
2
2 226
+7
Поблагодарить автора Отправить деньги

Комментарии: 12

Павел Гвоздь
23 января 2017, 18:24
+1
Для разработчиков компонентов это не вариант. Ведь для пакетов нужна ещё и схема. А вот если расширять свой сайт, то схема нафиг не нужна. Нужен только мап файл.
Компоненты тоже можно без схемы делать, на одних мап файлах. Николай Ланец так и делает.
    Сергей Шлоков
    23 января 2017, 18:25
    -1
    Тогда таблицы придется вручную создавать.
      Павел Гвоздь
      23 января 2017, 18:29
      0
      Это как? Через phpMyAdmin (например)?
        Сергей Шлоков
        23 января 2017, 18:34
        1
        -1
        Ага. Устанавливаешь например oneBooking и вместо того, чтобы сразу пользоваться, открываешь phpMyAdmin и создаешь несколько таблиц с нужными полями и индексами. :)
          Fi1osof
          24 января 2017, 21:03
          0
          Сергей, если тебе знаний xPDO не хватает, это не означает, что твои шутки становятся смешнее.
        Василий Наумкин
        23 января 2017, 18:46
        0
        Неа. Схема нужна исключительно для генерации map файлов. Таблицы создаются из объектов, которые загружаются из этих файлов.

        В xPDO 3 уже вроде и от map файлов должны были избавиться, оставив одни классы объектов с картой в свойстве — но я еще не проверял, как оно работает.
        Fi1osof
        24 января 2017, 21:02
        1
        +3
        Зачем? Есть методы типа $modx->getManager()->createObjectContainer(), $modx->getManager()->addField(), $modx->getManager()->addIndex(), $modx->getManager()->alterField() и т.п.
      Константин Обухов
      16 февраля 2017, 11:12
      +2
      Спасибо за чудо штуку)
        Сергей Шлоков
        16 февраля 2017, 16:52
        0
        Да пожалуйста! )
          Константин Обухов
          22 февраля 2017, 12:58
          0
          Можно еще попробывать сделать хелпер is_mob() сам использую сниппет Код основы тут на сайте где 70% с мобильных устройств косяка за регуляркой этого скрипта замечено не было…
            Сергей Шлоков
            22 февраля 2017, 15:28
            0
            Ок. Первое предложение за всё время.
            Я изначально предлагал подключиться разработчикам с предложениями упрощения рутинных задач разработки, так как у меня в этом опыта не много.

            П.С. В новой версии добавил очередь к email, чтобы не нагружать сайт при загрузке страницы. Т.е. вместо отправки почты она сохраняется в очередь, а потом в cron скрипте можно отправить из очереди. Причем очередей можно создать сколько угодно. Например, одна для админа с уведомлением о новом пользователе, другая для подписчиков новостей и т.д.
        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        12