简体   繁体   中英

Backward compatibility breaks in forms upgrading from symfony2.8 to 3.0

So the upgrade from symfony 2.8 to 3.0 (or to 3.4 actually which is the goal for now) which I have been dragging my feet with is every bit as troublesome as some of the previous minor updates. Some frameworks just love forcing you to rewrite code, I guess...

Anyways, I know this has been treated in a number of other posts, but I want to make it foolproof, like a "symfony forms for dummies" moving your forms from symfony 2.8 to 3.0.

If you run your app through app_dev.php you get nice hints in the footer regarding what is deprecated, in other words what won't work in version 3.0.

The deprecation message for this particular issue is:

Passing type instances to FormBuilder::add(), Form::add() or the FormFactory is deprecated since version 2.8 and will not be supported in 3.0. Use the fully-qualified type class name instead

The first thing I had to do about my forms was to change the way they are called from the controller. The symfony documentation is satisfied in saying:

Before:

$form = $this->createForm(new MyType());

After:

$form = $this->createForm(MyType::class);

But hold on, how then do I pass in my variables?? My form calls look more like this:

$form = $this->createForm(new extraOpeningType($user), $extraOpening);

I pass both the entity to match with the form, and an additional entity for permission purposes. Not big enough of an issue for the nice changelog guys at Sensiolabs to even comment on it.

Someone else noticed this and wrote up an issue for it here ( https://github.com/symfony/symfony/issues/18662 ) though he has a typo or two in his sample code. There is also an SO article here ( Passing data to buildForm() in Symfony 2.8, 3.0 and above ) that was very helpful in figuring this out.

So in my case, in pre-symfony3.0 I used to call the form like this:

$form = $this->createForm(new extraOpeningType($user), $extraOpening);

$user is a variable that I pass in for permission handling purposes in the form data, and $extraOpening is the actual entity matched up with the form. Here is how you now have to pass those variables from now on:

use ExtraOpeningBundle\Form\ExtraOpeningType as extraOpeningType; //this goes in the controller head, among your USE statements
...
$form = $this->createForm(extraOpeningType::class, $extraOpening, ['user' => $user]);

If you prefer not to use the USE statement in the head, you can put the fully qualified path to your Type instead, like this (note the leading backslash on the Type path):

$form = $this->createForm(\ExtraOpeningBundle\Form\ExtraOpeningType::class, $extraOpening, ['user' => $user]);

And on the receiving side, in your form (Type, as symfony terms it), where you previously had a constructor to pull in the passed variable...

class ExtraOpeningType extends AbstractType
{
    function __construct($user)
    {
        $this->user = $user;
    }

    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $user = $this->user;

Now it just looks like this:

class ExtraOpeningType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $this->user = $options['user'];  

Though you need to add this custom option that you just created to the list of approved options, otherwise you will be faced with an error saying 'user' is not a valid option. So amend your configureOptions method as below (create that method if you aren't already using it):

class ExtraOpeningType extends AbstractType
{

...

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'user' => null
        ));
    }

Symfony is often a dream, but when it comes to updates it can be a nightmare. Lots of backwards compatibility breaks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM