Description
When adding violations to a form, it would be good to be able to cite the label of the attribute being validated.
Scenario - imagine a "Class Constraint" validator, as documented on this page:
http://symfony.com/doc/current/cookbook/validation/custom_constraint.html
The class constraint validator then validates the entire form, perhaps searching for bad words or something within the attributes of the form.
The validator has access to all the attributes of the form's model, but it doesn't have access to any labels or placeholder texts. Therefore when one adds a Form-wide violation, it's not easy to point the user to the field they should check.
E.g. it would be good to be able to output errors at the top or bottom of the form like this:
The word "blah blah" is invalid in "Description"
The word "xyz" is invalid in "Title"
Where "Title" or "Description" are the actual labels or hint/placeholder texts for those fields.
The whole problem is that the adding of labels to forms and the adding of data to the form objects is decoupled - meaning that the model (or form data object) has no way of knowing what labels go with what attributes.
Labels are added via the builder, or in a custom Form "Type" object, where as the attributes are defined in the Form Model/Entity/Data object.
One way we solved the issue was doing a custom ProperyPathMapper class that records the labels and hint/placeholder texts into the form data object itself, but it seems there should be a better way:
namespace Blah\Blah\DataMapper;
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
use Symfony\Component\Form\FormInterface;
class BlahPropertyPathMapper
extends PropertyPathMapper
{
public function mapDataToForm($data, FormInterface $form)
{
// Determine label, attr, and name
$label = $form->getAttribute('label');
$attr = $form->getAttribute('attr');
$name = $form->getName();
// Set the label and hint text on the data object if appropriate
$func = function ($dataObj) use ($label, $attr, $name) {
if ($label)
$dataObj->setLabel($name, $label);
if (isset($attr['placeholder']) &&
method_exists($dataObj, 'setHintText'))
$dataObj->setHintText($name,
$attr['placeholder']);
};
// Try to set label and hint text on the data object, or the form's parent's data object
$dataObj = $form->getData();
if (is_object($dataObj) && method_exists($dataObj, 'setLabel'))
$func($dataObj);
else if ($parent = $form->getParent())
{
$dataObj = $parent->getData();
if (is_object($dataObj) &&
method_exists($dataObj, 'setLabel'))
$func($dataObj);
}
// Call parent
return parent::mapDataToForm($data, $form);
}
}
p.s. I'm submitting this Feature request per Bernhard who wrote:
On Mon, Oct 8, 2012 at 10:56 PM, Bernhard Schussek <bschussek@gmail.com> wrote:
> Hi Matthew,
>
> A very short but unsatisfiable answer is that this is currently not
> supported. Could you please open a feature request on the issue
> tracker?
>
> Cheers,
> Bernhard