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

Wednesday, May 11, 2022

[FIXED] How to add additional options on Symfony EntityType form widget?

 May 11, 2022     forms, symfony     No comments   

Issue

I have a filter form in Symfony, which can filter for an Entity. For this purpose, I have a field with an EntityFilterType (Lexik\Bundle\FormFilterBundle\Filter\Form\Type\EntityFilterType), which simply extends Symfony's builtin EntityType.

Now I want to add an "all" and a "none" option to this EntityType. If it was a ChoiceType, I would simply change the choices array, but the EntityType only accepts valid Entity-IDs as its value on submit and also only Entities in the array given to the 'choices' option.

My question is: How can I add additional options to an EntityType form field? Besides the ugly way to reimplement the Entity-stuff into a ChoiceType field? Any ideas on this? Am I missing a documented way?

Greets, spackmat


Solution

Some years have passed and the setting shines up again:

I have a ManyToMany related Entity that I want to filter for using the LexikFormFilterBundle. But I also want to allow to filter explicitly for Entities that have no such related Entity. In my case I want to allow to filter for ToDos that are assigned to some specific Users, but allow also to filter for ToDos that are not assigned at all. So the problems begin.

My solution for now is, indeed, switching to a ChoiceType::class and that looks like this:

// We are in a buildForm function of a Filter-Form extending
// Symfony\Component\Form\AbstractType and using The LexikFormFilterBundle

// prepare the choices with a "none"-choice on top
// feel free to add also a "all"-choice, if that is needed
$myChoices = [
    'None of those' => 'none',
];
foreach ($this->myWhateverRepository->getMyChoices() as $myChoice) {
    // where $myChoice is some related Entity
    $myChoices[$myChoice->getIdentifyingName()] = $myChoice->getId();
}
/*
now we have an array like this:
[
    'None of those' => 'none',
    'One related Entity' => 2,
    'Another related Entity' => 4,
]
*/

$builder    
    ->add('relatedWhatevers', ChoiceFilterType::class, [
        'choices' => $myChoices,
        'multiple' => true,
        'label' => 'Filter for related whatevers',
        'required' => false,
        'apply_filter' => function (QueryInterface $filterQuery, $field, $values) {
            if (count($values['value']) === 0) {
                // nothing to filter here
                return null;
            }

            $orNone = in_array('none', $values['value']);
            $myWhateverIds = array_filter($values['value'], function($v) { return 'none' !== $v; });

            // join the related field and don't forget to do that as an
            // innerJoin, otherwise the isNull() doesn't find anything
            $query = $filterQuery->getQueryBuilder();
            $query->leftJoin($field, 'myWhatever');

            if ($orNone) {
                if (count($userIds) > 0) {
                    $expression = $filterQuery->getExpr()->orX(
                        $filterQuery->getExpr()->isNull('myWhatever'),
                        $filterQuery->getExpr()->in('myWhatever.id', $myWhateverIds)
                    );
                }
                else {
                    $expression = $filterQuery->getExpr()->isNull('myWhatever');
                }
            }
            else {
                $expression = $filterQuery->getExpr()->in('myWhatever.id', $userIds);
            }
            return $filterQuery->createCondition($expression, []);
        },
    ])
;

And that works: I can find ToDos assigned to some Users and/or are assigned to nobody. And when I don't fill the field, the filter does not do anything.



Answered By - spackmat
Answer Checked By - Cary Denson (PHPFixing Admin)
  • 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