Маршрутизация к встроенным модулям / пакетам / контроллерам в Symfony 2

#php #symfony

#php #symfony

Вопрос:

Я полностью отредактировал этот пост после проведения исследования:

Я хотел бы реализовать боковую панель в разделе администратора, которая интегрирована на каждой странице, например. http://example.com/admin/index /:

 class MyController extends Controller {

    protected $modules = array();

    public function __construct(){
        $this->modules[] = "ModuleController:mainAction";
        $this->modules[] = "OtherModuleController:mainAction";
    }
    
    public function indexAction(Request $request){
        // do stuff here
        return $this->render("MyBundle:My:index.html.twig",$data);
    }
}
  

В представлении должно произойти что-то вроде:

 {% block modules %}
    {% for module in modules %}
        {% render module %}
    {% endfor %}
{% endblock %}
  

Пока все хорошо, но эти модули могут содержать формы, которые отправляют запросы post. Я бы хотел остаться на той же странице (http://example.com/admin/index /), поэтому атрибут action формы остается пустым. Проблема заключается в: Post-запрос никогда не будет распознан модулями. Итак, одна идея заключалась в том, чтобы скрыть поле в соответствующей форме, содержащее имя маршрута, преобразовать его в соответствующий uri и отправить дополнительный запрос (в MyController):

 public function indexAction(Request $request){
    if($request->request->has('hidden_module_route')){
        // collect all parameters via $request->request->keys()
        $uri = $router->generate($request->request->get('hidden_module_route'), $parameters);
        // 1: resolve the uri to the according controller and replace the target in the $this->modules array
        // or 2: (after step 1)
        $req = $request->create($uri, 'POST');
        $subresponse = $this->get('kernel')->handle($req,HttpKernelInterface::SUB_REQUEST);
        // inject the response into the modules and handle it in the view
    }
    [...]
}
  

Это сработало бы для меня, но я не рад иметь эти обязанности в контроллере, и кажется, что должно быть лучшее решение (одна из идей — зарегистрировать kernel.controller прослушиватель, который обрабатывает вложенные запросы и вводит пути к контроллеру (который, возможно, отмечен через интерфейс …)).

Что вы думаете?

Комментарии:

1. См . symfony.com/doc/2.0/book/templating.html и прокрутите вниз до пункта «Встраивание контроллеров». Это то, что вы ищете?

2. Я не думаю, что это вызывает внутреннюю маршрутизацию ?! В зависимости от запроса post мне нужен другой метод контроллера…

3. Используйте PHP в качестве языка шаблонов и меняйте имя метода контроллера на лету. Возможно, это немного банально, но у меня такое чувство, что я неправильно понимаю все детали вашего вопроса (или они не указаны), так что это более общее решение.

4. Это помогло бы, но мне кажется неправильным. Я провел небольшое исследование по этой теме, и я хочу сделать следующее: создать новый внутренний запрос на основе переменных post для всех зарегистрированных модулей (я знаю, что в Symfony нет модулей, но терминология соответствует моим потребностям). Итак, я мог бы подключить слушателя и создавать внутренние запросы через ядро, но на самом деле я не уверен, смогу ли я собирать ответы и передавать их обратно контроллеру.

5. Вы должны добавить это к своему вопросу, а не в комментарии 😉

Ответ №1:

Вы могли бы попробовать отправить основной запрос своим модулям, чтобы они могли связать с ним форму.

 {% block modules %}
    {% for module in modules %}
        {% render module with {'mainRequest': app.request} %}
    {% endfor %}
{% endblock %}
  

И модуль:

 public function moduleAction(Request $request, Request $mainRequest)
{
    $form = ...;
    if ($mainRequest->isMethod('POST')) {
        $form->bindRequest($mainRequest);
        if ($form->isValid()) {
            // You can have a beer, that worked
        }
    }
}