过滤器
index
页面的列表可以使用过滤器进行优化,过滤器是一系列表单控件,用于向查询添加条件(例如 price > 10
,enabled = true
)。使用仪表板或 CRUD 控制器的 configureFilters()
方法定义过滤器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
namespace App\Controller\Admin;
use EasyCorp\Bundle\EasyAdminBundle\Config\Filters;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
class ProductCrudController extends AbstractCrudController
{
// ...
public function configureFilters(Filters $filters): Filters
{
return $filters
->add('title')
->add('price')
->add('published')
;
}
}
EasyAdmin 为最常见的需求(日期、数值、集合等)提供了即用型过滤器。过滤器类型会根据属性的数据类型自动选择,但您也可以显式定义过滤器类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
namespace App\Controller\Admin;
use EasyCorp\Bundle\EasyAdminBundle\Config\Filters;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Filter\BooleanFilter;
class ProductCrudController extends AbstractCrudController
{
// ...
public function configureFilters(Filters $filters): Filters
{
return $filters
->add('title')
->add('price')
// most of the times there is no need to define the
// filter type because EasyAdmin can guess it automatically
->add(BooleanFilter::new('published'))
;
}
}
内置过滤器
以下是 EasyAdmin 提供的内置过滤器
ArrayFilter
:默认应用于数组字段。它呈现为一个<select>
列表,其中包含条件(等于/不等于)和另一个<select>
标签输入,用于引入比较值。BooleanFilter
:默认应用于布尔字段。它呈现为两个单选按钮,标签为“是”和“否”。ChoiceFilter
:它呈现为一个带有选项的<select>
列表。ComparisonFilter
:带有两个字段的通用复合过滤器。DatetimeFilter
:分别默认应用于 datetime、date 或 time 字段。它呈现为一个<select>
列表,其中包含条件(之前/之后/等等)和一个浏览器原生日期选择器,用于选择日期/时间。EntityFilter
:应用于具有 Doctrine 关联的字段(支持所有类型)。它呈现为一个<select>
列表,其中包含条件(等于/不等于/等等)和另一个<select>
列表,用于选择比较值。NullFilter
:默认不应用于任何字段。它对于根据属性的“null”或“非 null”值过滤结果很有用。它呈现为两个单选按钮,分别用于 null 和非 null 选项。NumericFilter
:默认应用于数值字段。它呈现为一个<select>
列表,其中包含条件(更高/更低/等于/等等)和一个<input>
,用于定义比较值。TextFilter
:默认应用于字符串/文本字段。它呈现为一个<select>
列表,其中包含条件(包含/不包含/等等)和一个<input>
或<textarea>
,用于定义比较值。
自定义过滤器
如果您的需求更具体,您可以创建自己的过滤器。过滤器使用两个类定义
- 实现
EasyCorp
的配置类用于配置过滤器选项,并在过滤器处于活动状态时应用搜索条件;\Bundle \EasyAdminBundle \Contracts \Filter \FilterInterface - 实现
Symfony\Component\Form\FormType
的表单类用于呈现 HTML 小部件,这些小部件用于在应用程序中输入过滤器数据。
您可以在过滤器配置类中使用 FilterTrait
以避免实现所有常用方法。这样,您只需要实现 apply()
方法,该方法是更改 $queryBuilder
对象以应用过滤器所需的查询子句的方法。
考虑以下示例,该示例创建了一个带有某些特殊值的自定义日期过滤器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
// src/Controller/Admin/Filter/DateCalendarFilter.php
namespace App\Controller\Admin\Filter;
use App\Form\Type\Admin\DateCalendarFilterType;
use Doctrine\ORM\QueryBuilder;
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Filter\FilterInterface;
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto;
use EasyCorp\Bundle\EasyAdminBundle\Dto\FilterDataDto;
use EasyCorp\Bundle\EasyAdminBundle\Filter\FilterTrait;
class DateCalendarFilter implements FilterInterface
{
use FilterTrait;
public static function new(string $propertyName, $label = null): self
{
return (new self())
->setFilterFqcn(__CLASS__)
->setProperty($propertyName)
->setLabel($label)
->setFormType(DateCalendarFilterType::class);
}
public function apply(QueryBuilder $queryBuilder, FilterDataDto $filterDataDto, ?FieldDto $fieldDto, EntityDto $entityDto): void
{
if ('today' === $filterDataDto->getValue()) {
$queryBuilder->andWhere(sprintf('%s.%s = :today', $filterDataDto->getEntityAlias(), $filterDataDto->getProperty()))
->setParameter('today', (new \DateTime('today'))->format('Y-m-d'));
}
// ...
}
}
然后,创建关联的表单类型,例如,呈现一个带有某些预定义值的 <select>
小部件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
// src/Form/Type/Admin/DateCalendarFilterType.php
namespace App\Form\Type\Admin;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\OptionsResolver\OptionsResolver;
class DateCalendarFilterType extends AbstractType
{
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'choices' => [
'Today' => 'today',
'This month' => 'this_month',
// ...
],
]);
}
public function getParent()
{
return ChoiceType::class;
}
}
您现在可以在任何仪表板和 CRUD 控制器中使用此自定义过滤器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
namespace App\Controller\Admin;
use App\Admin\Filter\DateCalendarFilter;
use EasyCorp\Bundle\EasyAdminBundle\Config\Filters;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Filter\BooleanFilter;
class UserCrudController extends AbstractCrudController
{
// ...
public function configureFilters(Filters $filters): Filters
{
return $filters
// ...
->add(DateCalendarFilter::new('signupDate'))
;
}
}
未映射的过滤器
默认情况下,每个过滤器都必须与实体的属性关联。但是,有时您需要按相关实体的属性进行过滤(例如,order
与 customer
关联,并且您想按 customer
的 country
属性过滤订单)。在这些情况下,请将过滤器中的 mapped
选项设置为 false
,否则您将看到异常
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
namespace App\Controller\Admin;
use App\Admin\Filter\CustomerCountryFilter;
use EasyCorp\Bundle\EasyAdminBundle\Config\Filters;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Filter\BooleanFilter;
class OrderCrudController extends AbstractCrudController
{
// ...
public function configureFilters(Filters $filters): Filters
{
return $filters
// 'country' doesn't exist as a property of 'Order' so it's
// defined as 'not mapped' to avoid errors
->add(CustomerCountryFilter::new('country')->mapped(false))
;
}
}
这项工作,包括代码示例,根据 Creative Commons BY-SA 3.0 许可协议获得许可。