php - ZF2 使用 zfcrbac zfcUser 和分层角色策略生成导航

标签 php zend-framework zend-framework2 zfcuser zfc-rbac

我从 zf2 开始,必须处理多对多权限/角色。使用ZfcRbac .

所以我用用户/层次角色(表名=角色)/权限进行映射

我用拒绝策略做了一些守卫。

我的守卫、 map 、数据库都正常。

我的 HierarchicalRole 实体看起来像:

class HierarchicalRole implements HierarchicalRoleInterface

目前它与 Bakura 给出的原始版本相同。

我的用户实体如下所示:

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 开发者工具,我可以看到 ZfcRbac\Collector\RbacCollector 显示了我想要的实际登录用户的所有内容(权限、子级、主要角色等...)。

我的问题是:如何为只能看到被授予访问权限的链接的用户生成动态导航?。并且还在用户未登录时检查连接并在用户登录时隐藏它......

我还是个新手,但如果可能的话,最好有一个很好地解释使用此模块进行良好动态导航的示例。

编辑(5 月 28 日) 到目前为止,我一直在寻求解决方案,我的尝试还没有帮助我。 您可以在这里找到一个: Spiffy navigation 仍然不能完美工作。

最佳答案

我将向您展示 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 Navigation View Helper 的 isAllowed 方法(最后将事件附加到 Zend Navigation View Helper 的 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')
    );
}

在 View 或布局中呈现菜单:

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

我正在使用这段代码,它运行得很好。它基于:

关于php - ZF2 使用 zfcrbac zfcUser 和分层角色策略生成导航,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22990852/

相关文章:

zend-framework - Zend Form 多选数组

php - 增加mysql连接数

php - 使用 Laravel Migration 使列自动递增

PHP header ('Location: ' 。 $url) http1.0 对比 http1.1 对比?

php - 使用php从Mysql编辑数据

zend-framework - Composer 错误: 'does not contain valid JS'

zend-framework - 单击 zend_form_element_submit 按钮时如何防止页面重新加载?

php - sql表如何添加从sql表中获取的数字数组

php - Zend Db(标准或表格网关)与 Zend 2 中的 Doctrine - 优点/缺点

php - 无法打开输入文件 : composer. phar