ZfcRbac が (ZF2) Zend/Navigation と連携する方法を紹介します。データベースにパーミッションの定義があるので、このセクションは省略します。
ナビゲーションを追加するページと権限を定義します。
config/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(); ?>
私はこのコードを使用していますが、非常にうまく機能します。以下に基づいています。