2016-11-28 7 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 
{ 
... 
} 

Этот способ URL, как http://example.com/entity/another-example.com сочетается с действием и соответствующее another-example.com юридическое лицо увлажненной и прошло к контроллеру.

Теперь этот объект имеет также идентификатор.

Я хотел бы перехватить 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 действие называется, если заполнитель не содержит точки (точка - это дискриминат: если местозаполнитель имеет точку, передается домен, если нет точки, замещающий объект, вероятно, представляет собой Entity by uts ID, и я должен перенаправить).

Проблема заключается в том, что, поскольку класс контроллера EntityController использует @ParamConverter, заполнитель когда-либо интерпретируется как домен, и, следовательно, я получаю AppBundle:Entity object not found..

Итак, есть ли способ применить @ParamConverter, только если у заполнителя есть точка? Или, какие другие подходы я могу использовать, чтобы сделать работу redirectToIdAction без выброса исключения Not found?

+0

лучше реализует слушателя для перенаправления материала и/или обычая paramconverter – Matteo

+1

Почему бы не поставить paramconverter на одну акцию который требует его вместо класса, или переместить действие перенаправления за его пределы? – Gerry

+1

«paramconverter» требуется для большего количества действий (около 7). Я думал о возможности перенести действие перенаправления из класса, но я надеялся, что есть еще один вариант, поэтому спросите здесь ... Вместо создания настраиваемого преобразователя параметров я думаю, что создам еще один контроллер, и в нем я поставлю действие перенаправления ... – Aerendir

ответ

1

Пользовательский ParamConverter может сделать трюк, но если вы не хотите его использовать, вам придется использовать разные маршруты для идентификаторов и доменных имен.

Решение 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

В качестве альтернативы, вы можете изменить вам метод репозитория findOneByDomainHost() к чему-то вроде findOneByDomainHostOrID(), и сделать его соответствия как домен имена и числовые идентификаторы.

Таким образом, вы получаете ошибки 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); 
     } 
    } 
} 
Смежные вопросы