2016-04-06 51 views
0

我正在使用Lexik Form Filter Bundle來過濾來自實體存儲庫的結果集。通過實體的所有屬性搜索關鍵字,Symfony2

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%' 

(請注意關鍵字ORLIKE在這裏。)

我寧願堅持Lexik過濾器保持過濾數據(使用會話)的方式,所以,如果更好我可以使用這個過濾器實現這一點。但我對我需要創建什麼類型的自定義字段以及如何修改條件生成器邏輯毫無頭緒。由於此關鍵字未附加到特定屬性,這甚至可以使用此過濾器嗎?

+0

您不使用偵聽器來創建您的queryBuilder? – darkomen

+0

感謝您的評論@ darkomen。我採取了這種方法來覆蓋應用過濾器的默認方式。我仍然有使用任何基礎實體的元數據來構建條件的問題。 –

回答

2

我想你正在尋找所有過濾器類型的'apply_filter'選項。
文檔可以在這裏看到Lexik Form Filters - Customize Condition Operators

我的關鍵字過濾器看起來像這樣,搜索5個字段; $ fields

->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); 
    } 
))