EasyAdmin 3:用户角色过滤器显示以前过滤器的数据

EasyAdmin 3: User role filter shows previous filter's data

使用 EasyAdmin 3.x 可以根据用户角色为用户实体的列表视图构建过滤器 select。例如,如果角色是 ROLE_REP,则使用 App\Entity\Person 实体的 RepresentativeCrudController 可能包含:

    public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
    {
        $role = serialize(["ROLE_REP"]);
        $qb = $this->get(EntityRepository::class)->createQueryBuilder($searchDto, $entityDto, $fields, $filters);
        $qb->andWhere('entity.roles = :role');
        $qb->setParameter('role', $role);

        return $qb;
    }

如果使用相同 App\Entity\Person 实体的不同名称的 CrudController 尝试使用 $role = serialize(["ROLE_SOMETHING_ELSE"]); 进行过滤,则会出现问题,应用 ROLE_REP 的查询。不同名称控制器的列表视图的 URI 与 ROLE_REP.

的 URI 相同也是事实

完全不清楚这个坑是怎么挖出来的。虽然类似于此 SO , it does not apply here. Nor is it clear how to apply the related comments at EasyCorp's github issues.

编辑:如果基于角色的 QueryBuilder 到 select 放置在扩展的 CrudController 中(例如,RepresentativeCrudController extends RoleRepCrudController),那么 Representative 的初始显示是正确的列出第二个角色的菜单提供了正确的列表。但是,使用菜单 return 到以前的 crud 控制器使用相同的 uri,从而更改列表,使原始代表 selection 消失。

这是仪表板:

class DashboardController extends AbstractDashboardController
{

    /**
     * @Route("/admin", name="admin")
     */
    public function index(): Response
    {
        $routeBuilder = $this->get(CrudUrlGenerator::class)->build();
        return $this->redirect($routeBuilder->setController(RepresentativeCrudController::class)->generateUrl());
    }

    public function configureDashboard(): Dashboard
    {
        return Dashboard::new()
                        ->setTitle('');
    }

    public function configureMenuItems(): iterable
    {
        yield MenuItem::linkToCrud('Representative', 'fa fa-home', Person::class);
        yield MenuItem::linkToCrud('Volunteer', 'fa fa-home', Person::class);
        yield MenuItem::linktoRoute('Dashboard', 'fas fa-folder-open', 'dashboard');
        yield MenuItem::linktoRoute('Home', 'fas fa-folder-open', 'home_page');
    }
...
}

和一个 CrudController:

class RepresentativeCrudController extends AbstractCrudController
{

    public static function getEntityFqcn(): string
    {
        return Person::class;
    }

    public function configureCrud(Crud $crud): Crud
    {
        return $crud
                        ->setPageTitle(Crud::PAGE_INDEX, 'Representative')
                        ->setHelp('index', 'Replacing removes current staff.')
                        ->setSearchFields(['id', 'roles', 'email', 'fname', 'sname', 'confirmationToken', 'replacementStatus']);
    }

    public function configureActions(Actions $actions): Actions
    {
        return $actions
                        ->disable('new', 'edit', 'delete');
    }

    public function configureFields(string $pageName): iterable
    {
...
        }
    }

    public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
    {
        $role = serialize(["ROLE_REP"]);
        $qb = $this->get(EntityRepository::class)->createQueryBuilder($searchDto, $entityDto, $fields, $filters);
        $qb->andWhere('entity.roles = :role');
        $qb->setParameter('role', $role);

        return $qb;
    }
...}

其实比较简单。对于每个角色,创建一个带有 querybuilder 的 crud 控制器以根据角色进行过滤。在仪表板中,configureMenuItems(),明确添加控制器。例如:

        yield MenuItem::linkToCrud('Representative', 'fa fa-home', Person::class)
                        ->setController(RepresentativeCrudController::class);

现在 Person 实体是按角色过滤的。