Жизненный цикл модуля¶
Как XC_VM обнаруживает, загружает, включает/отключает, устанавливает и распространяет модули во время выполнения. Чтобы создать модуль, смотрите Разработка модуля; для его расширений смотрите Точки расширения модуля.
Включение / выключение модулей¶
Все обнаруженные модули загружаются по умолчанию. Используйте src/config/modules.php для переопределения состояния:
return [
'my-module' => ['state' => 'disabled'], // preferred
// or legacy boolean (still accepted):
'my-module' => ['enabled' => false],
];
Доступные значения state (подкрепленные перечислением ModuleState):
| Ценность | Значение |
|---|---|
enabled |
Загрузка модуля (по умолчанию) |
disabled |
Модуль обнаружен, но пропущен |
installing |
Переходное состояние, заданное значением ModuleManager во время установки |
failed |
Ошибка установки; модуль пропущен (не загружен) |
Панельная диагностика. На странице Модули отображается желтый значок ⚠ Проблема зависимости рядом со статусом модуля, если требуемая зависимость отсутствует или не включена (например, в
plexуказаноEnabled, а вwatch-failed). Во всплывающей подсказке к значку перечислены конкретные проблемы. Это полеdependency_warningsвычисляется с помощьюModuleManager::listModules().
Чтобы переопределить класс, разрешенный для модуля:
config/modules.php содержит только переопределения. Пустой или отсутствующий файл означает, что все обнаруженные
загружаются модули.
Как работает загрузка¶
ModuleLoader выполняет эти действия при каждом запросе:
- Сканирование
src/Modules/*/module.json - Применяет переопределения из
config/modules.php - Фильтры по окружающей среде (
main/lb/any) - Определяет порядок загрузки:
pruneUnsatisfiableModules()удаляет модули, требуемые зависимости которых недоступны (каскадно, с зарегистрированным предупреждением), чтобы загрузка никогда не прерывалась- Топологическая сортировка (DFS) по графу зависимостей
- В пределах одной и той же группы зависимостей выполните сортировку по убыванию
priority, затем по алфавиту - Выдает
ModuleCycleExceptionдля циклов (подкласс\RuntimeException; циклические зависимости остаются фатальными) - Отсутствующие необязательные зависимости автоматически пропускаются
- Resolves class name:
my-module→ FQNXcVm\Module\MyModule\MyModuleModule(kebab-case → PascalCase; может быть переопределен с помощью клавишиclassв конфигурации) - Регистрирует автозагрузчик модуля PSR-4 (сопоставляет
XcVm\Module\<Name>с каталогом модуля) - Создает экземпляр класса module
В веб-контексте:
bootAll($container, $router)→ вызовыboot(),registerRoutes(),registerNavbar(), и подписывается на события для каждого загруженного модуля
В контексте командной строки:
registerAllCommands($registry)→ вызываетregisterCommands()для каждого загруженного модуля
Marketplace: установка через расширение C¶
Модули с платформы устанавливаются через ModuleManager::downloadFromPlatform():
Под капотом:
XC_VM::module_install($slug, $version, $apiKey)— Расширение C загружает, расшифровывает и распаковывает файлыinstallModule($slug)— запускаетinstall()в модулеEventDispatcher::dispatch(new PackageInstalledEvent(...))— отправляет событиеhotReload($slug, $path)— загружает модуль в текущем запросе без перезапуска PHP-FPM
Изолированные подсистемы¶
Модуль может быть полностью изолированной подсистемой со своей собственной точкой входа и начальной загрузкой
(например, Ministra). Это соглашение, а не маркерный интерфейс — он остается
обычный модуль ModuleInterface/BaseModule:
class MyModule extends BaseModule {
public function getName(): string {
return 'my-module';
}
public function getVersion(): string {
return '1.0.0';
}
}
Изоляция означает, что подсистема работает через свою собственную общедоступную точку входа (например,
my-module/portal.php, путь относительно src/, который обрабатывает свой собственный bootstrap)
с отдельным путем начальной загрузки. Он использует общую инфраструктуру (базу данных, кэш, конфигурацию), но
участвует ли нет в основных Router, ModuleLoader::bootAll() или
NavbarRegistry. Реализации boot() и registerRoutes() обычно являются
оставлено как унаследованное бездействие.
Composer обнаружение пакета¶
Модули могут распространяться в виде Composer пакетов с "type": "xcvm-module":
{
"name": "vendor/my-xcvm-module",
"type": "xcvm-module",
"extra": {
"xcvm": {
"module-path": "src"
}
}
}
ModuleLoader автоматически сканирует vendor/composer/installed.json (Composer 1 и 2
форматирует) и обнаруживает все установленные пакеты xcvm-module вместе со встроенным
каталог src/Modules/. Пакеты дедуплицируются — модуль как в modules/, так и в
vendor/ загружается только один раз.