1212namespace Symfony \UX \LiveComponent \DependencyInjection ;
1313
1414use Symfony \Component \AssetMapper \AssetMapperInterface ;
15+ use Symfony \Component \Config \Definition \Builder \ArrayNodeDefinition ;
16+ use Symfony \Component \Config \Definition \Builder \TreeBuilder ;
17+ use Symfony \Component \Config \Definition \ConfigurationInterface ;
18+ use Symfony \Component \DependencyInjection \Argument \TaggedIteratorArgument ;
1519use Symfony \Component \DependencyInjection \ChildDefinition ;
1620use Symfony \Component \DependencyInjection \ContainerBuilder ;
1721use Symfony \Component \DependencyInjection \ContainerInterface ;
5054use Symfony \UX \TwigComponent \ComponentFactory ;
5155use Symfony \UX \TwigComponent \ComponentRenderer ;
5256
53- use function Symfony \Component \DependencyInjection \Loader \Configurator \tagged_iterator ;
54-
5557/**
5658 * @author Kevin Bond <[email protected] > 5759 *
5860 * @internal
5961 */
60- final class LiveComponentExtension extends Extension implements PrependExtensionInterface
62+ final class LiveComponentExtension extends Extension implements PrependExtensionInterface, ConfigurationInterface
6163{
6264 public const TEMPLATES_MAP_FILENAME = 'live_components_twig_templates.map ' ;
6365
@@ -93,16 +95,19 @@ function (ChildDefinition $definition, AsLiveComponent $attribute) {
9395 }
9496 );
9597
98+ $ configuration = $ this ->getConfiguration ($ configs , $ container );
99+ $ config = $ this ->processConfiguration ($ configuration , $ configs );
100+
96101 $ container ->registerForAutoconfiguration (HydrationExtensionInterface::class)
97102 ->addTag (LiveComponentBundle::HYDRATION_EXTENSION_TAG );
98103
99104 $ container ->register ('ux.live_component.component_hydrator ' , LiveComponentHydrator::class)
100105 ->setArguments ([
101- tagged_iterator (LiveComponentBundle::HYDRATION_EXTENSION_TAG ),
106+ new TaggedIteratorArgument (LiveComponentBundle::HYDRATION_EXTENSION_TAG ),
102107 new Reference ('property_accessor ' ),
103108 new Reference ('ux.live_component.metadata_factory ' ),
104109 new Reference ('serializer ' , ContainerInterface::NULL_ON_INVALID_REFERENCE ),
105- ' %kernel.secret% ',
110+ $ config [ ' secret ' ], // defaults to ' %kernel.secret%'
106111 ])
107112 ;
108113
@@ -236,7 +241,7 @@ function (ChildDefinition $definition, AsLiveComponent $attribute) {
236241
237242 $ container ->register ('ux.live_component.deterministic_id_calculator ' , DeterministicTwigIdCalculator::class);
238243 $ container ->register ('ux.live_component.fingerprint_calculator ' , FingerprintCalculator::class)
239- ->setArguments ([' %kernel. secret% ' ]);
244+ ->setArguments ([$ config [ ' secret ' ]]); // default to %kernel.secret%
240245
241246 $ container ->setAlias (ComponentValidatorInterface::class, ComponentValidator::class);
242247
@@ -258,6 +263,35 @@ function (ChildDefinition $definition, AsLiveComponent $attribute) {
258263 ->addTag ('kernel.cache_warmer ' );
259264 }
260265
266+ public function getConfigTreeBuilder (): TreeBuilder
267+ {
268+ $ treeBuilder = new TreeBuilder ('live_component ' );
269+ $ rootNode = $ treeBuilder ->getRootNode ();
270+ \assert ($ rootNode instanceof ArrayNodeDefinition);
271+
272+ $ rootNode
273+ ->addDefaultsIfNotSet ()
274+ ->children ()
275+ ->scalarNode ('secret ' )
276+ ->info ('The secret used to compute fingerprints and checksums ' )
277+ ->beforeNormalization ()
278+ ->ifString ()
279+ ->then (trim (...))
280+ ->end ()
281+ ->cannotBeEmpty ()
282+ ->defaultValue ('%kernel.secret% ' )
283+ ->end ()
284+ ->end ()
285+ ;
286+
287+ return $ treeBuilder ;
288+ }
289+
290+ public function getConfiguration (array $ config , ContainerBuilder $ container ): ConfigurationInterface
291+ {
292+ return $ this ;
293+ }
294+
261295 private function isAssetMapperAvailable (ContainerBuilder $ container ): bool
262296 {
263297 if (!interface_exists (AssetMapperInterface::class)) {
0 commit comments