diff --git a/src/Symfony/Component/Form/ClearableErrorsInterface.php b/src/Symfony/Component/Form/ClearableErrorsInterface.php new file mode 100644 index 000000000000..f88151a96d65 --- /dev/null +++ b/src/Symfony/Component/Form/ClearableErrorsInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form; + +/** + * A form element whose errors can be cleared. + * + * @author Colin O'Dell + */ +interface ClearableErrorsInterface +{ + /** + * Removes all the errors of this form. + * + * @param bool $deep Whether to remove errors from child forms as well + */ + public function clearErrors(bool $deep = false); +} diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index 41170ea87aee..625cfe835227 100644 --- a/src/Symfony/Component/Form/Form.php +++ b/src/Symfony/Component/Form/Form.php @@ -58,7 +58,7 @@ * @author Fabien Potencier * @author Bernhard Schussek */ -class Form implements \IteratorAggregate, FormInterface +class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterface { /** * The form's configuration. @@ -795,6 +795,27 @@ public function getErrors($deep = false, $flatten = true) return new FormErrorIterator($this, $errors); } + /** + * {@inheritdoc} + * + * @return $this + */ + public function clearErrors(bool $deep = false): self + { + $this->errors = array(); + + if ($deep) { + // Clear errors from children + foreach ($this as $child) { + if ($child instanceof ClearableErrorsInterface) { + $child->clearErrors(true); + } + } + } + + return $this; + } + /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/Form/Tests/CompoundFormTest.php b/src/Symfony/Component/Form/Tests/CompoundFormTest.php index 73863a4dead7..33710d2587fa 100644 --- a/src/Symfony/Component/Form/Tests/CompoundFormTest.php +++ b/src/Symfony/Component/Form/Tests/CompoundFormTest.php @@ -879,6 +879,48 @@ public function testGetErrorsDeepRecursive() $this->assertSame($nestedError, $nestedErrorsAsArray[0]); } + public function testClearErrors() + { + $this->form->addError(new FormError('Error 1')); + $this->form->addError(new FormError('Error 2')); + + $this->assertCount(2, $this->form->getErrors()); + + $this->form->clearErrors(); + + $this->assertCount(0, $this->form->getErrors()); + } + + public function testClearErrorsShallow() + { + $this->form->addError($error1 = new FormError('Error 1')); + $this->form->addError($error2 = new FormError('Error 2')); + + $childForm = $this->getBuilder('Child')->getForm(); + $childForm->addError(new FormError('Nested Error')); + $this->form->add($childForm); + + $this->form->clearErrors(false); + + $this->assertCount(0, $this->form->getErrors(false)); + $this->assertCount(1, $this->form->getErrors(true)); + } + + public function testClearErrorsDeep() + { + $this->form->addError($error1 = new FormError('Error 1')); + $this->form->addError($error2 = new FormError('Error 2')); + + $childForm = $this->getBuilder('Child')->getForm(); + $childForm->addError($nestedError = new FormError('Nested Error')); + $this->form->add($childForm); + + $this->form->clearErrors(true); + + $this->assertCount(0, $this->form->getErrors(false)); + $this->assertCount(0, $this->form->getErrors(true)); + } + // Basic cases are covered in SimpleFormTest public function testCreateViewWithChildren() {