在ZF2中将输入过滤器添加到fieldset

时间:2014-04-21 16:38:13

标签: php zend-framework2

我有一个表单Register,其中有一个字段集Profile,而该字段集又有一个字段集Account。字段集实现InputFilterProviderInterface,因此实现getInputFilterSpecification方法。这是我添加通用验证器和过滤器的地方,每当使用字段集时都应该使用它们。

现在,在我的注册表单中,我想验证具有给定用户名的帐户是否尚不存在。因此,我需要添加一个验证器来补充Account字段集上定义的验证器。这是我遇到麻烦的地方。在挖了一下后,我找到了way to add input filters to fieldsets。这样,我想,我可以在我的Account字段集中添加一个额外的输入过滤器。

class Register extends Zend\InputFilter\InputFilter
{
    public function __construct()
    {
        $this->add(new RegisterProfileFilter(), 'profile');
    }
}

使用上面的代码,我可以在Profile字段集中添加输入过滤器,在该输入过滤器中,我可以对account字段集执行相同的操作。但是,这种方法看起来有两个问题:

  1. 好像我必须为层次结构中的每个字段集创建一个输入过滤器;在这种情况下,我必须为Profile字段集创建输入过滤器,以便我可以向Account字段集添加输入过滤器 - 即使我不需要添加任何验证器或Profile字段集的任何内容。如果我尝试直接将过滤器添加到account字段集,则无法正常工作
  2. 似乎向字段集添加输入过滤器对象会清除我在字段集getInputFilterSpecification方法中定义的过滤器,而不是像我想要的那样合并两者
  3. 有没有办法将我的fieldsets上定义的输入过滤器规范与另一个规范(或Zend\InputFilter\InputFilter的实例)合并,以便我不必将我的fieldset规范复制到我的输入过滤器类中?这将是重复的代码而不是非常易于维护。或者我错过了导致我走错路的东西?

    以下是我的代码,如果它有任何帮助。

    // The code has been altered to be more self-explanatory and shorter
    
    class RegisterForm extends \Zend\Form\Form
    {
        public function __construct()
        {
            parent::__construct('register');
    
            // Elements are added here
    
            $profileFieldset = new ProfileFieldset();
            $profileFieldset->setUseAsBaseFieldset(true);
            $this->add($profileFieldset);
        }
    }
    
    
    class ProfileFieldset extends \Zend\Form\Fieldset implements InputFilterProviderInterface
    {
        public function __construct()
        {
            parent::__construct('profile');
    
            // Elements are added here
    
            $this->add(new AccountFieldset());
        }
    
        public function getInputFilterSpecification()
        {
            return array(
                /***** The below is apparently cleared when adding an input filter to this fieldset *****/
                'some_element1' => array(
                    'required' => false,
                ),
                'some_element2' => array(
                    'required' => false,
                ),
            );
        }
    }
    
    
    class AccountFieldset extends \Zend\Form\Fieldset implements InputFilterProviderInterface
    {
        public function __construct()
        {
            parent::__construct('account');
    
            // Elements are added here
        }
    
        public function getInputFilterSpecification()
        {
            return array(
                /***** This is the element that I want to add an additional validator to in a specific context (form) *****/
                'username' => array(
                    'required' => true,
                    'validators' => array(
                        new Validator\StringLength(array(
                            'min' => 4,
                            'max' => 15,
                        )),
                        new I18nValidator\Alnum(false),
                    ),
                ),
    
                // Other elements here
            );
        }
    }
    

1 个答案:

答案 0 :(得分:6)

合并输入过滤器并未在Zend\Form组件中得到很好的覆盖。有人必须真正重构整个事情。

无论如何,在你的情况下我会推荐什么,是在通过覆盖表单中的getInputFilter方法创建整个InputFilter之后添加验证器。

class RegisterForm extends \Zend\Form\Form
{
    public function __construct()
    {
        // add stuff
    }

    public function getInputFilter()
    {
        $formInputFilter = parent::getInputFilter();
        $usernameInput = $formInputFilter->get('profile')->get('account')->get('username');

        $myValidator = new Validator\SomeValidator();
        $usernameInput->getValidatorChain()->addValidator($myValidator);

        return $formInputFilter;
    }
}    

作为旁注,我建议根据InputFilters而不是Form定义Fieldset,因为Fieldset中的元素通常具有不同的"验证要求&# 34;在不同的背景下(=表格)。但也许这更像是个人偏好。