2016-11-28 39 views
4

我有這樣的控制器:Symfony的@ParamConverter:排除使用,如果佔位符不包含點

/** 
* {@inheritdoc} 
* 
* @Route("entity/{domain_host}") 
* @ParamConverter("entity", class="AppBundle:Entity", options={ 
*  "repository_method" = "findOneByDomainHost", 
*  "mapping": {"domain_host": "domainHost"}, 
*  "map_method_signature" = true 
* }) 
*/ 
class EntityController extends Controller 
{ 
... 
} 

這樣像http://example.com/entity/another-example.com一個URL時動作匹配和相應another-example.com實體是水合,並通過到控制器。現在

,這個實體也有一個ID。

我想攔截的URL像http://example.com/entity/12345,重定向到http://example.com/entity/another-example.com

要做到這一點,我創建的EntityController另一種方法:

/** 
* {@inheritdoc} 
* 
* @Route("entity/{domain_host}") 
* @ParamConverter("store", class="AppBundle:Entity", options={ 
*  "repository_method" = "findOneByDomainHost", 
*  "mapping": {"domain_host": "domainHost"}, 
*  "map_method_signature" = true 
* }) 
*/ 
class EntityController extends Controller 
{ 
    public function redirectIdToDomainAction(Request $request) 
    { 
     die(dump($request)); 
     // Following will be the redirect logic 
    } 
} 

而且在我routing.yml,在該文件的頂部:

entity_id_to_domain: 
    path: /entity/{id} 
    defaults: { _controller: AppBundle:Entity:redirectIdToDomain } 
    requirements: 
     id: ^[^.]*$ 
    methods: [GET] 

實際上的redirectIdToDomain動作,如果佔位符稱爲不包含點(點是discrimen:如果佔位符有一個點,一個域名通過,如果沒有點,佔位符可能代表的實體由UTS ID,我必須重定向)。

問題是,由於控制器類EntityController使用@ParamConverter,佔位符永遠被解釋爲一個域,結果是我得到一個AppBundle:Entity object not found.

那麼,有沒有申請只有佔位符有一個點的@ParamConverter的方法嗎?或者,我可以使用其他哪些方法使redirectToIdAction工作,而不會拋出Not found異常?

+0

更好地實現對重定向的東西和/或paramconverter – Matteo

+1

定製的監聽器爲什麼不把paramconverter上一個動作需要它而不是課程,還是將重定向操作移出課程? – Gerry

+1

更多操作(約7)需要'paramconverter'。我曾考慮過將重定向操作移出課程的可能性,但我希望有另外的選擇,所以在這裏提出...不是創建一個自定義參數轉換器,而是創建另一個控制器,然後在其中放入重定向動作... – Aerendir

回答

1

定製ParamConverter可能做的伎倆,但如果你不想做一個,你將不得不使用的ID和域名不同的路線。

解決方案1 ​​

因爲你的路由是對整個類,而不是對自己的行爲做,恐怕你必須將重定向動作移動到另一個控制器類。

之後,你可以搭配選擇性地使用要求

/** 
*@Route(
    "entity/{domain_host}", 
    name="entity_domain", 
    requirements={"domain_host": "^(?=.*[\w])(?=.*[.]).+$"} 
*) 
*@ParamConverter(...) 
*/ 
someActionOnDomainAction() 
{ 
//... 
} 


/** 
*@Route(
    "entity/{id}", 
    name="entity_domain", 
    requirements={"id": "^[\d]$"} 
*) 
*/ 
redirectIdToDomainAction() 
{ 
//... 
} 

解決方案2

或者ID和域名,你可以儲存庫的方法findOneByDomainHost()改變你喜歡的東西findOneByDomainHostOrID(),並使其既域相匹配名稱和數字ID。

這樣,你得到Object Not Found錯誤的鑽機,你總是可以得到你的實體的域名,並執行重定向在同一個控制器的動作。

下面是一個例子:

/** 
* Class EntityController 
* 
* @Route("/entity/{domain_host}", name="domain_host") 
* @ParamConverter("domain_host", class="AppBundle:Entity", options={ 
*  "repository_method" = "findOneByHostOrID" 
* }) 
*/ 
class EntityController extends Controller 
{ 
    /** 
    * @Route("/", name="show_domain_host") 
    * @param Entity $domain_host 
    */ 
    public function domain_hostAction(Entity $domain_host, Request $request) 
    { 
     $id = $domain_host->getId(); 
     $host = $domain_host->getHost(); 

     // Get the unconverted route parameter. 
     $parameter = $request->attributes->get('_route_params')['domain_host']; 

     if ($parameter == $domain_host->getId()){ 
      // If the route parameter matches the ID, 
      // redirect to the same route using the domain host. 
      $url = $this->generateUrl('show_mail', ['mail' => $lib]); 
      return $this->redirect($url, 301); 
     } 

     return new Response("<html><body>$id $host</body></html>"); 
    } 
} 

而且倉儲類:

class EntityRepository extends EntityRepository 
{ 
    public function findOneByHostOrID($domain_host) 
    { 
     if (preg_match("[\\d]",$domain_host)) { 
      return $this->findOneById($domain_host); 
     } else { 
      return $this->findOneByHost($domain_host); 
     } 
    } 
}