8000 tmp · symfony/symfony@528f9f3 · GitHub
[go: up one dir, main page]

Skip to content

Commit 528f9f3

Browse files
committed
tmp
1 parent 07b498c commit 528f9f3

File tree

3 files changed

+75
-13
lines changed

3 files changed

+75
-13
lines changed

src/Symfony/Bridge/Doctrine/Form/ChoiceList/DoctrineChoiceLoader.php

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,26 @@ protected function loadChoices(): iterable
6060
;
6161
}
6262

63+
/**
64+
* This method is here for legacy.
65+
*
66+
* To remove in 6.0
67+
*/
6368
protected function doLoadValuesForChoices(array $choices): array
6469
{
70+
// Optimize performance for single-field identifiers. We already
71+
// know that the IDs are used as values
72+
// Attention: This optimization does not check choices for existence
6573
if ($this->idReader) {
66-
return array_filter(array_map(function ($choice): ?string {
67-
return $choice instanceof $this->class ? $this->idReader->getIdValue($choice) : null;
68-
}, $choices));
74+
@trigger_error(sprintf('Not defining explicitly the IdReader as value callback when query can be optimized has been deprecated in 5.1. Don\'t pass the IdReader to "%s" or define the "choice_value" option instead.', __CLASS__), E_USER_DEPRECATED);
75+
// Maintain order and indices of the given objects
76+
foreach ($choices as $i => $object) {
77+
if ($object instanceof $this->class) {
78+
$values[$i] = $this->idReader->getIdValue($object);
79+
}
80+
}
81+
82+
return $values ?? [];
6983
}
7084

7185
return parent::doLoadValuesForChoices($choices);
@@ -76,13 +90,16 @@ protected function doLoadValuesForChoices(array $choices): array
7690
*/
7791
protected function doLoadChoicesForValues(array $values, ?callable $value): array
7892
{
93+
$legacy = $this->idReader && null === $value;
94+
95+
if ($legacy) {
96+
@trigger_error(sprintf('Not defining explicitly the IdReader as value callback when query can be optimized has been deprecated in 5.1. Don\'t pass the IdReader to "%s" or define the choice_value instead.', __CLASS__), E_USER_DEPRECATED);
97+
}
98+
7999
// Optimize performance in case we have an object loader and
80100
// a single-field identifier
81-
$optimize = $this->idReader && (null === $value || (\is_array($value) && $this->idReader === $value[0]));
82-
83-
if ($optimize && $this->objectLoader) {
101+
if (($legacy || \is_array($value) && $this->idReader === $value[0]) && $this->objectLoader) {
84102
$objectsById = [];
85-
$objects = [];
86103

87104
// Maintain order and indices from the given $values
88105
// An alternative approach to the following loop is to add the
@@ -98,7 +115,7 @@ protected function doLoadChoicesForValues(array $values, ?callable $value): arra
98115
}
99116
}
100117

101-
return $objects;
118+
return $objects ?? [];
102119
}
103120

104121
return parent::doLoadChoicesForValues($values, $value);

src/Symfony/Bridge/Doctrine/Form/ChoiceList/IdReader.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,12 @@ public function isIntId(): bool
8484
*
8585
* This method assumes that the object has a single-column ID.
8686
*
87-
* @return string|null The ID value
87+
* @return string The ID value
8888
*/
8989
public function getIdValue(object $object = null)
9090
{
9191
if (!$object) {
92-
return null;
92+
return '';
9393
}
9494

9595
if (!$this->om->contains($object)) {

src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/DoctrineChoiceLoaderTest.php

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,11 @@ public function testLoadValuesForChoicesDoesNotLoadIfEmptyChoices()
190190
$this->assertSame([], $loader->loadValuesForChoices([]));
191191
}
192192

193+
/**
194+
* @group legacy
195+
*
196+
* @expectedDeprecation Not defining explicitly the IdReader as value callback when query can be optimized has been deprecated in 5.1. Don't pass the IdReader to "Symfony\Bridge\Doctrine\Form\ChoiceList\DoctrineChoiceLoader" or define the "choice_value" option instead.
197+
*/
193198
public function testLoadValuesForChoicesDoesNotLoadIfSingleIntId()
194199
{
195200
$loader = new DoctrineChoiceLoader(
@@ -258,8 +263,7 @@ public function testLoadChoicesForValues()
258263
{
259264
$loader = new DoctrineChoiceLoader(
260265
$this->om,
261-
$this->class,
262-
$this->idReader
266+
$this->class
263267
);
264268

265269
$choices = [$this->obj1, $this->obj2, $this->obj3];
@@ -289,7 +293,12 @@ public function testLoadChoicesForValuesDoesNotLoadIfEmptyValues()
289293
$this->assertSame([], $loader->loadChoicesForValues([]));
290294
}
291295

292-
public function testLoadChoicesForValuesLoadsOnlyChoicesIfValueUseIdReader()
296+
/**
297+
* @group legacy
298+
*
299+
* @expectedDeprecation Not defining explicitly the IdReader as value callback when query can be optimized has been deprecated in 5.1. Don't pass the IdReader to "Symfony\Bridge\Doctrine\Form\ChoiceList\DoctrineChoiceLoader" or define the choice_value instead.
300+
*/
301+
public function legacyTestLoadChoicesForValuesLoadsOnlyChoicesIfValueUseIdReader()
293302
{
294303
$loader = new DoctrineChoiceLoader(
295304
$this->om,
@@ -325,6 +334,42 @@ public function testLoadChoicesForValuesLoadsOnlyChoicesIfValueUseIdReader()
325334
));
326335
}
327336

337+
public function testLoadChoicesForValuesLoadsOnlyChoicesIfValueUseIdReader()
338+
{
339+
$loader = new DoctrineChoiceLoader(
340+
$this->om,
341+
$this->class,
342+
$this->idReader,
343+
$this->objectLoader
344+
);
345+
346+
$choices = [$this->obj2, $this->obj3];
347+
348+
$this->idReader->expects($this->any())
349+
->method('getIdField')
350+
->willReturn('idField');
351+
352+
$this->repository->expects($this->never())
353+
->method('findAll');
354+
355+
$this->objectLoader->expects($this->once())
356+
->method('getEntitiesByIds')
357+
->with('idField', [4 => '3', 7 => '2'])
358+
->willReturn($choices);
359+
360+
$this->idReader->expects($this->any())
361+
->method('getIdValue')
362+
->willReturnMap([
363+
[$this->obj2, '2'],
364+
[$this->obj3, '3'],
365+
]);
366+
367+
$this->assertSame(
368+
[4 => $this->obj3, 7 => $this->obj2],
369+
$loader->loadChoicesForValues([4 => '3', 7 => '2'], [$this->idReader, 'getIdValue']
370+
));
371+
}
372+
328373
public function testLoadChoicesForValuesLoadsAllIfSingleIntIdAndValueGiven()
329374
{
330375
$loader = new DoctrineChoiceLoader(

0 commit comments

Comments
 (0)
0