How to require a field only if some condition is true?

I have a field (let’s suppose it’s “prices”) that should only be required if other field (named “type”) is some value.
I saw that if some Input it’s not required, the package ignore when value is not provided, so add a validator in validator chain is useless. Also, if it’s required, the Input method will end the validation with an error before check if it’s really required.

How can I validate this case?

Hello and welcome to our forums! :smiley:

Do you mean laminas-inputfilter or the usage in form via laminas-form?

1 Like

It’s laminas-inputfilter.

Hi @valdinei,

The answer given in this post by @froschdesign might help you. Thanks!

Hi, @ALTAMASH80.

So, I know about the $context argument, but as I said in my post the validator that I would create and use the $context variable in isValid method won’t even be called by Input class (in this line 416).
The validation will fail in InputFilter isValid method (because the field is empty + not required) or it will fail in Input isValidmethod (because the field is empty + required), so will fail in both cases before my custom validator run.

The issue is not about condition with other field, is about be required in some conditions (what I think that it’s not possible with these packages).

Edit: in other words, I want to run the validator chain even if the value was not provided.

Hi @valdinei,

If you think what you’re trying to achieve is not possible in Laminas Validators/Filters packages then you should file an issue in the Laminas Form package and contribute to making it better for others. Thanks!

before you validate your form in your controller you can test the value of the type field and it its the type that doesn’t require a price you can remove the validator from the price field prior to validating the posted data.

1 Like

Please don’t do this! The form or the input filter can and should include the entire handling.
If you cannot find another solution, you can, for example, always overwrite the isValid method and change the input filter based on the specified data.

If you do this in the controller then you will run in the following problems:

  • handling of the data is outsourced and independent from forms and input filters
  • copy and past of external logic is needed if you use the form or input filter in other places, like controller actions, request handlers, …
  • the unit tests for form or input filter can not cover the real scenarios / usage

In some cases, the validation chain you define is never reached because the Laminas\InputFilter\Input::isValid() method produces a result before it:

If you run into this problem, the easiest option is to override the isValid method of your input filter. Or if you use laminas-form and specification of the input filter via array syntax, without separate class for the input filter, then overwrite the isValid of your form.

1 Like

I realize there are cons to my approach but it solves the problem till someone like you can point us to a more elegant solution. Thank You

Normalise and validate input – or other things – should not be spread over several layers. If you isolate it, it should work completely and correctly, then it can be easily reused and fully tested.
But this is not a problem specific of Laminas; it can be applied to any other framework.

The following issue can be found in the issue tracker of laminas-inputfilter:

2 Likes