在Symfony 2中路由到嵌入式模块/分发包/控制器

时间:2011-10-19 13:10:37

标签: php symfony

我在做完研究后对这篇文章进行了全面编辑:

我想在管理部分实现一个侧边栏,它集成在每个页面中,例如。 http://mydomain.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 %}

到目前为止一切顺利,但这些模块可以包含发送帖子请求的表单。我想留在同一页面(http://mydomain.com/admin/index/),因此表单的action属性保持为空。问题是:模块永远不会识别发布请求。因此,一个想法是隐藏包含路径名称的相应表单中的字段,将其转换为相应的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 个答案:

答案 0 :(得分: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
        }
    }
}