[Form] Errors now reference the field they were added to and the violation/exception that caused them
This commit is contained in:
parent
a596ba362b
commit
c8a0ee6b3a
|
@ -191,7 +191,7 @@
|
|||
</div>
|
||||
|
||||
{% for formName, formData in collector.data.forms %}
|
||||
{{ form_tree_details(formName, formData) }}
|
||||
{{ form_tree_details(formName, formData, collector.data.forms_by_hash) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
|
@ -366,7 +366,7 @@
|
|||
</li>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro form_tree_details(name, data) %}
|
||||
{% macro form_tree_details(name, data, forms_by_hash) %}
|
||||
<div class="tree-details" id="{{ data.id }}-details">
|
||||
<h2>
|
||||
{{ name }}
|
||||
|
@ -386,13 +386,32 @@
|
|||
|
||||
<table id="{{ data.id }}-errors">
|
||||
<tr>
|
||||
<th width="50%">Message</th>
|
||||
<th>Message</th>
|
||||
<th>Origin</th>
|
||||
<th>Cause</th>
|
||||
</tr>
|
||||
{% for error in data.errors %}
|
||||
<tr>
|
||||
<td>{{ error.message }}</td>
|
||||
<td><em>Unknown.</em></td>
|
||||
<td>
|
||||
{% if error.origin is empty %}
|
||||
<em>This form.</em>
|
||||
{% elseif forms_by_hash[error.origin] is not defined %}
|
||||
<em>Unknown.</em>
|
||||
{% else %}
|
||||
{{ forms_by_hash[error.origin].name }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if error.cause is empty %}
|
||||
<em>Unknown.</em>
|
||||
{% elseif error.cause.root is defined %}
|
||||
<strong>Constraint Violation</strong><br/>
|
||||
<pre>{{ error.cause.root }}{% if error.cause.path is not empty %}{% if error.cause.path|first != '[' %}.{% endif %}{{ error.cause.path }}{% endif %} = {{ error.cause.value }}</pre>
|
||||
{% else %}
|
||||
<pre>{{ error.cause }}</pre>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
@ -565,6 +584,6 @@
|
|||
</div>
|
||||
|
||||
{% for childName, childData in data.children %}
|
||||
{{ _self.form_tree_details(childName, childData) }}
|
||||
{{ _self.form_tree_details(childName, childData, forms_by_hash) }}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
|
|
|
@ -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
|
||||
-----
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -128,7 +128,8 @@ class ViolationMapper implements ViolationMapperInterface
|
|||
$violation->getMessage(),
|
||||
$violation->getMessageTemplate(),
|
||||
$violation->getMessageParameters(),
|
||||
$violation->getMessagePluralization()
|
||||
$violation->getMessagePluralization(),
|
||||
$violation
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -11,12 +11,14 @@
|
|||
|
||||
namespace Symfony\Component\Form;
|
||||
|
||||
use Symfony\Component\Form\Exception\BadMethodCallException;
|
||||
|
||||
/**
|
||||
* Wraps errors in forms
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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 <bschussek@gmail.com>
|
||||
|
@ -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');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Reference in New Issue