Bryce -

I think that it should be the job of the Zend_Validate_Builder to understand required and optional fields. Again, I go back to my point that it doesn't make sense for an integer validator to return true for an empty string. An empty string is not an integer, so the correct response should be false. Maybe a change needs to occur with the Zend_Validate_Builder. What if by default, all fields are optional and the developer only declares those fields that are required.

Lets use your example of the optional mailing address and add a required name field. Notice that instead of flagging the optional fields 'address2' and 'address3', I've lumped them in with 'address1' and 'city' (optional fields). I can then rely on the Zend_Validate_AllOrNone to signal an error if some but not all of the address fields are filled in.
<?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('name', $string100,
   Zend_Validate_Builder::REQUIRED);
$validate->addValidator($fields, new Zend_Validate_AllOrNone($reqd));
$validate->addValidator(array('address1', 'address2', 'address3', 'city'), $string100);
// 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)) {
   ...
}
?>

In your reply you stated "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.". Can you elaborate more on this item? If the field is supplied, then it should be validated. If it is not supplied (empty string), then what would be the purpose of validating it against the list of validators? I believe that its the responsibility of Zend_Validate_Builder to signal an error if a required field is not supplied. After all, its the one that understands the difference between optional and required fields.

As for your error message callback functionality. I love it. I think it's a great approach to a difficult problem of separating business and view logic.

Dale

Bryce Lohr wrote:
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


--
------------------------------------------------------------------------
Dale McNeill                  |
Alchemy Systems               | phone: (512) 532-8050
http://www.alchemysystems.com | email: [EMAIL PROTECTED]
------------------------------------------------------------------------

Reply via email to