Skip to content

Instantly share code, notes, and snippets.

@pjedrzejewski
Created December 11, 2015 09:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pjedrzejewski/a9d6728410040fc838fd to your computer and use it in GitHub Desktop.
Save pjedrzejewski/a9d6728410040fc838fd to your computer and use it in GitHub Desktop.
Issues with removing form type names in Symfony 3.0.
<?php
class ResourceAutocompleteType extends AbstractType
{
// ...
private $resourceName;
public function __construct($resourceName)
{
$this->resourceName = $resourceName;
}
public function getName()
{
return sprintf('sylius_%s_autocomplete', $this->resourceName);
}
}
// This allows us to generate form types:
// sylius_product_autocomplete
// sylius_customer_autocomplete
// Expected DX:
class MyCustomType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('products', 'sylius_product_autocomplete', array(
'multiple' => true,
))
;
}
}
// In Symfony 3.0 we would need to:
class ResourceAutocompleteType extends AbstractType
{
// ...
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setRequired(array('resource')); // etc.
}
public function getName()
{
return 'sylius_resource_autocomplete';
}
}
// Which results in following DX:
class MyCustomType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('products', 'sylius_resource_autocomplete', array(
'resource' => 'sylius.product',
'multiple' => true,
))
;
}
}
/* This also affects other aspects of DX and our implementation:
* We can no longer generate the form types based on configuration;
* We cannot easily pass dependencies to specific form types;
* Developer (end-user of the bundles/app) cannot override a specific form type easily:
Right now can override ``sylius_product_autocomplete`` to change all autocompletes across whole app.
With forms without type names, he would need to override all forms using ResourceAutocompleteType::class and replace it with his own class etc.
*/
@peterrehm
Copy link

You could also create one Type extending the ResourceAutocompleteType per category which might be a clean solution as well, depending on how many resource types you have.

Otherwise the option is also a feasible solution, upgrading can be some pain.

@webmozart
Copy link

Hi Pawel! Unfortunately auto-generation of form types was never an officially supported feature. With some shortening, your type could be adapted to:

class MyCustomType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('products', AutocompleteType::class, array(
                'resource' => Product::class,
                'multiple' => true,
            ))
        ;
    }
}

This is pretty straight-forward and easy to use. Naming conflicts are now dealt with implicitly since you are importing the class name.

Developers can override your AutocompleteType entirely or add a type extension that is only activated if resource matches a certain class.

Dependencies should be passed in the DIC (as always).

@koemeet
Copy link

koemeet commented Dec 19, 2015

@pjedrzejewski And what about using form type extensions to allow users to override Sylius form types? I think that is also the recommended way now to override form types in symfony 3.0. They live in a seperate service, and injecting stuff is easier, instead of altering the definition in a compiler pass.

@rvanlaak
Copy link

rvanlaak commented Oct 14, 2016

@pjedrzejewski how can the container eventually resolve sprintf('sylius_%s_autocomplete', $this->resourceName) to sylius_product_autocomplete? There should be some extra configuration to handle that right? That same configuration (e.g. the Product::class) should in my opinion be handled via the options, as @webmozart mentions in https://gist.github.com/pjedrzejewski/a9d6728410040fc838fd#gistcomment-1647210

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment