vendor/symfony/ux-twig-component/src/DependencyInjection/TwigComponentExtension.php line 54

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\UX\TwigComponent\DependencyInjection;
  11. use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
  12. use Symfony\Component\Config\Definition\Builder\TreeBuilder;
  13. use Symfony\Component\Config\Definition\ConfigurationInterface;
  14. use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
  15. use Symfony\Component\Config\FileLocator;
  16. use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
  17. use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
  18. use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
  19. use Symfony\Component\DependencyInjection\ChildDefinition;
  20. use Symfony\Component\DependencyInjection\ContainerBuilder;
  21. use Symfony\Component\DependencyInjection\ContainerInterface;
  22. use Symfony\Component\DependencyInjection\Exception\LogicException;
  23. use Symfony\Component\DependencyInjection\Extension\Extension;
  24. use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
  25. use Symfony\Component\DependencyInjection\Parameter;
  26. use Symfony\Component\DependencyInjection\Reference;
  27. use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
  28. use Symfony\UX\TwigComponent\CacheWarmer\TwigComponentCacheWarmer;
  29. use Symfony\UX\TwigComponent\Command\TwigComponentDebugCommand;
  30. use Symfony\UX\TwigComponent\ComponentFactory;
  31. use Symfony\UX\TwigComponent\ComponentProperties;
  32. use Symfony\UX\TwigComponent\ComponentRenderer;
  33. use Symfony\UX\TwigComponent\ComponentRendererInterface;
  34. use Symfony\UX\TwigComponent\ComponentStack;
  35. use Symfony\UX\TwigComponent\ComponentTemplateFinder;
  36. use Symfony\UX\TwigComponent\DependencyInjection\Compiler\TwigComponentPass;
  37. use Symfony\UX\TwigComponent\Twig\ComponentExtension;
  38. use Symfony\UX\TwigComponent\Twig\ComponentLexer;
  39. use Symfony\UX\TwigComponent\Twig\ComponentRuntime;
  40. use Symfony\UX\TwigComponent\Twig\TwigEnvironmentConfigurator;
  41. /**
  42.  * @author Kevin Bond <kevinbond@gmail.com>
  43.  *
  44.  * @internal
  45.  */
  46. final class TwigComponentExtension extends Extension implements ConfigurationInterface
  47. {
  48.     private const DEPRECATED_DEFAULT_KEY '__deprecated__use_old_naming_behavior';
  49.     public function load(array $configsContainerBuilder $container): void
  50.     {
  51.         $loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/../../config'));
  52.         if (!isset($container->getParameter('kernel.bundles')['TwigBundle'])) {
  53.             throw new LogicException('The TwigBundle is not registered in your application. Try running "composer require symfony/twig-bundle".');
  54.         }
  55.         $configuration $this->getConfiguration($configs$container);
  56.         $config $this->processConfiguration($configuration$configs);
  57.         $defaults $config['defaults'];
  58.         if ($defaults === [self::DEPRECATED_DEFAULT_KEY]) {
  59.             trigger_deprecation('symfony/ux-twig-component''2.13''Not setting the "twig_component.defaults" config option is deprecated. Check the documentation for an example configuration.');
  60.             $container->setParameter('ux.twig_component.legacy_autonaming'true);
  61.             $defaults = [];
  62.         }
  63.         $container->setParameter('ux.twig_component.component_defaults'$defaults);
  64.         $container->register('ux.twig_component.component_template_finder'ComponentTemplateFinder::class)
  65.             ->setArguments([
  66.                 new Reference('twig.loader'),
  67.                 $config['anonymous_template_directory'],
  68.             ]);
  69.         $container->setAlias(ComponentRendererInterface::class, 'ux.twig_component.component_renderer');
  70.         $container->registerAttributeForAutoconfiguration(
  71.             AsTwigComponent::class,
  72.             static function (ChildDefinition $definitionAsTwigComponent $attribute) {
  73.                 $definition->addTag('twig.component'array_filter($attribute->serviceConfig()));
  74.             }
  75.         );
  76.         $container->register('ux.twig_component.component_factory'ComponentFactory::class)
  77.             ->setArguments([
  78.                 new Reference('ux.twig_component.component_template_finder'),
  79.                 new AbstractArgument(\sprintf('Added in %s.'TwigComponentPass::class)),
  80.                 new Reference('property_accessor'),
  81.                 new Reference('event_dispatcher'),
  82.                 new AbstractArgument(\sprintf('Added in %s.'TwigComponentPass::class)),
  83.                 new AbstractArgument(\sprintf('Added in %s.'TwigComponentPass::class)),
  84.                 new Reference('twig'),
  85.             ])
  86.             ->addTag('kernel.reset', ['method' => 'reset'])
  87.         ;
  88.         $container->register('ux.twig_component.component_stack'ComponentStack::class);
  89.         $container->register('ux.twig_component.component_properties'ComponentProperties::class)
  90.             ->setArguments([
  91.                 new Reference('property_accessor'),
  92.                 new AbstractArgument(\sprintf('Added in %s.'TwigComponentPass::class)),
  93.                 new Reference('cache.ux.twig_component'ContainerInterface::IGNORE_ON_INVALID_REFERENCE),
  94.             ])
  95.         ;
  96.         $container->register('ux.twig_component.component_renderer'ComponentRenderer::class)
  97.             ->setArguments([
  98.                 new Reference('twig'),
  99.                 new Reference('event_dispatcher'),
  100.                 new Reference('ux.twig_component.component_factory'),
  101.                 new Reference('ux.twig_component.component_properties'),
  102.                 new Reference('ux.twig_component.component_stack'),
  103.             ])
  104.             ->addTag('kernel.reset', ['method' => 'reset'])
  105.         ;
  106.         $container->register('ux.twig_component.twig.component_extension'ComponentExtension::class)
  107.             ->addTag('twig.extension')
  108.         ;
  109.         $container->register('ux.twig_component.twig.component_runtime'ComponentRuntime::class)
  110.             ->setArguments([
  111.                 new Reference('ux.twig_component.component_renderer'),
  112.                 new ServiceLocatorArgument(new TaggedIteratorArgument('ux.twig_component.twig_renderer'indexAttribute'key'needsIndexestrue)),
  113.             ])
  114.             ->addTag('twig.runtime')
  115.         ;
  116.         $container->register('ux.twig_component.twig.lexer'ComponentLexer::class);
  117.         $container->register('ux.twig_component.twig.environment_configurator'TwigEnvironmentConfigurator::class)
  118.             ->setDecoratedService(new Reference('twig.configurator.environment'))
  119.             ->setArguments([new Reference('ux.twig_component.twig.environment_configurator.inner')]);
  120.         $container->register('ux.twig_component.command.debug'TwigComponentDebugCommand::class)
  121.             ->setArguments([
  122.                 new Parameter('twig.default_path'),
  123.                 new Reference('ux.twig_component.component_factory'),
  124.                 new Reference('twig'),
  125.                 new AbstractArgument(\sprintf('Added in %s.'TwigComponentPass::class)),
  126.                 $config['anonymous_template_directory'],
  127.             ])
  128.             ->addTag('console.command')
  129.         ;
  130.         $container->setAlias('console.command.stimulus_component_debug''ux.twig_component.command.debug')
  131.             ->setDeprecated('symfony/ux-twig-component''2.13''%alias_id%');
  132.         if ($container->getParameter('kernel.debug') && $config['profiler']) {
  133.             $loader->load('debug.php');
  134.         }
  135.         $loader->load('cache.php');
  136.         $container->register('ux.twig_component.cache_warmer'TwigComponentCacheWarmer::class)
  137.             ->setArguments([new Reference(\Psr\Container\ContainerInterface::class)])
  138.             ->addTag('kernel.cache_warmer')
  139.             ->addTag('container.service_subscriber', ['id' => 'ux.twig_component.component_properties'])
  140.         ;
  141.     }
  142.     public function getConfigTreeBuilder(): TreeBuilder
  143.     {
  144.         $treeBuilder = new TreeBuilder('twig_component');
  145.         $rootNode $treeBuilder->getRootNode();
  146.         \assert($rootNode instanceof ArrayNodeDefinition);
  147.         $rootNode
  148.             ->validate()
  149.             ->always(function ($v) {
  150.                 if (!isset($v['anonymous_template_directory'])) {
  151.                     trigger_deprecation('symfony/twig-component-bundle''2.13''Not setting the "twig_component.anonymous_template_directory" config option is deprecated. It will default to "components" in 3.0.');
  152.                     $v['anonymous_template_directory'] = null;
  153.                 }
  154.                 return $v;
  155.             })
  156.             ->end()
  157.             ->children()
  158.                 ->arrayNode('defaults')
  159.                     ->defaultValue([self::DEPRECATED_DEFAULT_KEY])
  160.                     ->useAttributeAsKey('namespace')
  161.                     ->validate()
  162.                         ->always(function ($v) {
  163.                             foreach ($v as $namespace => $defaults) {
  164.                                 if (!str_ends_with($namespace'\\')) {
  165.                                     throw new InvalidConfigurationException(\sprintf('The twig_component.defaults namespace "%s" is invalid: it must end in a "\".'$namespace));
  166.                                 }
  167.                             }
  168.                             return $v;
  169.                         })
  170.                     ->end()
  171.                     ->arrayPrototype()
  172.                         ->beforeNormalization()
  173.                             ->ifString()
  174.                             ->then(function (string $v) {
  175.                                 return ['template_directory' => $v];
  176.                             })
  177.                         ->end()
  178.                         ->children()
  179.                             ->scalarNode('template_directory')
  180.                                 ->defaultValue('components')
  181.                             ->end()
  182.                             ->scalarNode('name_prefix')
  183.                                 ->defaultValue('')
  184.                             ->end()
  185.                         ->end()
  186.                     ->end()
  187.                 ->end()
  188.                 ->scalarNode('anonymous_template_directory')
  189.                     ->info('Defaults to `components`')
  190.                 ->end()
  191.                 ->booleanNode('profiler')
  192.                     ->info('Enables the profiler for Twig Component (in debug mode)')
  193.                     ->defaultValue('%kernel.debug%')
  194.                 ->end()
  195.                 ->scalarNode('controllers_json')
  196.                     ->setDeprecated('symfony/ux-twig-component''2.18''The "twig_component.controllers_json" config option is deprecated, and will be removed in 3.0.')
  197.                     ->defaultNull()
  198.                 ->end()
  199.             ->end();
  200.         return $treeBuilder;
  201.     }
  202.     public function getConfiguration(array $configContainerBuilder $container): ConfigurationInterface
  203.     {
  204.         return $this;
  205.     }
  206. }