从module.php转发到另一个控制器/操作

时间:2013-10-29 07:17:18

标签: php zend-framework2

我正在ACL中为ZF2编写一个模块,而且我差不多完成了它。

我被困的地方是当用户无权访问所请求的页面时,我想转发用户到显示403消息的页面。

我已尝试重定向用户403,但它会更新URL,所以现在我要转到转发用户。

我想做的只是来自Module.php。我试过下面的代码 -

Module.php

if (!$isAllowed) {
    $e->getApplication()->getServiceManager()->get('ControllerPluginManager')->get('forward')->dispatch('acl');
}

使用此我收到以下错误 -

  

未捕获的异常'Zend \ Mvc \ Exception \ DomainException'及消息'Forward plugin需要一个实现InjectApplicationEventInterface的控制器'

我还试图用Acl实现InjectApplicationEventInterface控制器,但问题仍然存在。

您能否请ForwardAction解释如何Module.php到另一个{{1}}? 如果您需要更多详细信息,请与我们联系。

4 个答案:

答案 0 :(得分:3)

您可以做的是听取调度事件。您可以在此事件期间更新路由匹配,以匹配您自己定义的控制器/操作对,以呈现403页。

在代码中:

use MvcEvent;

class Module
{
    public function onBootstrap($e)
    {
        $app = $e->getApplication();
        $acl = $app->getServiceManager()->get('ACL'); // get your ACL here

        if (!$acl->isAllowed()) {
            $em = $app->getEventManager();
            $em->attach(MvcEvent::EVENT_DISPATCH, function($e) {
                $routeMatch = $e->getRouteMatch();

                $routeMatch->setParam('controller', 'my-403-controller');
                $routeMatch->setParam('action', 'my-403-action');
            }, 1000);
        }
    }
}

转发是在已经调度另一个控制器时调度控制器的模式。这不是你的情况,正如我从你的问题中读到的那样。所以不要使用转发插件,而是在分配之前修改路由匹配。

答案 1 :(得分:0)

您无法转发,但可以重定向到您的403页面,如下所示:

if (!$acl->isAllowed()) {
    $response = $e->getResponse();
    $response->getHeaders()->addHeaderLine('Location', $e->getRequest()->getBaseUrl() . '/403page');
    $response->setStatusCode(403);
}

答案 2 :(得分:0)

我认为,如果你想向用户发送信息,说明他在受限区域而没有更新网址,你必须:

  1. 更改显示限制区域消息的布局。
  2. 保留原始布局,只需切换操作模板,即可显示限制区域消息。
  3. 执行其中一项操作后,您只需将响应更改为403。 如果那是你想要的简单的事情。对于控制器中的任何操作,您只想使用发送403状态:

     $viewModel->setTemplate('partial/noRights');
     $this->getResponse()->setStatusCode('403');
     return $viewModel;
    

    或者如果您想更改自定义的布局:

     $this->layout('layout/custom');
     $this->getResponse()->setStatusCode('403');
     return $viewModel;
    

    你当然可以在你的模块的bootstrap部分中添加监听器在event_dispatch上,并检查是否$ acl-> isAllowed()之后你做了我上面写的更改。例如:

    public function onBootstrap(MvcEvent $e)
    {
        $app = $e->getApplication();
        $acl = $app->getServiceManager()->get('ACL'); // get your ACL here
    
        if (!$acl->isAllowed()) {
            $eventManager = $app->getEventManager();
            $sharedEventManager = $eventManager->getSharedManager();
            $sharedEventManager->attach(__NAMESPACE__, MvcEvent::EVENT_DISPATCH, function($e) {
                $controller = $e->getTarget(); //controller`s action which triggered event_dispatch
                $controller->getResponse()->setStatusCode('403');
                $controller->layout('layout/custom');
            }, 1000);
        }
    }
    

答案 3 :(得分:0)

当我实施ACL时, 我创建了自己的AUTH模块进行授权和身份验证 在那个模块中,我创建了ACL插件......如下所示

// Module.php

 /**
     * This method is called once the MVC bootstrapping is complete
     * 
     * @param \Zend\EventManager\EventInterface $e
     */
    public function onBootstrap(Event $e) 
    {
        $services = $e->getApplication()->getServiceManager();

        $eventManager = $e->getApplication()->getEventManager();
        $eventManager->attach('dispatch', array($this, 'loadConfiguration'), 101);
    }

    /**
     * 
     * @param \Zend\Mvc\MvcEvent $e
     */
    public function loadConfiguration(MvcEvent $e) 
    {        
        $e->getApplication()->getServiceManager()
                ->get('ControllerPluginManager')->get('AclPlugin')
                ->checkAcl($e); //Auth/src/Auth/Controller/AclPlugin      
    }

// Auth / src / Auth / Controller / AclPlugin

namespace Auth\Controller\Plugin;

/**
 * load libraries here
 */
class AclPlugin extends AbstractPlugin implements ServiceManagerAwareInterface 
{
    /*
     * @var Doctrine\ORM\EntityManager
     */

    protected $em;
    protected $sm;

    /**
     * @param Doctrine\ORM\EntityManager $em
     * @return string
     */
public function checkAcl($e) 
    {

        $matches = $e->getRouteMatch();
        $controller = $matches->getParam('controller');
        $action = $matches->getParam('action', 'index');

       if ($acl->isAllowed($role, $resource, $permission)) {


            return;

        } else {
            $matches->setParam('controller', 'Auth\Controller\User'); // redirect
            $matches->setParam('action', 'accessdenied');

            return;
        }

}

/// rest of the code here

}