EasyAdminBundle icon indicating copy to clipboard operation
EasyAdminBundle copied to clipboard

No way to disable fields based on entity property

Open nicklocking opened this issue 1 year ago • 3 comments

Describe the bug

Imagine you have an Order entity. It has a property named address (string) and submitted (bool). If the order is submitted=false, the address property can be edited. If the order is submitted=true, it cannot.

I can't work out a clean way of doing this with the existing EasyAdmin code. I can get to a point where I can optionally add fields to the edit form by hooking in to createEditFormBuilder, but they don't appear styled like EasyAdmin form fields so it feels like there must be a better way.

In the same way that Field::formatValue() takes a callable function, I would expect there to be some sort of Field::customizeField() method that takes a similar callable.

To Reproduce

Create entity as described above and then attempt to make a field's disabled property dynamic based on another entity property.

nicklocking avatar Aug 09 '24 06:08 nicklocking

In edit mode you can access $this->adminContext and from it the entity dto and the actual instance. Then you can change the configuration to your needs, based on given values, in configureFields method of your CrudController.

a-r-m-i-n avatar Aug 09 '24 09:08 a-r-m-i-n

https://github.com/EasyCorp/EasyAdminBundle/issues/6102 I have same problem and do it via security voter and setPermission on field. Will not work on index page, but I just disabled that field there.

Something like this in my case

//in controller configureFields
Field::new('disabled')->setPermission('NOT_YOURSELF')->setDisabled(Crud::PAGE_INDEX === $pageName)
<?php

namespace App\Security\Voter;

use EasyCorp\Bundle\EasyAdminBundle\Provider\AdminContextProvider;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\User\UserInterface;

class NotYourselfVoter extends Voter
{
    public const ATTR = 'NOT_YOURSELF';

    public function __construct(
        private AdminContextProvider $adminProvider,
    ) {}

    protected function supports(string $attribute, mixed $subject): bool
    {
        return $attribute === self::ATTR;
    }

    protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
    {
        $user = $token->getUser();
        // if the user is anonymous, grant access
        if (!$user instanceof UserInterface) {
            return true;
        }

        if (null === $entity = $this->adminProvider->getContext()->getEntity()->getInstance()) {
            return true;
        }

        return $entity->getUserIdentifier() !== $user->getUserIdentifier();
    }
}

zorn-v avatar Aug 11 '24 04:08 zorn-v

I have same problem

Not the same :smile: - you need just disable it. Then as @a-r-m-i-n said inject admin context and something like

->setDisabled($this->adminProvider->getContext()->getEntity()->getInstance()?->isSubmitted() ?? false)

zorn-v avatar Aug 11 '24 05:08 zorn-v