通过实体的所有属性Symfony2搜索关键字

时间:2016-04-06 06:07:09

标签: forms symfony filter

我正在使用Lexik Form Filter Bundle从实体存储库中过滤结果集。

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Lexik\Bundle\FormFilterBundle\Filter\Form\Type as Filters;

class ItemFilterType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', Filters\TextFilterType::class)
            ->add('description', Filters\TextFilterType::class);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'csrf_protection'   => false,
            'validation_groups' => array('filtering')
        ));
    }

    public function getBlockPrefix()
    {
        return 'item_filter';
    }
}

根据此过滤器的默认行为,在附加过滤条件后构建的最终查询将具有以下 WHERE 条件结构。

SELECT * FROM AppBundle\Entity\Item a WHERE
a.name = 'nameValue'
AND a.description = 'descriptionValue'

(假设传统的目录结构)

我的任务是在过滤器表单中再添加一个字段。这不会附加到任何特定财产。提交过滤器表单后,必须通过实体的所有属性搜索此输入。换句话说,生成的查询必须是这样的。

SELECT * FROM AppBundle\Entity\Item a WHERE
a.name LIKE '%nameValue%'
OR a.description LIKE '%descriptionValue%'

(请注意关键字 OR LIKE 。)

我更喜欢坚持Lexik Filter维护过滤器数据的方式(使用会话),所以如果我能使用这个过滤器实现这一点,那就更好了。但我对我需要创建什么类型的自定义字段以及如何更改条件构建器逻辑一无所知。由于此关键字未附加到特定属性,因此甚至可以使用此过滤器吗?

1 个答案:

答案 0 :(得分:2)

我认为您正在寻找' apply_filter'所有过滤器类型的选项 可在此处查看文档Lexik Form Filters - Customize Condition Operators

我的关键字过滤器看起来像这样,搜索5个字段; $字段

->add('keyword', TextFilterType::class, array(
    'required' => false,
    'attr' => array(
        'placeholder' => 'Keyword..'
    ),
    'apply_filter' => function(QueryInterface $filterQuery, $field, $values) {
        if($values['value'] === null || $values['value'] === '') {
            return null;
        }

        /** @var Expr $expr */
        $expr = $filterQuery->getExpr();

        $fields = [
            'exhibitorName',
            'exhibitorStandNumber',
            'address.city',
            'address.postcode',
            'address.country',
        ];

        $params = [];
        $expression = $expr->orX();  ///andX for must match all




        foreach($fields as $field) {
            $paramName = sprintf('p_%s', str_replace('.','_', $field));
            $ex = $expr->like($field, ':' . $paramName);
            $expression->add($ex);
            $params[$paramName] = '%' . $values['value'] . '%';
        }

        return $filterQuery->createCondition($expression, $params);
    }
))