Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ae6c88d

Browse filesBrowse files
committed
[Form] The trace of form errors is now displayed in the profiler
1 parent 499eeb4 commit ae6c88d
Copy full SHA for ae6c88d

File tree

Expand file treeCollapse file tree

7 files changed

+87
-22
lines changed
Filter options
Expand file treeCollapse file tree

7 files changed

+87
-22
lines changed

‎src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig
+21-7Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -473,14 +473,28 @@
473473
{% endif %}
474474
</td>
475475
<td>
476-
{% if error.cause is empty %}
477-
<em>Unknown.</em>
478-
{% elseif error.cause.root is defined %}
479-
<strong>Constraint Violation</strong><br/>
480-
<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>
476+
{% for trace in error.trace %}
477+
{% if not loop.first %}
478+
<br/>Caused by:<br/><br/>
479+
{% endif %}
480+
{% if trace.root is defined %}
481+
<strong>{{ trace.class }}</strong><br/>
482+
<pre>
483+
{{- trace.root -}}
484+
{%- if trace.path is not empty -%}
485+
{%- if trace.path|first != '[' %}.{% endif -%}
486+
{{- trace.path -}}
487+
{%- endif %} = {{ trace.value -}}
488+
</pre>
489+
{% elseif trace.message is defined %}
490+
<strong>{{ trace.class }}</strong><br/>
491+
<pre>{{ trace.message }}</pre>
492+
{% else %}
493+
<pre>{{ trace }}</pre>
494+
{% endif %}
481495
{% else %}
482-
<pre>{{ error.cause }}</pre>
483-
{% endif %}
496+
<em>Unknown.</em>
497+
{% endfor %}
484498
</td>
485499
</tr>
486500
{% endfor %}

‎src/Symfony/Component/Form/Button.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Button.php
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\Form\Exception\AlreadySubmittedException;
1515
use Symfony\Component\Form\Exception\BadMethodCallException;
16+
use Symfony\Component\Form\Exception\TransformationFailedException;
1617

1718
/**
1819
* A form button.
@@ -344,6 +345,15 @@ public function isSynchronized()
344345
return true;
345346
}
346347

348+
/**
349+
* Unsupported method.
350+
*
351+
* @return null Always returns null
352+
*/
353+
public function getTransformationFailure()
354+
{
355+
}
356+
347357
/**
348358
* Unsupported method.
349359
*

‎src/Symfony/Component/Form/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ CHANGELOG
2121
* ObjectChoiceList now compares choices by their value, if a value path is
2222
given
2323
* you can now pass interface names in the "data_class" option
24+
* [BC BREAK] added `FormInterface::getTransformationFailure()`
2425

2526
2.4.0
2627
-----

‎src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php
+29-8Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,18 +115,39 @@ public function extractSubmittedData(FormInterface $form)
115115
'origin' => is_object($error->getOrigin())
116116
? spl_object_hash($error->getOrigin())
117117
: null,
118+
'trace' => array(),
118119
);
119120

120121
$cause = $error->getCause();
121122

122-
if ($cause instanceof ConstraintViolationInterface) {
123-
$errorData['cause'] = array(
124-
'root' => $this->valueExporter->exportValue($cause->getRoot()),
125-
'path' => $this->valueExporter->exportValue($cause->getPropertyPath()),
126-
'value' => $this->valueExporter->exportValue($cause->getInvalidValue()),
127-
);
128-
} else {
129-
$errorData['cause'] = null !== $cause ? $this->valueExporter->exportValue($cause) : null;
123+
while (null !== $cause) {
124+
if ($cause instanceof ConstraintViolationInterface) {
125+
$errorData['trace'][] = array(
126+
'class' => $this->valueExporter->exportValue(get_class($cause)),
127+
'root' => $this->valueExporter->exportValue($cause->getRoot()),
128+
'path' => $this->valueExporter->exportValue($cause->getPropertyPath()),
129+
'value' => $this->valueExporter->exportValue($cause->getInvalidValue()),
130+
);
131+
132+
$cause = method_exists($cause, 'getCause') ? $cause->getCause() : null;
133+
134+
continue;
135+
}
136+
137+
if ($cause instanceof \Exception) {
138+
$errorData['trace'][] = array(
139+
'class' => $this->valueExporter->exportValue(get_class($cause)),
140+
'message' => $this->valueExporter->exportValue($cause->getMessage()),
141+
);
142+
143+
$cause = $cause->getPrevious();
144+
145+
continue;
146+
}
147+
148+
$errorData['trace'][] = $cause;
149+
150+
break;
130151
}
131152

132153
$data['errors'][] = $errorData;

‎src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ public function validate($form, Constraint $constraint)
103103
->setParameters(array_replace(array('{{ value }}' => $clientDataAsString), $config->getOption('invalid_message_parameters')))
104104
->setInvalidValue($form->getViewData())
105105
->setCode(Form::ERR_INVALID)
106+
->setCause($form->getTransformationFailure())
106107
->addViolation();
107108
}
108109
}

‎src/Symfony/Component/Form/Form.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Form.php
+13-7Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,10 @@ class Form implements \IteratorAggregate, FormInterface
121121
private $extraData = array();
122122

123123
/**
124-
* Whether the data in model, normalized and view format is
125-
* synchronized. Data may not be synchronized if transformation errors
126-
* occur.
127-
* @var bool
124+
* Returns the transformation failure generated during submission, if any
125+
* @var TransformationFailedException|null
128126
*/
129-
private $synchronized = true;
127+
private $transformationFailure;
130128

131129
/**
132130
* Whether the form's data has been initialized.
@@ -634,7 +632,7 @@ public function submit($submittedData, $clearMissing = true)
634632
$viewData = $this->normToView($normData);
635633
}
636634
} catch (TransformationFailedException $e) {
637-
$this->synchronized = false;
635+
$this->transformationFailure = $e;
638636

639637
// If $viewData was not yet set, set it to $submittedData so that
640638
// the erroneous data is accessible on the form.
@@ -711,7 +709,15 @@ public function isBound()
711709
*/
712710
public function isSynchronized()
713711
{
714-
return $this->synchronized;
712+
return null === $this->transformationFailure;
713+
}
714+
715+
/**
716+
* {@inheritdoc}
717+
*/
718+
public function getTransformationFailure()
719+
{
720+
return $this->transformationFailure;
715721
}
716722

717723
/**

‎src/Symfony/Component/Form/FormInterface.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/FormInterface.php
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\Form;
1313

14+
use Symfony\Component\Form\Exception\TransformationFailedException;
15+
1416
/**
1517
* A form group bundling multiple forms in a hierarchical structure.
1618
*
@@ -230,10 +232,20 @@ public function isEmpty();
230232
/**
231233
* Returns whether the data in the different formats is synchronized.
232234
*
235+
* If the data is not synchronized, you can get the transformation failure
236+
* by calling {@link getTransformationFailure()}.
237+
*
233238
* @return bool
234239
*/
235240
public function isSynchronized();
236241

242+
/**
243+
* Returns the data transformation failure, if any.
244+
*
245+
* @return TransformationFailedException|null The transformation failure
246+
*/
247+
public function getTransformationFailure();
248+
237249
/**
238250
* Initializes the form tree.
239251
*

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.