【问题标题】:How to implement a search filter form with Symfony2如何使用 Symfony2 实现搜索过滤器表单
【发布时间】:2012-07-12 10:23:46
【问题描述】:

我有一个要在页面上显示的项目列表,上面有一个搜索表单来过滤这些项目,就像在任何常见的后端一样。问题是我不知道如何将搜索条件添加到带有连接的现有查询中......这就是我所拥有的:

我在与实体关联的存储库上使用特定方法在查询中添加连接(以避免许多查询)。控制器如下所示:

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

谢谢!

【问题讨论】:

    标签: php doctrine-orm symfony-2.1


    【解决方案1】:

    这是我会尝试的:

    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 创建过程。

      您可以使用 Composer 将这两个服务安装为单独的捆绑包。生成的代码更干净

      从 README 中,以防您不想导航到 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

      【讨论】:

      • 这是最好的答案。 LexikFormFilterBundle 解决了过滤实体的问题。 AdrienBrault 的答案也可以,但无法按日期范围进行过滤。
      • 感谢 LexikFormFilterBundle 的建议,我厌倦了过滤器查询中的所有 andWheres。过滤器包在那里节省了很多工作和复杂性:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-06
      • 1970-01-01
      • 2019-09-19
      • 1970-01-01
      • 2021-11-25
      • 2023-02-25
      • 1970-01-01
      相关资源
      最近更新 更多