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

And*_*708 4 php zend-framework2

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

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

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

使用上面的代码,我可以在我的Profilefieldset中添加一个输入过滤器,在该输入过滤器中,我可以为我的accountfieldset 做同样的事情.但是,这种方法看起来有两个问题:

  1. 似乎我必须为层次结构中的每个字段集创建一个输入过滤器; 在这种情况下,我必须为Profilefieldset 创建一个输入过滤器,这样我就可以在fieldset中添加一个输入过滤器Account- 即使我不需要在fieldset中添加任何验证器或任何东西Profile.如果我尝试直接将过滤器添加到account字段集,它不起作用
  2. 似乎向字段集添加输入过滤器对象会消除我在fieldset getInputFilterSpecification方法中定义的过滤器,而不是像我想要的那样合并两者

有没有办法合并我的字段集上定义的输入过滤器规范与另一个规范(或Zend\InputFilter\InputFilter我不必将我的字段集规范复制到我的输入过滤器类的实例?这将是重复的代码,不是很可维护或者我错过了导致我走错路的东西?

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

// 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
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

net*_*iul 6

合并InputFilters在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;
    }
}    
Run Code Online (Sandbox Code Playgroud)

作为旁注,我建议InputFilters按每个Form基础而不是每个基础进行定义Fieldset,因为Fieldset在不同的上下文中,元素通常具有不同的"验证要求"(=表格).但也许这更像是个人偏好.