Zend Form revisited

Posted in development on January 3rd, 2009 by admin

Some time ago I introduced declarative creation of Zend Form instances. But what should you do if you have two or more forms that have common parts? Yes, you can copy-paste form files but adding extension mechanism is much easier and much more elegant :)

You will need only a couple changes to your code:


function exclude_duplicates($var) {

    if( is_array($var) && count($var) > 0 ) {
        $cnt = count($var) - 1;
        if( array_values($var) === $var ) {
            return exclude_duplicates( $var[$cnt] );
        }

        $keys   = array_keys($var);
        $values = array_map( 'exclude_duplicates', array_values($var));
        return array_combine($keys, $values);

    }
    return $var;
}

class KB_Form extends Zend_Form {

        ...
        public function setOptions(array $options) {
        $result = array();

        if( isset($options['extends']) ) {
            $form_name = $options['extends'];
            unset($options['extends']);

            $parent_options = KB_Form_Factory::getInstance()->getFormConfig($form_name);
            if( $parent_options == null ) {
                throw new KB_Exception('Cannot obtain form '.$form_name.' config.', KB_Exception::KB_FORM);
            }
            $result = array_merge_recursive($parent_options->toArray(), $options);
            $result = array_combine(array_keys($result), array_map( 'exclude_duplicates', array_values($result) ) );
        } else {
            $result = $options;
        }

        parent::setOptions($result);

        if (isset($result['bo_class'])) {
            $this->setBusinessObjectClass($result['bo_class']);
            unset($result['bo_class']);
        }
        return $this;
    }
    public function addElement($element, $name = null, $options = null) {
        parent::addElement( $element, $name, $options );

        if( $options !== null && isset($options['bo_method'])) {
            $name = $e->getName();
            if( ! isset($this->_bo_methods[$name]) ) {
                $this->_bo_methods[$name] = $spec['bo_method'];
            }
        }
    }
}

And now if you have form named ‘Search_Index’ you can derive your new form from it by adding one simple line:


; general form meta information
search.kanji.extends = "Search_Index"

You can override properties from parent form by simply adding them to your new file:


: override order
search.kanji.elements.submit.options.order = 6

That’s it for today…

Tags: ,