From db9cf273c338a442976d9a61ac5fe59c9a447134 Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Mon, 16 Jul 2012 19:11:36 +0200 Subject: [PATCH] [Form] Precalculated the closure for deciding whether a choice is selected (PHP +30ms, Twig +30ms) --- Extension/Core/Type/ChoiceType.php | 14 ++++++ Tests/FormRendererTest.php | 75 ------------------------------ 2 files changed, 14 insertions(+), 75 deletions(-) delete mode 100644 Tests/FormRendererTest.php diff --git a/Extension/Core/Type/ChoiceType.php b/Extension/Core/Type/ChoiceType.php index e906f46aa8..b031c45a5e 100644 --- a/Extension/Core/Type/ChoiceType.php +++ b/Extension/Core/Type/ChoiceType.php @@ -90,6 +90,20 @@ public function buildView(FormView $view, FormInterface $form, array $options) 'empty_value' => null, )); + // The decision, whether a choice is selected, is potentially done + // thousand of times during the rendering of a template. Provide a + // closure here that is optimized for the value of the form, to + // avoid making the type check inside the closure. + if ($options['multiple']) { + $view->vars['is_selected'] = function ($choice, array $values) { + return false !== array_search($choice, $values, true); + }; + } else { + $view->vars['is_selected'] = function ($choice, $value) { + return $choice === $value; + }; + } + // Check if the choices already contain the empty value // Only add the empty value option if this is not the case if (0 === count($options['choice_list']->getIndicesForValues(array('')))) { diff --git a/Tests/FormRendererTest.php b/Tests/FormRendererTest.php deleted file mode 100644 index fa36e75a59..0000000000 --- a/Tests/FormRendererTest.php +++ /dev/null @@ -1,75 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Form; - -/** - * @author Bernhard Schussek - */ -use Symfony\Component\Form\Extension\Core\View\ChoiceView; - -class FormRendererTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - private $engine; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - private $csrfProvider; - - /** - * @var FormRenderer - */ - private $renderer; - - protected function setUp() - { - $this->engine = $this->getMock('Symfony\Component\Form\FormRendererEngineInterface'); - $this->csrfProvider = $this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'); - $this->renderer = new FormRenderer($this->engine, $this->csrfProvider); - } - - public function isChoiceSelectedProvider() - { - // The commented cases should not be necessary anymore, because the - // choice lists should assure that both values passed here are always - // strings - return array( -// array(true, 0, 0), - array(true, '0', '0'), - array(true, '1', '1'), -// array(true, false, 0), -// array(true, true, 1), - array(true, '', ''), -// array(true, null, ''), - array(true, '1.23', '1.23'), - array(true, 'foo', 'foo'), - array(true, 'foo10', 'foo10'), - array(true, 'foo', array(1, 'foo', 'foo10')), - - array(false, 10, array(1, 'foo', 'foo10')), - array(false, 0, array(1, 'foo', 'foo10')), - ); - } - - /** - * @dataProvider isChoiceSelectedProvider - */ - public function testIsChoiceSelected($expected, $choice, $value) - { - $choice = new ChoiceView($choice, $choice . ' label'); - - $this->assertSame($expected, $this->renderer->isChoiceSelected($choice, $value)); - } -}