<?php

/* vim: set expandtab tabstop=4 shiftwidth=4: */

// +----------------------------------------------------------------------+

// | PHP version 4.0                                                      |

// +----------------------------------------------------------------------+

// | Copyright (c) 1997-2003 The PHP Group                                |

// +----------------------------------------------------------------------+

// | This source file is subject to version 2.0 of the PHP license,       |

// | that is bundled with this package in the file LICENSE, and is        |

// | available at through the world-wide-web at                           |

// | http://www.php.net/license/2_02.txt.                                 |

// | If you did not receive a copy of the PHP license and are unable to   |

// | obtain it through the world-wide-web, please send a note to          |

// | license@php.net so we can mail you a copy immediately.               |

// +----------------------------------------------------------------------+

// | Author: Ron McClain <ron@humaniq.com>                                |

// +----------------------------------------------------------------------+

//

// $Id: Object.php,v 1.1 2005/12/06 01:50:39 matthieu_ Exp $



require_once('HTML/QuickForm/Renderer.php');



/**

 * A concrete renderer for HTML_QuickForm, makes an object from form contents

 *

 * Based on HTML_Quickform_Renderer_Array code

 *

 * @access public

 */

class HTML_QuickForm_Renderer_Object extends HTML_QuickForm_Renderer

{

    /**

     * The object being generated

     * @var object $_obj

     */

    var $_obj= null;



    /**

     * Number of sections in the form (i.e. number of headers in it)

     * @var integer $_sectionCount

     */

    var $_sectionCount;



    /**

    * Current section number

    * @var integer $_currentSection

    */

    var $_currentSection;



    /**

    * Object representing current group

    * @var object $_currentGroup

    */

    var $_currentGroup = null;



    /**

     * Class of Element Objects

     * @var object $_elementType

     */

    var $_elementType = 'QuickFormElement';



    /**

    * Additional style information for different elements  

    * @var array $_elementStyles

    */

    var $_elementStyles = array();



    /**

    * true: collect all hidden elements into string; false: process them as usual form elements

    * @var bool $_collectHidden

    */

    var $_collectHidden = false;





    /**

     * Constructor

     *

     * @param collecthidden bool    true: collect all hidden elements

     * @access public

     */

    function HTML_QuickForm_Renderer_Object($collecthidden = false) 

    {

        $this->HTML_QuickForm_Renderer();

        $this->_collectHidden = $collecthidden;

        $this->_obj = new QuickformForm;

    }



    /**

     * Return the rendered Object

     * @access public

     */

    function toObject() 

    {

        return $this->_obj;

    }



    /**

     * Set the class of the form elements.  Defaults to QuickformElement.

     * @param type string   Name of element class

     * @access public

     */

    function setElementType($type)

    {

        $this->_elementType = $type;

    }



    function startForm(&$form) 

    {

        $this->_obj->frozen = $form->isFrozen();

        $this->_obj->javascript = $form->getValidationScript();

        $this->_obj->attributes = $form->getAttributes(true);

        $this->_obj->requirednote = $form->getRequiredNote();

        $this->_obj->errors = new StdClass;



        if($this->_collectHidden) {

            $this->_obj->hidden = '';

        }

        $this->_elementIdx = 1;

        $this->_currentSection = null;

        $this->_sectionCount = 0;

    } // end func startForm



    function renderHeader(&$header) 

    {

        $hobj = new StdClass;

        $hobj->header = $header->toHtml();

        $this->_obj->sections[$this->_sectionCount] = $hobj;

        $this->_currentSection = $this->_sectionCount++;

    }



    function renderElement(&$element, $required, $error) 

    {

        $elObj = $this->_elementToObject($element, $required, $error);

        if(!empty($error)) {

            $name = $elObj->name;

            $this->_obj->errors->$name = $error;

        }

        $this->_storeObject($elObj);

    } // end func renderElement



    function renderHidden(&$element)

    {

        if($this->_collectHidden) {

            $this->_obj->hidden .= $element->toHtml() . "\n";

        } else {

            $this->renderElement($element, false, null);

        }

    } //end func renderHidden



    function startGroup(&$group, $required, $error) 

    {

        $this->_currentGroup = $this->_elementToObject($group, $required, $error);

        if(!empty($error)) {

            $name = $this->_currentGroup->name;

            $this->_obj->errors->$name = $error;

        }

    } // end func startGroup



    function finishGroup(&$group) 

    {

        $this->_storeObject($this->_currentGroup);

        $this->_currentGroup = null;

    } // end func finishGroup



    /**

     * Creates an object representing an element

     *

     * @access private

     * @param element object    An HTML_QuickForm_element object

     * @param required bool         Whether an element is required

     * @param error string    Error associated with the element

     * @return object

     */

    function _elementToObject(&$element, $required, $error) 

    {

        if($this->_elementType) {

            $ret = new $this->_elementType;

        }

        $ret->name = $element->getName();

        $ret->value = $element->getValue();

        $ret->type = $element->getType();

        $ret->frozen = $element->isFrozen();

        $labels = $element->getLabel();

        if (is_array($labels)) {

            $ret->label = array_shift($labels);

            foreach ($labels as $key => $label) {

                $key = is_int($key)? $key + 2: $key;

                $ret->{'label_' . $key} = $label;

            }

        } else {

            $ret->label = $labels;

        }

        $ret->required = $required;

        $ret->error = $error;



        if(isset($this->_elementStyles[$ret->name])) {

            $ret->style = $this->_elementStyles[$ret->name];

            $ret->styleTemplate = "styles/". $ret->style .".html";

        }

        if($ret->type == 'group') {

            $ret->separator = $element->_separator;

            $ret->elements = array();

        } else {

            $ret->html = $element->toHtml();

        }

        return $ret;

    }



    /** 

     * Stores an object representation of an element in the form array

     *

     * @access private

     * @param elObj object     Object representation of an element

     * @return void

     */

    function _storeObject($elObj) 

    {

        $name = $elObj->name;

        if(is_object($this->_currentGroup) && $elObj->type != 'group') {

            $this->_currentGroup->elements[] = $elObj;

        } elseif (isset($this->_currentSection)) {

            $this->_obj->sections[$this->_currentSection]->elements[] = $elObj;

        } else {

            $this->_obj->elements[] = $elObj;

        }

    }



    function setElementStyle($elementName, $styleName = null)

    {

        if(is_array($elementName)) {

            $this->_elementStyles = array_merge($this->_elementStyles, $elementName);

        } else {

            $this->_elementStyles[$elementName] = $styleName;

        }

    }



} // end class HTML_QuickForm_Renderer_Object







/**

 * Convenience class for the form object passed to outputObject()

 * 

 * Eg.  

 * {form.outputJavaScript():h}

 * {form.outputHeader():h}

 *   <table>

 *     <tr>

 *       <td>{form.name.label:h}</td><td>{form.name.html:h}</td>

 *     </tr>

 *   </table>

 * </form>

 */

class QuickformForm

{

   /**

    * Whether the form has been frozen

    * @var boolean $frozen

    */

    var $frozen;



   /**

    * Javascript for client-side validation

    * @var string $javascript

    */

    var $javascript;



   /**

    * Attributes for form tag

    * @var string $attributes

    */

    var $attributes;



   /**

    * Note about required elements

    * @var string $requirednote

    */

    var $requirednote;



   /**

    * Collected html of all hidden variables

    * @var string $hidden

    */

    var $hidden;



   /**

    * Set if there were validation errors.  

    * StdClass object with element names for keys and their

    * error messages as values

    * @var object $errors

    */

    var $errors;



   /**

    * Array of QuickformElementObject elements.  If there are headers in the form

    * this will be empty and the elements will be in the 

    * separate sections

    * @var array $elements

    */

    var $elements;



   /**

    * Array of sections contained in the document

    * @var array $sections

    */

    var $sections;



   /**

    * Output &lt;form&gt; header

    * {form.outputHeader():h} 

    * @return string    &lt;form attributes&gt;

    */

    function outputHeader()

    {

        return "<form " . $this->attributes . ">\n";

    }



   /**

    * Output form javascript

    * {form.outputJavaScript():h}

    * @return string    Javascript

    */

    function outputJavaScript()

    {

        return $this->javascript;

    }

} // end class QuickformForm





/**

 * Convenience class describing a form element.

 * The properties defined here will be available from 

 * your flexy templates by referencing

 * {form.zip.label:h}, {form.zip.html:h}, etc.

 */

class QuickformElement

{

    /**

     * Element name

     * @var string $name

     */

    var $name;



    /**

     * Element value

     * @var mixed $value

     */

    var $value;



    /**

     * Type of element

     * @var string $type

     */

    var $type;



    /**

     * Whether the element is frozen

     * @var boolean $frozen

     */

    var $frozen;



    /**

     * Label for the element

     * @var string $label

     */

    var $label;



    /**

     * Whether element is required

     * @var boolean $required

     */

    var $required;



    /**

     * Error associated with the element

     * @var string $error

     */

    var $error;



    /**

     * Some information about element style

     * @var string $style

     */

    var $style;



    /**

     * HTML for the element

     * @var string $html

     */

    var $html;



    /**

     * If element is a group, the group separator

     * @var mixed $separator

     */

    var $separator;



    /**

     * If element is a group, an array of subelements

     * @var array $elements

     */

    var $elements;



    function isType($type)

    {

        return ($this->type == $type);

    }



    function notFrozen()

    {

        return !$this->frozen;

    }



    function isButton()

    {

        return ($this->type == "submit" || $this->type == "reset");

    }





   /**

    * XXX: why does it use Flexy when all other stuff here does not depend on it?

    */

    function outputStyle()

    {

        ob_start();

        HTML_Template_Flexy::staticQuickTemplate('styles/' . $this->style . '.html', $this);

        $ret = ob_get_contents();

        ob_end_clean();

        return $ret;

    }

} // end class QuickformElement

?>

