19
19
use Symfony \Component \DependencyInjection \Reference ;
20
20
use Symfony \Component \Serializer \Debug \TraceableEncoder ;
21
21
use Symfony \Component \Serializer \Debug \TraceableNormalizer ;
22
- use Symfony \Component \Serializer \SerializerInterface ;
23
22
24
23
/**
25
24
* Adds all services with the tags "serializer.encoder" and "serializer.normalizer" as
@@ -32,177 +31,47 @@ class SerializerPass implements CompilerPassInterface
32
31
{
33
32
use PriorityTaggedServiceTrait;
34
33
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 )
38
38
{
39
39
if (!$ container ->hasDefinition ('serializer ' )) {
40
40
return ;
41
41
}
42
42
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 )) {
50
44
throw new RuntimeException ('You must tag at least one service as "serializer.normalizer" to use the "serializer" service. ' );
51
45
}
52
46
53
- if (!$ encoders = $ this ->findAndSortTaggedServices ('serializer.encoder.default ' , $ container )) {
47
+ if (!$ encoders = $ this ->findAndSortTaggedServices ('serializer.encoder ' , $ container )) {
54
48
throw new RuntimeException ('You must tag at least one service as "serializer.encoder" to use the "serializer" service. ' );
55
49
}
56
50
57
51
if ($ container ->hasParameter ('serializer.default_context ' )) {
58
52
$ 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 ());
96
56
}
57
+ $ container ->getDefinition ('serializer ' )->replaceArgument (2 , $ defaultContext );;
58
+ $ container ->getParameterBag ()->remove ('serializer.default_context ' );
97
59
}
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
- }
107
60
108
- private function configureSerializer (ContainerBuilder $ container , string $ id , array $ normalizers , array $ encoders , string $ serializerName ): void
109
- {
110
61
if ($ container ->getParameter ('kernel.debug ' ) && $ container ->hasDefinition ('serializer.data_collector ' )) {
111
62
foreach ($ normalizers as $ i => $ normalizer ) {
112
63
$ 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 ' )]);
114
65
}
115
66
116
67
foreach ($ encoders as $ i => $ encoder ) {
117
68
$ 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 ' )]);
119
70
}
120
71
}
121
72
122
- $ serializerDefinition = $ container ->getDefinition ($ id );
73
+ $ serializerDefinition = $ container ->getDefinition (' serializer ' );
123
74
$ serializerDefinition ->replaceArgument (0 , $ normalizers );
124
75
$ serializerDefinition ->replaceArgument (1 , $ encoders );
125
76
}
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
- }
208
77
}
0 commit comments