Skip to content

Navigation Menu

Sign in
Appearance settings

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 d835acc

Browse filesBrowse files
committed
[Form] Fix same choice loader with different choice values
1 parent a9b9bd1 commit d835acc
Copy full SHA for d835acc

File tree

7 files changed

+88
-25
lines changed
Filter options

7 files changed

+88
-25
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/DoctrineChoiceLoaderTest.php
+1-2Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,7 @@ public function testLoadChoiceListUsesObjectLoaderIfAvailable()
152152
$this->assertEquals($choiceList, $loaded = $loader->loadChoiceList());
153153

154154
// no further loads on subsequent calls
155-
156-
$this->assertSame($loaded, $loader->loadChoiceList());
155+
$this->assertEquals($loaded, $loader->loadChoiceList());
157156
}
158157

159158
public function testLoadValuesForChoices()

‎src/Symfony/Component/Form/ChoiceList/LazyChoiceList.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/ChoiceList/LazyChoiceList.php
+33-4Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ class LazyChoiceList implements ChoiceListInterface
3838
*/
3939
private $value;
4040

41+
/**
42+
* @var ChoiceListInterface|null
43+
*/
44+
private $loadedList;
45+
4146
/**
4247
* Creates a lazily-loaded list using the given loader.
4348
*
@@ -58,38 +63,58 @@ public function __construct(ChoiceLoaderInterface $loader, callable $value = nul
5863
*/
5964
public function getChoices()
6065
{
61-
return $this->loader->loadChoiceList($this->value)->getChoices();
66+
if ($this->loadedList) {
67+
return $this->loadedList->getChoices();
68+
}
69+
70+
return ($this->loadedList = $this->loader->loadChoiceList($this->value))->getChoices();
6271
}
6372

6473
/**
6574
* {@inheritdoc}
6675
*/
6776
public function getValues()
6877
{
69-
return $this->loader->loadChoiceList($this->value)->getValues();
78+
if ($this->loadedList) {
79+
return $this->loadedList->getValues();
80+
}
81+
82+
return ($this->loadedList = $this->loader->loadChoiceList($this->value))->getValues();
7083
}
7184

7285
/**
7386
* {@inheritdoc}
7487
*/
7588
public function getStructuredValues()
7689
{
77-
return $this->loader->loadChoiceList($this->value)->getStructuredValues();
90+
if ($this->loadedList) {
91+
return $this->loadedList->getStructuredValues();
92+
}
93+
94+
return ($this->loadedList = $this->loader->loadChoiceList($this->value))->getStructuredValues();
7895
}
7996

8097
/**
8198
* {@inheritdoc}
8299
*/
83100
public function getOriginalKeys()
84101
{
85-
return $this->loader->loadChoiceList($this->value)->getOriginalKeys();
102+
if ($this->loadedList) {
103+
return $this->loadedList->getOriginalKeys();
104+
}
105+
106+
return ($this->loadedList = $this->loader->loadChoiceList($this->value))->getOriginalKeys();
86107
}
87108

88109
/**
89110
* {@inheritdoc}
90111
*/
91112
public function getChoicesForValues(array $values)
92113
{
114+
if ($this->loadedList) {
115+
return $this->loadedList->getChoicesForValues($values);
116+
}
117+
93118
return $this->loader->loadChoicesForValues($values, $this->value);
94119
}
95120

@@ -98,6 +123,10 @@ public function getChoicesForValues(array $values)
98123
*/
99124
public function getValuesForChoices(array $choices)
100125
{
126+
if ($this->loadedList) {
127+
return $this->loadedList->getValuesForChoices($choices);
128+
}
129+
101130
return $this->loader->loadValuesForChoices($choices, $this->value);
102131
}
103132
}

‎src/Symfony/Component/Form/ChoiceList/Loader/AbstractChoiceLoader.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/ChoiceList/Loader/AbstractChoiceLoader.php
+4-12Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@
2020
abstract class AbstractChoiceLoader implements ChoiceLoaderInterface
2121
{
2222
/**
23-
* The loaded choice list.
23+
* The loaded choices.
2424
*
25-
* @var ArrayChoiceList
25+
* @var array
2626
*/
27-
private $choiceList;
27+
private $choices;
2828

2929
/**
3030
* @final
@@ -33,7 +33,7 @@ abstract class AbstractChoiceLoader implements ChoiceLoaderInterface
3333
*/
3434
public function loadChoiceList(callable $value = null): ChoiceListInterface
3535
{
36-
return $this->choiceList ?? ($this->choiceList = new ArrayChoiceList($this->loadChoices(), $value));
36+
return new ArrayChoiceList($this->choices ?? $this->choices = $this->loadChoices(), $value);
3737
}
3838

3939
/**
@@ -45,10 +45,6 @@ public function loadChoicesForValues(array $values, callable $value = null)
4545
return [];
4646
}
4747

48-
if ($this->choiceList) {
49-
return $this->choiceList->getChoicesForValues($values);
50-
}
51-
5248
return $this->doLoadChoicesForValues($values, $value);
5349
}
5450

@@ -66,10 +62,6 @@ public function loadValuesForChoices(array $choices, callable $value = null)
6662
return array_map($value, $choices);
6763
}
6864

69-
if ($this->choiceList) {
70-
return $this->choiceList->getValuesForChoices($choices);
71-
}
72-
7365
return $this->doLoadValuesForChoices($choices);
7466
}
7567

‎src/Symfony/Component/Form/Tests/ChoiceList/LazyChoiceListTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Tests/ChoiceList/LazyChoiceListTest.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public function testGetChoicesForValuesForwardsCallIfListNotLoaded()
9898

9999
$this->assertSame(['foo', 'bar'], $list->getChoicesForValues(['a', 'b']));
100100
$this->assertSame(['foo', 'bar'], $list->getChoicesForValues(['a', 'b']));
101-
$this->assertSame(3, $calls);
101+
$this->assertSame(6, $calls);
102102
}
103103

104104
public function testGetChoicesForValuesUsesLoadedList()

‎src/Symfony/Component/Form/Tests/ChoiceList/Loader/CallbackChoiceLoaderTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Tests/ChoiceList/Loader/CallbackChoiceLoaderTest.php
+10-3Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,18 @@ public function testLoadChoiceList()
6767
$this->assertInstanceOf(ChoiceListInterface::class, self::$loader->loadChoiceList(self::$value));
6868
}
6969

70-
public function testLoadChoiceListOnlyOnce()
70+
public function testLoadChoicesOnlyOnce()
7171
{
72-
$loadedChoiceList = self::$loader->loadChoiceList(self::$value);
72+
$calls = 0;
73+
$loader = new CallbackChoiceLoader(function () use (&$calls) {
74+
++$calls;
7375

74-
$this->assertSame($loadedChoiceList, self::$loader->loadChoiceList(self::$value));
76+
return [1];
77+
});
78+
$loadedChoiceList = $loader->loadChoiceList();
79+
80+
$this->assertNotSame($loadedChoiceList, $loader->loadChoiceList());
81+
$this->assertSame(1, $calls);
7582
}
7683

7784
public function testLoadChoicesForValuesLoadsChoiceListOnFirstCall()

‎src/Symfony/Component/Form/Tests/ChoiceList/Loader/IntlCallbackChoiceLoaderTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Tests/ChoiceList/Loader/IntlCallbackChoiceLoaderTest.php
+11-3Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,19 @@ public function testLoadChoiceList()
6868
$this->assertInstanceOf(ChoiceListInterface::class, self::$loader->loadChoiceList(self::$value));
6969
}
7070

71-
public function testLoadChoiceListOnlyOnce()
71+
public function testLoadChoicesOnlyOnce()
7272
{
73-
$loadedChoiceList = self::$loader->loadChoiceList(self::$value);
73+
$calls = 0;
74+
$loader = new IntlCallbackChoiceLoader(function () use (&$calls) {
75+
++$calls;
7476

75-
$this->assertSame($loadedChoiceList, self::$loader->loadChoiceList(self::$value));
77+
return self::$choices;
78+
});
79+
80+
$loadedChoiceList = $loader->loadChoiceList(self::$value);
81+
82+
$this->assertNotSame($loadedChoiceList, $loader->loadChoiceList(self::$value));
83+
$this->assertSame(1, $calls);
7684
}
7785

7886
public function testLoadChoicesForValuesLoadsChoiceListOnFirstCall()

‎src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php
+28Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2264,4 +2264,32 @@ public function testUsingDeprecatedChoiceListFactory()
22642264

22652265
new ChoiceType(new DeprecatedChoiceListFactory());
22662266
}
2267+
2268+
public function testWithSameLoaderAndDifferentChoiceValueCallbacks()
2269+
{
2270+
$choiceLoader = new CallbackChoiceLoader(function () {
2271+
return [1, 2, 3];
2272+
});
2273+
2274+
$view = $this->factory->create(FormTypeTest::TESTED_TYPE)
2275+
->add('choice_one', self::TESTED_TYPE, [
2276+
'choice_loader' => $choiceLoader,
2277+
])
2278+
->add('choice_two', self::TESTED_TYPE, [
2279+
'choice_loader' => $choiceLoader,
2280+
'choice_value' => function ($choice) {
2281+
return $choice ? (string) $choice * 10 : '';
2282+
},
2283+
])
2284+
->createView()
2285+
;
2286+
2287+
$this->assertSame('1', $view['choice_one']->vars['choices'][0]->value);
2288+
$this->assertSame('2', $view['choice_one']->vars['choices'][1]->value);
2289+
$this->assertSame('3', $view['choice_one']->vars['choices'][2]->value);
2290+
2291+
$this->assertSame('10', $view['choice_two']->vars['choices'][0]->value);
2292+
$this->assertSame('20', $view['choice_two']->vars['choices'][1]->value);
2293+
$this->assertSame('30', $view['choice_two']->vars['choices'][2]->value);
2294+
}
22672295
}

0 commit comments

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