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 ;
5761 *
5862 * @internal
5963 */
60- final class LiveComponentExtension extends Extension implements PrependExtensionInterface
64+ final class LiveComponentExtension extends Extension implements PrependExtensionInterface, ConfigurationInterface
6165{
6266 public const TEMPLATES_MAP_FILENAME = 'live_components_twig_templates.map ' ;
6367
@@ -93,16 +97,19 @@ function (ChildDefinition $definition, AsLiveComponent $attribute) {
9397 }
9498 );
9599
100+ $ configuration = $ this ->getConfiguration ($ configs , $ container );
101+ $ config = $ this ->processConfiguration ($ configuration , $ configs );
102+
96103 $ container ->registerForAutoconfiguration (HydrationExtensionInterface::class)
97104 ->addTag (LiveComponentBundle::HYDRATION_EXTENSION_TAG );
98105
99106 $ container ->register ('ux.live_component.component_hydrator ' , LiveComponentHydrator::class)
100107 ->setArguments ([
101- tagged_iterator (LiveComponentBundle::HYDRATION_EXTENSION_TAG ),
108+ new TaggedIteratorArgument (LiveComponentBundle::HYDRATION_EXTENSION_TAG ),
102109 new Reference ('property_accessor ' ),
103110 new Reference ('ux.live_component.metadata_factory ' ),
104111 new Reference ('serializer ' , ContainerInterface::NULL_ON_INVALID_REFERENCE ),
105- ' %kernel.secret% ',
112+ $ config [ ' secret ' ], // defaults to ' %kernel.secret%'
106113 ])
107114 ;
108115
@@ -236,7 +243,7 @@ function (ChildDefinition $definition, AsLiveComponent $attribute) {
236243
237244 $ container ->register ('ux.live_component.deterministic_id_calculator ' , DeterministicTwigIdCalculator::class);
238245 $ container ->register ('ux.live_component.fingerprint_calculator ' , FingerprintCalculator::class)
239- ->setArguments ([' %kernel. secret% ' ]);
246+ ->setArguments ([$ config [ ' secret ' ]]); // default to %kernel.secret%
240247
241248 $ container ->setAlias (ComponentValidatorInterface::class, ComponentValidator::class);
242249
@@ -258,6 +265,35 @@ function (ChildDefinition $definition, AsLiveComponent $attribute) {
258265 ->addTag ('kernel.cache_warmer ' );
259266 }
260267
268+ public function getConfigTreeBuilder (): TreeBuilder
269+ {
270+ $ treeBuilder = new TreeBuilder ('live_component ' );
271+ $ rootNode = $ treeBuilder ->getRootNode ();
272+ \assert ($ rootNode instanceof ArrayNodeDefinition);
273+
274+ $ rootNode
275+ ->addDefaultsIfNotSet ()
276+ ->children ()
277+ ->scalarNode ('secret ' )
278+ ->info ('The secret used to compute fingerprints and checksums ' )
279+ ->beforeNormalization ()
280+ ->ifString ()
281+ ->then (trim (...))
282+ ->end ()
283+ ->cannotBeEmpty ()
284+ ->defaultValue ('%kernel.secret% ' )
285+ ->end ()
286+ ->end ()
287+ ;
288+
289+ return $ treeBuilder ;
290+ }
291+
292+ public function getConfiguration (array $ config , ContainerBuilder $ container ): ConfigurationInterface
293+ {
294+ return $ this ;
295+ }
296+
261297 private function isAssetMapperAvailable (ContainerBuilder $ container ): bool
262298 {
263299 if (!interface_exists (AssetMapperInterface::class)) {
0 commit comments