2012-07-12 10 views
5

ページに表示するアイテムのリストがあり、その上に検索フォームがあり、通常のバックエンドのようにこれらのアイテムをフィルタリングします。問題は、既存のクエリにジョインで検索条件を追加する方法がわからないことです。これは私が持っているものです:Symfony2で検索フィルタフォームを実装する方法

エンティティに関連付けられたリポジトリで特定のメソッドを使用して、クエリ(多くのクエリを避けるため)。コントローラは、次のようになります。リポジトリに

class ModelController extends Controller 
{ 
    public function indexAction(Request $request) 
    { 
     // ... 
     $em = $this->getDoctrine()->getManager(); 
     $query = $em->getRepository('AcmeDemoBundle:Item')->getList(); 
    } 
} 

getList方法は次のようになります。

use Doctrine\ORM\EntityRepository; 

// ... 

class ItemRepository extends EntityRepository 
{ 
    public function getList() 
    { 
     $queryBuilder = $this 
      ->createQueryBuilder('i') 
      ->innerJoin('i.brand', 'b'); 

     return $queryBuilder->getQuery(); 
    } 
} 

私はアイテムを検索するためのいくつかのフィールドで ItemSearchTypeフォームオブジェクトを作成しました。

フィルタリングされたアイテムを表示するために、検索フォームに提供されたデータから検索条件を簡単に追加するにはどうすればよいですか?

これは、検索フォームに関する私のコントローラで何です:

class ModelController extends Controller 
{ 
    public function indexAction(Request $request) 
    { 

     // ... 
     if ($request->getMethod() === 'POST') { 
      $searchForm->bindRequest($request); 

      if ($searchForm->isValid()) { 
       $searchCriteria = $searchForm->getData(); 

       // Do something with this data! ...but I don't know how 
      } 
    } 
} 

ありがとう!ここで

答えて

8

は私がしようとするものです。

ここ
public function getListBy($criteria) 
{ 
    $qb = $this->createQueryBuilder('i'); 

    $qb->innerJoin('i.brand', 'b'); 

    foreach ($criteria as $field => $value) { 
     if (!$this->getClassMetadata()->hasField($field)) { 
      // Make sure we only use existing fields (avoid any injection) 
      continue; 
     } 

     $qb ->andWhere($qb->expr()->eq('i.'.$field, ':i_'.$field)) 
      ->setParameter('i_'.$field, $value); 
    } 

    return $qb->getQuery()->getResult(); 
} 
2

私はLexikFormFilterBundle filterTypesとQueryBuilder、プラス私はそれがfilterForm作成プロセスを抽象化作っTypeGuesserを使用し、このためanswerを掲載しました。

両方のサービスをComposerとは別のバンドルとしてインストールできます。 P

/** 
* Creates a Filter form to search for Entities. 
* 
* @param AbstractType|string $formType The `generate:doctrine:form` generated Type or its FQCN. 
* 
* @return \Symfony\Component\Form\Form The filter Form 
*/ 
private function createFilterForm($formType) 
{ 
    $adapter = $this->get('dd_form.form_adapter'); 
    $form = $adapter->adaptForm(
     $formType, 
     $this->generateUrl('document_search'), 
     array('fieldToRemove1', 'fieldToRemove2') 
    ); 
    return $form; 
} 

SF> = 2.8 が修正here

+1

を必要とするためにそれが壊れています:結果のコードは、githubのに移動したくない場合には、READMEから

クリーナーですこれは最高の答えです。 LexikFormFilterBundleはエンティティのフィルタリングの問題を解決します。 AdrienBraultの回答も同様に機能しますが、つまりdaterangeでフィルタリングできません。 –

+0

LexikFormFilterBundleのアドバイスをいただきありがとうございます。フィルタークエリのandWheresのすべてにうんざりしていました。フィルタバンドルは多くの作業と複雑さを節約します:) – Sharpy35

関連する問題