31
31
*/
32
32
final class EntityValueResolver implements ArgumentValueResolverInterface
33
33
{
34
- private array $ defaultOptions = [
35
- 'object_manager ' => null ,
36
- 'expr ' => null ,
37
- 'mapping ' => [],
38
- 'exclude ' => [],
39
- 'strip_null ' => false ,
40
- 'id ' => null ,
41
- 'evict_cache ' => false ,
42
- 'auto_mapping ' => true ,
43
- 'attribute_only ' => false ,
44
- ];
45
-
46
34
public function __construct (
47
35
private ManagerRegistry $ registry ,
48
- private ?ExpressionLanguage $ language = null ,
49
- array $ defaultOptions = [] ,
36
+ private ?ExpressionLanguage $ expressionLanguage = null ,
37
+ private MapEntity $ defaults = new MapEntity () ,
50
38
) {
51
- $ this ->defaultOptions = array_merge ($ this ->defaultOptions , $ defaultOptions );
52
39
}
53
40
54
41
/**
@@ -61,20 +48,16 @@ public function supports(Request $request, ArgumentMetadata $argument): bool
61
48
}
62
49
63
50
$ options = $ this ->getOptions ($ argument );
64
- if (null === $ options ['class ' ]) {
65
- return false ;
66
- }
67
-
68
- if ($ options ['attribute_only ' ] && !$ options ['has_attribute ' ]) {
51
+ if (!$ options ->class || $ options ->disabled ) {
69
52
return false ;
70
53
}
71
54
72
55
// Doctrine Entity?
73
- if (null === $ objectManager = $ this ->getManager ($ options[ ' object_manager ' ] , $ options[ ' class ' ] )) {
56
+ if (! $ objectManager = $ this ->getManager ($ options-> objectManager , $ options-> class )) {
74
57
return false ;
75
58
}
76
59
77
- return !$ objectManager ->getMetadataFactory ()->isTransient ($ options[ ' class ' ] );
60
+ return !$ objectManager ->getMetadataFactory ()->isTransient ($ options-> class );
78
61
}
79
62
80
63
/**
@@ -83,20 +66,18 @@ public function supports(Request $request, ArgumentMetadata $argument): bool
83
66
public function resolve (Request $ request , ArgumentMetadata $ argument ): iterable
84
67
{
85
68
$ options = $ this ->getOptions ($ argument );
86
-
87
69
$ name = $ argument ->getName ();
88
- $ class = $ options[ ' class ' ] ;
70
+ $ class = $ options-> class ;
89
71
90
72
$ errorMessage = null ;
91
- if (null !== $ options[ ' expr ' ] ) {
92
- if (null === $ object = $ this ->findViaExpression ($ class , $ request , $ options[ ' expr ' ] , $ options )) {
93
- $ errorMessage = sprintf ('The expression "%s" returned null ' , $ options[ ' expr ' ] );
73
+ if (null !== $ options-> expr ) {
74
+ if (null === $ object = $ this ->findViaExpression ($ class , $ request , $ options-> expr , $ options )) {
75
+ $ errorMessage = sprintf ('The expression "%s" returned null ' , $ options-> expr );
94
76
}
95
77
// find by identifier?
96
78
} elseif (false === $ object = $ this ->find ($ class , $ request , $ options , $ name )) {
97
79
// find by criteria
98
- $ object = $ this ->findOneBy ($ class , $ request , $ options );
99
- if (false === $ object ) {
80
+ if (false === $ object = $ this ->findOneBy ($ class , $ request , $ options )) {
100
81
if (!$ argument ->isNullable ()) {
101
82
throw new \LogicException (sprintf ('Unable to guess how to get a Doctrine instance from the request information for parameter "%s". ' , $ name ));
102
83
}
@@ -134,9 +115,9 @@ private function getManager(?string $name, string $class): ?ObjectManager
134
115
}
135
116
}
136
117
137
- private function find (string $ class , Request $ request , array $ options , string $ name ): false |object |null
118
+ private function find (string $ class , Request $ request , MapEntity $ options , string $ name ): false |object |null
138
119
{
139
- if ($ options[ ' mapping ' ] || $ options[ ' exclude ' ] ) {
120
+ if ($ options-> mapping || $ options-> exclude ) {
140
121
return false ;
141
122
}
142
123
@@ -145,8 +126,8 @@ private function find(string $class, Request $request, array $options, string $n
145
126
return false ;
146
127
}
147
128
148
- $ objectManager = $ this ->getManager ($ options[ ' object_manager ' ] , $ class );
149
- if ($ options[ ' evict_cache ' ] && $ objectManager instanceof EntityManagerInterface) {
129
+ $ objectManager = $ this ->getManager ($ options-> objectManager , $ class );
130
+ if ($ options-> evictCache && $ objectManager instanceof EntityManagerInterface) {
150
131
$ cacheProvider = $ objectManager ->getCache ();
151
132
if ($ cacheProvider && $ cacheProvider ->containsEntity ($ class , $ id )) {
152
133
$ cacheProvider ->evictEntity ($ class , $ id );
@@ -160,11 +141,11 @@ private function find(string $class, Request $request, array $options, string $n
160
141
}
161
142
}
162
143
163
- private function getIdentifier (Request $ request , array $ options , string $ name ): mixed
144
+ private function getIdentifier (Request $ request , MapEntity $ options , string $ name ): mixed
164
145
{
165
- if (\is_array ($ options[ ' id ' ] )) {
146
+ if (\is_array ($ options-> id )) {
166
147
$ id = [];
167
- foreach ($ options[ ' id ' ] as $ field ) {
148
+ foreach ($ options-> id as $ field ) {
168
149
// Convert "%s_uuid" to "foobar_uuid"
169
150
if (str_contains ($ field , '%s ' )) {
170
151
$ field = sprintf ($ field , $ name );
@@ -176,59 +157,55 @@ private function getIdentifier(Request $request, array $options, string $name):
176
157
return $ id ;
177
158
}
178
159
179
- if (null !== $ options[ ' id ' ] ) {
180
- $ name = $ options[ ' id ' ] ;
160
+ if (null !== $ options-> id ) {
161
+ $ name = $ options-> id ;
181
162
}
182
163
183
164
if ($ request ->attributes ->has ($ name )) {
184
165
return $ request ->attributes ->get ($ name );
185
166
}
186
167
187
- if (!$ options[ ' id ' ] && $ request ->attributes ->has ('id ' )) {
168
+ if (!$ options-> id && $ request ->attributes ->has ('id ' )) {
188
169
return $ request ->attributes ->get ('id ' );
189
170
}
190
171
191
172
return false ;
192
173
}
193
174
194
- private function findOneBy (string $ class , Request $ request , array $ options ): false |object |null
175
+ private function findOneBy (string $ class , Request $ request , MapEntity $ options ): false |object |null
195
176
{
196
- if (!$ options ['mapping ' ]) {
197
- if (!$ options ['auto_mapping ' ]) {
198
- return false ;
199
- }
200
-
177
+ if (null === $ mapping = $ options ->mapping ) {
201
178
$ keys = $ request ->attributes ->keys ();
202
- $ options [ ' mapping ' ] = $ keys ? array_combine ($ keys , $ keys ) : [];
179
+ $ mapping = $ keys ? array_combine ($ keys , $ keys ) : [];
203
180
}
204
181
205
- foreach ($ options[ ' exclude ' ] as $ exclude ) {
206
- unset($ options [ ' mapping ' ] [$ exclude ]);
182
+ foreach ($ options-> exclude as $ exclude ) {
183
+ unset($ mapping [$ exclude ]);
207
184
}
208
185
209
- if (!$ options [ ' mapping ' ] ) {
186
+ if (!$ mapping ) {
210
187
return false ;
211
188
}
212
189
213
190
// if a specific id has been defined in the options and there is no corresponding attribute
214
191
// return false in order to avoid a fallback to the id which might be of another object
215
- if ($ options[ ' id ' ] && null === $ request ->attributes ->get ($ options[ ' id ' ] )) {
192
+ if (\is_string ( $ options-> id ) && null === $ request ->attributes ->get ($ options-> id )) {
216
193
return false ;
217
194
}
218
195
219
196
$ criteria = [];
220
- $ objectManager = $ this ->getManager ($ options[ ' object_manager ' ] , $ class );
197
+ $ objectManager = $ this ->getManager ($ options-> objectManager , $ class );
221
198
$ metadata = $ objectManager ->getClassMetadata ($ class );
222
199
223
- foreach ($ options [ ' mapping ' ] as $ attribute => $ field ) {
200
+ foreach ($ mapping as $ attribute => $ field ) {
224
201
if (!$ metadata ->hasField ($ field ) && (!$ metadata ->hasAssociation ($ field ) || !$ metadata ->isSingleValuedAssociation ($ field ))) {
225
202
continue ;
226
203
}
227
204
228
205
$ criteria [$ field ] = $ request ->attributes ->get ($ attribute );
229
206
}
230
207
231
- if ($ options[ ' strip_null ' ] ) {
208
+ if ($ options-> stripNull ) {
232
209
$ criteria = array_filter ($ criteria , static fn ($ value ) => null !== $ value );
233
210
}
234
211
@@ -243,51 +220,27 @@ private function findOneBy(string $class, Request $request, array $options): fal
243
220
}
244
221
}
245
222
246
- private function findViaExpression (string $ class , Request $ request , string $ expression , array $ options ): ?object
223
+ private function findViaExpression (string $ class , Request $ request , string $ expression , MapEntity $ options ): ?object
247
224
{
248
- if (null === $ this ->language ) {
225
+ if (! $ this ->expressionLanguage ) {
249
226
throw new \LogicException (sprintf ('You cannot use the "%s" if the ExpressionLanguage component is not available. Try running "composer require symfony/expression-language". ' , __CLASS__ ));
250
227
}
251
228
252
- $ repository = $ this ->getManager ($ options[ ' object_manager ' ] , $ class )->getRepository ($ class );
229
+ $ repository = $ this ->getManager ($ options-> objectManager , $ class )->getRepository ($ class );
253
230
$ variables = array_merge ($ request ->attributes ->all (), ['repository ' => $ repository ]);
254
231
255
232
try {
256
- return $ this ->language ->evaluate ($ expression , $ variables );
233
+ return $ this ->expressionLanguage ->evaluate ($ expression , $ variables );
257
234
} catch (NoResultException |ConversionException ) {
258
235
return null ;
259
236
}
260
237
}
261
238
262
- private function getOptions (ArgumentMetadata $ argument ): array
239
+ private function getOptions (ArgumentMetadata $ argument ): MapEntity
263
240
{
264
- /** @var ?MapEntity $configuration */
265
- $ configuration = $ argument ->getAttributes (MapEntity::class, ArgumentMetadata::IS_INSTANCEOF )[0 ] ?? null ;
266
-
267
- $ argumentClass = $ argument ->getType ();
268
- if ($ argumentClass && !class_exists ($ argumentClass )) {
269
- $ argumentClass = null ;
270
- }
271
-
272
- if (null === $ configuration ) {
273
- return array_merge ($ this ->defaultOptions , [
274
- 'class ' => $ argumentClass ,
275
- 'has_attribute ' => false ,
276
- ]);
277
- }
241
+ /** @var MapEntity $options */
242
+ $ options = $ argument ->getAttributes (MapEntity::class, ArgumentMetadata::IS_INSTANCEOF )[0 ] ?? $ this ->defaults ;
278
243
279
- return [
280
- 'class ' => $ configuration ->class ?? $ argumentClass ,
281
- 'object_manager ' => $ configuration ->objectManager ?? $ this ->defaultOptions ['object_manager ' ],
282
- 'expr ' => $ configuration ->expr ?? $ this ->defaultOptions ['expr ' ],
283
- 'mapping ' => $ configuration ->mapping ?? $ this ->defaultOptions ['mapping ' ],
284
- 'exclude ' => $ configuration ->exclude ?? $ this ->defaultOptions ['exclude ' ],
285
- 'strip_null ' => $ configuration ->stripNull ?? $ this ->defaultOptions ['strip_null ' ],
286
- 'id ' => $ configuration ->id ?? $ this ->defaultOptions ['id ' ],
287
- 'evict_cache ' => $ configuration ->evictCache ?? $ this ->defaultOptions ['evict_cache ' ],
288
- 'has_attribute ' => true ,
289
- 'auto_mapping ' => $ this ->defaultOptions ['auto_mapping ' ],
290
- 'attribute_only ' => $ this ->defaultOptions ['attribute_only ' ],
291
- ];
244
+ return $ options ->withDefaults ($ this ->defaults , $ argument ->getType ());
292
245
}
293
246
}
0 commit comments