2014-04-10 36 views
2

我從zf2開始,我必須處理多對多的權限/角色。使用ZfcRbacZF2使用zfcrbac zfcUser和分層角色策略生成導航

所以我就與用戶/層次角色(表名=角色)/權限

一個映射和我做一些與警衛拒絕策略。

我的警衛,映射,數據庫,都可以。

我HierarchicalRole實體的樣子:

class HierarchicalRole implements HierarchicalRoleInterface 

而且它的,現在一樣由巴庫拉給出的原件。

我的用戶實體看起來是這樣的:

class User extends ZfcUserEntity implements IdentityInterface 

/** 
* @var \Doctrine\Common\Collections\Collection 
* @ORM\ManyToMany(targetEntity="HierarchicalRole") 
* @ORM\JoinTable(
*  name="user_role_linker", 
*  joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="idUser")}, 
*  inverseJoinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id")} 
*) 
*/ 
protected $roles; 

和角色是由內置的構造函數:

function __construct() { 
    $this->roles = new ArrayCollection(); 
} 

與Zend developper工具,我可以看到ZfcRbac\Collector\RbacCollector顯示所有我想要的實際登錄用戶(權限,孩子,主角等) 。

我的問題是:如何生成一個動態導航,用戶只能看到授予訪問的鏈接?。並且當用戶沒有登錄時檢查連接,當他登錄時將其隱藏...

我是一個新手,但如果可能的話,它將是一個很好的例子,很好地解釋了使用這個做一個好的動態導航模塊。

EDIT(5月28日) 到目前爲止,我一直尋求解決的辦法,我嘗試並沒有幫助我呢.. 你可以在這裏找到一個: Spiffy navigation 仍然沒有完美的工作。

回答

2

我將向您展示ZfcRbac如何與(ZF2)Zend/Navigation一起使用。 您有數據庫中權限的定義,這就是爲什麼我會省略此部分。

定義您的導航添加頁面和權限:

配置/ global.phpPHP:

return array(
     'navigation' => array(
      'default' => array(
       array(
        'label' => 'Contracts', 
        'route' => 'contract', 
        'action' => 'list', 
        'permission' => 'contract.list', 
        'pages' => array(
         array(
          'label' => 'New contract', 
          'route' => 'contract', 
          'action' => 'add', 
          'permission' => 'contract.add', 
         ) 
        ) 
       ) 
      ) 
     ), 
     'service_manager' => array(
      'factories' => array(
       'navigation' => 'Zend\Navigation\Service\DefaultNavigationFactory', 
      ) 
     ) 
    ); 

創建監聽(/module/Application/src/Application/Authorization/RbacListener.php):

<?php 

namespace Application\Authorization; 

use Zend\EventManager\EventInterface; 
use Zend\Navigation\Page\AbstractPage; 
use ZfcRbac\Service\AuthorizationServiceInterface; 

class RbacListener 
{ 
    /** 
    * @var AuthorizationServiceInterface 
    */ 
    protected $authorizationService; 

    /** 
    * @param AuthorizationServiceInterface $authorizationService 
    */ 
    public function __construct(AuthorizationServiceInterface $authorizationService) 
    { 
     $this->authorizationService = $authorizationService; 
    } 

    /** 
    * @param EventInterface $event 
    * @return bool|void 
    */ 
    public function accept(EventInterface $event) 
    { 
     $page = $event->getParam('page'); 

     if (!$page instanceof AbstractPage) { 
      return; 
     } 

     $permission = $page->getPermission(); 

     if (is_null($permission)) { 
      $event->stopPropagation(); 
      return false; 
     } 

     $event->stopPropagation(); 

     return $this->authorizationService->isGranted($permission); 
    } 
} 

創建的RbacListener一廠(/module/Application/src/Application/Factory/RbacListenerFactory.php):

<?php 

namespace Application\Factory; 

use Application\Authorization\RbacListener; 
use Zend\ServiceManager\FactoryInterface; 
use Zend\ServiceManager\ServiceLocatorInterface; 

class RbacListenerFactory implements FactoryInterface 
{ 
    /** 
    * {@inheritDoc} 
    */ 
    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     $authorizationService = $serviceLocator->get('ZfcRbac\Service\AuthorizationService'); 

     return new RbacListener($authorizationService); 
    } 
} 

將您的RbacListenerFactory添加到您的ServiceManager(/module/Application/config/module.config。PHP):

<?php 

return array(
    'service_manager' => array(
     'factories' => array(
      'Application\Authorization\RbacListener' => 'Application\Factory\RbacListenerFactory', 
     ), 
    ), 
); 

附加一個事件到Zend的導航視圖助手的isAllowed方法(最後一個事件附加到了Zend導航視圖助手的isAllowed法):

<?php 

public function onBootstrap(MvcEvent $event) 
{ 
    $application  = $event->getApplication(); 
    $eventManager  = $application->getEventManager(); 
    $sharedEventManager = $eventManager->getSharedManager; 
    $serviceManager  = $application->getServiceManager(); 
    $rbacListener  = $serviceManager->get('Application\Authorization\RbacListener'); 

    $sharedEventManager->attach(
     'Zend\View\Helper\Navigation\AbstractHelper', 
     'isAllowed', 
     array($rbacListener, 'accept') 
    ); 
} 

要渲染在視圖或佈局菜單:

<?php echo $this->navigation('navigation')->menu(); ?> 

我使用此代碼,它工作得很好。它是基於: