2012-07-12 68 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

我在這裏張貼此一answer,我用LexikFormFilterBundle filterTypes和QueryBuilder的,再加上TypeGuesser我做了抽象filterForm創建過程。

您可以將兩種服務作爲單獨的Bundle與Composer一起安裝。生成的代碼是清潔

自述,如果你不想要導航到github上: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

這是最好的答案。 LexikFormFilterBundle解決了過濾實體的問題。 AdrienBrault的答案也會起作用,但無法按日期範圍進行過濾。 – 2016-03-04 12:58:33

+0

感謝您對LexikFormFilterBundle的建議,我對過濾器查詢中的所有和環境變得厭惡。過濾器包在那裏節省了大量的工作和複雜性:) – Sharpy35 2017-04-27 12:29:45