Разработка кастомного плагина MODX

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

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

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

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

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

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

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

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

  • 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

Разработка кастомного плагина MODX

Плагин MODX — PHP-код, привязанный к системным событиям. Перехватывает моменты жизненного цикла CMS: загрузка страницы, сохранение ресурса, аутентификация, ошибки, кэш. В отличие от сниппета, плагин не возвращает контент — он изменяет поведение системы.

Привязка к событиям

// Плагин AutoSEO — автоматически заполняет SEO-поля
// События: OnBeforeDocFormSave (до сохранения ресурса в менеджере)

$eventName = $modx->event->name;

switch ($eventName) {
    case 'OnBeforeDocFormSave':
        handleBeforeSave($modx, $resource, $mode);
        break;

    case 'OnDocFormSave':
        handleAfterSave($modx, $resource, $mode);
        break;
}

function handleBeforeSave($modx, $resource, $mode): void {
    // Автозаполнение description из introtext
    if (empty($resource->get('description')) && !empty($resource->get('introtext'))) {
        $description = mb_substr(strip_tags($resource->get('introtext')), 0, 160);
        $resource->set('description', $description);
    }

    // Автозаполнение longtitle из pagetitle
    if (empty($resource->get('longtitle'))) {
        $resource->set('longtitle', $resource->get('pagetitle'));
    }
}

Популярные события MODX

Событие Когда Применение
OnPageNotFound 404 ошибка Кастомный 404, редиректы
OnHandleRequest Каждый запрос Редиректы, геолокация
OnLoadWebDocument Загрузка ресурса Модификация контента
OnBeforeDocFormSave До сохранения в менеджере Валидация, автозаполнение
OnDocFormSave После сохранения Синхронизация с внешней системой
OnUserLogin Вход пользователя Логирование, 2FA
OnCacheUpdate Очистка кэша Синхронизация CDN
OnSiteRefresh Сброс настроек Хуки деплоя

Плагин 301-редиректов

<?php
// Плагин Redirects
// Событие: OnPageNotFound

$uri = $_SERVER['REQUEST_URI'];
$redirects = $modx->getOption('custom_redirects', null, '');

// Редиректы хранятся как JSON в системной настройке
$redirectMap = json_decode($redirects, true) ?? [];

foreach ($redirectMap as $from => $to) {
    if (strpos($uri, $from) === 0) {
        $target = str_replace($from, $to, $uri);
        $modx->sendRedirect($target, ['responseCode' => 'HTTP/1.1 301 Moved Permanently']);
        exit;
    }
}

// Показать кастомную 404 страницу
$errorPage = $modx->getOption('error_page', null, 404);
$modx->sendForward($errorPage, ['response_code' => 'HTTP/1.1 404 Not Found']);

Плагин геолокации

<?php
// Плагин GeoRedirect
// Событие: OnHandleRequest

if ($modx->context->key === 'web') {
    $ip = $_SERVER['HTTP_CF_CONNECTING_IP'] ?? $_SERVER['REMOTE_ADDR'] ?? '';

    // Только для первого посещения (без куки)
    if (!isset($_COOKIE['geo_redirect_done'])) {
        $geoData = getGeoByIp($ip);
        $currentUri = $_SERVER['REQUEST_URI'];

        $countryContextMap = ['BY' => 'by', 'UA' => 'ua', 'KZ' => 'kz'];
        $targetContext = $countryContextMap[$geoData['country']] ?? null;

        if ($targetContext && $modx->context->key !== $targetContext) {
            setcookie('geo_redirect_done', '1', time() + 86400, '/');
            $modx->sendRedirect('/' . $targetContext . $currentUri);
            exit;
        }
    }
}

function getGeoByIp(string $ip): array {
    // MaxMind GeoIP2 или ipapi.co
    $response = file_get_contents("https://ipapi.co/{$ip}/json/");
    return json_decode($response, true) ?? ['country' => 'RU'];
}

Плагин синхронизации с CRM

<?php
// Плагин CRMSync
// Событие: OnDocFormSave

if ($modx->event->params['mode'] === modSystemEvent::MODE_UPD
    && in_array($resource->get('template'), [5, 6])) {  // только определённые шаблоны

    $crmApiKey  = $modx->getOption('crm_api_key');
    $crmApiUrl  = $modx->getOption('crm_api_url');

    $data = [
        'id'       => $resource->id,
        'title'    => $resource->get('pagetitle'),
        'url'      => $modx->makeUrl($resource->id, '', '', 'full'),
        'price'    => $resource->getTVValue('price'),
        'category' => $resource->get('parent'),
        'updated'  => time(),
    ];

    $ch = curl_init($crmApiUrl . '/products/' . $resource->id);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CUSTOMREQUEST  => 'PUT',
        CURLOPT_POSTFIELDS     => json_encode($data),
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $crmApiKey,
        ],
        CURLOPT_TIMEOUT        => 5,
    ]);

    $response = curl_exec($ch);
    $httpCode  = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode >= 400) {
        $modx->log(modX::LOG_LEVEL_ERROR, "CRM sync failed for resource {$resource->id}: {$response}");
    }
}

Хранение плагина в файле

// В редакторе плагина: File Source = файловая система
// Файл: core/components/myplugin/myplugin.plugin.php

// Это позволяет версионировать плагин в git

Плагин StaticElements синхронизирует плагины между БД и файловой системой.

Сроки

Разработка плагина для одного-двух событий — 0.5–1 день. Сложный плагин с множеством событий и внешними интеграциями — 2–4 дня.