forked from rebillar/site-accueil-insa
		
	
		
			
				
	
	
		
			488 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			488 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * Base class for simple HTML_QuickForm2 containers
 | |
|  *
 | |
|  * PHP version 5
 | |
|  *
 | |
|  * LICENSE:
 | |
|  *
 | |
|  * Copyright (c) 2006-2010, Alexey Borzov <avb@php.net>,
 | |
|  *                          Bertrand Mansion <golgote@mamasam.com>
 | |
|  * All rights reserved.
 | |
|  *
 | |
|  * Redistribution and use in source and binary forms, with or without
 | |
|  * modification, are permitted provided that the following conditions
 | |
|  * are met:
 | |
|  *
 | |
|  *    * Redistributions of source code must retain the above copyright
 | |
|  *      notice, this list of conditions and the following disclaimer.
 | |
|  *    * Redistributions in binary form must reproduce the above copyright
 | |
|  *      notice, this list of conditions and the following disclaimer in the
 | |
|  *      documentation and/or other materials provided with the distribution.
 | |
|  *    * The names of the authors may not be used to endorse or promote products
 | |
|  *      derived from this software without specific prior written permission.
 | |
|  *
 | |
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 | |
|  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 | |
|  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | |
|  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 | |
|  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | |
|  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | |
|  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | |
|  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 | |
|  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | |
|  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | |
|  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
|  *
 | |
|  * @category   HTML
 | |
|  * @package    HTML_QuickForm2
 | |
|  * @author     Alexey Borzov <avb@php.net>
 | |
|  * @author     Bertrand Mansion <golgote@mamasam.com>
 | |
|  * @license    http://opensource.org/licenses/bsd-license.php New BSD License
 | |
|  * @version    SVN: $Id: Container.php 300722 2010-06-24 10:15:52Z mansion $
 | |
|  * @link       http://pear.php.net/package/HTML_QuickForm2
 | |
|  */
 | |
| 
 | |
| /**
 | |
|  * Base class for all HTML_QuickForm2 elements
 | |
|  */
 | |
| // require_once 'HTML/QuickForm2/Node.php';
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * Implements a recursive iterator for the container elements
 | |
|  *
 | |
|  * @category   HTML
 | |
|  * @package    HTML_QuickForm2
 | |
|  * @author     Alexey Borzov <avb@php.net>
 | |
|  * @author     Bertrand Mansion <golgote@mamasam.com>
 | |
|  * @version    Release: @package_version@
 | |
|  */
 | |
| class HTML_QuickForm2_ContainerIterator extends RecursiveArrayIterator implements RecursiveIterator
 | |
| {
 | |
|     public function __construct(HTML_QuickForm2_Container $container)
 | |
|     {
 | |
|         parent::__construct($container->getElements());
 | |
|     }
 | |
| 
 | |
|     public function hasChildren(): bool
 | |
|     {
 | |
|         return $this->current() instanceof HTML_QuickForm2_Container;
 | |
|     }
 | |
| 
 | |
|     public function getChildren(): HTML_QuickForm2_ContainerIterator
 | |
|     {
 | |
|         return new HTML_QuickForm2_ContainerIterator($this->current());
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Abstract base class for simple QuickForm2 containers
 | |
|  *
 | |
|  * @category   HTML
 | |
|  * @package    HTML_QuickForm2
 | |
|  * @author     Alexey Borzov <avb@php.net>
 | |
|  * @author     Bertrand Mansion <golgote@mamasam.com>
 | |
|  * @version    Release: @package_version@
 | |
|  */
 | |
| abstract class HTML_QuickForm2_Container extends HTML_QuickForm2_Node
 | |
|     implements IteratorAggregate, Countable
 | |
| {
 | |
|    /**
 | |
|     * Array of elements contained in this container
 | |
|     * @var array
 | |
|     */
 | |
|     protected $elements = array();
 | |
| 
 | |
| 
 | |
|     public function setName($name)
 | |
|     {
 | |
|         $this->attributes['name'] = (string)$name;
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     public function toggleFrozen($freeze = null)
 | |
|     {
 | |
|         if (null !== $freeze) {
 | |
|             foreach ($this as $child) {
 | |
|                 $child->toggleFrozen($freeze);
 | |
|             }
 | |
|         }
 | |
|         return parent::toggleFrozen($freeze);
 | |
|     }
 | |
| 
 | |
|     public function persistentFreeze($persistent = null)
 | |
|     {
 | |
|         if (null !== $persistent) {
 | |
|             foreach ($this as $child) {
 | |
|                 $child->persistentFreeze($persistent);
 | |
|             }
 | |
|         }
 | |
|         return parent::persistentFreeze($persistent);
 | |
|     }
 | |
| 
 | |
|    /**
 | |
|     * Whether container prepends its name to names of contained elements
 | |
|     *
 | |
|     * @return   bool
 | |
|     */
 | |
|     protected function prependsName()
 | |
|     {
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|    /**
 | |
|     * Returns the element's value
 | |
|     *
 | |
|     * The default implementation for Containers is to return an array with
 | |
|     * contained elements' values. The array is indexed the same way $_GET and
 | |
|     * $_POST arrays would be for these elements.
 | |
|     *
 | |
|     * @return   array|null
 | |
|     */
 | |
|     public function getValue()
 | |
|     {
 | |
|         $values = array();
 | |
|         foreach ($this as $child) {
 | |
|             $value = $child->getValue();
 | |
|             if (null !== $value) {
 | |
|                 if ($child instanceof HTML_QuickForm2_Container
 | |
|                     && !$child->prependsName()
 | |
|                 ) {
 | |
|                     $values = self::arrayMerge($values, $value);
 | |
|                 } else {
 | |
|                     $name = $child->getName();
 | |
|                     if (!strpos($name, '[')) {
 | |
|                         $values[$name] = $value;
 | |
|                     } else {
 | |
|                         $tokens   =  explode('[', str_replace(']', '', $name));
 | |
|                         $valueAry =& $values;
 | |
|                         do {
 | |
|                             $token = array_shift($tokens);
 | |
|                             if (!isset($valueAry[$token])) {
 | |
|                                 $valueAry[$token] = array();
 | |
|                             }
 | |
|                             $valueAry =& $valueAry[$token];
 | |
|                         } while (count($tokens) > 1);
 | |
|                         $valueAry[$tokens[0]] = $value;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         return empty($values)? null: $this->applyFilters($values);
 | |
|     }
 | |
| 
 | |
|    /**
 | |
|     * Merges two arrays
 | |
|     *
 | |
|     * Merges two arrays like the PHP function array_merge_recursive does,
 | |
|     * the difference being that existing integer keys will not be renumbered.
 | |
|     *
 | |
|     * @param    array
 | |
|     * @param    array
 | |
|     * @return   array   resulting array
 | |
|     */
 | |
|     protected static function arrayMerge($a, $b)
 | |
|     {
 | |
|         foreach ($b as $k => $v) {
 | |
|             if (!is_array($v) || isset($a[$k]) && !is_array($a[$k])) {
 | |
|                 $a[$k] = $v;
 | |
|             } else {
 | |
|                 $a[$k] = self::arrayMerge(isset($a[$k])? $a[$k]: array(), $v);
 | |
|             }
 | |
|         }
 | |
|         return $a;
 | |
|     }
 | |
| 
 | |
|    /**
 | |
|     * Returns an array of this container's elements
 | |
|     *
 | |
|     * @return   array   Container elements
 | |
|     */
 | |
|     public function getElements()
 | |
|     {
 | |
|         return $this->elements;
 | |
|     }
 | |
| 
 | |
|    /**
 | |
|     * Appends an element to the container
 | |
|     *
 | |
|     * If the element was previously added to the container or to another
 | |
|     * container, it is first removed there.
 | |
|     *
 | |
|     * @param    HTML_QuickForm2_Node     Element to add
 | |
|     * @return   HTML_QuickForm2_Node     Added element
 | |
|     * @throws   HTML_QuickForm2_InvalidArgumentException
 | |
|     */
 | |
|     public function appendChild(HTML_QuickForm2_Node $element)
 | |
|     {
 | |
|         if ($this === $element->getContainer()) {
 | |
|             $this->removeChild($element);
 | |
|         }
 | |
|         $element->setContainer($this);
 | |
|         $this->elements[] = $element;
 | |
|         return $element;
 | |
|     }
 | |
| 
 | |
|    /**
 | |
|     * Appends an element to the container (possibly creating it first)
 | |
|     *
 | |
|     * If the first parameter is an instance of HTML_QuickForm2_Node then all
 | |
|     * other parameters are ignored and the method just calls {@link appendChild()}.
 | |
|     * In the other case the element is first created via
 | |
|     * {@link HTML_QuickForm2_Factory::createElement()} and then added via the
 | |
|     * same method. This is a convenience method to reduce typing and ease
 | |
|     * porting from HTML_QuickForm.
 | |
|     *
 | |
|     * @param    string|HTML_QuickForm2_Node  Either type name (treated
 | |
|     *               case-insensitively) or an element instance
 | |
|     * @param    mixed   Element name
 | |
|     * @param    mixed   Element attributes
 | |
|     * @param    array   Element-specific data
 | |
|     * @return   HTML_QuickForm2_Node     Added element
 | |
|     * @throws   HTML_QuickForm2_InvalidArgumentException
 | |
|     * @throws   HTML_QuickForm2_NotFoundException
 | |
|     */
 | |
|     public function addElement($elementOrType, $name = null, $attributes = null,
 | |
|                                array $data = array())
 | |
|     {
 | |
|         if ($elementOrType instanceof HTML_QuickForm2_Node) {
 | |
|             return $this->appendChild($elementOrType);
 | |
|         } else {
 | |
|             return $this->appendChild(HTML_QuickForm2_Factory::createElement(
 | |
|                 $elementOrType, $name, $attributes, $data
 | |
|             ));
 | |
|         }
 | |
|     }
 | |
| 
 | |
|    /**
 | |
|     * Removes the element from this container
 | |
|     *
 | |
|     * If the reference object is not given, the element will be appended.
 | |
|     *
 | |
|     * @param    HTML_QuickForm2_Node     Element to remove
 | |
|     * @return   HTML_QuickForm2_Node     Removed object
 | |
|     */
 | |
|     public function removeChild(HTML_QuickForm2_Node $element)
 | |
|     {
 | |
| 
 | |
|         if ($element->getContainer() !== $this) {
 | |
|             throw new HTML_QuickForm2_NotFoundException(
 | |
|                 "Element with name '".$element->getName()."' was not found"
 | |
|             );
 | |
|         }
 | |
|         foreach ($this as $key => $child){
 | |
|             if ($child === $element) {
 | |
|                 unset($this->elements[$key]);
 | |
|                 $element->setContainer(null);
 | |
|                 break;
 | |
|             }
 | |
|         }
 | |
|         return $element;
 | |
|     }
 | |
| 
 | |
| 
 | |
|    /**
 | |
|     * Returns an element if its id is found
 | |
|     *
 | |
|     * @param    string  Element id to find
 | |
|     * @return   HTML_QuickForm2_Node|null
 | |
|     */
 | |
|     public function getElementById($id)
 | |
|     {
 | |
|         foreach ($this->getRecursiveIterator() as $element) {
 | |
|             if ($id == $element->getId()) {
 | |
|                 return $element;
 | |
|             }
 | |
|         }
 | |
|         return null;
 | |
|     }
 | |
| 
 | |
|    /**
 | |
|     * Returns an array of elements which name corresponds to element
 | |
|     *
 | |
|     * @param    string  Elements name to find
 | |
|     * @return   array
 | |
|     */
 | |
|     public function getElementsByName($name)
 | |
|     {
 | |
|         $found = array();
 | |
|         foreach ($this->getRecursiveIterator() as $element) {
 | |
|             if ($element->getName() == $name) {
 | |
|                 $found[] = $element;
 | |
|             }
 | |
|         }
 | |
|         return $found;
 | |
|     }
 | |
| 
 | |
|    /**
 | |
|     * Inserts an element in the container
 | |
|     *
 | |
|     * If the reference object is not given, the element will be appended.
 | |
|     *
 | |
|     * @param    HTML_QuickForm2_Node     Element to insert
 | |
|     * @param    HTML_QuickForm2_Node     Reference to insert before
 | |
|     * @return   HTML_QuickForm2_Node     Inserted element
 | |
|     */
 | |
|     public function insertBefore(HTML_QuickForm2_Node $element, HTML_QuickForm2_Node $reference = null)
 | |
|     {
 | |
|         if (null === $reference) {
 | |
|             return $this->appendChild($element);
 | |
|         }
 | |
|         $offset = 0;
 | |
|         foreach ($this as $child) {
 | |
|             if ($child === $reference) {
 | |
|                 if ($this === $element->getContainer()) {
 | |
|                     $this->removeChild($element);
 | |
|                 }
 | |
|                 $element->setContainer($this);
 | |
|                 array_splice($this->elements, $offset, 0, array($element));
 | |
|                 return $element;
 | |
|             }
 | |
|             $offset++;
 | |
|         }
 | |
|         throw new HTML_QuickForm2_NotFoundException(
 | |
|             "Reference element with name '".$reference->getName()."' was not found"
 | |
|         );
 | |
|     }
 | |
| 
 | |
|    /**
 | |
|     * Returns a recursive iterator for the container elements
 | |
|     *
 | |
|     * @return    HTML_QuickForm2_ContainerIterator
 | |
|     */
 | |
|     public function getIterator(): HTML_QuickForm2_ContainerIterator
 | |
|     {
 | |
|         return new HTML_QuickForm2_ContainerIterator($this);
 | |
|     }
 | |
| 
 | |
|    /**
 | |
|     * Returns a recursive iterator iterator for the container elements
 | |
|     *
 | |
|     * @param    int     mode passed to RecursiveIteratorIterator
 | |
|     * @return   RecursiveIteratorIterator
 | |
|     */
 | |
|     public function getRecursiveIterator($mode = RecursiveIteratorIterator::SELF_FIRST): RecursiveIteratorIterator
 | |
|     {
 | |
|         return new RecursiveIteratorIterator(
 | |
|                         new HTML_QuickForm2_ContainerIterator($this), $mode
 | |
|                    );
 | |
|     }
 | |
| 
 | |
|    /**
 | |
|     * Returns the number of elements in the container
 | |
|     *
 | |
|     * @return    int
 | |
|     */
 | |
|     public function count(): int
 | |
|     {
 | |
|         return count($this->elements);
 | |
|     }
 | |
| 
 | |
|    /**
 | |
|     * Called when the element needs to update its value from form's data sources
 | |
|     *
 | |
|     * The default behaviour is just to call the updateValue() methods of
 | |
|     * contained elements, since default Container doesn't have any value itself
 | |
|     */
 | |
|     public function updateValue()
 | |
|     {
 | |
|         foreach ($this as $child) {
 | |
|             $child->updateValue();
 | |
|         }
 | |
|     }
 | |
| 
 | |
| 
 | |
|    /**
 | |
|     * Performs the server-side validation
 | |
|     *
 | |
|     * This method also calls validate() on all contained elements.
 | |
|     *
 | |
|     * @return   boolean Whether the container and all contained elements are valid
 | |
|     */
 | |
|     protected function validate()
 | |
|     {
 | |
|         $valid = parent::validate();
 | |
|         foreach ($this as $child) {
 | |
|             $valid = $child->validate() && $valid;
 | |
|         }
 | |
|         return $valid;
 | |
|     }
 | |
| 
 | |
|    /**
 | |
|     * Appends an element to the container, creating it first
 | |
|     *
 | |
|     * The element will be created via {@link HTML_QuickForm2_Factory::createElement()}
 | |
|     * and then added via the {@link appendChild()} method.
 | |
|     * The element type is deduced from the method name.
 | |
|     * This is a convenience method to reduce typing.
 | |
|     *
 | |
|     * @param    mixed   Element name
 | |
|     * @param    mixed   Element attributes
 | |
|     * @param    array   Element-specific data
 | |
|     * @return   HTML_QuickForm2_Node     Added element
 | |
|     * @throws   HTML_QuickForm2_InvalidArgumentException
 | |
|     * @throws   HTML_QuickForm2_NotFoundException
 | |
|     */
 | |
|     public function __call($m, $a)
 | |
|     {
 | |
|         if (preg_match('/^(add)([a-zA-Z0-9_]+)$/', $m, $match)) {
 | |
|             if ($match[1] == 'add') {
 | |
|                 $type = strtolower($match[2]);
 | |
|                 $name = isset($a[0]) ? $a[0] : null;
 | |
|                 $attr = isset($a[1]) ? $a[1] : null;
 | |
|                 $data = isset($a[2]) ? $a[2] : array();
 | |
|                 return $this->addElement($type, $name, $attr, $data);
 | |
|             }
 | |
|         }
 | |
|         trigger_error("Fatal error: Call to undefined method ".get_class($this)."::".$m."()", E_USER_ERROR);
 | |
|     }
 | |
| 
 | |
|    /**
 | |
|     * Renders the container using the given renderer
 | |
|     *
 | |
|     * @param    HTML_QuickForm2_Renderer    Renderer instance
 | |
|     * @return   HTML_QuickForm2_Renderer
 | |
|     */
 | |
|     public function render(HTML_QuickForm2_Renderer $renderer)
 | |
|     {
 | |
|         foreach ($this->rules as $rule) {
 | |
|             if ($rule[1] & HTML_QuickForm2_Rule::RUNAT_CLIENT) {
 | |
|                 $renderer->getJavascriptBuilder()->addRule($rule[0]);
 | |
|             }
 | |
|         }
 | |
|         $renderer->startContainer($this);
 | |
|         foreach ($this as $element) {
 | |
|             $element->render($renderer);
 | |
|         }
 | |
|         $renderer->finishContainer($this);
 | |
|         return $renderer;
 | |
|     }
 | |
| 
 | |
|     public function __toString()
 | |
|     {
 | |
|         // require_once 'HTML/QuickForm2/Renderer.php';
 | |
| 
 | |
|         return $this->render(HTML_QuickForm2_Renderer::factory('default'))->__toString();
 | |
|     }
 | |
| 
 | |
|    /**
 | |
|     * Returns Javascript code for getting the element's value
 | |
|     *
 | |
|     * @return   string
 | |
|     */
 | |
|     public function getJavascriptValue()
 | |
|     {
 | |
|         $args = array();
 | |
|         foreach ($this as $child) {
 | |
|             if ($child instanceof HTML_QuickForm2_Container) {
 | |
|                 $args[] = $child->getJavascriptValue();
 | |
|             } else {
 | |
|                 $args[] = "'" . $child->getId() . "'";
 | |
|             }
 | |
|         }
 | |
|         return 'qf.form.getContainerValue(' . implode(', ', $args) . ')';
 | |
|     }
 | |
| }
 | |
| 
 | |
| ?>
 |