vlucas/valitron

Allow key to be null / empty or a valid date

adarshmadrecha opened this issue · 5 comments

I have a key dtcomplete which should be a valid date. However it can also be empty.

$v = new Valitron\Validator(array('dtcomplete'=>""));
$rules = [
    'required' => [['dtcomplete', true]],
    'date' => [['dtcomplete']]
];
$v->rules($rules);
$v->validate();

I was under impression based on the discussion #208 that if required is passed a second parameter as true, then empty or null value is allowed in the key.

The 'required' rule is not failing, but the 'date' rule is. This makes sense: an empty string is not a valid date. Not having the 'required' rule would make sure that Valitron doesn't try to validate empty fields, which sounds like what you need

The key is always present and required to be present. Since I am getting the value in $_POST through the android app API call

The 'required' rule checks if the key exists: it does.
The 'date' rule checks if the value is a valid date: it isn't.

You'll notice that $v->errors() will only have an error about the date

I agree,

The 'required' rule checks if the key exists: it does.
The 'date' rule checks if the value is a valid date: it isn't.

But, if the required rule has 2nd parameter as true, then I suggest the behaviour should be that date will allow empty value.
Just a suggestion, as currently there is no way to configure

Key required
Can be blank (Empty)
If specified then it should be valid date

The parameter for the required rule only applies to the required rule for the specific field(s). I don't think changing that is a good idea to be honest.

The problem is still that you want to check that 'dtcomplete' is a date OR empty. The date rule only does the first part of that. While there's no way to configure the date rule to also allow empty values, you can always create a custom rule:

$v = new Valitron\Validator(array('dtcomplete'=>""));

$v->addInstanceRule('dateOrEmpty', function ($field, $value) {
    //allow empty values
    if (empty($value)) {
        return true;
    }

    //allow DateTime instances
    if ($value instanceof \DateTime) {
        return true;
    }

    //allow strings that can be parsed as a date
    if (strtotime($value) !== false) {
        return true;
    }

    return false;
});

$rules = [
    'required' => [['dtcomplete', true]],
    'dateOrEmpty' => [['dtcomplete']]
];
$v->rules($rules);
$v->validate();