@@ -47,37 +47,45 @@ public function supports(Request $request, ArgumentMetadata $argument): bool
47
47
return false ;
48
48
}
49
49
50
- $ options = $ this ->getOptions ($ argument );
50
+ $ options = $ this ->getMapEntityAttribute ($ argument );
51
51
if (!$ options ->class || $ options ->disabled ) {
52
52
return false ;
53
53
}
54
54
55
+ if (null === $ options ->expr && !($ options ->mapping || $ options ->exclude ) && null === $ this ->getIdentifier ($ request , $ options , $ argument ->getName ())) {
56
+ return false ;
57
+ }
58
+
55
59
// Doctrine Entity?
56
60
if (!$ objectManager = $ this ->getManager ($ options ->objectManager , $ options ->class )) {
57
61
return false ;
58
62
}
59
63
60
- return !$ objectManager ->getMetadataFactory ()->isTransient ($ options ->class );
64
+ if ($ objectManager ->getMetadataFactory ()->isTransient ($ options ->class )) {
65
+ return false ;
66
+ }
67
+
68
+ return null !== $ options ->expr || $ this ->getCriteria ($ request , $ options , $ objectManager );
61
69
}
62
70
63
71
/**
64
72
* {@inheritdoc}
65
73
*/
66
74
public function resolve (Request $ request , ArgumentMetadata $ argument ): iterable
67
75
{
68
- $ options = $ this ->getOptions ($ argument );
76
+ $ options = $ this ->getMapEntityAttribute ($ argument );
69
77
$ name = $ argument ->getName ();
70
- $ class = $ options ->class ;
78
+ $ objectManager = $ this -> getManager ( $ options ->objectManager , $ options -> class ) ;
71
79
72
80
$ errorMessage = null ;
73
81
if (null !== $ options ->expr ) {
74
- if (null === $ object = $ this ->findViaExpression ($ class , $ request, $ options -> expr , $ options )) {
82
+ if (null === $ object = $ this ->findViaExpression ($ objectManager , $ request , $ options )) {
75
83
$ errorMessage = sprintf ('The expression "%s" returned null ' , $ options ->expr );
76
84
}
77
85
// find by identifier?
78
- } elseif (false === $ object = $ this ->find ($ class , $ request , $ options , $ name )) {
86
+ } elseif (false === $ object = $ this ->find ($ objectManager , $ request , $ options , $ name )) {
79
87
// find by criteria
80
- if (false === $ object = $ this ->findOneBy ($ class , $ request , $ options )) {
88
+ if (false === $ object = $ this ->findOneBy ($ objectManager , $ request , $ options )) {
81
89
if (!$ argument ->isNullable ()) {
82
90
throw new \LogicException (sprintf ('Unable to guess how to get a Doctrine instance from the request information for parameter "%s". ' , $ name ));
83
91
}
@@ -87,7 +95,7 @@ public function resolve(Request $request, ArgumentMetadata $argument): iterable
87
95
}
88
96
89
97
if (null === $ object && !$ argument ->isNullable ()) {
90
- $ message = sprintf ('"%s" object not found by the "%s" Argument Resolver. ' , $ class , self ::class);
98
+ $ message = sprintf ('"%s" object not found by the "%s" Argument Resolver. ' , $ options -> class , self ::class);
91
99
if ($ errorMessage ) {
92
100
$ message .= ' ' .$ errorMessage ;
93
101
}
@@ -115,7 +123,7 @@ private function getManager(?string $name, string $class): ?ObjectManager
115
123
}
116
124
}
117
125
118
- private function find (string $ class , Request $ request , MapEntity $ options , string $ name ): false |object |null
126
+ private function find (ObjectManager $ objectManager , Request $ request , MapEntity $ options , string $ name ): false |object |null
119
127
{
120
128
if ($ options ->mapping || $ options ->exclude ) {
121
129
return false ;
@@ -126,16 +134,15 @@ private function find(string $class, Request $request, MapEntity $options, strin
126
134
return $ id ;
127
135
}
128
136
129
- $ objectManager = $ this ->getManager ($ options ->objectManager , $ class );
130
137
if ($ options ->evictCache && $ objectManager instanceof EntityManagerInterface) {
131
138
$ cacheProvider = $ objectManager ->getCache ();
132
- if ($ cacheProvider && $ cacheProvider ->containsEntity ($ class , $ id )) {
133
- $ cacheProvider ->evictEntity ($ class , $ id );
139
+ if ($ cacheProvider && $ cacheProvider ->containsEntity ($ options -> class , $ id )) {
140
+ $ cacheProvider ->evictEntity ($ options -> class , $ id );
134
141
}
135
142
}
136
143
137
144
try {
138
- return $ objectManager ->getRepository ($ class )->find ($ id );
145
+ return $ objectManager ->getRepository ($ options -> class )->find ($ id );
139
146
} catch (NoResultException |ConversionException ) {
140
147
return null ;
141
148
}
@@ -162,40 +169,55 @@ private function getIdentifier(Request $request, MapEntity $options, string $nam
162
169
}
163
170
164
171
if ($ request ->attributes ->has ($ name )) {
165
- return $ request ->attributes ->get ($ name );
172
+ return $ request ->attributes ->get ($ name ) ?? ( $ options -> stripNull ? false : null ) ;
166
173
}
167
174
168
175
if (!$ options ->id && $ request ->attributes ->has ('id ' )) {
169
- return $ request ->attributes ->get ('id ' );
176
+ return $ request ->attributes ->get ('id ' ) ?? ( $ options -> stripNull ? false : null ) ;
170
177
}
171
178
172
179
return false ;
173
180
}
174
181
175
- private function findOneBy (string $ class , Request $ request , MapEntity $ options ): false |object |null
182
+ private function findOneBy (ObjectManager $ objectManager , Request $ request , MapEntity $ options ): false |object |null
183
+ {
184
+ if (!$ criteria = $ this ->getCriteria ($ request , $ options , $ objectManager )) {
185
+ return false ;
186
+ }
187
+
188
+ try {
189
+ return $ objectManager ->getRepository ($ options ->class )->findOneBy ($ criteria );
190
+ } catch (NoResultException |ConversionException ) {
191
+ return null ;
192
+ }
193
+ }
194
+
195
+ private function getCriteria (Request $ request , MapEntity $ options , ObjectManager $ objectManager ): array
176
196
{
177
197
if (null === $ mapping = $ options ->mapping ) {
178
- $ keys = $ request ->attributes ->keys ();
179
- $ mapping = $ keys ? array_combine ($ keys , $ keys ) : [];
198
+ $ mapping = $ request ->attributes ->keys ();
199
+ }
200
+
201
+ if ($ mapping && \is_array ($ mapping ) && array_is_list ($ mapping )) {
202
+ $ mapping = array_combine ($ mapping , $ mapping );
180
203
}
181
204
182
205
foreach ($ options ->exclude as $ exclude ) {
183
206
unset($ mapping [$ exclude ]);
184
207
}
185
208
186
209
if (!$ mapping ) {
187
- return false ;
210
+ return [] ;
188
211
}
189
212
190
213
// if a specific id has been defined in the options and there is no corresponding attribute
191
214
// return false in order to avoid a fallback to the id which might be of another object
192
215
if (\is_string ($ options ->id ) && null === $ request ->attributes ->get ($ options ->id )) {
193
- return false ;
216
+ return [] ;
194
217
}
195
218
196
219
$ criteria = [];
197
- $ objectManager = $ this ->getManager ($ options ->objectManager , $ class );
198
- $ metadata = $ objectManager ->getClassMetadata ($ class );
220
+ $ metadata = $ objectManager ->getClassMetadata ($ options ->class );
199
221
200
222
foreach ($ mapping as $ attribute => $ field ) {
201
223
if (!$ metadata ->hasField ($ field ) && (!$ metadata ->hasAssociation ($ field ) || !$ metadata ->isSingleValuedAssociation ($ field ))) {
@@ -209,34 +231,26 @@ private function findOneBy(string $class, Request $request, MapEntity $options):
209
231
$ criteria = array_filter ($ criteria , static fn ($ value ) => null !== $ value );
210
232
}
211
233
212
- if (!$ criteria ) {
213
- return false ;
214
- }
215
-
216
- try {
217
- return $ objectManager ->getRepository ($ class )->findOneBy ($ criteria );
218
- } catch (NoResultException |ConversionException ) {
219
- return null ;
220
- }
234
+ return $ criteria ;
221
235
}
222
236
223
- private function findViaExpression (string $ class , Request $ request, string $ expression , MapEntity $ options ): ?object
237
+ private function findViaExpression (ObjectManager $ objectManager , Request $ request , MapEntity $ options ): ?object
224
238
{
225
239
if (!$ this ->expressionLanguage ) {
226
240
throw new \LogicException (sprintf ('You cannot use the "%s" if the ExpressionLanguage component is not available. Try running "composer require symfony/expression-language". ' , __CLASS__ ));
227
241
}
228
242
229
- $ repository = $ this -> getManager ($ options ->objectManager , $ class )-> getRepository ( $ class );
243
+ $ repository = $ objectManager -> getRepository ($ options ->class );
230
244
$ variables = array_merge ($ request ->attributes ->all (), ['repository ' => $ repository ]);
231
245
232
246
try {
233
- return $ this ->expressionLanguage ->evaluate ($ expression , $ variables );
247
+ return $ this ->expressionLanguage ->evaluate ($ options -> expr , $ variables );
234
248
} catch (NoResultException |ConversionException ) {
235
249
return null ;
236
250
}
237
251
}
238
252
239
- private function getOptions (ArgumentMetadata $ argument ): MapEntity
253
+ private function getMapEntityAttribute (ArgumentMetadata $ argument ): MapEntity
240
254
{
241
255
/** @var MapEntity $options */
242
256
$ options = $ argument ->getAttributes (MapEntity::class, ArgumentMetadata::IS_INSTANCEOF )[0 ] ?? $ this ->defaults ;
0 commit comments