views:

96

answers:

2

How I can combine multiple form elements to one validator? I have address information which consists of

  • Street address
  • ZIP code
  • Post office

If I add validator to each of them as streetValidator, zipCodeValidator, postOfficeValidator I end up with problem: There can be foostreet in somewhere (validation ok), 10101 somewhere (validation ok also) and barOffice in somewhere (validation ok too). But all address information combined, there's no address of "foostreet, 10101, barOffice".

Now you have:

<?php
$f = new Zend_Form();

$street = new Zend_Form_Element_Text('street');
$f->addElement($street);

$zip = new Zend_Form_Element_Text('zip');
$f->addElement($zip);

$office = new Zend_Form_Element_Text('office');
$f->addElement($office);

But it should be:

$f = new Zend_Form();
// All three fields are still seperated
$address = new My_Address_Fields();
$address->addValidator(new addressValidator());
$f->addElement($address);

Validator is something like

class addressValidator extends Zend_Validator_Abstract
{
  public function isValid()
  {
    //$street = ???;
    //$zip = ???;
    //$office = ???;

    // XMLRPC client which does the actual check
    $v = new checkAddress($street, $zip, $office);
    return (bool)$v->isValid();
  }
}
A: 

I guess it is the part about how to create MyAddressField that's causing problems. You'd have to layer your decorators to create a composite Form Element. Check out this series of articles on form decorators. Especially the one linked as articles, should That should get you into the right direction.

Gordon
+1  A: 

When validating a form element, the validator is given all form values, within the $context parameter. So, your validator can look something like this:

  public function isValid( $value, $context = null )
  {
    $street = ( isset($context['street']) )? $context['street'] : null;
    $zip =    ( isset($context['zip']) )?    $context['zip']    : null;
    $office = ( isset($context['office']) )? $context['office'] : null;

    // XMLRPC client which does the actual check
    $v = new checkAddress($street, $zip, $office);
    return (bool)$v->isValid();
  }

Then, add the validator to your street element, say.

Cons: this validator is a little disembodied, attached to a specific element but not really.

Pros: it'll work.

Derek Illchuk
Since there's no `Zend_Validate_Abstract::__construct()` to take notice of, one could use that method for mapping, i.e. `Your_Validate::__construct($mapping = array())` which would be something like `$mapping['streetElementId'] = 'street'`, which in turn the method `Your_Validate::isValid()` would know which rules to validate each element to.
chelmertz