Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 068c12f

Browse filesBrowse files
[DoctrineBridge] Map entities by single-key when disabling auto-mapping
1 parent 069af99 commit 068c12f
Copy full SHA for 068c12f

File tree

3 files changed

+89
-2
lines changed
Filter options

3 files changed

+89
-2
lines changed

‎src/Symfony/Bridge/Doctrine/ArgumentResolver/EntityValueResolver.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Doctrine/ArgumentResolver/EntityValueResolver.php
+30-2
Original file line numberDiff line numberDiff line change
@@ -123,15 +123,21 @@ private function getIdentifier(Request $request, MapEntity $options, string $nam
123123
{
124124
if (\is_array($options->id)) {
125125
$id = [];
126+
$usedAttributes = [];
126127
foreach ($options->id as $field) {
127128
// Convert "%s_uuid" to "foobar_uuid"
128129
if (str_contains($field, '%s')) {
129130
$field = sprintf($field, $name);
130131
}
131132

133+
$usedAttributes[] = $field;
132134
$id[$field] = $request->attributes->get($field);
133135
}
134136

137+
if ($usedAttributes) {
138+
$request->attributes->set('_entity_used_attributes', array_merge($request->attributes->get('_entity_used_attributes') ?? [], $usedAttributes));
139+
}
140+
135141
return $id;
136142
}
137143

@@ -140,10 +146,14 @@ private function getIdentifier(Request $request, MapEntity $options, string $nam
140146
}
141147

142148
if ($request->attributes->has($name)) {
149+
$request->attributes->set('_entity_used_attributes', array_merge($request->attributes->get('_entity_used_attributes') ?? [], [$name]));
150+
143151
return $request->attributes->get($name) ?? ($options->stripNull ? false : null);
144152
}
145153

146154
if (!$options->id && $request->attributes->has('id')) {
155+
$request->attributes->set('_entity_used_attributes', array_merge($request->attributes->get('_entity_used_attributes') ?? [], ['id']));
156+
147157
return $request->attributes->get('id') ?? ($options->stripNull ? false : null);
148158
}
149159

@@ -152,11 +162,13 @@ private function getIdentifier(Request $request, MapEntity $options, string $nam
152162

153163
private function getCriteria(Request $request, MapEntity $options, ObjectManager $manager): array
154164
{
155-
if (null === $mapping = $options->mapping) {
165+
$singleKey = [] === $options->mapping;
166+
167+
if (!$mapping = $options->mapping) {
156168
$mapping = $request->attributes->keys();
157169
}
158170

159-
if ($mapping && \is_array($mapping) && array_is_list($mapping)) {
171+
if ($mapping && array_is_list($mapping)) {
160172
$mapping = array_combine($mapping, $mapping);
161173
}
162174

@@ -176,13 +188,29 @@ private function getCriteria(Request $request, MapEntity $options, ObjectManager
176188

177189
$criteria = [];
178190
$metadata = $manager->getClassMetadata($options->class);
191+
$usedAttributes = [];
192+
193+
if ($singleKey) {
194+
foreach ($request->attributes->get('_entity_used_attributes') ?? [] as $attribute) {
195+
unset($mapping[$attribute]);
196+
}
197+
}
179198

180199
foreach ($mapping as $attribute => $field) {
181200
if (!$metadata->hasField($field) && (!$metadata->hasAssociation($field) || !$metadata->isSingleValuedAssociation($field))) {
182201
continue;
183202
}
184203

204+
$usedAttributes[] = $attribute;
185205
$criteria[$field] = $request->attributes->get($attribute);
206+
207+
if ($singleKey) {
208+
break;
209+
}
210+
}
211+
212+
if ($usedAttributes) {
213+
$request->attributes->set('_entity_used_attributes', array_merge($request->attributes->get('_entity_used_attributes') ?? [], $usedAttributes));
186214
}
187215

188216
if ($options->stripNull) {

‎src/Symfony/Bridge/Doctrine/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Doctrine/CHANGELOG.md
+5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
7.1
5+
---
6+
7+
* Map entities by single-key when disabling auto-mapping
8+
49
7.0
510
---
611

‎src/Symfony/Bridge/Doctrine/Tests/ArgumentResolver/EntityValueResolverTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Doctrine/Tests/ArgumentResolver/EntityValueResolverTest.php
+54
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,60 @@ public function testResolveWithMappingAndExclude()
257257
$this->assertSame([$object], $resolver->resolve($request, $argument));
258258
}
259259

260+
public function testResolveWithMultipleEntitiesAndNoAutoMapping()
261+
{
262+
$manager = $this->getMockBuilder(ObjectManager::class)->getMock();
263+
$registry = $this->createRegistry($manager);
264+
$resolver = new EntityValueResolver($registry);
265+
266+
$request = new Request();
267+
$request->attributes->set('foo', 1);
268+
$request->attributes->set('bar', 2);
269+
270+
$argument1 = $this->createArgument('Foo', new MapEntity('Foo', mapping: []));
271+
$argument2 = $this->createArgument('Bar', new MapEntity('Bar', mapping: []));
272+
273+
$metadata1 = $this->getMockBuilder(ClassMetadata::class)->getMock();
274+
$metadata1->expects($this->once())
275+
->method('hasField')
276+
->with('foo')
277+
->willReturn(true);
278+
279+
$metadata2 = $this->getMockBuilder(ClassMetadata::class)->getMock();
280+
$metadata2->expects($this->once())
281+
->method('hasField')
282+
->with('bar')
283+
->willReturn(true);
284+
285+
$manager->expects($this->any())
286+
->method('getClassMetadata')
287+
->willReturnCallback(static fn ($v) => match ($v) {
288+
'Foo' => $metadata1,
289+
'Bar' => $metadata2,
290+
});
291+
292+
$object1 = new \stdClass();
293+
$object2 = new \stdClass();
294+
295+
$repository = $this->getMockBuilder(ObjectRepository::class)->getMock();
296+
$repository->expects($this->any())
297+
->method('findOneBy')
298+
->willReturnCallback(static fn ($v) => match ($v) {
299+
['foo' => 1] => $object1,
300+
['bar' => 2] => $object2,
301+
});
302+
303+
$manager->expects($this->any())
304+
->method('getRepository')
305+
->willReturn($repository);
306+
307+
$this->assertSame([$object1], $resolver->resolve($request, $argument1));
308+
$this->assertSame(['foo'], $request->attributes->get('_entity_used_attributes'));
309+
310+
$this->assertSame([$object2], $resolver->resolve($request, $argument2));
311+
$this->assertSame(['foo', 'bar'], $request->attributes->get('_entity_used_attributes'));
312+
}
313+
260314
public function testExceptionWithExpressionIfNoLanguageAvailable()
261315
{
262316
$manager = $this->getMockBuilder(ObjectManager::class)->getMock();

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.