J'utilise d'autres frameworks tels que TP et CI pour répondre aux exigences ci-dessus, et cela peut être facilement réalisé. Récemment, je souhaite également l'implémenter sur SF2 et écrire un adminBundle pour créer automatiquement un backend pour fournir des fonctions communes. Cependant, j'ai rencontré le problème suivant :
Puisque je souhaite détecter les autorisations d'accès des utilisateurs globalement en arrière-plan, j'ai écouté le contrôleur pour obtenir les informations de demande avant le déclenchement de chaque contrôleur et vérifier si l'utilisateur a accordé les autorisations correspondantes. Le code est le suivant :
class RunActListener {
protected $securityContext;
public function __construct(SecurityContextInterface $securityContext)
$this->securityContext = $securityContext;
}
public function onRunAct(FilterControllerEvent $event) {
$request = $event->getRequest();
$ajax = $request->isXmlHttpRequest();
if (preg_match('/^\/admin/', $request->getRequestUri())) {
$routeName = $request->get('_route');
if ($this->securityContext->isGranted(array($routeName))) {
} else {
$reffeer = $request->server->get('HTTP_REFERER');
$data['info'] = '您没有权限操作!';
$data['status'] = false;
if ($ajax) {
$event->setController(
function() use ($data) {
return new JsonResponse($data);
});
} else {
$event->setController(
function() use ($data) {
return new Response('<b>您没有足够的访问权限!</b><script>setTimeout("window.history.back(-1)",2000)</script>');
});
//。。。。。
Ensuite, j'ai introduit 2 rendus dans la mise en page en arrière-plan. Les codes de menu et de fil d'Ariane sont les suivants :
<nav id="navigation" class="collapse">
<ul>
{{ render(controller( 'CwpUtilBundle:Menu:showMenu')) }}
</ul>
</nav>
</aside>
<p id="sidebar-separator"></p>
<section id="main" class="clearfix">
<p id="main-header" class="page-header">
{{ render(controller( 'CwpUtilBundle:Menu:showCrumb')) }}
</p>
<p id="main-content">
{% block main %}
{% endblock %}
</p>
</section>
De cette façon, 2 sub_requests sont initiées, mais mon exigence est d'obtenir l'url de la requête parent dans la sub_request pour implémenter mon fil d'Ariane et mon menu. Il y a quelques problèmes dans SF. Quelqu'un a suggéré d'utiliser la pile de requêtes dans la sous-action
./**
* 显示面包屑
* @return type
*/
public function showCrumbAction() {
$request = $this->container->get('request');
$path = $request->server->get('REDIRECT_URL');
$path_arr = explode('/', $path);
$path_len = count($path_arr);
$top_index = (int) ($path_len - 2);
$path_top = $path_arr[$top_index];
$route_arr = $this->get('router')->match($path);
$route = $route_arr['_route'];
$em = $this->getDoctrine()->getManager();
//获取菜单结果集
$top_menu = $em->getRepository('CwpUtilBundle:Menu')->findOneByNode($path_top);
$sec_menu = $em->getRepository('CwpUtilBundle:Menu')->findOneByNode($route);
return $this->render('CwpUtilBundle:Layout:crumb.html.twig', array(
'top_menu' => $top_menu,
'sec_menu' => $sec_menu,
));
}
J'ai essayé d'obtenir request_stack dans l'action ci-dessus, mais une fois que je l'ai reçu, il semble qu'une requête ait été lancée dans cette action, mon écouteur a été déclenché, puis exécuté autrement, en sautant à l'invite indiquant que vous disposez d'autorisations insuffisantes. J'étais confus et je ne savais pas pourquoi.
L'écouteur qui surveille kernel.controller, ajoute un jugement et vérifie les autorisations uniquement lorsque la requête principale est effectuée :
FilterControllerEvent dans la version 2.3 n'a pas cette méthode, référez-vous simplement à cette logique et écrivez-la vous-même :
https://github.com/symfony/symfony/blob/2.7/src/Symfony/Component/HttpKernel/Event/KernelEvent.php #L100