Fluent Types v200.4.0
Fluent-билдеры и dual accept: массив или готовый объект — manifest, формы, changelog.
Зачем: меньше вложенных массивов, автодополнение в IDE и типобезопасность. Старые manifest.php с массивами продолжают работать — миграция необязательна.
DevCraft принимает и массив, и готовый объект (dual accept). Внутри всё равно приводится к DTO через ::fromArray() / ::fromLoaded().
Dual accept — что это
| Файл | Можно вернуть | Кто загружает |
|---|---|---|
manifest.php | array или ModuleManifest | Registry → ModuleManifest::fromLoaded() |
settings.schema.php | array или FormSchema | PluginContext → FormSchema::fromArray() при массиве |
changelog.data.php | массив записей: array, Changelog, ChangelogBuilder | Changelog::listFromManifest() |
Почему это удобно: генератор и legacy-модули отдают массив; новые модули — fluent-билдер с ->build(). Один загрузчик, два стиля.
Базовый слой: AbstractType::fromArray
Все DTO (FormSchema, Changelog, ModuleAjaxConfig …) наследуют DevCraft\Core\Abstracts\AbstractType → Devcraft\Abstracts\AbstractReflection из devcraftclub/dev-tools.
Массив в объект — одна строка:
$schema = FormSchema::fromArray(require 'settings.schema.php');
$ajax = ModuleAjaxConfig::fromArray($manifest['ajax']);
$entry = Changelog::fromArray(['version' => '200.4.0', 'changes' => ['added' => ['…']]]);Fluent-билдеры собирают те же DTO, что и fromArray, без дублирования логики.
Каталог билдеров: devcraft/src/classes/Builders/ (DevCraft\Builders). Загрузка таблиц DLE — отдельно: DataLoader и QueryBuilder.
ModuleManifestBuilder
Возвращает готовый ModuleManifest. Типичный паттерн:
return ModuleManifestBuilder::create()
->mod('my_module')
->code('my_module')
->name('Мой модуль')
->version('200.1.0')
->description(__('Кратко, зачем модуль'))
->icon('mif-cube')
->menu([
AdminLink::page(__('Главная'), 'dashboard', DashboardPage::class, 'mif-home'),
])
->ajax(/* см. ModuleAjaxConfigBuilder ниже */)
->changelog(require __DIR__ . '/changelog.data.php')
->build(__DIR__);->build(__DIR__)— финальный шаг; без него объект не собран.->toManifestArray()— если нужен legacy-массив (тесты, экспорт).
ModuleAjaxConfigBuilder
Admin-методы (controller=admin) и публичные (controller=public):
->ajax(
ModuleAjaxConfigBuilder::create('admin')
->methods([
'settings' => SettingsHandler::class,
])
->publicMethod('list', ListHandler::class, false)
->publicMethod('guest_ping', GuestHandler::class, true) // allow_guest
)| Метод | Назначение |
|---|---|
method($name, $handler) | один admin-метод |
methods([...]) | карта admin-методов |
publicMethod($name, $handler, $allowGuest) | публичный AJAX без авторизации DLE (если $allowGuest = true) |
Эквивалент массива:
'ajax' => [
'controller' => 'admin',
'methods' => ['settings' => SettingsHandler::class],
'public' => [
'list' => ['handler' => ListHandler::class, 'allow_guest' => false],
],
],ChangelogBuilder
Одна версия в changelog — builder или массив:
return [
ChangelogBuilder::create('200.4.0')
->date('2026-08-25')
->added([__('Fluent Types для manifest и changelog')])
->fixed([__('…')])
->build(),
// legacy-массив тоже ок:
['version' => '200.4.0', 'date' => '2026-07-01', 'changes' => ['added' => [__('…')]]],
];Группы: added, changed, fixed, removed, security, deprecated.
Живые примеры
DevCraft Admin — только admin-AJAX
return ModuleManifestBuilder::create()
->mod('devcraft')
->code('devcraft')
->name('DevCraft Admin')
->version('200.4.1')
->menu([/* AdminLink::page … */])
->ajax(
ModuleAjaxConfigBuilder::create('admin')
->methods([
'settings' => SettingsHandler::class,
'logs_table' => LogsTableHandler::class,
])
)
->changelog(require DLEPlugins::Check(__DIR__ . '/changelog.data.php'))
->build(__DIR__);Источник: devcraft/src/modules/Admin/manifest.php.
DLE Уведомления — admin + public API
return ModuleManifestBuilder::create()
->mod('notifications')
->code('dle_notifications')
->name('DLE Уведомления')
->menu([
AdminLink::page(__('Главная'), 'dashboard', DashboardPage::class, 'mif-home', 'notifications'),
])
->ajax(
ModuleAjaxConfigBuilder::create('admin')
->methods([
'settings' => SettingsHandler::class,
'permissions' => PermissionsHandler::class,
])
->publicMethod('subscribe', SubscribeHandler::class, false)
->publicMethod('list', ListHandler::class, false)
->publicMethod('unsubscribe_token', UnsubscribeTokenHandler::class, true)
)
->changelog(require DLEPlugins::Check(__DIR__ . '/changelog.data.php'))
->build(__DIR__);Источник: devcraft/src/modules/Notifications/manifest.php. Публичные методы — для inbox на фронте сайта (devcraft/ajax.php?controller=public&mod=notifications).
FormSchema — тот же dual accept
settings.schema.php может вернуть builder или массив:
// Fluent (рекомендуется)
return FormSchemaBuilder::create('my_module')
->layout(FormLayout::TABS)
->section(__('Основные'))
->text('export_path', __('Путь'))
->build();
// Legacy-массив — PluginContext вызовет FormSchema::fromArray()
return [
'codename' => 'my_module',
'layout' => 'tabs',
'sections' => [/* … */],
];Что выбрать
| Ситуация | Стиль |
|---|---|
| Новый модуль, много AJAX/changelog | Fluent + builders |
| Старый модуль, генератор | Массив — менять не обязательно |
| Смешанный changelog | ChangelogBuilder + legacy-массивы в одном файле |
См. также
- Module Identity —
mod/codeбез хардкода - Версионирование плагинов — почему
200.4.0, а не2.4.0 - Манифест модуля
- Примеры Form
- Shared-пакеты