Location: PHPKode > scripts > KForm > klederson-KForms-c6c2d2d/KForms.php
<?php

/**
 * Description of KForms
 *
 * @author Klederson Bueno <hide@address.com>
 */
class KForms {
  ##########################################
  # Elements
  ##########################################

  protected $domElement;
  protected $form;
  protected $search;
  protected $elements;
  protected $fieldContainer;
  protected $fieldset;
  protected $buttons;
  protected $sequence;
  protected $fields;

  ##########################################
  # Externals
  ##########################################
  public $classes = array(
      'formLayout' => 'formLayout'
  );

  ##########################################
  # Internals
  ##########################################
  protected $layout = array(2);
  protected $formOptions = array(
      'enctype' => 'multipart/form-data',
      'method' => 'POST',
      'width' => '100%',
      'height' => 'auto',
      '__breakLayout' => 'br',
      '__fieldContainer' => 'div'
  );
  protected $defaultFieldOptions = array(
      'type' => 'text',
  );
  protected $defaultButtonOptions = array();
  protected $fieldContainerOptions = array(
      'class' => 'fieldContainer'
  );
  protected $breakLayoutOptions = array(
      'class' => 'breakLayout'
  );
  protected $defaultFieldsetOptions = array(
      'class' => 'formFieldset'
  );

  ##########################################
  # Operational
  ##########################################

  public function __construct($formName, $action, $legend = NULL, array $formOptions = array()) {
//  Define identification
    $this->formOptions['action'] = $action;
    $this->formOptions['name'] = $formName;
    $this->formOptions['id'] = empty($formOptions['id']) ? $formName : $formOptions['id'];
    $this->formOptions['__fieldsetLegend'] = $legend;

//  Merging default options with user custom options
    $this->formOptions = array_merge($this->formOptions, $formOptions);

//  domElement
    $this->domElement = DOMImplementation::createDocument(NULL, 'form');
    $this->search = new DOMXPath($this->domElement);
  }

  /**
   * <p>
   * Defines a container for a field or button in order to keep easy to track and style form layout.
   * You can use a element tag to create this container such as div, span, or a custom one and also set all this attributes
   * by using an array with those.
   *
   * You can also override the default classes and attributes by setting it up.
   *
   * IMPORTANT: You can define this anytime in form creation but it will use only the last choosen one if you use $form->render();
   * If you intent to use different container for each field you must define it before call the field AND also use only $form->renderField('fieldName');
   * </p>
   *
   * @example
   * <code>
   * $form = new KForms('myForm','sendForm.php', array(
   *  '__fieldContainer' = 'span'
   * ));   *
   * </code>
   *
   * @example
   * <code>
   * $form = new KForms('myForm','sendForm.php');
   * $form->setFieldContainer('span');
   * </code>
   *
   * @example
   *
   * $form = new KForms('myForm','sendForm.php');
   *
   * //Render using span as container
   * $form->setFieldContainer('span');
   * $form->addText('myTextField');
   * print $form->renderField('myTextField');
   *
   * //Render using div as container
   * $form->setFieldContainer('div');
   * $form->addText('myTextField2');
   * print $form->renderField('myTextField2');
   * </code>
   *
   *
   * @param String $element
   * @param array $options
   */
  public function setFieldContainer($element, array $options = array()) {
//  Merging default options with user custom options
    $this->fieldContainerOptions = array_merge($this->fieldContainerOptions, $options);
    $this->fieldContainer = $this->createElement($this->formOptions['__fieldContainer'], $this->fieldContainerOptions);
  }

  public function setBreakLayout($element, array $options = array()) {
//  Merging default options with user custom options
    $this->breakLayoutOptions = array_merge($this->breakLayoutOptions, $options);
    $this->breakElement = $this->createElement($this->formOptions['__breakLayout'], $this->breakLayoutOptions);
  }

  public function getFieldContainer() {
    if (empty($this->fieldContainer))
      $this->setFieldContainer($this->formOptions['__fieldContainer']);

    return $this->fieldContainer;
  }

  public function getBreakLayout() {
    if (empty($this->breakElement))
      $this->setBreakLayout($this->formOptions['__breakLayout']);

    return $this->breakElement;
  }

  ##########################################
  # INPUT
  ##########################################

  /**
   * <p>
   * Add a INPUT type TEXT to your form.
   *
   * You can also setup your label text if you want to if not it will be created without a label.
   *
   * You can fully customize it by adding $fieldOptions array such as id, class, value, etc.
   *
   * It returns you the information structure of your field in a stdClass obj.
   *
   * IMPORTANT: $fieldName is your field's name.
   * </p>
   *
   * @example
   * <code>
   * $form = new KForms('myForm','sendForm.php');
   *
   * $form->addText('myDefaultField');
   * $form->addText('labeledField','This is my label: ');
   * $form->addText('customFieldAttributes','My second label: ', array(
   *  'id' => 'myCustomID',
   *  'value' => 'defaultValue',
   *  'class' => 'customClass'
   * ));
   *
   * $form->render();
   * </code>
   *
   * @param String $fieldName
   * @param String $labelContent
   * @param Array $fieldOptions
   * @return stdClass
   */
  public function addText($fieldName, $labelContent = NULL, array $fieldOptions = array()) {
    $fieldOptions['type'] = 'text';
    return $this->addField($fieldName, $labelContent, $fieldOptions);
  }

  /**
   * <p>
   * Add a INPUT type PASSWORD to your form.
   *
   * You can also setup your label text if you want to if not it will be created without a label.
   *
   * You can fully customize it by adding $fieldOptions array such as id, class, value, etc.
   *
   * It returns you the information structure of your field in a stdClass obj.
   *
   * IMPORTANT: $fieldName is your field's name.
   * </p>
   *
   * @example
   * <code>
   * $form = new KForms('myForm','sendForm.php');
   *
   * $form->addPassword('myDefaultField');
   * $form->addPassword('labeledField','This is my label: ');
   * $form->addPassword('customFieldAttributes','My second label: ', array(
   *  'id' => 'myCustomID',
   *  'value' => 'defaultValue',
   *  'class' => 'customClass'
   * ));
   *
   * $form->render();
   * </code>
   *
   * @param String $fieldName
   * @param String $labelContent
   * @param Array $fieldOptions
   * @return stdClass
   */
  public function addPassword($fieldName, $labelContent = NULL, array $fieldOptions = array()) {
    $fieldOptions['type'] = 'password';
    return $this->addField($fieldName, $labelContent, $fieldOptions);
  }

  /**
   * <p>
   * Add a INPUT type FILE to your form.
   *
   * You can also setup your label text if you want to if not it will be created without a label.
   *
   * You can fully customize it by adding $fieldOptions array such as id, class, value, etc.
   *
   * It returns you the information structure of your field in a stdClass obj.
   *
   * IMPORTANT: $fieldName is your field's name.
   * </p>
   *
   * @example
   * <code>
   * $form = new KForms('myForm','sendForm.php');
   *
   * $form->addFile('myDefaultField');
   * $form->addFile('labeledField','This is my label: ');
   * $form->addFile('customFieldAttributes','My second label: ', array(
   *  'id' => 'myCustomID',
   *  'class' => 'customClass'
   * ));
   *
   * $form->render();
   * </code>
   *
   * @param String $fieldName
   * @param String $labelContent
   * @param Array $fieldOptions
   * @return stdClass
   */
  public function addFile($fieldName, $labelContent = NULL, array $fieldOptions = array()) {
    $fieldOptions['type'] = 'file';
    return $this->addField($fieldName, $labelContent, $fieldOptions);
  }

  /**
   * <p>
   * Add a INPUT type SUBMIT to your form.
   *
   * You can also setup your label text if you want to if not it will be created without a label.
   *
   * You can fully customize it by adding $fieldOptions array such as id, class, value, etc.
   *
   * It returns you the information structure of your field in a stdClass obj.
   *
   * IMPORTANT: $fieldName is your field's name.
   * </p>
   *
   * @example
   * <code>
   * $form = new KForms('myForm','sendForm.php');
   *
   * $form->addSubmit('myDefaultField');
   * $form->addSubmit('labeledField','This is my label: ');
   * $form->addSubmit('customFieldAttributes','My second label: ', array(
   *  'id' => 'myCustomID',
   *  'value' => 'defaultValue',
   *  'class' => 'customClass'
   * ));
   *
   * $form->render();
   * </code>
   *
   * @param String $fieldName
   * @param String $labelContent
   * @param Array $fieldOptions
   * @return stdClass
   */
  public function addSubmit($fieldName, $labelContent = NULL, array $fieldOptions = array()) {
    $fieldOptions['type'] = 'submit';
    $fieldOptions['value'] = $fieldName;
    return $this->addField($fieldName, $labelContent, $fieldOptions);
  }

  /**
   * <p>
   * Add a INPUT type HIDDEN to your form.
   *
   * You can also setup your label text if you want to if not it will be created without a label.
   *
   * You can fully customize it by adding $fieldOptions array such as id, class, value, etc.
   *
   * It returns you the information structure of your field in a stdClass obj.
   *
   * IMPORTANT: $fieldName is your field's name.
   * </p>
   *
   * @example
   * <code>
   * $form = new KForms('myForm','sendForm.php');
   *
   * $form->addHidden('myDefaultField');
   * $form->addHidden('labeledField','This is my label: ');
   * $form->addHidden('customFieldAttributes','My second label: ', array(
   *  'id' => 'myCustomID',
   *  'value' => 'defaultValue',
   *  'class' => 'customClass'
   * ));
   *
   * $form->render();
   * </code>
   *
   * @param String $fieldName
   * @param String $labelContent
   * @param Array $fieldOptions
   * @return stdClass
   */
  public function addHidden($fieldName, $labelContent = NULL, array $fieldOptions = array()) {
    $fieldOptions['type'] = 'hidden';
    return $this->addField($fieldName, $labelContent, $fieldOptions);
  }

  /**
   * <p>
   * Add a INPUT type CHECKBOX to your form.
   *
   * You can also setup your label text if you want to if not it will be created without a label.
   *
   * You can fully customize it by adding $fieldOptions array such as id, class, value, etc.
   *
   * It returns you the information structure of your field in a stdClass obj.
   *
   * IMPORTANT: $fieldName is your field's name.
   * </p>
   *
   * @example
   * <code>
   * $form = new KForms('myForm','sendForm.php');
   *
   * $form->addPassword('myDefaultField');
   * $form->addPassword('labeledField','This is my label: ');
   * $form->addPassword('customFieldAttributes','My second label: ', array(
   *  'id' => 'myCustomID',
   *  'value' => 'defaultValue',
   *  'class' => 'customClass',
   *  'checked' => '' //it checks the field
   * ));
   *
   * $form->render();
   * </code>
   *
   * @param String $fieldName
   * @param String $labelContent
   * @param Array $fieldOptions
   * @return stdClass
   */
  public function addCheckbox($fieldName, $labelContent = NULL, array $fieldOptions = array()) {
    $fieldOptions['type'] = 'checkbox';
    return $this->addField($fieldName, $labelContent, $fieldOptions);
  }

  ##########################################
  # RADIO
  ##########################################

  /**
   * <p>
   * Add a INPUT type CHECKBOX to your form.
   *
   * You can also setup your label text if you want to if not it will be created without a label.
   *
   * You can fully customize it by adding $fieldOptions array such as id, class, value, etc.
   *
   * It returns you the information structure of your field in a stdClass obj.
   *
   * IMPORTANT: $fieldName is your field's name.
   *
   * It's a polimorphic funciton because it accept label text or options array as second parm if
   * label text is set automaticaly the third parm is the array of options.
   * </p>
   *
   * @example
   * <code>
   * $form = new KForms('myForm','sendForm.php');
   *
   * $radioOptions[]['My Label']['MY_VALUE'] = true; //it means it comes checked by default
   * $radioOptions[]['No']['my_no_value'] = false;
   * $radioOptions[]['Maybe']['my_maybe_value'] = false;
   *
   * $form->addRadioGroup('myRadioGroup', 'Choose one option: ', $radioOptions);
   *
   * $form->render();
   * </code>
   *
   * @example
   * <code>
   * $form = new KForms('myForm','sendForm.php');
   *
   * $radioOptions[]['My Label']['MY_VALUE'] = true; //it means it comes checked by default
   * $radioOptions[]['No']['my_no_value'] = false;
   * $radioOptions[]['Maybe']['my_maybe_value'] = false;
   *
   * $form->addRadioGroup('myRadioGroup', $radioOptions);
   *
   * $form->render();
   * </code>
   *
   * @example
   * <code>
   * $form = new KForms('myForm','sendForm.php');
   *
   * $radioOptions[]['My Label']['MY_VALUE'] = true; //it means it comes checked by default
   * $radioOptions[]['No']['my_no_value'] = false;
   * $radioOptions[]['Maybe']['my_maybe_value'] = false;
   *
   * $form->addRadioGroup('myRadioGroup', 'Choose one option: ', $radioOptions, array(
   *  'id' => 'myCustomID',
   *  'class' => 'customClass',
   * ));
   *
   * $form->render();
   * </code>
   *
   * @example
   * <code>
   * $form = new KForms('myForm','sendForm.php');
   *
   * $radioOptions[]['My Label']['MY_VALUE'] = true; //it means it comes checked by default
   * $radioOptions[]['No']['my_no_value'] = false;
   * $radioOptions[]['Maybe']['my_maybe_value'] = false;
   *
   * $form->addRadioGroup('myRadioGroup', $radioOptions, array(
   *  'id' => 'myCustomID',
   *  'class' => 'customClass',
   * ));
   *
   * $form->render();
   * </code>
   *
   *
   * @param String $fieldName
   * @param String $labelContent
   * @param Array $options
   * @param Array $fieldOptions
   * @return stdClass
   */
  public function addRadioGroup($fieldName, $labelContent, array $options = array(), $fieldOptions = array()) {
    $parms = func_get_args();
    if (is_array($parms[1])) {
      $options = $parms[1];
      $labelContent = NULL;

      if (isset($parms[2]))
        $fieldOptions = $parms[2];
    }

    $fieldOptions['type'] = 'radio';
    $fieldOptions['__options'] = $options;
    return $this->addField($fieldName, $labelContent, $fieldOptions);
  }

  ##########################################
  # TEXTAREA
  ##########################################

  /**
   * <p>
   * Add a TEXTAREA to your form.
   *
   * You can also setup your label text if you want to if not it will be created without a label.
   *
   * You can fully customize it by adding $fieldOptions array such as id, class, value, etc.
   *
   * It returns you the information structure of your field in a stdClass obj.
   *
   * IMPORTANT: $fieldName is your field's name.
   * </p>
   *
   * @example
   * <code>
   * $form = new KForms('myForm','sendForm.php');
   *
   * $form->addTextArea('myDefaultField');
   * $form->addTextArea('labeledField','This is my label: ');
   * $form->addTextArea('customFieldAttributes','My second label: ', array(
   *  'id' => 'myCustomID',
   *  'value' => 'defaultValue', //NOTE YOU MUST SET VALUE LIKE AN ATTRIBUTE BUT DONT WORRY IT WILL NOT CREATE AN VALUE ATTRIBUTE
   *  'class' => 'customClass'
   * ));
   *
   * $form->render();
   * </code>
   *
   * @param String $fieldName
   * @param String $labelContent
   * @param Array $fieldOptions
   * @return stdClass
   */
  public function addTextArea($fieldName, $labelContent = NULL, array $fieldOptions = array()) {
    $fieldOptions['type'] = 'textarea';
    $fieldOptions['__value'] = !empty($fieldOptions['value']) ? $fieldOptions['value'] : "";
    unset($fieldOptions['value']);
    return $this->addField($fieldName, $labelContent, $fieldOptions);
  }

  ##########################################
  # BUTTON
  ##########################################

  public function addButton($name, $labelContent = NULL, $options = array()) {
//  Define identification
    $options['name'] = $name;
    $options['id'] = empty($options['id']) ? $name : $options['id'];
    $options['__value'] = $options['value'];
    unset($options['value']);

//  Merging default options with user custom options
    $options = array_merge($this->defaultButtonOptions, $options);

//  Stage for render call
    $this->buttons[$name] = new stdClass();
    $this->buttons[$name]->options = $options;
    $this->buttons[$name]->label = empty($labelContent) ? "" : $labelContent;

    $this->sequence[]['button'] = &$this->buttons[$name];

    return $this->fields[$name];
  }

  ##########################################
  # SELECT
  ##########################################

  /**
   * <p>
   * Add a INPUT type CHECKBOX to your form.
   *
   * You can also setup your label text if you want to if not it will be created without a label.
   *
   * You can fully customize it by adding $fieldOptions array such as id, class, value, etc.
   *
   * It returns you the information structure of your field in a stdClass obj.
   *
   * IMPORTANT: $fieldName is your field's name.
   *
   * It's a polimorphic funciton because it accept label text or options array as second parm if
   * label text is set automaticaly the third parm is the array of options.
   * </p>
   *
   * @example
   * <code>
   * //A simplified way
   * $form = new KForms('myForm','sendForm.php');
   *
   * $form->addSelect('mySelect', 'Choose something: ", array(), array(
   *  'id' => 'myCustomID',
   *  'class' => 'customClass',
   * ));
   *
   * $form->addOption('mySelect', 'Choose an option', NULL);
   * $form->addOption('mySelect', 'Red', 'red', 'Colors');
   * $form->addOption('mySelect', 'Black', 'black', 'Colors');
   * $form->addOption('mySelect', 'Blue', 'blue', 'Colors');
   * $form->addOption('mySelect', 'New York', 'nyc', 'Places');
   * $form->addOption('mySelect', 'Tokio', 'tokio', 'Places');
   * $form->addOption('mySelect', 'São Paulo', 'saoPaulo', 'Places');
   * $form->addOption('mySelect', 'My common label', 'myCommonValue');
   * $form->addOption('mySelect', 'Other common label', 'otherCommonValue');
   *
   * $form->render();
   * </code>
   *
   * @example
   * <code>
   * $form = new KForms('myForm','sendForm.php');
   *
   * $selectOptions[]['Choose an Option'] = NULL;
   * $selectOptions['Colors'][]['Red'] = 'aa';
   * $selectOptions['Colors'][]['Black'] = 'bb';
   * $selectOptions['Colors'][]['Blue'] = 'cc';
   * $selectOptions['Places'][]['New York'] = 'nyc';
   * $selectOptions['Places'][]['Tokio'] = 'tokio';
   * $selectOptions['Places'][]['São Paulo'] = 'saoPaulo';
   * $selectOptions[]['My common label'] = 'myCommonValue';
   * $selectOptions[]['Other common label'] = 'myOtherCommonValue';
   *
   * $form->addSelect('mySelect', 'Choose one option: ', $selectOptions);
   *
   * $form->render();
   * </code>
   *
   * @example
   * <code>
   * $form = new KForms('myForm','sendForm.php');
   *
   * $selectOptions[]['Choose an Option'] = NULL;
   * $selectOptions['Colors'][]['Red'] = 'aa';
   * $selectOptions['Colors'][]['Black'] = 'bb';
   * $selectOptions['Colors'][]['Blue'] = 'cc';
   * $selectOptions['Places'][]['New York'] = 'nyc';
   * $selectOptions['Places'][]['Tokio'] = 'tokio';
   * $selectOptions['Places'][]['São Paulo'] = 'saoPaulo';
   * $selectOptions[]['My common label'] = 'myCommonValue';
   * $selectOptions[]['Other common label'] = 'myOtherCommonValue';
   *
   * $form->addSelect('mySelect', $selectOptions);
   *
   * $form->render();
   * </code>
   *
   * @example
   * <code>
   * $form = new KForms('myForm','sendForm.php');
   *
   * $selectOptions[]['Choose an Option'] = NULL;
   * $selectOptions['Colors'][]['Red'] = 'aa';
   * $selectOptions['Colors'][]['Black'] = 'bb';
   * $selectOptions['Colors'][]['Blue'] = 'cc';
   * $selectOptions['Places'][]['New York'] = 'nyc';
   * $selectOptions['Places'][]['Tokio'] = 'tokio';
   * $selectOptions['Places'][]['São Paulo'] = 'saoPaulo';
   * $selectOptions[]['My common label'] = 'myCommonValue';
   * $selectOptions[]['Other common label'] = 'myOtherCommonValue';
   *
   * $form->addSelect('mySelect', 'Choose one option: ', $selectOptions, array(
   *  'id' => 'myCustomID',
   *  'class' => 'customClass',
   * ));
   *
   * $form->render();
   * </code>
   *
   * @example
   * <code>
   * $form = new KForms('myForm','sendForm.php');
   *
   * $selectOptions[]['Choose an Option'] = NULL;
   * $selectOptions['Colors'][]['Red'] = 'red';
   * $selectOptions['Colors'][]['Black'] = 'black';
   * $selectOptions['Colors'][]['Blue'] = 'blue';
   * $selectOptions['Places'][]['New York'] = 'nyc';
   * $selectOptions['Places'][]['Tokio'] = 'tokio';
   * $selectOptions['Places'][]['São Paulo'] = 'saoPaulo';
   * $selectOptions[]['My common label'] = 'myCommonValue';
   * $selectOptions[]['Other common label'] = 'myOtherCommonValue';
   *
   * $form->addSelect('mySelect', $selectOptions, array(
   *  'id' => 'myCustomID',
   *  'class' => 'customClass',
   * ));
   *
   * $form->render();
   * </code>
   *
   *
   * @param String $fieldName
   * @param String $labelContent
   * @param Array $options
   * @param Array $fieldOptions
   * @return stdClass
   */
  public function addSelect($fieldName, $labelContent, array $options = array(), $fieldOptions = array()) {
    $parms = func_get_args();
    if (is_array($parms[1])) {
      $options = $parms[1];
      $labelContent = NULL;
    }

    $fieldOptions['type'] = 'select';
    $fieldOptions['__options'] = $options;
    return $this->addField($fieldName, $labelContent, $fieldOptions);
  }

  /**
   * Add an option to a SELECT for more information see addSelect()
   *
   * @example
   * <code>
   * //A simplified way
   * $form = new KForms('myForm','sendForm.php');
   *
   * $form->addSelect('mySelect', 'Choose something: ", array(), array(
   *  'id' => 'myCustomID',
   *  'class' => 'customClass',
   * ));
   *
   * $form->addOption('mySelect', 'Choose an option', NULL);
   * $form->addOption('mySelect', 'Red', 'red', 'Colors');
   * $form->addOption('mySelect', 'Black', 'black', 'Colors');
   * $form->addOption('mySelect', 'Blue', 'blue', 'Colors');
   * $form->addOption('mySelect', 'New York', 'nyc', 'Places');
   * $form->addOption('mySelect', 'Tokio', 'tokio', 'Places');
   * $form->addOption('mySelect', 'São Paulo', 'saoPaulo', 'Places');
   * $form->addOption('mySelect', 'My common label', 'myCommonValue');
   * $form->addOption('mySelect', 'Other common label', 'otherCommonValue');
   *
   * $form->render();
   * </code>
   * 
   * @param String $selectName
   * @param String $label
   * @param String $value
   * @param String $group
   */
  public function addOption($selectName, $label, $value, $group = NULL) {
    if ($group != NULL) {
      $this->getField($selectName)->options['__options'][$group][$label] = (string) $value;
    } else {
      $this->getField($selectName)->options['__options'][][$label] = (string) $value;
    }
  }

  ##########################################
  # Fieldset
  ##########################################

  /**
   * <p>
   * Add a FIELDSET to your form.
   *
   * You can also setup your legend text if you want to if not it will be created without a legend.
   *
   * You can fully customize it by adding $options array such as id, class, value, etc.
   *
   * It returns you the information structure of your fieldset in a stdClass obj.
   *
   * IMPORTANT: $name is your field's name.
   *
   * To insert fields into this fieldset you just must do two things:
   *
   * 1) create the fieldset by using this method
   * 2) in your field you must setup an $fieldOption['__fieldset'] = 'fieldsetName';
   * </p>
   *
   * @example
   * <code>
   * $form = new KForms('myForm','sendForm.php');
   *
   * $form->addFieldset('myFieldset','FIELDSET LABEL');
   * $form->addText('myText','My Text Label: ', array(
   *  '__fieldset' => 'myFieldset'
   * ));
   * </code>
   *
   * @example
   * <code>
   * $form = new KForms('myForm','sendForm.php');
   *
   * $form->addFieldset('myFieldset','FIELDSET LABEL', array(
   *  'id' => 'myCustomID',
   *  'class' => 'myCustomClass'
   * ));
   * 
   * $form->addText('myText','My Text Label: ', array(
   *  '__fieldset' => 'myFieldset'
   * ));
   * </code>
   * 
   * @param String $name
   * @param String $legend
   * @param array $options
   * @return stdClass
   */
  public function addFieldset($name, $legend = NULL, array $options = array()) {
//  Define identification
    $options['name'] = $name;
    $options['id'] = empty($options['id']) ? $name : $options['id'];

//  Merging default options with user custom options
    $options = array_merge($this->defaultFieldsetOptions, $options);

//  Stage for render call
    $this->fieldset[$name] = new stdClass();
    $this->fieldset[$name]->name = $name;
    $this->fieldset[$name]->options = $options;
    $this->fieldset[$name]->legend = $legend;

    $this->sequence[]['fieldset'] = &$this->fieldset[$name];

    return $this->fieldset[$name];
  }

  /**
   * <p>
   * Render a fieldset
   *
   * For supported modes see $this::output()
   * </p>
   *
   * @param String $name
   * @param String $mode
   * @return Mixed (based on $mode)
   */
  public function renderFieldset($name, $mode = 'print') {
    $element = $this->createElement('fieldset', $this->getFieldset($name)->options);
    $element->appendChild($this->createElement('legend', array(), $this->getFieldset($name)->legend));

    return $element;
  }

  ##########################################
  # Functions
  ##########################################

  /**
   * Add a field to current form is for INTERNAL USAGE ONLY
   *
   * @param String $fieldName
   * @param Array $fieldOptions
   * @return Array
   */
  protected function addField($fieldName, $labelContent = NULL, $fieldOptions = array()) {
//  Define identification
    $fieldOptions['name'] = $fieldName;
    $fieldOptions['id'] = empty($fieldOptions['id']) ? $fieldName : $fieldOptions['id'];

//  Merging default options with user custom options
    $fieldOptions = array_merge($this->defaultFieldOptions, $fieldOptions);

//  Stage for render call
    $this->fields[$fieldName] = new stdClass();
    $this->fields[$fieldName]->options = $fieldOptions;
    $this->fields[$fieldName]->label = empty($labelContent) ? "" : $labelContent;

    $this->sequence[]['field'] = &$this->fields[$fieldName];

    return $this->fields[$fieldName];
  }

  /**
   * Retreive a specific field structure information ( stdClass )
   * @param String $name
   * @return stdClass
   */
  protected function getField($name) {
    return $this->fields[$name];
  }

  /**
   * Retreive a specific button structure information ( stdClass )
   * @param String $name
   * @return stdClass
   */
  protected function getButton($name) {
    return $this->buttons[$name];
  }

  /**
   * Retreive a specific fieldset structure information ( stdClass )
   * @param String $name
   * @return stdClass
   */
  public function getFieldset($name) {
    return $this->fieldset[$name];
  }

  public function addClass(DOMElement &$element, $class) {
//  Add $type class for this element
    $elementClass = $element->getAttribute('class');
    $elementClass = !empty($elementClass) ? sprintf("%s %s", $elementClass, $class) : sprintf("%s", $class);
    $element->setAttribute('class', $elementClass);

    return $element;
  }

  protected function getContainer(DOMElement $element, $elementType, $mode) {
    $container = $this->createContainer();

//  Link container id with fieldName
    $containerID = sprintf("container_%s", $element->getAttribute('id'));

    $this->addClass($container, $elementType);

    $container->setAttribute('id', $containerID);

    return $this->output($container, $mode);
  }

  ##########################################
  # Output
  ##########################################

  /**
   *
   * @param String $type
   * @param array $attributes
   * @param String $value
   * @return DOMElement
   */
  public function createElement($type, array $attributes, $value = NULL) {
    $element = !isset($value) ? $this->domElement->createElement($type) : $this->domElement->createElement($type, $value);
    $this->setAttributes($element, $attributes);

    return $element;
  }

  public function setLayoutMap(array $map, $separator = NULL, array $separatorAttributes = array()) {
    if (is_string($separator))
      $this->breakElement = $this->createElement($separator, $separatorAttributes);

    $this->layout = $map;
  }

  /**
   * Set attributes to an element and avoid __ prefix for internal usage
   * 
   * @param DOMElement $element
   * @param array $attributes
   */
  protected function setAttributes(DOMElement &$element, array $attributes) {
    foreach ($attributes as $attr => $value) {
      if (!preg_match('(^__)', $attr) && !is_array($value))
        $element->setAttribute((string) $attr, (string) $value);
    }
  }

  public function renderButton($name, $mode = 'print') {
    $element = $this->createButton($name, $mode);

    $container = $this->getContainer($element, 'button', 'object');

    if (!empty($this->getButton($name)->label)) {
      $label = $this->renderLabel($this->getButton($name));
      $container->appendChild($label);
    }

    $container->appendChild($element);

    return $container;
  }

  public function renderLabel(stdClass $element) {
    $label = $this->createElement('label', array(
                'for' => $element->options['name'],
                'class' => 'formBurn'
                    ),
                    $element->label
    );
    return $label;
  }

  public function renderForm($renderElements = true) {

    $mainFieldsetOptions['id'] = sprintf('mainFieldset%s', $this->formOptions['id']);
    array_merge($mainFieldsetOptions, $this->formOptions);
    
    $this->form = $this->createElement('fieldset', $mainFieldsetOptions);
    $form = $this->createElement('form', $this->formOptions);
    $this->form->appendChild($form);

    $this->domElement->appendChild($this->form);
  }

  public function renderField($fieldName, $mode = 'print') {
//  Define fieldCreation Method based on field type
    $type = $this->getField($fieldName)->options['type'];
    $methodName = sprintf("createField%s", str_replace(" ", '', ucwords(str_replace('_', " ", $type))));

//  This implementation makes possible field customization and new elements
    if (method_exists($this, $methodName)) {
      $element = call_user_func_array(array($this, $methodName), array($fieldName, $mode));
    } else {
//    Default implementation
      $element = $this->createElement('input', $this->getField($fieldName)->options);
    }

    $this->addClass($element, $type);

    $container = $this->getContainer($element, sprintf("field %s", $type), 'object');

    if (!empty($this->getField($fieldName)->label)) {
      $label = $this->renderLabel($this->getField($fieldName));
      $container->appendChild($label);
    }

    $container->appendChild($element);

    return $this->output($container, $mode);
  }

  public function render($mode = 'print') {
//  Creating document

    $this->form = $this->createElement('form', $this->formOptions);

    $this->domElement->appendChild($this->form);

    $layoutLine = 0;
    $layoutCounter = 0;
    $lineNumber = 1;

    foreach ($this->sequence as $arrSequence) {
      $name = $arrSequence[key($arrSequence)]->options['name'];

      switch (key($arrSequence)) {
        case 'field':

          $element = $this->renderField($name, 'object');

          if (!empty($this->getField($name)->options['__fieldset'])) {
            $query = sprintf('//fieldset[@id="%s"]', $this->getField($name)->options['__fieldset']);
            $entry = $this->search->evaluate($query, $this->form);

            if ($entry instanceof DOMNodeList) {
              $entry->item(0)->appendChild(clone $element);
            }
            unset($element);
          }

          break;
        case 'button':
          $element = $this->renderButton($name, 'object');
          
          if (!empty($this->getButton($name)->options['__fieldset'])) {
            $query = sprintf('//fieldset[@id="%s"]', $this->getButton($name)->options['__fieldset']);
            $entry = $this->search->evaluate($query, $this->form);

            if ($entry instanceof DOMNodeList) {
              $entry->item(0)->appendChild(clone $element);
            }
            unset($element);
          }
          break;
        case 'fieldset':
          
          $element = $this->renderFieldset($name, 'object');

          if (!empty($this->getFieldset($name)->options['__fieldset'])) {
            $query = sprintf('//fieldset[@id="%s"]', $this->getFieldset($name)->options['__fieldset']);
            $entry = $this->search->evaluate($query, $this->form);

            if ($entry instanceof DOMNodeList) {
              $entry->item(0)->appendChild(clone $element);
            }
            unset($element);
          }

          
          break;
      }

//    Renderization
      $formLayoutClass = sprintf("%s_%s", $this->classes['formLayout'], $this->layout[$layoutLine]);
      if (isset($element)) {
        $this->addClass($element, $formLayoutClass);
        $this->form->appendChild(clone $element);
        unset($isChild);
        $layoutCounter++;
      }
      unset($formLayoutClass);

//    Checking if layoutLine has reach it's amount
      if ($this->layout[$layoutLine] == $layoutCounter) {
        $layoutCounter = 0;
        $lineNumber++;

//      Append a breaker
        $this->form->appendChild(clone $this->getBreakLayout());

//      Change layout line
        $layoutLine = $layoutLine == count($this->layout) - 1 ? 0 : $layoutLine + 1;
      }
    }

//  Main Fieldset
    $mainFieldsetOptions['id'] = sprintf('mainFieldset%s', $this->formOptions['id']);
    $wrapperFieldset = $this->createElement('fieldset', $mainFieldsetOptions);
    $mainFieldsetLegendOptions['id'] = sprintf('mainFieldsetLegend%s', $this->formOptions['id']);
    $legend = $this->createElement('legend', $mainFieldsetLegendOptions, $this->formOptions['__fieldsetLegend']);
    $wrapperFieldset->appendChild($legend);
    $wrapperFieldset->appendChild($this->form);
    
    return $this->output($wrapperFieldset, $mode);
  }

  protected function output(DOMElement &$element, $mode = 'print') {
    switch ($mode) {
      case 'string':
        return $this->domElement->saveXML($element);
        break;
      case 'object':
        return $element;
        break;
      case 'print':
      default:
        print $this->domElement->saveXML($element);
        break;
    }
  }

  ///////////////////

  public function createButton($name, $mode = 'print') {
    return $this->createElement('button', $this->getButton($name)->options, $this->getButton($name)->options['__value']);
  }

  public function createContainer() {
    return clone $this->getFieldContainer();
  }

  public function createFieldTextarea($fieldName, $mode) {
    return $this->createElement('textarea', $this->getField($fieldName)->options, $this->getField($fieldName)->options['__value']);
  }

  /**
   * Encapsulated method to build a Select Element
   * @param String $fieldName
   * @param String $mode
   * @return DOMNode
   */
  protected function createFieldSelect($fieldName, $mode) {
    $field = $this->createElement('select', $this->getField($fieldName)->options);
    foreach ($this->getField($fieldName)->options['__options'] as $group => $options) {
      if (is_string($group)) {
        $optGroup = $this->createElement('optgroup', array('label' => $group));
      }

      foreach ($options as $label => $value) {

        $optionLabel = is_array($value) ? key($value) : $label;
        $optionValue = is_array($value) ? $value[key($value)] : $value;

        $option = $this->createElement('option', array('value' => $optionValue), $optionLabel);

        if (is_string($group)) {
          $optGroup->appendChild($option);
        } else {
          $field->appendChild($option);
        }
      }

      if (is_string($group)) {
//          Putting group into the select
        $field->appendChild($optGroup);
      }

      unset($optGroup, $option);
    }

    return $field;
  }

  protected function createFieldRadio($fieldName, $mode = 'print') {
    $field = $this->createElement('span', array('for' => $this->getField($fieldName)->options['name']));

    foreach ($this->getField($fieldName)->options['__options'] as $index => $arrField) {
      $_options = $this->getField($fieldName)->options;
      $_options['value'] = key($arrField[key($arrField)]);
      if ($arrField[key($arrField)][$_options['value']] == true)
        $_options['checked'] = '';

      $_field = $this->createElement('input', $_options, key($arrField));
      $field->appendChild($_field);
    }

    return $field;
  }

}

?>
Return current item: KForm