1919use Symfony \Component \DependencyInjection \Reference ;
2020use Symfony \Component \Serializer \Debug \TraceableEncoder ;
2121use Symfony \Component \Serializer \Debug \TraceableNormalizer ;
22- use Symfony \Component \Serializer \SerializerInterface ;
2322
2423/**
2524 * Adds all services with the tags "serializer.encoder" and "serializer.normalizer" as
@@ -32,177 +31,47 @@ class SerializerPass implements CompilerPassInterface
3231{
3332 use PriorityTaggedServiceTrait;
3433
35- private const NAME_CONVERTER_METADATA_AWARE_ID = 'serializer.name_converter.metadata_aware ' ;
36-
37- public function process (ContainerBuilder $ container ): void
34+ /**
35+ * @return void
36+ */
37+ public function process (ContainerBuilder $ container )
3838 {
3939 if (!$ container ->hasDefinition ('serializer ' )) {
4040 return ;
4141 }
4242
43- $ namedSerializers = $ container ->hasParameter ('.serializer.named_serializers ' )
44- ? $ container ->getParameter ('.serializer.named_serializers ' ) : [];
45-
46- $ this ->createNamedSerializerTags ($ container , 'serializer.normalizer ' , 'include_built_in_normalizers ' , $ namedSerializers );
47- $ this ->createNamedSerializerTags ($ container , 'serializer.encoder ' , 'include_built_in_encoders ' , $ namedSerializers );
48-
49- if (!$ normalizers = $ this ->findAndSortTaggedServices ('serializer.normalizer.default ' , $ container )) {
43+ if (!$ normalizers = $ this ->findAndSortTaggedServices ('serializer.normalizer ' , $ container )) {
5044 throw new RuntimeException ('You must tag at least one service as "serializer.normalizer" to use the "serializer" service. ' );
5145 }
5246
53- if (!$ encoders = $ this ->findAndSortTaggedServices ('serializer.encoder.default ' , $ container )) {
47+ if (!$ encoders = $ this ->findAndSortTaggedServices ('serializer.encoder ' , $ container )) {
5448 throw new RuntimeException ('You must tag at least one service as "serializer.encoder" to use the "serializer" service. ' );
5549 }
5650
5751 if ($ container ->hasParameter ('serializer.default_context ' )) {
5852 $ defaultContext = $ container ->getParameter ('serializer.default_context ' );
59- $ this ->bindDefaultContext ($ container , array_merge ($ normalizers , $ encoders ), $ defaultContext );
60- $ container ->getParameterBag ()->remove ('serializer.default_context ' );
61- }
62-
63- $ this ->configureSerializer ($ container , 'serializer ' , $ normalizers , $ encoders , 'default ' );
64-
65- if ($ namedSerializers ) {
66- $ this ->configureNamedSerializers ($ container );
67- }
68- }
69-
70- private function createNamedSerializerTags (ContainerBuilder $ container , string $ tagName , string $ configName , array $ namedSerializers ): void
71- {
72- $ serializerNames = array_keys ($ namedSerializers );
73- $ withBuiltIn = array_filter ($ serializerNames , fn (string $ name ) => $ namedSerializers [$ name ][$ configName ] ?? false );
74-
75- foreach ($ container ->findTaggedServiceIds ($ tagName ) as $ serviceId => $ tags ) {
76- $ definition = $ container ->getDefinition ($ serviceId );
77-
78- foreach ($ tags as $ tag ) {
79- $ names = (array ) ($ tag ['serializer ' ] ?? []);
80-
81- if (!$ names ) {
82- $ names = ['default ' ];
83- } elseif (\in_array ('* ' , $ names , true )) {
84- $ names = array_unique (['default ' , ...$ serializerNames ]);
85- }
86-
87- if ($ tag ['built_in ' ] ?? false ) {
88- $ names = array_unique (['default ' , ...$ names , ...$ withBuiltIn ]);
89- }
90-
91- unset($ tag ['serializer ' ], $ tag ['built_in ' ]);
92-
93- foreach ($ names as $ name ) {
94- $ definition ->addTag ($ tagName .'. ' .$ name , $ tag );
95- }
53+ foreach (array_merge ($ normalizers , $ encoders ) as $ service ) {
54+ $ definition = $ container ->getDefinition ($ service );
55+ $ definition ->setBindings (['array $defaultContext ' => new BoundArgument ($ defaultContext , false )] + $ definition ->getBindings ());
9656 }
57+ $ container ->getDefinition ('serializer ' )->replaceArgument (2 , $ defaultContext );
58+ $ container ->getParameterBag ()->remove ('serializer.default_context ' );
9759 }
98- }
99-
100- private function bindDefaultContext (ContainerBuilder $ container , array $ services , array $ defaultContext ): void
101- {
102- foreach ($ services as $ id ) {
103- $ definition = $ container ->getDefinition ((string ) $ id );
104- $ definition ->setBindings (['array $defaultContext ' => new BoundArgument ($ defaultContext , false )] + $ definition ->getBindings ());
105- }
106- }
10760
108- private function configureSerializer (ContainerBuilder $ container , string $ id , array $ normalizers , array $ encoders , string $ serializerName ): void
109- {
11061 if ($ container ->getParameter ('kernel.debug ' ) && $ container ->hasDefinition ('serializer.data_collector ' )) {
11162 foreach ($ normalizers as $ i => $ normalizer ) {
11263 $ normalizers [$ i ] = $ container ->register ('.debug.serializer.normalizer. ' .$ normalizer , TraceableNormalizer::class)
113- ->setArguments ([$ normalizer , new Reference ('serializer.data_collector ' ), $ serializerName ]);
64+ ->setArguments ([$ normalizer , new Reference ('serializer.data_collector ' )]);
11465 }
11566
11667 foreach ($ encoders as $ i => $ encoder ) {
11768 $ encoders [$ i ] = $ container ->register ('.debug.serializer.encoder. ' .$ encoder , TraceableEncoder::class)
118- ->setArguments ([$ encoder , new Reference ('serializer.data_collector ' ), $ serializerName ]);
69+ ->setArguments ([$ encoder , new Reference ('serializer.data_collector ' )]);
11970 }
12071 }
12172
122- $ serializerDefinition = $ container ->getDefinition ($ id );
73+ $ serializerDefinition = $ container ->getDefinition (' serializer ' );
12374 $ serializerDefinition ->replaceArgument (0 , $ normalizers );
12475 $ serializerDefinition ->replaceArgument (1 , $ encoders );
12576 }
126-
127- private function configureNamedSerializers (ContainerBuilder $ container ): void
128- {
129- $ defaultSerializerNameConverter = $ container ->hasParameter ('.serializer.name_converter ' )
130- ? $ container ->getParameter ('.serializer.name_converter ' ) : null ;
131-
132- foreach ($ container ->getParameter ('.serializer.named_serializers ' ) as $ serializerName => $ config ) {
133- $ config += ['default_context ' => [], 'name_converter ' => null ];
134- $ serializerId = 'serializer. ' .$ serializerName ;
135-
136- if (!$ normalizers = $ this ->findAndSortTaggedServices ('serializer.normalizer. ' .$ serializerName , $ container )) {
137- throw new RuntimeException (\sprintf ('The named serializer "%1$s" requires at least one registered normalizer. Tag the normalizers as "serializer.normalizer" with the "serializer" attribute set to "%1$s". ' , $ serializerName ));
138- }
139-
140- if (!$ encoders = $ this ->findAndSortTaggedServices ('serializer.encoder. ' .$ serializerName , $ container )) {
141- throw new RuntimeException (\sprintf ('The named serializer "%1$s" requires at least one registered encoder. Tag the encoders as "serializer.encoder" with the "serializer" attribute set to "%1$s". ' , $ serializerName ));
142- }
143-
144- $ config ['name_converter ' ] = $ defaultSerializerNameConverter !== $ config ['name_converter ' ]
145- ? $ this ->buildChildNameConverterDefinition ($ container , $ config ['name_converter ' ])
146- : self ::NAME_CONVERTER_METADATA_AWARE_ID ;
147-
148- $ normalizers = $ this ->buildChildDefinitions ($ container , $ serializerName , $ normalizers , $ config );
149- $ encoders = $ this ->buildChildDefinitions ($ container , $ serializerName , $ encoders , $ config );
150-
151- $ this ->bindDefaultContext ($ container , array_merge ($ normalizers , $ encoders ), $ config ['default_context ' ]);
152-
153- $ container ->registerChild ($ serializerId , 'serializer ' );
154- $ container ->registerAliasForArgument ($ serializerId , SerializerInterface::class, $ serializerName .'.serializer ' );
155-
156- $ this ->configureSerializer ($ container , $ serializerId , $ normalizers , $ encoders , $ serializerName );
157-
158- if ($ container ->getParameter ('kernel.debug ' ) && $ container ->hasDefinition ('debug.serializer ' )) {
159- $ container ->registerChild ($ debugId = 'debug. ' .$ serializerId , 'debug.serializer ' )
160- ->setDecoratedService ($ serializerId )
161- ->replaceArgument (0 , new Reference ($ debugId .'.inner ' ))
162- ->replaceArgument (2 , $ serializerName );
163- }
164- }
165- }
166-
167- private function buildChildNameConverterDefinition (ContainerBuilder $ container , ?string $ nameConverter ): ?string
168- {
169- $ childId = self ::NAME_CONVERTER_METADATA_AWARE_ID .'. ' .ContainerBuilder::hash ($ nameConverter );
170-
171- if (!$ container ->hasDefinition ($ childId )) {
172- $ childDefinition = $ container ->registerChild ($ childId , self ::NAME_CONVERTER_METADATA_AWARE_ID .'.abstract ' );
173- if (null !== $ nameConverter ) {
174- $ childDefinition ->addArgument (new Reference ($ nameConverter ));
175- }
176- }
177-
178- return $ childId ;
179- }
180-
181- private function buildChildDefinitions (ContainerBuilder $ container , string $ serializerName , array $ services , array $ config ): array
182- {
183- foreach ($ services as &$ id ) {
184- $ childId = $ id .'. ' .$ serializerName ;
185-
186- $ definition = $ container ->registerChild ($ childId , (string ) $ id );
187-
188- if (null !== $ nameConverterIndex = $ this ->findNameConverterIndex ($ container , (string ) $ id )) {
189- $ definition ->replaceArgument ($ nameConverterIndex , new Reference ($ config ['name_converter ' ]));
190- }
191-
192- $ id = new Reference ($ childId );
193- }
194-
195- return $ services ;
196- }
197-
198- private function findNameConverterIndex (ContainerBuilder $ container , string $ id ): int |string |null
199- {
200- foreach ($ container ->getDefinition ($ id )->getArguments () as $ index => $ argument ) {
201- if ($ argument instanceof Reference && self ::NAME_CONVERTER_METADATA_AWARE_ID === (string ) $ argument ) {
202- return $ index ;
203- }
204- }
205-
206- return null ;
207- }
20877}
0 commit comments