2011-06-09 30 views
1

有問題,我有一個Federico_Plugin_Acl延伸Zend_Controller_Plugin_Abstract看起來像這樣:結合Zend_Acl中和Zend_Navigation

class Federico_Plugin_Acl extends Zend_Controller_Plugin_Abstract { 

private $_acl = null; 
private $_auth = null; 
const DEFAULT_ROLE = 'guest'; 

public function __construct($auth) { 
    $this->_auth = $auth; 

    $this->_acl = new Zend_Acl(); 
    $this->_acl->addRole(new Zend_Acl_Role(self::DEFAULT_ROLE)); 
    $this->_acl->addRole(new Zend_Acl_Role('user'), self::DEFAULT_ROLE); 
    $this->_acl->addRole(new Zend_Acl_Role('admin'), 'user'); 

    $this->_acl->addResource(new Zend_Acl_Resource('index')); 
    $this->_acl->addResource(new Zend_Acl_Resource('users')); 
    $this->_acl->addResource(new Zend_Acl_Resource('about')); 
    $this->_acl->addResource(new Zend_Acl_Resource('gisele')); 
    $this->_acl->addResource(new Zend_Acl_Resource('admin')); 

    $this->_acl->allow('guest', 'index'); 
    $this->_acl->allow('guest', 'about'); 
    $this->_acl->deny('guest', 'gisele'); 
    $this->_acl->deny('guest', 'users'); 

    $this->_acl->allow('user', 'users', array('index')); 
    $this->_acl->allow('admin', 'users'); 
    $this->_acl->allow('admin', 'gisele'); 
} 

public function preDispatch(Zend_Controller_Request_Abstract $request) { 
    if ($this->_auth->hasIdentity()) { 
     $role = $this->_auth->getStorage()->read()->role; 
    } else { 
     $role = self::DEFAULT_ROLE; 
    } 

    $action = $request->getActionName(); 
    $controller = $request->getControllerName(); 
    if ($this->_acl->has($controller)) { 
     if (!$this->_acl->isAllowed($role, $controller, $action)) { 
      $request->setActionName('login'); 
      $request->setControllerName('index'); 
     } 
    } 
} 
} 

而這個方法在我的引導,使這個類的使用:

protected function _initNavigation() 
{ 
    $this->_auth = Zend_Auth::getInstance(); 
    $this->_acl = new Federico_Plugin_Acl($this->_auth); 

    $this->bootstrap('view'); 

    $view = $this->getResource('view'); 
    $config = new Zend_Config_Xml(APPLICATION_PATH . '/configs/navigation.xml','nav'); 
    $navigation = new Zend_Navigation($config); 

    $roleAuth = $this->_auth->getIdentity(); 
    if(null == $roleAuth) 
     $role = 'guest'; 
    else 
     $role = $roleAuth->role; 

    $view->navigation($navigation)->setAcl($this->_acl)->setRole($role); 
} 

隨着這些配置設置像這樣,我得到以下錯誤:

Catchable fatal error: Argument 1 passed to Zend_View_Helper_Navigation_HelperAbstract::setAcl() must be an instance of Zend_Acl, instance of Federico_Plugin_Acl given, called in /home/fiodorovich/public_html/gisele/application/Bootstrap.php on line 118 and defined in /home/fiodorovich/library/ZendFramework/library/Zend/View/Helper/Navigation/HelperAbstract.php on line 333 Call Stack

這是自Federico_Plugin_Acl可以預料的是Zend_Controller_Plugin_Abstract的全部實例......不過,如果我延長Zend_Acl裏,而不是我得到這個錯誤:

Fatal error: Zend_Acl_Role_Registry_Exception: Role 'guest' not found in /home/fiodorovich/library/ZendFramework/library/Zend/View/Helper/Navigation/HelperAbstract.php on line 522 

所以......我一直在努力了一段時間才能得到這個事情解決了,......但似乎沒有得到這個工作正常...任何想法,我在這裏失蹤?

+0

SETACL期望得到一個Zend_Acl中的實例,但你的ACL是在擴展Zend_Controller_Plugin_Abstract definied 。你必須使用setAcl($ this - > _ acl - > _ acl)(這將不起作用,你已經設置它爲私人,但你明白了。) – Rufinus 2011-06-09 14:29:27

+0

@Rufinus,這是真的。我應該把它設置爲公共還是什麼?我真的不知道這是什麼方法 – 2011-06-09 14:32:36

+0

是的,這是最簡單的解決方案,或者你添加一個像'''''public function getAcl(){return $ this - > _ acl; }' – Rufinus 2011-06-09 14:42:16

回答

1

Zend_Controller_Plugin_Abstract和Zend_Acl是完全不同的東西。你想要做的就是讓ACL對象你的插件(這是現在在私營部分),並把它傳遞到

$view->navigation($navigation)->setAcl(<here>); 
+0

我知道,但我在Federico_Plugin_Acl中實例化了Zend_Acl,那麼有沒有辦法解決這個問題? – 2011-06-09 14:30:49

+0

可能的解決方案:將getAcl()方法添加到您的插件中,該插件返回$ this - > _ acl,然後在上面顯示的位置調用$ plugin-> getAcl()。 – akond 2011-06-09 14:34:00