-
Notifications
You must be signed in to change notification settings - Fork 49
Problems working with allowEmpty & required #7
Conversation
http://validator.particle-php.com/en/latest/required-optional/
This feels really clear compared to ZF inputFilter stituation - how about learning from them and introduce "optional" to zend-inputfilters? |
@Mischosch if I understand correctly the <?php
<<<CONFIG
packages:
- "zendframework/zend-inputfilter: ~2.5"
CONFIG;
// http://melody.sensiolabs.org/
$inputFilter = new \Zend\InputFilter\InputFilter();
$inputFilter->add([
'name' => 'foo',
'required' => true,
'allow_empty' => false,
]);
$inputFilter->add([
'name' => 'bar',
// I set required to false to signal that this key can be omitted entirely
'required' => false,
'allow_empty' => true,
]);
$data = [
'foo' => 'xyz',
];
$inputFilter->setData($data);
assert($inputFilter->isValid() === true);
|
jup, so far the theory - feel free to run the test yourself. |
Is this the essense of what you're getting at? <?php
<<<CONFIG
packages:
- "zendframework/zend-inputfilter: ~2.5"
CONFIG;
// http://melody.sensiolabs.org/
$inputFilter = new \Zend\InputFilter\InputFilter();
$inputFilter->add([
'name' => 'foo',
'required' => true,
'allow_empty' => true,
]);
$data = [ ];
$inputFilter->setData($data);
assert($inputFilter->isValid() === false); // fails If the Input is marked EDIT: I ran the above case against the highest revision of each minor ZF2 version and they all behave in the same way. |
Had my learning about having my own understanding and running into problems because of that. Better have explicit tests to find out what it is all about. I do believe others would run into the same problem, like you did now. If it's a bug, not sure, could be feature, too. There is a difference between having a value required, or the existence of a key related to the allowed_empty value. Not sure who is the package maintainer to ask more directly about this. You are the first commenting on my questions. I would not start workign on a possible fix for that until opinions on this topic are clear. I do not want to start to work on a PR that gets rejected, because it being a "hot" topic inside the last releases. |
@Mischosch have you seen #4 ? I'm not entirely sure if that's the only reason to fix things (it's certainly not the most beautiful one), but it works as intended now. This pretty much boils down to PHP Arrays and the handling of |
I'm really not a fan of the way We get far too many questions about it, too. It would be really nice if we could tidy this up. |
@manuakasam yes I read all related threads I could find about this topic. But I didn't found a solution to my problem there, only, that there were def some refactorings going on. @akrabat how do you think about the approach of http://validator.particle-php.com/en/latest/required-optional/ ? It feels really clear by only reading the description, as they divide between key and value. I have read much more about required/allow_empty for Zend\InputFilter and it was a huge amount of trying out the params to see what is happening. |
For the record, zendframework/zendframework#7474 details the exact interactions between |
@weierophinney as I understand your statement: this part is a sensible one and you would prefer keeping the things like they are instead of perhaps breaking (again) existing workflows by adding more otptions (like |
@Mischosch Adding another flag increases the complexity even more. "Optional" is the opposite of "Required", so, to my mind, I think having it as an additional flag would be even more confusing. I'll take a look at your question in more detail later today, and see if I can provide a solution using the existing flags; it's very likely possible, but it may require validation groups. |
@Mischosch I've taken your test cases from above and run them, and what I see is:
Based on your narrative, what you're looking for is the following:
The combination of |
@weierophinney yes, you understood my point! Thanks a lot for looking again at my question/tests. I do appreciate that you really tried to understand what my problem is and even more, that you try to find a possible solution. If I can help at any point, let me know! |
Per the issue, this patch ensures that if an input is marked as required **and** marked to allow empty that the following works as expected: - If the input name is present in the data set, but a value that evaluates to empty, it will validate as true. - If the input name **is not** present in the data set, it will validate as false.
- Mainly to ensure tests will pass!
@@ -219,7 +218,7 @@ public function isValid($context = null) | |||
} | |||
|
|||
$inputs = $this->validationGroup ?: array_keys($this->inputs); | |||
return $this->validateInputs($inputs, $data, $context); | |||
return $this->validateInputs($inputs, $this->data, $context); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This turned out to be the key. Using getRawValues()
was a poor solution, as it pulls values from the inputs themselves; since these return null when no value is set, there's no clean way to determine if the field was missing in the original data set!
Since the $data
set is what was originall passed, and it's only used for its keys in validateInputs()
, this provided the key to fixing the issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getRawValues
usage was exactly what I spotted to be the problem for my usecase and what I didn't understood on the validation workflow side (why don't they rely on given data and take the input filter as default set¿). I thought it was intended to go this way (always having a null default), so I didn't thought of it being a "poor solution". I just always thought that I didn't found the missing puzzle piece to understand it :)
I think that we should likely do an LTS release with this fix as well, as the problem and solution fit a number of reports I've seen since the 2.4 release. I'll schedule that for Monday (27 July 2015). |
Wow, @weierophinney - you're making me so happy. Thanks a lot for your done work. Next time I will try to add a possible solution as PR to my initial request. I think in this case you're def having a better overview of changes affecting other users, the history of the code and the definition of what these parameters should do or not do. (Hopefully my next problem is not inside such a sensible topic like validation.) I think this is a good thing for the InputFilter library. Makes it much more usable for API validation now and we do not need to refactor our code to another validation library. Thanks again for your time and work! 🎆 |
I agree. |
Released with:
(For ZF2 2.5 versions, just do a |
Per report on zendframework#15, the change made in zendframework#7 could lead to an issue if $data is an `ArrayAccess` instance, as `validateInputs()` typehinted on `array`. This patch adds a test for that condition, and removes the typehint.
Per report on zendframework#15, the change made in zendframework#7 could lead to an issue if $data is an `ArrayAccess` instance, as `validateInputs()` typehinted on `array`. This patch adds a test for that condition, and removes the typehint.
zendframework/zend-inputfilter#7 introduced a minor change in how required elements are handled in specific cases, and this results in a change in how the "Value is required" validation message is injected into validation failures. This patch makes the test more robust in searching for that message.
This PR broke BC for our project when upgrading from I suggest caution when upgrading until we actually find the regression (or verify that it was already fixed in /cc @asgrim |
Yes indeed, this change breaks our tests when upgrading, but it seems we are relying on incorrect behaviour to run tests. Despite reading through and agreeing with this particular change (which makes sense), it's still a BC break because previously behaviour was undefined, and projects (such as ours) are relying on this behaviour. I also understand that effort is being put in to clearly define expected behaviour now:
which it seems we're in this boat ;) We're going to have to lock our composer.json to |
Per report on zendframework#15, the change made in zendframework#7 could lead to an issue if $data is an `ArrayAccess` instance, as `validateInputs()` typehinted on `array`. This patch adds a test for that condition, and removes the typehint.
#74 already claims this introduce a BC Break. |
Hey there,
I'm trying to get my head around using Zend\InputFilter for validation. I don't use the library with Zend\Form, I try to use it for API backend data validation and filtering. In this setup we have POST data coming from outside and I would like to validate this against business rules.
Let's say, I have the attribute
foo
, which is required and allow_empty is false and I havebar
, which is required, but needs allow_empty true, to be able to set an empty string as value. Doing it this way, isValid returns false, if I do not provide anyfoo
key inside the array I provide with setData call. This is what I expect, everything finet.But if I provided a valid
foo
attribute and I do not provide anybar
key inside the data array, the isValid call will return true. What I would expect: failing like the first test, because the keybar
is completly missing.I do know, that there were many changes around isRequire and allowEmpty in last two releases. Since then we're struggeling with our defined InputFilters and trying to understand, what changes happend and how the logic behind this is thought to work now. I already have read, that the attribute continueIfEmpty is also having a role inside the InputFilter process and it is working for me, that validation rules get processed if I set it to true.
Digging through the isValid process I recognized, that firing an isValid call is first running through $this->getRawValues(); - after that point, $data array contains
bar
with NULL value, because the data keys are generated out of defined inputFilter. So setting continueIfEmpty to true and adding an own validator to check for existing key inside my data array does not work, because it does exist inside there, being populated through getRawValues call.So, is there any way to validate provided input for existiting keys with InpuFilter? Or how can I achieve having a fixed requirement of data keys, that need to be provided, or input gets marked as invalid? I would really to avoid extra checks like
My tests to show, what my problem is.