diff --git a/docs/configuration.md b/docs/configuration.md index 9054a2bb..4eb0d471 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -38,6 +38,7 @@ $testContainer = $builder->getTestContainer(); * `ContainerBuilder#setDumpDir()`: Configures the directory to be used to dump the cache files * `ContainerBuilder#setParameter()`: Configures a dynamic parameter * `ContainerBuilder#setBaseClass()`: Modifies which class should be used as base class for the container +* `ContainerBuilder#setProfileName()`: Enables the loading of application profile-specific services via the `when@{profile-name}` syntax ## Configuration file example @@ -63,7 +64,8 @@ if (getenv('APP_PROFILE') !== 'prod') { $builder->enableDebugging(); } -return $builder->setDumpDir($projectRoot . '/var/tmp') +return $builder->setProfileName(getenv('APP_PROFILE')) + ->setDumpDir($projectRoot . '/var/tmp') ->setParameter('app.basedir', $projectRoot) ->addFile(__DIR__ . '/container.xml') ->getContainer(); diff --git a/src/Builder.php b/src/Builder.php index 7eb96b41..0393805b 100644 --- a/src/Builder.php +++ b/src/Builder.php @@ -53,6 +53,11 @@ public function addDelayedPass( */ public function addPackage(string $className, array $constructArguments = []): Builder; + /** + * Configures the application profile name to support profile-specific services + */ + public function setProfileName(string $profileName): Builder; + /** * Mark the container to be used as development mode * diff --git a/src/Config/ContainerConfiguration.php b/src/Config/ContainerConfiguration.php index fd561c02..c64378d9 100644 --- a/src/Config/ContainerConfiguration.php +++ b/src/Config/ContainerConfiguration.php @@ -31,6 +31,8 @@ final class ContainerConfiguration private string $dumpDir; + private ?string $profileName = null; + /** * phpcs:disable Generic.Files.LineLength * @@ -51,6 +53,16 @@ public function __construct( $this->dumpDir = sys_get_temp_dir(); } + public function setProfileName(string $profileName): void + { + $this->profileName = $profileName; + } + + public function profileName(): ?string + { + return $this->profileName; + } + /** @return Package[] */ public function getPackages(): array { @@ -183,6 +195,7 @@ public function getDumpFile(): string { return $this->dumpDir . DIRECTORY_SEPARATOR . strtolower(str_replace('\\', '_', $this->namespace)) . DIRECTORY_SEPARATOR + . ($this->profileName !== null ? $this->profileName . DIRECTORY_SEPARATOR : '') . self::CLASS_NAME . '.php'; } diff --git a/src/ContainerBuilder.php b/src/ContainerBuilder.php index 7c72672c..9aa752e9 100644 --- a/src/ContainerBuilder.php +++ b/src/ContainerBuilder.php @@ -144,6 +144,13 @@ public function addPackage(string $className, array $constructArguments = []): B return $this; } + public function setProfileName(string $profileName): Builder + { + $this->config->setProfileName($profileName); + + return $this; + } + public function useDevelopmentMode(): Builder { return $this->enableDebugging(); diff --git a/src/Generator.php b/src/Generator.php index 48435e60..3c81d4e3 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -51,7 +51,7 @@ public function initializeContainer(ContainerConfiguration $config): SymfonyBuil $container = new $this->builderClass(); $container->addResource(new FileResource($this->configurationFile)); - $loader = $this->getLoader($container, $config->getPaths()); + $loader = $this->getLoader($container, $config->getPaths(), $config->profileName()); foreach ($config->getFiles() as $file) { $loader->load($file); @@ -61,5 +61,9 @@ public function initializeContainer(ContainerConfiguration $config): SymfonyBuil } /** @param string[] $paths */ - abstract public function getLoader(SymfonyBuilder $container, array $paths): LoaderInterface; + abstract public function getLoader( + SymfonyBuilder $container, + array $paths, + ?string $profileName = null, + ): LoaderInterface; } diff --git a/src/Generators/Delegating.php b/src/Generators/Delegating.php index 178b36c5..4e0eb481 100644 --- a/src/Generators/Delegating.php +++ b/src/Generators/Delegating.php @@ -19,16 +19,16 @@ final class Delegating extends Generator { /** @inheritDoc */ - public function getLoader(SymfonyBuilder $container, array $paths): LoaderInterface + public function getLoader(SymfonyBuilder $container, array $paths, ?string $profileName = null): LoaderInterface { $locator = new FileLocator($paths); return new DelegatingLoader( new LoaderResolver( [ - new XmlFileLoader($container, $locator), - new YamlFileLoader($container, $locator), - new PhpFileLoader($container, $locator), + new XmlFileLoader($container, $locator, $profileName), + new YamlFileLoader($container, $locator, $profileName), + new PhpFileLoader($container, $locator, $profileName), ], ), ); diff --git a/src/Generators/Php.php b/src/Generators/Php.php index a998b801..85c34b00 100644 --- a/src/Generators/Php.php +++ b/src/Generators/Php.php @@ -15,11 +15,12 @@ final class Php extends Generator { /** @inheritDoc */ - public function getLoader(SymfonyBuilder $container, array $paths): LoaderInterface + public function getLoader(SymfonyBuilder $container, array $paths, ?string $profileName = null): LoaderInterface { return new PhpFileLoader( $container, new FileLocator($paths), + $profileName, ); } } diff --git a/src/Generators/Xml.php b/src/Generators/Xml.php index 9400c8ba..dba92122 100644 --- a/src/Generators/Xml.php +++ b/src/Generators/Xml.php @@ -15,11 +15,12 @@ final class Xml extends Generator { /** @inheritDoc */ - public function getLoader(SymfonyBuilder $container, array $paths): LoaderInterface + public function getLoader(SymfonyBuilder $container, array $paths, ?string $profileName = null): LoaderInterface { return new XmlFileLoader( $container, new FileLocator($paths), + $profileName, ); } } diff --git a/src/Generators/Yaml.php b/src/Generators/Yaml.php index 6ba588b4..668057ba 100644 --- a/src/Generators/Yaml.php +++ b/src/Generators/Yaml.php @@ -15,11 +15,12 @@ final class Yaml extends Generator { /** @inheritDoc */ - public function getLoader(SymfonyBuilder $container, array $paths): LoaderInterface + public function getLoader(SymfonyBuilder $container, array $paths, ?string $profileName = null): LoaderInterface { return new YamlFileLoader( $container, new FileLocator($paths), + $profileName, ); } } diff --git a/test/Config/ContainerConfigurationTest.php b/test/Config/ContainerConfigurationTest.php index e348397d..c1dfc5bd 100644 --- a/test/Config/ContainerConfigurationTest.php +++ b/test/Config/ContainerConfigurationTest.php @@ -289,6 +289,19 @@ public function getDumpFileShouldReturnTheFullPathOfDumpFile(): void ); } + #[PHPUnit\Test] + public function getDumpFileShouldIncludeProfileNameWhenItIsSet(): void + { + $config = new ContainerConfiguration('Me\\MyApp'); + $config->setProfileName('prod'); + + self::assertEquals( + sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'me_myapp' . DIRECTORY_SEPARATOR + . 'prod' . DIRECTORY_SEPARATOR . 'AppContainer.php', + $config->getDumpFile(), + ); + } + #[PHPUnit\Test] public function getDumpOptionsShouldReturnTheDumpingInformation(): void { @@ -357,4 +370,16 @@ public function withAddedNamespaceShouldModifyTheNamespaceOfANewInstanceOnly(): self::assertSame('Me\\MyApp\\AppContainer', $config->getClassName()); self::assertSame('Me\\MyApp\\Testing\\AppContainer', $other->getClassName()); } + + #[PHPUnit\Test] + public function profileNameShouldBeConfigurable(): void + { + $config = new ContainerConfiguration('Me\\MyApp'); + + self::assertNull($config->profileName()); + + $config->setProfileName('test'); + + self::assertSame('test', $config->profileName()); + } } diff --git a/test/ContainerBuilderTest.php b/test/ContainerBuilderTest.php index 2479b83f..d61f4bb7 100644 --- a/test/ContainerBuilderTest.php +++ b/test/ContainerBuilderTest.php @@ -232,4 +232,13 @@ public function getTestContainerShouldGenerateAndReturnTheContainer(): void self::assertCount(1, $compilerPasses); self::assertSame($this->parameterBag, $compilerPasses[0][0]); } + + #[PHPUnit\Test] + public function profileNameShouldBeConfigurable(): void + { + $builder = new ContainerBuilder($this->config, $this->generator, $this->parameterBag); + $builder->setProfileName('testing'); + + self::assertSame('testing', $this->config->profileName()); + } }