Wednesday, August 25, 2010

Custom Form Validators in Zend Framework

This problem got me for a few hours the other day and google was barely helpful.  So I thought I'd share this.

When you write a custom validator, you have to tell the form object where to look.  I was unable to find a way for the autoloader to find it (please correct me if there is!).  I'm not a fan of this syntax because I don't like burying and hard coding path information this deep into the code, especially with a framework as configurable as Zend.



Let's say we have a validator and it's located in APPLICATION_PATH/shiny/Validate/Omg.php

class Shiny_Validate_Omg extends Zend_Validate_Abstract {

    const NOT_OMG = 'notOmg';

    protected $_messageTempaltes = array(
        self::NOT_OMG => 'This is not omg'
    );

    public function isValid($value, $context = null) {
        $value = (string)$value;
        $this->_setValue($value);
        if (!isset($value) || 'omg' != strtolower($value) {
            return false;
        }
        return true;
    }

}

Your form class will look like this:

class Application_Form_AddShiny extends Zend_Form {
    public function init() {
        // Here is the hard coded path I don't like
        $this->addElementPrefixPath('Shiny_', APPLICATION_PATH . '/shiny');
        $this->setMethod('post');

        $this->addElement('text', 'wtfisthis', array(
            'filters' => array('StringTrim'),
            'validators' => array(
                array('Omg', false) // check if this is an OMG!!!!
            )
        ));
    }
}

So, who would have thought to call addElementPrefixPath() to enable a custom validator?  Hopefully this is something that can be cleaned up for ZF2.

No comments: