代码之家  ›  专栏  ›  技术社区  ›  Volo

Zend Framework 2通过工厂创建表单。如何根据角色从字段集中删除元素?

  •  0
  • Volo  · 技术社区  · 8 年前

    我通过配置字段集,使用工厂和指定的表单结构创建表单。

    但是,角色为“”的用户 管理 “可以使用实体和普通用户的所有字段编辑表单” 客户 “只编辑几个字段。这就是为什么我必须从controller中的字段集中删除元素。

        $this->form->getBaseFieldset()->remove('name');
        $this->form->getBaseFieldset()->remove('title');
        $this->form->getBaseFieldset()->remove('message');`
    

    是否可以在字段集或表单配置中指定必须添加或删除的角色元素?

    class ZoneDefaultElement extends Fieldset implements InputFilterProviderInterface
    {
    
        public function __construct($name, $entity)
        {
            parent::__construct($name);
    
            $this->add([
                'name' => 'title',
                'type' => Element\Text::class,
                'attributes' => [
                    'class' => 'form-control',
                ],
                'options' => [
                    'label' => 'Title',
                    'label_attributes' => [
                        'class' => 'col-sm-2 control-label required',
                    ],
                ],
            ], ['priority' => 1])
         };
    }
    
    2 回复  |  直到 8 年前
        1
  •  0
  •   Jeffwa    8 年前

    构造函数的第二个参数可以是任何东西(实际上 Fieldset 它是一个空的 array 如果没有给出),那么您应该能够传入一个要使用的项目数组:

    class ZoneDefaultElement extends Fieldset implements InputFilterProviderInterface
    {
    
        public function __construct($name, $options)
        {
            parent::__construct($name);
    
            $entity = $options['entity'];
            $user = $options['user'];
    
            // Standard element
            $this->add([
                'name' => 'title',
                'type' => Element\Text::class,
                'attributes' => [
                    'class' => 'form-control',
                ],
                'options' => [
                    'label' => 'Title',
                    'label_attributes' => [
                        'class' => 'col-sm-2 control-label required',
                    ],
                ],
            ], ['priority' => 1]);
    
            if ($user->isAdmin()) {
                // Add "admin-only" elements
            }
        };
    }
    
        2
  •  0
  •   Volo    8 年前

    上面提供的解决方案很好。如果系统不是很大,并且形式上包含的元素很少,则可以对其进行维护。由于系统有点复杂,我决定提供更多面向对象的解决方案。

    class ZoneDefaultElement extends Fieldset implements InputFilterProviderInterface
    {
        public function __construct($name, $entity)
        {
            parent::__construct($name);
    
            $this->add([
                'name' => 'title',
                'options' => [
                    'label' => 'Title',                  
                ],
            ], ['priority' => 1, 'access' => ['allow' => ['admin'])
         }
    };
    

    拒绝配置如下:

            $this->add([
              'name' => 'message',            
              'options' => [
                'label' => 'Message',              
              ],
            ], ['priority' => 1, 'access' => ['deny' => ['guest'])
    

    我在字段集和自定义字段集之间又添加了一层:

    class ExtendedFieldset extends Fieldset
    {
        public $formMiddleware;
    
        public function __construct($name = null, $options = array())
        {
            parent::__construct($name);
        }
    
        public function add($elementOrFieldset, array $flags = [])
        {
            if (array_key_exists('access', $flags)) {
                if(!$this->getFormMiddleware()->filter($flags['access'])){
                    return false;
                };
            }
            parent::add($elementOrFieldset, $flags);
        }
    
        public function setFormMiddleware(FormMiddleware $formMiddleware)
        {
            $this->formMiddleware = $formMiddleware;
        }
    
        public function getFormMiddleware()
        {
            if (!$this->formMiddleware) {
                throw new \InvalidArgumentException("FormMiddleware not specified");
            }
            return $this->formMiddleware;
        }
    }
    

    现在,我们必须从这个ExtendedFiedset进行扩展,它覆盖父add()方法,并为实现过滤逻辑的中间件提供setter和getter。

    class UserFieldset extends ExtendedFieldset implements InputFilterProviderInterface
    {
        private $entityManager;
    
        public function __construct(EntityManager $entity, FormMiddleware $formMiddleware)
        {
            $this->setFormMiddleware($formMiddleware);
    
            parent::__construct('fieldset');
    
            $this->add([
                'name' => 'email',
                'type' => Element\Email::class,
                'attributes' => [
                    'class' => 'form-control',
                    'required'  => 'required',
                ],
                'options' => [
                    'label' => 'Email:',
                    'label_attributes' => [
                        'class' => 'col-sm-4 control-label required',
                    ],
                ],
            ], ['priority' => 1, ['access' => ['deny' => ['guest']]]]);
      }
    

    }

    最后是FormMiddleware:

    class FormMiddleware
    {
        private $authenticationService;
    
        public function __construct(AuthenticationServiceInterface $service)
        {
            $this->authenticationService = $service;
        }
    
        private function getUserRole() : string
        {
            $this->getIdentity()->getRole();                
        }
    
        public function getIdentity()
        {
            $identity = $this->authenticationService->getIdentity();
            return $identity;
        }
    
        public function filter(array $resource = [])
        {
            $marker = true;
            if(!empty($resource)){
    
                if(array_key_exists('deny', $resource)){
                    if(in_array($this->getUserRole(), $resource['deny'])){
                        $marker = false;
                    }else{
                        $marker = true;
                    }
                }
    
                if(array_key_exists('allow', $resource)) {
                    if(in_array($this->getUserRole(), $resource['allow'])){
                        $marker = true;
                    }else{
                        $marker = false;
                    }
                }
            }
            return $marker;
        }
    }
    

    这取决于项目结构,我希望一个想法是明确的。。。

    推荐文章