Search code examples
symfonyeasyadmin

access entity property from type_options


In my entity I defined a field color with a callback. The colors can only be selected in the COLORS list (const in this class)

/**
 * @ORM\Entity(repositoryClass="App\Repository\EventTagRepository")
 */
class EventTag
{
    const COLORS = [
        "primary"=>"primary", 
        "secondary"=>"secondary", 
        "success"=> "success", 
        "danger"=>"danger", 
        "warning"=>"warning", 
        "info"=>"info", 
        "light"=>"light", 
        "dark"=>"dark"
    ];

   /**
     * @ORM\Column(type="string", length=255)
     * @Assert\Choice(callback="getColors")
     */
    private $color;

    public function getColors()
    {
        return $this::COLORS;
    }

When I'm creating the form in easy-admin, I'd like to access this callback in the choice type options to prevent the user to choose a wrong color.

EventTag:
            class: App\Entity\EventTag
            list:
                actions: ['-delete']
            form:
                fields:
                    - { type: 'group', label: 'Content', icon: 'pencil-alt', columns: 8 }
                    - 'name'
                    - { property: 'color', type: 'choice', type_options: { expanded: false, multiple: false, choices: 'colors'} }

Unfortunately in the type_options I didn't find a way to access the entity properties, instead of searching for getColors(), IsColors(), hasColors() methods, it only reads the string.

Is it possible to do it another way ?


Solution

  • The callback refers to an entity const:

    you can use

    @Assert\Choice(choices=EventTag::COLORS)
    

    in the PHP entity and

    choices: App\Entity\EventTag::COLORS 
    

    in the YAML config

    the callback refers to a more specific value:

    you need to manually extend the AdminController

    public function createCategoryEntityFormBuilder($entity, $view)
        {
            $formBuilder = parent::createEntityFormBuilder($entity, $view);
    
            $field = $formBuilder->get('type');
            $options = $field->getOptions();
            $attr = $field->getAttributes();
    
            $options['choices'] = $formBuilder->getData()->getTypeLabels();
            $formBuilder->add($field->getName(), ChoiceType::class, $options);
            $formBuilder->get($field->getName())
                ->setAttribute('easyadmin_form_tab', $attr['easyadmin_form_tab'])
                ->setAttribute('easyadmin_form_group', $attr['easyadmin_form_group']);
    
            return $formBuilder;
        }
    

    As $formBuilder->add erases attributes we need to set them again manually. Probably it can be skipped if you are not using Groups/Tabs, otherwise it will throw Exception saying that field was already rendered.