Hi all,
Thank you for all of the replies! That feedback is very valuable to me in trying
to figure out what to do with this stuff. I appreciate that you took your time
to share some of your input.
Allow me to elaborate on some the rationale behind the proposed changes, for
your kind consideration.
Passing empty strings:
I've actually removed this from the current version of the proposal, but I still
feel the idea has some merit. I certainly understand that it doesn't make much
sense at first to pass an empty string to Zend_Validate_Int, and it return true.
But if the validators are solely responsible for passing or failing all
values, it would be possible to write validators with complex rules for whether
or not a field is required, and yet still work with other validators on the same
field. If the higher-level class made the decision not to pass a field to a
validator (because it was empty), then the validators never get a chance to make
more intelligent decisions. And if all validators always failed empty strings,
you would not be able to combine validators on optional fields.
Consider the hypothetical validator, Zend_Validate_AllOrNone. This passes a
field if it's not empty, and all the fields passed to the constructor are not
empty, or if the field is empty and all the fields passed to the constructor are
empty. Here's an example:
<?php
$fields = array('address1', 'city', 'state', 'zip')
$reqd = array_intersect_key($post, array_flip($fields));
$string100 = new Zend_Validate_StringLength(100);
// This form has an optional mailing address where address1, city, state,
// and zip are all required if any are present. Otherwise, they must all be
// blank. address2 and address3 are always optional.
$validate = new Zend_Validate_Builder;
$validate->addValidator($fields, new Zend_Validate_AllOrNone($reqd));
$validate->addValidator(array('address1', 'city'), $string100);
$validate->addValidator(array('address2', 'address3'), $string100,
Zend_Validate_Builder::OPTIONAL);
// Assume $states is a valid array of US states
$validate->addValidator('state', new Zend_Validate_InArray($states));
// Another custom validator for Zip codes
$validate->addValidator('zip', new My_Zipcode_Valiadator);
if ($validate->isValid($post)) {
...
}
?>
Conditionally required fields, such as in this form, are rather common in
real-world applications. I don't consider this an edge case. This example will
only work under two conditions:
* The validators pass the empty string. If the $string100 validator doesn't
pass the empty string, then that validator will not allow the case where all
four main address fields are omitted.
* The higher-level isn't involved in the decision. If I put the OPTIONAL flag
on the four main address fields, then there's nothing that forces, for example,
the city field to be populated if the address1 field is populated.
So, in summary, if the validators pass the empty string, it allows more
collaboration between the validators, and complex validation can be done much
more easily. Of course, the biggest drawback is the fact you have to use at
least two validators to validate a required field. This is way I tried to make
doing this as painless as possible in the Zend_Validate_Builder proposal.
However, I do understand the burden this puts on those already using the
validators, as is. So, basically, I need you guys to tell me if the benefit is
worth the cost. I hope that I've made the benefits clear enough so you can see
the potential it would allow.
External validation errors:
When I started the Zend_Validate_Builder proposal, I was thinking I would see if
I could get all the current validators to start using some kind of Error
Manager class to generate and raise their errors. This class would be could be
set by the user to their own class, if they wanted to. I as I thought about it,
I realized that I could push basically the same API that would be used against
the Error Manager out to an arbitrary callback function. If one were to treat
the callback function as a sort of user-defined extension of the validator
function, and put code in there to invoke some kind of Error Manager class, then
you could get same results, only easier. The Framework could still provide a
default Error Manager class, but there would be no implicit dependency this way.
It's loose coupling at it's best, IMHO. The validators would impose absolutely
no policy of their own on how you handle error messages. That said, the "best
practice" way to handle validation errors could still be designed, recommended,
and documented by the Zend Framework authors. Example "best practice" usage
could be shown in the documents and tutorials. It's just that one specific
policy wouldn't be hard-coded into the system.
I hope this clarifies for you guys why I proposed some of the things I did. I'm
certainly not adverse to other solutions, however, so please, suggest
alternatives. :)
Many thanks,
Bryce Lohr