2011-08-03 68 views
5

Symfony2是否有任何開源(或示例)代碼可以使用多個參數過濾某個模型?在這個Trulia網頁上可以看到我正在尋找的一個很好的例子。用symfony2過濾

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 ....) 
{ 
    .... 
} 

謝謝。

回答

1

簡單查詢(即,你不需要有一個數據範圍,如最小 - 最大值),你可以使用實體庫來查找給出的請求參數實體。假設你的實體是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(也可能是custom repository),以更細緻地控制要提取的實體。

1

爲了構建您的路線,我相信你看看文檔的Routing頁面,但是你注意到你可以在路線上放置需求嗎? This頁面解釋瞭如何使用註釋執行此操作。

至於過濾,我想DQL將是確定的,但你也可以寫直了學說SQL,和您的查詢的結果映射到一個或多個實體。這被描述爲here。它可能比DQL更靈活。

+0

註解讓你匹配多於一個的路線,這是偉大的,但這並不能避免你寫手動將所有可能的組合爲所有濾波器參數,我的意思是,有ABC參數所有可能的路徑組合將是, ABC,AB,BC,AC,這是一種痛苦。我不知道是否實現自己的路由將允許這種動態URL匹配。 – csg

+1

找到了一個解決方案,非常簡單/ ** * @Route(「/ search/{q}」,requirements = {「q」:「。+」}) * ........ */ q然後將匹配一切,直到URL的結尾。然後由你來解析「q」,更多信息http://symfony.com/doc/currentbook/routing/slash_in_parameter.html – csg

0

csg,你的解決方案是好的(使用@Route(「/ search/{q}),如果你只需要使用」單向「路由選擇,但是如果你需要打印一些價格過濾鏈接通過URL訪問網頁: http://www.trulia.com/for_sale/30000-1000000_price/10001_zip/

@Route("/search/{q}情況下,你將無法使用路徑方法的URL使用參數產生

0

有一個叫LexikFormFilterBundle "lexik/form-filter-bundle": "~2.0"大包,可以幫助你後產生的複雜DQL。過濾器的形式由用戶完成。

I C reated一個包,依賴於它,改變的類型給定的FormType(如由SencioGeneratorBundle產生的一個),這樣就可以顯示正確的FilterForm,然後後創建DQL(與Lexik)。

可以與作曲家安裝它,下面這個README.md

它所做的就是重寫主義類型猜測器,這意味着每個實體領域所需的FormType,並通過適當的LexikFormFilterType更換指定的類型。例如,用簡單的NumberType代替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(), 
    ); 
} 
相關問題