feature #27580 [Form] Add ability to clear form errors (colinodell)

This PR was squashed before being merged into the 4.2-dev branch (closes #27580).

Discussion
----------

[Form] Add ability to clear form errors

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #14060
| License       | MIT
| Doc PR        | symfony/symfony-docs#9916

This PR adds the ability to manually clear form errors, thus improving the DX issue reported in #14060.

Unlike my original approach in #14233 and #27571 which break BC, this adds a new `ClearableErrorInterface` which `Form` implements.  (`Button` does not implement it because buttons can't have errors.)

Commits
-------

9eb755c07f [Form] Add ability to clear form errors
This commit is contained in:
Fabien Potencier 2018-06-25 11:51:57 +02:00
commit 53a39b791e
3 changed files with 91 additions and 1 deletions

View File

@ -0,0 +1,27 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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 <colinodell@gmail.com>
*/
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);
}

View File

@ -58,7 +58,7 @@ use Symfony\Component\PropertyAccess\PropertyPath;
* @author Fabien Potencier <fabien@symfony.com>
* @author Bernhard Schussek <bschussek@gmail.com>
*/
class Form implements \IteratorAggregate, FormInterface
class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterface
{
/**
* The form's configuration.
@ -795,6 +795,27 @@ class Form implements \IteratorAggregate, FormInterface
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}
*/

View File

@ -879,6 +879,48 @@ class CompoundFormTest extends AbstractFormTest
$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()
{