Symfony2 Form Event PreSetData Subscriber

末鹿安然 提交于 2019-12-10 09:27:12

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!