RFC: New Validation Component

I’ve started the repository under my own username on github at this time:

What I’ve done at this time:

  • I’m using the name zend-datavalidator, with the namespace Zend\DataValidator.
  • I’ve modified the proposed interfaces and traits to use the Interface and Trait suffixes pending a decision on how these artifacts should be named; consistency with existing components is likely more important at this time than other concerns.
  • I’ve added a ValidatorChain implementation, which relies on a ResultAggregate implementation to deliver the results. The chain only aggregates concrete validator instances, and executes them in the order in which they are attached (no container or priority awareness).
  • I’ve provided a Between validator implementation to demonstrate how validators might be written. It in turn extends an AbstractValidator implementation; this only provides some basics around failure message codes/templates, as well as a mechanism for building a validation failure result based on one or more such templates.

I’ve not written documentation yet, pending review by interested parties; use the tests to get an idea of how the component works.

My feeling at this time is that validator chains should likely be built from concrete instances. Since both validators and chains are stateless, this means that the services can be safely shared; I would expect discrete factories based on the needs of your application and/or individual data sets.

5 Likes

Why should the Result object contain the validated value? Provide the value is not the responsibility of validators, nor of the Result object, is it ?

The idea is that this will eventually be part of an input filter; in that situation, we would want access to both the filtered/normalized value and the raw value.

Additionally, encapsulating the value allows passing the result as a single message, giving the receiver access to the value as well.

Finally, having the value present allows it to be passed along with any other contextual variables to the ValidationErrorMessage instances for purposes of reporting or logging; we want to delay creation of these instances until they are requested.

Retaining the value is not the responsibility of the validator, as that
makes the validator not reusable in the context of concurrent or shared
(across layers) usage due to its stateful nature.

Getting rid of the value/messages from the validator was the first step in
this design.

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

@matthew

The current InputFilter component already retains the raw values, and the new InputFilter proposed by Bakura (which seems will be used for 3.0) retains the raw and filtered values.
We can still access to the raw values using InputFilter even if the validator result does not contain it.

When using validators without InputFilter, the raw value is passed to the validator, so the raw value is already available.

If ValidationErrorMessage instances must use the raw value, it could be passed by the validator to the ValidationErrorMessage constructor in the same way that contextual variables are.
As validators are now stateless, the raw value used to validate is a contextual variable.

@matthew, @ocramius Anyway, I understand your points of view, but we can consider not keeping the value in the result of validator.

The value in the result are required to compose error messages and for
logging purposes.

Also, that’s what you’d pass to the next “layer”: a “validated result”.

This is not necessarily true; it’s more than probable we will not use that code base, particularly as it made assumptions about the design of the validation component that are no longer true.

The plan at this point is for input filtering to also be stateless, and follow a similar design to this component: pass values to validate, and receive a result object back.

As @ocramius also notes, retaining the value in the result asked us to pass a single message to loggers, error handlers, etc. without requiring an additional message/argument.

I’m curious why you feel so strongly that we should not do this…

It’s just a suggestion, I’m not saying that we should not do this.

It seems strange to me to retain the raw value in the validator result, as we already have access to it anyway. The exception is, as you pointed, to get the value to compose error messages, but in this case value could be part of the $this->messageVariables passed to the constructor of ValidationFailureMessage. I’m not aware about how loggers work, I don’t know if they need the value to be treated differently from other messages variables.

Anyway, I got my answer, thanks :slight_smile:

We may have access to it in the scope in which the validation occurs, but that would then require passing that raw value and the result to any logger/reporter functionality. Passing only the result is far simpler.

+1 about Interface and Trait suffixes: “[…] consistency with existing components is likely more important at this time than other concerns.”

This change has already been made, and is reflected in the repository.

1 Like