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