[Form][FrameworkBundle][TwigBundle] Introduced class FieldError to wrap form errors

This commit is contained in:
Bernhard Schussek 2010-11-18 23:33:44 +01:00 committed by Fabien Potencier
parent 68cebd667a
commit e0d6aad5f4
9 changed files with 111 additions and 30 deletions

View File

@ -1,7 +1,11 @@
<?php if ($field->hasErrors()): ?>
<ul>
<?php foreach ($field->getErrors() as $error): ?>
<li><?php echo $view['translator']->trans($error[0], $error[1], 'validators') ?></li>
<li><?php echo $view['translator']->trans(
$error->getMessageTemplate(),
$error->getMessageParameters()->getRawValue(),
'validators'
) ?></li>
<?php endforeach; ?>
</ul>
<?php endif ?>

View File

@ -16,7 +16,7 @@
{% if field.hasErrors %}
<ul>
{% for error in field.errors %}
<li>{% trans error.0 with error.1 from validators %}</li>
<li>{% trans error.messageTemplate with error.messageParameters from validators %}</li>
{% endfor %}
</ul>
{% endif %}

View File

@ -275,7 +275,7 @@ abstract class Field extends Configurable implements FieldInterface
} catch (TransformationFailedException $e) {
// TODO better text
// TESTME
$this->addError('invalid (localized)');
$this->addError(new FieldError('invalid (localized)'));
}
}
@ -317,9 +317,9 @@ abstract class Field extends Configurable implements FieldInterface
*
* @see FieldInterface
*/
public function addError($messageTemplate, array $messageParameters = array(), PropertyPathIterator $pathIterator = null, $type = null)
public function addError(FieldError $error, PropertyPathIterator $pathIterator = null, $type = null)
{
$this->errors[] = array($messageTemplate, $messageParameters);
$this->errors[] = $error;
}
/**

View File

@ -0,0 +1,57 @@
<?php
namespace Symfony\Component\Form;
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
/**
* Wraps errors in form fields
*
* @author Bernhard Schussek <bernhard.schussek@symfony-project.com>
*/
class FieldError
{
protected $messageTemplate;
protected $messageParameters;
/**
* Constructor
*
* @param string $messageTemplate The template for the error message
* @param array $messageParameters The parameters that should be
* substituted in the message template.
*/
public function __construct($messageTemplate, array $messageParameters = array())
{
$this->messageTemplate = $messageTemplate;
$this->messageParameters = $messageParameters;
}
/**
* Returns the error message template
*
* @return string
*/
public function getMessageTemplate()
{
return $this->messageTemplate;
}
/**
* Returns the parameters to be inserted in the message template
*
* @return array
*/
public function getMessageParameters()
{
return $this->messageParameters;
}
}

View File

@ -392,7 +392,7 @@ class FieldGroup extends Field implements \IteratorAggregate, FieldGroupInterfac
/**
* {@inheritDoc}
*/
public function addError($messageTemplate, array $messageParameters = array(), PropertyPathIterator $pathIterator = null, $type = null)
public function addError(FieldError $error, PropertyPathIterator $pathIterator = null, $type = null)
{
if ($pathIterator !== null) {
if ($type === self::FIELD_ERROR && $pathIterator->hasNext()) {
@ -403,7 +403,7 @@ class FieldGroup extends Field implements \IteratorAggregate, FieldGroupInterfac
}
if ($this->has($pathIterator->current()) && !$this->get($pathIterator->current())->isHidden()) {
$this->get($pathIterator->current())->addError($messageTemplate, $messageParameters, $pathIterator, $type);
$this->get($pathIterator->current())->addError($error, $pathIterator, $type);
return;
}
@ -418,7 +418,7 @@ class FieldGroup extends Field implements \IteratorAggregate, FieldGroupInterfac
$pathIterator->next();
}
$field->addError($messageTemplate, $messageParameters, $pathIterator, $type);
$field->addError($error, $pathIterator, $type);
return;
}
@ -427,7 +427,7 @@ class FieldGroup extends Field implements \IteratorAggregate, FieldGroupInterfac
}
}
parent::addError($messageTemplate, $messageParameters);
parent::addError($error);
}
/**

View File

@ -181,11 +181,11 @@ interface FieldInterface extends Localizable
* ...
* </code>
*
* @param FieldInterface $field
* @param FieldError $error
* @param PropertyPathIterator $pathIterator
* @param ConstraintViolation$violation
*/
function addError($messageTemplate, array $messageParameters = array(), PropertyPathIterator $pathIterator = null, $type = null);
function addError(FieldError $error, PropertyPathIterator $pathIterator = null, $type = null);
/**
* Returns whether the field is bound.

View File

@ -147,7 +147,7 @@ class Form extends FieldGroup
$type = self::FIELD_ERROR;
}
$this->addError($violation->getMessageTemplate(), $violation->getMessageParameters(), $iterator, $type);
$this->addError(new FieldError($violation->getMessageTemplate(), $violation->getMessageParameters()), $iterator, $type);
}
}
}

View File

@ -7,6 +7,7 @@ require_once __DIR__ . '/Fixtures/TestField.php';
require_once __DIR__ . '/Fixtures/TestFieldGroup.php';
use Symfony\Component\Form\Field;
use Symfony\Component\Form\FieldError;
use Symfony\Component\Form\FieldInterface;
use Symfony\Component\Form\FieldGroup;
use Symfony\Component\Form\PropertyPath;
@ -157,25 +158,29 @@ class FieldGroupTest extends \PHPUnit_Framework_TestCase
public function testAddErrorMapsFieldValidationErrorsOntoFields()
{
$error = new FieldError('Message');
$field = $this->createMockField('firstName');
$field->expects($this->once())
->method('addError')
->with($this->equalTo('Message'));
->with($this->equalTo($error));
$group = new TestFieldGroup('author');
$group->add($field);
$path = new PropertyPath('fields[firstName].data');
$group->addError('Message', array(), $path->getIterator(), FieldGroup::FIELD_ERROR);
$group->addError($error, $path->getIterator(), FieldGroup::FIELD_ERROR);
}
public function testAddErrorMapsFieldValidationErrorsOntoFieldsWithinNestedFieldGroups()
{
$error = new FieldError('Message');
$field = $this->createMockField('firstName');
$field->expects($this->once())
->method('addError')
->with($this->equalTo('Message'));
->with($this->equalTo($error));
$group = new TestFieldGroup('author');
$innerGroup = new TestFieldGroup('names');
@ -184,11 +189,13 @@ class FieldGroupTest extends \PHPUnit_Framework_TestCase
$path = new PropertyPath('fields[names].fields[firstName].data');
$group->addError('Message', array(), $path->getIterator(), FieldGroup::FIELD_ERROR);
$group->addError($error, $path->getIterator(), FieldGroup::FIELD_ERROR);
}
public function testAddErrorKeepsFieldValidationErrorsIfFieldNotFound()
{
$error = new FieldError('Message');
$field = $this->createMockField('foo');
$field->expects($this->never())
->method('addError');
@ -198,13 +205,15 @@ class FieldGroupTest extends \PHPUnit_Framework_TestCase
$path = new PropertyPath('fields[bar].data');
$group->addError('Message', array(), $path->getIterator(), FieldGroup::FIELD_ERROR);
$group->addError($error, $path->getIterator(), FieldGroup::FIELD_ERROR);
$this->assertEquals(array(array('Message', array())), $group->getErrors());
$this->assertEquals(array($error), $group->getErrors());
}
public function testAddErrorKeepsFieldValidationErrorsIfFieldIsHidden()
{
$error = new FieldError('Message');
$field = $this->createMockField('firstName');
$field->expects($this->any())
->method('isHidden')
@ -217,13 +226,15 @@ class FieldGroupTest extends \PHPUnit_Framework_TestCase
$path = new PropertyPath('fields[firstName].data');
$group->addError('Message', array(), $path->getIterator(), FieldGroup::FIELD_ERROR);
$group->addError($error, $path->getIterator(), FieldGroup::FIELD_ERROR);
$this->assertEquals(array(array('Message', array())), $group->getErrors());
$this->assertEquals(array($error), $group->getErrors());
}
public function testAddErrorMapsDataValidationErrorsOntoFields()
{
$error = new FieldError('Message');
// path is expected to point at "firstName"
$expectedPath = new PropertyPath('firstName');
$expectedPathIterator = $expectedPath->getIterator();
@ -234,18 +245,20 @@ class FieldGroupTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue(new PropertyPath('firstName')));
$field->expects($this->once())
->method('addError')
->with($this->equalTo('Message'), array(), $this->equalTo($expectedPathIterator), $this->equalTo(FieldGroup::DATA_ERROR));
->with($this->equalTo($error), $this->equalTo($expectedPathIterator), $this->equalTo(FieldGroup::DATA_ERROR));
$group = new TestFieldGroup('author');
$group->add($field);
$path = new PropertyPath('firstName');
$group->addError('Message', array(), $path->getIterator(), FieldGroup::DATA_ERROR);
$group->addError($error, $path->getIterator(), FieldGroup::DATA_ERROR);
}
public function testAddErrorKeepsDataValidationErrorsIfFieldNotFound()
{
$error = new FieldError('Message');
$field = $this->createMockField('foo');
$field->expects($this->any())
->method('getPropertyPath')
@ -258,11 +271,13 @@ class FieldGroupTest extends \PHPUnit_Framework_TestCase
$path = new PropertyPath('bar');
$group->addError('Message', array(), $path->getIterator(), FieldGroup::DATA_ERROR);
$group->addError($error, $path->getIterator(), FieldGroup::DATA_ERROR);
}
public function testAddErrorKeepsDataValidationErrorsIfFieldIsHidden()
{
$error = new FieldError('Message');
$field = $this->createMockField('firstName');
$field->expects($this->any())
->method('isHidden')
@ -278,11 +293,13 @@ class FieldGroupTest extends \PHPUnit_Framework_TestCase
$path = new PropertyPath('firstName');
$group->addError('Message', array(), $path->getIterator(), FieldGroup::DATA_ERROR);
$group->addError($error, $path->getIterator(), FieldGroup::DATA_ERROR);
}
public function testAddErrorMapsDataValidationErrorsOntoNestedFields()
{
$error = new FieldError('Message');
// path is expected to point at "street"
$expectedPath = new PropertyPath('address.street');
$expectedPathIterator = $expectedPath->getIterator();
@ -294,18 +311,20 @@ class FieldGroupTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue(new PropertyPath('address')));
$field->expects($this->once())
->method('addError')
->with($this->equalTo('Message'), array(), $this->equalTo($expectedPathIterator), $this->equalTo(FieldGroup::DATA_ERROR));
->with($this->equalTo($error), $this->equalTo($expectedPathIterator), $this->equalTo(FieldGroup::DATA_ERROR));
$group = new TestFieldGroup('author');
$group->add($field);
$path = new PropertyPath('address.street');
$group->addError('Message', array(), $path->getIterator(), FieldGroup::DATA_ERROR);
$group->addError($error, $path->getIterator(), FieldGroup::DATA_ERROR);
}
public function testAddErrorMapsErrorsOntoFieldsInAnonymousGroups()
{
$error = new FieldError('Message');
// path is expected to point at "address"
$expectedPath = new PropertyPath('address');
$expectedPathIterator = $expectedPath->getIterator();
@ -316,7 +335,7 @@ class FieldGroupTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue(new PropertyPath('address')));
$field->expects($this->once())
->method('addError')
->with($this->equalTo('Message'), array(), $this->equalTo($expectedPathIterator), $this->equalTo(FieldGroup::DATA_ERROR));
->with($this->equalTo($error), $this->equalTo($expectedPathIterator), $this->equalTo(FieldGroup::DATA_ERROR));
$group = new TestFieldGroup('author');
$group2 = new TestFieldGroup('anonymous', array('property_path' => null));
@ -325,7 +344,7 @@ class FieldGroupTest extends \PHPUnit_Framework_TestCase
$path = new PropertyPath('address');
$group->addError('Message', array(), $path->getIterator(), FieldGroup::DATA_ERROR);
$group->addError($error, $path->getIterator(), FieldGroup::DATA_ERROR);
}
public function testAddThrowsExceptionIfAlreadyBound()

View File

@ -9,6 +9,7 @@ require_once __DIR__ . '/Fixtures/RequiredOptionsField.php';
use Symfony\Component\Form\ValueTransformer\ValueTransformerInterface;
use Symfony\Component\Form\PropertyPath;
use Symfony\Component\Form\FieldError;
use Symfony\Tests\Component\Form\Fixtures\Author;
use Symfony\Tests\Component\Form\Fixtures\TestField;
use Symfony\Tests\Component\Form\Fixtures\InvalidField;
@ -91,14 +92,14 @@ class FieldTest extends \PHPUnit_Framework_TestCase
public function testFieldWithErrorsIsInvalid()
{
$this->field->bind('data');
$this->field->addError('Some error');
$this->field->addError(new FieldError('Some error'));
$this->assertFalse($this->field->isValid());
}
public function testBindResetsErrors()
{
$this->field->addError('Some error');
$this->field->addError(new FieldError('Some error'));
$this->field->bind('data');
$this->assertTrue($this->field->isValid());