2016-04-06 13 views
0

Lexikフォームフィルタバンドルを使用して、エンティティリポジトリから結果セットをフィルタリングしています。 エンティティのすべてのプロパティを使用してキーワードを検索する、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'; 
    } 
} 

は、このフィルタのデフォルトの動作を1として、フィルタ条件を取り付けた後に構築され、最終的なクエリは、次のよう 条件構造を持つことになります。

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

(従来のディレクトリ構造を想定)

私のタスクは、フィルタフォームに1つ以上のフィールドを追加することです。これは特定の不動産には結びつきません。フィルタフォームを提出すると、この入力はエンティティのすべてのプロパティを通じて検索されなければなりません。言い換えれば、結果のクエリはこのようなものでなければなりません。

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

それがあれば良いですので、私は、Lexikフィルターは、フィルターのデータ(セッションを使用して)を維持する方法に付着することを好む

(キーワードOR、ここLIKE。注意してください)私はこのフィルタを使ってこれを達成することができます。しかし、私はどのタイプのカスタムフィールドを作成する必要があるのか​​、どのように条件作成ロジックを変更できるのかについてはわかりません。このキーワードは特定のプロパティに関連付けられていないため、このフィルタを使用しても可能ですか?

+0

あなたはqueryBuilderの作成にリスナーを使用していませんか? – darkomen

+0

@darkomenご意見ありがとうございます。フィルタを適用するデフォルトの方法をオーバーライドする方法を採用しました。基本的なエンティティのメタデータを使用して条件を構築するという問題はまだあります。 –

答えて

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); 
    } 
)) 
関連する問題