Розробка кастомного плагіна October CMS

Коли стандартний плагін не справляється з бізнес-завданнями, а доопрацювання чужого коду призводить до збоїв і втрати часу, на допомогу приходить індивідуальна розробка. Ми створюємо кастомні плагіни October CMS з нуля, повністю адаптуючи їх під вашу архітектуру та бізнес-процеси. Наша команда бере на себе весь цикл — від проєктування до впровадження та подальшої підтримки, забезпечуючи стабільну роботу й легке масштабування рішення.

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

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

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

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

Розробка кастомного плагіна October CMS

Уявіть: готовий плагін з маркетплейсу не дає потрібної гнучкості — форма не збирає кастомні поля, фільтрація за пов'язаними моделями не працює, API-інтеграція зависає. Вихід — розробити плагін під себе. За 5 років ми випустили понад 50 кастомних рішень для October CMS, і цей досвід дозволяє робити їх швидко, без сюрпризів.

Як кастомний плагін вирішує бізнес-завдання?

Плагін в October CMS — це повноцінний Laravel-пакет, який реєструє компоненти, моделі, маршрути та бекенд-контролери. Він може замінити цілий мікросервіс: керувати відгуками, інтегруватися з 1С або CRM, виводити кастомні фільтри. На відміну від доопрацювань через копіпасту в тему, плагін легко оновлюється, не ламає ядро і повторно використовується на інших сайтах проекту.

Чому кастомний плагін кращий за доопрацювання готового?

Правити чужий код — ризикувати стабільністю. При кожному оновленні плагіна ваші правки затруться. Спеціалізований плагін пишеться з нуля під вашу архітектуру: ми контролюємо кожну таблицю, кожну подію. Кастомне рішення в 3 рази швидше працює, ніж доопрацьований стандартний плагін. Порівняйте: на доопрацювання існуючого плагіна йде 2–3 дні, але потім ще тиждень на відлов багів. Новий плагін — 5 днів і готово, з гарантією та документацією. Вартість розробки простого плагіна стартує від $500.

Які проблеми вирішуємо?

Найчастіше клієнти стикаються з відсутністю потрібних полів у формах, неоптимальними SQL-запитами (N+1) та неможливістю гнучко налаштувати права доступу. Ми закриваємо ці проблеми на етапі проектування: використовуємо eager loading, кешування через Cache::remember та кастомні валідатори. Близько 90% клієнтів обирають кастомну розробку після консультації.

Процес створення плагіна

Як ми розробляємо?

  1. Аналіз — отримуємо від вас ТЗ або описуємо вимоги разом. Фіксуємо моделі, зв'язки, компоненти, права доступу.
  2. Проектування — малюємо ER-діаграму, схему компонентів, бекенд-навігацію.
  3. Реалізація — пишемо міграції, моделі, компоненти, контролери та події. Код покриваємо тестами (Pest/PHPUnit).
  4. Інтеграція — підключаємо плагін до вашого сайту, налаштовуємо кешування, оптимізуємо запити.
  5. Деплой та документація — передаємо архів з composer.json, README, конфіги, а також навчання вашої команди.

Що входить до складу плагіна?

  • Вихідний код плагіна з ліцензією MIT (або вашою)
  • composer.json з автозавантаженням
  • Міграції та seed-дані
  • Бекенд-контролери та меню навігації
  • Компоненти для фронтенду (Twig/Partial)
  • Події та хуки для розширення
  • Тести (якщо потрібно)
  • README з описом встановлення та використання
  • Підтримка 30 днів після здачі

Типові помилки та їх запобігання

Які помилки допускають найчастіше?

  • N+1 запити в компонентах — забувають про with() та load(). Ми використовуємо eager loading та кешування через Cache::remember.
  • Жорстка прив'язка до ID в навігації — при перенесенні на інший сервер ламається. У нас — автоматична побудова через Backend::url().
  • Відсутність валідації — користувач вводить що завгодно. Ставимо Validation трейт з правилами.
  • Ігнорування подій — не підписуються на cms.page.beforeDisplay, через що не спрацьовує кастомізація. Ми завжди використовуємо подієву модель.
Приклад з практики: інтеграція з CRM за 2 дні Один з проектів вимагав синхронізацію замовлень з AmoCRM. Проблема полягала в тому, що стандартні плагіни не підтримували кастомні поля угод. Ми розробили плагін з компонентом, який через REST API відправляв дані при створенні замовлення. Вся робота зайняла 2 дні, тести покрили 95% коду.

Порівняння: кастомний плагін vs доопрацювання існуючого

Критерій Кастомний плагін Доопрацювання існуючого
Сумісність з оновленнями Повна — код не перетинається При кожному оновленні потрібно переносити правки
Час розробки 3–14 днів під ключ 2–3 дні на патч, але ризик багів
Гнучкість Будь-яка логіка, зв'язки, події Обмежений структурою плагіна
Документація README, код-коментарі, навчання Часто відсутня
Гарантія 30 днів на виправлення Залежить від автора

Приклад коду

Нижче наведено мінімальний каркас плагіна. Повний набір файлів показано на прикладі моделі відгуків.

Plugin.php — реєстрація компонентів та навігації

// Plugin.php
namespace MyCompany\MySite;

use Backend;
use System\Classes\PluginBase;

class Plugin extends PluginBase
{
    public function pluginDetails(): array
    {
        return [
            'name' => 'My Site',
            'description' => 'Site-specific functionality',
            'author' => 'My Company',
            'icon' => 'icon-leaf',
        ];
    }

    public function registerComponents(): array
    {
        return [
            \MyCompany\MySite\Components\ReviewList::class => 'reviewList',
            \MyCompany\MySite\Components\ReviewForm::class => 'reviewForm',
        ];
    }

    public function registerNavigation(): array
    {
        return [
            'mysite' => [
                'label' => 'My Site',
                'url' => Backend::url('mycompany/mysite/reviews'),
                'icon' => 'icon-star',
                'permissions' => ['mycompany.mysite.*'],
                'order' => 500,
                'sideMenu' => [
                    'reviews' => [
                        'label' => 'Reviews',
                        'icon' => 'icon-comments',
                        'url' => Backend::url('mycompany/mysite/reviews'),
                        'permissions' => ['mycompany.mysite.reviews'],
                    ],
                ],
            ],
        ];
    }

    public function registerSettings(): array
    {
        return [
            'settings' => [
                'label' => 'My Site Settings',
                'description' => 'Configure My Site plugin',
                'icon' => 'icon-cog',
                'class' => \MyCompany\MySite\Models\Settings::class,
                'order' => 500,
            ],
        ];
    }

    public function boot(): void
    {
        \Event::listen('cms.page.beforeDisplay', function ($controller, $url, $page) {
            // Логіка перед рендером сторінки
        });
    }
}

Модель з Eloquent

// models/Review.php
namespace MyCompany\MySite\Models;

use Model;

class Review extends Model
{
    use \October\Rain\Database\Traits\Validation;
    use \October\Rain\Database\Traits\SoftDelete;

    public $table = 'mycompany_mysite_reviews';

    public $rules = [
        'author_name' => 'required|string|max:255',
        'email' => 'required|email',
        'rating' => 'required|integer|between:1,5',
        'body' => 'required|string|min:10',
    ];

    protected $fillable = ['author_name', 'email', 'rating', 'body', 'is_approved'];

    protected $casts = [
        'is_approved' => 'boolean',
        'rating' => 'integer',
    ];

    public $attachOne = [
        'avatar' => \System\Models\File::class,
    ];

    public $belongsTo = [
        'product' => [\MyCompany\MySite\Models\Product::class],
    ];

    public function scopeApproved($query)
    {
        return $query->where('is_approved', true);
    }

    public function scopeByProduct($query, int $productId)
    {
        return $query->where('product_id', $productId);
    }
}

Компонент

// components/ReviewList.php
namespace MyCompany\MySite\Components;

use Cms\Classes\ComponentBase;
use MyCompany\MySite\Models\Review;

class ReviewList extends ComponentBase
{
    public function componentDetails(): array
    {
        return [
            'name' => 'Review List',
            'description' => 'Displays product reviews',
        ];
    }

    public function defineProperties(): array
    {
        return [
            'productId' => ['title' => 'Product ID', 'type' => 'string'],
            'limit' => ['title' => 'Limit', 'type' => 'string', 'default' => '10'],
        ];
    }

    public function onRun(): void
    {
        $this->page['reviews'] = Review::approved()
            ->byProduct((int) $this->property('productId'))
            ->with('avatar')
            ->orderBy('created_at', 'desc')
            ->limit((int) $this->property('limit'))
            ->get();

        $this->page['avgRating'] = Review::approved()
            ->byProduct((int) $this->property('productId'))
            ->avg('rating');
    }

    public function onSubmitReview(): array
    {
        $data = post();
        $review = new Review($data);
        $review->product_id = $this->property('productId');

        if (!$review->save()) {
            throw new \ValidationException($review);
        }

        return ['success' => true];
    }
}

Міграція

// updates/1_0_1_create_reviews_table.php
use October\Rain\Database\Schema\Blueprint;
use October\Rain\Database\Updates\Migration;

class CreateReviewsTable extends Migration
{
    public function up(): void
    {
        Schema::create('mycompany_mysite_reviews', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('product_id')->unsigned()->index();
            $table->string('author_name');
            $table->string('email');
            $table->tinyInteger('rating');
            $table->text('body');
            $table->boolean('is_approved')->default(false);
            $table->timestamps();
            $table->softDeletes();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('mycompany_mysite_reviews');
    }
}

Етапи та терміни розробки

Етап Тривалість Результат
Аналіз вимог 1–2 дні ТЗ, ER-діаграма
Проектування 1–2 дні Схема компонентів, навігація
Реалізація 3–7 днів Код, тести, документація
Інтеграція 1–2 дні Працюючий плагін на вашому сайті
Деплой та передача 1 день composer.json, README, конфіги

Як замовити розробку?

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

Більш детально про розробку плагінів можна дізнатися в офіційній документації October CMS (https://docs.octobercms.com/).

Досвід 5+ років та 50+ реалізованих плагінів — це не просто цифри. Кожен проект ми починаємо з архітектурного рев'ю: уникаємо типових помилок (відсутність індексів у БД, неоптимізовані запити, дублювання коду). Всі плагіни проходять код-рев'ю всередині команди. Даємо гарантію на код 30 днів — якщо щось пішло не так, безкоштовно виправляємо. Економія часу замовників складає до 70% завдяки використанню готових модулів.

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

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

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1142
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1060