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

Skip to content

Commit 39e937f

Browse files
committed
[Form] add CallbackChoiceLoader
1 parent 8acc601 commit 39e937f

File tree

3 files changed

+272
-0
lines changed

3 files changed

+272
-0
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
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 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+
if (null === $this->choiceList) {
65+
$this->loadChoiceList($value);
66+
}
67+
68+
return $this->choiceList->getChoicesForValues($values);
69+
}
70+
71+
/**
72+
* {@inheritdoc}
73+
*/
74+
public function loadValuesForChoices(array $choices, $value = null)
75+
{
76+
// Optimize
77+
if (empty($choices)) {
78+
return array();
79+
}
80+
81+
if (null === $this->choiceList) {
82+
$this->loadChoiceList($value);
83+
}
84+
85+
return $this->choiceList->getValuesForChoices($choices);
86+
}
87+
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
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+
16+
/**
17+
* @author Jules Pietri <jules@heahprod.com>
18+
*/
19+
abstract class AbstractChoiceLoaderTest extends \PHPUnit_Framework_TestCase
20+
{
21+
/**
22+
* @var \Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface
23+
*/
24+
private $loader;
25+
26+
/**
27+
* @var null|callable
28+
*/
29+
private $value;
30+
31+
/**
32+
* @var array||Traversable
33+
*/
34+
private $choices;
35+
36+
/**
37+
* @var string[]
38+
*/
39+
private $choiceValues;
40+
41+
/**
42+
* @var \Symfony\Component\Form\ChoiceList\LazyChoiceList
43+
*/
44+
private $lazyChoiceList;
45+
46+
protected function setUp()
47+
{
48+
parent::setUp();
49+
50+
$this->loader = $this->createChoiceLoader();
51+
$this->value = $this->getValue();
52+
$this->choices = $this->getChoices();
53+
$this->choiceValues = $this->getChoiceValues();
54+
$this->lazyChoiceList = new LazyChoiceList($this->loader, $this->value);
55+
}
56+
57+
public function testLoadChoiceList()
58+
{
59+
$this->assertInstanceOf('\Symfony\Component\Form\ChoiceList\ChoiceListInterface', $this->loader->loadChoiceList($this->value));
60+
}
61+
62+
public function testLoadChoiceListOnlyOnce()
63+
{
64+
$loadedChoiceList = $this->loader->loadChoiceList($this->value);
65+
66+
$this->assertSame($loadedChoiceList, $this->loader->loadChoiceList($this->value));
67+
}
68+
69+
public function testLoadChoicesForValuesLoadsChoiceListOnFirstCall()
70+
{
71+
$this->assertSame(
72+
$this->loader->loadChoicesForValues($this->choiceValues, $this->value),
73+
$this->lazyChoiceList->getChoicesForValues($this->choiceValues),
74+
'Choice list should not be reloaded.'
75+
);
76+
}
77+
78+
public function testLoadValuesForChoicesLoadsChoiceListOnFirstCall()
79+
{
80+
$this->assertSame(
81+
$this->loader->loadValuesForChoices($this->choices, $this->value),
82+
$this->lazyChoiceList->getValuesForChoices($this->choices),
83+
'Choice list should not be reloaded.'
84+
);
85+
}
86+
87+
protected function tearDown()
88+
{
89+
parent::tearDown();
90+
91+
$this->loader = null;
92+
$this->value = null;
93+
$this->choices = array();
94+
$this->choiceValues = array();
95+
$this->lazyChoiceList = null;
96+
}
97+
98+
/**
99+
* @return \Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface
100+
*/
101+
abstract protected function createChoiceLoader();
102+
103+
/**
104+
* @return null|callable
105+
*/
106+
abstract protected function getValue();
107+
108+
/**
109+
* @return array|\Traversable
110+
*/
111+
abstract protected function getChoices();
112+
113+
/**
114+
* @return string[]
115+
*/
116+
abstract protected function getChoiceValues();
117+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
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\Loader\CallbackChoiceLoader;
15+
16+
/**
17+
* @author Jules Pietri <jules@heahprod.com>
18+
*/
19+
class CallbackChoiceLoaderTest extends AbstractChoiceLoaderTest
20+
{
21+
protected function setUp()
22+
{
23+
parent::setUp();
24+
}
25+
26+
protected function tearDown()
27+
{
28+
parent::tearDown();
29+
}
30+
31+
/**
32+
* @return \Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface
33+
*/
34+
protected function createChoiceLoader()
35+
{
36+
return new CallbackChoiceLoader(function() {
37+
return $this->getChoices();
38+
});
39+
}
40+
41+
/**
42+
* @return null|callable
43+
*/
44+
protected function getValue() {
45+
return function ($choice) {
46+
return isset($choice->value) ? $choice->value : null;
47+
};
48+
}
49+
50+
/**
51+
* @return array|\Traversable
52+
*/
53+
protected function getChoices()
54+
{
55+
return array(
56+
(object) array('value' => 'choice_one'),
57+
(object) array('value' => 'choice_two'),
58+
);
59+
}
60+
61+
/**
62+
* @return string[]
63+
*/
64+
protected function getChoiceValues()
65+
{
66+
return array('choice_one', 'choice_two');
67+
}
68+
}

0 commit comments

Comments
 (0)
0