3131 */
3232final class EntityValueResolver implements ArgumentValueResolverInterface
3333{
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-
4634 public function __construct (
4735 private ManagerRegistry $ registry ,
48- private ?ExpressionLanguage $ language = null ,
49- array $ defaultOptions = [] ,
36+ private ?ExpressionLanguage $ expressionLanguage = null ,
37+ private MapEntity $ defaults = new MapEntity () ,
5038 ) {
51- $ this ->defaultOptions = array_merge ($ this ->defaultOptions , $ defaultOptions );
5239 }
5340
5441 /**
@@ -61,20 +48,16 @@ public function supports(Request $request, ArgumentMetadata $argument): bool
6148 }
6249
6350 $ 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 ) {
6952 return false ;
7053 }
7154
7255 // Doctrine Entity?
73- if (null === $ objectManager = $ this ->getManager ($ options[ ' object_manager ' ] , $ options[ ' class ' ] )) {
56+ if (! $ objectManager = $ this ->getManager ($ options-> objectManager , $ options-> class )) {
7457 return false ;
7558 }
7659
77- return !$ objectManager ->getMetadataFactory ()->isTransient ($ options[ ' class ' ] );
60+ return !$ objectManager ->getMetadataFactory ()->isTransient ($ options-> class );
7861 }
7962
8063 /**
@@ -83,20 +66,18 @@ public function supports(Request $request, ArgumentMetadata $argument): bool
8366 public function resolve (Request $ request , ArgumentMetadata $ argument ): iterable
8467 {
8568 $ options = $ this ->getOptions ($ argument );
86-
8769 $ name = $ argument ->getName ();
88- $ class = $ options[ ' class ' ] ;
70+ $ class = $ options-> class ;
8971
9072 $ 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 );
9476 }
9577 // find by identifier?
9678 } elseif (false === $ object = $ this ->find ($ class , $ request , $ options , $ name )) {
9779 // find by criteria
98- $ object = $ this ->findOneBy ($ class , $ request , $ options );
99- if (false === $ object ) {
80+ if (false === $ object = $ this ->findOneBy ($ class, $ request , $ options )) {
10081 if (!$ argument ->isNullable ()) {
10182 throw new \LogicException (sprintf ('Unable to guess how to get a Doctrine instance from the request information for parameter "%s". ' , $ name ));
10283 }
@@ -134,9 +115,9 @@ private function getManager(?string $name, string $class): ?ObjectManager
134115 }
135116 }
136117
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
138119 {
139- if ($ options[ ' mapping ' ] || $ options[ ' exclude ' ] ) {
120+ if ($ options-> mapping || $ options-> exclude ) {
140121 return false ;
141122 }
142123
@@ -145,8 +126,8 @@ private function find(string $class, Request $request, array $options, string $n
145126 return false ;
146127
9E88
}
147128
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) {
150131 $ cacheProvider = $ objectManager ->getCache ();
151132 if ($ cacheProvider && $ cacheProvider ->containsEntity ($ class , $ id )) {
152133 $ cacheProvider ->evictEntity ($ class , $ id );
@@ -160,11 +141,11 @@ private function find(string $class, Request $request, array $options, string $n
160141 }
161142 }
162143
163- private function getIdentifier (Request $ request , array $ options , string $ name ): mixed
144+ private function getIdentifier (Request $ request , MapEntity $ options , string $ name ): mixed
164145 {
165- if (\is_array ($ options[ ' id ' ] )) {
146+ if (\is_array ($ options-> id )) {
166147 $ id = [];
167- foreach ($ options[ ' id ' ] as $ field ) {
148+ foreach ($ options-> id as $ field ) {
168149 // Convert "%s_uuid" to "foobar_uuid"
169150 if (str_contains ($ field , '%s ' )) {
170151 $ field = sprintf ($ field , $ name );
@@ -176,59 +157,55 @@ private function getIdentifier(Request $request, array $options, string $name):
176157 return $ id ;
177158 }
178159
179- if (null !== $ options[ ' id ' ] ) {
180- $ name = $ options[ ' id ' ] ;
160+ if (null !== $ options-> id ) {
161+ $ name = $ options-> id ;
181162 }
182163
183164 if ($ request ->attributes ->has ($ name )) {
184165 return $ request ->attributes ->get ($ name );
185166 }
186167
187- if (!$ options[ ' id ' ] && $ request ->attributes ->has ('id ' )) {
168+ if (!$ options-> id && $ request ->attributes ->has ('id ' )) {
188169 return $ request ->attributes ->get ('id ' );
189170 }
190171
191172 return false ;
192173 }
193174
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
195176 {
196- if (!$ options ['mapping ' ]) {
197- if (!$ options ['auto_mapping ' ]) {
198- return false ;
199- }
200-
177+ if (null === $ mapping = $ options ->mapping ) {
201178 $ keys = $ request ->attributes ->keys ();
202- $ options [ ' mapping ' ] = $ keys ? array_combine ($ keys , $ keys ) : [];
179+ $ mapping = $ keys ? array_combine ($ keys , $ keys ) : [];
203180 }
204181
205- foreach ($ options[ ' exclude ' ] as $ exclude ) {
206- unset($ options [ ' mapping ' ] [$ exclude ]);
182+ foreach ($ options-> exclude as $ exclude ) {
183+ unset($ mapping [$ exclude ]);
207184 }
208185
209- if (!$ options [ ' mapping ' ] ) {
186+ if (!$ mapping ) {
210187 return false ;
211188 }
212189
213190 // if a specific id has been defined in the options and there is no corresponding attribute
214191 // 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 )) {
216193 return false ;
217194 }
218195
219196 $ criteria = [];
220- $ objectManager = $ this ->getManager ($ options[ ' object_manager ' ] , $ class );
197+ $ objectManager = $ this ->getManager ($ options-> objectManager , $ class );
221198 $ metadata = $ objectManager ->getClassMetadata ($ class );
222199
223- foreach ($ options [ ' mapping ' ] as $ attribute => $ field ) {
200+ foreach ($ mapping as $ attribute => $ field ) {
224201 if (!$ metadata ->hasField ($ field ) && (!$ metadata ->hasAssociation ($ field ) || !$ metadata ->isSingleValuedAssociation ($ field ))) {
225202 continue ;
226203 }
227204
228205 $ criteria [$ field ] = $ request ->attributes ->get ($ attribute );
229206 }
230207
231- if ($ options[ ' strip_null ' ] ) {
208+ if ($ options-> stripNull ) {
232209 $ criteria = array_filter ($ criteria , static fn ($ value ) => null !== $ value );
233210 }
234211
@@ -243,51 +220,27 @@ private function findOneBy(string $class, Request $request, array $options): fal
243220 }
244221 }
245222
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
247224 {
248- if (null === $ this ->language ) {
225+ if (! $ this ->expressionLanguage ) {
249226 throw new \LogicException (sprintf ('You cannot use the "%s" if the ExpressionLanguage component is not available. Try running "composer require symfony/expression-language". ' , __CLASS__ ));
250227 }
251228
252- $ repository = $ this ->getManager ($ options[ ' object_manager ' ] , $ class )->getRepository ($ class );
229+ $ repository = $ this ->getManager ($ options-> objectManager , $ class )->getRepository ($ class );
253230 $ variables = array_merge ($ request ->attributes ->all (), ['repository ' => $ repository ]);
254231
255232 try {
256- return $ this ->language ->evaluate ($ expression , $ variables );
233+ return $ this ->expressionLanguage ->evaluate ($ expression , $ variables );
257234 } catch (NoResultException |ConversionException ) {
258235 return null ;
259236 }
260237 }
261238
262- private function getOptions (ArgumentMetadata $ argument ): array
239+ private function getOptions (ArgumentMetadata $ argument ): MapEntity
263240 {
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 ;
278243
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 ());
292245 }
293246}
0 commit comments