diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig index 602ae9668b..bdeb8d7e94 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig @@ -191,7 +191,7 @@ {% for formName, formData in collector.data.forms %} - {{ form_tree_details(formName, formData) }} + {{ form_tree_details(formName, formData, collector.data.forms_by_hash) }} {% endfor %} {% else %} @@ -366,7 +366,7 @@ {% endmacro %} -{% macro form_tree_details(name, data) %} +{% macro form_tree_details(name, data, forms_by_hash) %}

{{ name }} @@ -386,13 +386,32 @@ - + + {% for error in data.errors %} - + + {% endfor %}
MessageMessageOrigin Cause
{{ error.message }}Unknown. + {% if error.origin is empty %} + This form. + {% elseif forms_by_hash[error.origin] is not defined %} + Unknown. + {% else %} + {{ forms_by_hash[error.origin].name }} + {% endif %} + + {% if error.cause is empty %} + Unknown. + {% elseif error.cause.root is defined %} + Constraint Violation
+
{{ error.cause.root }}{% if error.cause.path is not empty %}{% if error.cause.path|first != '[' %}.{% endif %}{{ error.cause.path }}{% endif %} = {{ error.cause.value }}
+ {% else %} +
{{ error.cause }}
+ {% endif %} +
@@ -565,6 +584,6 @@

{% for childName, childData in data.children %} - {{ _self.form_tree_details(childName, childData) }} + {{ _self.form_tree_details(childName, childData, forms_by_hash) }} {% endfor %} {% endmacro %} diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index b9c8256b5a..ff4e46284f 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -5,6 +5,8 @@ CHANGELOG ------ * added an option for multiple files upload + * form errors now reference their cause (constraint violation, exception, ...) + * form errors now remember which form they were originally added to 2.4.0 ----- diff --git a/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php b/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php index 2119248132..bcadfc5977 100644 --- a/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php +++ b/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php @@ -69,6 +69,7 @@ class FormDataCollector extends DataCollector implements FormDataCollectorInterf $this->dataExtractor = $dataExtractor; $this->data = array( 'forms' => array(), + 'forms_by_hash' => array(), 'nb_errors' => 0, ); } @@ -184,7 +185,7 @@ class FormDataCollector extends DataCollector implements FormDataCollectorInterf { $this->data['forms'][$form->getName()] = array(); - $this->recursiveBuildPreliminaryFormTree($form, $this->data['forms'][$form->getName()]); + $this->recursiveBuildPreliminaryFormTree($form, $this->data['forms'][$form->getName()], $this->data['forms_by_hash']); } /** @@ -194,7 +195,7 @@ class FormDataCollector extends DataCollector implements FormDataCollectorInterf { $this->data['forms'][$form->getName()] = array(); - $this->recursiveBuildFinalFormTree($form, $view, $this->data['forms'][$form->getName()]); + $this->recursiveBuildFinalFormTree($form, $view, $this->data['forms'][$form->getName()], $this->data['forms_by_hash']); } /** @@ -213,7 +214,7 @@ class FormDataCollector extends DataCollector implements FormDataCollectorInterf return $this->data; } - private function recursiveBuildPreliminaryFormTree(FormInterface $form, &$output = null) + private function recursiveBuildPreliminaryFormTree(FormInterface $form, &$output = null, array &$outputByHash) { $hash = spl_object_hash($form); @@ -221,16 +222,18 @@ class FormDataCollector extends DataCollector implements FormDataCollectorInterf ? $this->dataByForm[$hash] : array(); + $outputByHash[$hash] = &$output; + $output['children'] = array(); foreach ($form as $name => $child) { $output['children'][$name] = array(); - $this->recursiveBuildPreliminaryFormTree($child, $output['children'][$name]); + $this->recursiveBuildPreliminaryFormTree($child, $output['children'][$name], $outputByHash); } } - private function recursiveBuildFinalFormTree(FormInterface $form = null, FormView $view, &$output = null) + private function recursiveBuildFinalFormTree(FormInterface $form = null, FormView $view, &$output = null, array &$outputByHash) { $viewHash = spl_object_hash($view); $formHash = null; @@ -255,6 +258,8 @@ class FormDataCollector extends DataCollector implements FormDataCollectorInterf ? $this->dataByForm[$formHash] : array() ); + + $outputByHash[$formHash] = &$output; } $output['children'] = array(); @@ -268,7 +273,7 @@ class FormDataCollector extends DataCollector implements FormDataCollectorInterf $output['children'][$name] = array(); - $this->recursiveBuildFinalFormTree($childForm, $childView, $output['children'][$name]); + $this->recursiveBuildFinalFormTree($childForm, $childView, $output['children'][$name], $outputByHash); } } } diff --git a/src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php b/src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php index 8765b13ca4..80e910177a 100644 --- a/src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php +++ b/src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php @@ -14,6 +14,7 @@ namespace Symfony\Component\Form\Extension\DataCollector; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormView; use Symfony\Component\HttpKernel\DataCollector\Util\ValueExporter; +use Symfony\Component\Validator\ConstraintViolationInterface; /** * Default implementation of {@link FormDataExtractorInterface}. @@ -43,6 +44,7 @@ class FormDataExtractor implements FormDataExtractorInterface { $data = array( 'id' => $this->buildId($form), + 'name' => $form->getName(), 'type' => $form->getConfig()->getType()->getName(), 'type_class' => get_class($form->getConfig()->getType()->getInnerType()), 'synchronized' => $this->valueExporter->exportValue($form->isSynchronized()), @@ -108,9 +110,26 @@ class FormDataExtractor implements FormDataExtractorInterface } foreach ($form->getErrors() as $error) { - $data['errors'][] = array( + $errorData = array( 'message' => $error->getMessage(), + 'origin' => is_object($error->getOrigin()) + ? spl_object_hash($error->getOrigin()) + : null, ); + + $cause = $error->getCause(); + + if ($cause instanceof ConstraintViolationInterface) { + $errorData['cause'] = array( + 'root' => $this->valueExporter->exportValue($cause->getRoot()), + 'path' => $this->valueExporter->exportValue($cause->getPropertyPath()), + 'value' => $this->valueExporter->exportValue($cause->getInvalidValue()), + ); + } else { + $errorData['cause'] = null !== $cause ? $this->valueExporter->exportValue($cause) : null; + } + + $data['errors'][] = $errorData; } $data['synchronized'] = $this->valueExporter->exportValue($form->isSynchronized()); @@ -127,8 +146,12 @@ class FormDataExtractor implements FormDataExtractorInterface // Set the ID in case no FormInterface object was collected for this // view - if (isset($view->vars['id'])) { - $data['id'] = $view->vars['id']; + if (!isset($data['id'])) { + $data['id'] = isset($view->vars['id']) ? $view->vars['id'] : null; + } + + if (!isset($data['name'])) { + $data['name'] = isset($view->vars['name']) ? $view->vars['name'] : null; } foreach ($view->vars as $varName => $value) { diff --git a/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php b/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php index 6ea56eb03b..15ceb0cf08 100644 --- a/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php +++ b/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php @@ -128,7 +128,8 @@ class ViolationMapper implements ViolationMapperInterface $violation->getMessage(), $violation->getMessageTemplate(), $violation->getMessageParameters(), - $violation->getMessagePluralization() + $violation->getMessagePluralization(), + $violation )); } } diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index e677fff629..f4696c0dfe 100644 --- a/src/Symfony/Component/Form/Form.php +++ b/src/Symfony/Component/Form/Form.php @@ -673,6 +673,10 @@ class Form implements \IteratorAggregate, FormInterface public function addError(FormError $error) { if ($this->parent && $this->config->getErrorBubbling()) { + if (null === $error->getOrigin()) { + $error->setOrigin($this); + } + $this->parent->addError($error); } else { $this->errors[] = $error; diff --git a/src/Symfony/Component/Form/FormError.php b/src/Symfony/Component/Form/FormError.php index 343165ca46..6970244cf7 100644 --- a/src/Symfony/Component/Form/FormError.php +++ b/src/Symfony/Component/Form/FormError.php @@ -11,12 +11,14 @@ namespace Symfony\Component\Form; +use Symfony\Component\Form\Exception\BadMethodCallException; + /** * Wraps errors in forms * * @author Bernhard Schussek */ -class FormError +class FormError implements \Serializable { /** * @var string @@ -41,6 +43,18 @@ class FormError */ protected $messagePluralization; + /** + * The cause for this error + * @var mixed + */ + private $cause; + + /** + * The form that spawned this error + * @var FormInterface + */ + private $origin; + /** * Constructor * @@ -50,17 +64,19 @@ class FormError * @param string $message The translated error message * @param string|null $messageTemplate The template for the error message * @param array $messageParameters The parameters that should be - * substituted in the message template. + * substituted in the message template * @param integer|null $messagePluralization The value for error message pluralization + * @param mixed $cause The cause of the error * * @see \Symfony\Component\Translation\Translator */ - public function __construct($message, $messageTemplate = null, array $messageParameters = array(), $messagePluralization = null) + public function __construct($message, $messageTemplate = null, array $messageParameters = array(), $messagePluralization = null, $cause = null) { $this->message = $message; $this->messageTemplate = $messageTemplate ?: $message; $this->messageParameters = $messageParameters; $this->messagePluralization = $messagePluralization; + $this->cause = $cause; } /** @@ -102,4 +118,68 @@ class FormError { return $this->messagePluralization; } + + /** + * Returns the cause of this error. + * + * @return mixed The cause of this error + */ + public function getCause() + { + return $this->cause; + } + + /** + * Sets the form that caused this error. + * + * This method must only be called once. + * + * @param FormInterface $origin The form that caused this error + * + * @throws BadMethodCallException If the method is called more than once + */ + public function setOrigin(FormInterface $origin) + { + if (null !== $this->origin) { + throw new BadMethodCallException('setOrigin() must only be called once.'); + } + + $this->origin = $origin; + } + + /** + * Returns the form that caused this error. + * + * @return FormInterface The form that caused this error + */ + public function getOrigin() + { + return $this->origin; + } + + /** + * Serializes this error. + * + * @return string The serialized error + */ + public function serialize() + { + return serialize(array( + $this->message, + $this->messageTemplate, + $this->messageParameters, + $this->messagePluralization, + $this->cause + )); + } + + /** + * Unserializes a serialized error. + * + * @param string $serialized The serialized error + */ + public function unserialize($serialized) + { + list($this->message, $this->messageTemplate, $this->messageParameters, $this->messagePluralization, $this->cause) = unserialize($serialized); + } } diff --git a/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataCollectorTest.php b/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataCollectorTest.php index 99ac76ac23..885b4b68d1 100644 --- a/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataCollectorTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataCollectorTest.php @@ -111,23 +111,31 @@ class FormDataCollectorTest extends \PHPUnit_Framework_TestCase $this->dataCollector->collectSubmittedData($this->form); $this->dataCollector->buildPreliminaryFormTree($this->form); - $this->assertSame(array( - 'forms' => array( - 'name' => array( - 'config' => 'foo', - 'default_data' => 'foo', - 'submitted_data' => 'foo', - 'children' => array( - 'child' => array( - 'config' => 'bar', - 'default_data' => 'bar', - 'submitted_data' => 'bar', - 'children' => array(), - ), - ), - ), + $childFormData = array( + 'config' => 'bar', + 'default_data' => 'bar', + 'submitted_data' => 'bar', + 'children' => array(), + ); + + $formData = array( + 'config' => 'foo', + 'default_data' => 'foo', + 'submitted_data' => 'foo', + 'children' => array( + 'child' => $childFormData, ), - 'nb_errors' => 0, + ); + + $this->assertSame(array( + 'forms' => array( + 'name' => $formData, + ), + 'forms_by_hash' => array( + spl_object_hash($this->form) => $formData, + spl_object_hash($this->childForm) => $childFormData, + ), + 'nb_errors' => 0, ), $this->dataCollector->getData()); } @@ -149,28 +157,36 @@ class FormDataCollectorTest extends \PHPUnit_Framework_TestCase $this->dataCollector->collectConfiguration($form2); $this->dataCollector->buildPreliminaryFormTree($form1); + $form1Data = array( + 'config' => 'foo', + 'children' => array(), + ); + $this->assertSame(array( 'forms' => array( - 'form1' => array( - 'config' => 'foo', - 'children' => array(), - ), + 'form1' => $form1Data, + ), + 'forms_by_hash' => array( + spl_object_hash($form1) => $form1Data, ), 'nb_errors' => 0, ), $this->dataCollector->getData()); $this->dataCollector->buildPreliminaryFormTree($form2); + $form2Data = array( + 'config' => 'bar', + 'children' => array(), + ); + $this->assertSame(array( 'forms' => array( - 'form1' => array( - 'config' => 'foo', - 'children' => array(), - ), - 'form2' => array( - 'config' => 'bar', - 'children' => array(), - ), + 'form1' => $form1Data, + 'form2' => $form2Data, + ), + 'forms_by_hash' => array( + spl_object_hash($form1) => $form1Data, + spl_object_hash($form2) => $form2Data, ), 'nb_errors' => 0, ), $this->dataCollector->getData()); @@ -191,12 +207,17 @@ class FormDataCollectorTest extends \PHPUnit_Framework_TestCase $this->dataCollector->collectConfiguration($this->form); $this->dataCollector->buildPreliminaryFormTree($this->form); + $formData = array( + 'config' => 'foo', + 'children' => array(), + ); + $this->assertSame(array( 'forms' => array( - 'name' => array( - 'config' => 'foo', - 'children' => array(), - ), + 'name' => $formData, + ), + 'forms_by_hash' => array( + spl_object_hash($this->form) => $formData, ), 'nb_errors' => 0, ), $this->dataCollector->getData()); @@ -204,13 +225,18 @@ class FormDataCollectorTest extends \PHPUnit_Framework_TestCase $this->dataCollector->collectDefaultData($this->form); $this->dataCollector->buildPreliminaryFormTree($this->form); + $formData = array( + 'config' => 'foo', + 'default_data' => 'foo', + 'children' => array(), + ); + $this->assertSame(array( 'forms' => array( - 'name' => array( - 'config' => 'foo', - 'default_data' => 'foo', - 'children' => array(), - ), + 'name' => $formData, + ), + 'forms_by_hash' => array( + spl_object_hash($this->form) => $formData, ), 'nb_errors' => 0, ), $this->dataCollector->getData()); @@ -220,11 +246,16 @@ class FormDataCollectorTest extends \PHPUnit_Framework_TestCase { $this->dataCollector->buildPreliminaryFormTree($this->form); + $formData = array( + 'children' => array(), + ); + $this->assertSame(array( 'forms' => array( - 'name' => array( - 'children' => array(), - ), + 'name' => $formData, + ), + 'forms_by_hash' => array( + spl_object_hash($this->form) => $formData, ), 'nb_errors' => 0, ), $this->dataCollector->getData()); @@ -278,23 +309,31 @@ class FormDataCollectorTest extends \PHPUnit_Framework_TestCase $this->dataCollector->collectViewVariables($this->view); $this->dataCollector->buildFinalFormTree($this->form, $this->view); + $childFormData = array( + 'view_vars' => 'bar', + 'config' => 'bar', + 'default_data' => 'bar', + 'submitted_data' => 'bar', + 'children' => array(), + ); + + $formData = array( + 'view_vars' => 'foo', + 'config' => 'foo', + 'default_data' => 'foo', + 'submitted_data' => 'foo', + 'children' => array( + 'child' => $childFormData, + ), + ); + $this->assertSame(array( 'forms' => array( - 'name' => array( - 'view_vars' => 'foo', - 'config' => 'foo', - 'default_data' => 'foo', - 'submitted_data' => 'foo', - 'children' => array( - 'child' => array( - 'view_vars' => 'bar', - 'config' => 'bar', - 'default_data' => 'bar', - 'submitted_data' => 'bar', - 'children' => array(), - ), - ), - ), + 'name' => $formData, + ), + 'forms_by_hash' => array( + spl_object_hash($this->form) => $formData, + spl_object_hash($this->childForm) => $childFormData, ), 'nb_errors' => 0, ), $this->dataCollector->getData()); @@ -302,41 +341,57 @@ class FormDataCollectorTest extends \PHPUnit_Framework_TestCase public function testFinalFormReliesOnFormViewStructure() { - $this->form->add($this->createForm('first')); - $this->form->add($this->createForm('second')); + $this->form->add($child1 = $this->createForm('first')); + $this->form->add($child2 = $this->createForm('second')); $this->view->children['second'] = $this->childView; $this->dataCollector->buildPreliminaryFormTree($this->form); + $child1Data = array( + 'children' => array(), + ); + + $child2Data = array( + 'children' => array(), + ); + + $formData = array( + 'children' => array( + 'first' => $child1Data, + 'second' => $child2Data, + ), + ); + $this->assertSame(array( 'forms' => array( - 'name' => array( - 'children' => array( - 'first' => array( - 'children' => array(), - ), - 'second' => array( - 'children' => array(), - ), - ), - ), + 'name' => $formData, + ), + 'forms_by_hash' => array( + spl_object_hash($this->form) => $formData, + spl_object_hash($child1) => $child1Data, + spl_object_hash($child2) => $child2Data, ), 'nb_errors' => 0, ), $this->dataCollector->getData()); $this->dataCollector->buildFinalFormTree($this->form, $this->view); + $formData = array( + 'children' => array( + // "first" not present in FormView + 'second' => $child2Data, + ), + ); + $this->assertSame(array( 'forms' => array( - 'name' => array( - 'children' => array( - // "first" not present in FormView - 'second' => array( - 'children' => array(), - ), - ), - ), + 'name' => $formData, + ), + 'forms_by_hash' => array( + spl_object_hash($this->form) => $formData, + spl_object_hash($child1) => $child1Data, + spl_object_hash($child2) => $child2Data, ), 'nb_errors' => 0, ), $this->dataCollector->getData()); @@ -363,17 +418,25 @@ class FormDataCollectorTest extends \PHPUnit_Framework_TestCase $this->dataCollector->collectConfiguration($this->childForm); $this->dataCollector->buildFinalFormTree($this->form, $this->view); + $childFormData = array( + // no "config" key + 'children' => array(), + ); + + $formData = array( + 'config' => 'foo', + 'children' => array( + 'child' => $childFormData, + ), + ); + $this->assertSame(array( 'forms' => array( - 'name' => array( - 'config' => 'foo', - 'children' => array( - 'child' => array( - // no "config" key - 'children' => array(), - ), - ), - ), + 'name' => $formData, + ), + 'forms_by_hash' => array( + spl_object_hash($this->form) => $formData, + // no child entry ), 'nb_errors' => 0, ), $this->dataCollector->getData()); @@ -403,17 +466,25 @@ class FormDataCollectorTest extends \PHPUnit_Framework_TestCase $this->dataCollector->collectConfiguration($this->childForm); $this->dataCollector->buildFinalFormTree($this->form, $this->view); + $childFormData = array( + 'config' => 'bar', + 'children' => array(), + ); + + $formData = array( + 'config' => 'foo', + 'children' => array( + 'child' => $childFormData, + ), + ); + $this->assertSame(array( 'forms' => array( - 'name' => array( - 'config' => 'foo', - 'children' => array( - 'child' => array( - 'config' => 'bar', - 'children' => array(), - ), - ), - ), + 'name' => $formData, + ), + 'forms_by_hash' => array( + spl_object_hash($this->form) => $formData, + spl_object_hash($this->childForm) => $childFormData, ), 'nb_errors' => 0, ), $this->dataCollector->getData()); diff --git a/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataExtractorTest.php b/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataExtractorTest.php index bf3cd71975..37b5b7d86c 100644 --- a/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataExtractorTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataExtractorTest.php @@ -27,7 +27,7 @@ class FormDataExtractorTest_SimpleValueExporter extends ValueExporter */ public function exportValue($value) { - return var_export($value, true); + return is_object($value) ? sprintf('object(%s)', get_class($value)) : var_export($value, true); } } @@ -80,6 +80,7 @@ class FormDataExtractorTest extends \PHPUnit_Framework_TestCase $this->assertSame(array( 'id' => 'name', + 'name' => 'name', 'type' => 'type_name', 'type_class' => 'stdClass', 'synchronized' => 'true', @@ -113,6 +114,7 @@ class FormDataExtractorTest extends \PHPUnit_Framework_TestCase $this->assertSame(array( 'id' => 'name', + 'name' => 'name', 'type' => 'type_name', 'type_class' => 'stdClass', 'synchronized' => 'true', @@ -147,6 +149,7 @@ class FormDataExtractorTest extends \PHPUnit_Framework_TestCase $this->assertSame(array( 'id' => 'name', + 'name' => 'name', 'type' => 'type_name', 'type_class' => 'stdClass', 'synchronized' => 'true', @@ -186,6 +189,7 @@ class FormDataExtractorTest extends \PHPUnit_Framework_TestCase $this->assertSame(array( 'id' => 'grandParent_parent_name', + 'name' => 'name', 'type' => 'type_name', 'type_class' => 'stdClass', 'synchronized' => 'true', @@ -315,7 +319,48 @@ class FormDataExtractorTest extends \PHPUnit_Framework_TestCase 'norm' => "'Foobar'", ), 'errors' => array( - array('message' => 'Invalid!'), + array('message' => 'Invalid!', 'origin' => null, 'cause' => null), + ), + 'synchronized' => 'true', + ), $this->dataExtractor->extractSubmittedData($form)); + } + + public function testExtractSubmittedDataStoresErrorOrigin() + { + $form = $this->createBuilder('name')->getForm(); + + $error = new FormError('Invalid!'); + $error->setOrigin($form); + + $form->submit('Foobar'); + $form->addError($error); + + $this->assertSame(array( + 'submitted_data' => array( + 'norm' => "'Foobar'", + ), + 'errors' => array( + array('message' => 'Invalid!', 'origin' => spl_object_hash($form), 'cause' => null), + ), + 'synchronized' => 'true', + ), $this->dataExtractor->extractSubmittedData($form)); + } + + public function testExtractSubmittedDataStoresErrorCause() + { + $form = $this->createBuilder('name')->getForm(); + + $exception = new \Exception(); + + $form->submit('Foobar'); + $form->addError(new FormError('Invalid!', null, array(), null, $exception)); + + $this->assertSame(array( + 'submitted_data' => array( + 'norm' => "'Foobar'", + ), + 'errors' => array( + array('message' => 'Invalid!', 'origin' => null, 'cause' => 'object(Exception)'), ), 'synchronized' => 'true', ), $this->dataExtractor->extractSubmittedData($form)); @@ -353,15 +398,18 @@ class FormDataExtractorTest extends \PHPUnit_Framework_TestCase 'a' => 'bar', 'c' => 'baz', 'id' => 'foo_bar', + 'name' => 'bar', ); $this->assertSame(array( 'id' => 'foo_bar', + 'name' => 'bar', 'view_vars' => array( 'a' => "'bar'", 'b' => "'foo'", 'c' => "'baz'", 'id' => "'foo_bar'", + 'name' => "'bar'", ), ), $this->dataExtractor->extractViewVariables($view)); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php index a84d5b951a..3c9886d7cf 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php @@ -19,6 +19,7 @@ use Symfony\Component\Form\FormConfigBuilder; use Symfony\Component\Form\FormError; use Symfony\Component\PropertyAccess\PropertyPath; use Symfony\Component\Validator\ConstraintViolation; +use Symfony\Component\Validator\ConstraintViolationInterface; /** * @author Bernhard Schussek @@ -109,9 +110,9 @@ class ViolationMapperTest extends \PHPUnit_Framework_TestCase /** * @return FormError */ - protected function getFormError() + protected function getFormError(ConstraintViolationInterface $violation) { - return new FormError($this->message, $this->messageTemplate, $this->params); + return new FormError($this->message, $this->messageTemplate, $this->params, null, $violation); } public function testMapToFormInheritingParentDataIfDataDoesNotMatch() @@ -127,7 +128,7 @@ class ViolationMapperTest extends \PHPUnit_Framework_TestCase $this->mapper->mapViolation($violation, $parent); $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); - $this->assertEquals(array($this->getFormError()), $child->getErrors(), $child->getName().' should have an error, but has none'); + $this->assertEquals(array($this->getFormError($violation)), $child->getErrors(), $child->getName().' should have an error, but has none'); $this->assertCount(0, $grandChild->getErrors(), $grandChild->getName().' should not have an error, but has one'); } @@ -154,7 +155,7 @@ class ViolationMapperTest extends \PHPUnit_Framework_TestCase $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); $this->assertCount(0, $child->getErrors(), $child->getName().' should not have an error, but has one'); $this->assertCount(0, $grandChild->getErrors(), $grandChild->getName().' should not have an error, but has one'); - $this->assertEquals(array($this->getFormError()), $grandGrandChild->getErrors(), $grandGrandChild->getName().' should have an error, but has none'); + $this->assertEquals(array($this->getFormError($violation)), $grandGrandChild->getErrors(), $grandGrandChild->getName().' should have an error, but has none'); } public function testAbortMappingIfNotSynchronized() @@ -745,17 +746,17 @@ class ViolationMapperTest extends \PHPUnit_Framework_TestCase $this->mapper->mapViolation($violation, $parent); if (self::LEVEL_0 === $target) { - $this->assertEquals(array($this->getFormError()), $parent->getErrors(), $parent->getName().' should have an error, but has none'); + $this->assertEquals(array($this->getFormError($violation)), $parent->getErrors(), $parent->getName().' should have an error, but has none'); $this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one'); $this->assertCount(0, $grandChild->getErrors(), $grandChildName.' should not have an error, but has one'); } elseif (self::LEVEL_1 === $target) { $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); - $this->assertEquals(array($this->getFormError()), $child->getErrors(), $childName.' should have an error, but has none'); + $this->assertEquals(array($this->getFormError($violation)), $child->getErrors(), $childName.' should have an error, but has none'); $this->assertCount(0, $grandChild->getErrors(), $grandChildName.' should not have an error, but has one'); } else { $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); $this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one'); - $this->assertEquals(array($this->getFormError()), $grandChild->getErrors(), $grandChildName.' should have an error, but has none'); + $this->assertEquals(array($this->getFormError($violation)), $grandChild->getErrors(), $grandChildName.' should have an error, but has none'); } } @@ -1217,17 +1218,17 @@ class ViolationMapperTest extends \PHPUnit_Framework_TestCase } if (self::LEVEL_0 === $target) { - $this->assertEquals(array($this->getFormError()), $parent->getErrors(), $parent->getName().' should have an error, but has none'); + $this->assertEquals(array($this->getFormError($violation)), $parent->getErrors(), $parent->getName().' should have an error, but has none'); $this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one'); $this->assertCount(0, $grandChild->getErrors(), $grandChildName.' should not have an error, but has one'); } elseif (self::LEVEL_1 === $target) { $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); - $this->assertEquals(array($this->getFormError()), $child->getErrors(), $childName.' should have an error, but has none'); + $this->assertEquals(array($this->getFormError($violation)), $child->getErrors(), $childName.' should have an error, but has none'); $this->assertCount(0, $grandChild->getErrors(), $grandChildName.' should not have an error, but has one'); } else { $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); $this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one'); - $this->assertEquals(array($this->getFormError()), $grandChild->getErrors(), $grandChildName.' should have an error, but has none'); + $this->assertEquals(array($this->getFormError($violation)), $grandChild->getErrors(), $grandChildName.' should have an error, but has none'); } } @@ -1399,16 +1400,16 @@ class ViolationMapperTest extends \PHPUnit_Framework_TestCase if (self::LEVEL_0 === $target) { $this->assertCount(0, $errorChild->getErrors(), $errorName.' should not have an error, but has one'); - $this->assertEquals(array($this->getFormError()), $parent->getErrors(), $parent->getName().' should have an error, but has none'); + $this->assertEquals(array($this->getFormError($violation)), $parent->getErrors(), $parent->getName().' should have an error, but has none'); $this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one'); $this->assertCount(0, $grandChild->getErrors(), $grandChildName.' should not have an error, but has one'); } elseif (self::LEVEL_1 === $target) { $this->assertCount(0, $errorChild->getErrors(), $errorName.' should not have an error, but has one'); $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); - $this->assertEquals(array($this->getFormError()), $child->getErrors(), $childName.' should have an error, but has none'); + $this->assertEquals(array($this->getFormError($violation)), $child->getErrors(), $childName.' should have an error, but has none'); $this->assertCount(0, $grandChild->getErrors(), $grandChildName.' should not have an error, but has one'); } elseif (self::LEVEL_1B === $target) { - $this->assertEquals(array($this->getFormError()), $errorChild->getErrors(), $errorName.' should have an error, but has none'); + $this->assertEquals(array($this->getFormError($violation)), $errorChild->getErrors(), $errorName.' should have an error, but has none'); $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); $this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one'); $this->assertCount(0, $grandChild->getErrors(), $grandChildName.' should not have an error, but has one'); @@ -1416,7 +1417,7 @@ class ViolationMapperTest extends \PHPUnit_Framework_TestCase $this->assertCount(0, $errorChild->getErrors(), $errorName.' should not have an error, but has one'); $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); $this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one'); - $this->assertEquals(array($this->getFormError()), $grandChild->getErrors(), $grandChildName.' should have an error, but has none'); + $this->assertEquals(array($this->getFormError($violation)), $grandChild->getErrors(), $grandChildName.' should have an error, but has none'); } } @@ -1461,17 +1462,17 @@ class ViolationMapperTest extends \PHPUnit_Framework_TestCase $this->mapper->mapViolation($violation, $parent); if (self::LEVEL_0 === $target) { - $this->assertEquals(array($this->getFormError()), $parent->getErrors(), $parent->getName().' should have an error, but has none'); + $this->assertEquals(array($this->getFormError($violation)), $parent->getErrors(), $parent->getName().' should have an error, but has none'); $this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one'); $this->assertCount(0, $grandChild->getErrors(), $grandChildName.' should not have an error, but has one'); } elseif (self::LEVEL_1 === $target) { $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); - $this->assertEquals(array($this->getFormError()), $child->getErrors(), $childName.' should have an error, but has none'); + $this->assertEquals(array($this->getFormError($violation)), $child->getErrors(), $childName.' should have an error, but has none'); $this->assertCount(0, $grandChild->getErrors(), $grandChildName.' should not have an error, but has one'); } else { $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); $this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one'); - $this->assertEquals(array($this->getFormError()), $grandChild->getErrors(), $grandChildName.' should have an error, but has none'); + $this->assertEquals(array($this->getFormError($violation)), $grandChild->getErrors(), $grandChildName.' should have an error, but has none'); } } }