Продвинутое

Плагины

Плагин — это Composer-пакет, чьи контроллеры монтируются в приложение под своим URL-префиксом одной строкой регистрации. Так подключают переиспользуемые подприложения: авторизацию, биллинг, админку.

Регистрация Plugin::registry()Хук Boot::plugins()Обнаружение vendor/<pkg>/src

Что такое плагин и зачем

Плагин — самостоятельный пакет с контроллерами, встраиваемый в приложение под префиксом.

Проблема. Общую функциональность (авторизация, биллинг) хочется вынести в переиспользуемый пакет и подключать к разным проектам — но так, чтобы его маршруты жили под своим префиксом и не конфликтовали с приложением.

Решение. Зарегистрируйте пакет как плагин с префиксом — Winter просканирует его контроллеры и смонтирует под этим путём. Об этом и раздел.

Регистрация

В хуке plugins() класса Boot:

bootstrap.php
use Flytachi\Winter\K2\Plugin;

protected static function plugins(): void
{
  Plugin::registry('acme/auth-plugin', '/auth');
  Plugin::registry('acme/admin-plugin', '/admin', required: false);
}

Сигнатура:

php
public static function registry(string $package, string $prefix, bool $required = true): void
Параметр Назначение
$package Имя Composer-пакета (путь резолвится автоматически)
$prefix URL-префикс (слэши нормализуются → /auth)
$required true — бросить ошибку, если пакет не установлен; false — тихо пропустить

Как строится URL

plugins() выполняется до скана маршрутов. Для каждого зарегистрированного плагина роутер сканирует vendor/<package>/src/ тем же механизмом, что и ваш код. Итоговый путь складывается из трёх частей:

text
префикс плагина  +  #[RequestMapping] класса  +  путь метода
 /billing      +        invoices           +     {id}
= GET /billing/invoices/{id}
vendor/acme/billing/src/InvoiceController.php
#[RequestMapping('invoices')]
class InvoiceController extends Controller
{
  #[GetMapping('{id:\d+}')]
  public function get(#[PathVariable] int $id): ResponseEntity { /* ... */ }
}
// с префиксом '/billing' → GET /billing/invoices/42

Границы плагина

Что плагин не может

Плагины не регистрируют свои обработчики #[AdviceException] (работает только ExceptionCollector приложения), не монтируются вне своего префикса и не переопределяют глобальный Cors::configure() приложения. Дублирующийся префикс бросает ошибку.

Дальше