8000 Add MicroExtension and deprecating ConfigurableExtension · symfony/symfony@cd98d85 · GitHub
[go: up one dir, main page]

Skip to content

Commit cd98d85

Browse files
committed
Add MicroExtension and deprecating ConfigurableExtension
1 parent 7d717b9 commit cd98d85

File tree

18 files changed

+426
-68
lines changed

18 files changed

+426
-68
lines changed

UPGRADE-6.1.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ HttpKernel
1717
----------
1818

1919
* Deprecate StreamedResponseListener, it's not needed anymore
20+
* Deprecate `ConfigurableExtension` class, use `MicroExtension` instead
2021

2122
Serializer
2223
----------
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Config\Definition;
13+
14+
use Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator;
15+
16+
/**
17+
* @author Yonel Ceruto <yonelceruto@gmail.com>
18+
*/
19+
interface ConfigurableInterface
20+
{
21+
/**
22+
* Generates the configuration tree builder.
23+
*/
24+
public function configuration(DefinitionConfigurator $definition): void;
25+
}

src/Symfony/Component/HttpKernel/Bundle/BundleConfiguration.php renamed to src/Symfony/Component/Config/Definition/Configuration.php

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,9 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
namespace Symfony\Component\HttpKernel\Bundle;
12+
namespace Symfony\Component\Config\Definition;
1313

1414
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
15-
use Symfony\Component\Config\Definition\ConfigurationInterface;
1615
use Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator;
1716
use Symfony\Component\Config\Definition\Loader\DefinitionFileLoader;
1817
use Symfony\Component\Config\FileLocator;
@@ -21,25 +20,25 @@
2120
/**
2221
* @author Yonel Ceruto <yonelceruto@gmail.com>
2322
*
24-
* @internal
23+
* @final
2524
*/
26-
class BundleConfiguration implements ConfigurationInterface
25+
class Configuration implements ConfigurationInterface
2726
{
2827
public function __construct(
29-
private MicroBundle $bundle,
30-
private ContainerBuilder $container,
28+
private ConfigurableInterface $subject,
29+
private ?ContainerBuilder $container,
3130
private string $alias
3231
) {
3332
}
3433

3534
public function getConfigTreeBuilder(): TreeBuilder
3635
{
3736
$treeBuilder = new TreeBuilder($this->alias);
38-
$file = (new \ReflectionObject($this->bundle))->getFileName();
37+
$file = (new \ReflectionObject($this->subject))->getFileName();
3938
$loader = new DefinitionFileLoader($treeBuilder, new FileLocator(\dirname($file)), $this->container);
4039
$configurator = new DefinitionConfigurator($treeBuilder, $loader, $file, $file);
4140

42-
$this->bundle->configuration($configurator);
41+
$this->subject->configuration($configurator);
4342

4443
return $treeBuilder;
4544
}

src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ CHANGELOG
77
* Add `$exclude` to `TaggedIterator` and `TaggedLocator` attributes
88
* Add `$exclude` to `tagged_iterator` and `tagged_locator` configurator
99
* Add an `env` function to the expression language provider
10+
* Add `MicroExtension` class for DI configuration/definition on a single file
1011

1112
6.0
1213
---
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DependencyInjection\Extension;
13+
14+
use Symfony\Component\Config\Definition\ConfigurableInterface;
15+
use Symfony\Component\DependencyInjection\ContainerBuilder;
16+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
17+
18+
/**
19+
* @author Yonel Ceruto <yonelceruto@gmail.com>
20+
*/
21+
interface ConfigurableExtensionInterface extends ConfigurableInterface
22+
{
23+
/**
24+
* Allow an extension to prepend the extension configurations.
25+
*/
26+
public function prependExtension(ContainerConfigurator $container, ContainerBuilder $builder): void;
27+
28+
/**
29+
* Loads a specific configuration.
30+
*/
31+
public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void;
32+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DependencyInjection\Extension;
13+
14+
use Symfony\Component\Config\Builder\ConfigBuilderGenerator;
15+
use Symfony\Component\Config\FileLocator;
16+
use Symfony\Component\Config\Loader\DelegatingLoader;
17+
use Symfony\Component\Config\Loader\LoaderResolver;
18+
use Symfony\Component\DependencyInjection\ContainerBuilder;
19+
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
20+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
21+
use Symfony\Component\DependencyInjection\Loader\DirectoryLoader;
22+
use Symfony\Component\DependencyInjection\Loader\GlobFileLoader;
23+
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
24+
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
25+
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
26+
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
27+
28+
/**
29+
* @author Yonel Ceruto <yonelceruto@gmail.com>
30+
*/
31+
trait ExtensionTrait
32+
{
33+
private function executeConfiguratorCallback(ContainerBuilder $container, \Closure $callback, ConfigurableExtensionInterface $subject): void
34+
{
35+
$env = $container->getParameter('kernel.environment');
36+
$loader = $this->createContainerLoader($container, $env);
37+
$file = (new \ReflectionObject($subject))->getFileName();
38+
$bundleLoader = $loader->getResolver()->resolve($file);
39+
if (!$bundleLoader instanceof PhpFileLoader) {
40+
throw new \LogicException('Unable to create the ContainerConfigurator.');
41+
}
42+
$bundleLoader->setCurrentDir(\dirname($file));
43+
$instanceof = &\Closure::bind(function &() { return $this->instanceof; }, $bundleLoader, $bundleLoader)();
44+
45+
try {
46+
$callback(new ContainerConfigurator($container, $bundleLoader, $instanceof, $file, $file, $env));
47+
} finally {
48+
$instanceof = [];
49+
$bundleLoader->registerAliasesForSinglyImplementedInterfaces();
50+
}
51+
}
52+
53+
private function createContainerLoader(ContainerBuilder $container, string $env): DelegatingLoader
54+
{
55+
$buildDir = $container->getParameter('kernel.build_dir');
56+
$locator = new FileLocator();
57+
$resolver = new LoaderResolver([
58+
new XmlFileLoader($container, $locator, $env),
59+
new YamlFileLoader($container, $locator, $env),
60+
new IniFileLoader($container, $locator, $env),
61+
new PhpFileLoader($container, $locator, $env, new ConfigBuilderGenerator($buildDir)),
62+
new GlobFileLoader($container, $locator, $env),
63+
new DirectoryLoader($container, $locator, $env),
64+
new ClosureLoader($container, $env),
65+
]);
66+
67+
return new DelegatingLoader($resolver);
68+
}
69+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DependencyInjection\Extension;
13+
14+
use Symfony\Component\Config\Definition\Configuration;
15+
use Symfony\Component\Config\Definition\ConfigurationInterface;
16+
use Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator;
17+
use Symfony\Component\DependencyInjection\ContainerBuilder;
18+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
19+
20+
/**
21+
* An Extension that provides configuration hooks.
22+
*
23+
* @author Yonel Ceruto <yonelceruto@gmail.com>
24+
*/
25+
abstract class MicroExtension extends Extension implements ConfigurableExtensionInterface, PrependExtensionInterface
26+
{
27+
use ExtensionTrait;
28+
29+
public function configuration(DefinitionConfigurator $definition): void
30+
{
31+
}
32< 10000 code class="diff-text syntax-highlighted-line addition">+
33+
public function prependExtension(ContainerConfigurator $container, ContainerBuilder $builder): void
34+
{
35+
}
36+
37+
public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void
38+
{
39+
}
40+
41+
public function getConfiguration(array $config, ContainerBuilder $container): ?ConfigurationInterface
42+
{
43+
return new Configuration($this, $container, $this->getAlias());
44+
}
45+
46+
final public function prepend(ContainerBuilder $container): void
47+
{
48+
$callback = function (ContainerConfigurator $configurator) use ($container) {
49+
$this->prependExtension($configurator, $container);
50+
};
51+
52+
$this->executeConfiguratorCallback($container, $callback, $this);
53+
}
54+
55+
final public function load(array $configs, ContainerBuilder $container): void
56+
{
57+
$config = $this->processConfiguration($this->getConfiguration([], $container), $configs);
58+
59+
$callback = function (ContainerConfigurator $configurator) use ($config, $container) {
60+
$this->loadExtension($config, $configurator, $container);
61+
};
62+
63+
$this->executeConfiguratorCallback($container, $callback, $this);
64+
}
65+
}

0 commit comments

Comments
 (0)
0