问题
In my Application the user can create Custom Fields for some entities and then set the values for this custom fields for each entity object when i display a form.
The implementation is like this:
1º) I created a Interface for the forms, and the forms that i want implement this Interface.
2º) I created a form extension for all forms:
app_core_form_builder.form_extension:
class: App\Core\Bundle\FormBuilderBundle\Form\FormExtension
arguments: ["@service_container", "@doctrine.orm.entity_manager"]
tags:
- { name: form.type_extension, alias: form }
3º) In this extension if the form implements the interface referenced in the step 1 i add a EventSubscriber:
if($formType instanceof \App\Core\Bundle\FormBuilderBundle\Model\IAllowCustomFieldsdInterface){
$builder->addEventSubscriber(new FormSubscriber($this->container, $this->em));
}
4º) This Form Subscriber subscribes the preSetData FormEvent. In this method i get the Entity associated with the form and i get all custom fields created for it. Then i add this fields to the form with the help of Symfony2 Form Type. Everything goes well, and when i display my form the custom fields are rendered correct. Just for the record, when i save the form the values inserted in the custom fields also are store well.
public function preSetData(FormEvent $event) {
$data = $event->getData();
$form = $event->getForm();
// During form creation setData() is called with null as an argument
// by the FormBuilder constructor. You're only concerned with when
// setData is called with an actual Entity object in it (whether new
// or fetched with Doctrine). This if statement lets you skip right
// over the null condition.
if (null === $data) {
return;
}
$formEntity = $form->getConfig()->getType()->getInnerType()->getEntity();
$DbEntity = $this->em->getRepository('AppCoreSchemaBundle:DbEntity')->findOneBy(array('id' => $formEntity));
if ($DbEntity && $DbEntity->getAllowCustomFields()) {
$organization = $this->container->get('app_user.user_manager')->getCurrentOrganization();
if (!$organization) {
throw $this->createNotFoundException('Unable to find Organization entity.');
}
$params = array(
'organization' => $organization,
'entity' => $DbEntity,
);
$entities = $this->em->getRepository('AppCoreSchemaBundle:DbCustomField')->getAll($params);
# RUN BY ALL CUSTOM FIELDS AND ADD APPROPRIATE FIELD TYPES AND VALIDATORS
foreach ($entities as $customField) {
# configurate customfield
FieldConfiguration::configurate($customField, $form);
# THE PROBLEM IS HERE
# IF OBJECT IS NOT NULL THEN MAKE SET DATA FOR APPROPRIATED FIELD
if ($data->getId()) {
$filters = array(
'custom_field' => $customField,
'object' => $data->getId(),
);
$DbCustomFieldValue = $this->em->getRepository('UebCoreSchemaBundle:DbCustomFieldValue')->getFieldValue($filters);
if ($DbCustomFieldValue) {
$form[$customField->getFieldAlias()]->setData($DbCustomFieldValue->getValue());
} else {
$form[$customField->getFieldAlias()]->setData(array());
}
}
}
}
}
The problem is when i try to edit a form. if you look at the part in the code above where says "THE PROBLEM IS HERE" you can understand.
If the object of the form has an ID, then i will get the values stored for the custom fields of that object, and i call $form[field_alias']->setData(value returned from database that is mapped as type Array).
But this dont work, and the Data is not set for the fields. But if in my controller i do the same, the data is set properly.
Does anybody have an idea where the problem can be? Can't i set the data in preSetData Event?
EDITED
The value field from the Entity DbCustomField is mapped in this way:
/**
* @var string
*
* @ORM\Column(name="value", type="array", nullable=true)
*/
protected $value;
`
var_dump($DbCustomFieldValue)
-> object(Ueb\Core\Bundle\SchemaBundle\Entity\DbCustomFieldValue)
var_dump(DbCustomFieldValue->getValue())
-> string(11) "bruno valor"
But even if i try something like:
var_dump($customField->getFieldAlias());
= string(21) "testebruno-1383147874"
$form[$customField->getFieldAlias()]->setData('example1');
it doesnt work.
But in my controller if i do the following for the fieldAlias above:
$form['testebruno-1383147874']->setData('example2');
-> it does work
Any idea?
回答1:
As metalvarez suggested in his/her comment and working as expected, use the postSetData
event instead of the preSetData
one:
public function postSetData(FormEvent $event) {
// ...
}
The preSetData
event method is called before populating the form with default values, then Symfony2 will set the data and it may change from what you set before, thus the use of postSetData
instead.

Figure from the doc
来源:https://stackoverflow.com/questions/19691951/symfony2-form-event-presetdata-subscriber