Symfony EasyAdminBundle 3 覆盖 createIndexQueryBuilder()
Symfony EasyAdminBundle 3 override the createIndexQueryBuilder()
EasyAdminBundle 文档上说
For example, the index() action calls to a method named createIndexQueryBuilder() to create the Doctrine query builder used to get the results displayed on the index listing. If you want to customize that listing, it’s better to override the createIndexQueryBuilder() method instead of the entire index() method.
所以让我们想象一下,当用户被删除时,我在我的用户实体中将字段 isDeleted 设置为 true。在索引页中,我只想显示 isDeleted = false 的用户。
如何为此目的覆盖 createIndexQueryBuilder()?
这是方法 createIndexQueryBuilder
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
{
return $this->get(EntityRepository::class)->createQueryBuilder($searchDto, $entityDto, $fields, $filters);
}
我试过像这样覆盖它,但没有成功
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
{
$response = $this->get(EntityRepository::class)->createQueryBuilder($searchDto, $entityDto, $fields, $filters);
$response->where('isDeleted', true);
return $response;
}
您只需要在 where 子句中添加 entity.
:)
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
{
parent::createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters);
$response = $this->get(EntityRepository::class)->createQueryBuilder($searchDto, $entityDto, $fields, $filters);
$response->where('entity.isDeleted = 1');
return $response;
}
这里有一个关于如何在 EasyAdmin 中替换 DQL FILTER 的例子v3.x
EasyAdmin v2.x DQL 过滤器:
easy_admin:
entities:
User:
class: App\Entity\User
list:
dql_filter: "entity.roles NOT LIKE '%%ROLE_SUPER_ADMIN%%'"
EasyAdmin v3.x 在 UserCrudController 中:
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
{
$response = $this->get(EntityRepository::class)->createQueryBuilder($searchDto, $entityDto, $fields, $filters);
$response->where("entity.roles NOT LIKE '%%ROLE_SUPER_ADMIN%%'");
return $response;
}
对于使用已接受的答案关注 QueryException 并通过搜索找到它的每个人:
QueryException
Too many parameters: the query defines 1 parameters and you bound 3
您的 EntityCrudController 中的 EasyAdmin v3.x:
- 使用->andWhere()函数
- 使用 entity. 作为前缀(真的,使用“实体”,不要替换为您的实体名称)
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
{
$response = $this->get(EntityRepository::class)->createQueryBuilder($searchDto, $entityDto, $fields, $filters);
$response->andWhere('entity.isDeleted = 1');
return $response;
}
EasyAdmin 对我有用4.x
use EasyCorp\Bundle\EasyAdminBundle\Orm\EntityRepository;
class CampaignCrudController extends AbstractCrudController
{
public function __construct(EntityRepository $entityRepository)
{
$this->entityRepository = $entityRepository;
}
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): ORMQueryBuilder
{
$response = $this->entityRepository->createQueryBuilder($searchDto, $entityDto, $fields, $filters);
$response->andWhere('entity.user = :user')->setParameter('user', $this->getUser());
return $response;
}
EasyAdmin4 解决方案
注意:关键字(别名)entity
很重要
use Doctrine\ORM\QueryBuilder;
class ArticleCrudController extends AbstractCrudController
{
...
public function configureFields(string $pageName): iterable
{
return [
...
AssociationField::new('author')->setQueryBuilder(
fn (QueryBuilder $queryBuilder) => $queryBuilder
->leftJoin('entity.article', 'a')
->andWhere('entity.isActive = 1')
->andWhere('a.author is NULL')
),
...
]
}
...
}
EasyAdminBundle 文档上说
For example, the index() action calls to a method named createIndexQueryBuilder() to create the Doctrine query builder used to get the results displayed on the index listing. If you want to customize that listing, it’s better to override the createIndexQueryBuilder() method instead of the entire index() method.
所以让我们想象一下,当用户被删除时,我在我的用户实体中将字段 isDeleted 设置为 true。在索引页中,我只想显示 isDeleted = false 的用户。 如何为此目的覆盖 createIndexQueryBuilder()?
这是方法 createIndexQueryBuilder
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
{
return $this->get(EntityRepository::class)->createQueryBuilder($searchDto, $entityDto, $fields, $filters);
}
我试过像这样覆盖它,但没有成功
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
{
$response = $this->get(EntityRepository::class)->createQueryBuilder($searchDto, $entityDto, $fields, $filters);
$response->where('isDeleted', true);
return $response;
}
您只需要在 where 子句中添加 entity.
:)
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
{
parent::createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters);
$response = $this->get(EntityRepository::class)->createQueryBuilder($searchDto, $entityDto, $fields, $filters);
$response->where('entity.isDeleted = 1');
return $response;
}
这里有一个关于如何在 EasyAdmin 中替换 DQL FILTER 的例子v3.x
EasyAdmin v2.x DQL 过滤器:
easy_admin:
entities:
User:
class: App\Entity\User
list:
dql_filter: "entity.roles NOT LIKE '%%ROLE_SUPER_ADMIN%%'"
EasyAdmin v3.x 在 UserCrudController 中:
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
{
$response = $this->get(EntityRepository::class)->createQueryBuilder($searchDto, $entityDto, $fields, $filters);
$response->where("entity.roles NOT LIKE '%%ROLE_SUPER_ADMIN%%'");
return $response;
}
对于使用已接受的答案关注 QueryException 并通过搜索找到它的每个人:
QueryException
Too many parameters: the query defines 1 parameters and you bound 3
您的 EntityCrudController 中的 EasyAdmin v3.x:
- 使用->andWhere()函数
- 使用 entity. 作为前缀(真的,使用“实体”,不要替换为您的实体名称)
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
{
$response = $this->get(EntityRepository::class)->createQueryBuilder($searchDto, $entityDto, $fields, $filters);
$response->andWhere('entity.isDeleted = 1');
return $response;
}
EasyAdmin 对我有用4.x
use EasyCorp\Bundle\EasyAdminBundle\Orm\EntityRepository;
class CampaignCrudController extends AbstractCrudController
{
public function __construct(EntityRepository $entityRepository)
{
$this->entityRepository = $entityRepository;
}
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): ORMQueryBuilder
{
$response = $this->entityRepository->createQueryBuilder($searchDto, $entityDto, $fields, $filters);
$response->andWhere('entity.user = :user')->setParameter('user', $this->getUser());
return $response;
}
EasyAdmin4 解决方案
注意:关键字(别名)entity
很重要
use Doctrine\ORM\QueryBuilder;
class ArticleCrudController extends AbstractCrudController
{
...
public function configureFields(string $pageName): iterable
{
return [
...
AssociationField::new('author')->setQueryBuilder(
fn (QueryBuilder $queryBuilder) => $queryBuilder
->leftJoin('entity.article', 'a')
->andWhere('entity.isActive = 1')
->andWhere('a.author is NULL')
),
...
]
}
...
}