PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Sunday, January 23, 2022

[FIXED] Best way to filter Symfony Form CollectionType

 January 23, 2022     doctrine, symfony     No comments   

Issue

Brief introduction to my entities:

I have two enities. "User" and "Timekeepings". A "User" can have many "Timekeepings".

I want to create a form where a user can edit his timekeepings on a per day basis. So i have to filter the Timekeepings by day. What is the best approach to do this?

I could add a OneToMany relationship in my "User" entity like this:

/**
 * @ORM\OneToMany(targetEntity=Timekeeping::class, mappedBy="user")
 */
private $timekeepings;

And then filter those in my FormType, which im not quite sure how to do. But if i go this way Doctrine will fetch all "Timekeepings" for that user. I would like to the filtering on database level if possible, so only the "Timekeepings" im interested are beeing fetched from the database. For example todays date.

Another solution i thought of is by adding a non mapped field in my FormType and fill it manually.

$builder->add('timekeepings', CollectionType::class, [
    'entry_type' => TimekeepingType::class,
    'mapped' => false,
])

I could use a repository to get the Timekeepings of interest. But im not sure how to assign them to my form "timekeepings". And later retrieve them to save changes to the database.

EDIT: Alexandre suggested to use query_builder, which i initially thought of as well, but unfortunetly there is no query_builder for CollectionType


Solution

Ok so here is how i solved it:

In my controller i fetch the timekeepings of interest from my repository and pass them forward to my form via form options.

$timekeepingsProject = $this->getDoctrine()
    ->getRepository(TimekeepingProject::class)
    ->findByUserAndYearAndMonthAndDay($user, $year, $month, $day);

$form = $this->createForm(TimekeepingUserType::class, $timekeepingUser, [
    'timekeepingsProject' => $timekeepingsProject,
]);

In my form i then add an unmapped field of this type. The data of the field then gets filled with the supplied option in a 'POST_SET_DATA' FormEvent:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        // omitted fields...
        ->add('timekeepingsProject', CollectionType::class, [
            'entry_type' => TimekeepingProjectType::class,
            'allow_add' => true,
            'allow_delete' => true,
            'required' => false,
            'mapped' => false,
            'label' => false,
        ]);
    
    $builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) use($options) {
        $form = $event->getForm();
        $form->get('timekeepingsProject')->setData($options['timekeepingsProject']);
    });
}

Make sure the option is set as required in the form:

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setRequired('timekeepingsProject');
    $resolver->setDefaults([
        'data_class' => TimekeepingUser::class,
    ]);
}

Finally my controller handles persisting/removing the timekeepingsProject object to the database. This has to be done because the field is marked as unmapped and thus gets not automatically saved to the database. Unmapped fields can be accessed like this:

$form['timekeepingsProject']->getData()


Answered By - Reeley
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing