Концепція компонентів

Компонент у Concept Core — ізольований функціональний модуль застосунку (модульний моноліт): власні маршрути, шаблони, міграції, CLI-команди та опційно провайдери DI. Ядро збирає активні компоненти через ComponentRegistry і ComponentsServiceProvider.

Див. також: структура каталогів, провайдери компонентів, створення компонента (AuthAdmin).

Навіщо компоненти

  • Package by feature — код адмінки, кабінету, каталогу лежить поруч, а не розмазаний по шарах App/Controllers.
  • Вмикання/вимикання — модуль підключається одним рядком у config/components.php.
  • Межі команди — зміни в AuthAdmin/ рідко чіпають UserCabinet/.
  • Спільне ядро — HTTP, валідація, Twig, БД залишаються в Concept Core і App/.

Де що зберігати

src/
├── App/                          # спільний код застосунку
│   ├── Controllers/              # глобальні сторінки (головна, about)
│   ├── Models/                   # BaseModel, спільні сутності
│   └── Extensions/Twig/          # глобальні Twig-розширення
└── Components/
    └── AuthAdmin/                # приклад модуля
        ├── AuthAdminComponent.php
        ├── routes.php            # HTTP-маршрути
        ├── Controllers/
        ├── Middlewares/
        ├── Requests/  Dto/  Models/
        ├── Services/
        ├── Views/                # шаблони модуля (@auth-admin/...)
        ├── Database/
        │   ├── Migrations/
        │   └── Seeders/
        ├── Commands/             # console-команди
        ├── Extensions/           # Twig для модуля
        └── Assets/               # JS/CSS → public через CLI

config/
└── components.php                # які модулі активні

resources/views/                # спільні layouts (@dashboard, @frontend)
routes/web.php                  # глобальні маршрути + middleware стек
ЩоКомпонентЗастосунок (App/)
Маршрути фічіComponent/routes.phproutes/web.php
Шаблони модуляComponent/Views/resources/views/
Міграції модуляComponent/Database/Migrations/database/migrations/
Базова модель, утилітиApp/Models/
Спільний admin layoutextends @dashboard/...resources/views/dashboard/

Контракт ComponentInterface

Клас компонента напряму реалізує Concept\Core\Services\Component\Contracts\ComponentInterface — метадані та дані реєстрації повертаються з його методів:

МетодПризначення
name(), version(), description()Метадані для component:list
routes()Абсолютний шлях до routes.php або null
providers()Додаткові service providers модуля
viewPaths()Twig namespace → шлях (auth-admin/src/Components/.../Views)
viewContexts()Префікс URI → контекст (/admindashboard)
viewExtensions()Класи Twig\Extension\ExtensionInterface
commands()Symfony Console команди
seeders()Класи сидерів
migrationPaths()Шляхи до каталогів міграцій
assets()Мапа source → public для component:publish-assets

У конструкторі використовуйте PathManager, щоб будувати шляхи відносно кореня застосунку (див. AuthAdminComponent).

Реєстрація в застосунку

// config/components.php
return [
    'components' => [
        AuthAdminComponent::class => AuthAdminComponent::class,
        UserCabinetComponent::class => UserCabinetComponent::class,
    ],
];

Ключ і значення — FQCN класу компонента (контейнер створює екземпляр через DI). У config/dev/components.php можна додати лише dev-модулі (наприклад DebugBar).

Список класів потрапляє в ComponentRegistry при реєстрації ComponentsServiceProvider (останній у bootstrap/providers/app.php).

Що відбувається при boot

ComponentsServiceProvider::boot() для кожного активного компонента:

  1. Записує телеметрію FRAMEWORK_COMPONENT_REGISTERED (Телеметрія)
  2. Реєструє console-команди, шляхи міграцій і seeders
  3. Реєструє вкладені service providers з providers()
  4. Виконує require файлів routes.php (доступна змінна $router)
  5. У HTTP (не CLI) — додає Twig paths, extensions і view contexts

Порядок: провайдери ядра → ComponentsServiceProvider → маршрути й views модулів.

Як зібрати існуючий код у компонент

Типовий рефакторинг з «плоского» App/:

  1. Створіть src/Components/MyFeature/ з підкаталогами за зразком AuthAdmin.
  2. Перенесіть контролери, моделі, FormRequest, views, middleware у каталог компонента; оновіть namespace на Concept\Components\MyFeature\....
  3. Винесіть маршрути фічі з routes/web.php у MyFeature/routes.php.
  4. Додайте MyFeatureComponent.php, що реалізує ComponentInterface.
  5. Зареєструйте клас у config/components.php.
  6. Залиште в App/ лише спільне: BaseModel, глобальні layouts, утиліти.
  7. Запустіть php bin/console.php db:migrate і component:publish-assets за потреби.

Якщо модуль використовує спільний layout (@dashboard), шаблони в resources/views/dashboard/ не переносять — компонент лише extends їх у Twig.

Еталонні компоненти

Demo-застосунок містить кілька готових модулів (код у src/Components/):

КомпонентПризначенняРеєстрація
AuthAdmin Адмін-логін, dashboard, CRUD користувачів config/components.php
Acl RBAC, route interceptor, admin UI config/components.php + routes.interceptors
SettingsManager Типізовані налаштування, admin CRUD, Twig helpers config/components.php
DebugBar PHP Debug Bar для HTML (лише dev) config/dev/components.php

Для Acl також потрібні AclRouteAuthorization у config/routes.php і HandleAccessDeniedMiddleware першим глобальним middleware — див. Route interceptors.

Компонент vs код у App

Не обов’язково все виносити в компоненти. Залишайте в App/:

  • landing, статичні сторінки, спільний API gateway;
  • базові класи моделей, інтерфейси, крос-модульні сервіси;
  • глобальні Twig namespaces (frontend, dashboard) у config/view.php.

Окремий компонент — коли є чітка межа: «адмінка», «особистий кабінет», «каталог проєктів».

Один компонент — одна відповідальність. Якщо два модулі імпортують одна одну напряму, винесіть спільне в App/ або окремий «core» пакет застосунку.