Symfony2是否有任何开源(或示例(代码可以使用多个参数过滤某些模型?我正在寻找的一个很好的例子可以在这个 Trulia 网页上看到。
http://www.trulia.com/for_sale/30000-1000000_price/10001_zip/
http://www.trulia.com/for_rent/Chicago,IL/#for_rent/Chicago,IL/0-500_price/wd,dw_amenities/sm_dogs_pets"
http://www.trulia.com/for_rent/Chicago,IL/#for_rent/Chicago,IL/400-500_price/wd,dw_amenities
http://www.trulia.com/for_rent/Chicago,IL/#for_rent/Chicago,IL/wd,dw_amenities"
http://www.trulia.com/for_rent/Chicago,IL/#for_rent/Chicago,IL/400p_price/dw,cs_amenities
http://www.trulia.com/for_rent/Chicago,IL/#for_rent/Chicago,IL/1p_beds/1p_baths/400p_price/dw,cs_amenities
请注意单击表单时如何构建URL,我想是对所有路由使用一个控制器,这是如何完成的?我认为它不会将所有可能的路由重定向到特定的控制器(如下所示(,也许是某种动态路由?
/**
* @Route("/for_rent/{state}/{beds}_beds/{bath}_bath/{mix_price}-{max_price}_price /{amenities_list}
* @Route("/for_rent/{state}/{mix_price}-{max_price}_price/{amenities_list}
* @Route("/for_rent/{state}/{bath}_bath/{mix_price}-{max_price}_price/{amenities_list}
* @Route("/for_rent/{state}/{mix_price}_price/{amenities_list}
* @Route("/for_rent/{state}/{beds}_beds/{bath}_bath/{amenities_list}
* ........
*/
public function filterAction($state, $beds, $bath, $min_price, $max_price ....)
{
....
}
谢谢。
对于简单的查询(即不需要数据范围,例如最小-最大值(,您可以使用实体存储库通过给定的请求参数查找实体。假设您的实体Acme'FooBundle'Entity'Bar
:
$em = $this->getDoctrine()->getEntityManager();
$repo = $em->getRepository('AcmeFooBundle:Bar');
$criteria = array(
'state' => $state,
'beds' => $beds,
// and so on...
);
$data = $repo->findBy($criteria);
在构建 $criteria
数组时,您可能需要一些逻辑,以便仅按提供的条件进行排序,而不是按所有可能的值进行排序。 然后,$data
将包含与条件匹配的所有实体。
对于更复杂的查询,您需要查看 DQL(也许还有自定义存储库(,以便对要提取的实体进行更精细的控制。
为了构建您的路由,我相信您已经查看了文档的路由页面,但是您是否注意到您可以对路由提出要求?本页介绍如何使用注释进行操作。
至于过滤,我想DQL是可以的,但你也可以用Doctrine直接编写SQL,并将查询结果映射到一个或多个实体。此处对此进行了描述。它可能比 DQL 更灵活。
csg,如果你只需要在"单向"中使用路由,你的解决方案很好(使用 @Route("/search/{q}(。但是,如果您需要在可通过 url 访问的页面上打印一些价格过滤器链接,该怎么办:http://www.trulia.com/for_sale/30000-1000000_price/10001_zip/
在这种情况下@Route("/search/{q}
您将无法使用带有参数生成的路由方法 url。
有一个名为 LexikFormFilterBundle "lexik/form-filter-bundle": "~2.0"
的很棒的捆绑包,可帮助您在用户完成过滤器表单后生成复杂的 DQL。
我创建了一个依赖于它的捆绑包,它更改给定FormType的类型(如SencioGeneratorBundle生成的类型(,因此您可以显示正确的FilterForm,然后在它之后创建DQL(使用Lexik(。
您可以按照以下 README.md 使用 Composer 安装它
它所做的只是覆盖Doctrine Type Guesser,该猜测器为每个实体字段建议所需的FormType,并将给定的类型替换为正确的LexikFormFilterType。例如, 将简单的NumberType
替换为呈现为两个数字 Max 和 Min 间隔边界的filter_number
。
private function createFilterForm($formType)
{
$adapter = $this->get('dd_form.form_adapter');
$form = $adapter->adaptForm(
$formType,
$this->generateUrl('document_search'),
array('fieldToRemove1', 'fieldToRemove2')
);
return $form;
}
提交表单后,您只需将其提供给 Lexik 并运行生成的查询,如我的示例所示。
public function searchAction(Request $request)
{
// $docType = new FormType/FQCN() could do too.
$docType = 'FormType/FQCN';
$filterForm = $this->createFilterForm($docType);
$filterForm->handleRequest($request);
$filterBuilder = $this->getDocRepo($docType)
->createQueryBuilder('e');
$this->get('lexik_form_filter.query_builder_updater')
->addFilterConditions($filterForm, $filterBuilder);
$entities = $filterBuilder->getQuery()->execute();
return array(
'entities' => $entities,
'filterForm' => $filterForm->createView(),
);
}