A free and open-source book on ZF3 for beginners


17.14. Добавляем плагин контроллера Access и помощник представления

Для обращения к RbacManager внутри контроллеров и шаблонов представлений, нам нужно создать специальный плагин контроллера (который мы назовем Access) и специальный помощник представления (который мы тоже назовем Access).

17.14.1. Плагин контроллера Access

Иногда требуется проверить какую-либо привилегию внутри контроллера. Например, это понадобится для привилегии profile.own.view, которая использует динамические утверждения. Для этой цели мы создадим плагин контроллера Access.

Код данного плагина будет находиться внутри файла AccessPlugin.php в каталоге Controller/Plugin корневой директории модуля User:

<?php
namespace User\Controller\Plugin;

use Zend\Mvc\Controller\Plugin\AbstractPlugin;

/**
 * Этот плагин контроллера используется для контроля доступа на основе ролей (RBAC).
 */
class AccessPlugin extends AbstractPlugin
{
    private $rbacManager;
    
    public function __construct($rbacManager)
    {
        $this->rbacManager = $rbacManager;
    }
    
    /**
     * Проверяет наличие заданной привилегии у залогиненного в текущий момент пользователя.
     * @param string $permission Имя привилегии.
     * @param array $params Опциональные параметры (используются только если привилегия связана с утверждением).
     */
    public function __invoke($permission, $params = [])
    {
        return $this->rbacManager->isGranted(null, $permission, $params);
    }
}

Фабрика плагина Access выглядит таким образом:

<?php
namespace User\Controller\Plugin\Factory;

use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use User\Service\RbacManager;
use User\Controller\Plugin\AccessPlugin;

/**
 * Это фабрика для AccessPlugin. Ее целями являются инстанцирование плагина
 * и внедрение зависимостей в его конструктор.
 */
class AccessPluginFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {   
        $rbacManager = $container->get(RbacManager::class);
        
        return new AccessPlugin($rbacManager);
    }
}

Плагин регистрируется внутри файла module.config.php следующим образом:

// Мы регистрируем предоставляемые модулем плагины контроллера под этим ключом.
'controller_plugins' => [
    'factories' => [
        Controller\Plugin\AccessPlugin::class => Controller\Plugin\Factory\AccessPluginFactory::class,
    ],
    'aliases' => [
        'access' => Controller\Plugin\AccessPlugin::class,
    ],
],

Таким образом, вы легко можете вызвать этот плагин в вашем действии контроллера:

if (!$this->access('profile.own.view', ['user'=>$user])) {
    return $this->redirect()->toRoute('not-authorized');
}        

17.14.2. Помощник представления Access

Иногда может потребоваться обратиться к RbacManager внутри шаблона представления. Например, вам может понадобиться спрятать или, наоборот, показать какой-нибудь HTML-блок в зависимости от привилегий текущего пользователя.

Код помощника представления будет находиться в файле Access.php в каталоге View/Helper корневой директории модуля User:

<?php
namespace User\View\Helper;

use Zend\View\Helper\AbstractHelper;

/**
 * Этот помощник представления используется для проверки привилегий пользователя.
 */
class Access extends AbstractHelper 
{
    private $rbacManager = null;
    
    public function __construct($rbacManager) 
    {
        $this->rbacManager = $rbacManager;
    }
    
    public function __invoke($permission, $params = [])
    {
        return $this->rbacManager->isGranted(null, $permission, $params);
    }
}

Фабрика помощника представления Access выглядит следующим образом:

<?php
namespace User\View\Helper\Factory;

use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use User\Service\RbacManager;
use User\View\Helper\Access;

/**
 * Это фабрика для помощника представления Access. Ее целями являются инстанцирование помощника
 * и внедрение зависимостей в его конструктор.
 */
class AccessFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {   
        $rbacManager = $container->get(RbacManager::class);
        
        return new Access($rbacManager);
    }
}

Помощник представления зарегистрирован в файле конфигурации *module.config.php:

// Мы регистрируем предоставляемые модулем помощники представления под этим ключом.
'view_helpers' => [
    'factories' => [
        View\Helper\Access::class => View\Helper\Factory\AccessFactory::class,
    ],
    'aliases' => [
        'access' => View\Helper\Access::class,
    ],
],

Таким образом, вы легко можете вызвать помощник представления из любого из ваших шаблонов представления:

if ($this->access('profile.own.view, ['user'=>$user]))) {
   // что-то делаем...
}

Top