From c1d6c0e57ab09303046407f2c9f2223f2adc94a9 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Tue, 13 Apr 2021 19:00:06 +0200 Subject: [PATCH] [Config][FrameworkBundle] Add CacheWarmer for ConfigBuilder --- .../CacheWarmer/ConfigBuilderCacheWarmer.php | 90 +++++++++++++++++++ .../Resources/config/services.php | 4 + 2 files changed, 94 insertions(+) create mode 100644 src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ConfigBuilderCacheWarmer.php diff --git a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ConfigBuilderCacheWarmer.php b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ConfigBuilderCacheWarmer.php new file mode 100644 index 0000000000000..f44527af51bda --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ConfigBuilderCacheWarmer.php @@ -0,0 +1,90 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\CacheWarmer; + +use Psr\Log\LoggerInterface; +use Symfony\Bundle\FrameworkBundle\Command\BuildDebugContainerTrait; +use Symfony\Component\Config\Builder\ConfigBuilderGenerator; +use Symfony\Component\Config\Builder\ConfigBuilderGeneratorInterface; +use Symfony\Component\Config\Definition\ConfigurationInterface; +use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface; +use Symfony\Component\HttpKernel\KernelInterface; + +/** + * Generate all config builders. + * + * @author Tobias Nyholm + */ +class ConfigBuilderCacheWarmer implements CacheWarmerInterface +{ + use BuildDebugContainerTrait; + + private $kernel; + private $logger; + + public function __construct(KernelInterface $kernel, LoggerInterface $logger = null) + { + $this->kernel = $kernel; + $this->logger = $logger; + } + + /** + * {@inheritdoc} + * + * @return string[] + */ + public function warmUp(string $cacheDir) + { + $generator = new ConfigBuilderGenerator($cacheDir); + + foreach ($this->kernel->getBundles() as $bundle) { + $extension = $bundle->getContainerExtension(); + if (null === $extension) { + continue; + } + + try { + $this->dumpExtension($extension, $generator); + } catch (\Exception $e) { + if ($this->logger) { + $this->logger->warning('Failed to generate ConfigBuilder for extension {extensionClass}.', ['exception' => $e, 'extensionClass' => \get_class($extension)]); + } + } + } + + // No need to preload anything + return []; + } + + private function dumpExtension(ExtensionInterface $extension, ConfigBuilderGeneratorInterface $generator): void + { + if ($extension instanceof ConfigurationInterface) { + $configuration = $extension; + } elseif ($extension instanceof ConfigurationExtensionInterface) { + $configuration = $extension->getConfiguration([], $this->getContainerBuilder($this->kernel)); + } else { + throw new \LogicException(sprintf('Could not get configuration for extension "%s".', \get_class($extension))); + } + + $generator->build($configuration); + } + + /** + * {@inheritdoc} + */ + public function isOptional() + { + return true; + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.php index c3ecb8b6f6e44..d649364f19916 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.php @@ -11,6 +11,7 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator; +use Symfony\Bundle\FrameworkBundle\CacheWarmer\ConfigBuilderCacheWarmer; use Symfony\Bundle\FrameworkBundle\HttpCache\HttpCache; use Symfony\Component\Config\Resource\SelfCheckingResourceChecker; use Symfony\Component\Config\ResourceCheckerConfigCacheFactory; @@ -208,5 +209,8 @@ class_exists(WorkflowEvents::class) ? WorkflowEvents::ALIASES : [] ->args([ service('container.getenv'), ]) + ->set('config_builder.warmer', ConfigBuilderCacheWarmer::class) + ->args([service(KernelInterface::class), service('logger')->nullOnInvalid()]) + ->tag('kernel.cache_warmer') ; };