Разработка кастомного пакета (Extra) MODX

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Разработка кастомного пакета (Extra) MODX
Сложная
~1-2 недели
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Разработка кастомного пакета (Extra) MODX

Extra MODX — полноценное расширение: компонент (интерфейс в менеджере), набор сниппетов, плагинов, чанков, системных настроек. Упаковывается в .transport.zip для установки через Package Manager. Это правильный способ распространять и поддерживать сложную функциональность.

Структура Extra

core/components/myextra/
├── controllers/
│   └── home.class.php          # MODX контроллер
├── docs/
│   └── changelog.txt
├── elements/
│   ├── chunks/
│   ├── plugins/
│   ├── snippets/
│   └── templates/
├── lexicon/
│   └── ru/
│       └── default.inc.php     # Переводы
├── model/
│   └── myextra/                # xPDO модели
│       ├── myitem.class.php
│       ├── mysql/
│       │   ├── myitem.class.php
│       │   └── myitem.map.inc.php
│       └── myextra.mysql.schema.xml
└── processors/
    └── mgr/
        └── items/
            ├── getlist.class.php
            ├── get.class.php
            ├── create.class.php
            ├── update.class.php
            └── remove.class.php

assets/components/myextra/
├── js/
│   ├── mgr/
│   │   └── myextra.js          # ExtJS интерфейс
│   └── widgets/
│       └── items.grid.js
└── css/
    └── mgr.css

xPDO схема БД

<!-- core/components/myextra/model/myextra/mysql/myextra.mysql.schema.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<model package="myextra" baseClass="xPDOObject" platform="mysql" version="1.1">
    <object class="MyItem" table="myextra_items" extends="xPDOSimpleObject">
        <field key="name" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
        <field key="description" dbtype="text" phptype="string" null="true"/>
        <field key="price" dbtype="decimal" precision="10,2" phptype="float" null="false" default="0.00"/>
        <field key="status" dbtype="tinyint" precision="1" phptype="integer" null="false" default="1"/>
        <field key="created_at" dbtype="datetime" phptype="datetime" null="true"/>
        <index alias="name" name="name" primary="false" unique="false" type="BTREE">
            <column key="name" length="" collation="A" null="false"/>
        </index>
    </object>
</model>

xPDO модель

// core/components/myextra/model/myextra/myitem.class.php
class MyItem extends xPDOSimpleObject {
    public function getLink(): string {
        return $this->xpdo->makeUrl(
            $this->xpdo->getOption('myextra.item_page', null, 1),
            '',
            ['id' => $this->get('id')],
            'full'
        );
    }
}

Процессор (CRUD операции)

// core/components/myextra/processors/mgr/items/getlist.class.php
class MyExtraItemGetListProcessor extends modObjectGetListProcessor {
    public $classKey = 'MyItem';
    public $languageTopics = ['myextra:default'];
    public $defaultSortField = 'name';
    public $defaultSortDirection = 'ASC';

    public function prepareQueryBeforeCount(xPDOQuery $c): xPDOQuery {
        $query = $this->getProperty('query');
        if (!empty($query)) {
            $c->where(['name:LIKE' => "%{$query}%"]);
        }

        $status = $this->getProperty('status', null);
        if ($status !== null && $status !== '') {
            $c->where(['status' => (int)$status]);
        }

        return $c;
    }

    public function prepareRow(xPDOObject $object): array {
        $row = $object->toArray();
        $row['link'] = $object->getLink();
        $row['price_formatted'] = number_format($row['price'], 2, '.', ' ') . ' ₽';
        return $row;
    }
}

Сниппет Extra

<?php
// core/components/myextra/elements/snippets/myextra.snippet.php
$basePath = $modx->getOption('myextra.core_path', null,
    $modx->getOption('core_path') . 'components/myextra/');

$modx->addPackage('myextra', $basePath . 'model/');
$modx->lexicon->load('myextra:default');

$limit  = (int)($scriptProperties['limit'] ?? 10);
$offset = (int)($scriptProperties['offset'] ?? 0);
$tpl    = $scriptProperties['tpl'] ?? 'myextra.item';

$c = $modx->newQuery('MyItem');
$c->where(['status' => 1]);
$c->limit($limit, $offset);
$c->sortby('name', 'ASC');

$items = $modx->getCollection('MyItem', $c);
$output = '';

foreach ($items as $item) {
    $output .= $modx->getChunk($tpl, $item->toArray());
}

return $output;

Сборка Transport Package

// _build/build.transport.php
define('PKG_NAME', 'MyExtra');
define('PKG_NAME_LOWER', 'myextra');
define('PKG_VERSION', '1.0.0');
define('PKG_RELEASE', 'pl');

// Создание пакета
$builder = new modPackageBuilder($modx);
$builder->createPackage(PKG_NAME_LOWER, PKG_VERSION, PKG_RELEASE);
$builder->registerNamespace(PKG_NAME_LOWER, false, true, '{core_path}components/' . PKG_NAME_LOWER . '/');

// Добавить категорию с элементами
$category = $modx->newObject('modCategory');
$category->set('id', 1);
$category->set('category', PKG_NAME);

// Добавить сниппеты, чанки, плагины...
$snippets = includeSnippets($builder, $modx);
$category->addMany($snippets);

// Создать vehicle
$attr = [
    xPDOTransport::PRESERVE_KEYS => false,
    xPDOTransport::UPDATE_OBJECT => true,
    xPDOTransport::UNIQUE_KEY => 'category',
    xPDOTransport::RELATED_OBJECTS => true,
    xPDOTransport::RELATED_OBJECT_ATTRIBUTES => ['Snippets' => [...], 'Chunks' => [...]],
];

$vehicle = $builder->createVehicle($category, $attr);
$builder->putVehicle($vehicle);

// Финальная упаковка
$builder->pack();

Сроки

Разработка Extra с CRUD интерфейсом в менеджере, 2–3 сниппетами и базовой схемой БД — 2–3 недели.