在我的应用程序中,用户可以为某些实体创建自定义字段,然后在我显示表单时为每个实体对象设置此自定义字段的值。
实现是这样的:
1º)我为表单创建了一个接口,我想要实现这个接口的表单。
2º)我为所有表单创建了一个表单扩展:
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º) 在这个扩展中,如果表单实现了步骤 1 中引用的接口,我添加一个 EventSubscriber:
if($formType instanceof \App\Core\Bundle\FormBuilderBundle\Model\IAllowCustomFieldsdInterface){
$builder->addEventSubscriber(new FormSubscriber($this->container, $this->em));
}
4º) 此表单订阅者订阅 preSetData FormEvent。在这种方法中,我获得了与表单关联的实体,并获得了为其创建的所有自定义字段。然后我在 Symfony2 Form Type 的帮助下将此字段添加到表单中。一切顺利,当我显示我的表单时,自定义字段呈现正确。仅作记录,当我保存表单时,自定义字段中插入的值也可以很好地存储。
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());
}
}
}
}
}
问题是当我尝试编辑表单时。如果您查看上面代码中“问题在这里”的部分,您就可以理解。
如果表单的对象具有 ID,那么我将获取为该对象的自定义字段存储的值,然后调用 $form[field_alias']->setData(从映射为数组类型的数据库返回的值)。
但这不起作用,并且没有为字段设置数据。但如果在我的控制器中我也这样做,则数据设置正确。
有人知道问题出在哪里吗?我不能在 preSetData 事件中设置数据吗?
已编辑
Entity DbCustomField 中的值字段以这种方式映射:
/**
* @var string
*
* @ORM\Column(name="value", type="array", nullable=true)
*/
protected $value;
`
var_dump($DbCustomFieldValue)
-> 对象(Ueb\Core\Bundle\SchemaBundle\Entity\DbCustomFieldValue)
var_dump(DbCustomFieldValue->getValue())
-> 字符串(11)“布鲁诺勇气”
但即使我尝试类似:
var_dump($customField->getFieldAlias());
= 字符串(21)“testebruno-1383147874”
$form[$customField->getFieldAlias()]->setData('example1');
它不起作用。
但是在我的控制器中,如果我对上面的 fieldAlias 执行以下操作:
$form['testebruno-1383147874']->setData('example2');
-> 它确实有效
任何想法?