codeguy
codeguy

Reputation: 700

Symfony 3 - Forms as Services Issue

It seems in Symfony 3, if you want to create a form as a service so you can inject services or arguments, you can only do it once.

What I wanted to do was have 2 forms as services that use the same form type class but take different arguments to allow me to set the validation groups to use:

services:
  add_page:
    class: BackendContent\Form\PageType
    arguments: [ "add" ]
    tags:
      - { name: form.type }
  edit_page:
    class: BackendContent\Form\PageType
    arguments: [ "edit" ]
    tags:
      - { name: form.type }

But when I go and create the form in my controller, all I can do is use the FQCN and not use the alias of the form etc:

$form = $this->container->get('form.factory')->createForm(PageType::class);

This will only allow me to use one of the service definations.

The only other way around this is creating 2 forms and extending the 1 PageType form so I then have, AddPageType, EditPageType and PageType which I didn't really want to do.

Does anyone have a solution to this problem?

Sorry if this is something I have overlooked but I am unable to find anything in the docs.

Thanks!

Upvotes: 2

Views: 306

Answers (3)

user5699033
user5699033

Reputation:

You can set validation groups inside the Form's configureOptions, for example:

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'data_class' => Page::class,
        'validation_groups' => function (FormInterface $form) {
            $data = $form->getData();

            // if page exists, apply your own logic here
            if ($data->getId()) {
                return ['edit'];
            }

            return ['add'];
        }
    ]);
}

Upvotes: 0

codeguy
codeguy

Reputation: 700

The only way around this for me is creating another 2 classes called AddPageType and EditPageType, extending the PageType class and just setting the validation group in each of the Add/Edit classes.

This works fine when using the services now but it is not ideal.

services:
   add_page:
     class: BackendContent\Form\AddPageType #this extends the PageType class
     tags:
       - { name: form.type }
   edit_page:
     class: BackendContent\Form\EditPageType #this extends the PageType class
     tags:
       - { name: form.type }

Now when I create a form in my controller I can call it like this:

$form = $this->container->get('form.factory')->createForm(AddPageType::class);

This should from what I have read / been told from others, inject any services etc into my class because it is in the services.

Any further insight on this is very welcome!

Upvotes: 0

Wouter J
Wouter J

Reputation: 41934

If your form type differs for "add" and "edit", you should use 2 form types: AddPageType and EditPageType.

If only some behaviour changed, you should use form type option of your custom types.

It does not make much sense to use the same form type class for 2 different forms, that's why it's no longer possible in Symfony 3.

Upvotes: 1

Related Questions