8000 Merge branch '4.4' into 5.4 · symfony/symfony@01f2ace · GitHub
[go: up one dir, main page]

Skip to content

Commit 01f2ace

Browse files
committed
Merge branch '4.4' into 5.4
* 4.4: [Form] Fix same choice loader with different choice values [Filesystem] Safeguard (sym)link calls
2 parents 1a010a5 + 2ec626f commit 01f2ace

File tree

8 files changed

+101
-26
lines changed

8 files changed

+101
-26
lines changed

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

Lines 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/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,4 +1779,32 @@ public function testSubmitNullMultipleUsesDefaultEmptyData()
17791779
$this->assertEquals($collection, $form->getNormData());
17801780
$this->assertEquals($collection, $form->getData());
17811781
}
1782+
1783+
public function testWithSameLoaderAndDifferentChoiceValueCallbacks()
1784+
{
1785+
$entity1 = new SingleIntIdEntity(1, 'Foo');
1786+
$entity2 = new SingleIntIdEntity(2, 'Bar');
1787+
$this->persist([$entity1, $entity2]);
1788+
1789+
$view = $this->factory->create(FormTypeTest::TESTED_TYPE)
1790+
->add('entity_one', self::TESTED_TYPE, [
1791+
'em' => 'default',
1792+
'class' => self::SINGLE_IDENT_CLASS,
1793+
])
1794+
->add('entity_two', self::TESTED_TYPE, [
1795+
'em' => 'default',
1796+
'class' => self::SINGLE_IDENT_CLASS,
1797+
'choice_value' => function ($choice) {
1798+
return $choice ? $choice->name : '';
1799+
},
1800+
])
1801+
->createView()
1802+
;
1803+
1804+
$this->assertSame('1', $view['entity_one']->vars['choices'][1]->value);
1805+
$this->assertSame('2', $view['entity_one']->vars['choices'][2]->value);
1806+
1807+
$this->assertSame('Foo', $view['entity_two']->vars['choices']['Foo']->value);
1808+
$this->assertSame('Bar', $view['entity_two']->vars['choices']['Bar']->value);
1809+
}
17821810
}

src/Symfony/Component/Filesystem/Filesystem.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,8 @@ private function isReadable(string $filename): bool
329329
*/
330330
public function symlink(string $originDir, string $targetDir, bool $copyOnWindows = false)
331331
{
332+
self::assertFunctionExists('symlink');
333+
332334
if ('\\' === \DIRECTORY_SEPARATOR) {
333335
$originDir = strtr($originDir, '/', '\\');
334336
$targetDir = strtr($targetDir, '/', '\\');
@@ -364,6 +366,8 @@ public function symlink(string $originDir, string $targetDir, bool $copyOnWindow
364366
*/
365367
public function hardlink(string $originFile, $targetFiles)
366368
{
369+
self::assertFunctionExists('link');
370+
367371
if (!$this->exists($originFile)) {
368372
throw new FileNotFoundException(null, 0, null, $originFile);
369373
}
@@ -730,13 +734,22 @@ private function getSchemeAndHierarchy(string $filename): array
730734
return 2 === \count($components) ? [$components[0], $components[1]] : [null, $components[0]];
731735
}
732736

737+
private static function assertFunctionExists(string $func): void
738+
{
739+
if (!\function_exists($func)) {
740+
throw new IOException(sprintf('Unable to perform filesystem operation because the "%s()" function has been disabled.', $func));
741+
}
742+
}
743+
733744
/**
734745
* @param mixed ...$args
735746
*
736747
* @return mixed
737748
*/
738-
private static function box(callable $func, ...$args)
749+
private static function box(string $func, ...$args)
739750
{
751+
self::assertFunctionExists($func);
752+
740753
self::$lastError = null;
741754
set_error_handler(__CLASS__.'::handleError');
742755
try {

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

Lines 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 iterable|null
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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public function testGetChoiceLoadersLoadsLoadedListOnFirstCall()
3232

3333
$this->assertSame(['RESULT'], $list->getChoices());
3434
$this->assertSame(['RESULT'], $list->getChoices());
35-
$this->assertSame(1, $calls);
35+
$this->assertSame(2, $calls);
3636
}
3737

3838
public function testGetValuesLoadsLoadedListOnFirstCall()
@@ -46,7 +46,7 @@ public function testGetValuesLoadsLoadedListOnFirstCall()
4646

4747
$this->assertSame(['RESULT'], $list->getValues());
4848
$this->assertSame(['RESULT'], $list->getValues());
49-
$this->assertSame(1, $calls);
49+
$this->assertSame(2, $calls);
5050
}
5151

5252
public function testGetStructuredValuesLoadsLoadedListOnFirstCall()
@@ -60,7 +60,7 @@ public function testGetStructuredValuesLoadsLoadedListOnFirstCall()
6060

6161
$this->assertSame(['RESULT'], $list->getStructuredValues());
6262
$this->assertSame(['RESULT'], $list->getStructuredValues());
63-
$this->assertSame(1, $calls);
63+
$this->assertSame(2, $calls);
6464
}
6565

6666
public function testGetOriginalKeysLoadsLoadedListOnFirstCall()
@@ -79,7 +79,7 @@ public function testGetOriginalKeysLoadsLoadedListOnFirstCall()
7979

8080
$this->assertSame(['foo' => 'a', 'bar' => 'b', 'baz' => 'c'], $list->getOriginalKeys());
8181
$this->assertSame(['foo' => 'a', 'bar' => 'b', 'baz' => 'c'], $list->getOriginalKeys());
82-
$this->assertSame(3, $calls);
82+
$this->assertSame(6, $calls);
8383
}
8484

8585
public function testGetChoicesForValuesForwardsCallIfListNotLoaded()
@@ -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

Lines 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

Lines 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

Lines 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