bug #22140 [Form] Improve the exceptions when trying to get the data in a PRE_SET_DATA listener and the data has not already been set (fancyweb)

This PR was merged into the 2.7 branch.

Discussion
----------

[Form] Improve the exceptions when trying to get the data in a PRE_SET_DATA listener and the data has not already been set

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #22103
| License       | MIT
| Doc PR        | -

Commits
-------

ef39b704cc [Form] Improve the exceptions when trying to get the data in a PRE_SET_DATA listener and the data has not already been set
This commit is contained in:
Fabien Potencier 2017-03-31 16:36:01 +02:00
commit 6008489153
2 changed files with 58 additions and 0 deletions

View File

@ -408,6 +408,10 @@ class Form implements \IteratorAggregate, FormInterface
}
if (!$this->defaultDataSet) {
if ($this->lockSetData) {
throw new RuntimeException('A cycle was detected. Listeners to the PRE_SET_DATA event must not call getData() if the form data has not already been set. You should call getData() on the FormEvent object instead.');
}
$this->setData($this->config->getData());
}
@ -428,6 +432,10 @@ class Form implements \IteratorAggregate, FormInterface
}
if (!$this->defaultDataSet) {
if ($this->lockSetData) {
throw new RuntimeException('A cycle was detected. Listeners to the PRE_SET_DATA event must not call getNormData() if the form data has not already been set.');
}
$this->setData($this->config->getData());
}
@ -448,6 +456,10 @@ class Form implements \IteratorAggregate, FormInterface
}
if (!$this->defaultDataSet) {
if ($this->lockSetData) {
throw new RuntimeException('A cycle was detected. Listeners to the PRE_SET_DATA event must not call getViewData() if the form data has not already been set.');
}
$this->setData($this->config->getData());
}

View File

@ -903,6 +903,7 @@ class SimpleFormTest extends AbstractFormTest
/**
* @expectedException \Symfony\Component\Form\Exception\RuntimeException
* @expectedExceptionMessage A cycle was detected. Listeners to the PRE_SET_DATA event must not call setData(). You should call setData() on the FormEvent object instead.
*/
public function testSetDataCannotInvokeItself()
{
@ -1084,6 +1085,51 @@ class SimpleFormTest extends AbstractFormTest
$fooType->setDefaultOptions($resolver);
}
/**
* @expectedException \Symfony\Component\Form\Exception\RuntimeException
* @expectedExceptionMessage A cycle was detected. Listeners to the PRE_SET_DATA event must not call getData() if the form data has not already been set. You should call getData() on the FormEvent object instead.
*/
public function testCannotCallGetDataInPreSetDataListenerIfDataHasNotAlreadyBeenSet()
{
$config = new FormConfigBuilder('name', 'stdClass', $this->dispatcher);
$config->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$event->getForm()->getData();
});
$form = new Form($config);
$form->setData('foo');
}
/**
* @expectedException \Symfony\Component\Form\Exception\RuntimeException
* @expectedExceptionMessage A cycle was detected. Listeners to the PRE_SET_DATA event must not call getNormData() if the form data has not already been set.
*/
public function testCannotCallGetNormDataInPreSetDataListener()
{
$config = new FormConfigBuilder('name', 'stdClass', $this->dispatcher);
$config->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$event->getForm()->getNormData();
});
$form = new Form($config);
$form->setData('foo');
}
/**
* @expectedException \Symfony\Component\Form\Exception\RuntimeException
* @expectedExceptionMessage A cycle was detected. Listeners to the PRE_SET_DATA event must not call getViewData() if the form data has not already been set.
*/
public function testCannotCallGetViewDataInPreSetDataListener()
{
$config = new FormConfigBuilder('name', 'stdClass', $this->dispatcher);
$config->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$event->getForm()->getViewData();
});
$form = new Form($config);
$form->setData('foo');
}
protected function createForm()
{
return $this->getBuilder()->getForm();