Розробка кастомного модуля Craft CMS під бізнес-задачі

Інтернет-магазин на Craft CMS — товари надходять з 1С по CommerceML, але ціни оновлюються раз на добу. Клієнти скаржаться на застарілі акції, а редактору потрібен кастомний звіт по продажах з фільтрами за категоріями та періодами. Стандартні плагіни на кшталт CP Reports не дають потрібної гнучкості

Розробка та обслуговування будь-яких видів сайтів:

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

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Розробка кастомного модуля Craft CMS під бізнес-задачі
Середній
~3-5 днів

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

Часті запитання

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1467
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1317
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1014
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1276
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1019
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1019

Інтернет-магазин на Craft CMS — товари надходять з 1С по CommerceML, але ціни оновлюються раз на добу. Клієнти скаржаться на застарілі акції, а редактору потрібен кастомний звіт по продажах з фільтрами за категоріями та періодами. Стандартні плагіни на кшталт CP Reports не дають потрібної гнучкості — доводиться лізти в ядро Craft або писати CRON-скрипти поверх. Вихід — розробити кастомний модуль на Yii2 (Yii Framework), який вирішує обидві задачі: консольна команда для синхронізації цін і Twig-розширення для звіту.

Ми створюємо модулі, які вирішують рівно одну задачу і не тягнуть зайвого. За п'ять років реалізували понад 20 проєктів: від простих Twig-розширень до повноцінних консольних синхронізаторів із зовнішніми API. У цій статті — як ми це робимо і що виходить у результаті.

Розробка кастомного модуля Craft CMS: як це робиться

Проблеми, які вирішуємо — розробка кастомного модуля

  • Інтеграція із зовнішнім API: синхронізація товарів з 1С через REST API. Стандартні плагіни не підтримують кастомні поля, тому модуль реалізує сервіс SyncService з методами syncPrices(), syncStocks(). Консольна команда запускається по крону кожні 15 хвилин, забезпечуючи актуальність даних.
  • Кастомні звіти та дашборди: для редактора потрібен звіт по продажах за тиждень з групуванням за категоріями. Через модуль підключаємо свій контролер DashboardController і Twig-шаблони, використовуючи Yii2 GridView для таблиць.
  • Складні Twig-фільтри: форматування телефонів, цін з пробілами, SVG-іконок. Виносимо в Twig-розширення, щоб не дублювати код у шаблонах.
  • Нестандартні поля: наприклад, поле «термін придатності» з автоматичним розрахунком. Створюємо поведінку (behavior) для елемента, яка валідує поле при збереженні.

Як ми це робимо

Використовуємо актуальні версії: Craft CMS 4/5, PHP 8.1+, Yii2 — основа Craft CMS. Основний стек — PHP, Yii2, Twig, MySQL/PostgreSQL. Для консольних команд — Symfony Console, вбудований у Craft.

Розберемо типовий кейс: інтернет-магазину знадобився кастомний блок «Товари зі знижкою» з динамічним оновленням цін кожні 15 хвилин. Ми реалізували:

  • Сервіс DiscountService — отримує товари зі знижкою з БД із кешуванням через Redis.
  • Twig-функцію discountProducts() — виводить блок на сторінці.
  • Консольну команду discount/update — оновлює дані по крону.

Завдяки оптимізації запитів час генерації складних звітів скорочується на 40%. Модуль не створює зайвого навантаження на сервер — всі сервіси завантажуються лише при необхідності.

Ключовий клас модуля — SiteCustomModule, який реєструє сервіси та Twig-розширення. Ось його структура:

// modules/sitecustom/SiteCustomModule.php namespace modules\sitecustom; use Craft; use craft\events\RegisterComponentTypesEvent; use craft\services\Elements; use craft\web\twig\variables\CraftVariable; use modules\sitecustom\services\ProductService; use modules\sitecustom\variables\SiteVariable; use modules\sitecustom\twigextensions\SiteTwigExtension; use yii\base\Event; use yii\base\Module; class SiteCustomModule extends Module { public static SiteCustomModule $instance; public function init(): void { parent::init(); self::$instance = $this; Craft::setAlias('@modules/sitecustom', __DIR__); $this->setComponents([ 'products' => ProductService::class, ]); Event::on(CraftVariable::class, CraftVariable::EVENT_INIT, function (Event $event) { $event->sender->set('site', SiteVariable::class); }); if (Craft::$app->request->getIsSiteRequest()) { Craft::$app->view->registerTwigExtension(new SiteTwigExtension()); } } } 

Реєстрація в config/app.php:

return [ 'modules' => [ 'site-custom' => \modules\sitecustom\SiteCustomModule::class, ], 'bootstrap' => ['site-custom'], ]; 

Приклад сервісу з бізнес-логікою

// modules/sitecustom/services/ProductService.php namespace modules\sitecustom\services; use craft\base\Component; use craft\elements\Entry; class ProductService extends Component { public function getFeaturedProducts(int $limit = 6): array { return Entry::find() ->section('products') ->featured(true) ->inStock(true) ->orderBy('sortOrder asc, postDate desc') ->limit($limit) ->with(['featuredImage', 'categories']) ->all(); } public function updateStock(int $entryId, int $quantity): bool { $entry = Entry::find()->id($entryId)->one(); if (!$entry) return false; $entry->setFieldValue('stockQuantity', $quantity); return \Craft::$app->elements->saveElement($entry); } } 

Приклад Twig-розширення

// modules/sitecustom/twigextensions/SiteTwigExtension.php namespace modules\sitecustom\twigextensions; use Twig\Extension\AbstractExtension; use Twig\TwigFilter; use Twig\TwigFunction; class SiteTwigExtension extends AbstractExtension { public function getFilters(): array { return [ new TwigFilter('formatPrice', [$this, 'formatPrice']), new TwigFilter('phoneFormat', [$this, 'formatPhone']), ]; } public function getFunctions(): array { return [ new TwigFunction('svg', [$this, 'inlineSvg'], ['is_safe' => ['html']]), ]; } public function formatPrice(float $price, string $currency = 'RUB'): string { return number_format($price, 0, '.', ' ') . ' ' . $currency; } public function formatPhone(string $phone): string { $digits = preg_replace('/\D/', '', $phone); return preg_replace('/(\d)(\d{3})(\d{3})(\d{2})(\d{2})/', '+$1 ($2) $3-$4-$5', $digits); } public function inlineSvg(string $name): string { $path = \Craft::getAlias('@webroot/icons/' . $name . '.svg'); return file_exists($path) ? file_get_contents($path) : ''; } } 

Приклад консольної команди

// modules/sitecustom/console/controllers/SyncController.php namespace modules\sitecustom\console\controllers; use craft\console\Controller; use yii\console\ExitCode; class SyncController extends Controller { public function actionProducts(): int { $this->stdout("Синхронізація товарів...\n"); $count = SiteCustomModule::$instance->products->syncFromExternalApi(); $this->stdout("Синхронізовано: {$count} товарів\n"); return ExitCode::OK; } } 

Запуск: php craft site-custom/sync/products.

Чому модуль краще плагіна для унікальних завдань?

Характеристика Модуль Плагін
Поширення Тільки в проєкті Composer-пакет
Ліцензія Не потрібна Є (MIT, GPL тощо)
Версіонування Немає CHANGELOG.md
Вартість розробки На 30–40% нижча Вища через універсальність
Швидкість розробки В 2–3 рази швидше Довше через універсальність

Модуль краще, якщо функціональність прив'язана до конкретного сайту. Плагін — коли планується публікація або тиражування. Ми гарантуємо, що модуль не містить зайвих залежностей і суворо відповідає вашим вимогам. Замовте розробку модуля під ключ — заощадьте до 40% бюджету порівняно з самостійним впровадженням.

Склад кастомного модуля

Етапи розробки

Етап Тривалість Результат
Аналіз вимог 1–2 дні ТЗ, проектування
Реалізація сервісів і розширень 2–5 днів Код модуля
Інтеграція та тестування 1–2 дні Працююча функціональність
Документування та здача 0.5–1 день Документація, доступи

Загальний термін: від 3 до 7 днів залежно від складності.

Що входить у роботу

  • Код модуля з коментарями українською/англійською
  • Документація з установки та налаштування
  • Консольні команди (за наявності)
  • Інтеграція з шаблонами (Twig-розширення)
  • 30 днів підтримки після здачі проєкту

Типові помилки при розробці модулів

  • Плутанина з простором імен — модуль має бути в неймспейсі modules\ім'япроєкту, інакше автозавантаження не спрацює.
  • Забули прописати alias — без Craft::setAlias('@modules/...', __DIR__) не підвантажаться файли.
  • Дублювання логіки — часто намагаються копіювати код з плагінів, порушуючи принцип єдиної відповідальності.

Уникнути цих помилок допомагає наш досвід і code review. Сертифіковані розробники з 5+ роками досвіду гарантують якість коду.

Процес роботи та реєстрація модуля

  1. Створіть папку modules/ваш-модуль і додайте основний клас.
  2. Визначте неймспейс modules\ваш-модуль.
  3. Зареєструйте модуль в config/app.php у секціях 'modules' і 'bootstrap'.
  4. Пропишіть alias Craft::setAlias('@modules/ваш-модуль', __DIR__) в методі init() основного класу.
  5. Запустіть php craft project-config/apply для синхронізації конфігурації.

Чому вигідно замовити модуль під ключ?

Розробка модуля під ключ економить час вашої команди: не потрібно розбиратися в тонкощах Yii2 та архітектури Craft. Ми беремо на себе проектування, реалізацію та тестування. Зв'яжіться з нами, щоб розробити кастомний модуль Craft CMS для вашого проєкту. Отримайте консультацію — оцінимо задачу та запропонуємо рішення.