Veikko Mäkinen

Wednesday, 2009-01-07

» Agavi Tip: Validation Gotchas

Agavi Validation Gotchas

Agavi’s input validation system is extremely versatile and even people with long history with Agavi - me for example - sometimes struggle to get their head around it. So I decided to put down a few gotchas. Here goes…

Validators Can Be Grouped

You can use AgaviAndValidator, AgaviOrValidator and AgaviXorValidator to group several validators.


<validator class="or">
  <validators>
    <validator class="email" required="false" >
      <arguments>
        <argument>email</argument>
      </arguments>
    </validator>
    <validator class="MyPhoneNumberValidator" required="false" >
      <arguments>
        <argument>phone</argument>
      </arguments>
    </validator>
  </validators>
  <errors>
    <error>Please provide email or phone</error>
  </errors>
</validator>

Validator Can Depend on Another Validator

Quite often you only want validate input B only if the user provided input A. Agavi makes this simple:


<validator ... required="false" provides="street_set">
  <arguments base="contact">
    <argument>Street</argument>
  </arguments>
</validator>

<validator ... required="true" depends="contact[street_set]">
  <arguments base="contact">
    <argument>Zip</argument>
  </arguments>
</validator>

Note: argument’s base attribute affects also provides/depends attributes (see example above) !!

Pimp My Error Messages

A validator can throw different error message based on what went wrong and error messages can be translated on the fly. Error message options vary between validators. See API docs for more.


<validator class="string" translation_domain="default.errors">
  <arguments>
    <argument>my_input</argument>
  </arguments>
  <errors>
    <error for="required">Please fill this input</error>
    <error for="max">Please keep it shorter than 40 characters</error>
  </errors>
  <ae:parameters>
    <ae:parameter name="max">40</ae:parameter>
  </ae:parameters>
</validator>

Validating Array Inputs

<input name=”rows[Id]”


<arguments base="rows">
    <argument>Id</argument>
</arguments>

<!-- or -->

<arguments>
    <argument>rows[Id]</argument>
</arguments>

<input name=”rows[1][Id]”


<arguments base="rows[]">
    <argument>Id</argument>
</arguments>

<input name=”rows[]”


<arguments base="rows[]">
    <argument/>
</argument>

Validator Can Normalize And Export Combined Values

This example shows how to get AgaviDateValidator to validate a compound value. But that’s not all! It’ll even export a proper timestamp for you to use in your application code.


<validator class="AgaviDateTimeValidator">
    <arguments>
        <argument name="AgaviDateDefinitions::DATE">day</argument>
        <argument name="AgaviDateDefinitions::MONTH">month</argument>
        <argument name="AgaviDateDefinitions::YEAR">year</argument>
    </arguments>
    <errors>
        <error>Validation error</error>
    </errors>
    <ae:parameters>
        <ae:parameter name="export">MyDatestamp</ae:parameter>
    </ae:parameters>
</validator>

Remember to Validate ALL Input

Validation is not limited to GET/POST input parameters but HTTP headers and cookies can (and should) be validated too. Use the source attribute to tell the validator where to get the data from.


<validator ... source="headers"> <argument>REFERER</argument>

Validator is ran only if the parameter is non-empty.

By default the validator base class AgaviValidator checks that all the arguments are set before executing the actual validation. If the input value is empty or non-existent but required error is thrown. But if required attribute is set to False the validation just quietly continues to another validator. Normally this is not a problem but you might want to code a custom validator that exports a default value for empty parameters. In this case you need to override AgaviValidator’s checkAllArgumentsSet().

Did I forget something?

Join #agavi IRC channel and hassle me there or send email to veikko@veikko.fi.

Tags

Comments (View)
blog comments powered by Disqus