<?php
declare(strict_types=1);
namespace Butschster\ContextGenerator\Config;
use Butschster\ContextGenerator\Config\Import\ImportParserPlugin;
use Butschster\ContextGenerator\Config\Import\Merger\ConfigMergerInterface;
use Butschster\ContextGenerator\Config\Import\Merger\ConfigMergerProviderInterface;
use Butschster\ContextGenerator\Config\Import\Merger\ConfigMergerRegistry;
use Butschster\ContextGenerator\Config\Import\Merger\VariablesConfigMerger;
use Butschster\ContextGenerator\Config\Loader\ConfigLoaderFactory;
use Butschster\ContextGenerator\Config\Loader\ConfigLoaderFactoryInterface;
use Butschster\ContextGenerator\Config\Loader\ConfigLoaderInterface;
use Butschster\ContextGenerator\Config\Parser\ConfigParserPluginInterface;
use Butschster\ContextGenerator\Config\Parser\ParserPluginRegistry;
use Butschster\ContextGenerator\Config\Reader\ConfigReaderRegistry;
use Butschster\ContextGenerator\Config\Reader\JsonReader;
use Butschster\ContextGenerator\Config\Reader\PhpReader;
use Butschster\ContextGenerator\Config\Reader\YamlReader;
use Butschster\ContextGenerator\DirectoriesInterface;
use Butschster\ContextGenerator\Document\Compiler\DocumentCompiler;
use Butschster\ContextGenerator\Document\DocumentConfigMerger;
use Butschster\ContextGenerator\Document\DocumentsParserPlugin;
use Butschster\ContextGenerator\Modifier\Alias\AliasesRegistry;
use Butschster\ContextGenerator\Modifier\Alias\ModifierResolver;
use Spiral\Boot\Bootloader\Bootloader;
use Spiral\Core\Attribute\Singleton;
use Spiral\Core\Config\Proxy;
use Spiral\Core\FactoryInterface;
use Spiral\Files\FilesInterface;
/**
* Bootloader for configuration loading components
*/
#[Singleton]
final class ConfigLoaderBootloader extends Bootloader
{
/** @var ConfigParserPluginInterface[] */
private array $parserPlugins = [];
/** @var ConfigMergerInterface[] */
private array $mergers = [];
#[\Override]
public function defineDependencies(): array
{
return [
ImportBootloader::class,
];
}
/**
* Register additional parser plugins
*/
public function registerParserPlugin(ConfigParserPluginInterface $plugin): void
{
$this->parserPlugins[] = $plugin;
}
/**
* Register additional config merger
*/
public function registerMerger(ConfigMergerInterface $merger): void
{
$this->mergers[] = $merger;
}
#[\Override]
public function defineSingletons(): array
{
return [
AliasesRegistry::class => AliasesRegistry::class,
ModifierResolver::class => ModifierResolver::class,
ParserPluginRegistry::class => fn(
ImportParserPlugin $importParserPlugin,
DocumentsParserPlugin $documentsParserPlugin,
) => new ParserPluginRegistry([
// todo: think about priority when registering plugins
...$this->parserPlugins,
$documentsParserPlugin,
$importParserPlugin,
]),
DocumentCompiler::class => static fn(
FactoryInterface $factory,
DirectoriesInterface $dirs,
) => $factory->make(DocumentCompiler::class, [
'basePath' => (string) $dirs->getOutputPath(),
]),
ConfigReaderRegistry::class => static fn(
FilesInterface $files,
JsonReader $jsonReader,
YamlReader $yamlReader,
PhpReader $phpReader,
) => new ConfigReaderRegistry(
readers: [
'json' => $jsonReader,
'yaml' => $yamlReader,
'yml' => $yamlReader,
'php' => $phpReader,
],
),
ConfigLoaderFactoryInterface::class => ConfigLoaderFactory::class,
ConfigLoaderInterface::class => new Proxy(
interface: ConfigLoaderInterface::class,
),
ConfigMergerProviderInterface::class => function (
ConfigMergerRegistry $registry,
) {
foreach ($this->mergers as $merger) {
$registry->register($merger);
}
return $registry;
},
];
}
public function init(
DocumentConfigMerger $documentConfigMerger,
VariablesConfigMerger $variablesConfigMerger,
): void {
$this->registerMerger($documentConfigMerger);
$this->registerMerger($variablesConfigMerger);
}
}