如何在控制器插件中从Zend_Navigation中检索当前页面


How to retrieve the current page from Zend_Navigation within a Controller Plugin

我正在使用控制器插件进行身份验证插件。我在application.ini文件中定义了导航配置,然后使用该配置和数据库用户记录动态加载ACL并将其应用于Zend_Navigation。这一点是有效的,因为它成功地加载了菜单,并且只显示允许用户看到的页面。

但是,这并不能阻止用户直接进入页面。我想做的是识别当用户要去一个页面,他们没有访问控制器插件,所以我可以重定向他们的请求到认证页面。

我想一定有一个函数来检索当前页面从Zend_Navigation,但我找不到它…所以也许它不存在。

无论如何,这是我的完整控制器插件。有人想到解决办法了吗?

<?php
class Pog_Model_AuthPlugin extends Zend_Controller_Plugin_Abstract
{
    public function preDispatch(Zend_Controller_Request_Abstract $oRequest)
    {
        /**
         * Load user
         */
        $oAuth = Zend_Auth::getInstance();
        $oDbUsers = new Pog_Model_DbTable_Users();
        if (!$oAuth->hasIdentity())
        {
            $oUser       = $oDbUsers->createRow();
            $oUser->name = "guest";
            $oUser->setReadOnly(true);
        }
        else
        {
            $oUser = $oAuth->getIdentity();
            $oUser->setTable($oDbUsers);
        }
        /**
         * Load ACL
         */    
        $oAcl = new Zend_Acl();
        $oAcl->addRole($oUser->name);

        /**
         * Add current user privileges
         */
        $oPrivileges = $oUser->getPrivileges();
        foreach ($oPrivileges as $oPrivilege)
        {
            if (!$oAcl->has($oPrivilege->resource))
                $oAcl->addResource($oPrivilege->resource);
            $oAcl->allow($oUser->name, $oPrivilege->resource, $oPrivilege->privilege);
        }

        /**
         * Load Navigation view helper
         */
        $oViewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
        $oNavigation   = $oViewRenderer->view->navigation();

        /**
         * Add remaining Navigation resources
         */
        foreach ($oNavigation->getPages() as $oPage)
        {
            if (!is_null($oPage->getResource()) && !$oAcl->has($oPage->getResource()))
                $oAcl->addResource($oPage->getResource());
        }

        /**
         * Set ACL and Role
         */
        $oNavigation->setAcl($oAcl)->setRole($oUser->name);

        /**
         * Check if use is allowed to be here
         */
        ...MAGIC GOES HERE...
    }
}

我认为你应该能够得到当前的导航页如下:

     /**
     * Load Navigation view helper
     */
    $oViewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
    $oNavigation   = $oViewRenderer->view->navigation();
    /*@var $active array */        
    $active = $oNavigation->findActive($oNavigation->getContainer());
    /*@var $activePage Zend_Navigation_Page_Mvc */   
    $activePage =  $active['page'];
    // example of getting page info        
    var_dump($activePage->getLabel(), $activePage->getController(), $activePage->getAction());

这是我使用的解决方案,因为我不能得到Marcin的解决方案在我的设置中工作的某些原因。

我又想了一下,想到了一个很好的简单的解决问题的办法。我没有使用Navigation模块来查找Active页面,而是自己查找。因为我已经遍历了页面,所以比较控制器和动作是小菜一碟——如果它们都匹配,我就有了活动页面!

新的getPages() foreach循环看起来像这样:

$oCurrentPage = null;
foreach ($oNavigation->getPages() as $oPage)
{
    /**
     * Check for Current Page
     */
    if ($oPage->getController() == $oRequest->getControllerName()
      && $oPage->getAction() == $oRequest->getActionName())
        $oCurrentPage = $oPage;

    /**
     * Add Resource, if missing
     */
    if (!is_null($oPage->getResource()) && !$oAcl->has($oPage->getResource()))
        $oAcl->addResource($oPage->getResource());
}