8000 [Form] add `CallbackChoiceLoader` · symfony/symfony@dc303ff · GitHub
[go: up one dir, main page]

Skip to content

Commit dc303ff

Browse files
committed
[Form] add CallbackChoiceLoader
1 parent b44abe3 commit dc303ff

File tree

3 files changed

+181
-1
lines changed

3 files changed

+181
-1
lines changed

src/Symfony/Component/Form/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ CHANGELOG
77
* deprecated the "choices_as_values" option of ChoiceType
88
* deprecated support for data objects that implements both `Traversable` and
99
`ArrayAccess` in `ResizeFormListener::preSubmit` method
10-
1110
* Using callable strings as choice options in `ChoiceType` has been deprecated
1211
and will be used as `PropertyPath` instead of callable in Symfony 4.0.
12+
* added `CallbackChoiceLoader`
1313

1414
3.0.0
1515
-----
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Form\ChoiceList\Loader;
13+
14+
use Symfony\Component\Form\ChoiceList\ArrayChoiceList;
15+
16+
/**
17+
* Loads a {@link ArrayChoiceList} interface from any callable.
18+
*
19+
* @author Jules Pietri <jules@heahprod.com>
20+
*/
21+
class CallbackChoiceLoader implements ChoiceLoaderInterface
22+
{
23+
/**
24+
* The callable used to load the array of choices.
25+
*
26+
* @var callable
27+
*/
28+
private $callback;
29+
30+
/**
31+
* The loaded choice list.
32+
*
33+
* @var ArrayChoiceList
34+
*/
35+
private $choiceList;
36+
37+
public function __construct(callable $callback)
38+
{
39+
$this->callback = $callback;
40+
}
41+
42+
/**
43+
* {@inheritdoc}
44+
*/
45+
public function loadChoiceList($value = null)
46+
{
47+
if (null !== $this->choiceList) {
48+
return $this->choiceList;
49+
}
50+
51+
return $this->choiceList = new ArrayChoiceList(call_user_func($this->callback), $value);
52+
}
53+
54+
/**
55+
* {@inheritdoc}
56+
*/
57+
public function loadChoicesForValues(array $values, $value = null)
58+
{
59+
// Optimize
60+
if (empty($values)) {
61+
return array();
62+
}
63+
64+
return $this->loadChoiceList($value)->getChoicesForValues($values);
65+
}
66+
67+
/**
68+
* {@inheritdoc}
69+
*/
70+
public function loadValuesForChoices(array $choices, $value = null)
71+
{
72+
// Optimize
73+
if (empty($choices)) {
74+
return array();
75+
}
76+
77+
return $this->loadChoiceList($value)->getValuesForChoices($choices);
78+
}
79+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Form\Tests\ChoiceList\Loader;
13+
14+
use Symfony\Component\Form\ChoiceList\LazyChoiceList;
15+
use Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader;
16+
17+
/**
18+
* @author Jules Pietri <jules@heahprod.com>
19+
*/
20+
class CallbackChoiceLoaderTest extends \PHPUnit_Framework_TestCase
21+
{
22+
/**
23+
* @var \Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader
24+
*/
25+
static private $loader;
26+
27+
/**
28+
* @var callable
29+
*/
30+
static private $value;
31+
32+
/**
33+
* @var array
34+
*/
35+
static private $choices;
36+
37+
/**
38+
* @var string[]
39+
*/
40+
static private $choiceValues;
41+
42+
/**
43+
* @var \Symfony\Component\Form\ChoiceList\LazyChoiceList
44+
*/
45+
static private $lazyChoiceList;
46+
47+
static public function setUpBeforeClass()
48+
{
49+
self::$loader = new CallbackChoiceLoader(function() {
50+
return self::$choices;
51+
});
52+
self::$value = function ($choice) {
53+
return isset($choice->value) ? $choice->value : null;
54+
};
55+
self::$choices = array(
56+
(object) array('value' => 'choice_one'),
57+
(object) array('value' => 'choice_two'),
58+
);
59+
self::$choiceValues = array('choice_one', 'choice_two');
60+
self::$lazyChoiceList = new LazyChoiceList(self::$loader, self::$value);
61+
}
62+
63+
public function testLoadChoiceList()
64+
{
65+
$this->assertInstanceOf('\Symfony\Component\Form\ChoiceList\ChoiceListInterface', self::$loader->loadChoiceList(self::$value));
66+
}
67+
68+
public function testLoadChoiceListOnlyOnce()
69+
{
70+
$loadedChoiceList = self::$loader->loadChoiceList(self::$value);
71+
72+
$this->assertSame($loadedChoiceList, self::$loader->loadChoiceList(self::$value));
73+
}
74+
75+
public function testLoadChoicesForValuesLoadsChoiceListOnFirstCall()
76+
{
77+
$this->assertSame(
78+
self::$loader->loadChoicesForValues(self::$choiceValues, self::$value),
79+
self::$lazyChoiceList->getChoicesForValues(self::$choiceValues),
80+
'Choice list should not be reloaded.'
81+
);
82+
}
83+
84+
public function testLoadValuesForChoicesLoadsChoiceListOnFirstCall()
85+
{
86+
$this->assertSame(
87+
self::$loader->loadValuesForChoices(self::$choices, self::$value),
88+
self::$lazyChoiceList->getValuesForChoices(self::$choices),
89+
'Choice list should not be reloaded.'
90+
);
91+
}
92+
93+
static public function tearDownAfterClass()
94+
{
95+
self::$loader = null;
96+
self::$value = null;
97+
self::$choices = array();
98+
self::$choiceValues = array();
99+
self::$lazyChoiceList = null;
100+
}
101+
}

0 commit comments

Comments
 (0)
0