Symfony:如何将表单过滤器与实体中不存在的字段一起使用?

Symfony: How to use a form filter with an field that does not exist in an entity?

我正在尝试弄清楚如何在不映射到数据库中任何列的搜索中传递自定义字段。

例如,我想检查用户个人资料是否完整或不完整,然后对其进行过滤。我想以 post 的形式传递一个“状态”,并根据值是什么将在特定列上搜索(因用户类型而异)。

我试过这样做:

 $profile_status = "";
 if($request->query->get("item_filter")['status']){
    $profile_status = $request->query->get("item_filter")['status'];
    $request->query->remove("item_filter")['status'];
 }

但是它似乎删除了我随表格一起提供的所有其他数据。

这就是我在 form_filter class

中构建表单字段的方式
$builder->add('status', ChoiceType::class, [
    'expanded' => false,
    'multiple' => false,
    'required' => false,
    'choices'  => [
        'Filter by Status' => '',
        'Profile Complete' => 'complete',
        'Profile Incomplete' => 'incomplete'
    ]
]);

这就是我查询数据库的方式:

$filterBuilder = $this->educatorUserRepository->createQueryBuilder('u');
$filterBuilder->andWhere('u.deleted = 0');
$filterBuilder->addOrderBy('u.firstName', 'ASC');

if($user->isSiteAdmin()) {
    $filterBuilder->where('u.site = :site')
        ->setParameter('site', $user->getSite());
}

if($profile_status == 'complete'){
    $filterBuilder->andWhere('u.briefBio IS NOT NULL');
} elseif($profile_status == 'incomplete') {
    $filterBuilder->andWhere('u.briefBio IS NULL');
}

if ($form->isSubmitted() && $form->isValid()) {
    // build the query from the given form object
    $this->filterBuilder->addFilterConditions($form, $filterBuilder);
}

$filterQuery = $filterBuilder->getQuery();

如果对此有任何帮助,那就太好了。

根据您代码中的方法 addFilterConditions,我相信您使用的是 LexikFormFilterBundle

我没用过那个包,不过你可以试试下面的方法:

1- 在定义表单字段时使用 ChoiceFilterType 而不是 ChoiceType

2- 捆绑包本身通过设置 'apply_filter' => false.

提供了 disable filtering for one field 的方法

3- 设置表单域为mapped => false.

您的表单定义代码如下所示:

$builder->add('status', ChoiceFilterType::class, [
    'apply_filter' => false,
    'mapped' => false,
    'expanded' => false,
    'multiple' => false,
    'required' => false,
    'choices'  => [
        'Filter by Status' => '',
        'Profile Complete' => 'complete',
        'Profile Incomplete' => 'incomplete'
    ]
]);

4- 删除这段代码:

 $profile_status = "";
 if($request->query->get("item_filter")['status']){
    $profile_status = $request->query->get("item_filter")['status'];
    $request->query->remove("item_filter")['status'];
 }

5- 将控制器中的代码更改为如下所示。这样您将使用未映射的字段 statusbriefBio

进行过滤
$filterBuilder = $this->educatorUserRepository->createQueryBuilder('u');
$filterBuilder->andWhere('u.deleted = 0');
$filterBuilder->addOrderBy('u.firstName', 'ASC');

if($user->isSiteAdmin()) {
    $filterBuilder->where('u.site = :site')
        ->setParameter('site', $user->getSite());
}

if ($form->isSubmitted() && $form->isValid()) {
    if($form->get('status')->getData() == 'complete') {
        $filterBuilder->andWhere('u.briefBio IS NOT NULL');
    } elseif($form->get('status')->getData() == 'incomplete') {
        $filterBuilder->andWhere('u.briefBio IS NULL');
    }

    // build the query from the given form object
    $this->filterBuilder->addFilterConditions($form, $filterBuilder);
}

$filterQuery = $filterBuilder->getQuery();