From bca8249db7530f63592bc9f1363a6f8c3d34d87b Mon Sep 17 00:00:00 2001 From: Bart van den Burg Date: Sun, 10 Jun 2012 21:33:51 +0200 Subject: [PATCH 1/4] created tests for added listeners to children --- .../Fixtures/AuthorWithListenersType.php | 60 +++++++++++++++++++ src/Symfony/Component/Form/Tests/FormTest.php | 21 +++++++ 2 files changed, 81 insertions(+) create mode 100644 src/Symfony/Component/Form/Tests/Fixtures/AuthorWithListenersType.php diff --git a/src/Symfony/Component/Form/Tests/Fixtures/AuthorWithListenersType.php b/src/Symfony/Component/Form/Tests/Fixtures/AuthorWithListenersType.php new file mode 100644 index 0000000000000..23b12429e9de0 --- /dev/null +++ b/src/Symfony/Component/Form/Tests/Fixtures/AuthorWithListenersType.php @@ -0,0 +1,60 @@ +getFormFactory(); + + $builder->add('lastName'); + + $basicListener = function(FormEvent $e) use ($factory) { + $data = $e->getData(); + if (null === $data) { + return; + } + if ($data == 'Smith') { + $e->getForm()->getParent()->add($factory->createNamed('australian', 'checkbox')); + } + }; + + switch($options['listener_set']) { + case self::POST_SET_DATA: + $builder->get('lastName')->addEventListener(FormEvents::POST_SET_DATA, $basicListener); + break; + case self::POST_BIND: + $builder->get('lastName')->addEventListener(FormEvents::POST_BIND, $basicListener); + break; + } + } + + public function getName() + { + return 'author_with_listeners'; + } + + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $resolver->setDefaults(array( + 'data_class' => 'Symfony\Component\Form\Tests\Fixtures\Author', + 'listener_set' => self::POST_SET_DATA + )); + + $resolver->setAllowedValues(array( + 'listener_set' => array(self::POST_SET_DATA, self::POST_BIND) + )); + } +} diff --git a/src/Symfony/Component/Form/Tests/FormTest.php b/src/Symfony/Component/Form/Tests/FormTest.php index 63dc7c5a6b12e..44024b2b7b29c 100644 --- a/src/Symfony/Component/Form/Tests/FormTest.php +++ b/src/Symfony/Component/Form/Tests/FormTest.php @@ -1298,6 +1298,27 @@ public function testClientDataMustBeObjectIfDataClassIsSet() $form->setData('foo'); } + public function testChildListenerCanAddFieldBasedOnOtherField() + { + $factory = new \Symfony\Component\Form\FormFactory(array(new \Symfony\Component\Form\Extension\Core\CoreExtension())); + + $baseAuthor = new Fixtures\Author; + $baseAuthor->setLastName('Smith'); + + $form = $factory->createNamedBuilder('author', new Fixtures\AuthorWithListenersType(), clone $baseAuthor)->getForm(); + $this->assertTrue($form->has('australian')); + + $form = $factory->createNamedBuilder('author', new Fixtures\AuthorWithListenersType(), clone $baseAuthor, array('listener_set' => Fixtures\AuthorWithListenersType::POST_BIND))->getForm(); + $form->bind(array('lastName' => 'Smith', 'australian' => 1)); + $this->assertTrue($form->has('australian')); + $this->assertTrue($form->getData()->isAustralian()); + + $form = $factory->createNamedBuilder('author', new Fixtures\AuthorWithListenersType(), clone $baseAuthor, array('listener_set' => Fixtures\AuthorWithListenersType::POST_BIND))->getForm(); + $form->bind(array('australian' => 1, 'lastName' => 'Smith')); + $this->assertTrue($form->has('australian')); + $this->assertTrue($form->getData()->isAustralian()); + } + protected function getBuilder($name = 'name', EventDispatcherInterface $dispatcher = null, $dataClass = null) { return new FormBuilder($name, $dataClass, $dispatcher ?: $this->dispatcher, $this->factory); From 5438481c5343a21eaa204f0a9e87d056fd7ea535 Mon Sep 17 00:00:00 2001 From: Bart van den Burg Date: Sun, 10 Jun 2012 21:43:47 +0200 Subject: [PATCH 2/4] fixed test by looping over the view data as long as fields have been bound --- src/Symfony/Component/Form/Form.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index cc6bedccaffeb..4082f208d37ac 100644 --- a/src/Symfony/Component/Form/Form.php +++ b/src/Symfony/Component/Form/Form.php @@ -493,13 +493,17 @@ public function bind($submittedData) } } - foreach ($viewData as $name => $value) { - if ($this->has($name)) { - $this->children[$name]->bind($value); - } else { - $extraData[$name] = $value; + $extraData = $viewData; + do { + $countBound = 0; + foreach ($extraData as $name => $value) { + if ($this->has($name)) { + $this->children[$name]->bind($value); + unset($extraData[$name]); + $countBound++; + } } - } + } while ($countBound > 0); // If we have a data mapper, use old view data and merge // data from the children into it later From 084e2e295852d56e9736108ef14543edfcd776f5 Mon Sep 17 00:00:00 2001 From: Bart van den Burg Date: Sun, 10 Jun 2012 21:56:27 +0200 Subject: [PATCH 3/4] removed the 'null ===' check as it is apparently not necessary anymore --- .../Component/Form/Tests/Fixtures/AuthorWithListenersType.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Symfony/Component/Form/Tests/Fixtures/AuthorWithListenersType.php b/src/Symfony/Component/Form/Tests/Fixtures/AuthorWithListenersType.php index 23b12429e9de0..392f3ad4102ba 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/AuthorWithListenersType.php +++ b/src/Symfony/Component/Form/Tests/Fixtures/AuthorWithListenersType.php @@ -23,9 +23,6 @@ public function buildForm(FormBuilderInterface $builder, array $options) $basicListener = function(FormEvent $e) use ($factory) { $data = $e->getData(); - if (null === $data) { - return; - } if ($data == 'Smith') { $e->getForm()->getParent()->add($factory->createNamed('australian', 'checkbox')); } From bc9dd05af1e0d8fe73a22761c72b4840cab28d5f Mon Sep 17 00:00:00 2001 From: Bart van den Burg Date: Mon, 11 Jun 2012 15:44:46 +0300 Subject: [PATCH 4/4] Stoffed --- .../Form/Tests/Fixtures/AuthorWithListenersType.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Form/Tests/Fixtures/AuthorWithListenersType.php b/src/Symfony/Component/Form/Tests/Fixtures/AuthorWithListenersType.php index 392f3ad4102ba..a4ba8888e1eff 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/AuthorWithListenersType.php +++ b/src/Symfony/Component/Form/Tests/Fixtures/AuthorWithListenersType.php @@ -10,11 +10,9 @@ class AuthorWithListenersType extends AbstractType { - const - POST_SET_DATA = 1, - POST_BIND = 2 - ; - + const POST_SET_DATA = 1; + const POST_BIND = 2; + public function buildForm(FormBuilderInterface $builder, array $options) { $factory = $builder->getFormFactory();