2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
   5  * HTML class for a form element group
 
   9  * LICENSE: This source file is subject to version 3.01 of the PHP license
 
  10  * that is available through the world-wide-web at the following URI:
 
  11  * http://www.php.net/license/3_01.txt If you did not receive a copy of
 
  12  * the PHP License and are unable to obtain it through the web, please
 
  13  * send a note to license@php.net so we can mail you a copy immediately.
 
  16  * @package     HTML_QuickForm
 
  17  * @author      Adam Daniel <adaniel1@eesus.jnj.com>
 
  18  * @author      Bertrand Mansion <bmansion@mamasam.com>
 
  19  * @author      Alexey Borzov <avb@php.net>
 
  20  * @copyright   2001-2011 The PHP Group
 
  21  * @license     http://www.php.net/license/3_01.txt PHP License 3.01
 
  23  * @link        http://pear.php.net/package/HTML_QuickForm
 
  27  * Base class for form elements
 
  29 require_once 'HTML/QuickForm/element.php';
 
  32  * HTML class for a form element group
 
  35  * @package     HTML_QuickForm
 
  36  * @author      Adam Daniel <adaniel1@eesus.jnj.com>
 
  37  * @author      Bertrand Mansion <bmansion@mamasam.com>
 
  38  * @author      Alexey Borzov <avb@php.net>
 
  39  * @version     Release: 3.2.16
 
  42 class HTML_QuickForm_group extends HTML_QuickForm_element
 
  55      * Array of grouped elements
 
  60     var $_elements = array();
 
  63      * String to separate elements
 
  68     var $_separator = null;
 
  71      * Required elements in this group
 
  76     var $_required = array();
 
  79     * Whether to change elements' names to $groupName[$elementName] or leave them as is 
 
  84     var $_appendName = true;
 
  92      * @param     string    $elementName    (optional)Group name
 
  93      * @param     array     $elementLabel   (optional)Group label
 
  94      * @param     array     $elements       (optional)Group elements
 
  95      * @param     mixed     $separator      (optional)Use a string for one separator,
 
  96      *                                      use an array to alternate the separators.
 
  97      * @param     bool      $appendName     (optional)whether to change elements' names to
 
  98      *                                      the form $groupName[$elementName] or leave 
 
 104     function HTML_QuickForm_group($elementName=null, $elementLabel=null, $elements=null, $separator=null, $appendName = true)
 
 106         $this->HTML_QuickForm_element($elementName, $elementLabel);
 
 107         $this->_type = 'group';
 
 108         if (isset($elements) && is_array($elements)) {
 
 109             $this->setElements($elements);
 
 111         if (isset($separator)) {
 
 112             $this->_separator = $separator;
 
 114         if (isset($appendName)) {
 
 115             $this->_appendName = $appendName;
 
 123      * Sets the group name
 
 125      * @param     string    $name   Group name
 
 130     function setName($name)
 
 132         $this->_name = $name;
 
 139      * Returns the group name
 
 154      * Sets values for group's elements
 
 156      * @param     mixed    Values for group's elements
 
 161     function setValue($value)
 
 163         $this->_createElementsIfNotExist();
 
 164         foreach (array_keys($this->_elements) as $key) {
 
 165             if (!$this->_appendName) {
 
 166                 $v = $this->_elements[$key]->_findValue($value);
 
 168                     $this->_elements[$key]->onQuickFormEvent('setGroupValue', $v, $this);
 
 172                 $elementName = $this->_elements[$key]->getName();
 
 173                 $index       = strlen($elementName) ? $elementName : $key;
 
 174                 if (is_array($value)) {
 
 175                     if (isset($value[$index])) {
 
 176                         $this->_elements[$key]->onQuickFormEvent('setGroupValue', $value[$index], $this);
 
 178                 } elseif (isset($value)) {
 
 179                     $this->_elements[$key]->onQuickFormEvent('setGroupValue', $value, $this);
 
 183     } //end func setValue
 
 189      * Returns the value of the group
 
 198         foreach (array_keys($this->_elements) as $key) {
 
 199             $element =& $this->_elements[$key];
 
 200             switch ($element->getType()) {
 
 202                     $v = $element->getChecked()? $element->getValue(): null;
 
 205                     $v = $element->getChecked()? true: null;
 
 208                     $v = $element->getValue();
 
 211                 $elementName = $element->getName();
 
 212                 if (is_null($elementName)) {
 
 215                     if (!is_array($value)) {
 
 216                         $value = is_null($value)? array(): array($value);
 
 218                     if ('' === $elementName) {
 
 221                         $value[$elementName] = $v;
 
 227     } // end func getValue
 
 233      * Sets the grouped elements
 
 235      * @param     array     $elements   Array of elements
 
 240     function setElements($elements)
 
 242         $this->_elements = array_values($elements);
 
 243         if ($this->_flagFrozen) {
 
 246     } // end func setElements
 
 252      * Gets the grouped elements
 
 258     function &getElements()
 
 260         $this->_createElementsIfNotExist();
 
 261         return $this->_elements;
 
 262     } // end func getElements
 
 265     // {{{ getGroupType()
 
 268      * Gets the group type based on its elements
 
 269      * Will return 'mixed' if elements contained in the group
 
 270      * are of different types.
 
 273      * @return    string    group elements type
 
 275     function getGroupType()
 
 277         $this->_createElementsIfNotExist();
 
 279         foreach (array_keys($this->_elements) as $key) {
 
 280             $type = $this->_elements[$key]->getType();
 
 281             if ($type != $prevType && $prevType != '') {
 
 287     } // end func getGroupType
 
 293      * Returns Html for the group
 
 301         include_once('HTML/QuickForm/Renderer/Default.php');
 
 302         $renderer = new HTML_QuickForm_Renderer_Default();
 
 303         $renderer->setElementTemplate('{element}');
 
 304         $this->accept($renderer);
 
 305         return $renderer->toHtml();
 
 309     // {{{ getElementName()
 
 312      * Returns the element name inside the group such as found in the html form
 
 314      * @param     mixed     $index  Element name or element index in the group
 
 317      * @return    mixed     string with element name, false if not found
 
 319     function getElementName($index)
 
 321         $this->_createElementsIfNotExist();
 
 322         $elementName = false;
 
 323         if (is_int($index) && isset($this->_elements[$index])) {
 
 324             $elementName = $this->_elements[$index]->getName();
 
 325             if (isset($elementName) && $elementName == '') {
 
 326                 $elementName = $index;
 
 328             if ($this->_appendName) {
 
 329                 if (is_null($elementName)) {
 
 330                     $elementName = $this->getName();
 
 332                     $elementName = $this->getName().'['.$elementName.']';
 
 336         } elseif (is_string($index)) {
 
 337             foreach (array_keys($this->_elements) as $key) {
 
 338                 $elementName = $this->_elements[$key]->getName();
 
 339                 if ($index == $elementName) {
 
 340                     if ($this->_appendName) {
 
 341                         $elementName = $this->getName().'['.$elementName.']';
 
 344                 } elseif ($this->_appendName && $this->getName().'['.$elementName.']' == $index) {
 
 350     } //end func getElementName
 
 353     // {{{ getFrozenHtml()
 
 356      * Returns the value of field without HTML tags
 
 362     function getFrozenHtml()
 
 365         $this->_createElementsIfNotExist();
 
 366         foreach (array_keys($this->_elements) as $key) {
 
 367             if (false === ($flags[$key] = $this->_elements[$key]->isFrozen())) {
 
 368                 $this->_elements[$key]->freeze();
 
 371         $html = $this->toHtml();
 
 372         foreach (array_keys($this->_elements) as $key) {
 
 374                 $this->_elements[$key]->unfreeze();
 
 378     } //end func getFrozenHtml
 
 381     // {{{ onQuickFormEvent()
 
 384      * Called by HTML_QuickForm whenever form event is made on this element
 
 386      * @param     string    $event  Name of event
 
 387      * @param     mixed     $arg    event arguments
 
 388      * @param     object    &$caller calling object
 
 393     function onQuickFormEvent($event, $arg, &$caller)
 
 397                 $this->_createElementsIfNotExist();
 
 398                 foreach (array_keys($this->_elements) as $key) {
 
 399                     if ($this->_appendName) {
 
 400                         $elementName = $this->_elements[$key]->getName();
 
 401                         if (is_null($elementName)) {
 
 402                             $this->_elements[$key]->setName($this->getName());
 
 403                         } elseif ('' === $elementName) {
 
 404                             $this->_elements[$key]->setName($this->getName() . '[' . $key . ']');
 
 406                             $this->_elements[$key]->setName($this->getName() . '[' . $elementName . ']');
 
 409                     $this->_elements[$key]->onQuickFormEvent('updateValue', $arg, $caller);
 
 410                     if ($this->_appendName) {
 
 411                         $this->_elements[$key]->setName($elementName);
 
 417                 parent::onQuickFormEvent($event, $arg, $caller);
 
 420     } // end func onQuickFormEvent
 
 428     * @param HTML_QuickForm_Renderer    renderer object
 
 429     * @param bool                       Whether a group is required
 
 430     * @param string                     An error message associated with a group
 
 434     function accept(&$renderer, $required = false, $error = null)
 
 436         $this->_createElementsIfNotExist();
 
 437         $renderer->startGroup($this, $required, $error);
 
 438         $name = $this->getName();
 
 439         foreach (array_keys($this->_elements) as $key) {
 
 440             $element =& $this->_elements[$key];
 
 442             if ($this->_appendName) {
 
 443                 $elementName = $element->getName();
 
 444                 if (isset($elementName)) {
 
 445                     $element->setName($name . '['. (strlen($elementName)? $elementName: $key) .']');
 
 447                     $element->setName($name);
 
 451             $required = !$element->isFrozen() && in_array($element->getName(), $this->_required);
 
 453             $element->accept($renderer, $required);
 
 455             // restore the element's name
 
 456             if ($this->_appendName) {
 
 457                 $element->setName($elementName);
 
 460         $renderer->finishGroup($this);
 
 467     * As usual, to get the group's value we access its elements and call
 
 468     * their exportValue() methods
 
 470     function exportValue(&$submitValues, $assoc = false)
 
 473         foreach (array_keys($this->_elements) as $key) {
 
 474             $elementName = $this->_elements[$key]->getName();
 
 475             if ($this->_appendName) {
 
 476                 if (is_null($elementName)) {
 
 477                     $this->_elements[$key]->setName($this->getName());
 
 478                 } elseif ('' === $elementName) {
 
 479                     $this->_elements[$key]->setName($this->getName() . '[' . $key . ']');
 
 481                     $this->_elements[$key]->setName($this->getName() . '[' . $elementName . ']');
 
 484             $v = $this->_elements[$key]->exportValue($submitValues, $assoc);
 
 485             if ($this->_appendName) {
 
 486                 $this->_elements[$key]->setName($elementName);
 
 489                 // Make $value an array, we will use it like one
 
 490                 if (null === $value) {
 
 494                     // just like HTML_QuickForm::exportValues()
 
 495                     $value = HTML_QuickForm::arrayMerge($value, $v);
 
 497                     // just like getValue(), but should work OK every time here
 
 498                     if (is_null($elementName)) {
 
 500                     } elseif ('' === $elementName) {
 
 503                         $value[$elementName] = $v;
 
 508         // do not pass the value through _prepareValue, we took care of this already
 
 513     // {{{ _createElements()
 
 516     * Creates the group's elements.
 
 518     * This should be overriden by child classes that need to create their 
 
 519     * elements. The method will be called automatically when needed, calling
 
 520     * it from the constructor is discouraged as the constructor is usually
 
 521     * called _twice_ on element creation, first time with _no_ parameters.
 
 526     function _createElements()
 
 532     // {{{ _createElementsIfNotExist()
 
 535     * A wrapper around _createElements()
 
 537     * This method calls _createElements() if the group's _elements array
 
 538     * is empty. It also performs some updates, e.g. freezes the created
 
 539     * elements if the group is already frozen.
 
 543     function _createElementsIfNotExist()
 
 545         if (empty($this->_elements)) {
 
 546             $this->_createElements();
 
 547             if ($this->_flagFrozen) {
 
 559         foreach (array_keys($this->_elements) as $key) {
 
 560             $this->_elements[$key]->freeze();
 
 570         foreach (array_keys($this->_elements) as $key) {
 
 571             $this->_elements[$key]->unfreeze();
 
 576     // {{{ setPersistantFreeze()
 
 578     function setPersistantFreeze($persistant = false)
 
 580         parent::setPersistantFreeze($persistant);
 
 581         foreach (array_keys($this->_elements) as $key) {
 
 582             $this->_elements[$key]->setPersistantFreeze($persistant);
 
 587 } //end class HTML_QuickForm_group