2009年7月20日星期一

RE: [fw-mvc] breakChainOnFailure

Can you not just subclass Zend_Form and override the isValid() method in your
subclass to behave as you want?


Seth Atkins wrote:
>
> I appreciate the help here, but I think both of you are missing the
> point a little bit, or I haven't explained the problem well. I don't
> want to validate one element at a time, and yes I DO use the $context in
> my isValid function. Context gives you the full form input, I wouldn't
> even be asking this question if I didn't know how to pass the context
> and verify one field against the other. Context, to the best of my
> knowledge does not tell you the validation status of other elements, it
> just tells you what the user inputted for those elements, bogus or not.
>
> Let me ask it this way. If I were to submit country asdf and state
> gffdds, how the heck are you going to verify if the zip code is of the
> right format for a bogus country/state submission. Any error you present
> next to the zipcode field is going to be meaningless. You haven't helped
> the user at all by providing that extra "info" and you haven't decreased
> the likelihood one bit of them not having to resubmit the form a couple
> more times to get all the fields correct.
>
> If I assume that the country is a real country and the state a real
> state, then sure, all the tools I need are $context and serial
> validation of all elements. But when it comes to security of a website,
> preventing injection attacks and things of that nature, "assuming"
> things like this is a pretty poor practice. I'm not trusting in the
> honorability of the user to only select what I have in the select boxes
> when I know how easy it is to fabricate POST data to a website.
>
> The real situation I face is not a zip code, but that was an easier
> example to use than to describe how I have several joins and where
> clauses to make to pull together a data set that contains the data
> needed for form creation and validation. Now, I could simply remove the
> where clauses so it retrieves all records so it is all available to
> verify the dependent fields based on other fields and possible choices.
> Not real efficient. Or I could live with an extremely inefficient use of
> the database, with multiple queries to retrieve the same data: once to
> generate the form, once for EACH validator to validate the form based on
> it's own view of context, and once to write the form data back to
> database. Or I minimize the database querying by not validating what
> can't be validated if other fields are not correct. I'm trying to
> optimize and there are a number of cases where validation of an element
> is meaningless based on other elements and their validation. This is
> what I am trying to avoid.
>
> All the arguments presented against why I would find this feature useful
> can be used to argue against breakChainOnFailure at the element level
> too. Why not show all the things wrong with an entry? Why make the user
> fix one mistake at a time on an entry? The fact is, there are times when
> it is actually useful to suspend the remaining validation checks on an
> element once one check fails, JUST LIKE this is also sometimes useful
> behavior at the form level.
>
>
> --Seth
>
> -----Original Message-----
> From: Matthew Weier O'Phinney [mailto:matthew@zend.com]
> Sent: Saturday, July 18, 2009 5:01 PM
> To: fw-mvc@lists.zend.com
> Subject: Re: [fw-mvc] breakChainOnFailure
>
> -- Seth Atkins <satkins@nortel.com> wrote (on Friday, 17 July 2009,
> 01:19 PM -0500):
>> Then how does one validate dependent input? If certain fields need
>> certain validation criteria depending on a previous field containing
>> valid data, you can't properly validate the other fields.
>
> This has been covered many times before: add a second argument to your
> validator's isValid() declaration for $context:
>
> public function isValid($value, $context = null)
> {
> }
>
> Zend_Form passes the entire array as a second argument to isValid(). If
> you need to use it, it's available.
>
> This is well documented in the manual:
>
>
> http://framework.zend.com/manual/en/zend.form.elements.html#zend.form.el
> ements.validators
>
> and search for the heading, "Validation Context."
>
> This feature has been available since the initial stable release of
> Zend_Form in 1.5.0.
>
> This *is* different than having a "breakChainOnFailure" feature for
> Zend_Form itself, however, as this latter functionality changes the
> behavior of Zend_Form substantially. The current behavior is to run
> validation on *all* elements in order to return as much information
> about invalid entries as possible.
>
>> For example
>> suppose you wanted to check for valid zip codes based on the entered
>> state (so someone couldn't enter a NY zip code with state AZ. If
>> someone entered an invalid state and that failed its check, the
>> remaining check on the zip code would give a bogus "invalid" message.
>> I'd rather it simply suspend the rest of the form validation since the
>
>> rest cannot be validated properly.
>>
>> This may fall into the needed feature bucket for future releases,
>> unless there is an easy workaround. I managed to find a clunky way of
>> doing this by sort of "pre-validating" the input of the field that the
>
>> others depend on so I can put in a conditional to addValidator for the
>
>> affected elements. That way if the pre-validation fails, no validators
>
>> are added at all. If the pre-validation passes, then the others are
> validated.
>>
>> The way I implemented pre-validation was to pass the field input to
>> the form constructor. The form constructor has to gather some data
>> from the database anyway, so I simply compare that field input to this
>
>> data to ensure it is a valid selection. Hence it is pre-validated.
>>
>> I looked through the code for isValid methods and it seems that this
>> would be a fairly easy feature to implement if there was a mechanism
>> in Zend_Form::isValid similar to breakChainOnFailure to tell it to
>> stop looping through the element validators once one comes back false.
>
>> I could even do that myself, but I'm reluctant to start tinkering
>> around changing the code base of ZF.
>>
>>
>>
>> --Seth
>>
>> -----Original Message-----
>> From: Matthew Weier O'Phinney [mailto:matthew@zend.com]
>> Sent: Thursday, July 16, 2009 4:56 PM
>> To: fw-mvc@lists.zend.com
>> Subject: Re: [fw-mvc] breakChainOnFailure
>>
>> -- Seth Atkins <satkins@nortel.com> wrote (on Thursday, 16 July 2009,
>> 02:47 PM -0500):
>> > I believe this feature works only within the scope of a single
>> > element
>>
>> > validation. I may be misunderstanding how it works, but I believe it
>
>> > means that if the first validation fails, it stops validating and
>> > outputs only the first validation error message.
>>
>> It means that if the given validator fails, it will not process any
>> validators occurring after it in the chain.
>>
>> > What I am looking for is a way to break out of all form validation
>> > if an element fails. If several fields have validators set, and the
>> > first
>>
>> > field fails its check, then I'd like the $form->isValid($data) to
>> > exit
>>
>> > the validation loop that takes it through the remaining elements. I
>> > don't see a way to do this within the functions provided in ZF
>> > unless I am missing something. Am I missing something?
>>
>> Zend_Form does not allow for this; it attempts to validate all
>> elements, so that you can return all possible validation errors for
>> all elements back to the user.
>>
>> You could likely write a validator that you insert at the top of each
>> element that checks the parent form for any failed element validations
>
>> and skips validation -- but it would mark that element as failed in
>> validation as well.
>>
>> --
>> Matthew Weier O'Phinney
>> Project Lead | matthew@zend.com
>> Zend Framework | http://framework.zend.com/
>>
>
> --
> Matthew Weier O'Phinney
> Project Lead | matthew@zend.com
> Zend Framework | http://framework.zend.com/
>
>
>

--
View this message in context: http://www.nabble.com/breakChainOnFailure-tp24523215p24569949.html
Sent from the Zend MVC mailing list archive at Nabble.com.

没有评论: