将输入过滤器添加到 ZF2 中的字段集 [英] Adding input filter to fieldset in ZF2
问题描述
我有一个表单Register
,它有一个字段集Profile
,而它又具有一个字段集Account
.字段集实现了 InputFilterProviderInterface
,从而实现了 getInputFilterSpecification
方法.这是我添加了在使用字段集时应使用的通用验证器和过滤器的地方.
I have a form Register
, which has a fieldset Profile
, which in turn has a fieldset Account
. The fieldsets implement InputFilterProviderInterface
and thus the getInputFilterSpecification
method. This is where I have added general validators and filters that should be used whenever the fieldsets are used.
现在,在我的注册表中,我想验证具有给定用户名的帐户不存在.因此,我需要添加一个验证器来补充在 Account
字段集上定义的验证器.这就是我遇到麻烦的地方.经过一番挖掘,我发现了一个 向字段集添加输入过滤器的方法.这样,我想,我可以向我的 Account
字段集添加一个额外的输入过滤器.
Now, in my registration form, I want to validate that an account with a given username does not already exist. Therefore I need to add a validator to complement the validators that are defined on the Account
fieldset. This is where I got in trouble. After digging around a bit, I found a way to add input filters to fieldsets. This way, I figured, I could add an additional input filter to my Account
fieldset.
class Register extends Zend\InputFilter\InputFilter
{
public function __construct()
{
$this->add(new RegisterProfileFilter(), 'profile');
}
}
使用上面的代码,我可以将输入过滤器添加到我的 Profile
字段集,并且在该输入过滤器中,我可以对我的 account
字段集执行相同操作.但是,这种方法似乎存在两个问题:
With the above code, I am able to add an input filter to my Profile
fieldset, and within that input filter, I can do the same for my account
fieldset. However, it looks like there are two problems with this approach:
- 似乎我必须为层次结构中的每个字段集创建一个输入过滤器;在这种情况下,我必须为
Profile
字段集创建一个输入过滤器,以便我可以将输入过滤器添加到Account
字段集 - 即使我不需要将任何验证器或任何内容添加到Profile
字段集.如果我尝试将过滤器直接添加到account
字段集,则它不起作用 - 似乎将输入过滤器对象添加到字段集会清除我在字段集的
getInputFilterSpecification
方法中定义的过滤器,而不是像我想要的那样合并两者
- It seems as if I have to create an input filter for each of my fieldsets in the hierarchy; in this case I have to create an input filter for the
Profile
fieldset just so that I can add an input filter to theAccount
fieldset - even if I don't need to add any validators or anything to theProfile
fieldset. It doesn't work if I try to add the filter to theaccount
fieldset directly - It seems as if adding an input filter object to a fieldset wipes out the filter that I have defined in the fieldset's
getInputFilterSpecification
method instead of merging the two like I want
有没有办法将在我的字段集上定义的输入过滤器规范与附加规范(或 Zend\InputFilter\InputFilter
的实例)合并,这样我就不必将我的字段集规范复制到我的输入过滤器类?那将是重复的代码并且不是很容易维护.还是我错过了什么导致我走错了路?
Is there a way to merge the input filter specification defined on my fieldsets with an additional specification (or instance of Zend\InputFilter\InputFilter
such that I don't have to copy my fieldset specification into my input filter class? That would be duplicate code and not be very maintainable. Or did I miss something causing me to be on the wrong track?
以下是我的代码,如果有帮助的话.
Below is my code if it is helpful in any way.
// 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
);
}
}
推荐答案
Merging InputFilters 在 Zend\Form
组件中没有很好地涵盖.必须有人真正重构整个事情.
Merging InputFilters isn't very well covered in the Zend\Form
component. Someone must really refactor the whole thing.
无论如何,在您的情况下,通过覆盖表单中的 getInputFilter
方法,在创建整个 InputFilter 之后添加验证器是可行的,因此我建议您这样做.
Anyway, what will work and therefore I would recommend in your situation, is adding the validator after the whole InputFilter has been created by overriding the getInputFilter
method in your Form.
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;
}
}
作为旁注,我建议每个 Form
基础而不是每个 Fieldset
定义 InputFilters
,因为 Fieldset
中的元素code> 在不同的上下文(=Form)中通常有不同的验证要求".但也许这更多是个人喜好.
As a sidenote I would recommend defining InputFilters
per Form
basis and not per Fieldset
, since elements in a Fieldset
often have different "validation requirements" in different contexts(=Form). But maybe that's more a personal preference.
这篇关于将输入过滤器添加到 ZF2 中的字段集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!