skip to Main Content

I’m having a hard time building forms for my entities that are themselves built with traits.

For example my “Article” entity only contains the link to the category and 2 pics, the rest of its properties is in the SeoTrait (title, meta_title, meta_desc, content, etc…), ValidTrait (isValid true/false)… which I want to use for other entities.

It all works fine for doctrine, that generates my schema with all the fields from the Traits in each entity that use them. The problem is for the forms :

I’ve created the SeoTraitType for the “SEO” properties :

class SeoTraitType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class, array(
                'label' => 'Nom'
            ))
            ->add('metaTitle', TextType::class, array(
                'label' => 'Meta Title'
            ))
            ->add('metaDescription', TextareaType::class, array(
                'label' => 'Meta Description'
            ))
            ->add('metaKeywords', TextType::class, array(
                'label' => 'Keywords'
            ))
            ->add('content', TextareaType::class, array(
                'label' => 'Content'
            ))
        ;
    }
}

And then I’m using it in my ArticleType :

class ArticleType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('seo', SeoTraitType::class, array(
                'label' => 'Seo',
                'mapped' => false
            ))
            ->add('isValid',    ValidTraitType::class,      array(
                'label' => 'Valid',
                'mapped' => false
            ))
            ->add('save',       SubmitType::class,          array(
                'label' => 'form_save',
                'translation_domain' => 'back_default'
            ));
        ;
    }
}

The two problems I have here is that I must set mapped => false for the 2 TraitTypes when I want to embed them in my main entity’s form
And then in my form I get article[seo][name] for the SeoTrait’s fields, so I can’t really use the $form->handleRequest() methods and all… to handle the submission of my form

I was wondering if there is a special way to do this within the provided methods of the form component, or if I just have to handle the request myself and parse the trait arrays myself to build my entity before saving it ? I couldn’t really find anything on the internet 🙁

2

Answers


  1. Chosen as BEST ANSWER

    Ok so the Trait solution works fine, but I chose to go for this method here : https://symfony.com/doc/current/form/inherit_data_option.html

    Thanks so much guys, I was pretty sure that the solution would be somewhere in the documentation but couldn't find it !


  2. One way to solve your problem is to transform your class SeoTraitType into a Trait.

    like:

    trait SeoTraitType
    {
        public function buildSEOForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('name', TextType::class, array(
                    'label' => 'Nom'
                ))
                ->add('metaTitle', TextType::class, array(
                    'label' => 'Meta Title'
                ))
                ->add('metaDescription', TextareaType::class, array(
                    'label' => 'Meta Description'
                ))
                ->add('metaKeywords', TextType::class, array(
                    'label' => 'Keywords'
                ))
                ->add('content', TextareaType::class, array(
                    'label' => 'Content'
                ))
            ;
        }
    }
    

    Then:

    class ArticleType extends AbstractType
    {
        use SeoTraitType;
    
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $this->buildSEOForm($builder, $options);
    
            $builder
                ->add('isValid',    ValidTraitType::class,      array(
                    'label' => 'Valid',
                    'mapped' => false
                ))
                ->add('save',       SubmitType::class,          array(
                    'label' => 'form_save',
                    'translation_domain' => 'back_default'
                ));
            ;
        }
    }
    

    You can also do this with static method. Not a big fan of Trait.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search