简体   繁体   中英

Conditionally required in Zend Framework's 2 InputFilter

I am making an application using Zend Framework 2. I am validating input using it's InputFilter . Is it possible, to make some Input s required conditionally? I mean I have code like that:

$filter = new \Zend\InputFilter\InputFilter();
$factory = new \Zend\InputFilter\Factory();
$filter->add($factory->createInput(array(
    'name' => 'type',
    'required' => true
)));
$filter->add($factory->createInput(array(
    'name' => 'smth',
    'required' => true
)));

I want the field something , to be required, ONLY when type is equal 1 . Is there a built-in way to do that? Or should I just create custom validator?

First of all, you may want to enable validation on empty/null values as of Empty values passed to Zend framework 2 validators

You can use a callback input filter as in following example:

$filter = new \Zend\InputFilter\InputFilter();
$type   = new \Zend\InputFilter\Input('type');
$smth   = new \Zend\InputFilter\Input('smth');

$smth
    ->getValidatorChain()
    ->attach(new \Zend\Validator\NotEmpty(\Zend\Validator\NotEmpty::NULL))
    ->attach(new \Zend\Validator\Callback(function ($value) use ($type) {
        return $value || (1 != $type->getValue());
    }));

$filter->add($type);
$filter->add($smth);

This will basically work when the value smth is an empty string and the value for type is not 1 . If the value for type is 1 , then smth has to be different from an empty string.

I couldn't quite get the example by Ocramius to work, as $type->getValue was always NULL. I changed the code slightly to use $context and this did the trick for me:

$filter = new \Zend\InputFilter\InputFilter();
$type   = new \Zend\InputFilter\Input('type');
$smth   = new \Zend\InputFilter\Input('smth');

$smth
    ->getValidatorChain()
    ->attach(new \Zend\Validator\NotEmpty(\Zend\Validator\NotEmpty::NULL))
    ->attach(new \Zend\Validator\Callback(function ($value, $context){
        return $value || (1 != $context['type']);
    }));

$filter->add($type);
$filter->add($smth);

You can also use setValidationGroup for this.

Create your own InputFilter class where you set validation groups depending on the data that is set inside the inputfilter before executing the actual validation.

class MyInputFilter extends InputFilter
{
   setData($data){
       if(isset($data['type']) && $data['type'] === 1){
           // if we have type in data and value equals 1 we validate all fields including something
           setValidationGroup(InputFilterInterface::VALIDATE_ALL);
       }else{
           // in all other cases we only validate type field
           setValidationGroup(['type']);
       }
       parent::setData($data);
   }
}

This is just a simple example to show what is possible with setValidatioGroup , you can create your own combinations for setting validation groups after your specific needs.

$inputFilter->add([
        'name' => 'commPersconphone1number',
        'required' => (($this->session->ouCode == '50001') ? true : false),
        'error_message' => $this->arrLabels['err_phone'],
        'filters' => [
            ['name' => 'StringTrim'],
            ['name' => 'StripTags'],
            ['name' => 'StripNewlines'],
        ],
        'validators' => [
            [
                'name' => 'StringLength',
                'options' => [
                    'min' => 0,
                    'max' => 15,
                    'error_message' => $this->arrLabels['err_phone_invalid']
                ],
            ],
            [
                'name' => 'Regex',
                'options' => [

                    'pattern' => '/^[0-9]*$/',
                    'message' => $this->arrLabels['err_phone_invalid'],
                ],
            ],
        ],
    ]);

Unfortunately you'd have to set the required option based on your conditions like so:

$filter->add($factory->createInput(array(
    'name' => 'smth',
    'required' => (isset($_POST['type']) && $_POST['type'] == '1'),
)));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM