New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Validations with Callback or Iterator #497
Comments
@doc987 I don't have the time to implement this; I already have too much stuff on my todo list, and this feature is complex. However, you are welcome to implement it yourself and submit a pull request. Due to the way JSON schema works, and some of the changes coming up in draft-08, this would be best done as a callback, rather than an iterator. I'd be happy with a callback feature, but would object strongly to an iterator-based implementation. |
I'm not familiar with the code for this project. Would you be able to provide any guidance on where a callback implementation should go? Any pointers or suggestions you have could be helpful. Out of curiosity, what drawbacks do you envision for an iterator? |
It's a mess. Lots of legacy garbage. It's been cleaned up somewhat over the last year or so, but there's still a long way to go.
Iteration is a preprocessing model, which isn't possible with JSON schema. Attempting to pre-process |
Also: JSON Schema uses an injection model that should allow you to subclass as many of the constraints as you need and then you can simply override any point in the code that seems appropriate for what you want to do. The upside of such an approach is that you don't have to sell the idea to us or get put through the unit test wringer. The downside is that you will be circumventing the API contract and will be on your own for making sure your code doesn't break if internal changes ever happen. For example:
|
What do you think about changing the For example, consider the function protected function checkString($value, $schema = null, JsonPointer $path = null, $i = null)
{
$validator = $this->factory->createInstanceFor('string');
$validator->check($value, $schema, $path, $i);
$this->addErrors($validator->getErrors());
} Suppose the The change of $value to a reference would maybe apply to:
Callbacks could be added to:
Side Note: Many of the functions in that file have a similar format. Do you think it makes sense to make a more generic function (example below)? protected function checkType($type, $value, $schema = null, JsonPointer $path = null, $more = [])
{
$validator = $this->factory->createInstanceFor($type);
$validator->check($value, $schema, $path, $more);
$this->addErrors($validator->getErrors());
} |
I'd be OK with that, provided there's a legitimate reason for doing so - some of them already do this for the purpose of setting defaults. However... ...why do you want to change them? You've proposed adding callbacks in many places (rather than just one), and changing
|
I was thinking that specific checks (e.g. string) didn't go through At that stage the |
That sounds good. How do you intend to handle cases where failure is actually the expected outcome (i.e. failure does not mean that the value is invalid)? |
I'm not sure that the expected outcome is relevant for this purpose. The callback functions would be called in all cases, so those functions get to choose what to do (if anything). Am I missing something? |
Well, you mentioned that the primary purpose of these callbacks was to modify values that failed validation, in order to make them pass validation on a second attempt. If something is supposed to fail, then the callback would need to know that, in order to avoid modifying a value that should not be modified. If you don't pass expected-failure information to the callback, then how will you know whether or not to modify the value? |
I was thinking that |
I'm saying that, as things stand, you cannot tell the difference between the following:
With the way validation works currently, they look exactly the same - in both cases, For example, take the following schema: {
"not": {
"type": "string"
},
"maximum": "10"
} If your document is In order to implement your feature, you will need some way for the callback to tell the difference between an error in |
Is it possible to "wait" until all validations have been run for a field? In your example, that would mean that the post-validation callback isn't called until the not string and maximum tests have been run, at which point the callback would be informed that the field is valid (no errors). Alternatively, is it possible to wait until the full not string validation is complete before calling the post-validation callback? |
There is not currently any mechanism in the library to do this - you would need to implement it yourself as part of the PR. |
I would humbly suggest closing this. It seems outside the scope of what this library is trying to accomplish, and would significantly increase the complexity of the business logic, an order of magnitude more edge cases that would need to be covered in tests, etc. I think the more important thing is to have granular and complete error reporting so that the application using the validator can react, re-validate as needed, etc. |
Although I've mentioned this issue in #716 in the list of Issues that need a more in depth triage. But considering this once again and seeing the thoughts of @dafeder I think that it is indeed best to consider this out of scope for this library indeed. @doc987 you probably can still make this into a separate project which uses this library in its core for the validation. |
I'd like to be able to do an action before and after each field validation, and then have the option to redo the validation after the action. This would help to accept a JSON document that has some invalid entries, but could still be accepted with some modification. Example use cases:
This could be achieved by either of the following:
The text was updated successfully, but these errors were encountered: