[ModExtra3] Заготовка для создания компонентов для MODX3

Одна из проблем развития экосистемы MODX3 на текущий день — не очень большой объем доступной информации, инструкций. Официальный сайт только недавно начал выпускать справочные пособия на тему разработки MODX3.

Мне в свое время очень помогла в понимании работы компонентов, подготовленная @Василий Наумкин заготовка для создания компонентов modExtra. Я решил поднять это знамя и донести его до MODX3

Представляю вашему вниманию ModExtra3. Заготовка для создания компонентов и справочное пособие по MODX3.

Сразу хочу сказать, что я далеко не специалист по MODX3. Собственно этот компонент у меня первый. Да и по-современному PHP тоже не особо специалист. Потому прошу отнестись к текстовым пояснениям и самому коду как к любительскому.

Если вы разработчик MODX и ранее пользовались заготовкой modExtra для быстрого создания собственных компонентов — то в общем, то ничего принципиально нового не найдете. Я постарался полностью сохранить логику и функционал старого доброго приложения, лишь переведя его на новые рельсы MODX3.

Далее рассмотрим детали проекта, с точки зрения подготовки нового компонента.

Системные требования


MODX 3.x понятное дело
Минимальная версия PHP теперь 7.2.
Рекомендованной является 7.4.
На 8.0 не тестировалось.

Подготовка



Клонируйте или скачайте zip архив проекта из официального репозитория сообщества. Если скачали Zip архив, его потребуется распаковать.

Переименование компонента



Скорее всего вы не будете использовать текущее название компонента ModExtra, а захотите использовать свое.
Для переименования компонента предусмотрен файл rename_it.php, который запустит автоматическую процедуру изменения названия и упоминания этого названия везде по коду. Я назову свой компонент SuperPack

Обратите внимание. Важно называть компонент с большой буквы. Так как по этому наименованию внутри будут созданы соответствующие PHP классы, а современные стандарты, которые славу богу поддерживает MODX3 требуют именования классов и файлов классов с большой буквы!

Если вы запускаете переименование через консоль (локально на компьютере) укажите новое название как параметр команды через пробел.
php ModExtra3/rename_it.php SuperPack
Если же вы положили распакованные файлы компонента где-то на сервере и обращаетесь к php файлу через браузер — то название можно указать GET параметром rename_it.php?name=SuperPack.

Подготовка таблицы базы данных



Следующий логический шаг это подготовка таблицы (или нескольких таблиц) базы данных.
Чтобы описать необходимую для вас таблицу базы данных, необходимо открыть файл modextra.mysql.schema.xml.

В этом файле мы можем рассмотреть первое отличие MODX3 и MODX2. Оно же собственно является главным. Это namespace и следование стандарту PHP PSR-4

Базовая заготовка содержит следующий код.
<?xml version="1.0" encoding="UTF-8"?>
<model package="ModExtra\Model" baseClass="xPDO\Om\xPDOObject" platform="mysql" defaultEngine="InnoDB" version="3.0">
    <object class="ModExtraItem" table="modextra_items" extends="xPDO\Om\xPDOSimpleObject">
        <field key="name" dbtype="varchar" precision="100" phptype="string" null="false" default=""/>
        <field key="description" dbtype="text" phptype="string" null="true" default=""/>
        <field key="active" dbtype="tinyint" precision="1" phptype="boolean" null="true" default="1"/>

        <index alias="name" name="name" primary="false" unique="false" type="BTREE">
            <column key="name" length="" collation="A" null="false"/>
        </index>
        <index alias="active" name="active" primary="false" unique="false" type="BTREE">
            <column key="active" length="" collation="A" null="false"/>
        </index>
    </object>
</model>
Изменения коснулись нескольких строк, которые почти не требуется менять.
Поле package=«ModExtra\Model» Это расположение каталога в котором будут находиться описания объектов для работы с таблицами.

Если в modx2 для обращения к объекту вы писали примерно так
$modx->getObject('modextraitem', 1);

// Некоторые даже так
$modx->getObject(modextraitem::class, 1);
То теперь логика обращения стала сложнее и здесь нам как раз нужно знать, что мы указали в поле package

$modx->getObject(ModExtra\Model\ModExtraItem::class, 1);
Не все так плохо. На помощь приходит PSR-4 который, позволяет писать вот так:

// Один раз укажем какой именно класс мы имеем ввиду когда вызываем ModExtraItem
use ModExtra\Model\ModExtraItem;

// и дальше используем короткую запись
$modx->getObject(ModExtraItem::class, 1);
Внутри компонента есть пример сниппета, там вы можете посмотреть живой пример обращения к базе через getObject.

Продолжим рассмотрение схемы базы данных.

Поле baseClass=«xPDO\Om\xPDOObject» тоже изменилось по сравнению с MODX2, но, в общем то, не меняется из проекта в проект. Оставьте как есть.

Далее по коду схемы идет описание объекта
<object class="ModExtraItem" table="modextra_items" extends="xPDO\Om\xPDOSimpleObject">
Что тут нужно знать. Каждый объект — это отдельная таблица. Именование класса обязательно с большой буквы. Этого требует стандарт. Название таблицы базы данных указывайте без префикса. Он будет добавлен автоматически.

Поле extends=«xPDO\Om\xPDOSimpleObject» почти всегда остается таким.

В MODX всего два базовых класса.
  • xPDOObject
  • xPDOSimpleObject
Разница лишь в том что xPDOObject не имеет поля ID и используется в довольно специфических случаях. Если не знаете что использовать оставьте как есть xPDO\Om\xPDOSimpleObject

Ну и далее все без изменений относительно MODX2
Описываете поля по собственному разумению
<field key="name" dbtype="varchar" precision="100" phptype="string" null="false" default=""/>
Готовая база примеров таких полей это minishop2. Всегда можно подсмотреть как правильно описать поля.

Если схема составлена правильно — во время установки автоматически будет обновлен и дополнен каталог Model
Его содержимое совсем не обязательно редактировать вручную. Можно вообще очистить, а потом скачать с сайта свежее содержимое. В комплекте он нужен только для того, чтобы IDE корректно подсвечивала код.

Автозагрузка



Собственно этот пункт не является как таковым шагом настройки компонента. Просто хочу обратить внимание на новшество MODX3. Теперь каждому компоненту рекомендуется иметь файл bootstrap.php в корне каталога компонента.

Смысл файла сводится к тому, чтобы сразу загрузить базовые настройки компонента в память MODX. Например, сделать доступными по умолчанию таблицы компонента.

Базовое содержание bootstap.php может быть вот таким

// Загружает в память MODX информацию о таблицах базы данных. 
$modx->addPackage('ModExtra\Model', $namespace['path'] . 'src/', null, 'ModExtra\\');

// Загружает в память основной PHP класс компонента.  
$modx->services->add('ModExtra', function ($c) use ($modx) {
    return new ModExtra\ModExtra($modx);
});

Обратите внимание — не всегда нужно забивать память MODX всеми доступными компонентами. Некоторые могут понадобиться в каких то специфических случаях. Их можно загрузить потом вручную.

Резолверы



Резолверы — это скрипты, которые выполняются один раз при установке компонента.
В комплекте прикладывается целый ряд резолверов. Среди них есть следующие
  • tables.php — скрипт который обновляет базу данных. Именно он отвечает за то, чтобы содержимое из Шага 3 попало в таблицу базы
  • setup.php — умеет скачивать указанные компоненты как зависимости. То есть при установке компонента будут загружены дополнительные компоненты
По примеру кода любого из вложенных резолверов вы можете набросать свой скрипт, выполняющий необходимые вам действия. Резолверы выполняются в алфавитном порядке. Если имя резолвера начинается со знака подчеркивания — он пропускается.

Элементы



Это набор различных сущностей MODX — Таких как шаблоны, чанки, сниппеты, плагины и т.п. Их установка уже предусмотрена в билдере компонента. Вам достаточно заполнить стартовые данные по уже готовым примерам.
Здесь работает такое же правило. Если имя элемента начинается с подчеркивания — он пропускается. Потому если вам нужно создать чанки или добавить сниппет, проследите чтобы имя было без подчёркивания.

Процессоры



Процессоры MODX претерпели некоторые изменения. Давайте рассмотрим что с ними произошло.

Если вы ранее имели дело с процессорами MODX2 и даже готовили свои — то знаете, что каждый процессор требовал уникального названия в рамках всего проекта. Вот так к примеру назывался один из процессоров minishop2 msProductFileRemoveProcessor

С приходом namespace все стало проще. Теперь процессоры именуются Create, Remove, Update. Но обязательно нужно указывать namespace. Общее правильно — именование процессора должно быть уникальным внутри одного namespace (внутри каталога)

namespace ModExtra\Processors\Item;

use MODX\Revolution\Processors\Model\CreateProcessor;

class Create extends CreateProcessor
Как можно увидеть из примера — родные процессоры MODX, которые обычно наследуют — тоже изменили свои именования. А вот общая логика осталась прежней. Главное следить за неймспейсом, импортом и наименованием.

ExtJS



Здесь все осталось без особых изменений. Так как фреймворк extJS не менял версии. Единственное изменение, которое мне удалось пощупать — это вызов процессоров.

Давайте вспомним как дергают процессоры в extJS
Вот так это выглядит в двойке
action: 'mgr/item/enable',
Мало о чем говорящая строка, она может вести куда угодно. все зависит от URL коннектора

А вот так вызов выглядит в тройке

action: 'ModExtra\\Processors\\Item\\Enable',
Здесь уже используется пространство имен. И стало несколько более информативнее.

Завершение


Вот и подошел к завершению мой сумбурный экскурс в MODX3 и ModExtra3
Он далек от идеала настолько же, как я далек от Льва Толстого (и как программист, и как писатель).

Большая получилась простыня текста. Возможно было бы правильно разбить все на небольшие более детальные статьи. Вы уж меня простите.

Тем не менее — минимум информации и пособий по MODX3 на русском языке — дают мне право считать себя одним из первопроходцев.

После знакомства с MODX3 я могу уверенно сказать что испытал удовольствие как программист. Переход к
неймспейсам, импортам, традиционным стандартам PSR вызывает только приятные ощущения. Да глобально MODX все еще считается устаревшим продуктом. Но он совершенно точно вырос в качестве. Это заметно, это радует.

Далее традиционно хочу написать про финансовую поддержку.
Впереди по идее перенос Minishop на новые рельсы, а за ним еще большое количество популярных продуктов, сделавших MODX таким как он есть и ныне почти заброшенных. Это большой объем работы, который все ждут, часто спрашивают, но почему то мало кто решается поддержать кодом или мотивировать финансово.

Нам требуется ваша финансовая поддержка. Ибо только так, мы можем подготовить ожидаемые продукты, не отвлекаясь на насущные заботы, связанные с заработком.

Предлагаю каждому, кто использует modExtra и планирует использовать ModExtra3 поблагодарить команду modx.pro за потраченное время и внести свой посильный взнос на развитие нашей продуктовой линейки, так как она позволяет зарабатывать и вам тоже.

Развитие проектов modx.pro происходит исключительно благодаря Вам друзья!
Финансовая поддержка с вашей стороны, позволяет выделять больше времени на развитие сообщества и обновлять наши проекты, которые в свою очередь приносят пользу и вам.

Поддержать нас можно, используя следующие каналы для доната:
Огромное спасибо, всем кто поддерживает!
Николай Савин
06 июля 2022, 16:56
modx.pro
6
1 795
+20
Поблагодарить автора Отправить деньги

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

Роман
07 июля 2022, 09:02
+2
Отличная статья и работа.
>>Обратите внимание. Важно называть компонент с большой буквы.
тут можно было использовать — ucfirst.
    Александр Мельник
    07 июля 2022, 16:49
    0
    Спасибо большое. Нужная вещь. Когда вы только время находите.
      Максим
      12 августа 2022, 16:11
      0
      Спасибо! Опередили меня буквально на пару дней (день разработки и день составления статьи)!
      А мне одному не хватает заготовки для медиасорсов? Или я почти переписав так и не разобрался до конца с ним и постоянно использую костыльно-ориентированное программирование?
        Николай Савин
        12 августа 2022, 16:14
        0
        Насчет медиаресурсов — в открытом доступе есть minishop2 там есть заготовка для медиа.
        MIniShop3 для MODX3 тоже есть, но он в пока в закрытом доступе. Разница конкретно в установке медиасорсов не особо большая.
          Максим
          12 августа 2022, 16:25
          0
          Да у меня нет проблем с добавлением! Просто это рутинная работа работа повторяющаяся из компонента в компонент!))
        Stepan
        22 января 2023, 06:13
        0
        я там пару изменений внес
        мне помогли может и вам пригодится
          Николай Савин
          22 января 2023, 08:52
          0
          Хорошо посмотрю на досуге. Спасибо.
            Stepan
            22 января 2023, 12:41
            0
            отменили правки…
          Дима Касаткин
          22 января 2023, 16:34
          0
          Подскажите кто в курсе, какой лучший рецепт сейчас, для создания универсальных компонентов под MODX2+MODX3?

          Если я соберу компонент способом из статьи, совместимости с MODX2 ведь не останется, а она пока нужна.
          Григорий Розенбаум
          13 августа 2023, 14:43
          0
          Возникла странная проблема.
          Для локальной разработки под виндой я использую Docker + wsl2.
          При вызове build.php каталоги Extras/ModExtra3/core/components/modextra3 и Extras/ModExtra3/assets/components/modextra3 почему-то превращаются в файлы (так они видны как из виртуалки так и из винды). При этом сам скрипт отрабатывает нормально. Что это может быть? Как этого избежать? У кого какие мысли?
            Григорий Розенбаум
            13 августа 2023, 14:56
            0
            UPD. Вопрос снят. каталоги превращаются в symlink на новое место ) Видимо заработался… )
            Ivan
            11 октября 2023, 17:22
            0
            Спасибо за заготовку. Кстати отлично работает под php 8.1
              Ivan
              11 октября 2023, 18:50
              0
              Хочу еще отметить, если скачивать zip-архив, почему-то нерабочая версия заготовки в этом архиве. А вот если клонировать, то все нормально.
                Николай Савин
                12 октября 2023, 17:09
                0
                Спасибо за обратную связь. Расскажи откуда ты берешь zip и как понял что он не рабочий?
                  Ivan
                  12 октября 2023, 17:16
                  0
                  С github, жму download zip. Почему-то там лежит вариант с ошибками в коде, конкретно в файле rename_it.php. Понял когда не получилось переименовать пакет)
                    Ivan
                    12 октября 2023, 17:21
                    0
                    Опять попробовал скачать. Теперь все в порядке, мистика)
                      Николай Савин
                      12 октября 2023, 17:23
                      0
                      Там нет отдельного архива — он формируется автоматом в момент нажатия кнопки.
                        Ivan
                        12 октября 2023, 17:26
                        0
                        Наверное я сам, что-то натворил). Все рабочее
                Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                19