Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/libs/HTML
diff options
context:
space:
mode:
authorrobocoder <anthon.pang@gmail.com>2010-07-06 21:28:27 +0400
committerrobocoder <anthon.pang@gmail.com>2010-07-06 21:28:27 +0400
commit8876741c030c5bbd27ac7c6394fa081783f231e2 (patch)
tree46629aa66fb5f130b5eed07902f3930d8404d25c /libs/HTML
parentf2a0232aca7ed6e34f2cba80cb2862d7d3e644d7 (diff)
refs #1442 - add HTML_Common2 and HTML_QuickForm2 - New BSD licensed
git-svn-id: http://dev.piwik.org/svn/trunk@2435 59fd770c-687e-43c8-a1e3-f5a4ff64c105
Diffstat (limited to 'libs/HTML')
-rw-r--r--libs/HTML/Common2.php488
-rw-r--r--libs/HTML/QuickForm2.php224
-rw-r--r--libs/HTML/QuickForm2/Container.php487
-rw-r--r--libs/HTML/QuickForm2/Container/Fieldset.php92
-rw-r--r--libs/HTML/QuickForm2/Container/Group.php328
-rw-r--r--libs/HTML/QuickForm2/Controller.php506
-rw-r--r--libs/HTML/QuickForm2/Controller/Action.php68
-rw-r--r--libs/HTML/QuickForm2/Controller/Action/Back.php74
-rw-r--r--libs/HTML/QuickForm2/Controller/Action/Direct.php71
-rw-r--r--libs/HTML/QuickForm2/Controller/Action/Display.php117
-rw-r--r--libs/HTML/QuickForm2/Controller/Action/Jump.php209
-rw-r--r--libs/HTML/QuickForm2/Controller/Action/Next.php88
-rw-r--r--libs/HTML/QuickForm2/Controller/Action/Submit.php79
-rw-r--r--libs/HTML/QuickForm2/Controller/DefaultAction.php106
-rw-r--r--libs/HTML/QuickForm2/Controller/Page.php258
-rw-r--r--libs/HTML/QuickForm2/Controller/SessionContainer.php195
-rw-r--r--libs/HTML/QuickForm2/DataSource.php67
-rw-r--r--libs/HTML/QuickForm2/DataSource/Array.php101
-rw-r--r--libs/HTML/QuickForm2/DataSource/Session.php78
-rw-r--r--libs/HTML/QuickForm2/DataSource/Submit.php76
-rw-r--r--libs/HTML/QuickForm2/DataSource/SuperGlobal.php170
-rw-r--r--libs/HTML/QuickForm2/Element.php133
-rw-r--r--libs/HTML/QuickForm2/Element/Button.php161
-rw-r--r--libs/HTML/QuickForm2/Element/Date.php503
-rw-r--r--libs/HTML/QuickForm2/Element/Input.php114
-rw-r--r--libs/HTML/QuickForm2/Element/InputButton.php99
-rw-r--r--libs/HTML/QuickForm2/Element/InputCheckable.php172
-rw-r--r--libs/HTML/QuickForm2/Element/InputCheckbox.php99
-rw-r--r--libs/HTML/QuickForm2/Element/InputFile.php268
-rw-r--r--libs/HTML/QuickForm2/Element/InputHidden.php82
-rw-r--r--libs/HTML/QuickForm2/Element/InputImage.php162
-rw-r--r--libs/HTML/QuickForm2/Element/InputPassword.php71
-rw-r--r--libs/HTML/QuickForm2/Element/InputRadio.php69
-rw-r--r--libs/HTML/QuickForm2/Element/InputReset.php99
-rw-r--r--libs/HTML/QuickForm2/Element/InputSubmit.php120
-rw-r--r--libs/HTML/QuickForm2/Element/InputText.php64
-rw-r--r--libs/HTML/QuickForm2/Element/Select.php575
-rw-r--r--libs/HTML/QuickForm2/Element/Static.php153
-rw-r--r--libs/HTML/QuickForm2/Element/Textarea.php110
-rw-r--r--libs/HTML/QuickForm2/Exception.php109
-rw-r--r--libs/HTML/QuickForm2/Factory.php229
-rw-r--r--libs/HTML/QuickForm2/JavascriptBuilder.php120
-rw-r--r--libs/HTML/QuickForm2/Loader.php140
-rw-r--r--libs/HTML/QuickForm2/Node.php692
-rw-r--r--libs/HTML/QuickForm2/Renderer.php360
-rw-r--r--libs/HTML/QuickForm2/Renderer/Array.php376
-rw-r--r--libs/HTML/QuickForm2/Renderer/Default.php598
-rw-r--r--libs/HTML/QuickForm2/Renderer/Plugin.php69
-rw-r--r--libs/HTML/QuickForm2/Renderer/Proxy.php262
-rw-r--r--libs/HTML/QuickForm2/Rule.php333
-rw-r--r--libs/HTML/QuickForm2/Rule/Callback.php172
-rw-r--r--libs/HTML/QuickForm2/Rule/Compare.php231
-rw-r--r--libs/HTML/QuickForm2/Rule/Each.php137
-rw-r--r--libs/HTML/QuickForm2/Rule/Empty.php89
-rw-r--r--libs/HTML/QuickForm2/Rule/Length.php236
-rw-r--r--libs/HTML/QuickForm2/Rule/MaxFileSize.php124
-rw-r--r--libs/HTML/QuickForm2/Rule/MimeType.php122
-rw-r--r--libs/HTML/QuickForm2/Rule/Nonempty.php141
-rw-r--r--libs/HTML/QuickForm2/Rule/NotCallback.php80
-rw-r--r--libs/HTML/QuickForm2/Rule/NotRegex.php106
-rw-r--r--libs/HTML/QuickForm2/Rule/Regex.php133
-rw-r--r--libs/HTML/QuickForm2/Rule/Required.php88
62 files changed, 11883 insertions, 0 deletions
diff --git a/libs/HTML/Common2.php b/libs/HTML/Common2.php
new file mode 100644
index 0000000000..0228889b12
--- /dev/null
+++ b/libs/HTML/Common2.php
@@ -0,0 +1,488 @@
+<?php
+/**
+ * HTML_Common2: port of HTML_Common package to PHP5
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2004-2009, Alexey Borzov <avb@php.net>
+ *
+ * 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_Common2
+ * @author Alexey Borzov <avb@php.net>
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Common2.php 295050 2010-02-14 05:01:19Z clockwerx $
+ * @link http://pear.php.net/package/HTML_Common2
+ */
+
+/**
+ * Base class for HTML classes
+ *
+ * Implements methods for working with HTML attributes, parsing and generating
+ * attribute strings. Port of HTML_Common class for PHP4 originally written by
+ * Adam Daniel with contributions from numerous other developers.
+ *
+ * @category HTML
+ * @package HTML_Common2
+ * @author Alexey Borzov <avb@php.net>
+ * @version Release: @package_version@
+ */
+abstract class HTML_Common2
+{
+ /**
+ * Associative array of attributes
+ * @var array
+ */
+ protected $attributes = array();
+
+ /**
+ * List of attribites changes to which will be announced via onAttributeChange()
+ * method rather than performed by HTML_Common2 class itself
+ * @var array
+ * @see onAttributeChange()
+ */
+ protected $watchedAttributes = array();
+
+ /**
+ * Indentation level of the element
+ * @var int
+ */
+ private $_indentLevel = 0;
+
+ /**
+ * Comment associated with the element
+ * @var string
+ */
+ private $_comment = null;
+
+ /**
+ * Global options for all elements generated by subclasses of HTML_Common2
+ *
+ * Preset options are
+ * - 'charset': charset parameter used in htmlspecialchars() calls,
+ * defaults to 'ISO-8859-1'
+ * - 'indent': string used to indent HTML elements, defaults to "\11"
+ * - 'linebreak': string used to indicate linebreak, defaults to "\12"
+ *
+ * @var array
+ */
+ private static $_options = array(
+ 'charset' => 'ISO-8859-1',
+ 'indent' => "\11",
+ 'linebreak' => "\12"
+ );
+
+ /**
+ * Sets global option(s)
+ *
+ * @param string|array Option name or array ('option name' => 'option value')
+ * @param mixed Option value, if first argument is not an array
+ */
+ public static function setOption($nameOrOptions, $value = null)
+ {
+ if (is_array($nameOrOptions)) {
+ foreach ($nameOrOptions as $k => $v) {
+ self::setOption($k, $v);
+ }
+ } else {
+ $linebreaks = array('win' => "\15\12", 'unix' => "\12", 'mac' => "\15");
+ if ('linebreak' == $nameOrOptions && isset($linebreaks[$value])) {
+ $value = $linebreaks[$value];
+ }
+ self::$_options[$nameOrOptions] = $value;
+ }
+ }
+
+ /**
+ * Returns global option(s)
+ *
+ * @param string Option name
+ * @return mixed Option value, null if option does not exist,
+ * array of all options if $name is not given
+ */
+ public static function getOption($name = null)
+ {
+ if (null === $name) {
+ return self::$_options;
+ } else {
+ return isset(self::$_options[$name])? self::$_options[$name]: null;
+ }
+ }
+
+ /**
+ * Parses the HTML attributes given as string
+ *
+ * @param string HTML attribute string
+ * @return array An associative aray of attributes
+ */
+ protected static function parseAttributes($attrString)
+ {
+ $attributes = array();
+ if (preg_match_all(
+ "/(([A-Za-z_:]|[^\\x00-\\x7F])([A-Za-z0-9_:.-]|[^\\x00-\\x7F])*)" .
+ "([ \\n\\t\\r]+)?(=([ \\n\\t\\r]+)?(\"[^\"]*\"|'[^']*'|[^ \\n\\t\\r]*))?/",
+ $attrString,
+ $regs
+ )) {
+ for ($i = 0; $i < count($regs[1]); $i++) {
+ $name = trim($regs[1][$i]);
+ $check = trim($regs[0][$i]);
+ $value = trim($regs[7][$i]);
+ if ($name == $check) {
+ $attributes[strtolower($name)] = strtolower($name);
+ } else {
+ if (!empty($value) && ($value[0] == '\'' || $value[0] == '"')) {
+ $value = substr($value, 1, -1);
+ }
+ $attributes[strtolower($name)] = $value;
+ }
+ }
+ }
+ return $attributes;
+ }
+
+ /**
+ * Creates a valid attribute array from either a string or an array
+ *
+ * @param mixed Array of attributes or HTML attribute string
+ * @return array An associative aray of attributes
+ */
+ protected static function prepareAttributes($attributes)
+ {
+ $prepared = array();
+ if (is_string($attributes)) {
+ return self::parseAttributes($attributes);
+
+ } elseif (is_array($attributes)) {
+ foreach ($attributes as $key => $value) {
+ if (is_int($key)) {
+ $key = strtolower($value);
+ $prepared[$key] = $key;
+ } else {
+ $prepared[strtolower($key)] = (string)$value;
+ }
+ }
+ }
+ return $prepared;
+ }
+
+ /**
+ * Removes an attribute from an attribute array
+ *
+ * @param array Attribute array
+ * @param string Name of attribute to remove
+ */
+ protected static function removeAttributeArray(&$attributes, $name)
+ {
+ unset($attributes[strtolower($name)]);
+ }
+
+ /**
+ * Creates HTML attribute string from array
+ *
+ * @param array Attribute array
+ * @return string Attribute string
+ */
+ protected static function getAttributesString($attributes)
+ {
+ $str = '';
+ if (is_array($attributes)) {
+ $charset = self::getOption('charset');
+ foreach ($attributes as $key => $value) {
+ $str .= ' ' . $key . '="' . htmlspecialchars($value, ENT_QUOTES, $charset) . '"';
+ }
+ }
+ return $str;
+ }
+
+ /**
+ * Class constructor, sets default attributes
+ *
+ * @param mixed Array of attribute 'name' => 'value' pairs or HTML attribute string
+ */
+ public function __construct($attributes = null)
+ {
+ $this->mergeAttributes($attributes);
+ }
+
+ /**
+ * Sets the value of the attribute
+ *
+ * @param string Attribute name
+ * @param string Attribute value (will be set to $name if omitted)
+ * @return HTML_Common2
+ */
+ public function setAttribute($name, $value = null)
+ {
+ $name = strtolower($name);
+ if (is_null($value)) {
+ $value = $name;
+ }
+ if (in_array($name, $this->watchedAttributes)) {
+ $this->onAttributeChange($name, $value);
+ } else {
+ $this->attributes[$name] = (string)$value;
+ }
+ return $this;
+ }
+
+ /**
+ * Returns the value of an attribute
+ *
+ * @param string Attribute name
+ * @return string Attribute value, null if attribute does not exist
+ */
+ public function getAttribute($name)
+ {
+ $name = strtolower($name);
+ return isset($this->attributes[$name])? $this->attributes[$name]: null;
+ }
+
+ /**
+ * Sets the attributes
+ *
+ * @param mixed Array of attribute 'name' => 'value' pairs or HTML attribute string
+ * @return HTML_Common2
+ */
+ public function setAttributes($attributes)
+ {
+ $attributes = self::prepareAttributes($attributes);
+ $watched = array();
+ foreach ($this->watchedAttributes as $watchedKey) {
+ if (isset($attributes[$watchedKey])) {
+ $this->setAttribute($watchedKey, $attributes[$watchedKey]);
+ unset($attributes[$watchedKey]);
+ } else {
+ $this->removeAttribute($watchedKey);
+ }
+ if (isset($this->attributes[$watchedKey])) {
+ $watched[$watchedKey] = $this->attributes[$watchedKey];
+ }
+ }
+ $this->attributes = array_merge($watched, $attributes);
+ return $this;
+ }
+
+ /**
+ * Returns the attribute array or string
+ *
+ * @param bool Whether to return attributes as string
+ * @return mixed Either an array or string of attributes
+ */
+ public function getAttributes($asString = false)
+ {
+ if ($asString) {
+ return self::getAttributesString($this->attributes);
+ } else {
+ return $this->attributes;
+ }
+ }
+
+ /**
+ * Merges the existing attributes with the new ones
+ *
+ * @param mixed Array of attribute 'name' => 'value' pairs or HTML attribute string
+ * @return HTML_Common2
+ */
+ public function mergeAttributes($attributes)
+ {
+ $attributes = self::prepareAttributes($attributes);
+ foreach ($this->watchedAttributes as $watchedKey) {
+ if (isset($attributes[$watchedKey])) {
+ $this->onAttributeChange($watchedKey, $attributes[$watchedKey]);
+ unset($attributes[$watchedKey]);
+ }
+ }
+ $this->attributes = array_merge($this->attributes, $attributes);
+ return $this;
+ }
+
+ /**
+ * Removes an attribute
+ *
+ * @param string Name of attribute to remove
+ * @return HTML_Common2
+ */
+ public function removeAttribute($attribute)
+ {
+ if (in_array(strtolower($attribute), $this->watchedAttributes)) {
+ $this->onAttributeChange(strtolower($attribute), null);
+ } else {
+ self::removeAttributeArray($this->attributes, $attribute);
+ }
+ return $this;
+ }
+
+ /**
+ * Sets the indentation level
+ *
+ * @param int
+ * @return HTML_Common2
+ */
+ public function setIndentLevel($level)
+ {
+ $level = intval($level);
+ if (0 <= $level) {
+ $this->_indentLevel = $level;
+ }
+ return $this;
+ }
+
+ /**
+ * Gets the indentation level
+ *
+ * @return int
+ */
+ public function getIndentLevel()
+ {
+ return $this->_indentLevel;
+ }
+
+ /**
+ * Returns the string to indent the element
+ *
+ * @return string
+ */
+ protected function getIndent()
+ {
+ return str_repeat(self::getOption('indent'), $this->getIndentLevel());
+ }
+
+ /**
+ * Sets the comment for the element
+ *
+ * @param string
+ * @return HTML_Common2
+ */
+ public function setComment($comment)
+ {
+ $this->_comment = $comment;
+ return $this;
+ }
+
+ /**
+ * Returns the comment associated with the element
+ *
+ * @return string
+ */
+ public function getComment()
+ {
+ return $this->_comment;
+ }
+
+ /**
+ * Checks whether the element has given CSS class
+ *
+ * @param string Class name
+ * @return bool
+ */
+ public function hasClass($class)
+ {
+ $regex = '/(^|\s)' . preg_quote($class, '/') . '(\s|$)/';
+ return (bool)preg_match($regex, $this->getAttribute('class'));
+ }
+
+ /**
+ * Adds the given CSS class(es) to the element
+ *
+ * @param string|array Class name, multiple class names separated by
+ * whitespace, array of class names
+ * @return HTML_Common2
+ */
+ public function addClass($class)
+ {
+ if (!is_array($class)) {
+ $class = preg_split('/\s+/', $class, null, PREG_SPLIT_NO_EMPTY);
+ }
+ $curClass = preg_split('/\s+/', $this->getAttribute('class'),
+ null, PREG_SPLIT_NO_EMPTY);
+ foreach ($class as $c) {
+ if (!in_array($c, $curClass)) {
+ $curClass[] = $c;
+ }
+ }
+ $this->setAttribute('class', implode(' ', $curClass));
+
+ return $this;
+ }
+
+ /**
+ * Removes the given CSS class(es) from the element
+ *
+ * @param string|array Class name, multiple class names separated by
+ * whitespace, array of class names
+ * @return HTML_Common2
+ */
+ public function removeClass($class)
+ {
+ if (!is_array($class)) {
+ $class = preg_split('/\s+/', $class, null, PREG_SPLIT_NO_EMPTY);
+ }
+ $curClass = array_diff(
+ preg_split('/\s+/', $this->getAttribute('class'),
+ null, PREG_SPLIT_NO_EMPTY),
+ $class
+ );
+ if (0 == count($curClass)) {
+ $this->removeAttribute('class');
+ } else {
+ $this->setAttribute('class', implode(' ', $curClass));
+ }
+ return $this;
+ }
+
+ /**
+ * Returns the HTML representation of the element
+ *
+ * This magic method allows using the instances of HTML_Common2 in string
+ * contexts
+ *
+ * @return string
+ */
+ abstract public function __toString();
+
+ /**
+ * Called if trying to change an attribute with name in $watchedAttributes
+ *
+ * This method is called for each attribute whose name is in the
+ * $watchedAttributes array and which is being changed by setAttribute(),
+ * setAttributes() or mergeAttributes() or removed via removeAttribute().
+ * Note that the operation for the attribute is not carried on after calling
+ * this method, it is the responsibility of this method to change or remove
+ * (or not) the attribute.
+ *
+ * @param string Attribute name
+ * @param string Attribute value, null if attribute is being removed
+ */
+ protected function onAttributeChange($name, $value = null)
+ {
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2.php b/libs/HTML/QuickForm2.php
new file mode 100644
index 0000000000..787b6001bd
--- /dev/null
+++ b/libs/HTML/QuickForm2.php
@@ -0,0 +1,224 @@
+<?php
+/**
+ * Class representing a HTML form
+ *
+ * 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: QuickForm2.php 299706 2010-05-24 18:32:37Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Abstract base class for QuickForm2 containers
+ */
+require_once 'HTML/QuickForm2/Container.php';
+
+/**
+ * Data source for HTML_QuickForm2 objects based on superglobal arrays
+ */
+require_once 'HTML/QuickForm2/DataSource/SuperGlobal.php';
+
+/**
+ * Class representing a HTML form
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2 extends HTML_QuickForm2_Container
+{
+ /**
+ * Data sources providing values for form elements
+ * @var array
+ */
+ protected $datasources = array();
+
+ /**
+ * We do not allow setting "method" and "id" other than through constructor
+ * @var array
+ */
+ protected $watchedAttributes = array('id', 'method');
+
+ /**
+ * Class constructor, form's "id" and "method" attributes can only be set here
+ *
+ * @param string "id" attribute of <form> tag
+ * @param string HTTP method used to submit the form
+ * @param mixed Additional attributes (either a string or an array)
+ * @param bool Whether to track if the form was submitted by adding
+ * a special hidden field
+ */
+ public function __construct($id, $method = 'post', $attributes = null, $trackSubmit = true)
+ {
+ $method = ('GET' == strtoupper($method))? 'get': 'post';
+ if (empty($id)) {
+ $id = self::generateId('');
+ $trackSubmit = false;
+ } else {
+ self::storeId($id);
+ }
+ $this->attributes = array_merge(
+ self::prepareAttributes($attributes),
+ array('id' => (string)$id, 'method' => $method)
+ );
+ if (!isset($this->attributes['action'])) {
+ $this->attributes['action'] = $_SERVER['PHP_SELF'];
+ }
+ if ($trackSubmit && isset($_REQUEST['_qf__' . $id]) ||
+ !$trackSubmit && ('get' == $method && !empty($_GET) ||
+ 'post' == $method && (!empty($_POST) || !empty($_FILES))))
+ {
+ $this->addDataSource(new HTML_QuickForm2_DataSource_SuperGlobal(
+ $method, get_magic_quotes_gpc()
+ ));
+ }
+ if ($trackSubmit) {
+ $this->appendChild(HTML_QuickForm2_Factory::createElement(
+ 'hidden', '_qf__' . $id
+ ));
+ }
+ }
+
+ protected function onAttributeChange($name, $value = null)
+ {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'Attribute \'' . $name . '\' is read-only'
+ );
+ }
+
+ protected function setContainer(HTML_QuickForm2_Container $container = null)
+ {
+ throw new HTML_QuickForm2_Exception('Form cannot be added to container');
+ }
+
+ public function setId($id = null)
+ {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ "Attribute 'id' is read-only"
+ );
+ }
+
+
+ /**
+ * Adds a new data source to the form
+ *
+ * @param HTML_QuickForm2_DataSource Data source
+ */
+ public function addDataSource(HTML_QuickForm2_DataSource $datasource)
+ {
+ $this->datasources[] = $datasource;
+ $this->updateValue();
+ }
+
+ /**
+ * Replaces the list of form's data sources with a completely new one
+ *
+ * @param array A new data source list
+ * @throws HTML_QuickForm2_InvalidArgumentException if given array
+ * contains something that is not a valid data source
+ */
+ public function setDataSources(array $datasources)
+ {
+ foreach ($datasources as $ds) {
+ if (!$ds instanceof HTML_QuickForm2_DataSource) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'Array should contain only DataSource instances'
+ );
+ }
+ }
+ $this->datasources = $datasources;
+ $this->updateValue();
+ }
+
+ /**
+ * Returns the list of data sources attached to the form
+ *
+ * @return array
+ */
+ public function getDataSources()
+ {
+ return $this->datasources;
+ }
+
+ public function getType()
+ {
+ return 'form';
+ }
+
+ public function setValue($value)
+ {
+ throw new HTML_QuickForm2_Exception('Not implemented');
+ }
+
+ /**
+ * Performs the server-side validation
+ *
+ * @return boolean Whether all form's elements are valid
+ */
+ public function validate()
+ {
+ $isSubmitted = false;
+ foreach ($this->datasources as $ds) {
+ if ($ds instanceof HTML_QuickForm2_DataSource_Submit) {
+ $isSubmitted = true;
+ break;
+ }
+ }
+ return $isSubmitted? parent::validate(): false;
+ }
+
+ /**
+ * Renders the form using the given renderer
+ *
+ * @param HTML_QuickForm2_Renderer Renderer instance
+ * @return HTML_QuickForm2_Renderer
+ */
+ public function render(HTML_QuickForm2_Renderer $renderer)
+ {
+ $renderer->startForm($this);
+ $renderer->getJavascriptBuilder()->startForm($this);
+ foreach ($this as $element) {
+ $element->render($renderer);
+ }
+ $renderer->finishForm($this);
+ return $renderer;
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Container.php b/libs/HTML/QuickForm2/Container.php
new file mode 100644
index 0000000000..b62a435f06
--- /dev/null
+++ b/libs/HTML/QuickForm2/Container.php
@@ -0,0 +1,487 @@
+<?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';
+
+/**
+ * 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()
+ {
+ 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)
+ {
+ return new RecursiveIteratorIterator(
+ new HTML_QuickForm2_ContainerIterator($this), $mode
+ );
+ }
+
+ /**
+ * Returns the number of elements in the container
+ *
+ * @return int
+ */
+ public function count()
+ {
+ 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
+ */
+ protected 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) . ')';
+ }
+}
+
+/**
+ * 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()
+ {
+ return $this->current() instanceof HTML_QuickForm2_Container;
+ }
+
+ public function getChildren()
+ {
+ return new HTML_QuickForm2_ContainerIterator($this->current());
+ }
+}
+
+?> \ No newline at end of file
diff --git a/libs/HTML/QuickForm2/Container/Fieldset.php b/libs/HTML/QuickForm2/Container/Fieldset.php
new file mode 100644
index 0000000000..bf362431c8
--- /dev/null
+++ b/libs/HTML/QuickForm2/Container/Fieldset.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Base class for fieldsets
+ *
+ * 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: Fieldset.php 294052 2010-01-26 20:00:22Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for fieldsets
+ */
+require_once 'HTML/QuickForm2/Container.php';
+
+/**
+ * Concrete implementation of a container for fieldsets
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Container_Fieldset extends HTML_QuickForm2_Container
+{
+ /**
+ * Fieldsets don't have a 'name' attribute, so we only handle 'id'
+ * @var array
+ */
+ protected $watchedAttributes = array('id');
+
+ public function getType()
+ {
+ return 'fieldset';
+ }
+
+
+ public function getName()
+ {
+ return null;
+ }
+
+
+ public function setName($name)
+ {
+ // Fieldsets do not have a name attribute
+ return $this;
+ }
+
+
+ public function setValue($value)
+ {
+ throw new HTML_QuickForm2_Exception('Not implemented');
+ }
+}
+?> \ No newline at end of file
diff --git a/libs/HTML/QuickForm2/Container/Group.php b/libs/HTML/QuickForm2/Container/Group.php
new file mode 100644
index 0000000000..4ef7b1b552
--- /dev/null
+++ b/libs/HTML/QuickForm2/Container/Group.php
@@ -0,0 +1,328 @@
+<?php
+/**
+ * Base class for HTML_QuickForm2 groups
+ *
+ * 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: Group.php 294057 2010-01-26 21:10:28Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for all HTML_QuickForm2 containers
+ */
+require_once 'HTML/QuickForm2/Container.php';
+
+/**
+ * Base class for QuickForm2 groups of 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_Container_Group extends HTML_QuickForm2_Container
+{
+ /**
+ * Group name
+ * If set, group name will be used as prefix for contained
+ * element names, like groupname[elementname].
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * Previous group name
+ * Stores the previous group name when the group name is changed.
+ * Used to restore children names if necessary.
+ * @var string
+ */
+ protected $previousName;
+
+ public function getType()
+ {
+ return 'group';
+ }
+
+ protected function prependsName()
+ {
+ return strlen($this->name) > 0;
+ }
+
+ public function getValue()
+ {
+ $value = parent::getValue();
+ if (!$this->prependsName()) {
+ return $value;
+
+ } elseif (!strpos($this->getName(), '[')) {
+ return isset($value[$this->getName()])? $value[$this->getName()]: null;
+
+ } else {
+ $tokens = explode('[', str_replace(']', '', $this->getName()));
+ $valueAry =& $value;
+ do {
+ $token = array_shift($tokens);
+ if (!isset($valueAry[$token])) {
+ return null;
+ }
+ $valueAry =& $valueAry[$token];
+ } while ($tokens);
+ return $valueAry;
+ }
+ }
+
+ public function setValue($value)
+ {
+ // Prepare a mapper for element names as array
+
+ if ($this->prependsName()) {
+ $prefix = explode('[', str_replace(']', '', $this->getName()));
+ }
+
+ $elements = array();
+ foreach ($this as $child) {
+ $tokens = explode('[', str_replace(']', '', $child->getName()));
+ if (!empty($prefix)) {
+ $tokens = array_slice($tokens, count($prefix));
+ }
+ $elements[] = $tokens;
+ }
+
+ // Iterate over values to find corresponding element
+
+ $index = 0;
+
+ foreach ($value as $k => $v) {
+ $val = array($k => $v);
+ $found = null;
+ foreach ($elements as $i => $tokens) {
+ do {
+ $token = array_shift($tokens);
+ $numeric = false;
+ if ($token == "") {
+ // Deal with numeric indexes in values
+ $token = $index;
+ $numeric = true;
+ }
+ if (isset($val[$token])) {
+ // Found a value
+ $val = $val[$token];
+ $found = $val;
+ if ($numeric) {
+ $index += 1;
+ }
+ } else {
+ // Not found, skip next iterations
+ $found = null;
+ break;
+ }
+
+ } while (!empty($tokens));
+
+ if (!is_null($found)) {
+ // Found a value corresponding to element name
+ $child = $this->elements[$i];
+ $child->setValue($val);
+ unset($val);
+ if (!($child instanceof HTML_QuickForm2_Container_Group)) {
+ // Speed up next iterations
+ unset($elements[$i]);
+ }
+ break;
+ }
+ }
+ }
+ }
+
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function setName($name)
+ {
+ $this->previousName = $this->name;
+ $this->name = $name;
+ foreach ($this as $child) {
+ $this->renameChild($child);
+ }
+ return $this;
+ }
+
+ protected function renameChild(HTML_QuickForm2_Node $element)
+ {
+ $tokens = explode('[', str_replace(']', '', $element->getName()));
+ if ($this === $element->getContainer()) {
+ // Child has already been renamed by its group before
+ if (!is_null($this->previousName) &&
+ $this->previousName !== '') {
+ $gtokens = explode('[', str_replace(']', '', $this->previousName));
+ $pos = array_search(end($gtokens), $tokens);
+ if (!is_null($pos)) {
+ $tokens = array_slice($tokens, $pos+1);
+ }
+ }
+ }
+ if (is_null($this->name) || $this->name === '') {
+ if (is_null($this->previousName) || $this->previousName === '') {
+ return $element;
+ } else {
+ $elname = $tokens[0];
+ unset($tokens[0]);
+ foreach ($tokens as $v) {
+ $elname .= '['.$v.']';
+ }
+ }
+ } else {
+ $elname = $this->getName().'['.implode('][', $tokens).']';
+ }
+ $element->setName($elname);
+ return $element;
+ }
+
+ /**
+ * 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 (null !== ($container = $element->getContainer())) {
+ $container->removeChild($element);
+ }
+ // Element can be renamed only after being removed from container
+ $this->renameChild($element);
+
+ $element->setContainer($this);
+ $this->elements[] = $element;
+ return $element;
+ }
+
+ /**
+ * 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)
+ {
+ $element = parent::removeChild($element);
+ if ($this->prependsName()) {
+ $name = preg_replace('/^' . $this->getName() . '\[([^\]]*)\]/', '\1', $element->getName());
+ $element->setName($name);
+ }
+ return $element;
+ }
+
+ /**
+ * 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);
+ }
+ return parent::insertBefore($this->renameChild($element), $reference);
+ }
+
+ /**
+ * Sets string(s) to separate grouped elements
+ *
+ * @param string|array Use a string for one separator, array for
+ * alternating separators
+ * @return HTML_QuickForm2_Container_Group
+ */
+ public function setSeparator($separator)
+ {
+ $this->data['separator'] = $separator;
+ return $this;
+ }
+
+ /**
+ * Returns string(s) to separate grouped elements
+ *
+ * @return string|array Separator, null if not set
+ */
+ public function getSeparator()
+ {
+ return isset($this->data['separator'])? $this->data['separator']: null;
+ }
+
+ /**
+ * Renders the group using the given renderer
+ *
+ * @param HTML_QuickForm2_Renderer Renderer instance
+ * @return HTML_QuickForm2_Renderer
+ */
+ public function render(HTML_QuickForm2_Renderer $renderer)
+ {
+ $renderer->startGroup($this);
+ foreach ($this as $element) {
+ $element->render($renderer);
+ }
+ $renderer->finishGroup($this);
+ return $renderer;
+ }
+
+ public function __toString()
+ {
+ require_once 'HTML/QuickForm2/Renderer.php';
+
+ return $this->render(
+ HTML_QuickForm2_Renderer::factory('default')
+ ->setTemplateForId($this->getId(), '{content}')
+ )->__toString();
+ }
+}
+?> \ No newline at end of file
diff --git a/libs/HTML/QuickForm2/Controller.php b/libs/HTML/QuickForm2/Controller.php
new file mode 100644
index 0000000000..d2aa144fdc
--- /dev/null
+++ b/libs/HTML/QuickForm2/Controller.php
@@ -0,0 +1,506 @@
+<?php
+/**
+ * Class implementing the Page Controller pattern for multipage forms
+ *
+ * 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: Controller.php 295963 2010-03-08 14:33:43Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/** The class representing a page of a multipage form */
+require_once 'HTML/QuickForm2/Controller/Page.php';
+
+/** Object wrapping around session variable used to store controller data */
+require_once 'HTML/QuickForm2/Controller/SessionContainer.php';
+
+/** Class presenting the values stored in session by Controller as submitted ones */
+require_once 'HTML/QuickForm2/DataSource/Session.php';
+
+/**
+ * Class implementing the Page Controller pattern for multipage forms
+ *
+ * This class keeps track of pages and (default) action handlers for the form,
+ * it manages $_SESSION container for the form values, allows setting
+ * DataSources for the form as a whole and getting its value.
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Controller implements IteratorAggregate
+{
+ /**
+ * Key in $_REQUEST array that contains the ID of the Controller
+ */
+ const KEY_ID = '_qfc_id';
+
+ /**
+ * Key in $_SESSION array that contains the Controller data (needs ID substituted via sprintf())
+ */
+ const KEY_CONTAINER = '_%s_container';
+
+ /**
+ * Whether the form is a wizard
+ * @var boolean
+ */
+ protected $wizard = true;
+
+ /**
+ * Whether Controller ID should be sent in GET and POST parameters
+ * @var boolean
+ */
+ protected $propagate = true;
+
+ /**
+ * Controller ID
+ * @var string
+ */
+ protected $id = null;
+
+ /**
+ * Contains the pages (instances of HTML_QuickForm2_Controller_Page) of the multipage form
+ * @var array
+ */
+ protected $pages = array();
+
+ /**
+ * Contains the mapping of action names to handlers (objects implementing HTML_QuickForm2_Controller_Action)
+ * @var array
+ */
+ protected $handlers = array();
+
+ /**
+ * The action extracted from HTTP request: array('page', 'action')
+ * @var array
+ */
+ protected $actionName = null;
+
+ /**
+ * A wrapper around session variable used to store form data
+ * @var HTML_QuickForm2_Controller_SessionContainer
+ */
+ protected $sessionContainer = null;
+
+ /**
+ * Finds a controller name in $_REQUEST
+ *
+ * @return string|null Returns nulle if either a KEY_ID is not present
+ * in $_REQUEST or KEY_CONTAINER is not present in
+ * $_SESSION
+ */
+ public static function findControllerID()
+ {
+ if (empty($_REQUEST[self::KEY_ID])
+ || empty($_SESSION[sprintf(self::KEY_CONTAINER, $_REQUEST[self::KEY_ID])])
+ ) {
+ return null;
+ } else {
+ return $_REQUEST[self::KEY_ID];
+ }
+ }
+
+ /**
+ * Class constructor
+ *
+ * Sets the form ID, whether to send this ID in POST and GET parameters,
+ * wizard / non-wizard behaviour.
+ *
+ * Different forms should be given different IDs, as they are used to store
+ * values in session. If $id is empty, the controller will try to find it
+ * in $_REQUEST, throwing the exception if this fails.
+ *
+ * Wizard forms only allow going to the next page if all the previous ones
+ * are valid.
+ *
+ * @param string Form ID
+ * @param boolean Whether the form is a wizard
+ * @param boolean Whether form's ID should be sent with GET and POST parameters
+ * @throws HTML_QuickForm2_NotFoundException if ID is not given and cannot
+ * be found in $_REQUEST, or session container is empty
+ */
+ public function __construct($id = null, $wizard = true, $propagateId = false)
+ {
+ if (empty($id)) {
+ $propagateId = true;
+ $id = self::findControllerID();
+ }
+ if (empty($id)) {
+ throw new HTML_QuickForm2_NotFoundException(
+ 'Controller ID not available in $_REQUEST or session ' .
+ 'container is empty, please provide ID to constructor'
+ );
+ }
+ $this->id = $id;
+ $this->wizard = (bool)$wizard;
+ $this->propagate = (bool)$propagateId;
+ }
+
+ /**
+ * Returns whether the form is a wizard
+ *
+ * @return boolean
+ */
+ public function isWizard()
+ {
+ return $this->wizard;
+ }
+
+ /**
+ * Returns the form ID
+ *
+ * @return string
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ /**
+ * Returns whether to send form id with GET and POST parameters
+ *
+ * @return boolean
+ */
+ public function propagateId()
+ {
+ return $this->propagate;
+ }
+
+ /**
+ * Returns the session container with the controller data
+ *
+ * @return HTML_QuickForm2_Controller_SessionContainer
+ */
+ public function getSessionContainer()
+ {
+ if (empty($this->sessionContainer)) {
+ $this->sessionContainer = new HTML_QuickForm2_Controller_SessionContainer($this);
+ }
+ return $this->sessionContainer;
+ }
+
+ /**
+ * Removes the session variable containing the controller data
+ */
+ public function destroySessionContainer()
+ {
+ unset($_SESSION[sprintf(self::KEY_CONTAINER, $this->id)]);
+ $this->sessionContainer = null;
+ }
+
+ /**
+ * Extracts the name of the page and the action to perform with it from HTTP request data
+ *
+ * @return array first element is page name, second is action name
+ */
+ public function getActionName()
+ {
+ if (is_array($this->actionName)) {
+ return $this->actionName;
+ }
+ if (empty($this->pages)) {
+ throw new HTML_QuickForm2_NotFoundException('No pages added to the form');
+ }
+ $names = array_map('preg_quote', array_keys($this->pages));
+ $regex = '/^_qf_(' . implode('|', $names) . ')_(.+?)(_x)?$/';
+ foreach (array_keys($_REQUEST) as $key) {
+ if (preg_match($regex, $key, $matches)) {
+ $this->actionName = array($matches[1], $matches[2]);
+ break;
+ }
+ }
+ if (!is_array($this->actionName)) {
+ reset($this->pages);
+ $this->actionName = array(key($this->pages), 'display');
+ }
+ return $this->actionName;
+ }
+
+ /**
+ * Processes the request
+ *
+ * This finds the page, the action to perform with it and passes the action
+ * to the page's handle() method.
+ *
+ * @throws HTML_QuickForm2_Exception
+ */
+ public function run()
+ {
+ list($page, $action) = $this->getActionName();
+ return $this->pages[$page]->handle($action);
+ }
+
+ /**
+ * Adds a handler for a specific action
+ *
+ * @param string action name
+ * @param HTML_QuickForm2_Controller_Action the handler for the action
+ */
+ public function addHandler($actionName, HTML_QuickForm2_Controller_Action $action)
+ {
+ $this->handlers[$actionName] = $action;
+ }
+
+ /**
+ * Handles an action
+ *
+ * This will be called if the page itself does not have a handler for a
+ * specific action. The method also loads and uses default handlers for
+ * common actions, if specific ones were not added.
+ *
+ * @param HTML_QuickForm2_Controller_Page form page
+ * @param string action name
+ * @throws HTML_QuickForm2_NotFoundException if handler for an action is missing
+ */
+ public function handle(HTML_QuickForm2_Controller_Page $page, $actionName)
+ {
+ if (!isset($this->handlers[$actionName])
+ && in_array($actionName, array('next', 'back', 'submit', 'display', 'jump'))
+ ) {
+ $className = 'HTML_QuickForm2_Controller_Action_' . ucfirst($actionName);
+ HTML_QuickForm2_Loader::loadClass($className);
+ $this->addHandler($actionName, new $className());
+ }
+ if (isset($this->handlers[$actionName])) {
+ return $this->handlers[$actionName]->perform($page, $actionName);
+ } else {
+ throw new HTML_QuickForm2_NotFoundException(
+ "Unhandled action '{$actionName}' for page '{$page->getForm()->getId()}'"
+ );
+ }
+ }
+
+ /**
+ * Adds a new page to the form
+ *
+ * @param HTML_QuickForm2_Controller_Page
+ */
+ public function addPage(HTML_QuickForm2_Controller_Page $page)
+ {
+ $pageId = $page->getForm()->getId();
+ if (!empty($this->pages[$pageId])) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ "Duplicate page ID '{$pageId}'"
+ );
+ }
+ $page->setController($this);
+ $this->pages[$pageId] = $page;
+ }
+
+ /**
+ * Returns a page
+ *
+ * @param string Page ID
+ * @return HTML_QuickForm2_Controller_Page
+ * @throws HTML_QuickForm2_NotFoundException if there is no page with
+ * the given ID
+ */
+ public function getPage($pageId)
+ {
+ if (!empty($this->pages[$pageId])) {
+ return $this->pages[$pageId];
+ } else {
+ throw new HTML_QuickForm2_NotFoundException(
+ "Unknown page '{$pageId}'"
+ );
+ }
+ }
+
+ /**
+ * Returns the page preceding the given one
+ *
+ * @param HTML_QuickForm2_Controller_Page
+ * @return HTML_QuickForm2_Controller_Page|null
+ */
+ public function previousPage(HTML_QuickForm2_Controller_Page $reference)
+ {
+ $previous = null;
+ foreach ($this->pages as $page) {
+ if ($page === $reference) {
+ return $previous;
+ }
+ $previous = $page;
+ }
+ return null;
+ }
+
+ /**
+ * Returns the page following the given one
+ *
+ * @param HTML_QuickForm2_Controller_Page
+ * @return HTML_QuickForm2_Controller_Page|null
+ */
+ public function nextPage(HTML_QuickForm2_Controller_Page $reference)
+ {
+ $previous = null;
+ foreach ($this->pages as $page) {
+ if ($previous === $reference) {
+ return $page;
+ }
+ $previous = $page;
+ }
+ return null;
+ }
+
+ /**
+ * Checks whether the pages of the controller are valid
+ *
+ * @param HTML_QuickForm2_Controller_Page If given, check only the pages
+ * before (not including) that page
+ * @return bool
+ */
+ public function isValid(HTML_QuickForm2_Controller_Page $reference = null)
+ {
+ $container = $this->getSessionContainer();
+ foreach ($this->pages as $id => $page) {
+ if ($reference === $page) {
+ return true;
+ }
+ if (!$container->getValidationStatus($id)) {
+ // We should handle the possible situation when the user has never
+ // seen a page of a non-modal multipage form
+ if (!$this->isWizard()
+ && null === $container->getValidationStatus($id)
+ ) {
+ // Empty Session datasource makes the form look submitted
+ $page->getForm()->setDatasources(array_merge(
+ $container->getDatasources(),
+ array(new HTML_QuickForm2_DataSource_Session(array()))
+ ));
+ // This will store the "submitted" values in session and
+ // return validation status
+ if ($page->storeValues()) {
+ continue;
+ }
+ }
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns the first page that failed validation
+ *
+ * @return HTML_QuickForm2_Controller_Page|null
+ */
+ public function getFirstInvalidPage()
+ {
+ foreach ($this->pages as $id => $page) {
+ if (!$this->getSessionContainer()->getValidationStatus($id)) {
+ return $page;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Adds a new data source to the Controller
+ *
+ * Note that Controller data sources are stored in session, so your data source
+ * implementation should properly handle its (un)serialization.
+ *
+ * @param HTML_QuickForm2_DataSource Data source
+ */
+ public function addDataSource(HTML_QuickForm2_DataSource $datasource)
+ {
+ $this->getSessionContainer()->storeDatasources(
+ array_merge($this->getSessionContainer()->getDatasources(),
+ array($datasource))
+ );
+ }
+
+ /**
+ * Returns the form's values
+ *
+ * @return array
+ */
+ public function getValue()
+ {
+ $values = array();
+ foreach (array_keys($this->pages) as $id) {
+ $pageValues = $this->getSessionContainer()->getValues($id);
+ // skip elements representing actions
+ foreach ($pageValues as $key => $value) {
+ if (0 !== strpos($key, '_qf')) {
+ if (isset($values[$key]) && is_array($value)) {
+ $values[$key] = self::arrayMerge($values[$key], $value);
+ } else {
+ $values[$key] = $value;
+ }
+ }
+ }
+ }
+ return $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 Iterator for the form's pages
+ *
+ * @return ArrayIterator
+ */
+ public function getIterator()
+ {
+ return new ArrayIterator($this->pages);
+ }
+}
+?> \ No newline at end of file
diff --git a/libs/HTML/QuickForm2/Controller/Action.php b/libs/HTML/QuickForm2/Controller/Action.php
new file mode 100644
index 0000000000..85e0c0cd77
--- /dev/null
+++ b/libs/HTML/QuickForm2/Controller/Action.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * Interface for Controller action handlers
+ *
+ * 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: Action.php 293335 2010-01-09 20:14:38Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+
+/**
+ * Interface for Controller action handlers
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+interface HTML_QuickForm2_Controller_Action
+{
+ /**
+ * Performs the given action upon the given page
+ *
+ * @param HTML_QuickForm2_Controller_Page page of the multipage form
+ * @param string action name, some action handlers
+ * may perform different tasks depending
+ * on this
+ */
+ public function perform(HTML_QuickForm2_Controller_Page $page, $name);
+}
+?> \ No newline at end of file
diff --git a/libs/HTML/QuickForm2/Controller/Action/Back.php b/libs/HTML/QuickForm2/Controller/Action/Back.php
new file mode 100644
index 0000000000..1e591b4a42
--- /dev/null
+++ b/libs/HTML/QuickForm2/Controller/Action/Back.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Action handler for a 'back' button of wizard-type multipage form
+ *
+ * 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: Back.php 293411 2010-01-11 16:51:32Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/** Interface for Controller action handlers */
+require_once 'HTML/QuickForm2/Controller/Action.php';
+
+/**
+ * Action handler for a 'back' button of wizard-type multipage form
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Controller_Action_Back
+ implements HTML_QuickForm2_Controller_Action
+{
+ public function perform(HTML_QuickForm2_Controller_Page $page, $name)
+ {
+ $page->storeValues(!$page->getController()->isWizard());
+
+ // go to the previous page if one is available
+ // we don't check validation status here, 'jump' handler should
+ if ($previous = $page->getController()->previousPage($page)) {
+ return $previous->handle('jump');
+ } else {
+ return $page->handle('jump');
+ }
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Controller/Action/Direct.php b/libs/HTML/QuickForm2/Controller/Action/Direct.php
new file mode 100644
index 0000000000..1c760a0432
--- /dev/null
+++ b/libs/HTML/QuickForm2/Controller/Action/Direct.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Action handler for going to a specific page of a multipage form
+ *
+ * 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: Direct.php 293411 2010-01-11 16:51:32Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/** Interface for Controller action handlers */
+require_once 'HTML/QuickForm2/Controller/Action.php';
+
+/**
+ * Action handler for going to a specific page of a multipage form
+ *
+ * When an instance of this class is added in addHandler(), action name
+ * should be set to ID of a page you want to go to, not 'direct'
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Controller_Action_Direct
+ implements HTML_QuickForm2_Controller_Action
+{
+ public function perform(HTML_QuickForm2_Controller_Page $page, $name)
+ {
+ $page->storeValues();
+
+ return $page->getController()->getPage($name)->handle('jump');
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Controller/Action/Display.php b/libs/HTML/QuickForm2/Controller/Action/Display.php
new file mode 100644
index 0000000000..dc75a8dfe1
--- /dev/null
+++ b/libs/HTML/QuickForm2/Controller/Action/Display.php
@@ -0,0 +1,117 @@
+<?php
+/**
+ * Action handler for outputting the form
+ *
+ * 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: Display.php 294028 2010-01-25 23:09:11Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/** Interface for Controller action handlers */
+require_once 'HTML/QuickForm2/Controller/Action.php';
+
+/** Class presenting the values stored in session by Controller as submitted ones */
+require_once 'HTML/QuickForm2/DataSource/Session.php';
+
+/**
+ * Action handler for outputting the form
+ *
+ * If you want to customize the form display, subclass this class and override
+ * the renderForm() method, you don't need to change the perform() method.
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Controller_Action_Display
+ implements HTML_QuickForm2_Controller_Action
+{
+ public function perform(HTML_QuickForm2_Controller_Page $page, $name)
+ {
+ $validate = false;
+ $datasources = $page->getForm()->getDataSources();
+ $container = $page->getController()->getSessionContainer();
+ list(, $oldName) = $page->getController()->getActionName();
+ // Check the original action name, we need to do additional processing
+ // if it was 'display'
+ if ('display' == $oldName) {
+ // In case of wizard-type controller we should not allow access to
+ // a page unless all previous pages are valid (see also bug #2323)
+ if ($page->getController()->isWizard()
+ && !$page->getController()->isValid($page)
+ ) {
+ return $page->getController()->getFirstInvalidPage()->handle('jump');
+ }
+ // If we have values in container then we should inject the Session
+ // DataSource, if page was invalid previously we should later call
+ // validate() to get the errors
+ if (count($container->getValues($page->getForm()->getId()))) {
+ array_unshift($datasources, new HTML_QuickForm2_DataSource_Session(
+ $container->getValues($page->getForm()->getId())
+ ));
+ $validate = false === $container->getValidationStatus($page->getForm()->getId());
+ }
+ }
+
+ // Add "defaults" datasources stored in session
+ $page->getForm()->setDataSources(array_merge($datasources, $container->getDatasources()));
+ $page->populateFormOnce();
+ if ($validate) {
+ $page->getForm()->validate();
+ }
+ return $this->renderForm($page->getForm());
+ }
+
+ /**
+ * Outputs the form
+ *
+ * Default behaviour is to rely on form's __toString() magic method.
+ * If you want to customize form appearance or use a different Renderer,
+ * you should override this method.
+ *
+ * @param HTML_QuickForm2
+ */
+ protected function renderForm(HTML_QuickForm2 $form)
+ {
+ echo $form;
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Controller/Action/Jump.php b/libs/HTML/QuickForm2/Controller/Action/Jump.php
new file mode 100644
index 0000000000..4e29492f83
--- /dev/null
+++ b/libs/HTML/QuickForm2/Controller/Action/Jump.php
@@ -0,0 +1,209 @@
+<?php
+/**
+ * This handler performs an HTTP redirect to a specific page
+ *
+ * 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: Jump.php 294039 2010-01-26 12:29:46Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/** Interface for Controller action handlers */
+require_once 'HTML/QuickForm2/Controller/Action.php';
+
+/**
+ * This handler performs an HTTP redirect to a specific page
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Controller_Action_Jump
+ implements HTML_QuickForm2_Controller_Action
+{
+ /**
+ * Splits (part of) the URI into path and query components
+ *
+ * @param string String of the form 'foo?bar'
+ * @return array Array of the form array('foo', '?bar)
+ */
+ protected static function splitUri($uri)
+ {
+ if (false === ($qm = strpos($uri, '?'))) {
+ return array($uri, '');
+ } else {
+ return array(substr($uri, 0, $qm), substr($uri, $qm));
+ }
+ }
+
+ /**
+ * Removes the '..' and '.' segments from the path component
+ *
+ * @param string Path component of the URL, possibly with '.' and '..' segments
+ * @return string Path component of the URL with '.' and '..' segments removed
+ */
+ protected static function normalizePath($path)
+ {
+ $pathAry = explode('/', $path);
+ $i = 1;
+
+ do {
+ if ('.' == $pathAry[$i]) {
+ if ($i < count($pathAry) - 1) {
+ array_splice($pathAry, $i, 1);
+ } else {
+ $pathAry[$i] = '';
+ $i++;
+ }
+
+ } elseif ('..' == $pathAry[$i]) {
+ if (1 == $i) {
+ array_splice($pathAry, 1, 1);
+
+ } elseif ('..' != $pathAry[$i - 1]) {
+ if ($i < count($pathAry) - 1) {
+ array_splice($pathAry, $i - 1, 2);
+ $i--;
+ } else {
+ array_splice($pathAry, $i - 1, 2, '');
+ }
+ }
+
+ } else {
+ $i++;
+ }
+ } while ($i < count($pathAry));
+
+ return implode('/', $pathAry);
+ }
+
+ /**
+ * Resolves relative URL using current page's URL as base
+ *
+ * The method follows procedure described in section 4 of RFC 1808 and
+ * passes the examples provided in section 5 of said RFC. Values from
+ * $_SERVER array are used for calculation of "current URL"
+ *
+ * @param string Relative URL, probably from form's action attribute
+ * @return string Absolute URL
+ */
+ protected static function resolveRelativeURL($url)
+ {
+ $https = !empty($_SERVER['HTTPS']) && ('off' != strtolower($_SERVER['HTTPS']));
+ $scheme = ($https? 'https:': 'http:');
+ if ('//' == substr($url, 0, 2)) {
+ return $scheme . $url;
+
+ } else {
+ $host = $scheme . '//' . $_SERVER['SERVER_NAME'] .
+ (($https && 443 == $_SERVER['SERVER_PORT'] ||
+ !$https && 80 == $_SERVER['SERVER_PORT'])? '': ':' . $_SERVER['SERVER_PORT']);
+ if ('' == $url) {
+ return $host . $_SERVER['REQUEST_URI'];
+
+ } elseif ('/' == $url[0]) {
+ list($actPath, $actQuery) = self::splitUri($url);
+ return $host . self::normalizePath($actPath) . $actQuery;
+
+ } else {
+ list($basePath, $baseQuery) = self::splitUri($_SERVER['REQUEST_URI']);
+ list($actPath, $actQuery) = self::splitUri($url);
+ if ('' == $actPath) {
+ return $host . $basePath . $actQuery;
+ } else {
+ $path = substr($basePath, 0, strrpos($basePath, '/') + 1) . $actPath;
+ return $host . self::normalizePath($path) . $actQuery;
+ }
+ }
+ }
+ }
+
+ public function perform(HTML_QuickForm2_Controller_Page $page, $name)
+ {
+ // we check whether *all* pages up to current are valid
+ // if there is an invalid page we go to it, instead of the
+ // requested one
+ if ($page->getController()->isWizard()
+ && !$page->getController()->isValid($page)
+ ) {
+ $page = $page->getController()->getFirstInvalidPage();
+ }
+
+ // generate the URL for the page 'display' event and redirect to it
+ $action = $page->getForm()->getAttribute('action');
+ // Bug #13087: RFC 2616 requires an absolute URI in Location header
+ if (!preg_match('@^([a-z][a-z0-9.+-]*):@i', $action)) {
+ $action = self::resolveRelativeURL($action);
+ }
+
+ if (!$page->getController()->propagateId()) {
+ $controllerId = '';
+ } else {
+ $controllerId = '&' . HTML_QuickForm2_Controller::KEY_ID . '=' .
+ $page->getController()->getId();
+ }
+ if (!defined('SID') || '' == SID || ini_get('session.use_only_cookies')) {
+ $sessionId = '';
+ } else {
+ $sessionId = '&' . SID;
+ }
+
+ return $this->doRedirect(
+ $action . (false === strpos($action, '?')? '?': '&') .
+ $page->getButtonName('display') . '=true' . $controllerId . $sessionId
+ );
+ }
+
+
+ /**
+ * Redirects to a given URL via Location: header and exits the script
+ *
+ * A separate method is mostly needed for creating mocks of this class
+ * during testing.
+ *
+ * @param string URL to redirect to
+ */
+ protected function doRedirect($url)
+ {
+ header('Location: ' . $url);
+ exit;
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Controller/Action/Next.php b/libs/HTML/QuickForm2/Controller/Action/Next.php
new file mode 100644
index 0000000000..b01b9c6413
--- /dev/null
+++ b/libs/HTML/QuickForm2/Controller/Action/Next.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Action handler for a 'next' button of wizard-type multipage form
+ *
+ * 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: Next.php 293411 2010-01-11 16:51:32Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/** Interface for Controller action handlers */
+require_once 'HTML/QuickForm2/Controller/Action.php';
+
+/**
+ * Action handler for a 'next' button of wizard-type multipage form
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Controller_Action_Next
+ implements HTML_QuickForm2_Controller_Action
+{
+ public function perform(HTML_QuickForm2_Controller_Page $page, $name)
+ {
+ $valid = $page->storeValues();
+
+ // Wizard and page is invalid: don't go further
+ if ($page->getController()->isWizard() && !$valid) {
+ return $page->handle('display');
+ }
+
+ // More pages?
+ if (null !== ($next = $page->getController()->nextPage($page))) {
+ return $next->handle('jump');
+
+ // Consider this a 'finish' button, if there is no explicit one
+ } elseif($page->getController()->isWizard()) {
+ if ($page->getController()->isValid()) {
+ return $page->handle('process');
+ } else {
+ // redirect to the first invalid page
+ return $page->getController()->getFirstInvalidPage()->handle('jump');
+ }
+
+ } else {
+ return $page->handle('display');
+ }
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Controller/Action/Submit.php b/libs/HTML/QuickForm2/Controller/Action/Submit.php
new file mode 100644
index 0000000000..67fb436240
--- /dev/null
+++ b/libs/HTML/QuickForm2/Controller/Action/Submit.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Action handler for a 'submit' button
+ *
+ * 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: Submit.php 293411 2010-01-11 16:51:32Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/** Interface for Controller action handlers */
+require_once 'HTML/QuickForm2/Controller/Action.php';
+
+/**
+ * Action handler for a 'submit' button
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Controller_Action_Submit
+ implements HTML_QuickForm2_Controller_Action
+{
+ public function perform(HTML_QuickForm2_Controller_Page $page, $name)
+ {
+ $valid = $page->storeValues();
+
+ // All pages are valid, process
+ if ($page->getController()->isValid()) {
+ return $page->handle('process');
+
+ // Current page is invalid, display it
+ } elseif (!$valid) {
+ return $page->handle('display');
+
+ // Some other page is invalid, redirect to it
+ } else {
+ return $page->getController()->getFirstInvalidPage()->handle('jump');
+ }
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Controller/DefaultAction.php b/libs/HTML/QuickForm2/Controller/DefaultAction.php
new file mode 100644
index 0000000000..d88a07a47b
--- /dev/null
+++ b/libs/HTML/QuickForm2/Controller/DefaultAction.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * A hidden button used to submit the form when the user presses Enter
+ *
+ * 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: DefaultAction.php 293465 2010-01-12 18:24:37Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/** Class for <input type="image" /> elements */
+require_once 'HTML/QuickForm2/Element/InputImage.php';
+
+/**
+ * A hidden button used to submit the form when the user presses Enter
+ *
+ * This element is used by {@link HTML_QuickForm2_Controller_Page::setDefaultAction()}
+ * to define the action that will take place if the user presses Enter on one
+ * of the form elements instead of explicitly clicking one of the submit
+ * buttons. Injecting a hidden <input type="image" /> element is about the
+ * only cross-browser way to achieve this.
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ * @link http://www.alanflavell.org.uk/www/formquestion.html
+ * @link http://muffinresearch.co.uk/archives/2005/12/08/fun-with-multiple-submit-buttons/
+ */
+class HTML_QuickForm2_Controller_DefaultAction
+ extends HTML_QuickForm2_Element_InputImage
+{
+ protected $attributes = array('type' => 'image', 'id' => '_qf_default',
+ 'width' => '1', 'height' => '1');
+
+ /**
+ * Disallow changing the 'id' attribute
+ *
+ * @param string Attribute name
+ * @param string Attribute value, null if attribute is being removed
+ */
+ protected function onAttributeChange($name, $value = null)
+ {
+ if ('id' == $name) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ "Attribute 'id' is read-only"
+ );
+ }
+ parent::onAttributeChange($name, $value);
+ }
+
+ /**
+ * This element is rendered using renderHidden() method
+ *
+ * renderHidden() is used to
+ * - prevent using the standard element template as this button is
+ * expected to be hidden
+ * - render it above all other submit buttons since hidden elements
+ * are usually at the top of the form
+ *
+ * @param HTML_QuickForm2_Renderer Renderer instance
+ * @return HTML_QuickForm2_Renderer
+ */
+ public function render(HTML_QuickForm2_Renderer $renderer)
+ {
+ $renderer->renderHidden($this);
+ return $renderer;
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Controller/Page.php b/libs/HTML/QuickForm2/Controller/Page.php
new file mode 100644
index 0000000000..1d639161d6
--- /dev/null
+++ b/libs/HTML/QuickForm2/Controller/Page.php
@@ -0,0 +1,258 @@
+<?php
+/**
+ * Class representing a page of a multipage form
+ *
+ * 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: Page.php 295963 2010-03-08 14:33:43Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Class representing a page of a multipage form
+ *
+ * Unlike old HTML_QuickForm_Controller, this does not extend HTML_QuickForm2
+ * but accepts an instance of that in the constructor. You need to create a
+ * subclass of this class and implement its populateForm() method.
+ *
+ * @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_Controller_Page
+{
+ /**
+ * Button name template (needs form ID and action name substituted by sprintf())
+ */
+ const KEY_NAME = '_qf_%s_%s';
+
+ /**
+ * Whether populateForm() was already called
+ * @var boolean
+ */
+ private $_formPopulated = false;
+
+ /**
+ * The form wrapped by this page
+ * @var HTML_QuickForm2
+ */
+ protected $form = null;
+
+ /**
+ * Controller this page belongs to
+ * @var HTML_QuickForm2_Controller
+ */
+ protected $controller = null;
+
+ /**
+ * Contains the mapping of action names to handlers (objects implementing HTML_QuickForm2_Controller_Action)
+ * @var array
+ */
+ protected $handlers = array();
+
+ /**
+ * Class constructor, accepts the form to wrap around
+ *
+ * @param HTML_QuickForm2
+ */
+ public function __construct(HTML_QuickForm2 $form)
+ {
+ $this->form = $form;
+ }
+
+ /**
+ * Returns the form this page wraps around
+ *
+ * @return HTML_QuickForm2
+ */
+ public function getForm()
+ {
+ return $this->form;
+ }
+
+ /**
+ * Sets the controller owning the page
+ *
+ * @param HTML_QuickForm2_Controller controller the page belongs to
+ */
+ public function setController(HTML_QuickForm2_Controller $controller)
+ {
+ $this->controller = $controller;
+ }
+
+ /**
+ * Returns the controller owning this page
+ *
+ * @return HTML_QuickForm2_Controller
+ */
+ public function getController()
+ {
+ return $this->controller;
+ }
+
+ /**
+ * Adds a handler for a specific action
+ *
+ * @param string action name
+ * @param HTML_QuickForm2_Controller_Action the handler for the action
+ */
+ public function addHandler($actionName, HTML_QuickForm2_Controller_Action $action)
+ {
+ $this->handlers[$actionName] = $action;
+ }
+
+ /**
+ * Handles an action
+ *
+ * If the page does not contain a handler for this action, controller's
+ * handle() method will be called.
+ *
+ * @param string Name of the action
+ * @throws HTML_QuickForm2_NotFoundException if handler for an action is missing
+ */
+ public function handle($actionName)
+ {
+ if (isset($this->handlers[$actionName])) {
+ return $this->handlers[$actionName]->perform($this, $actionName);
+ } else {
+ return $this->getController()->handle($this, $actionName);
+ }
+ }
+
+ /**
+ * Returns a name for a submit button that will invoke a specific action
+ *
+ * @param string Name of the action
+ * @return string "name" attribute for a submit button
+ */
+ public function getButtonName($actionName)
+ {
+ return sprintf(self::KEY_NAME, $this->getForm()->getId(), $actionName);
+ }
+
+ /**
+ * Sets the default action invoked on page-form submit
+ *
+ * This is necessary as the user may just press Enter instead of
+ * clicking one of the named submit buttons and then no action name will
+ * be passed to the script.
+ *
+ * @param string Default action name
+ * @param string Path to a 1x1 transparent GIF image
+ * @return object Returns the image input used for default action
+ */
+ public function setDefaultAction($actionName, $imageSrc = '')
+ {
+ require_once 'HTML/QuickForm2/Controller/DefaultAction.php';
+
+ if (0 == count($this->form)) {
+ $image = $this->form->appendChild(
+ new HTML_QuickForm2_Controller_DefaultAction(
+ $this->getButtonName($actionName), array('src' => $imageSrc)
+ )
+ );
+
+ // replace the existing DefaultAction
+ } elseif ($image = $this->form->getElementById('_qf_default')) {
+ $image->setName($this->getButtonName($actionName))
+ ->setAttribute('src', $imageSrc);
+
+ // Inject the element to the first position to improve chances that
+ // it ends up on top in the output
+ } else {
+ $it = $this->form->getIterator();
+ $it->rewind();
+ $image = $this->form->insertBefore(
+ new HTML_QuickForm2_Controller_DefaultAction(
+ $this->getButtonName($actionName), array('src' => $imageSrc)
+ ),
+ $it->current()
+ );
+ }
+ return $image;
+ }
+
+ /**
+ * Wrapper around populateForm() ensuring that it is only called once
+ */
+ final public function populateFormOnce()
+ {
+ if (!$this->_formPopulated) {
+ if (!empty($this->controller) && $this->controller->propagateId()) {
+ $this->form->addElement(
+ 'hidden', HTML_QuickForm2_Controller::KEY_ID,
+ array('id' => HTML_QuickForm2_Controller::KEY_ID)
+ )->setValue($this->controller->getId());
+ }
+ $this->populateForm();
+ $this->_formPopulated = true;
+ }
+ }
+
+ /**
+ * Populates the form with the elements
+ *
+ * The implementation of this method in your subclass of
+ * HTML_QuickForm2_Controller_Page should contain all the necessary
+ * addElement(), addRule() etc. calls. The method will only be called if
+ * needed to prevent wasting resources on the forms that aren't going to
+ * be seen by the user.
+ */
+ abstract protected function populateForm();
+
+ /**
+ * Stores the form values (and validation status) is session container
+ *
+ * @param bool Whether to store validation status
+ */
+ public function storeValues($validate = true)
+ {
+ $this->populateFormOnce();
+ $container = $this->getController()->getSessionContainer();
+ $id = $this->form->getId();
+
+ $container->storeValues($id, (array)$this->form->getValue());
+ if ($validate) {
+ $container->storeValidationStatus($id, $this->form->validate());
+ }
+ return $container->getValidationStatus($id);
+ }
+}
+?> \ No newline at end of file
diff --git a/libs/HTML/QuickForm2/Controller/SessionContainer.php b/libs/HTML/QuickForm2/Controller/SessionContainer.php
new file mode 100644
index 0000000000..14b8674b1a
--- /dev/null
+++ b/libs/HTML/QuickForm2/Controller/SessionContainer.php
@@ -0,0 +1,195 @@
+<?php
+/**
+ * Object wrapping around session variable used to store controller data
+ *
+ * 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: SessionContainer.php 293868 2010-01-23 18:37:16Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Object wrapping around session variable used to store controller data
+ *
+ * Unlike old HTML_QuickForm_Controller, this does not extend HTML_QuickForm2
+ * but accepts an instance of that in the constructor. You need to create a
+ * subclass of this class and implement its populateForm() method.
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Controller_SessionContainer
+{
+ /**
+ * A reference to a key in $_SESSION superglobal array
+ * @var array
+ */
+ protected $data;
+
+ /**
+ * Class constructor
+ *
+ * Initializes a variable in $_SESSION array, its name is based upon the
+ * name of the Controller passed here
+ *
+ * @param HTML_QuickForm2_Controller
+ */
+ public function __construct(HTML_QuickForm2_Controller $controller)
+ {
+ $name = sprintf(HTML_QuickForm2_Controller::KEY_CONTAINER,
+ $controller->getId());
+ if (empty($_SESSION[$name])) {
+ $_SESSION[$name] = array(
+ 'datasources' => array(),
+ 'values' => array(),
+ 'valid' => array()
+ );
+ }
+ $this->data =& $_SESSION[$name];
+ }
+
+ /**
+ * Stores the page submit values
+ *
+ * @param string Page ID
+ * @param array Page submit values
+ */
+ public function storeValues($pageId, array $values)
+ {
+ $this->data['values'][$pageId] = $values;
+ }
+
+ /**
+ * Returns the page values kept in session
+ *
+ * @param string Page ID
+ * @return array
+ */
+ public function getValues($pageId)
+ {
+ return array_key_exists($pageId, $this->data['values'])
+ ? $this->data['values'][$pageId]: array();
+ }
+
+ /**
+ * Stores the page validation status
+ *
+ * @param string Page ID
+ * @param bool Whether the page is valid
+ */
+ public function storeValidationStatus($pageId, $status)
+ {
+ $this->data['valid'][$pageId] = (bool)$status;
+ }
+
+ /**
+ * Returns the page validation status kept in session
+ *
+ * @param string Page ID
+ * @return bool
+ */
+ public function getValidationStatus($pageId)
+ {
+ return array_key_exists($pageId, $this->data['valid'])
+ ? $this->data['valid'][$pageId]: null;
+
+ }
+
+ /**
+ * Stores the controller data sources
+ *
+ * @param array A new data source list
+ * @throws HTML_QuickForm2_InvalidArgumentException if given array
+ * contains something that is not a valid data source
+ */
+ public function storeDatasources(array $datasources)
+ {
+ foreach ($datasources as $ds) {
+ if (!$ds instanceof HTML_QuickForm2_DataSource) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'Array should contain only DataSource instances'
+ );
+ }
+ }
+ $this->data['datasources'] = $datasources;
+ }
+
+ /**
+ * Returns the controller data sources
+ *
+ * @return array
+ */
+ public function getDatasources()
+ {
+ return $this->data['datasources'];
+ }
+
+ /**
+ * Stores some user-supplied parameter alongside controller data
+ *
+ * It is sometimes useful to pass some additional user data between pages
+ * of the form, thus this method. It will be removed with all the other
+ * data by {@link HTML_QuickForm2_Controller::destroySessionContainer()}
+ *
+ * @param string Parameter name
+ * @param string Parameter value
+ */
+ public function storeOpaque($name, $value)
+ {
+ if (!array_key_exists('opaque', $this->data)) {
+ $this->data['opaque'] = array();
+ }
+ $this->data['opaque'][$name] = $value;
+ }
+
+ /**
+ * Returns a user-supplied parameter
+ *
+ * @param string Parameter name
+ * @return mixed
+ */
+ public function getOpaque($name)
+ {
+ return (array_key_exists('opaque', $this->data)
+ && array_key_exists($name, $this->data['opaque']))
+ ? $this->data['opaque'][$name]: null;
+ }
+} \ No newline at end of file
diff --git a/libs/HTML/QuickForm2/DataSource.php b/libs/HTML/QuickForm2/DataSource.php
new file mode 100644
index 0000000000..9bd3a4a004
--- /dev/null
+++ b/libs/HTML/QuickForm2/DataSource.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Interface for data sources used by HTML_QuickForm2 objects
+ *
+ * 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: DataSource.php 300722 2010-06-24 10:15:52Z mansion $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Interface for data sources used by HTML_QuickForm2 objects
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+interface HTML_QuickForm2_DataSource
+{
+ /**
+ * Returns value for the element with the given name
+ *
+ * If data source doesn't have a requested value it should return null
+ *
+ * @param string Element's name
+ * @return mixed Element's value
+ */
+ public function getValue($name);
+}
+?>
diff --git a/libs/HTML/QuickForm2/DataSource/Array.php b/libs/HTML/QuickForm2/DataSource/Array.php
new file mode 100644
index 0000000000..8bb2a2959e
--- /dev/null
+++ b/libs/HTML/QuickForm2/DataSource/Array.php
@@ -0,0 +1,101 @@
+<?php
+/**
+ * Array-based data source for HTML_QuickForm2 objects
+ *
+ * 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: Array.php 294057 2010-01-26 21:10:28Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Interface for data sources used by HTML_QuickForm2 objects
+ */
+require_once 'HTML/QuickForm2/DataSource.php';
+
+/**
+ * Array-based data source for HTML_QuickForm2 objects
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_DataSource_Array implements HTML_QuickForm2_DataSource
+{
+ /**
+ * Array containing elements' values
+ * @var array
+ */
+ protected $values;
+
+ /**
+ * Class constructor, initializes the values array
+ *
+ * @param array Array containing the elements' values
+ */
+ public function __construct($values = array())
+ {
+ $this->values = $values;
+ }
+
+ public function getValue($name)
+ {
+ if (empty($this->values)) {
+ return null;
+ }
+ if (strpos($name, '[')) {
+ $tokens = explode('[', str_replace(']', '', $name));
+ $value = $this->values;
+ do {
+ $token = array_shift($tokens);
+ if (!isset($value[$token])) {
+ return null;
+ }
+ $value = $value[$token];
+ } while (!empty($tokens));
+ return $value;
+ } elseif (isset($this->values[$name])) {
+ return $this->values[$name];
+ } else {
+ return null;
+ }
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/DataSource/Session.php b/libs/HTML/QuickForm2/DataSource/Session.php
new file mode 100644
index 0000000000..e4634557af
--- /dev/null
+++ b/libs/HTML/QuickForm2/DataSource/Session.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Class presenting the values stored in session by Controller as submitted ones
+ *
+ * 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: Session.php 293411 2010-01-11 16:51:32Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/** Interface for data sources containing submitted values */
+require_once 'HTML/QuickForm2/DataSource/Submit.php';
+
+/** Array-based data source for HTML_QuickForm2 objects */
+require_once 'HTML/QuickForm2/DataSource/Array.php';
+
+/**
+ * Class presenting the values stored in session by Controller as submitted ones
+ *
+ * This is a less hackish implementation of loadValues() method in old
+ * HTML_QuickForm_Controller. The values need to be presented as submitted so
+ * that elements like checkboxes and multiselects do not try to use default
+ * values from subsequent datasources.
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_DataSource_Session
+ extends HTML_QuickForm2_DataSource_Array
+ implements HTML_QuickForm2_DataSource_Submit
+{
+ /**
+ * File upload data is not stored in the session
+ */
+ public function getUpload($name)
+ {
+ return null;
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/DataSource/Submit.php b/libs/HTML/QuickForm2/DataSource/Submit.php
new file mode 100644
index 0000000000..fa9f6d3648
--- /dev/null
+++ b/libs/HTML/QuickForm2/DataSource/Submit.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Interface for data sources containing submitted values
+ *
+ * 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: Submit.php 300722 2010-06-24 10:15:52Z mansion $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Interface for data sources used by HTML_QuickForm2 objects
+ */
+require_once 'HTML/QuickForm2/DataSource.php';
+
+/**
+ * Interface for data sources containing submitted values
+ *
+ * This interface provides method for getting information on uploaded files.
+ * Additionally some elements will only consider getting their values from data
+ * sources implementing this interface.
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+interface HTML_QuickForm2_DataSource_Submit extends HTML_QuickForm2_DataSource
+{
+ /**
+ * Returns the information about uploaded file
+ *
+ * If data source doesn't such information it should return null
+ *
+ * @param string Name of file upload field
+ * @return array|null Information on uploaded file, from $_FILES array
+ */
+ public function getUpload($name);
+}
+?>
diff --git a/libs/HTML/QuickForm2/DataSource/SuperGlobal.php b/libs/HTML/QuickForm2/DataSource/SuperGlobal.php
new file mode 100644
index 0000000000..38fd7906d7
--- /dev/null
+++ b/libs/HTML/QuickForm2/DataSource/SuperGlobal.php
@@ -0,0 +1,170 @@
+<?php
+/**
+ * Data source for HTML_QuickForm2 objects based on superglobal arrays
+ *
+ * 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: SuperGlobal.php 294057 2010-01-26 21:10:28Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Interface for data sources containing submitted values
+ */
+require_once 'HTML/QuickForm2/DataSource/Submit.php';
+
+/**
+ * Array-based data source for HTML_QuickForm2 objects
+ */
+require_once 'HTML/QuickForm2/DataSource/Array.php';
+
+/**
+ * Data source for HTML_QuickForm2 objects based on superglobal arrays
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_DataSource_SuperGlobal
+ extends HTML_QuickForm2_DataSource_Array
+ implements HTML_QuickForm2_DataSource_Submit
+{
+ /**
+ * Information on file uploads (from $_FILES)
+ * @var array
+ */
+ protected $files = array();
+
+ /**
+ * Keys present in the $_FILES array
+ * @var array
+ */
+ private static $_fileKeys = array('name', 'type', 'size', 'tmp_name', 'error');
+
+ /**
+ * Class constructor, intializes the internal arrays from superglobals
+ *
+ * @param string Request method (GET or POST)
+ * @param bool Whether magic_quotes_gpc directive is on
+ */
+ public function __construct($requestMethod = 'POST', $magicQuotesGPC = false)
+ {
+ if (!$magicQuotesGPC) {
+ if ('GET' == strtoupper($requestMethod)) {
+ $this->values = $_GET;
+ } else {
+ $this->values = $_POST;
+ $this->files = $_FILES;
+ }
+ } else {
+ if ('GET' == strtoupper($requestMethod)) {
+ $this->values = $this->arrayMapRecursive('stripslashes', $_GET);
+ } else {
+ $this->values = $this->arrayMapRecursive('stripslashes', $_POST);
+ foreach ($_FILES as $key1 => $val1) {
+ foreach ($val1 as $key2 => $val2) {
+ if ('name' == $key2) {
+ $this->files[$key1][$key2] = $this->arrayMapRecursive(
+ 'stripslashes', $val2
+ );
+ } else {
+ $this->files[$key1][$key2] = $val2;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * A recursive version of array_map() function
+ *
+ * @param callback Callback function to apply
+ * @param mixed Input array
+ * @return array with callback applied
+ */
+ protected function arrayMapRecursive($callback, $arr)
+ {
+ if (!is_array($arr)) {
+ return call_user_func($callback, $arr);
+ }
+ $mapped = array();
+ foreach ($arr as $k => $v) {
+ $mapped[$k] = is_array($v)?
+ $this->arrayMapRecursive($callback, $v):
+ call_user_func($callback, $v);
+ }
+ return $mapped;
+ }
+
+ public function getUpload($name)
+ {
+ if (empty($this->files)) {
+ return null;
+ }
+ if (false !== ($pos = strpos($name, '['))) {
+ $tokens = explode('[', str_replace(']', '', $name));
+ $base = array_shift($tokens);
+ $value = array();
+ if (!isset($this->files[$base]['name'])) {
+ return null;
+ }
+ foreach (self::$_fileKeys as $key) {
+ $value[$key] = $this->files[$base][$key];
+ }
+
+ do {
+ $token = array_shift($tokens);
+ if (!isset($value['name'][$token])) {
+ return null;
+ }
+ foreach (self::$_fileKeys as $key) {
+ $value[$key] = $value[$key][$token];
+ }
+ } while (!empty($tokens));
+ return $value;
+ } elseif(isset($this->files[$name])) {
+ return $this->files[$name];
+ } else {
+ return null;
+ }
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Element.php b/libs/HTML/QuickForm2/Element.php
new file mode 100644
index 0000000000..b89e6b8b6f
--- /dev/null
+++ b/libs/HTML/QuickForm2/Element.php
@@ -0,0 +1,133 @@
+<?php
+/**
+ * Base class for simple HTML_QuickForm2 elements (not 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: Element.php 299706 2010-05-24 18:32:37Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for all HTML_QuickForm2 elements
+ */
+require_once 'HTML/QuickForm2/Node.php';
+
+/**
+ * Abstract base class for simple QuickForm2 elements (not 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_Element extends HTML_QuickForm2_Node
+{
+ public function setName($name)
+ {
+ $this->attributes['name'] = (string)$name;
+ $this->updateValue();
+ return $this;
+ }
+
+ /**
+ * Generates hidden form field containing the element's value
+ *
+ * This is used to pass the frozen element's value if 'persistent freeze'
+ * feature is on
+ *
+ * @return string
+ */
+ protected function getPersistentContent()
+ {
+ if (!$this->persistent || null === ($value = $this->getValue())) {
+ return '';
+ }
+ return '<input type="hidden"' . self::getAttributesString(array(
+ 'name' => $this->getName(),
+ 'value' => $value,
+ 'id' => $this->getId()
+ )) . ' />';
+ }
+
+ /**
+ * Called when the element needs to update its value from form's data sources
+ *
+ * The default behaviour is to go through the complete list of the data
+ * sources until the non-null value is found.
+ */
+ protected function updateValue()
+ {
+ $name = $this->getName();
+ foreach ($this->getDataSources() as $ds) {
+ if (null !== ($value = $ds->getValue($name))) {
+ $this->setValue($value);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Renders the element 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->renderElement($this);
+ return $renderer;
+ }
+
+ /**
+ * Returns Javascript code for getting the element's value
+ *
+ * @return string
+ */
+ public function getJavascriptValue()
+ {
+ return "qf.form.getValue(document.getElementById('" . $this->getId() . "'))";
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Element/Button.php b/libs/HTML/QuickForm2/Element/Button.php
new file mode 100644
index 0000000000..8fb87b1f1b
--- /dev/null
+++ b/libs/HTML/QuickForm2/Element/Button.php
@@ -0,0 +1,161 @@
+<?php
+/**
+ * Class for <button> elements
+ *
+ * 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: Button.php 300722 2010-06-24 10:15:52Z mansion $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for simple HTML_QuickForm2 elements
+ */
+require_once 'HTML/QuickForm2/Element.php';
+
+/**
+ * Class for <button> elements
+ *
+ * Note that this element was named 'xbutton' in previous version of QuickForm,
+ * the name 'button' being used for current 'inputbutton' element.
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Element_Button extends HTML_QuickForm2_Element
+{
+ /**
+ * Contains options and data used for the element creation
+ * - content: Content to be displayed between <button></button> tags
+ * @var array
+ */
+ protected $data = array('content' => '');
+
+ /**
+ * Element's submit value
+ * @var string
+ */
+ protected $submitValue = null;
+
+
+ public function getType()
+ {
+ return 'button';
+ }
+
+ /**
+ * Buttons can not be frozen
+ *
+ * @param bool Whether element should be frozen or editable. This
+ * parameter is ignored in case of buttons
+ * @return bool Always returns false
+ */
+ public function toggleFrozen($freeze = null)
+ {
+ return false;
+ }
+
+ /**
+ * Sets the contents of the button element
+ *
+ * @param string Button content (HTML to add between <button></button> tags)
+ * @return HTML_QuickForm2_Element_Button
+ */
+ function setContent($content)
+ {
+ $this->data['content'] = $content;
+ return $this;
+ }
+
+ /**
+ * Button's value cannot be set via this method
+ *
+ * @param mixed Element's value, this parameter is ignored
+ * @return HTML_QuickForm2_Element_Button
+ */
+ public function setValue($value)
+ {
+ return $this;
+ }
+
+ /**
+ * Returns the element's value
+ *
+ * The value is only returned if the following is true
+ * - button has 'type' attribute set to 'submit' (or no 'type' attribute)
+ * - the form was submitted by clicking on this button
+ *
+ * This method returns the actual value submitted by the browser. Note that
+ * different browsers submit different values!
+ *
+ * @return string|null
+ */
+ public function getValue()
+ {
+ if ((empty($this->attributes['type']) || 'submit' == $this->attributes['type']) &&
+ !$this->getAttribute('disabled'))
+ {
+ return $this->applyFilters($this->submitValue);
+ } else {
+ return null;
+ }
+ }
+
+ public function __toString()
+ {
+ return $this->getIndent() . '<button' . $this->getAttributes(true) .
+ '>' . $this->data['content'] . '</button>';
+ }
+
+ protected function updateValue()
+ {
+ foreach ($this->getDataSources() as $ds) {
+ if ($ds instanceof HTML_QuickForm2_DataSource_Submit &&
+ null !== ($value = $ds->getValue($this->getName())))
+ {
+ $this->submitValue = $value;
+ return;
+ }
+ }
+ $this->submitValue = null;
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Element/Date.php b/libs/HTML/QuickForm2/Element/Date.php
new file mode 100644
index 0000000000..4b98a8a457
--- /dev/null
+++ b/libs/HTML/QuickForm2/Element/Date.php
@@ -0,0 +1,503 @@
+<?php
+/**
+ * Date element
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2006-2009, 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: Date.php 297453 2010-04-04 10:22:39Z mansion $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for HTML_QuickForm2 group of elements
+ */
+require_once 'HTML/QuickForm2/Container/Group.php';
+/**
+ * Base class for HTML_QuickForm2 select element
+ */
+require_once 'HTML/QuickForm2/Element/Select.php';
+
+/**
+ * Class for a group of elements used to input dates (and times).
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Element_Date extends HTML_QuickForm2_Container_Group
+{
+ public function getType()
+ {
+ return 'date';
+ }
+
+ /**
+ * Various options to control the element's display.
+ * @var array
+ */
+ protected $data = array(
+ 'language' => 'en',
+ 'format' => 'dMY',
+ 'minYear' => 2001,
+ 'maxYear' => 2010,
+ 'addEmptyOption' => false,
+ 'emptyOptionValue' => '',
+ 'emptyOptionText' => '&nbsp;',
+ 'optionIncrement' => array('i' => 1, 's' => 1)
+ );
+
+ /**
+ * Class constructor
+ *
+ * The following keys may appear in $data array:
+ * - 'language': date language
+ * - 'format': Format of the date, based on PHP's date() function.
+ * The following characters are currently recognised in format string:
+ * <pre>
+ * D => Short names of days
+ * l => Long names of days
+ * d => Day numbers
+ * M => Short names of months
+ * F => Long names of months
+ * m => Month numbers
+ * Y => Four digit year
+ * y => Two digit year
+ * h => 12 hour format
+ * H => 23 hour format
+ * i => Minutes
+ * s => Seconds
+ * a => am/pm
+ * A => AM/PM
+ * </pre>
+ * - 'minYear': Minimum year in year select
+ * - 'maxYear': Maximum year in year select
+ * - 'addEmptyOption': Should an empty option be added to the top of
+ * each select box?
+ * - 'emptyOptionValue': The value passed by the empty option.
+ * - 'emptyOptionText': The text displayed for the empty option.
+ * - 'optionIncrement': Step to increase the option values by (works for 'i' and 's')
+ *
+ * @param string Element name
+ * @param mixed Attributes (either a string or an array)
+ * @param array Element data (label, options and data used for element creation)
+ */
+ public function __construct($name = null, $attributes = null, $data = null)
+ {
+ parent::__construct($name, $attributes, $data);
+
+ $locale =& $this->locale[$this->data['language']];
+ $backslash = false;
+ $separators = array();
+ $separator = '';
+
+ for ($i = 0, $length = strlen($this->data['format']); $i < $length; $i++) {
+ $sign = $this->data['format']{$i};
+ if ($backslash) {
+ $backslash = false;
+ $separator .= $sign;
+ } else {
+ $loadSelect = true;
+ switch ($sign) {
+ case 'D':
+ // Sunday is 0 like with 'w' in date()
+ $options = $locale['weekdays_short'];
+ break;
+ case 'l':
+ $options = $locale['weekdays_long'];
+ break;
+ case 'd':
+ $options = $this->createOptionList(1, 31);
+ break;
+ case 'M':
+ $options = $locale['months_short'];
+ array_unshift($options , '');
+ unset($options[0]);
+ break;
+ case 'm':
+ $options = $this->createOptionList(1, 12);
+ break;
+ case 'F':
+ $options = $locale['months_long'];
+ array_unshift($options , '');
+ unset($options[0]);
+ break;
+ case 'Y':
+ $options = $this->createOptionList(
+ $this->data['minYear'],
+ $this->data['maxYear'],
+ $this->data['minYear'] > $this->data['maxYear']? -1: 1
+ );
+ break;
+ case 'y':
+ $options = $this->createOptionList(
+ $this->data['minYear'],
+ $this->data['maxYear'],
+ $this->data['minYear'] > $this->data['maxYear']? -1: 1
+ );
+ array_walk($options, create_function('&$v,$k','$v = substr($v,-2);'));
+ break;
+ case 'h':
+ $options = $this->createOptionList(1, 12);
+ break;
+ case 'g':
+ $options = $this->createOptionList(1, 12);
+ array_walk($options, create_function('&$v,$k', '$v = intval($v);'));
+ break;
+ case 'H':
+ $options = $this->createOptionList(0, 23);
+ break;
+ case 'i':
+ $options = $this->createOptionList(0, 59, $this->data['optionIncrement']['i']);
+ break;
+ case 's':
+ $options = $this->createOptionList(0, 59, $this->data['optionIncrement']['s']);
+ break;
+ case 'a':
+ $options = array('am' => 'am', 'pm' => 'pm');
+ break;
+ case 'A':
+ $options = array('AM' => 'AM', 'PM' => 'PM');
+ break;
+ case 'W':
+ $options = $this->createOptionList(1, 53);
+ break;
+ case '\\':
+ $backslash = true;
+ $loadSelect = false;
+ break;
+ default:
+ $separator .= (' ' == $sign? '&nbsp;': $sign);
+ $loadSelect = false;
+ }
+
+ if ($loadSelect) {
+ if (0 < count($this)) {
+ $separators[] = $separator;
+ }
+ $separator = '';
+ // Should we add an empty option to the top of the select?
+ if (!is_array($this->data['addEmptyOption']) && $this->data['addEmptyOption'] ||
+ is_array($this->data['addEmptyOption']) && !empty($this->data['addEmptyOption'][$sign])) {
+
+ // Using '+' array operator to preserve the keys
+ if (is_array($this->data['emptyOptionText']) && !empty($this->data['emptyOptionText'][$sign])) {
+ $options = array($this->data['emptyOptionValue'] => $this->data['emptyOptionText'][$sign]) + $options;
+ } else {
+ $options = array($this->data['emptyOptionValue'] => $this->data['emptyOptionText']) + $options;
+ }
+ }
+ $this->addSelect($sign, $this->getAttributes())->loadOptions($options);
+ }
+ }
+ }
+ $separators[] = $separator . ($backslash? '\\': '');
+ $this->setSeparator($separators);
+ }
+
+ /**
+ * Creates an option list containing the numbers from the start number to the end, inclusive
+ *
+ * @param int The start number
+ * @param int The end number
+ * @param int Increment by this value
+ * @return array An array of numeric options.
+ */
+ protected function createOptionList($start, $end, $step = 1)
+ {
+ for ($i = $start, $options = array(); $start > $end? $i >= $end: $i <= $end; $i += $step) {
+ $options[$i] = sprintf('%02d', $i);
+ }
+ return $options;
+ }
+
+ /**
+ * Trims leading zeros from the (numeric) string
+ *
+ * @param string A numeric string, possibly with leading zeros
+ * @return string String with leading zeros removed
+ */
+ protected function trimLeadingZeros($str)
+ {
+ if (0 == strcmp($str, $this->data['emptyOptionValue'])) {
+ return $str;
+ }
+ $trimmed = ltrim($str, '0');
+ return strlen($trimmed)? $trimmed: '0';
+ }
+
+
+ /**
+ * Tries to convert the given value to a usable date before setting the
+ * element value
+ * @param int|string|array A timestamp, a string compatible with strtotime()
+ * or an array that fits the element names
+ */
+ public function setValue($value)
+ {
+ if (empty($value)) {
+ $value = array();
+ } elseif (is_scalar($value)) {
+ if (!is_numeric($value)) {
+ $value = strtotime($value);
+ }
+ // might be a unix epoch, then we fill all possible values
+ $arr = explode('-', date('w-j-n-Y-g-G-i-s-a-A-W', (int)$value));
+ $value = array(
+ 'D' => $arr[0],
+ 'l' => $arr[0],
+ 'd' => $arr[1],
+ 'M' => $arr[2],
+ 'm' => $arr[2],
+ 'F' => $arr[2],
+ 'Y' => $arr[3],
+ 'y' => $arr[3],
+ 'h' => $arr[4],
+ 'g' => $arr[4],
+ 'H' => $arr[5],
+ 'i' => $this->trimLeadingZeros($arr[6]),
+ 's' => $this->trimLeadingZeros($arr[7]),
+ 'a' => $arr[8],
+ 'A' => $arr[9],
+ 'W' => $this->trimLeadingZeros($arr[10])
+ );
+ } else {
+ $value = array_map(array($this, 'trimLeadingZeros'), $value);
+ }
+ return parent::setValue($value);
+ }
+
+ /**
+ * Called when the element needs to update its value from form's data sources
+ *
+ * Since the date element also accepts a timestamp as value, the default
+ * group behavior is changed.
+ */
+ protected function updateValue()
+ {
+ $name = $this->getName();
+ foreach ($this->getDataSources() as $ds) {
+ if (null !== ($value = $ds->getValue($name))) {
+ $this->setValue($value);
+ return;
+ }
+ }
+ parent::updateValue();
+ }
+
+ /**
+ * Options in different languages
+ *
+ * Note to potential translators: to avoid encoding problems please send
+ * your translations with "weird" letters encoded as HTML Unicode entities
+ *
+ * @var array
+ */
+ protected $locale = array(
+ 'en' => array (
+ 'weekdays_short'=> array ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'),
+ 'weekdays_long' => array ('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'),
+ 'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
+ 'months_long' => array ('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December')
+ ),
+ 'de' => array (
+ 'weekdays_short'=> array ('So', 'Mon', 'Di', 'Mi', 'Do', 'Fr', 'Sa'),
+ 'weekdays_long' => array ('Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'),
+ 'months_short' => array ('Jan', 'Feb', 'M&#xe4;rz', 'April', 'Mai', 'Juni', 'Juli', 'Aug', 'Sept', 'Okt', 'Nov', 'Dez'),
+ 'months_long' => array ('Januar', 'Februar', 'M&#xe4;rz', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember')
+ ),
+ 'fr' => array (
+ 'weekdays_short'=> array ('Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'),
+ 'weekdays_long' => array ('Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'),
+ 'months_short' => array ('Jan', 'F&#xe9;v', 'Mar', 'Avr', 'Mai', 'Juin', 'Juil', 'Ao&#xfb;t', 'Sep', 'Oct', 'Nov', 'D&#xe9;c'),
+ 'months_long' => array ('Janvier', 'F&#xe9;vrier', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Ao&#xfb;t', 'Septembre', 'Octobre', 'Novembre', 'D&#xe9;cembre')
+ ),
+ 'hu' => array (
+ 'weekdays_short'=> array ('V', 'H', 'K', 'Sze', 'Cs', 'P', 'Szo'),
+ 'weekdays_long' => array ('vas&#xe1;rnap', 'h&#xe9;tf&#x151;', 'kedd', 'szerda', 'cs&#xfc;t&#xf6;rt&#xf6;k', 'p&#xe9;ntek', 'szombat'),
+ 'months_short' => array ('jan', 'feb', 'm&#xe1;rc', '&#xe1;pr', 'm&#xe1;j', 'j&#xfa;n', 'j&#xfa;l', 'aug', 'szept', 'okt', 'nov', 'dec'),
+ 'months_long' => array ('janu&#xe1;r', 'febru&#xe1;r', 'm&#xe1;rcius', '&#xe1;prilis', 'm&#xe1;jus', 'j&#xfa;nius', 'j&#xfa;lius', 'augusztus', 'szeptember', 'okt&#xf3;ber', 'november', 'december')
+ ),
+ 'pl' => array (
+ 'weekdays_short'=> array ('Nie', 'Pn', 'Wt', '&#x15a;r', 'Czw', 'Pt', 'Sob'),
+ 'weekdays_long' => array ('Niedziela', 'Poniedzia&#x142;ek', 'Wtorek', '&#x15a;roda', 'Czwartek', 'Pi&#x105;tek', 'Sobota'),
+ 'months_short' => array ('Sty', 'Lut', 'Mar', 'Kwi', 'Maj', 'Cze', 'Lip', 'Sie', 'Wrz', 'Pa&#x17a;', 'Lis', 'Gru'),
+ 'months_long' => array ('Stycze&#x144;', 'Luty', 'Marzec', 'Kwiecie&#x144;', 'Maj', 'Czerwiec', 'Lipiec', 'Sierpie&#x144;', 'Wrzesie&#x144;', 'Pa&#x17a;dziernik', 'Listopad', 'Grudzie&#x144;')
+ ),
+ 'sl' => array (
+ 'weekdays_short'=> array ('Ned', 'Pon', 'Tor', 'Sre', 'Cet', 'Pet', 'Sob'),
+ 'weekdays_long' => array ('Nedelja', 'Ponedeljek', 'Torek', 'Sreda', 'Cetrtek', 'Petek', 'Sobota'),
+ 'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Avg', 'Sep', 'Okt', 'Nov', 'Dec'),
+ 'months_long' => array ('Januar', 'Februar', 'Marec', 'April', 'Maj', 'Junij', 'Julij', 'Avgust', 'September', 'Oktober', 'November', 'December')
+ ),
+ 'ru' => array (
+ 'weekdays_short'=> array ('&#x412;&#x441;', '&#x41f;&#x43d;', '&#x412;&#x442;', '&#x421;&#x440;', '&#x427;&#x442;', '&#x41f;&#x442;', '&#x421;&#x431;'),
+ 'weekdays_long' => array ('&#x412;&#x43e;&#x441;&#x43a;&#x440;&#x435;&#x441;&#x435;&#x43d;&#x44c;&#x435;', '&#x41f;&#x43e;&#x43d;&#x435;&#x434;&#x435;&#x43b;&#x44c;&#x43d;&#x438;&#x43a;', '&#x412;&#x442;&#x43e;&#x440;&#x43d;&#x438;&#x43a;', '&#x421;&#x440;&#x435;&#x434;&#x430;', '&#x427;&#x435;&#x442;&#x432;&#x435;&#x440;&#x433;', '&#x41f;&#x44f;&#x442;&#x43d;&#x438;&#x446;&#x430;', '&#x421;&#x443;&#x431;&#x431;&#x43e;&#x442;&#x430;'),
+ 'months_short' => array ('&#x42f;&#x43d;&#x432;', '&#x424;&#x435;&#x432;', '&#x41c;&#x430;&#x440;', '&#x410;&#x43f;&#x440;', '&#x41c;&#x430;&#x439;', '&#x418;&#x44e;&#x43d;', '&#x418;&#x44e;&#x43b;', '&#x410;&#x432;&#x433;', '&#x421;&#x435;&#x43d;', '&#x41e;&#x43a;&#x442;', '&#x41d;&#x43e;&#x44f;', '&#x414;&#x435;&#x43a;'),
+ 'months_long' => array ('&#x42f;&#x43d;&#x432;&#x430;&#x440;&#x44c;', '&#x424;&#x435;&#x432;&#x440;&#x430;&#x43b;&#x44c;', '&#x41c;&#x430;&#x440;&#x442;', '&#x410;&#x43f;&#x440;&#x435;&#x43b;&#x44c;', '&#x41c;&#x430;&#x439;', '&#x418;&#x44e;&#x43d;&#x44c;', '&#x418;&#x44e;&#x43b;&#x44c;', '&#x410;&#x432;&#x433;&#x443;&#x441;&#x442;', '&#x421;&#x435;&#x43d;&#x442;&#x44f;&#x431;&#x440;&#x44c;', '&#x41e;&#x43a;&#x442;&#x44f;&#x431;&#x440;&#x44c;', '&#x41d;&#x43e;&#x44f;&#x431;&#x440;&#x44c;', '&#x414;&#x435;&#x43a;&#x430;&#x431;&#x440;&#x44c;')
+ ),
+ 'es' => array (
+ 'weekdays_short'=> array ('Dom', 'Lun', 'Mar', 'Mi&#xe9;', 'Jue', 'Vie', 'S&#xe1;b'),
+ 'weekdays_long' => array ('Domingo', 'Lunes', 'Martes', 'Mi&#xe9;rcoles', 'Jueves', 'Viernes', 'S&#xe1;bado'),
+ 'months_short' => array ('Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'),
+ 'months_long' => array ('Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre')
+ ),
+ 'da' => array (
+ 'weekdays_short'=> array ('S&#xf8;n', 'Man', 'Tir', 'Ons', 'Tor', 'Fre', 'L&#xf8;r'),
+ 'weekdays_long' => array ('S&#xf8;ndag', 'Mandag', 'Tirsdag', 'Onsdag', 'Torsdag', 'Fredag', 'L&#xf8;rdag'),
+ 'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'),
+ 'months_long' => array ('Januar', 'Februar', 'Marts', 'April', 'Maj', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'December')
+ ),
+ 'is' => array (
+ 'weekdays_short'=> array ('Sun', 'M&#xe1;n', '&#xde;ri', 'Mi&#xf0;', 'Fim', 'F&#xf6;s', 'Lau'),
+ 'weekdays_long' => array ('Sunnudagur', 'M&#xe1;nudagur', '&#xde;ri&#xf0;judagur', 'Mi&#xf0;vikudagur', 'Fimmtudagur', 'F&#xf6;studagur', 'Laugardagur'),
+ 'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Ma&#xed;', 'J&#xfa;n', 'J&#xfa;l', '&#xc1;g&#xfa;', 'Sep', 'Okt', 'N&#xf3;v', 'Des'),
+ 'months_long' => array ('Jan&#xfa;ar', 'Febr&#xfa;ar', 'Mars', 'Apr&#xed;l', 'Ma&#xed;', 'J&#xfa;n&#xed;', 'J&#xfa;l&#xed;', '&#xc1;g&#xfa;st', 'September', 'Okt&#xf3;ber', 'N&#xf3;vember', 'Desember')
+ ),
+ 'it' => array (
+ 'weekdays_short'=> array ('Dom', 'Lun', 'Mar', 'Mer', 'Gio', 'Ven', 'Sab'),
+ 'weekdays_long' => array ('Domenica', 'Luned&#xec;', 'Marted&#xec;', 'Mercoled&#xec;', 'Gioved&#xec;', 'Venerd&#xec;', 'Sabato'),
+ 'months_short' => array ('Gen', 'Feb', 'Mar', 'Apr', 'Mag', 'Giu', 'Lug', 'Ago', 'Set', 'Ott', 'Nov', 'Dic'),
+ 'months_long' => array ('Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno', 'Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre')
+ ),
+ 'sk' => array (
+ 'weekdays_short'=> array ('Ned', 'Pon', 'Uto', 'Str', '&#x8a;tv', 'Pia', 'Sob'),
+ 'weekdays_long' => array ('Nede&#x17e;a', 'Pondelok', 'Utorok', 'Streda', '&#x8a;tvrtok', 'Piatok', 'Sobota'),
+ 'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'M&#xe1;j', 'J&#xfa;n', 'J&#xfa;l', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'),
+ 'months_long' => array ('Janu&#xe1;r', 'Febru&#xe1;r', 'Marec', 'Apr&#xed;l', 'M&#xe1;j', 'J&#xfa;n', 'J&#xfa;l', 'August', 'September', 'Okt&#xf3;ber', 'November', 'December')
+ ),
+ 'cs' => array (
+ 'weekdays_short'=> array ('Ne', 'Po', '&#xda;t', 'St', '&#x10c;t', 'P&#xe1;', 'So'),
+ 'weekdays_long' => array ('Ned&#x11b;le', 'Pond&#x11b;l&#xed;', '&#xda;ter&#xfd;', 'St&#x159;eda', '&#x10c;tvrtek', 'P&#xe1;tek', 'Sobota'),
+ 'months_short' => array ('Led', '&#xda;no', 'B&#x159;e', 'Dub', 'Kv&#x11b;', '&#x10c;en', '&#x10c;ec', 'Srp', 'Z&#xe1;&#x159;', '&#x158;&#xed;j', 'Lis', 'Pro'),
+ 'months_long' => array ('Leden', '&#xda;nor', 'B&#x159;ezen', 'Duben', 'Kv&#x11b;ten', '&#x10c;erven', '&#x10c;ervenec', 'Srpen', 'Z&#xe1;&#x159;&#xed;', '&#x158;&#xed;jen', 'Listopad', 'Prosinec')
+ ),
+ 'hy' => array (
+ 'weekdays_short'=> array ('&#x53f;&#x580;&#x56f;', '&#x535;&#x580;&#x56f;', '&#x535;&#x580;&#x584;', '&#x549;&#x580;&#x584;', '&#x540;&#x576;&#x563;', '&#x548;&#x582;&#x580;', '&#x547;&#x562;&#x569;'),
+ 'weekdays_long' => array ('&#x53f;&#x56b;&#x580;&#x561;&#x56f;&#x56b;', '&#x535;&#x580;&#x56f;&#x578;&#x582;&#x577;&#x561;&#x562;&#x569;&#x56b;', '&#x535;&#x580;&#x565;&#x584;&#x577;&#x561;&#x562;&#x569;&#x56b;', '&#x549;&#x578;&#x580;&#x565;&#x584;&#x577;&#x561;&#x562;&#x569;&#x56b;', '&#x540;&#x56b;&#x576;&#x563;&#x577;&#x561;&#x562;&#x569;&#x56b;', '&#x548;&#x582;&#x580;&#x562;&#x561;&#x569;', '&#x547;&#x561;&#x562;&#x561;&#x569;'),
+ 'months_short' => array ('&#x540;&#x576;&#x57e;', '&#x553;&#x57f;&#x580;', '&#x544;&#x580;&#x57f;', '&#x531;&#x57a;&#x580;', '&#x544;&#x575;&#x57d;', '&#x540;&#x576;&#x57d;', '&#x540;&#x56c;&#x57d;', '&#x555;&#x563;&#x57d;', '&#x54d;&#x57a;&#x57f;', '&#x540;&#x56f;&#x57f;', '&#x546;&#x575;&#x574;', '&#x534;&#x56f;&#x57f;'),
+ 'months_long' => array ('&#x540;&#x578;&#x582;&#x576;&#x57e;&#x561;&#x580;', '&#x553;&#x565;&#x57f;&#x580;&#x57e;&#x561;&#x580;', '&#x544;&#x561;&#x580;&#x57f;', '&#x531;&#x57a;&#x580;&#x56b;&#x56c;', '&#x544;&#x561;&#x575;&#x56b;&#x57d;', '&#x540;&#x578;&#x582;&#x576;&#x56b;&#x57d;', '&#x540;&#x578;&#x582;&#x56c;&#x56b;&#x57d;', '&#x555;&#x563;&#x578;&#x57d;&#x57f;&#x578;&#x57d;', '&#x54d;&#x565;&#x57a;&#x57f;&#x565;&#x574;&#x562;&#x565;&#x580;', '&#x540;&#x578;&#x56f;&#x57f;&#x565;&#x574;&#x562;&#x565;&#x580;', '&#x546;&#x578;&#x575;&#x565;&#x574;&#x562;&#x565;&#x580;', '&#x534;&#x565;&#x56f;&#x57f;&#x565;&#x574;&#x562;&#x565;&#x580;')
+ ),
+ 'nl' => array (
+ 'weekdays_short'=> array ('Zo', 'Ma', 'Di', 'Wo', 'Do', 'Vr', 'Za'),
+ 'weekdays_long' => array ('Zondag', 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrijdag', 'Zaterdag'),
+ 'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'),
+ 'months_long' => array ('Januari', 'Februari', 'Maart', 'April', 'Mei', 'Juni', 'Juli', 'Augustus', 'September', 'Oktober', 'November', 'December')
+ ),
+ 'et' => array (
+ 'weekdays_short'=> array ('P', 'E', 'T', 'K', 'N', 'R', 'L'),
+ 'weekdays_long' => array ('P&#xfc;hap&#xe4;ev', 'Esmasp&#xe4;ev', 'Teisip&#xe4;ev', 'Kolmap&#xe4;ev', 'Neljap&#xe4;ev', 'Reede', 'Laup&#xe4;ev'),
+ 'months_short' => array ('Jaan', 'Veebr', 'M&#xe4;rts', 'Aprill', 'Mai', 'Juuni', 'Juuli', 'Aug', 'Sept', 'Okt', 'Nov', 'Dets'),
+ 'months_long' => array ('Jaanuar', 'Veebruar', 'M&#xe4;rts', 'Aprill', 'Mai', 'Juuni', 'Juuli', 'August', 'September', 'Oktoober', 'November', 'Detsember')
+ ),
+ 'tr' => array (
+ 'weekdays_short'=> array ('Paz', 'Pzt', 'Sal', '&#xc7;ar', 'Per', 'Cum', 'Cts'),
+ 'weekdays_long' => array ('Pazar', 'Pazartesi', 'Sal&#x131;', '&#xc7;ar&#x15f;amba', 'Per&#x15f;embe', 'Cuma', 'Cumartesi'),
+ 'months_short' => array ('Ock', '&#x15e;bt', 'Mrt', 'Nsn', 'Mys', 'Hzrn', 'Tmmz', 'A&#x11f;st', 'Eyl', 'Ekm', 'Ksm', 'Arlk'),
+ 'months_long' => array ('Ocak', '&#x15e;ubat', 'Mart', 'Nisan', 'May&#x131;s', 'Haziran', 'Temmuz', 'A&#x11f;ustos', 'Eyl&#xfc;l', 'Ekim', 'Kas&#x131;m', 'Aral&#x131;k')
+ ),
+ 'no' => array (
+ 'weekdays_short'=> array ('S&#xf8;n', 'Man', 'Tir', 'Ons', 'Tor', 'Fre', 'L&#xf8;r'),
+ 'weekdays_long' => array ('S&#xf8;ndag', 'Mandag', 'Tirsdag', 'Onsdag', 'Torsdag', 'Fredag', 'L&#xf8;rdag'),
+ 'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Des'),
+ 'months_long' => array ('Januar', 'Februar', 'Mars', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Desember')
+ ),
+ 'eo' => array (
+ 'weekdays_short'=> array ('Dim', 'Lun', 'Mar', 'Mer', '&#x134;a&#x16D;', 'Ven', 'Sab'),
+ 'weekdays_long' => array ('Diman&#x109;o', 'Lundo', 'Mardo', 'Merkredo', '&#x134;a&#x16D;do', 'Vendredo', 'Sabato'),
+ 'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'A&#x16D;g', 'Sep', 'Okt', 'Nov', 'Dec'),
+ 'months_long' => array ('Januaro', 'Februaro', 'Marto', 'Aprilo', 'Majo', 'Junio', 'Julio', 'A&#x16D;gusto', 'Septembro', 'Oktobro', 'Novembro', 'Decembro')
+ ),
+ 'ua' => array (
+ 'weekdays_short'=> array ('&#x41d;&#x434;&#x43b;', '&#x41f;&#x43d;&#x434;', '&#x412;&#x442;&#x440;', '&#x421;&#x440;&#x434;', '&#x427;&#x442;&#x432;', '&#x41f;&#x442;&#x43d;', '&#x421;&#x431;&#x442;'),
+ 'weekdays_long' => array ('&#x41d;&#x435;&#x434;&#x456;&#x43b;&#x44f;', '&#x41f;&#x43e;&#x43d;&#x435;&#x434;&#x456;&#x43b;&#x43e;&#x43a;', '&#x412;&#x456;&#x432;&#x442;&#x43e;&#x440;&#x43e;&#x43a;', '&#x421;&#x435;&#x440;&#x435;&#x434;&#x430;', '&#x427;&#x435;&#x442;&#x432;&#x435;&#x440;', '&#x41f;\'&#x44f;&#x442;&#x43d;&#x438;&#x446;&#x44f;', '&#x421;&#x443;&#x431;&#x43e;&#x442;&#x430;'),
+ 'months_short' => array ('&#x421;&#x456;&#x447;', '&#x41b;&#x44e;&#x442;', '&#x411;&#x435;&#x440;', '&#x41a;&#x432;&#x456;', '&#x422;&#x440;&#x430;', '&#x427;&#x435;&#x440;', '&#x41b;&#x438;&#x43f;', '&#x421;&#x435;&#x440;', '&#x412;&#x435;&#x440;', '&#x416;&#x43e;&#x432;', '&#x41b;&#x438;&#x441;', '&#x413;&#x440;&#x443;'),
+ 'months_long' => array ('&#x421;&#x456;&#x447;&#x435;&#x43d;&#x44c;', '&#x41b;&#x44e;&#x442;&#x438;&#x439;', '&#x411;&#x435;&#x440;&#x435;&#x437;&#x435;&#x43d;&#x44c;', '&#x41a;&#x432;&#x456;&#x442;&#x435;&#x43d;&#x44c;', '&#x422;&#x440;&#x430;&#x432;&#x435;&#x43d;&#x44c;', '&#x427;&#x435;&#x440;&#x432;&#x435;&#x43d;&#x44c;', '&#x41b;&#x438;&#x43f;&#x435;&#x43d;&#x44c;', '&#x421;&#x435;&#x440;&#x43f;&#x435;&#x43d;&#x44c;', '&#x412;&#x435;&#x440;&#x435;&#x441;&#x435;&#x43d;&#x44c;', '&#x416;&#x43e;&#x432;&#x442;&#x435;&#x43d;&#x44c;', '&#x41b;&#x438;&#x441;&#x442;&#x43e;&#x43f;&#x430;&#x434;', '&#x413;&#x440;&#x443;&#x434;&#x435;&#x43d;&#x44c;')
+ ),
+ 'ro' => array (
+ 'weekdays_short'=> array ('Dum', 'Lun', 'Mar', 'Mie', 'Joi', 'Vin', 'Sam'),
+ 'weekdays_long' => array ('Duminica', 'Luni', 'Marti', 'Miercuri', 'Joi', 'Vineri', 'Sambata'),
+ 'months_short' => array ('Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun', 'Iul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
+ 'months_long' => array ('Ianuarie', 'Februarie', 'Martie', 'Aprilie', 'Mai', 'Iunie', 'Iulie', 'August', 'Septembrie', 'Octombrie', 'Noiembrie', 'Decembrie')
+ ),
+ 'he' => array (
+ 'weekdays_short'=> array ('&#1512;&#1488;&#1513;&#1493;&#1503;', '&#1513;&#1504;&#1497;', '&#1513;&#1500;&#1497;&#1513;&#1497;', '&#1512;&#1489;&#1497;&#1506;&#1497;', '&#1495;&#1502;&#1497;&#1513;&#1497;', '&#1513;&#1497;&#1513;&#1497;', '&#1513;&#1489;&#1514;'),
+ 'weekdays_long' => array ('&#1497;&#1493;&#1501; &#1512;&#1488;&#1513;&#1493;&#1503;', '&#1497;&#1493;&#1501; &#1513;&#1504;&#1497;', '&#1497;&#1493;&#1501; &#1513;&#1500;&#1497;&#1513;&#1497;', '&#1497;&#1493;&#1501; &#1512;&#1489;&#1497;&#1506;&#1497;', '&#1497;&#1493;&#1501; &#1495;&#1502;&#1497;&#1513;&#1497;', '&#1497;&#1493;&#1501; &#1513;&#1497;&#1513;&#1497;', '&#1513;&#1489;&#1514;'),
+ 'months_short' => array ('&#1497;&#1504;&#1493;&#1488;&#1512;', '&#1508;&#1489;&#1512;&#1493;&#1488;&#1512;', '&#1502;&#1512;&#1509;', '&#1488;&#1508;&#1512;&#1497;&#1500;', '&#1502;&#1488;&#1497;', '&#1497;&#1493;&#1504;&#1497;', '&#1497;&#1493;&#1500;&#1497;', '&#1488;&#1493;&#1490;&#1493;&#1505;&#1496;', '&#1505;&#1508;&#1496;&#1502;&#1489;&#1512;', '&#1488;&#1493;&#1511;&#1496;&#1493;&#1489;&#1512;', '&#1504;&#1493;&#1489;&#1502;&#1489;&#1512;', '&#1491;&#1510;&#1502;&#1489;&#1512;'),
+ 'months_long' => array ('&#1497;&#1504;&#1493;&#1488;&#1512;', '&#1508;&#1489;&#1512;&#1493;&#1488;&#1512;', '&#1502;&#1512;&#1509;', '&#1488;&#1508;&#1512;&#1497;&#1500;', '&#1502;&#1488;&#1497;', '&#1497;&#1493;&#1504;&#1497;', '&#1497;&#1493;&#1500;&#1497;', '&#1488;&#1493;&#1490;&#1493;&#1505;&#1496;', '&#1505;&#1508;&#1496;&#1502;&#1489;&#1512;', '&#1488;&#1493;&#1511;&#1496;&#1493;&#1489;&#1512;', '&#1504;&#1493;&#1489;&#1502;&#1489;&#1512;', '&#1491;&#1510;&#1502;&#1489;&#1512;')
+ ),
+ 'sv' => array (
+ 'weekdays_short'=> array ('S&#xf6;n', 'M&#xe5;n', 'Tis', 'Ons', 'Tor', 'Fre', 'L&#xf6;r'),
+ 'weekdays_long' => array ('S&#xf6;ndag', 'M&#xe5;ndag', 'Tisdag', 'Onsdag', 'Torsdag', 'Fredag', 'L&#xf6;rdag'),
+ 'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'),
+ 'months_long' => array ('Januari', 'Februari', 'Mars', 'April', 'Maj', 'Juni', 'Juli', 'Augusti', 'September', 'Oktober', 'November', 'December')
+ ),
+ 'pt' => array (
+ 'weekdays_short'=> array ('Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'S&aacute;b'),
+ 'weekdays_long' => array ('Domingo', 'Segunda-feira', 'Ter&ccedil;a-feira', 'Quarta-feira', 'Quinta-feira', 'Sexta-feira', 'S&aacute;bado'),
+ 'months_short' => array ('Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'),
+ 'months_long' => array ('Janeiro', 'Fevereiro', 'Mar&ccedil;o', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro')
+ ),
+ 'tw' => array (
+ 'weekdays_short'=> array ('&#36913;&#26085;','&#36913;&#19968;', '&#36913;&#20108;','&#36913;&#19977;', '&#36913;&#22235;','&#36913;&#20116;', '&#36913;&#20845;'),
+ 'weekdays_long' => array ('&#26143;&#26399;&#26085;', '&#26143;&#26399;&#19968;', '&#26143;&#26399;&#20108;', '&#26143;&#26399;&#19977;', '&#26143;&#26399;&#22235;', '&#26143;&#26399;&#20116;', '&#26143;&#26399;&#20845;'),
+ 'months_short' => array ('&#19968;&#26376;', '&#20108;&#26376;', '&#19977;&#26376;', '&#22235;&#26376;', '&#20116;&#26376;', '&#20845;&#26376;', '&#19971;&#26376;', '&#20843;&#26376;', '&#20061;&#26376;', '&#21313;&#26376;', '&#21313;&#19968;&#26376;', '&#21313;&#20108;&#26376;'),
+ 'months_long' => array ('&#19968;&#26376;', '&#20108;&#26376;', '&#19977;&#26376;', '&#22235;&#26376;', '&#20116;&#26376;', '&#20845;&#26376;', '&#19971;&#26376;', '&#20843;&#26376;', '&#20061;&#26376;', '&#21313;&#26376;', '&#21313;&#19968;&#26376;', '&#21313;&#20108;&#26376;')
+ ),
+ 'pt-br' => array (
+ 'weekdays_short'=> array ('Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'S&aacute;b'),
+ 'weekdays_long' => array ('Domingo', 'Segunda', 'Ter&ccedil;a', 'Quarta', 'Quinta', 'Sexta', 'S&aacute;bado'),
+ 'months_short' => array ('Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'),
+ 'months_long' => array ('Janeiro', 'Fevereiro', 'Mar&ccedil;o', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro')
+ ),
+ 'sr' => array (
+ 'weekdays_short'=> array ('&#1053;&#1077;&#1076;', '&#1055;&#1086;&#1085;', '&#1059;&#1090;&#1086;', '&#1057;&#1088;&#1077;', '&#1063;&#1077;&#1090;', '&#1055;&#1077;&#1090;', '&#1057;&#1091;&#1073;'),
+ 'weekdays_long' => array ('&#1053;&#1077;&#1076;&#1077;&#1113;&#1072;', '&#1055;&#1086;&#1085;&#1077;&#1076;&#1077;&#1113;&#1072;&#1082;', '&#1059;&#1090;&#1086;&#1088;&#1072;&#1082;', '&#1057;&#1088;&#1077;&#1076;&#1072;', '&#1063;&#1077;&#1090;&#1074;&#1088;&#1090;&#1072;&#1082;', '&#1055;&#1077;&#1090;&#1072;&#1082;', '&#1057;&#1091;&#1073;&#1086;&#1090;&#1072;'),
+ 'months_short' => array ('&#1032;&#1072;&#1085;', '&#1060;&#1077;&#1073;', '&#1052;&#1072;&#1088;', '&#1040;&#1087;&#1088;', '&#1052;&#1072;&#1112;', '&#1032;&#1091;&#1085;', '&#1032;&#1091;&#1083;', '&#1040;&#1074;&#1075;', '&#1057;&#1077;&#1087;', '&#1054;&#1082;&#1090;', '&#1053;&#1086;&#1074;', '&#1044;&#1077;&#1094;'),
+ 'months_long' => array ('&#1032;&#1072;&#1085;&#1091;&#1072;&#1088;', '&#1060;&#1077;&#1073;&#1088;&#1091;&#1072;&#1088;', '&#1052;&#1072;&#1088;&#1090;', '&#1040;&#1087;&#1088;&#1080;&#1083;', '&#1052;&#1072;&#1112;', '&#1032;&#1091;&#1085;', '&#1032;&#1091;&#1083;', '&#1040;&#1074;&#1075;&#1091;&#1089;&#1090;', '&#1057;&#1077;&#1087;&#1090;&#1077;&#1084;&#1073;&#1072;&#1088;', '&#1054;&#1082;&#1090;&#1086;&#1073;&#1072;&#1088;', '&#1053;&#1086;&#1074;&#1077;&#1084;&#1073;&#1072;&#1088;', '&#1044;&#1077;&#1094;&#1077;&#1084;&#1073;&#1072;&#1088;')
+ ),
+ 'el' => array (
+ 'weekdays_short'=> array ('&#916;&#949;&#965;', '&#932;&#961;&#943;', '&#932;&#949;&#964;', '&#928;&#941;&#956;', '&#928;&#945;&#961;', '&#931;&#940;&#946;', '&#922;&#965;&#961;'),
+ 'weekdays_long' => array ('&#916;&#949;&#965;&#964;&#941;&#961;&#945;', '&#932;&#961;&#943;&#964;&#951;', '&#932;&#949;&#964;&#940;&#961;&#964;&#951;', '&#928;&#941;&#956;&#960;&#964;&#951;', '&#928;&#945;&#961;&#945;&#963;&#954;&#949;&#965;&#942;', '&#931;&#940;&#946;&#946;&#945;&#964;&#959;', '&#922;&#965;&#961;&#953;&#945;&#954;&#942;'),
+ 'months_short' => array ('&#921;&#945;&#957;', '&#934;&#949;&#946;', '&#924;&#940;&#961;', '&#913;&#960;&#961;', '&#924;&#940;&#970;', 'Io&#973;&#957;', '&#921;&#959;&#973;&#955;', '&#913;&#973;&#947;', '&#931;&#949;&#960;', '&#927;&#954;&#964;', '&#925;&#959;&#941;', '&#916;&#949;&#954;'),
+ 'months_long' => array ('&#921;&#945;&#957;&#959;&#965;&#940;&#961;&#953;&#959;&#962;', '&#934;&#949;&#946;&#961;&#959;&#965;&#940;&#961;&#953;&#959;&#962;', '&#924;&#940;&#961;&#964;&#953;&#959;&#962;', '&#913;&#960;&#961;&#943;&#955;&#953;&#959;&#962;', '&#924;&#940;&#970;&#959;&#962;', '&#921;&#959;&#973;&#957;&#953;&#959;&#962;', 'Io&#973;&#955;&#953;&#959;&#962;', '&#913;&#973;&#947;&#959;&#965;&#963;&#964;&#959;&#962;', '&#931;&#949;&#960;&#964;&#941;&#956;&#946;&#961;&#953;&#959;&#962;', '&#927;&#954;&#964;&#974;&#946;&#961;&#953;&#959;&#962;', '&#925;&#959;&#941;&#956;&#946;&#961;&#953;&#959;&#962;', '&#916;&#949;&#954;&#941;&#956;&#946;&#961;&#953;&#959;&#962;')
+ )
+ );
+}
+?> \ No newline at end of file
diff --git a/libs/HTML/QuickForm2/Element/Input.php b/libs/HTML/QuickForm2/Element/Input.php
new file mode 100644
index 0000000000..65024a05fd
--- /dev/null
+++ b/libs/HTML/QuickForm2/Element/Input.php
@@ -0,0 +1,114 @@
+<?php
+/**
+ * Base class for <input> elements
+ *
+ * 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: Input.php 300722 2010-06-24 10:15:52Z mansion $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for simple HTML_QuickForm2 elements (not Containers)
+ */
+require_once 'HTML/QuickForm2/Element.php';
+
+/**
+ * Base class for <input> 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_Element_Input extends HTML_QuickForm2_Element
+{
+ /**
+ * 'type' attribute should not be changeable
+ * @var array
+ */
+ protected $watchedAttributes = array('id', 'name', 'type');
+
+ protected function onAttributeChange($name, $value = null)
+ {
+ if ('type' == $name) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ "Attribute 'type' is read-only"
+ );
+ }
+ parent::onAttributeChange($name, $value);
+ }
+
+ public function getType()
+ {
+ return $this->attributes['type'];
+ }
+
+ public function setValue($value)
+ {
+ $this->setAttribute('value', $value);
+ return $this;
+ }
+
+ public function getValue()
+ {
+ return $this->getAttribute('disabled')? null: $this->applyFilters($this->getAttribute('value'));
+ }
+
+ public function __toString()
+ {
+ if ($this->frozen) {
+ return $this->getFrozenHtml();
+ } else {
+ return '<input' . $this->getAttributes(true) . ' />';
+ }
+ }
+
+ /**
+ * Returns the field's value without HTML tags
+ * @return string
+ */
+ protected function getFrozenHtml()
+ {
+ $value = $this->getAttribute('value');
+ return (('' != $value)? htmlspecialchars($value, ENT_QUOTES, self::getOption('charset')): '&nbsp;') .
+ $this->getPersistentContent();
+ }
+}
+?> \ No newline at end of file
diff --git a/libs/HTML/QuickForm2/Element/InputButton.php b/libs/HTML/QuickForm2/Element/InputButton.php
new file mode 100644
index 0000000000..b3a2ef7cf9
--- /dev/null
+++ b/libs/HTML/QuickForm2/Element/InputButton.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Class for <input type="button" /> elements
+ *
+ * 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: InputButton.php 294057 2010-01-26 21:10:28Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for <input> elements
+ */
+require_once 'HTML/QuickForm2/Element/Input.php';
+
+/**
+ * Class for <input type="button" /> 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_Element_InputButton extends HTML_QuickForm2_Element_Input
+{
+ protected $attributes = array('type' => 'button');
+
+ /**
+ * Buttons can not be frozen
+ *
+ * @param bool Whether element should be frozen or editable. This
+ * parameter is ignored in case of buttons
+ * @return bool Always returns false
+ */
+ public function toggleFrozen($freeze = null)
+ {
+ return false;
+ }
+
+ /**
+ * Button elements cannot have any submit values
+ *
+ * @param mixed Element's value, this parameter is ignored
+ * @return HTML_QuickForm2_Element_InputButton
+ */
+ public function setValue($value)
+ {
+ return $this;
+ }
+
+ /**
+ * Button elements cannot have any submit values
+ *
+ * This method always returns null
+ *
+ * return string|null
+ */
+ public function getValue()
+ {
+ return null;
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Element/InputCheckable.php b/libs/HTML/QuickForm2/Element/InputCheckable.php
new file mode 100644
index 0000000000..5d9b30dff2
--- /dev/null
+++ b/libs/HTML/QuickForm2/Element/InputCheckable.php
@@ -0,0 +1,172 @@
+<?php
+/**
+ * Base class for checkboxes and radios
+ *
+ * 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: InputCheckable.php 300722 2010-06-24 10:15:52Z mansion $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for <input> elements
+ */
+require_once 'HTML/QuickForm2/Element/Input.php';
+
+/**
+ * Base class for <input> elements having 'checked' attribute (checkboxes and radios)
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Element_InputCheckable extends HTML_QuickForm2_Element_Input
+{
+ protected $persistent = true;
+
+ /**
+ * HTML to represent the element in "frozen" state
+ *
+ * Array index "checked" contains HTML for element's "checked" state,
+ * "unchecked" for not checked
+ * @var array
+ */
+ protected $frozenHtml = array(
+ 'checked' => 'On',
+ 'unchecked' => 'Off'
+ );
+
+ /**
+ * Contains options and data used for the element creation
+ * - content: Label "glued" to a checkbox or radio
+ * @var array
+ */
+ protected $data = array('content' => '');
+
+ public function __construct($name = null, $attributes = null, $data = null)
+ {
+ parent::__construct($name, $attributes, $data);
+ // "checked" attribute should be updated on changes to "value" attribute
+ // see bug #15708
+ $this->watchedAttributes[] = 'value';
+ }
+
+ protected function onAttributeChange($name, $value = null)
+ {
+ if ('value' != $name) {
+ return parent::onAttributeChange($name, $value);
+ }
+ if (null === $value) {
+ unset($this->attributes['value'], $this->attributes['checked']);
+ } else {
+ $this->attributes['value'] = $value;
+ $this->updateValue();
+ }
+ }
+
+
+ /**
+ * Sets the label to be rendered glued to the element
+ *
+ * This label is returned by {@link __toString()} method with the element's
+ * HTML. It is automatically wrapped into the <label> tag.
+ *
+ * @param string
+ * @return HTML_QuickForm2_Element_InputCheckable
+ */
+ public function setContent($content)
+ {
+ $this->data['content'] = $content;
+ return $this;
+ }
+
+ /**
+ * Returns the label that will be "glued" to element's HTML
+ *
+ * @return string
+ */
+ public function getContent()
+ {
+ return $this->data['content'];
+ }
+
+
+ public function setValue($value)
+ {
+ if ((string)$value == $this->getAttribute('value')) {
+ return $this->setAttribute('checked');
+ } else {
+ return $this->removeAttribute('checked');
+ }
+ }
+
+ public function getValue()
+ {
+ if (!empty($this->attributes['checked']) && empty($this->attributes['disabled'])) {
+ return $this->applyFilters($this->getAttribute('value'));
+ } else {
+ return null;
+ }
+ }
+
+ public function __toString()
+ {
+ if (0 == strlen($this->data['content'])) {
+ $label = '';
+ } elseif ($this->frozen) {
+ $label = $this->data['content'];
+ } else {
+ $label = '<label for="' . htmlspecialchars(
+ $this->getId(), ENT_QUOTES, self::getOption('charset')
+ ) . '">' . $this->data['content'] . '</label>';
+ }
+ return parent::__toString() . $label;
+ }
+
+ public function getFrozenHtml()
+ {
+ if ($this->getAttribute('checked')) {
+ return $this->frozenHtml['checked'] . $this->getPersistentContent();
+ } else {
+ return $this->frozenHtml['unchecked'];
+ }
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Element/InputCheckbox.php b/libs/HTML/QuickForm2/Element/InputCheckbox.php
new file mode 100644
index 0000000000..7e2ab8e065
--- /dev/null
+++ b/libs/HTML/QuickForm2/Element/InputCheckbox.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Class for <input type="checkbox" /> elements
+ *
+ * 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: InputCheckbox.php 294057 2010-01-26 21:10:28Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for checkboxes and radios
+ */
+require_once 'HTML/QuickForm2/Element/InputCheckable.php';
+
+/**
+ * Class for <input type="checkbox" /> 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_Element_InputCheckbox extends HTML_QuickForm2_Element_InputCheckable
+{
+ protected $attributes = array('type' => 'checkbox');
+
+ protected $frozenHtml = array(
+ 'checked' => '<tt>[x]</tt>',
+ 'unchecked' => '<tt>[&nbsp;]</tt>'
+ );
+
+ public function __construct($name = null, $attributes = null, array $data = array())
+ {
+ parent::__construct($name, $attributes, $data);
+ if (!$this->getAttribute('value')) {
+ $this->setAttribute('value', 1);
+ }
+ }
+
+ protected function updateValue()
+ {
+ $name = $this->getName();
+ if ('[]' == substr($name, -2)) {
+ $name = substr($name, 0, -2);
+ }
+ foreach ($this->getDataSources() as $ds) {
+ if (null !== ($value = $ds->getValue($name))
+ || $ds instanceof HTML_QuickForm2_DataSource_Submit
+ ) {
+ if (!is_array($value)) {
+ $this->setValue($value);
+ } elseif (in_array($this->getAttribute('value'), array_map('strval', $value), true)) {
+ $this->setAttribute('checked');
+ } else {
+ $this->removeAttribute('checked');
+ }
+ return;
+ }
+ }
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Element/InputFile.php b/libs/HTML/QuickForm2/Element/InputFile.php
new file mode 100644
index 0000000000..8fdf99aa55
--- /dev/null
+++ b/libs/HTML/QuickForm2/Element/InputFile.php
@@ -0,0 +1,268 @@
+<?php
+/**
+ * Class for <input type="file" /> elements
+ *
+ * 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: InputFile.php 300722 2010-06-24 10:15:52Z mansion $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for <input> elements
+ */
+require_once 'HTML/QuickForm2/Element/Input.php';
+
+/**
+ * Class for <input type="file" /> 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_Element_InputFile extends HTML_QuickForm2_Element_Input
+{
+ /**
+ * Default language for error messages
+ */
+ const DEFAULT_LANGUAGE = 'en';
+
+ /**
+ * Localized error messages for PHP's file upload errors
+ * @var array
+ */
+ protected $errorMessages = array(
+ 'en' => array(
+ UPLOAD_ERR_INI_SIZE => 'The uploaded file exceeds size permitted by PHP configuration (%d bytes)',
+ UPLOAD_ERR_FORM_SIZE => 'The uploaded file exceeds the MAX_FILE_SIZE directive in HTML form (%d bytes)',
+ UPLOAD_ERR_PARTIAL => 'The file was only partially uploaded',
+ UPLOAD_ERR_NO_TMP_DIR => 'Server error: temporary directory is missing',
+ UPLOAD_ERR_CANT_WRITE => 'Server error: failed to write the file to disk',
+ UPLOAD_ERR_EXTENSION => 'File upload was stopped by extension'
+ ),
+ 'fr' => array(
+ UPLOAD_ERR_INI_SIZE => 'Le fichier envoy&eacute; exc&egrave;de la taille autoris&eacute;e par la configuration de PHP (%d octets)',
+ UPLOAD_ERR_FORM_SIZE => 'Le fichier envoy&eacute; exc&egrave;de la taille de MAX_FILE_SIZE sp&eacute;cifi&eacute;e dans le formulaire HTML (%d octets)',
+ UPLOAD_ERR_PARTIAL => 'Le fichier n\'a &eacute;t&eacute; que partiellement t&eacute;l&eacute;charg&eacute;',
+ UPLOAD_ERR_NO_TMP_DIR => 'Erreur serveur: le r&eacute;pertoire temporaire est manquant',
+ UPLOAD_ERR_CANT_WRITE => 'Erreur serveur: &eacute;chec de l\'&eacute;criture du fichier sur le disque',
+ UPLOAD_ERR_EXTENSION => 'L\'envoi de fichier est arr&ecirc;t&eacute; par l\'extension'
+ ),
+ 'ru' => array(
+ UPLOAD_ERR_INI_SIZE => '&#x420;&#x430;&#x437;&#x43c;&#x435;&#x440; &#x437;&#x430;&#x433;&#x440;&#x443;&#x436;&#x435;&#x43d;&#x43d;&#x43e;&#x433;&#x43e; &#x444;&#x430;&#x439;&#x43b;&#x430; &#x43f;&#x440;&#x435;&#x432;&#x43e;&#x441;&#x445;&#x43e;&#x434;&#x438;&#x442; &#x43c;&#x430;&#x43a;&#x441;&#x438;&#x43c;&#x430;&#x43b;&#x44c;&#x43d;&#x43e; &#x440;&#x430;&#x437;&#x440;&#x435;&#x448;&#x451;&#x43d;&#x43d;&#x44b;&#x439; &#x43d;&#x430;&#x441;&#x442;&#x440;&#x43e;&#x439;&#x43a;&#x430;&#x43c;&#x438; PHP (%d &#x431;&#x430;&#x439;&#x442;)',
+ UPLOAD_ERR_FORM_SIZE => '&#x420;&#x430;&#x437;&#x43c;&#x435;&#x440; &#x437;&#x430;&#x433;&#x440;&#x443;&#x436;&#x435;&#x43d;&#x43d;&#x43e;&#x433;&#x43e; &#x444;&#x430;&#x439;&#x43b;&#x430; &#x43f;&#x440;&#x435;&#x432;&#x43e;&#x441;&#x445;&#x43e;&#x434;&#x438;&#x442; &#x434;&#x438;&#x440;&#x435;&#x43a;&#x442;&#x438;&#x432;&#x443; MAX_FILE_SIZE, &#x443;&#x43a;&#x430;&#x437;&#x430;&#x43d;&#x43d;&#x443;&#x44e; &#x432; &#x444;&#x43e;&#x440;&#x43c;&#x435; (%d &#x431;&#x430;&#x439;&#x442;)',
+ UPLOAD_ERR_PARTIAL => '&#x424;&#x430;&#x439;&#x43b; &#x431;&#x44b;&#x43b; &#x437;&#x430;&#x433;&#x440;&#x443;&#x436;&#x435;&#x43d; &#x43d;&#x435; &#x43f;&#x43e;&#x43b;&#x43d;&#x43e;&#x441;&#x442;&#x44c;&#x44e;',
+ UPLOAD_ERR_NO_TMP_DIR => '&#x41e;&#x448;&#x438;&#x431;&#x43a;&#x430; &#x43d;&#x430; &#x441;&#x435;&#x440;&#x432;&#x435;&#x440;&#x435;: &#x43e;&#x442;&#x441;&#x443;&#x442;&#x441;&#x442;&#x432;&#x443;&#x435;&#x442; &#x43a;&#x430;&#x442;&#x430;&#x43b;&#x43e;&#x433; &#x434;&#x43b;&#x44f; &#x432;&#x440;&#x435;&#x43c;&#x435;&#x43d;&#x43d;&#x44b;&#x445; &#x444;&#x430;&#x439;&#x43b;&#x43e;&#x432;',
+ UPLOAD_ERR_CANT_WRITE => '&#x41e;&#x448;&#x438;&#x431;&#x43a;&#x430; &#x43d;&#x430; &#x441;&#x435;&#x440;&#x432;&#x435;&#x440;&#x435;: &#x43d;&#x435; &#x443;&#x434;&#x430;&#x43b;&#x43e;&#x441;&#x44c; &#x437;&#x430;&#x43f;&#x438;&#x441;&#x430;&#x442;&#x44c; &#x444;&#x430;&#x439;&#x43b; &#x43d;&#x430; &#x434;&#x438;&#x441;&#x43a;',
+ UPLOAD_ERR_EXTENSION => '&#x417;&#x430;&#x433;&#x440;&#x443;&#x437;&#x43a;&#x430; &#x444;&#x430;&#x439;&#x43b;&#x430; &#x431;&#x44b;&#x43b;&#x430; &#x43e;&#x441;&#x442;&#x430;&#x43d;&#x43e;&#x432;&#x43b;&#x435;&#x43d;&#x430; &#x440;&#x430;&#x441;&#x448;&#x438;&#x440;&#x435;&#x43d;&#x438;&#x435;&#x43c;'
+ )
+ );
+
+ /**
+ * Language to display error messages in
+ * @var string
+ */
+ protected $language;
+
+ /**
+ * Information on uploaded file, from submit data source
+ * @var array
+ */
+ protected $value = null;
+
+ protected $attributes = array('type' => 'file');
+
+
+ /**
+ * Class constructor
+ *
+ * Possible keys in $data array are:
+ * - 'language': language to display error messages in, it should either be
+ * already available in the class or provided in 'errorMessages'
+ * - 'errorMessages': an array of error messages with the following format
+ * <pre>
+ * 'language code 1' => array(
+ * UPLOAD_ERR_... => 'message',
+ * ...
+ * UPLOAD_ERR_... => 'message'
+ * ),
+ * ...
+ * 'language code N' => array(
+ * ...
+ * )
+ * </pre>
+ * Note that error messages for UPLOAD_ERR_INI_SIZE and UPLOAD_ERR_FORM_SIZE
+ * may contain '%d' placeholders that will be automatically replaced by the
+ * appropriate size limits. Note also that you don't need to provide messages
+ * for every possible error code in the arrays, you may e.g. override just
+ * one error message for a particular language.
+ *
+ * @param string Element name
+ * @param mixed Attributes (either a string or an array)
+ * @param array Data used to set up error messages for PHP's file
+ * upload errors.
+ */
+ public function __construct($name = null, $attributes = null, array $data = array())
+ {
+ if (isset($data['errorMessages'])) {
+ // neither array_merge() nor array_merge_recursive will do
+ foreach ($data['errorMessages'] as $lang => $ary) {
+ foreach ($ary as $code => $message) {
+ $this->errorMessages[$lang][$code] = $message;
+ }
+ }
+ unset($data['errorMessages']);
+ }
+ if (!isset($data['language'])) {
+ $this->language = self::DEFAULT_LANGUAGE;
+ } else {
+ $this->language = isset($this->errorMessages[$data['language']])?
+ $data['language']: self::DEFAULT_LANGUAGE;
+ unset($data['language']);
+ }
+ parent::__construct($name, $attributes, $data);
+ }
+
+
+ /**
+ * File upload elements cannot be frozen
+ *
+ * To properly "freeze" a file upload element one has to store the uploaded
+ * file somewhere and store the file info in session. This is way outside
+ * the scope of this class.
+ *
+ * @param bool Whether element should be frozen or editable. This
+ * parameter is ignored in case of file uploads
+ * @return bool Always returns false
+ */
+ public function toggleFrozen($freeze = null)
+ {
+ return false;
+ }
+
+ /**
+ * Returns the information on uploaded file
+ *
+ * @return array|null
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ /**
+ * File upload's value cannot be set here
+ *
+ * @param mixed Value for file element, this parameter is ignored
+ * @return HTML_QuickForm2_Element_InputFile
+ */
+ public function setValue($value)
+ {
+ return $this;
+ }
+
+ protected function updateValue()
+ {
+ foreach ($this->getDataSources() as $ds) {
+ if ($ds instanceof HTML_QuickForm2_DataSource_Submit) {
+ $value = $ds->getUpload($this->getName());
+ if (null !== $value) {
+ $this->value = $value;
+ return;
+ }
+ }
+ }
+ $this->value = null;
+ }
+
+ /**
+ * Performs the server-side validation
+ *
+ * Before the Rules added to the element kick in, the element checks the
+ * error code added to the $_FILES array by PHP. If the code isn't
+ * UPLOAD_ERR_OK or UPLOAD_ERR_NO_FILE then a built-in error message will be
+ * displayed and no further validation will take place.
+ *
+ * @return boolean Whether the element is valid
+ */
+ protected function validate()
+ {
+ if (strlen($this->error)) {
+ return false;
+ }
+ if (isset($this->value['error']) &&
+ !in_array($this->value['error'], array(UPLOAD_ERR_OK, UPLOAD_ERR_NO_FILE)))
+ {
+ if (isset($this->errorMessages[$this->language][$this->value['error']])) {
+ $errorMessage = $this->errorMessages[$this->language][$this->value['error']];
+ } else {
+ $errorMessage = $this->errorMessages[self::DEFAULT_LANGUAGE][$this->value['error']];
+ }
+ if (UPLOAD_ERR_INI_SIZE == $this->value['error']) {
+ $iniSize = ini_get('upload_max_filesize');
+ $size = intval($iniSize);
+ switch (strtoupper(substr($iniSize, -1))) {
+ case 'G': $size *= 1024;
+ case 'M': $size *= 1024;
+ case 'K': $size *= 1024;
+ }
+
+ } elseif (UPLOAD_ERR_FORM_SIZE == $this->value['error']) {
+ foreach ($this->getDataSources() as $ds) {
+ if ($ds instanceof HTML_QuickForm2_DataSource_Submit) {
+ $size = intval($ds->getValue('MAX_FILE_SIZE'));
+ break;
+ }
+ }
+ }
+ $this->error = isset($size)? sprintf($errorMessage, $size): $errorMessage;
+ return false;
+ }
+ return parent::validate();
+ }
+
+ public function addFilter($callback, array $options = null, $recursive = true)
+ {
+ throw new HTML_QuickForm2_Exception(
+ 'InputFile elements do not support filters'
+ );
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Element/InputHidden.php b/libs/HTML/QuickForm2/Element/InputHidden.php
new file mode 100644
index 0000000000..578af01fa3
--- /dev/null
+++ b/libs/HTML/QuickForm2/Element/InputHidden.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Class for <input type="hidden" /> elements
+ *
+ * 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: InputHidden.php 294057 2010-01-26 21:10:28Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for <input> elements
+ */
+require_once 'HTML/QuickForm2/Element/Input.php';
+
+/**
+ * Class for <input type="hidden" /> 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_Element_InputHidden extends HTML_QuickForm2_Element_Input
+{
+ protected $attributes = array('type' => 'hidden');
+
+ /**
+ * Hidden elements can not be frozen
+ *
+ * @param bool Whether element should be frozen or editable. This
+ * parameter is ignored in case of hidden elements
+ * @return bool Always returns false
+ */
+ public function toggleFrozen($freeze = null)
+ {
+ return false;
+ }
+
+ public function render(HTML_QuickForm2_Renderer $renderer)
+ {
+ $renderer->renderHidden($this);
+ return $renderer;
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Element/InputImage.php b/libs/HTML/QuickForm2/Element/InputImage.php
new file mode 100644
index 0000000000..369bd49ee4
--- /dev/null
+++ b/libs/HTML/QuickForm2/Element/InputImage.php
@@ -0,0 +1,162 @@
+<?php
+/**
+ * Class for <input type="image" /> elements
+ *
+ * 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: InputImage.php 300722 2010-06-24 10:15:52Z mansion $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for <input> elements
+ */
+require_once 'HTML/QuickForm2/Element/Input.php';
+
+/**
+ * Class for <input type="image" /> 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_Element_InputImage extends HTML_QuickForm2_Element_Input
+{
+ protected $attributes = array('type' => 'image');
+
+ /**
+ * Coordinates of user click within the image, array contains keys 'x' and 'y'
+ * @var array
+ */
+ protected $coordinates = null;
+
+ /**
+ * Image buttons can not be frozen
+ *
+ * @param bool Whether element should be frozen or editable. This
+ * parameter is ignored in case of image elements
+ * @return bool Always returns false
+ */
+ public function toggleFrozen($freeze = null)
+ {
+ return false;
+ }
+
+ /**
+ * Image button's value cannot be set via this method
+ *
+ * @param mixed Element's value, this parameter is ignored
+ * @return HTML_QuickForm2_Element_InputImage
+ */
+ public function setValue($value)
+ {
+ return $this;
+ }
+
+ /**
+ * Returns the element's value
+ *
+ * The value is only returned if the form was actually submitted and this
+ * image button was clicked. Returns null in all other cases.
+ *
+ * @return array|null An array with keys 'x' and 'y' containing the
+ * coordinates of user click if the image was clicked,
+ * null otherwise
+ */
+ public function getValue()
+ {
+ return $this->getAttribute('disabled')? null: $this->applyFilters($this->coordinates);
+ }
+
+ /**
+ * Returns the HTML representation of the element
+ *
+ * The method changes the element's name to foo[bar][] if it was foo[bar]
+ * originally. If it is not done, then one of the click coordinates will be
+ * lost, see {@link http://bugs.php.net/bug.php?id=745}
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ if (false === strpos($this->attributes['name'], '[') ||
+ '[]' == substr($this->attributes['name'], -2))
+ {
+ return parent::__toString();
+ } else {
+ $this->attributes['name'] .= '[]';
+ $html = parent::__toString();
+ $this->attributes['name'] = substr($this->attributes['name'], 0, -2);
+ return $html;
+ }
+ }
+
+ protected function updateValue()
+ {
+ foreach ($this->getDataSources() as $ds) {
+ if ($ds instanceof HTML_QuickForm2_DataSource_Submit) {
+ $name = $this->getName();
+ if (false === strpos($name, '[') &&
+ null !== ($value = $ds->getValue($name . '_x')))
+ {
+ $this->coordinates = array(
+ 'x' => $value,
+ 'y' => $ds->getValue($name . '_y')
+ );
+ return;
+
+ } elseif (false !== strpos($name, '[')) {
+ if ('[]' == substr($name, -2)) {
+ $name = substr($name, 0, -2);
+ }
+ if (null !== ($value = $ds->getValue($name))) {
+ $this->coordinates = array(
+ 'x' => $value[0],
+ 'y' => $value[1]
+ );
+ return;
+ }
+ }
+ }
+ }
+ $this->coordinates = null;
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Element/InputPassword.php b/libs/HTML/QuickForm2/Element/InputPassword.php
new file mode 100644
index 0000000000..12a975f240
--- /dev/null
+++ b/libs/HTML/QuickForm2/Element/InputPassword.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Class for <input type="password" /> elements
+ *
+ * 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: InputPassword.php 294057 2010-01-26 21:10:28Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for <input> elements
+ */
+require_once 'HTML/QuickForm2/Element/Input.php';
+
+/**
+ * Class for <input type="password" /> 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_Element_InputPassword extends HTML_QuickForm2_Element_Input
+{
+ protected $attributes = array('type' => 'password');
+
+ protected function getFrozenHtml()
+ {
+ $value = $this->getValue();
+ return (('' != $value)? '********': '&nbsp;') .
+ $this->getPersistentContent();
+ }
+}
+?> \ No newline at end of file
diff --git a/libs/HTML/QuickForm2/Element/InputRadio.php b/libs/HTML/QuickForm2/Element/InputRadio.php
new file mode 100644
index 0000000000..a005c71513
--- /dev/null
+++ b/libs/HTML/QuickForm2/Element/InputRadio.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Class for <input type="radio" /> elements
+ *
+ * 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: InputRadio.php 294057 2010-01-26 21:10:28Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for checkboxes and radios
+ */
+require_once 'HTML/QuickForm2/Element/InputCheckable.php';
+
+/**
+ * Class for <input type="radio" /> 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_Element_InputRadio extends HTML_QuickForm2_Element_InputCheckable
+{
+ protected $attributes = array('type' => 'radio');
+
+ protected $frozenHtml = array(
+ 'checked' => '<tt>(x)</tt>',
+ 'unchecked' => '<tt>(&nbsp;)</tt>'
+ );
+}
+?>
diff --git a/libs/HTML/QuickForm2/Element/InputReset.php b/libs/HTML/QuickForm2/Element/InputReset.php
new file mode 100644
index 0000000000..b6dd914582
--- /dev/null
+++ b/libs/HTML/QuickForm2/Element/InputReset.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Class for <input type="reset" /> elements
+ *
+ * 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: InputReset.php 294057 2010-01-26 21:10:28Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for <input> elements
+ */
+require_once 'HTML/QuickForm2/Element/Input.php';
+
+/**
+ * Class for <input type="reset" /> 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_Element_InputReset extends HTML_QuickForm2_Element_Input
+{
+ protected $attributes = array('type' => 'reset');
+
+ /**
+ * Reset buttons can not be frozen
+ *
+ * @param bool Whether element should be frozen or editable. This
+ * parameter is ignored in case of reset buttons
+ * @return bool Always returns false
+ */
+ public function toggleFrozen($freeze = null)
+ {
+ return false;
+ }
+
+ /**
+ * Reset elements cannot have any submit values
+ *
+ * @param mixed Element's value, this parameter is ignored
+ * @return HTML_QuickForm2_Element_InputReset
+ */
+ public function setValue($value)
+ {
+ return $this;
+ }
+
+ /**
+ * Reset elements cannot have any submit values
+ *
+ * This method always returns null
+ *
+ * @return string|null
+ */
+ public function getValue()
+ {
+ return null;
+ }
+}
+?> \ No newline at end of file
diff --git a/libs/HTML/QuickForm2/Element/InputSubmit.php b/libs/HTML/QuickForm2/Element/InputSubmit.php
new file mode 100644
index 0000000000..c538ad0a68
--- /dev/null
+++ b/libs/HTML/QuickForm2/Element/InputSubmit.php
@@ -0,0 +1,120 @@
+<?php
+/**
+ * Class for <input type="submit" /> elements
+ *
+ * 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: InputSubmit.php 300722 2010-06-24 10:15:52Z mansion $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for <input> elements
+ */
+require_once 'HTML/QuickForm2/Element/Input.php';
+
+/**
+ * Class for <input type="submit" /> 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_Element_InputSubmit extends HTML_QuickForm2_Element_Input
+{
+ protected $attributes = array('type' => 'submit');
+
+ /**
+ * Element's submit value
+ * @var string
+ */
+ protected $submitValue = null;
+
+
+ /**
+ * Submit buttons can not be frozen
+ *
+ * @param bool Whether element should be frozen or editable. This
+ * parameter is ignored in case of submit elements
+ * @return bool Always returns false
+ */
+ public function toggleFrozen($freeze = null)
+ {
+ return false;
+ }
+
+ /**
+ * Submit's value cannot be set via this method
+ *
+ * @param mixed Element's value, this parameter is ignored
+ * @return HTML_QuickForm2_Element_InputSubmit
+ */
+ public function setValue($value)
+ {
+ return $this;
+ }
+
+ /**
+ * Returns the element's value
+ *
+ * The value is only returned if the form was actually submitted and this
+ * submit button was clicked. Returns null in all other cases
+ *
+ * @return string|null
+ */
+ public function getValue()
+ {
+ return $this->getAttribute('disabled')? null: $this->applyFilters($this->submitValue);
+ }
+
+ protected function updateValue()
+ {
+ foreach ($this->getDataSources() as $ds) {
+ if ($ds instanceof HTML_QuickForm2_DataSource_Submit &&
+ null !== ($value = $ds->getValue($this->getName())))
+ {
+ $this->submitValue = $value;
+ return;
+ }
+ }
+ $this->submitValue = null;
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Element/InputText.php b/libs/HTML/QuickForm2/Element/InputText.php
new file mode 100644
index 0000000000..5b9e62ebf9
--- /dev/null
+++ b/libs/HTML/QuickForm2/Element/InputText.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Class for <input type="text" /> elements
+ *
+ * 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: InputText.php 294057 2010-01-26 21:10:28Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for <input> elements
+ */
+require_once 'HTML/QuickForm2/Element/Input.php';
+
+/**
+ * Class for <input type="text" /> 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_Element_InputText extends HTML_QuickForm2_Element_Input
+{
+ protected $attributes = array('type' => 'text');
+}
+?>
diff --git a/libs/HTML/QuickForm2/Element/Select.php b/libs/HTML/QuickForm2/Element/Select.php
new file mode 100644
index 0000000000..ec7d596194
--- /dev/null
+++ b/libs/HTML/QuickForm2/Element/Select.php
@@ -0,0 +1,575 @@
+<?php
+/**
+ * Classes for <select> elements
+ *
+ * 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: Select.php 300722 2010-06-24 10:15:52Z mansion $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for simple HTML_QuickForm2 elements
+ */
+require_once 'HTML/QuickForm2/Element.php';
+
+
+/**
+ * Collection of <option>s and <optgroup>s
+ *
+ * This class handles the output of <option> tags. The class is not intended to
+ * be used directly.
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Element_Select_OptionContainer extends HTML_Common2
+ implements IteratorAggregate, Countable
+{
+ /**
+ * List of options and optgroups in this container
+ *
+ * Options are stored as arrays (for performance reasons), optgroups as
+ * instances of Optgroup class.
+ *
+ * @var array
+ */
+ protected $options = array();
+
+ /**
+ * Reference to parent <select>'s values
+ * @var array
+ */
+ protected $values;
+
+ /**
+ * Reference to parent <select>'s possible values
+ * @var array
+ */
+ protected $possibleValues;
+
+
+ /**
+ * Class constructor
+ *
+ * @param array Reference to values of parent <select> element
+ * @param array Reference to possible values of parent <select> element
+ */
+ public function __construct(&$values, &$possibleValues)
+ {
+ $this->values =& $values;
+ $this->possibleValues =& $possibleValues;
+ }
+
+ /**
+ * Adds a new option
+ *
+ * Please note that if you pass 'selected' attribute in the $attributes
+ * parameter then this option's value will be added to <select>'s values.
+ *
+ * @param string Option text
+ * @param string 'value' attribute for <option> tag
+ * @param mixed Additional attributes for <option> tag (either as a
+ * string or as an associative array)
+ */
+ public function addOption($text, $value, $attributes = null)
+ {
+ if (null === $attributes) {
+ $attributes = array('value' => (string)$value);
+ } else {
+ $attributes = self::prepareAttributes($attributes);
+ if (isset($attributes['selected'])) {
+ // the 'selected' attribute will be set in __toString()
+ unset($attributes['selected']);
+ if (!in_array($value, $this->values)) {
+ $this->values[] = $value;
+ }
+ }
+ $attributes['value'] = (string)$value;
+ }
+ if (!isset($attributes['disabled'])) {
+ $this->possibleValues[(string)$value] = true;
+ }
+ $this->options[] = array('text' => $text, 'attr' => $attributes);
+ }
+
+ /**
+ * Adds a new optgroup
+ *
+ * @param string 'label' attribute for optgroup tag
+ * @param mixed Additional attributes for <optgroup> tag (either as a
+ * string or as an associative array)
+ * @return HTML_QuickForm2_Element_Select_Optgroup
+ */
+ public function addOptgroup($label, $attributes = null)
+ {
+ $optgroup = new HTML_QuickForm2_Element_Select_Optgroup(
+ $this->values, $this->possibleValues,
+ $label, $attributes
+ );
+ $this->options[] = $optgroup;
+ return $optgroup;
+ }
+
+ /**
+ * Returns an array of contained options
+ *
+ * @return array
+ */
+ public function getOptions()
+ {
+ return $this->options;
+ }
+
+ public function __toString()
+ {
+ $indentLvl = $this->getIndentLevel();
+ $indent = $this->getIndent() . self::getOption('indent');
+ $linebreak = self::getOption('linebreak');
+ $html = '';
+ $strValues = array_map('strval', $this->values);
+ foreach ($this->options as $option) {
+ if (is_array($option)) {
+ if (in_array($option['attr']['value'], $strValues, true)) {
+ $option['attr']['selected'] = 'selected';
+ }
+ $html .= $indent . '<option' .
+ self::getAttributesString($option['attr']) .
+ '>' . $option['text'] . '</option>' . $linebreak;
+ } elseif ($option instanceof HTML_QuickForm2_Element_Select_OptionContainer) {
+ $option->setIndentLevel($indentLvl + 1);
+ $html .= $option->__toString();
+ }
+ }
+ return $html;
+ }
+
+ /**
+ * Returns an iterator over contained elements
+ *
+ * @return HTML_QuickForm2_Element_Select_OptionIterator
+ */
+ public function getIterator()
+ {
+ return new HTML_QuickForm2_Element_Select_OptionIterator($this->options);
+ }
+
+ /**
+ * Returns a recursive iterator over contained elements
+ *
+ * @return RecursiveIteratorIterator
+ */
+ public function getRecursiveIterator()
+ {
+ return new RecursiveIteratorIterator(
+ new HTML_QuickForm2_Element_Select_OptionIterator($this->options),
+ RecursiveIteratorIterator::SELF_FIRST
+ );
+ }
+
+ /**
+ * Returns the number of options in the container
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return count($this->options);
+ }
+}
+
+
+/**
+ * Class representing an <optgroup> tag
+ *
+ * Do not instantiate this class yourself, use
+ * {@link HTML_QuickForm2_Element_Select::addOptgroup()} method
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Element_Select_Optgroup
+ extends HTML_QuickForm2_Element_Select_OptionContainer
+{
+ /**
+ * Class constructor
+ *
+ * @param array Reference to values of parent <select> element
+ * @param array Reference to possible values of parent <select> element
+ * @param string 'label' attribute for optgroup tag
+ * @param mixed Additional attributes for <optgroup> tag (either as a
+ * string or as an associative array)
+ */
+ public function __construct(&$values, &$possibleValues, $label, $attributes = null)
+ {
+ parent::__construct($values, $possibleValues);
+ $this->setAttributes($attributes);
+ $this->attributes['label'] = (string)$label;
+ }
+
+ public function __toString()
+ {
+ $indent = $this->getIndent();
+ $linebreak = self::getOption('linebreak');
+ return $indent . '<optgroup' . $this->getAttributes(true) . '>' .
+ $linebreak . parent::__toString() . $indent . '</optgroup>' . $linebreak;
+ }
+}
+
+/**
+ * Implements a recursive iterator for options arrays
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Element_Select_OptionIterator extends RecursiveArrayIterator
+ implements RecursiveIterator
+{
+ public function hasChildren()
+ {
+ return $this->current() instanceof HTML_QuickForm2_Element_Select_OptionContainer;
+ }
+
+ public function getChildren()
+ {
+ return new HTML_QuickForm2_Element_Select_OptionIterator(
+ $this->current()->getOptions()
+ );
+ }
+}
+
+
+/**
+ * Class representing a <select> element
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Element_Select extends HTML_QuickForm2_Element
+{
+ protected $persistent = true;
+
+ /**
+ * Values for the select element (i.e. values of the selected options)
+ * @var array
+ */
+ protected $values = array();
+
+ /**
+ * Possible values for select elements
+ *
+ * A value is considered possible if it is present as a value attribute of
+ * some option and that option is not disabled.
+ * @var array
+ */
+ protected $possibleValues = array();
+
+
+ /**
+ * Object containing options for the <select> element
+ * @var HTML_QuickForm2_Element_Select_OptionContainer
+ */
+ protected $optionContainer;
+
+ /**
+ * Enable intrinsic validation by default
+ * @var array
+ */
+ protected $data = array('intrinsic_validation' => true);
+
+ /**
+ * Class constructor
+ *
+ * Select element can understand the following keys in $data parameter:
+ * - 'options': data to populate element's options with. Passed to
+ * {@link loadOptions()} method.
+ * - 'intrinsic_validation': setting this to false will disable
+ * that validation, {@link getValue()} will then return all submit
+ * values, not just those corresponding to options present in the
+ * element. May be useful in AJAX scenarios.
+ *
+ * @param string Element name
+ * @param mixed Attributes (either a string or an array)
+ * @param array Additional element data
+ * @throws HTML_QuickForm2_InvalidArgumentException if junk is given in $options
+ */
+ public function __construct($name = null, $attributes = null, array $data = array())
+ {
+ $options = isset($data['options'])? $data['options']: array();
+ unset($data['options']);
+ parent::__construct($name, $attributes, $data);
+ $this->loadOptions($options);
+ }
+
+ public function getType()
+ {
+ return 'select';
+ }
+
+ public function __toString()
+ {
+ if ($this->frozen) {
+ return $this->getFrozenHtml();
+ } else {
+ if (empty($this->attributes['multiple'])) {
+ $attrString = $this->getAttributes(true);
+ } else {
+ $this->attributes['name'] .= '[]';
+ $attrString = $this->getAttributes(true);
+ $this->attributes['name'] = substr($this->attributes['name'], 0, -2);
+ }
+ $indent = $this->getIndent();
+ return $indent . '<select' . $attrString . '>' .
+ self::getOption('linebreak') .
+ $this->optionContainer->__toString() .
+ $indent . '</select>';
+ }
+ }
+
+ protected function getFrozenHtml()
+ {
+ if (null === ($value = $this->getValue())) {
+ return '&nbsp;';
+ }
+ $valueHash = is_array($value)? array_flip($value): array($value => true);
+ $options = array();
+ foreach ($this->optionContainer->getRecursiveIterator() as $child) {
+ if (is_array($child) && isset($valueHash[$child['attr']['value']]) &&
+ empty($child['attr']['disabled']))
+ {
+ $options[] = $child['text'];
+ }
+ }
+
+ $html = implode('<br />', $options);
+ if ($this->persistent) {
+ $name = $this->attributes['name'] .
+ (empty($this->attributes['multiple'])? '': '[]');
+ // Only use id attribute if doing single hidden input
+ $idAttr = (1 == count($valueHash))? array('id' => $this->getId()): array();
+ foreach ($valueHash as $key => $item) {
+ $html .= '<input type="hidden"' . self::getAttributesString(array(
+ 'name' => $name,
+ 'value' => $key
+ ) + $idAttr) . ' />';
+ }
+ }
+ return $html;
+ }
+
+ /**
+ * Returns the value of the <select> element
+ *
+ * Please note that the returned value may not necessarily be equal to that
+ * passed to {@link setValue()}. It passes "intrinsic validation" confirming
+ * that such value could possibly be submitted by this <select> element.
+ * Specifically, this method will return null if the elements "disabled"
+ * attribute is set, it will not return values if there are no options having
+ * such a "value" attribute or if such options' "disabled" attribute is set.
+ * It will also only return a scalar value for single selects, mimicking
+ * the common browsers' behaviour.
+ *
+ * @return mixed "value" attribute of selected option in case of single
+ * select, array of selected options' "value" attributes in
+ * case of multiple selects, null if no options selected
+ */
+ public function getValue()
+ {
+ if (!empty($this->attributes['disabled']) || 0 == count($this->values)
+ || ($this->data['intrinsic_validation']
+ && (0 == count($this->optionContainer) || 0 == count($this->possibleValues)))
+ ) {
+ return null;
+ }
+
+ $values = array();
+ foreach ($this->values as $value) {
+ if (!$this->data['intrinsic_validation'] || !empty($this->possibleValues[$value])) {
+ $values[] = $value;
+ }
+ }
+ if (0 == count($values)) {
+ return null;
+ } elseif (!empty($this->attributes['multiple'])) {
+ return $this->applyFilters($values);
+ } elseif (1 == count($values)) {
+ return $this->applyFilters($values[0]);
+ } else {
+ // The <select> is not multiple, but several options are to be
+ // selected. At least IE and Mozilla select the last selected
+ // option in this case, we should do the same
+ foreach ($this->optionContainer->getRecursiveIterator() as $child) {
+ if (is_array($child) && in_array($child['attr']['value'], $values)) {
+ $lastValue = $child['attr']['value'];
+ }
+ }
+ return $this->applyFilters($lastValue);
+ }
+ }
+
+ public function setValue($value)
+ {
+ if (is_array($value)) {
+ $this->values = array_values($value);
+ } else {
+ $this->values = array($value);
+ }
+ return $this;
+ }
+
+ /**
+ * Loads <option>s (and <optgroup>s) for select element
+ *
+ * The method expects a array of options and optgroups:
+ * <pre>
+ * array(
+ * 'option value 1' => 'option text 1',
+ * ...
+ * 'option value N' => 'option text N',
+ * 'optgroup label 1' => array(
+ * 'option value' => 'option text',
+ * ...
+ * ),
+ * ...
+ * )
+ * </pre>
+ * If value is a scalar, then array key is treated as "value" attribute of
+ * <option> and value as this <option>'s text. If value is an array, then
+ * key is treated as a "label" attribute of <optgroup> and value as an
+ * array of <option>s for this <optgroup>.
+ *
+ * If you need to specify additional attributes for <option> and <optgroup>
+ * tags, then you need to use {@link addOption()} and {@link addOptgroup()}
+ * methods instead of this one.
+ *
+ * @param array
+ * @throws HTML_QuickForm2_InvalidArgumentException if junk is given in $options
+ * @return HTML_QuickForm2_Element_Select
+ */
+ public function loadOptions(array $options)
+ {
+ $this->possibleValues = array();
+ $this->optionContainer = new HTML_QuickForm2_Element_Select_OptionContainer(
+ $this->values, $this->possibleValues
+ );
+ $this->loadOptionsFromArray($this->optionContainer, $options);
+ return $this;
+ }
+
+
+ /**
+ * Adds options from given array into given container
+ *
+ * @param HTML_QuickForm2_Element_Select_OptionContainer options will be
+ * added to this container
+ * @param array options array
+ */
+ protected function loadOptionsFromArray(
+ HTML_QuickForm2_Element_Select_OptionContainer $container, $options
+ )
+ {
+ foreach ($options as $key => $value) {
+ if (is_array($value)) {
+ $optgroup = $container->addOptgroup($key);
+ $this->loadOptionsFromArray($optgroup, $value);
+ } else {
+ $container->addOption($value, $key);
+ }
+ }
+ }
+
+
+ /**
+ * Adds a new option
+ *
+ * Please note that if you pass 'selected' attribute in the $attributes
+ * parameter then this option's value will be added to <select>'s values.
+ *
+ * @param string Option text
+ * @param string 'value' attribute for <option> tag
+ * @param mixed Additional attributes for <option> tag (either as a
+ * string or as an associative array)
+ */
+ public function addOption($text, $value, $attributes = null)
+ {
+ return $this->optionContainer->addOption($text, $value, $attributes);
+ }
+
+ /**
+ * Adds a new optgroup
+ *
+ * @param string 'label' attribute for optgroup tag
+ * @param mixed Additional attributes for <optgroup> tag (either as a
+ * string or as an associative array)
+ * @return HTML_QuickForm2_Element_Select_Optgroup
+ */
+ public function addOptgroup($label, $attributes = null)
+ {
+ return $this->optionContainer->addOptgroup($label, $attributes);
+ }
+
+ protected function updateValue()
+ {
+ if (!$this->getAttribute('multiple')) {
+ parent::updateValue();
+ } else {
+ $name = $this->getName();
+ foreach ($this->getDataSources() as $ds) {
+ if (null !== ($value = $ds->getValue($name)) ||
+ $ds instanceof HTML_QuickForm2_DataSource_Submit)
+ {
+ $this->setValue(null === $value? array(): $value);
+ return;
+ }
+ }
+ }
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Element/Static.php b/libs/HTML/QuickForm2/Element/Static.php
new file mode 100644
index 0000000000..bfee75e130
--- /dev/null
+++ b/libs/HTML/QuickForm2/Element/Static.php
@@ -0,0 +1,153 @@
+<?php
+/**
+ * Class for static elements that only contain text or markup
+ *
+ * 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: Static.php 299206 2010-05-10 10:21:10Z mansion $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for simple HTML_QuickForm2 elements (not Containers)
+ */
+require_once 'HTML/QuickForm2/Element.php';
+
+/**
+ * Class for static elements that only contain text or markup
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Element_Static extends HTML_QuickForm2_Element
+{
+
+ /**
+ * Contains options and data used for the element creation
+ * - content: Content of the static element
+ * @var array
+ */
+ protected $data = array('content' => '');
+
+ public function getType()
+ {
+ return 'static';
+ }
+
+ /**
+ * Static element can not be frozen
+ *
+ * @param bool Whether element should be frozen or editable. This
+ * parameter is ignored in case of static elements
+ * @return bool Always returns false
+ */
+ public function toggleFrozen($freeze = null)
+ {
+ return false;
+ }
+
+ /**
+ * Sets the contents of the static element
+ *
+ * @param string Static content
+ * @return HTML_QuickForm2_Element_Static
+ */
+ function setContent($content)
+ {
+ $this->data['content'] = $content;
+ return $this;
+ }
+
+ /**
+ * Returns the contents of the static element
+ *
+ * @return string
+ */
+ function getContent()
+ {
+ return $this->data['content'];
+ }
+
+ /**
+ * Static element's content can also be set via this method
+ *
+ * @param mixed Element's value, this parameter is ignored
+ * @return HTML_QuickForm2_Element_Static
+ */
+ public function setValue($value)
+ {
+ $this->setContent($value);
+ return $this;
+ }
+
+ /**
+ * Static elements have no value
+ *
+ * @return null
+ */
+ public function getValue()
+ {
+ return null;
+ }
+
+ public function __toString()
+ {
+ return $this->getIndent() . $this->data['content'];
+ }
+
+ /**
+ * Called when the element needs to update its value from form's data sources
+ *
+ * Static elements content can be updated with default form values.
+ */
+ protected function updateValue()
+ {
+ foreach ($this->getDataSources() as $ds) {
+ if (!$ds instanceof HTML_QuickForm2_DataSource_Submit &&
+ null !== ($value = $ds->getValue($this->getName())))
+ {
+ $this->setContent($value);
+ return;
+ }
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/libs/HTML/QuickForm2/Element/Textarea.php b/libs/HTML/QuickForm2/Element/Textarea.php
new file mode 100644
index 0000000000..ff6892d35c
--- /dev/null
+++ b/libs/HTML/QuickForm2/Element/Textarea.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ * Class for <textarea> elements
+ *
+ * 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: Textarea.php 300722 2010-06-24 10:15:52Z mansion $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for simple HTML_QuickForm2 elements
+ */
+require_once 'HTML/QuickForm2/Element.php';
+
+/**
+ * Class for <textarea> 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_Element_Textarea extends HTML_QuickForm2_Element
+{
+ protected $persistent = true;
+
+ /**
+ * Value for textarea field
+ * @var string
+ */
+ protected $value = null;
+
+ public function getType()
+ {
+ return 'textarea';
+ }
+
+ public function setValue($value)
+ {
+ $this->value = $value;
+ return $this;
+ }
+
+ public function getValue()
+ {
+ return empty($this->attributes['disabled'])? $this->applyFilters($this->value): null;
+ }
+
+ public function __toString()
+ {
+ if ($this->frozen) {
+ return $this->getFrozenHtml();
+ } else {
+ return $this->getIndent() . '<textarea' . $this->getAttributes(true) .
+ '>' . preg_replace("/(\r\n|\n|\r)/", '&#010;', htmlspecialchars(
+ $this->value, ENT_QUOTES, self::getOption('charset')
+ )) . '</textarea>';
+ }
+ }
+
+ public function getFrozenHtml()
+ {
+ $value = htmlspecialchars($this->value, ENT_QUOTES, self::getOption('charset'));
+ if ('off' == $this->getAttribute('wrap')) {
+ $html = $this->getIndent() . '<pre>' . $value .
+ '</pre>' . self::getOption('linebreak');
+ } else {
+ $html = nl2br($value) . self::getOption('linbebreak');
+ }
+ return $html . $this->getPersistentContent();
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Exception.php b/libs/HTML/QuickForm2/Exception.php
new file mode 100644
index 0000000000..29e7a7f206
--- /dev/null
+++ b/libs/HTML/QuickForm2/Exception.php
@@ -0,0 +1,109 @@
+<?php
+/**
+ * Exception classes for HTML_QuickForm2
+ *
+ * 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: Exception.php 294057 2010-01-26 21:10:28Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for exceptions in PEAR
+ */
+require_once 'PEAR/Exception.php';
+
+/**
+ * Base class for exceptions in HTML_QuickForm2 package
+ *
+ * Such a base class is required by the Exception RFC:
+ * http://pear.php.net/pepr/pepr-proposal-show.php?id=132
+ * It will rarely be thrown directly, its specialized subclasses will be
+ * thrown most of the time.
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Exception extends PEAR_Exception
+{
+}
+
+/**
+ * Exception that denotes some resource was not found
+ *
+ * One example is trying to instantiate a nonexistent class in Factory
+ * <code>
+ * try {
+ * HTML_QuickForm2_Factory::registerElement('missing', 'NonExistent');
+ * $el = HTML_QuickForm2_Factory::createElement('missing');
+ * } catch (HTML_QuickForm2_NotFoundException $e) {
+ * echo $e->getMessage();
+ * }
+ * </code>
+ * This code fill output "Class 'NonExistent' does not exist and no file to load"
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_NotFoundException extends HTML_QuickForm2_Exception
+{
+}
+
+/**
+ * Exception that denotes invalid arguments were passed
+ *
+ * One example is trying to create an element of type which is unknown to Factory
+ * <code>
+ * try {
+ * $el = HTML_QuickForm2_Factory::createElement('unknown');
+ * } catch (HTML_QuickForm2_InvalidArgumentException $e) {
+ * echo $e->getMessage();
+ * }
+ * </code>
+ * This code will output "Element type 'unknown' is not known"
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_InvalidArgumentException extends HTML_QuickForm2_Exception
+{
+}
+?>
diff --git a/libs/HTML/QuickForm2/Factory.php b/libs/HTML/QuickForm2/Factory.php
new file mode 100644
index 0000000000..5f3028edbe
--- /dev/null
+++ b/libs/HTML/QuickForm2/Factory.php
@@ -0,0 +1,229 @@
+<?php
+/**
+ * Static Factory class for HTML_QuickForm2 package
+ *
+ * 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: Factory.php 299305 2010-05-12 20:15:28Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Class with static methods for loading classes and files
+ */
+require_once 'HTML/QuickForm2/Loader.php';
+
+/**
+ * Static factory class
+ *
+ * The class handles instantiation of Element and Rule objects as well as
+ * registering of new Element and Rule classes.
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Factory
+{
+ /**
+ * List of element types known to Factory
+ * @var array
+ */
+ protected static $elementTypes = array(
+ 'button' => array('HTML_QuickForm2_Element_Button', null),
+ 'checkbox' => array('HTML_QuickForm2_Element_InputCheckbox', null),
+ 'date' => array('HTML_QuickForm2_Element_Date', null),
+ 'fieldset' => array('HTML_QuickForm2_Container_Fieldset', null),
+ 'group' => array('HTML_QuickForm2_Container_Group', null),
+ 'file' => array('HTML_QuickForm2_Element_InputFile', null),
+ 'hidden' => array('HTML_QuickForm2_Element_InputHidden', null),
+ 'image' => array('HTML_QuickForm2_Element_InputImage', null),
+ 'inputbutton' => array('HTML_QuickForm2_Element_InputButton', null),
+ 'password' => array('HTML_QuickForm2_Element_InputPassword', null),
+ 'radio' => array('HTML_QuickForm2_Element_InputRadio', null),
+ 'reset' => array('HTML_QuickForm2_Element_InputReset', null),
+ 'select' => array('HTML_QuickForm2_Element_Select', null),
+ 'submit' => array('HTML_QuickForm2_Element_InputSubmit', null),
+ 'text' => array('HTML_QuickForm2_Element_InputText', null),
+ 'textarea' => array('HTML_QuickForm2_Element_Textarea', null)
+ );
+
+ /**
+ * List of registered rules
+ * @var array
+ */
+ protected static $registeredRules = array(
+ 'nonempty' => array('HTML_QuickForm2_Rule_Nonempty', null),
+ 'empty' => array('HTML_QuickForm2_Rule_Empty', null),
+ 'required' => array('HTML_QuickForm2_Rule_Required', null),
+ 'compare' => array('HTML_QuickForm2_Rule_Compare', null),
+ 'eq' => array('HTML_QuickForm2_Rule_Compare', null,
+ array('operator' => '===')),
+ 'neq' => array('HTML_QuickForm2_Rule_Compare', null,
+ array('operator' => '!==')),
+ 'lt' => array('HTML_QuickForm2_Rule_Compare', null,
+ array('operator' => '<')),
+ 'lte' => array('HTML_QuickForm2_Rule_Compare', null,
+ array('operator' => '<=')),
+ 'gt' => array('HTML_QuickForm2_Rule_Compare', null,
+ array('operator' => '>')),
+ 'gte' => array('HTML_QuickForm2_Rule_Compare', null,
+ array('operator' => '>=')),
+ 'regex' => array('HTML_QuickForm2_Rule_Regex', null),
+ 'callback' => array('HTML_QuickForm2_Rule_Callback', null),
+ 'length' => array('HTML_QuickForm2_Rule_Length', null),
+ 'minlength' => array('HTML_QuickForm2_Rule_Length', null,
+ array('max' => 0)),
+ 'maxlength' => array('HTML_QuickForm2_Rule_Length', null,
+ array('min' => 0)),
+ 'maxfilesize' => array('HTML_QuickForm2_Rule_MaxFileSize', null),
+ 'mimetype' => array('HTML_QuickForm2_Rule_MimeType', null),
+ 'each' => array('HTML_QuickForm2_Rule_Each', null),
+ 'notcallback' => array('HTML_QuickForm2_Rule_NotCallback', null),
+ 'notregex' => array('HTML_QuickForm2_Rule_NotRegex', null)
+ );
+
+
+ /**
+ * Registers a new element type
+ *
+ * @param string Type name (treated case-insensitively)
+ * @param string Class name
+ * @param string File containing the class, leave empty if class already loaded
+ */
+ public static function registerElement($type, $className, $includeFile = null)
+ {
+ self::$elementTypes[strtolower($type)] = array($className, $includeFile);
+ }
+
+
+ /**
+ * Checks whether an element type is known to factory
+ *
+ * @param string Type name (treated case-insensitively)
+ * @return bool
+ */
+ public static function isElementRegistered($type)
+ {
+ return isset(self::$elementTypes[strtolower($type)]);
+ }
+
+
+ /**
+ * Creates a new element object of the given type
+ *
+ * @param string Type name (treated case-insensitively)
+ * @param mixed Element name (passed to element's constructor)
+ * @param mixed Element attributes (passed to element's constructor)
+ * @param array Element-specific data (passed to element's constructor)
+ * @return HTML_QuickForm2_Node A created element
+ * @throws HTML_QuickForm2_InvalidArgumentException If type name is unknown
+ * @throws HTML_QuickForm2_NotFoundException If class for the element can
+ * not be found and/or loaded from file
+ */
+ public static function createElement($type, $name = null, $attributes = null,
+ array $data = array())
+ {
+ $type = strtolower($type);
+ if (!isset(self::$elementTypes[$type])) {
+ throw new HTML_QuickForm2_InvalidArgumentException("Element type '$type' is not known");
+ }
+ list($className, $includeFile) = self::$elementTypes[$type];
+ HTML_QuickForm2_Loader::loadClass($className, $includeFile);
+ return new $className($name, $attributes, $data);
+ }
+
+
+ /**
+ * Registers a new rule type
+ *
+ * @param string Rule type name (treated case-insensitively)
+ * @param string Class name
+ * @param string File containing the class, leave empty if class already loaded
+ * @param mixed Configuration data for rules of the given type
+ */
+ public static function registerRule($type, $className, $includeFile = null,
+ $config = null)
+ {
+ self::$registeredRules[strtolower($type)] = array($className, $includeFile, $config);
+ }
+
+
+ /**
+ * Checks whether a rule type is known to Factory
+ *
+ * @param string Rule type name (treated case-insensitively)
+ * @return bool
+ */
+ public static function isRuleRegistered($type)
+ {
+ return isset(self::$registeredRules[strtolower($type)]);
+ }
+
+
+ /**
+ * Creates a new Rule of the given type
+ *
+ * @param string Rule type name (treated case-insensitively)
+ * @param HTML_QuickForm2_Node Element to validate by the rule
+ * @param string Message to display if validation fails
+ * @param mixed Configuration data for the rule
+ * @return HTML_QuickForm2_Rule A created Rule
+ * @throws HTML_QuickForm2_InvalidArgumentException If rule type is unknown
+ * @throws HTML_QuickForm2_NotFoundException If class for the rule
+ * can't be found and/or loaded from file
+ */
+ public static function createRule($type, HTML_QuickForm2_Node $owner,
+ $message = '', $config = null)
+ {
+ $type = strtolower($type);
+ if (!isset(self::$registeredRules[$type])) {
+ throw new HTML_QuickForm2_InvalidArgumentException("Rule '$type' is not known");
+ }
+ list($className, $includeFile) = self::$registeredRules[$type];
+ HTML_QuickForm2_Loader::loadClass($className, $includeFile);
+ if (isset(self::$registeredRules[$type][2])) {
+ $config = call_user_func(array($className, 'mergeConfig'), $config,
+ self::$registeredRules[$type][2]);
+ }
+ return new $className($owner, $message, $config);
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/JavascriptBuilder.php b/libs/HTML/QuickForm2/JavascriptBuilder.php
new file mode 100644
index 0000000000..8723d05905
--- /dev/null
+++ b/libs/HTML/QuickForm2/JavascriptBuilder.php
@@ -0,0 +1,120 @@
+<?php
+/**
+ * Javascript aggregator and builder class
+ *
+ * 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: JavascriptBuilder.php 299480 2010-05-19 06:55:03Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Exception classes for HTML_QuickForm2
+ */
+require_once 'HTML/QuickForm2/Exception.php';
+
+/**
+ * Javascript aggregator and builder class
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_JavascriptBuilder
+{
+ /**
+ * Client-side rules
+ * @var array
+ */
+ protected $rules = array();
+
+ /**
+ * Current form ID
+ * @var string
+ */
+ protected $formId = null;
+
+ /**
+ * Sets the form currently being processed
+ *
+ * @param HTML_QuickForm2
+ */
+ public function startForm(HTML_QuickForm2 $form)
+ {
+ $this->formId = $form->getId();
+ $this->rules[$this->formId] = array();
+ }
+
+ /**
+ * Adds the Rule javascript to the list of current form Rules
+ *
+ * @param HTML_QuickForm2_Rule
+ */
+ public function addRule(HTML_QuickForm2_Rule $rule)
+ {
+ $this->rules[$this->formId][] = $rule->getJavascript();
+ }
+
+ /**
+ * Returns client-side validation code
+ *
+ * @todo This shouldn't probably be __toString() as we can't throw exceptions from that
+ * @todo Of course we shouldn't put library files into each page, need some means to include them via <script> tags
+ */
+ public function __toString()
+ {
+ $js = '';
+ foreach ($this->rules as $formId => $rules) {
+ if (!empty($rules)) {
+ $js .= "new qf.validator(document.getElementById('{$formId}'), [\n" .
+ implode(",\n", $rules) .
+ "\n]);";
+ }
+ }
+ if ('' != $js) {
+ $js = "<script type=\"text/javascript\">\n//<![CDATA[\n" .
+ file_get_contents('@data_dir@/HTML_QuickForm2/quickform.js') .
+ "qf.events.contentReady(function() {\n{$js}\n});\n" .
+ "//]]>\n</script>";
+ }
+ return $js;
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Loader.php b/libs/HTML/QuickForm2/Loader.php
new file mode 100644
index 0000000000..f058d45dd5
--- /dev/null
+++ b/libs/HTML/QuickForm2/Loader.php
@@ -0,0 +1,140 @@
+<?php
+/**
+ * Class with static methods for loading classes and files
+ *
+ * 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: Loader.php 294057 2010-01-26 21:10:28Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Exception classes for HTML_QuickForm2
+ */
+require_once 'HTML/QuickForm2/Exception.php';
+
+/**
+ * Class with static methods for loading classes and files
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Loader
+{
+ /**
+ * Tries to load a given class
+ *
+ * If no $includeFile was provided, $className will be used with underscores
+ * replaced with path separators and '.php' extension appended
+ *
+ * @param string Class name to load
+ * @param string Name of the file (supposedly) containing the given class
+ * @throws HTML_QuickForm2_NotFoundException If the file either can't be
+ * loaded or doesn't contain the given class
+ */
+ public static function loadClass($className, $includeFile = null)
+ {
+ if (class_exists($className, false) || interface_exists($className, false)) {
+ return true;
+ }
+
+ if (empty($includeFile)) {
+ $includeFile = str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
+ }
+ // Do not silence the errors with @, parse errors will not be seen
+ include $includeFile;
+
+ // Still no class?
+ if (!class_exists($className, false) && !interface_exists($className, false)) {
+ if (!self::fileExists($includeFile)) {
+ throw new HTML_QuickForm2_NotFoundException(
+ "File '$includeFile' was not found"
+ );
+ } else {
+ throw new HTML_QuickForm2_NotFoundException(
+ "Class '$className' was not found within file '$includeFile'"
+ );
+ }
+ }
+ }
+
+ /**
+ * Checks whether the file exists in the include path
+ *
+ * @param string file name
+ * @return bool
+ */
+ public static function fileExists($fileName)
+ {
+ $fp = @fopen($fileName, 'r', true);
+ if (is_resource($fp)) {
+ fclose($fp);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Loading of HTML_QuickForm2_* classes suitable for SPL autoload mechanism
+ *
+ * This method will only try to load a class if its name starts with
+ * HTML_QuickForm2. Register with the following:
+ * <code>
+ * spl_autoload_register(array('HTML_QuickForm2_Loader', 'autoload'));
+ * </code>
+ *
+ * @param string Class name
+ * @return bool Whether class loaded successfully
+ */
+ public static function autoload($class)
+ {
+ if (0 !== strpos($class, 'HTML_QuickForm2')) {
+ return false;
+ }
+ try {
+ @self::loadClass($class);
+ return true;
+ } catch (Exception $e) {
+ return false;
+ }
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Node.php b/libs/HTML/QuickForm2/Node.php
new file mode 100644
index 0000000000..ae770561ba
--- /dev/null
+++ b/libs/HTML/QuickForm2/Node.php
@@ -0,0 +1,692 @@
+<?php
+/**
+ * Base class for all HTML_QuickForm2 elements
+ *
+ * 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: Node.php 300747 2010-06-25 16:16:50Z mansion $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * HTML_Common2 - base class for HTML elements
+ */
+require_once 'HTML/Common2.php';
+
+// By default, we generate element IDs with numeric indexes appended even for
+// elements with unique names. If you want IDs to be equal to the element
+// names by default, set this configuration option to false.
+if (null === HTML_Common2::getOption('id_force_append_index')) {
+ HTML_Common2::setOption('id_force_append_index', true);
+}
+
+/**
+ * Exception classes for HTML_QuickForm2
+ */
+require_once 'HTML/QuickForm2/Exception.php';
+
+/**
+ * Static factory class for QuickForm2 elements
+ */
+require_once 'HTML/QuickForm2/Factory.php';
+
+/**
+ * Base class for HTML_QuickForm2 rules
+ */
+require_once 'HTML/QuickForm2/Rule.php';
+
+
+/**
+ * Abstract base class for all QuickForm2 Elements and Containers
+ *
+ * This class is mostly here to define the interface that should be implemented
+ * by the subclasses. It also contains static methods handling generation
+ * of unique ids for elements which do not have ids explicitly set.
+ *
+ * @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_Node extends HTML_Common2
+{
+ /**
+ * Array containing the parts of element ids
+ * @var array
+ */
+ protected static $ids = array();
+
+ /**
+ * Element's "frozen" status
+ * @var boolean
+ */
+ protected $frozen = false;
+
+ /**
+ * Whether element's value should persist when element is frozen
+ * @var boolean
+ */
+ protected $persistent = false;
+
+ /**
+ * Element containing current
+ * @var HTML_QuickForm2_Container
+ */
+ protected $container = null;
+
+ /**
+ * Contains options and data used for the element creation
+ * @var array
+ */
+ protected $data = array();
+
+ /**
+ * Validation rules for element
+ * @var array
+ */
+ protected $rules = array();
+
+ /**
+ * An array of callback filters for element
+ * @var array
+ */
+ protected $filters = array();
+
+ /**
+ * Error message (usually set via Rule if validation fails)
+ * @var string
+ */
+ protected $error = null;
+
+ /**
+ * Changing 'name' and 'id' attributes requires some special handling
+ * @var array
+ */
+ protected $watchedAttributes = array('id', 'name');
+
+ /**
+ * Intercepts setting 'name' and 'id' attributes
+ *
+ * These attributes should always be present and thus trying to remove them
+ * will result in an exception. Changing their values is delegated to
+ * setName() and setId() methods, respectively
+ *
+ * @param string Attribute name
+ * @param string Attribute value, null if attribute is being removed
+ * @throws HTML_QuickForm2_InvalidArgumentException if trying to
+ * remove a required attribute
+ */
+ protected function onAttributeChange($name, $value = null)
+ {
+ if ('name' == $name) {
+ if (null === $value) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ "Required attribute 'name' can not be removed"
+ );
+ } else {
+ $this->setName($value);
+ }
+ } elseif ('id' == $name) {
+ if (null === $value) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ "Required attribute 'id' can not be removed"
+ );
+ } else {
+ $this->setId($value);
+ }
+ }
+ }
+
+ /**
+ * Class constructor
+ *
+ * @param string Element name
+ * @param mixed Attributes (either a string or an array)
+ * @param array Element data (label, options and data used for element creation)
+ */
+ public function __construct($name = null, $attributes = null, $data = null)
+ {
+ parent::__construct($attributes);
+ $this->setName($name);
+ // Autogenerating the id if not set on previous steps
+ if ('' == $this->getId()) {
+ $this->setId();
+ }
+ if (!empty($data)) {
+ $this->data = array_merge($this->data, $data);
+ }
+ }
+
+
+ /**
+ * Generates an id for the element
+ *
+ * Called when an element is created without explicitly given id
+ *
+ * @param string Element name
+ * @return string The generated element id
+ */
+ protected static function generateId($elementName)
+ {
+ $stop = !self::getOption('id_force_append_index');
+ $tokens = strlen($elementName)
+ ? explode('[', str_replace(']', '', $elementName))
+ : ($stop? array('qfauto', ''): array('qfauto'));
+ $container =& self::$ids;
+ $id = '';
+
+ do {
+ $token = array_shift($tokens);
+ // Handle the 'array[]' names
+ if ('' === $token) {
+ if (empty($container)) {
+ $token = 0;
+ } else {
+ $keys = array_keys($container);
+ $token = end($keys);
+ while (isset($container[$token])) {
+ $token++;
+ }
+ }
+ }
+ $id .= '-' . $token;
+ if (!isset($container[$token])) {
+ $container[$token] = array();
+ // Handle duplicate names when not having mandatory indexes
+ } elseif (empty($tokens) && $stop) {
+ $tokens[] = '';
+ }
+ // Handle mandatory indexes
+ if (empty($tokens) && !$stop) {
+ $tokens[] = '';
+ $stop = true;
+ }
+ $container =& $container[$token];
+ } while (!empty($tokens));
+
+ return substr($id, 1);
+ }
+
+
+ /**
+ * Stores the explicitly given id to prevent duplicate id generation
+ *
+ * @param string Element id
+ */
+ protected static function storeId($id)
+ {
+ $tokens = explode('-', $id);
+ $container =& self::$ids;
+
+ do {
+ $token = array_shift($tokens);
+ if (!isset($container[$token])) {
+ $container[$token] = array();
+ }
+ $container =& $container[$token];
+ } while (!empty($tokens));
+ }
+
+
+ /**
+ * Returns the element options
+ *
+ * @return array
+ */
+ public function getData()
+ {
+ return $this->data;
+ }
+
+
+ /**
+ * Returns the element's type
+ *
+ * @return string
+ */
+ abstract public function getType();
+
+
+ /**
+ * Returns the element's name
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return isset($this->attributes['name'])? $this->attributes['name']: null;
+ }
+
+
+ /**
+ * Sets the element's name
+ *
+ * @param string
+ * @return HTML_QuickForm2_Node
+ */
+ abstract public function setName($name);
+
+
+ /**
+ * Returns the element's id
+ *
+ * @return string
+ */
+ public function getId()
+ {
+ return isset($this->attributes['id'])? $this->attributes['id']: null;
+ }
+
+
+ /**
+ * Sets the elements id
+ *
+ * Please note that elements should always have an id in QuickForm2 and
+ * therefore it will not be possible to remove the element's id or set it to
+ * an empty value. If id is not explicitly given, it will be autogenerated.
+ *
+ * @param string Element's id, will be autogenerated if not given
+ * @return HTML_QuickForm2_Node
+ */
+ public function setId($id = null)
+ {
+ if (is_null($id)) {
+ $id = self::generateId($this->getName());
+ } else {
+ self::storeId($id);
+ }
+ $this->attributes['id'] = (string)$id;
+ return $this;
+ }
+
+
+ /**
+ * Returns the element's value
+ *
+ * @return mixed
+ */
+ abstract public function getValue();
+
+
+ /**
+ * Sets the element's value
+ *
+ * @param mixed
+ * @return HTML_QuickForm2_Node
+ */
+ abstract public function setValue($value);
+
+
+ /**
+ * Returns the element's label(s)
+ *
+ * @return string|array
+ */
+ public function getLabel()
+ {
+ if (isset($this->data['label'])) {
+ return $this->data['label'];
+ }
+ return null;
+ }
+
+
+ /**
+ * Sets the element's label(s)
+ *
+ * @param string|array Label for the element (may be an array of labels)
+ * @return HTML_QuickForm2_Node
+ */
+ public function setLabel($label)
+ {
+ $this->data['label'] = $label;
+ return $this;
+ }
+
+
+ /**
+ * Changes the element's frozen status
+ *
+ * @param bool Whether the element should be frozen or editable. If
+ * omitted, the method will not change the frozen status,
+ * just return its current value
+ * @return bool Old value of element's frozen status
+ */
+ public function toggleFrozen($freeze = null)
+ {
+ $old = $this->frozen;
+ if (null !== $freeze) {
+ $this->frozen = (bool)$freeze;
+ }
+ return $old;
+ }
+
+
+ /**
+ * Changes the element's persistent freeze behaviour
+ *
+ * If persistent freeze is on, the element's value will be kept (and
+ * submitted) in a hidden field when the element is frozen.
+ *
+ * @param bool New value for "persistent freeze". If omitted, the
+ * method will not set anything, just return the current
+ * value of the flag.
+ * @return bool Old value of "persistent freeze" flag
+ */
+ public function persistentFreeze($persistent = null)
+ {
+ $old = $this->persistent;
+ if (null !== $persistent) {
+ $this->persistent = (bool)$persistent;
+ }
+ return $old;
+ }
+
+
+ /**
+ * Adds the link to the element containing current
+ *
+ * @param HTML_QuickForm2_Container Element containing the current one,
+ * null if the link should really be
+ * removed (if removing from container)
+ * @throws HTML_QuickForm2_InvalidArgumentException If trying to set a
+ * child of an element as its container
+ */
+ protected function setContainer(HTML_QuickForm2_Container $container = null)
+ {
+ if (null !== $container) {
+ $check = $container;
+ do {
+ if ($this === $check) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'Cannot set an element or its child as its own container'
+ );
+ }
+ } while ($check = $check->getContainer());
+ if (null !== $this->container && $container !== $this->container) {
+ $this->container->removeChild($this);
+ }
+ }
+ $this->container = $container;
+ if (null !== $container) {
+ $this->updateValue();
+ }
+ }
+
+
+ /**
+ * Returns the element containing current
+ *
+ * @return HTML_QuickForm2_Container|null
+ */
+ public function getContainer()
+ {
+ return $this->container;
+ }
+
+ /**
+ * Returns the data sources for this element
+ *
+ * @return array
+ */
+ protected function getDataSources()
+ {
+ if (empty($this->container)) {
+ return array();
+ } else {
+ return $this->container->getDataSources();
+ }
+ }
+
+ /**
+ * Called when the element needs to update its value from form's data sources
+ */
+ abstract protected function updateValue();
+
+ /**
+ * Adds a validation rule
+ *
+ * @param HTML_QuickForm2_Rule|string Validation rule or rule type
+ * @param string|int If first parameter is rule type, then
+ * message to display if validation fails, otherwise constant showing
+ * whether to perfom validation client-side and/or server-side
+ * @param mixed Additional data for the rule
+ * @param int Whether to perfom validation server-side
+ * and/or client side. Combination of HTML_QuickForm2_Rule::RUNAT_* constants
+ * @return HTML_QuickForm2_Rule The added rule
+ * @throws HTML_QuickForm2_InvalidArgumentException if $rule is of a
+ * wrong type or rule name isn't registered with Factory
+ * @throws HTML_QuickForm2_NotFoundException if class for a given rule
+ * name cannot be found
+ * @todo Need some means to mark the Rules for running client-side
+ */
+ public function addRule($rule, $messageOrRunAt = '', $options = null,
+ $runAt = HTML_QuickForm2_Rule::RUNAT_SERVER)
+ {
+ if ($rule instanceof HTML_QuickForm2_Rule) {
+ $rule->setOwner($this);
+ $runAt = '' == $messageOrRunAt? HTML_QuickForm2_Rule::RUNAT_SERVER: $messageOrRunAt;
+ } elseif (is_string($rule)) {
+ $rule = HTML_QuickForm2_Factory::createRule($rule, $this, $messageOrRunAt, $options);
+ } else {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'addRule() expects either a rule type or ' .
+ 'a HTML_QuickForm2_Rule instance'
+ );
+ }
+
+ $this->rules[] = array($rule, $runAt);
+ return $rule;
+ }
+
+ /**
+ * Removes a validation rule
+ *
+ * The method will *not* throw an Exception if the rule wasn't added to the
+ * element.
+ *
+ * @param HTML_QuickForm2_Rule Validation rule to remove
+ * @return HTML_QuickForm2_Rule Removed rule
+ */
+ public function removeRule(HTML_QuickForm2_Rule $rule)
+ {
+ foreach ($this->rules as $i => $r) {
+ if ($r[0] === $rule) {
+ unset($this->rules[$i]);
+ break;
+ }
+ }
+ return $rule;
+ }
+
+ /**
+ * Creates a validation rule
+ *
+ * This method is mostly useful when when chaining several rules together
+ * via {@link HTML_QuickForm2_Rule::and_()} and {@link HTML_QuickForm2_Rule::or_()}
+ * methods:
+ * <code>
+ * $first->addRule('nonempty', 'Fill in either first or second field')
+ * ->or_($second->createRule('nonempty'));
+ * </code>
+ *
+ * @param string Rule type
+ * @param string Message to display if validation fails
+ * @param mixed Additional data for the rule
+ * @return HTML_QuickForm2_Rule The created rule
+ * @throws HTML_QuickForm2_InvalidArgumentException If rule type is unknown
+ * @throws HTML_QuickForm2_NotFoundException If class for the rule
+ * can't be found and/or loaded from file
+ */
+ public function createRule($type, $message = '', $options = null)
+ {
+ return HTML_QuickForm2_Factory::createRule($type, $this, $message, $options);
+ }
+
+
+ /**
+ * Checks whether an element is required
+ *
+ * @return boolean
+ */
+ public function isRequired()
+ {
+ foreach ($this->rules as $rule) {
+ if ($rule[0] instanceof HTML_QuickForm2_Rule_Required) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ /**
+ * Performs the server-side validation
+ *
+ * @return boolean Whether the element is valid
+ */
+ protected function validate()
+ {
+ foreach ($this->rules as $rule) {
+ if (strlen($this->error)) {
+ break;
+ }
+ if ($rule[1] & HTML_QuickForm2_Rule::RUNAT_SERVER) {
+ $rule[0]->validate();
+ }
+ }
+ return !strlen($this->error);
+ }
+
+ /**
+ * Sets the error message to the element
+ *
+ * @param string
+ * @return HTML_QuickForm2_Node
+ */
+ public function setError($error = null)
+ {
+ $this->error = (string)$error;
+ return $this;
+ }
+
+ /**
+ * Returns the error message for the element
+ *
+ * @return string
+ */
+ public function getError()
+ {
+ return $this->error;
+ }
+
+ /**
+ * Returns Javascript code for getting the element's value
+ *
+ * @return string
+ */
+ abstract public function getJavascriptValue();
+
+ /**
+ * Adds a filter
+ *
+ * A filter is simply a PHP callback which will be applied to the element value
+ * when getValue() is called. A filter is by default applied recursively :
+ * if the value is an array, each elements it contains will
+ * also be filtered, unless the recursive flag is set to false.
+ *
+ * @param callback The PHP callback used for filter
+ * @param array Optional arguments for the callback. The first parameter
+ * will always be the element value, then these options will
+ * be used as parameters for the callback.
+ * @param bool Whether to apply the filter recursively to contained elements
+ * @return HTML_QuickForm2_Node The element
+ * @throws HTML_QuickForm2_InvalidArgumentException If callback is incorrect
+ */
+ public function addFilter($callback, array $options = null, $recursive = true)
+ {
+ if (!is_callable($callback, false, $callbackName)) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'Callback Filter requires a valid callback, \'' . $callbackName .
+ '\' was given'
+ );
+ }
+ $this->filters[] = array($callback, $options, 'recursive' => $recursive);
+ return $this;
+ }
+
+ /**
+ * Removes all element filters
+ */
+ public function removeFilters()
+ {
+ $this->filters = array();
+ }
+
+ /**
+ * Applies element filters on element value
+ * @param mixed Element value
+ * @return mixed Filtered value
+ */
+ protected function applyFilters($value)
+ {
+ foreach ($this->filters as $filter) {
+ if (is_array($value) && !empty($filter['recursive'])) {
+ array_walk_recursive(&$value,
+ array('HTML_QuickForm2_Node', 'applyFilter'), $filter);
+ } else {
+ self::applyFilter($value, null, $filter);
+ }
+ }
+ return $value;
+ }
+
+ protected static function applyFilter(&$value, $key = null, $filter)
+ {
+ $callback = $filter[0];
+ $options = $filter[1];
+ if (!is_array($options)) {
+ $options = array();
+ }
+ array_unshift($options, $value);
+ $value = call_user_func_array($callback, $options);
+ }
+
+}
+?>
diff --git a/libs/HTML/QuickForm2/Renderer.php b/libs/HTML/QuickForm2/Renderer.php
new file mode 100644
index 0000000000..3b696a5c03
--- /dev/null
+++ b/libs/HTML/QuickForm2/Renderer.php
@@ -0,0 +1,360 @@
+<?php
+/**
+ * Base class for HTML_QuickForm2 renderers
+ *
+ * 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: Renderer.php 299706 2010-05-24 18:32:37Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Class with static methods for loading classes and files
+ */
+require_once 'HTML/QuickForm2/Loader.php';
+
+/**
+ * Abstract base class for QuickForm2 renderers
+ *
+ * This class serves two main purposes:
+ * <ul>
+ * <li>Defines the API all renderers should implement (render*() methods);</li>
+ * <li>Provides static methods for registering renderers and their plugins
+ * and {@link factory()} method for creating renderer instances.</li>
+ * </ul>
+ *
+ * Note that renderers should always be instantiated through factory(), in the
+ * other case it will not be possible to add plugins.
+ *
+ * @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_Renderer
+{
+ /**
+ * List of registered renderer types
+ * @var array
+ */
+ private static $_types = array(
+ 'default' => array('HTML_QuickForm2_Renderer_Default', null),
+ 'array' => array('HTML_QuickForm2_Renderer_Array', null)
+ );
+
+ /**
+ * List of registered renderer plugins
+ * @var array
+ */
+ private static $_pluginClasses = array(
+ 'default' => array(),
+ 'array' => array()
+ );
+
+ /**
+ * Renderer options
+ * @var array
+ * @see setOption()
+ */
+ protected $options = array(
+ 'group_hiddens' => true,
+ 'required_note' => '<em>*</em> denotes required fields.',
+ 'errors_prefix' => 'Invalid information entered:',
+ 'errors_suffix' => 'Please correct these fields.',
+ 'group_errors' => false
+ );
+
+ /**
+ * Javascript builder object
+ * @var HTML_QuickForm2_JavascriptBuilder
+ */
+ protected $jsBuilder;
+
+ /**
+ * Creates a new renderer instance of the given type
+ *
+ * A renderer is always wrapped by a Proxy, which handles calling its
+ * "published" methods and methods of its plugins. Registered plugins are
+ * added automagically to the existing renderer instances so that
+ * <code>
+ * $foo = HTML_QuickForm2_Renderer::factory('foo');
+ * // Plugin implementing bar() method
+ * HTML_QuickForm2_Renderer::registerPlugin('foo', 'Plugin_Foo_Bar');
+ * $foo->bar();
+ * </code>
+ * will work.
+ *
+ * @param string Type name (treated case-insensitively)
+ * @return HTML_QuickForm2_Renderer_Proxy A renderer instance of the given
+ * type wrapped by a Proxy
+ * @throws HTML_QuickForm2_InvalidArgumentException If type name is unknown
+ * @throws HTML_QuickForm2_NotFoundException If class for the renderer can
+ * not be found and/or loaded from file
+ */
+ final public static function factory($type)
+ {
+ $type = strtolower($type);
+ if (!isset(self::$_types[$type])) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ "Renderer type '$type' is not known"
+ );
+ }
+
+ list ($className, $includeFile) = self::$_types[$type];
+ HTML_QuickForm2_Loader::loadClass($className, $includeFile);
+ HTML_QuickForm2_Loader::loadClass('HTML_QuickForm2_Renderer_Proxy');
+ return new HTML_QuickForm2_Renderer_Proxy(new $className, self::$_pluginClasses[$type]);
+ }
+
+ /**
+ * Registers a new renderer type
+ *
+ * @param string Type name (treated case-insensitively)
+ * @param string Class name
+ * @param string File containing the class, leave empty if class already loaded
+ * @throws HTML_QuickForm2_InvalidArgumentException if type already registered
+ */
+ final public static function register($type, $className, $includeFile = null)
+ {
+ $type = strtolower($type);
+ if (!empty(self::$_types[$type])) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ "Renderer type '$type' is already registered"
+ );
+ }
+ self::$_types[$type] = array($className, $includeFile);
+ if (empty(self::$_pluginClasses[$type])) {
+ self::$_pluginClasses[$type] = array();
+ }
+ }
+
+ /**
+ * Registers a plugin for a renderer type
+ *
+ * @param string Renderer type name (treated case-insensitively)
+ * @param string Plugin class name
+ * @param string File containing the plugin class, leave empty if class already loaded
+ * @throws HTML_QuickForm2_InvalidArgumentException if plugin is already registered
+ */
+ final public static function registerPlugin($type, $className, $includeFile = null)
+ {
+ $type = strtolower($type);
+ // We don't check self::$_types, since a plugin may be registered
+ // before renderer itself if it goes with some custom element
+ if (empty(self::$_pluginClasses[$type])) {
+ self::$_pluginClasses[$type] = array(array($className, $includeFile));
+ } else {
+ foreach (self::$_pluginClasses[$type] as $plugin) {
+ if (0 == strcasecmp($plugin[0], $className)) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ "Plugin '$className' for renderer type '$type' is already registered"
+ );
+ }
+ }
+ self::$_pluginClasses[$type][] = array($className, $includeFile);
+ }
+ }
+
+ /**
+ * Constructor
+ *
+ * Renderer instances should not be created directly, use {@link factory()}
+ */
+ protected function __construct()
+ {
+ }
+
+ /**
+ * Returns an array of "published" method names that should be callable through proxy
+ *
+ * Methods defined in HTML_QuickForm2_Renderer are proxied automatically,
+ * only additional methods should be returned.
+ *
+ * @return array
+ */
+ protected function exportMethods()
+ {
+ return array();
+ }
+
+ /**
+ * Sets the option(s) affecting renderer behaviour
+ *
+ * The following options are available:
+ * <ul>
+ * <li>'group_hiddens' - whether to group hidden elements together or
+ * render them where they were added (boolean)</li>
+ * <li>'group_errors' - whether to group error messages or render them
+ * alongside elements they apply to (boolean)</li>
+ * <li>'errors_prefix' - leading message for grouped errors (string)</li>
+ * <li>'errors_suffix' - trailing message for grouped errors (string)</li>
+ * <li>'required_note' - note displayed if the form contains required
+ * elements (string)</li>
+ * </ul>
+ *
+ * @param string|array option name or array ('option name' => 'option value')
+ * @param mixed parameter value if $nameOrConfig is not an array
+ * @return HTML_QuickForm2_Renderer
+ * @throws HTML_QuickForm2_NotFoundException in case of unknown option
+ */
+ public function setOption($nameOrOptions, $value = null)
+ {
+ if (is_array($nameOrOptions)) {
+ foreach ($nameOrOptions as $name => $value) {
+ $this->setOption($name, $value);
+ }
+
+ } else {
+ if (!array_key_exists($nameOrOptions, $this->options)) {
+ throw new HTML_QuickForm2_NotFoundException(
+ "Unknown option '{$nameOrOptions}'"
+ );
+ }
+ $this->options[$nameOrOptions] = $value;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns the value(s) of the renderer option(s)
+ *
+ * @param string parameter name
+ * @return mixed value of $name parameter, array of all configuration
+ * parameters if $name is not given
+ * @throws HTML_QuickForm2_NotFoundException in case of unknown option
+ */
+ public function getOption($name = null)
+ {
+ if (null === $name) {
+ return $this->options;
+ } elseif (!array_key_exists($name, $this->options)) {
+ throw new HTML_QuickForm2_NotFoundException(
+ "Unknown option '{$name}'"
+ );
+ }
+ return $this->options[$name];
+ }
+
+ /**
+ * Returns the javascript builder object
+ *
+ * @return HTML_QuickForm2_JavascriptBuilder
+ */
+ public function getJavascriptBuilder()
+ {
+ if (empty($this->jsBuilder)) {
+ HTML_QuickForm2_Loader::loadClass('HTML_QuickForm2_JavascriptBuilder');
+ $this->jsBuilder = new HTML_QuickForm2_JavascriptBuilder();
+ }
+ return $this->jsBuilder;
+ }
+
+ /**
+ * Sets the javascript builder object
+ *
+ * You may want to reuse the same builder object if outputting several
+ * forms on one page.
+ *
+ * @param HTML_QuickForm2_JavascriptBuilder
+ * @return HTML_QuickForm2_Renderer
+ */
+ public function setJavascriptBuilder(HTML_QuickForm2_JavascriptBuilder $builder = null)
+ {
+ $this->jsBuilder = $builder;
+ return $this;
+ }
+
+ /**
+ * Renders a generic element
+ *
+ * @param HTML_QuickForm2_Node Element being rendered
+ */
+ abstract public function renderElement(HTML_QuickForm2_Node $element);
+
+ /**
+ * Renders a hidden element
+ *
+ * @param HTML_QuickForm2_Node Hidden element being rendered
+ */
+ abstract public function renderHidden(HTML_QuickForm2_Node $element);
+
+ /**
+ * Starts rendering a form, called before processing contained elements
+ *
+ * @param HTML_QuickForm2_Node Form being rendered
+ */
+ abstract public function startForm(HTML_QuickForm2_Node $form);
+
+ /**
+ * Finishes rendering a form, called after processing contained elements
+ *
+ * @param HTML_QuickForm2_Node Form being rendered
+ */
+ abstract public function finishForm(HTML_QuickForm2_Node $form);
+
+ /**
+ * Starts rendering a generic container, called before processing contained elements
+ *
+ * @param HTML_QuickForm2_Node Container being rendered
+ */
+ abstract public function startContainer(HTML_QuickForm2_Node $container);
+
+ /**
+ * Finishes rendering a generic container, called after processing contained elements
+ *
+ * @param HTML_QuickForm2_Node Container being rendered
+ */
+ abstract public function finishContainer(HTML_QuickForm2_Node $container);
+
+ /**
+ * Starts rendering a group, called before processing grouped elements
+ *
+ * @param HTML_QuickForm2_Node Group being rendered
+ */
+ abstract public function startGroup(HTML_QuickForm2_Node $group);
+
+ /**
+ * Finishes rendering a group, called after processing grouped elements
+ *
+ * @param HTML_QuickForm2_Node Group being rendered
+ */
+ abstract public function finishGroup(HTML_QuickForm2_Node $group);
+}
+?>
diff --git a/libs/HTML/QuickForm2/Renderer/Array.php b/libs/HTML/QuickForm2/Renderer/Array.php
new file mode 100644
index 0000000000..57f1dd7000
--- /dev/null
+++ b/libs/HTML/QuickForm2/Renderer/Array.php
@@ -0,0 +1,376 @@
+<?php
+/**
+ * A renderer for HTML_QuickForm2 building an array of form elements
+ *
+ * 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>
+ * @author Thomas Schulz <ths@4bconsult.de>
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version SVN: $Id: Array.php 294052 2010-01-26 20:00:22Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Abstract base class for QuickForm2 renderers
+ */
+require_once 'HTML/QuickForm2/Renderer.php';
+
+/**
+ * A renderer for HTML_QuickForm2 building an array of form elements
+ *
+ * Based on Array renderer from HTML_QuickForm 3.x package
+ *
+ * The form array structure is the following:
+ * <pre>
+ * array(
+ * 'id' => form's "id" attribute (string),
+ * 'frozen' => whether the form is frozen (bool),
+ * 'attributes' => attributes for &lt;form&gt; tag (string),
+ * // if form contains required elements:
+ * 'required_note' => note about the required elements (string),
+ * // if 'group_hiddens' option is true:
+ * 'hidden' => array with html of hidden elements (array),
+ * // if 'group_errors' option is true:
+ * 'errors' => array(
+ * '1st element id' => 'Error for the 1st element',
+ * ...
+ * 'nth element id' => 'Error for the nth element'
+ * ),
+ * 'elements' => array(
+ * element_1,
+ * ...
+ * element_N
+ * )
+ * );
+ * </pre>
+ * Where element_i is an array of the form
+ * <pre>
+ * array(
+ * 'id' => element id (string),
+ * 'type' => type of the element (string),
+ * 'frozen' => whether element is frozen (bool),
+ * // if element has a label:
+ * 'label' => 'label for the element',
+ * // note that if 'static_labels' option is true and element's label is an
+ * // array then there will be several 'label_*' keys corresponding to
+ * // labels' array keys
+ * 'required' => whether element is required (bool),
+ * // if a validation error is present and 'group_errors' option is false:
+ * 'error' => error associated with the element (string),
+ * // if some style was associated with an element:
+ * 'style' => 'some information about element style (e.g. for Smarty)',
+ *
+ * // if element is not a Container
+ * 'value' => element value (mixed),
+ * 'html' => HTML for the element (string),
+ *
+ * // if element is a Container
+ * 'attributes' => container attributes (string)
+ * // only for groups, if separator is set:
+ * 'separator' => separator for group elements (mixed),
+ * 'elements' => array(
+ * element_1,
+ * ...
+ * element_N
+ * )
+ * );
+ * </pre>
+ *
+ * While almost everything in this class is defined as public, its properties
+ * and those methods that are not published (i.e. not in array returned by
+ * exportMethods()) will be available to renderer plugins only.
+ *
+ * The following methods are published:
+ * - {@link reset()}
+ * - {@link toArray()}
+ * - {@link setStyleForId()}
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @author Thomas Schulz <ths@4bconsult.de>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Renderer_Array extends HTML_QuickForm2_Renderer
+{
+ /**
+ * An array being generated
+ * @var array
+ */
+ public $array = array();
+
+ /**
+ * Array with references to 'elements' fields of currently processed containers
+ * @var unknown_type
+ */
+ public $containers = array();
+
+ /**
+ * Whether the form contains required elements
+ * @var bool
+ */
+ public $hasRequired = false;
+
+ /**
+ * Additional style information for elements
+ * @var array
+ */
+ public $styles = array();
+
+ /**
+ * Constructor, adds a new 'static_labels' option
+ */
+ protected function __construct()
+ {
+ $this->options['static_labels'] = false;
+ }
+
+ protected function exportMethods()
+ {
+ return array(
+ 'reset',
+ 'toArray',
+ 'setStyleForId'
+ );
+ }
+
+ /**
+ * Resets the accumulated data
+ *
+ * This method is called automatically by startForm() method, but should
+ * be called manually before calling other rendering methods separately.
+ *
+ * @return HTML_QuickForm2_Renderer_Array
+ */
+ public function reset()
+ {
+ $this->array = array();
+ $this->containers = array();
+ $this->hasRequired = false;
+
+ return $this;
+ }
+
+ /**
+ * Returns the resultant array
+ *
+ * @return array
+ */
+ public function toArray()
+ {
+ return $this->array;
+ }
+
+ /**
+ * Creates an array with fields that are common to all elements
+ *
+ * @param HTML_QuickForm2_Node Element being rendered
+ * @return array
+ */
+ public function buildCommonFields(HTML_QuickForm2_Node $element)
+ {
+ $ary = array(
+ 'id' => $element->getId(),
+ 'frozen' => $element->toggleFrozen()
+ );
+ if ($labels = $element->getLabel()) {
+ if (!is_array($labels) || !$this->options['static_labels']) {
+ $ary['label'] = $labels;
+ } else {
+ foreach ($labels as $key => $label) {
+ $key = is_int($key)? $key + 1: $key;
+ if (1 === $key) {
+ $ary['label'] = $label;
+ } else {
+ $ary['label_' . $key] = $label;
+ }
+ }
+ }
+ }
+ if (($error = $element->getError()) && $this->options['group_errors']) {
+ $this->array['errors'][$ary['id']] = $error;
+ } elseif ($error) {
+ $ary['error'] = $error;
+ }
+ if (isset($this->styles[$ary['id']])) {
+ $ary['style'] = $this->styles[$ary['id']];
+ }
+ if (!$element instanceof HTML_QuickForm2_Container) {
+ $ary['html'] = $element->__toString();
+ } else {
+ $ary['elements'] = array();
+ $ary['attributes'] = $element->getAttributes(true);
+ }
+ return $ary;
+ }
+
+ /**
+ * Stores an array representing "scalar" element in the form array
+ *
+ * @param array
+ */
+ public function pushScalar(array $element)
+ {
+ if (!empty($element['required'])) {
+ $this->hasRequired = true;
+ }
+ if (empty($this->containers)) {
+ $this->array += $element;
+ } else {
+ $this->containers[count($this->containers) - 1][] = $element;
+ }
+ }
+
+ /**
+ * Stores an array representing a Container in the form array
+ *
+ * @param array
+ */
+ public function pushContainer(array $container)
+ {
+ if (!empty($container['required'])) {
+ $this->hasRequired = true;
+ }
+ if (empty($this->containers)) {
+ $this->array += $container;
+ $this->containers = array(&$this->array['elements']);
+ } else {
+ $cntIndex = count($this->containers) - 1;
+ $myIndex = count($this->containers[$cntIndex]);
+ $this->containers[$cntIndex][$myIndex] = $container;
+ $this->containers[$cntIndex + 1] =& $this->containers[$cntIndex][$myIndex]['elements'];
+ }
+ }
+
+ /**
+ * Sets a style for element rendering
+ *
+ * "Style" is some information that is opaque to Array Renderer but may be
+ * of use to e.g. template engine that receives the resultant array.
+ *
+ * @param string|array Element id or array ('element id' => 'style')
+ * @param sting Element style if $idOrStyles is not an array
+ * @return HTML_QuickForm2_Renderer_Array
+ */
+ public function setStyleForId($idOrStyles, $style = null)
+ {
+ if (is_array($idOrStyles)) {
+ $this->styles = array_merge($this->styles, $idOrStyles);
+ } else {
+ $this->styles[$idOrStyles] = $style;
+ }
+ return $this;
+ }
+
+ /**#@+
+ * Implementations of abstract methods from {@link HTML_QuickForm2_Renderer}
+ */
+ public function renderElement(HTML_QuickForm2_Node $element)
+ {
+ $ary = $this->buildCommonFields($element) + array(
+ 'value' => $element->getValue(),
+ 'type' => $element->getType(),
+ 'required' => $element->isRequired(),
+ );
+ $this->pushScalar($ary);
+ }
+
+ public function renderHidden(HTML_QuickForm2_Node $element)
+ {
+ if ($this->options['group_hiddens']) {
+ $this->array['hidden'][] = $element->__toString();
+ } else {
+ $this->renderElement($element);
+ }
+ }
+
+ public function startForm(HTML_QuickForm2_Node $form)
+ {
+ $this->reset();
+
+ $this->array = $this->buildCommonFields($form);
+ if ($this->options['group_errors']) {
+ $this->array['errors'] = array();
+ }
+ if ($this->options['group_hiddens']) {
+ $this->array['hidden'] = array();
+ }
+ $this->containers = array(&$this->array['elements']);
+ }
+
+ public function finishForm(HTML_QuickForm2_Node $form)
+ {
+ $this->finishContainer($form);
+ if ($this->hasRequired) {
+ $this->array['required_note'] = $this->options['required_note'];
+ }
+ }
+
+ public function startContainer(HTML_QuickForm2_Node $container)
+ {
+ $ary = $this->buildCommonFields($container) + array(
+ 'required' => $container->isRequired(),
+ 'type' => $container->getType()
+ );
+ $this->pushContainer($ary);
+ }
+
+ public function finishContainer(HTML_QuickForm2_Node $container)
+ {
+ array_pop($this->containers);
+ }
+
+ public function startGroup(HTML_QuickForm2_Node $group)
+ {
+ $ary = $this->buildCommonFields($group) + array(
+ 'required' => $group->isRequired(),
+ 'type' => $group->getType()
+ );
+ if ($separator = $group->getSeparator()) {
+ $ary['separator'] = $separator;
+ }
+ $this->pushContainer($ary);
+ }
+
+ public function finishGroup(HTML_QuickForm2_Node $group)
+ {
+ $this->finishContainer($group);
+ }
+ /**#@-*/
+}
+?>
diff --git a/libs/HTML/QuickForm2/Renderer/Default.php b/libs/HTML/QuickForm2/Renderer/Default.php
new file mode 100644
index 0000000000..a58f011fbe
--- /dev/null
+++ b/libs/HTML/QuickForm2/Renderer/Default.php
@@ -0,0 +1,598 @@
+<?php
+/**
+ * Default renderer for HTML_QuickForm2
+ *
+ * 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: Default.php 299706 2010-05-24 18:32:37Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Abstract base class for QuickForm2 renderers
+ */
+require_once 'HTML/QuickForm2/Renderer.php';
+
+/**
+ * Default renderer for QuickForm2
+ *
+ * Mostly a direct port of Default renderer from QuickForm 3.x package.
+ *
+ * While almost everything in this class is defined as public, its properties
+ * and those methods that are not published (i.e. not in array returned by
+ * exportMethods()) will be available to renderer plugins only.
+ *
+ * The following methods are published:
+ * - {@link reset()}
+ * - {@link setTemplateForClass()}
+ * - {@link setTemplateForId()}
+ * - {@link setErrorTemplate()}
+ * - {@link setElementTemplateForGroupClass()}
+ * - {@link setElementTemplateForGroupId()}
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Renderer_Default extends HTML_QuickForm2_Renderer
+{
+ /**
+ * Whether the form contains required elements
+ * @var bool
+ */
+ public $hasRequired = false;
+
+ /**
+ * HTML generated for the form
+ * @var array
+ */
+ public $html = array(array());
+
+ /**
+ * HTML for hidden elements if 'group_hiddens' option is on
+ * @var string
+ */
+ public $hiddenHtml = '';
+
+ /**
+ * Array of validation errors if 'group_errors' option is on
+ * @var array
+ */
+ public $errors = array();
+
+ /**
+ * Default templates for elements of the given class
+ * @var array
+ */
+ public $templatesForClass = array(
+ 'html_quickform2_element_inputhidden' => '<div style="display: none;">{element}</div>',
+ 'html_quickform2' => '<div class="quickform">{errors}<form{attributes}>{hidden}{content}</form><qf:reqnote><div class="reqnote">{reqnote}</div></qf:reqnote></div>',
+ 'html_quickform2_container_fieldset' => '<fieldset{attributes}><qf:label><legend id="{id}-legend">{label}</legend></qf:label>{content}</fieldset>',
+ 'special:error' => array(
+ 'prefix' => '<div class="errors"><qf:message><p>{message}</p></qf:message><ul><li>',
+ 'separator' => '</li><li>',
+ 'suffix' => '</li></ul><qf:message><p>{message}</p></qf:message></div>'
+ ),
+ 'html_quickform2_element' => '<div class="row"><label for="{id}" class="element"><qf:required><span class="required">* </span></qf:required>{label}</label><div class="element<qf:error> error</qf:error>"><qf:error><span class="error">{error}</span><br /></qf:error>{element}</div></div>',
+ 'html_quickform2_container_group' => '<div class="row"><label class="element"><qf:required><span class="required">* </span></qf:required>{label}</label><div class="element group<qf:error> error</qf:error>"><qf:error><span class="error">{error}</span><br /></qf:error>{content}</div></div>'
+ );
+
+ /**
+ * Custom templates for elements with the given IDs
+ * @var array
+ */
+ public $templatesForId = array();
+
+ /**
+ * Default templates for elements in groups of the given classes
+ *
+ * Array has the form ('group class' => ('element class' => 'template', ...), ...)
+ *
+ * @var array
+ */
+ public $elementTemplatesForGroupClass = array(
+ 'html_quickform2_container' => array(
+ 'html_quickform2_element' => '{element}',
+ 'html_quickform2_container_fieldset' => '<fieldset{attributes}><qf:label><legend id="{id}-legend">{label}</legend></qf:label>{content}</fieldset>'
+ )
+ );
+
+ /**
+ * Custom templates for grouped elements in the given group IDs
+ *
+ * Array has the form ('group id' => ('element class' => 'template', ...), ...)
+ *
+ * @var array
+ */
+ public $elementTemplatesForGroupId = array();
+
+ /**
+ * Array containing IDs of the groups being rendered
+ * @var array
+ */
+ public $groupId = array();
+
+ protected function exportMethods()
+ {
+ return array(
+ 'reset',
+ 'setTemplateForClass',
+ 'setTemplateForId',
+ 'setErrorTemplate',
+ 'setGroupedTemplateForClass',
+ 'setElementTemplateForGroupClass',
+ 'setElementTemplateForGroupId'
+ );
+ }
+
+ /**
+ * Sets template for form elements that are instances of the given class
+ *
+ * When searching for a template to use, renderer will check for templates
+ * set for element's class and its parent classes, until found. Thus a more
+ * specific template will override a more generic one.
+ *
+ * @param string Class name
+ * @param mixed Template to use for elements of that class
+ * @return HTML_QuickForm2_Renderer_Default
+ */
+ public function setTemplateForClass($className, $template)
+ {
+ $this->templatesForClass[strtolower($className)] = $template;
+ return $this;
+ }
+
+ /**
+ * Sets template for form element with the given id
+ *
+ * If a template is set for an element via this method, it will be used.
+ * In the other case a generic template set by {@link setTemplateForClass()}
+ * or {@link setGroupedTemplateForClass()} will be used.
+ *
+ * @param string Element's id
+ * @param mixed Template to use for rendering of that element
+ * @return HTML_QuickForm2_Renderer_Default
+ */
+ public function setTemplateForId($id, $template)
+ {
+ $this->templatesForId[$id] = $template;
+ return $this;
+ }
+
+ /**
+ * Sets template for rendering validation errors
+ *
+ * This template will be used if 'group_errors' option is set to true.
+ * The template array should contain 'prefix', 'suffix' and 'separator'
+ * keys.
+ *
+ * @param array Template for validation errors
+ * @return HTML_QuickForm2_Renderer_Default
+ */
+ public function setErrorTemplate(array $template)
+ {
+ return $this->setTemplateForClass('special:error', $template);
+ }
+
+ /**
+ * Sets grouped elements templates using group class
+ *
+ * Templates set via {@link setTemplateForClass()} will not be used for
+ * grouped form elements. When searching for a template to use, the renderer
+ * will first consider template set for a specific group id, then the
+ * group templates set by group class.
+ *
+ * @param string Group class name
+ * @param string Element class name
+ * @param mixed Template
+ * @return HTML_QuickForm2_Renderer_Default
+ */
+ public function setElementTemplateForGroupClass($groupClass, $elementClass, $template)
+ {
+ $this->elementTemplatesForGroupClass[strtolower($groupClass)][strtolower($elementClass)] = $template;
+ return $this;
+ }
+
+ /**
+ * Sets grouped elements templates using group id
+ *
+ * Templates set via {@link setTemplateForClass()} will not be used for
+ * grouped form elements. When searching for a template to use, the renderer
+ * will first consider template set for a specific group id, then the
+ * group templates set by group class.
+ *
+ * @param string Group id
+ * @param string Element class name
+ * @param mixed Template
+ * @return HTML_QuickForm2_Renderer_Default
+ */
+ public function setElementTemplateForGroupId($groupId, $elementClass, $template)
+ {
+ $this->elementTemplatesForGroupId[$groupId][strtolower($elementClass)] = $template;
+ return $this;
+ }
+
+ /**
+ * Resets the accumulated data
+ *
+ * This method is called automatically by startForm() method, but should
+ * be called manually before calling other rendering methods separately.
+ *
+ * @return HTML_QuickForm2_Renderer_Default
+ */
+ public function reset()
+ {
+ $this->html = array(array());
+ $this->hiddenHtml = '';
+ $this->errors = array();
+ $this->hasRequired = false;
+ $this->groupId = array();
+
+ return $this;
+ }
+
+ /**
+ * Returns generated HTML
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return (isset($this->html[0][0])? $this->html[0][0]: '') .
+ $this->hiddenHtml;
+ }
+
+ /**
+ * Renders a generic element
+ *
+ * @param HTML_QuickForm2_Node Element being rendered
+ */
+ public function renderElement(HTML_QuickForm2_Node $element)
+ {
+ $elTpl = $this->prepareTemplate($this->findTemplate($element), $element);
+ $this->html[count($this->html) - 1][] = str_replace(array('{element}', '{id}'),
+ array($element, $element->getId()), $elTpl);
+ }
+
+ /**
+ * Renders a hidden element
+ *
+ * @param HTML_QuickForm2_Node Hidden element being rendered
+ */
+ public function renderHidden(HTML_QuickForm2_Node $element)
+ {
+ if ($this->options['group_hiddens']) {
+ $this->hiddenHtml .= $element->__toString();
+ } else {
+ $this->html[count($this->html) - 1][] = str_replace('{element}', $element,
+ $this->findTemplate($element));
+ }
+ }
+
+ /**
+ * Starts rendering a generic container, called before processing contained elements
+ *
+ * @param HTML_QuickForm2_Node Container being rendered
+ */
+ public function startContainer(HTML_QuickForm2_Node $container)
+ {
+ $this->html[] = array();
+ $this->groupId[] = false;
+ }
+
+ /**
+ * Finishes rendering a generic container, called after processing contained elements
+ *
+ * @param HTML_QuickForm2_Node Container being rendered
+ */
+ public function finishContainer(HTML_QuickForm2_Node $container)
+ {
+ array_pop($this->groupId);
+
+ $cTpl = str_replace(
+ array('{attributes}', '{id}'),
+ array($container->getAttributes(true), $container->getId()),
+ $this->prepareTemplate($this->findTemplate($container, '{content}'), $container)
+ );
+ $cHtml = array_pop($this->html);
+ $break = HTML_Common2::getOption('linebreak');
+ $indent = str_repeat(HTML_Common2::getOption('indent'), count($this->html));
+ $this->html[count($this->html) - 1][] = str_replace(
+ '{content}', $break . $indent . implode($break . $indent, $cHtml), $cTpl
+ );
+ }
+
+ /**
+ * Starts rendering a group, called before processing grouped elements
+ *
+ * @param HTML_QuickForm2_Node Group being rendered
+ */
+ public function startGroup(HTML_QuickForm2_Node $group)
+ {
+ $this->html[] = array();
+ $this->groupId[] = $group->getId();
+ }
+
+ /**
+ * Finishes rendering a group, called after processing grouped elements
+ *
+ * @param HTML_QuickForm2_Node Group being rendered
+ */
+ public function finishGroup(HTML_QuickForm2_Node $group)
+ {
+ $gTpl = str_replace(
+ array('{attributes}', '{id}'),
+ array($group->getAttributes(true), array_pop($this->groupId)),
+ $this->prepareTemplate($this->findTemplate($group, '{content}'), $group)
+ );
+
+ $separator = $group->getSeparator();
+ $elements = array_pop($this->html);
+ if (!is_array($separator)) {
+ $content = implode((string)$separator, $elements);
+ } else {
+ $content = '';
+ $cSeparator = count($separator);
+ for ($i = 0, $count = count($elements); $i < $count; $i++) {
+ $content .= (0 == $i? '': $separator[($i - 1) % $cSeparator]) .
+ $elements[$i];
+ }
+ }
+
+ $this->html[count($this->html) - 1][] = str_replace('{content}', $content, $gTpl);
+ }
+
+ /**
+ * Starts rendering a form, called before processing contained elements
+ *
+ * @param HTML_QuickForm2_Node Form being rendered
+ */
+ public function startForm(HTML_QuickForm2_Node $form)
+ {
+ $this->reset();
+ }
+
+ /**
+ * Finishes rendering a form, called after processing contained elements
+ *
+ * @param HTML_QuickForm2_Node Form being rendered
+ */
+ public function finishForm(HTML_QuickForm2_Node $form)
+ {
+ $formTpl = str_replace(
+ array('{attributes}', '{hidden}', '{errors}'),
+ array($form->getAttributes(true), $this->hiddenHtml,
+ $this->outputGroupedErrors()),
+ $this->findTemplate($form, '{content}')
+ );
+ $this->hiddenHtml = '';
+
+ // required note
+ if (!$this->hasRequired || $form->toggleFrozen() ||
+ empty($this->options['required_note']))
+ {
+ $formTpl = preg_replace('!<qf:reqnote>.*</qf:reqnote>!isU', '', $formTpl);
+ } else {
+ $formTpl = str_replace(
+ array('<qf:reqnote>', '</qf:reqnote>', '{reqnote}'),
+ array('', '', $this->options['required_note']),
+ $formTpl
+ );
+ }
+
+ $break = HTML_Common2::getOption('linebreak');
+ $script = $this->getJavascriptBuilder()->__toString();
+ $this->html[0] = array((empty($script)? '': $script . $break) . str_replace(
+ '{content}', $break . implode($break, $this->html[0]), $formTpl
+ ));
+ }
+
+ /**
+ * Creates a error list if 'group_errors' option is true
+ *
+ * @return string HTML with a list of all validation errors
+ */
+ public function outputGroupedErrors()
+ {
+ if (empty($this->errors)) {
+ return '';
+ }
+ if (!empty($this->options['errors_prefix'])) {
+ $errorHtml = str_replace(array('<qf:message>', '</qf:message>', '{message}'),
+ array('', '', $this->options['errors_prefix']),
+ $this->templatesForClass['special:error']['prefix']);
+ } else {
+ $errorHtml = preg_replace('!<qf:message>.*</qf:message>!isU', '',
+ $this->templatesForClass['special:error']['prefix']);
+ }
+ $errorHtml .= implode($this->templatesForClass['special:error']['separator'], $this->errors);
+ if (!empty($this->options['errors_suffix'])) {
+ $errorHtml .= str_replace(array('<qf:message>', '</qf:message>', '{message}'),
+ array('', '', $this->options['errors_suffix']),
+ $this->templatesForClass['special:error']['suffix']);
+ } else {
+ $errorHtml .= preg_replace('!<qf:message>.*</qf:message>!isU', '',
+ $this->templatesForClass['special:error']['suffix']);
+ }
+ return $errorHtml;
+ }
+
+ /**
+ * Finds a proper template for the element
+ *
+ * Templates are scanned in a predefined order. First, if a template was
+ * set for a specific element by id, it is returned, no matter if the
+ * element belongs to a group. If the element does not belong to a group,
+ * we try to match a template using the element class.
+ * But, if the element belongs to a group, templates are first looked up
+ * using the containing group id, then using the containing group class.
+ * When no template is found, the provided default template is returned.
+ *
+ * @param HTML_QuickForm2_Node Element being rendered
+ * @param string Default template to use if not found
+ * @return string Template
+ */
+ public function findTemplate(HTML_QuickForm2_Node $element, $default = '{element}')
+ {
+ if (!empty($this->templatesForId[$element->getId()])) {
+ return $this->templatesForId[$element->getId()];
+ }
+ $class = strtolower(get_class($element));
+ $groupId = end($this->groupId);
+ $elementClasses = array();
+ do {
+ if (empty($groupId) && !empty($this->templatesForClass[$class])) {
+ return $this->templatesForClass[$class];
+ }
+ $elementClasses[$class] = true;
+ } while ($class = strtolower(get_parent_class($class)));
+
+ if (!empty($groupId)) {
+ if (!empty($this->elementTemplatesForGroupId[$groupId])) {
+ while (list($elClass) = each($elementClasses)) {
+ if (!empty($this->elementTemplatesForGroupId[$groupId][$elClass])) {
+ return $this->elementTemplatesForGroupId[$groupId][$elClass];
+ }
+ }
+ }
+
+ $group = $element->getContainer();
+ $grClass = strtolower(get_class($group));
+ do {
+ if (!empty($this->elementTemplatesForGroupClass[$grClass])) {
+ reset($elementClasses);
+ while (list($elClass) = each($elementClasses)) {
+ if (!empty($this->elementTemplatesForGroupClass[$grClass][$elClass])) {
+ return $this->elementTemplatesForGroupClass[$grClass][$elClass];
+ }
+ }
+ }
+ } while ($grClass = strtolower(get_parent_class($grClass)));
+ }
+ return $default;
+ }
+
+ /**
+ * Processes the element's template, adding label(s), required note and error message
+ *
+ * @param string Element template
+ * @param HTML_QuickForm2_Node Element being rendered
+ * @return string Template with some substitutions done
+ */
+ public function prepareTemplate($elTpl, HTML_QuickForm2_Node $element)
+ {
+ // if element is required
+ $elTpl = $this->markRequired($elTpl, $element->isRequired());
+ $elTpl = $this->outputError($elTpl, $element->getError());
+ return $this->outputLabel($elTpl, $element->getLabel());
+ }
+
+ /**
+ * Marks element required or removes "required" block
+ *
+ * @param string Element template
+ * @param bool Whether element is required
+ * @return string Template with processed "required" block
+ */
+ public function markRequired($elTpl, $required)
+ {
+ if ($required) {
+ $this->hasRequired = true;
+ $elTpl = str_replace(array('<qf:required>', '</qf:required>'),
+ array('', ''), $elTpl);
+ } else {
+ $elTpl = preg_replace('!<qf:required>.*</qf:required>!isU', '', $elTpl);
+ }
+ return $elTpl;
+ }
+
+ /**
+ * Outputs element error, removes empty error blocks
+ *
+ * @param string Element template
+ * @param string Validation error for the element
+ * @return string Template with error substitutions done
+ */
+ public function outputError($elTpl, $error)
+ {
+ if ($error && !$this->options['group_errors']) {
+ $elTpl = str_replace(array('<qf:error>', '</qf:error>', '{error}'),
+ array('', '', $error), $elTpl);
+ } else {
+ if ($error && $this->options['group_errors']) {
+ $this->errors[] = $error;
+ }
+ $elTpl = preg_replace('!<qf:error>.*</qf:error>!isU', '', $elTpl);
+ }
+ return $elTpl;
+ }
+
+ /**
+ * Outputs element's label(s), removes empty label blocks
+ *
+ * @param string Element template
+ * @param mixed Element label(s)
+ * @return string Template with label substitutions done
+ */
+ public function outputLabel($elTpl, $label)
+ {
+ $mainLabel = is_array($label)? array_shift($label): $label;
+ $elTpl = str_replace('{label}', $mainLabel, $elTpl);
+ if (false !== strpos($elTpl, '<qf:label>')) {
+ if ($mainLabel) {
+ $elTpl = str_replace(array('<qf:label>', '</qf:label>'), array('', ''), $elTpl);
+ } else {
+ $elTpl = preg_replace('!<qf:label>.*</qf:label>!isU', '', $elTpl);
+ }
+ }
+ if (is_array($label)) {
+ foreach($label as $key => $text) {
+ $key = is_int($key)? $key + 2: $key;
+ $elTpl = str_replace(array('<qf:label_' . $key . '>', '</qf:label_' . $key . '>', '{label_' . $key . '}'),
+ array('', '', $text), $elTpl);
+ }
+ }
+ if (strpos($elTpl, '{label_')) {
+ $elTpl = preg_replace('!<qf:label_([^>]+)>.*</qf:label_\1>!isU', '', $elTpl);
+ }
+ return $elTpl;
+ }
+}
+?> \ No newline at end of file
diff --git a/libs/HTML/QuickForm2/Renderer/Plugin.php b/libs/HTML/QuickForm2/Renderer/Plugin.php
new file mode 100644
index 0000000000..eb0aa9114e
--- /dev/null
+++ b/libs/HTML/QuickForm2/Renderer/Plugin.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Abstract base class for HTML_QuickForm2_Renderer plugin classes
+ *
+ * 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: Plugin.php 294057 2010-01-26 21:10:28Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Abstract base class for HTML_QuickForm2_Renderer plugin classes
+ *
+ * @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_Renderer_Plugin
+{
+ protected $renderer;
+
+ /**
+ * Sets the base renderer this plugin is enhancing
+ *
+ * @param HTML_QuickForm2_Renderer base renderer
+ */
+ public function setRenderer(HTML_QuickForm2_Renderer $renderer)
+ {
+ $this->renderer = $renderer;
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Renderer/Proxy.php b/libs/HTML/QuickForm2/Renderer/Proxy.php
new file mode 100644
index 0000000000..5b424ea1c0
--- /dev/null
+++ b/libs/HTML/QuickForm2/Renderer/Proxy.php
@@ -0,0 +1,262 @@
+<?php
+/**
+ * Proxy class for HTML_QuickForm2 renderers and their plugins
+ *
+ * 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: Proxy.php 299706 2010-05-24 18:32:37Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Abstract base class for QuickForm2 renderers
+ */
+require_once 'HTML/QuickForm2/Renderer.php';
+
+/**
+ * Proxy class for HTML_QuickForm2 renderers and their plugins
+ *
+ * This class serves two purposes:
+ * <ol>
+ * <li>Aggregates renderer and its plugins. From user's point of view
+ * renderer plugins simply add new methods to renderer instances.</li>
+ * <li>Restricts access to renderer properties and methods. Those are defined
+ * as 'public' to allow easy access from plugins, but only methods
+ * with names explicitly returned by Renderer::exportMethods() are
+ * available to the outside world.</li>
+ * </ol>
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Renderer_Proxy extends HTML_QuickForm2_Renderer
+{
+ /**
+ * Renderer instance
+ * @var HTML_QuickForm2_Renderer
+ */
+ private $_renderer;
+
+ /**
+ * Additional renderer methods to proxy via __call(), as returned by exportMethods()
+ * @var array
+ */
+ private $_rendererMethods = array();
+
+ /**
+ * Reference to a list of registered renderer plugins for that renderer type
+ * @var array
+ */
+ private $_pluginClasses;
+
+ /**
+ * Plugins for this renderer
+ * @var array
+ */
+ private $_plugins = array();
+
+ /**
+ * Plugin methods to call via __call() magic method
+ *
+ * Array has the form ('lowercase method name' => 'index in _plugins array')
+ *
+ * @var array
+ */
+ private $_pluginMethods = array();
+
+ /**
+ * Constructor, sets proxied renderer and its plugins
+ *
+ * @param HTML_QuickForm2_Renderer Renderer instance to proxy
+ * @param array Plugins registered for that renderer type
+ */
+ protected function __construct(HTML_QuickForm2_Renderer $renderer, array &$pluginClasses)
+ {
+ foreach ($renderer->exportMethods() as $method) {
+ $this->_rendererMethods[strtolower($method)] = true;
+ }
+ $this->_renderer = $renderer;
+ $this->_pluginClasses = &$pluginClasses;
+ }
+
+ /**
+ * Magic function; call an imported method of a renderer or its plugin
+ *
+ * @param string method name
+ * @param array method arguments
+ * @return mixed
+ */
+ public function __call($name, $arguments)
+ {
+ $lower = strtolower($name);
+ if (isset($this->_rendererMethods[$lower])) {
+ // support fluent interfaces
+ $ret = call_user_func_array(array($this->_renderer, $name), $arguments);
+ return $ret === $this->_renderer? $this: $ret;
+ }
+ // any additional plugins since last __call()?
+ for ($i = count($this->_plugins); $i < count($this->_pluginClasses); $i++) {
+ list($className, $includeFile) = $this->_pluginClasses[$i];
+ HTML_QuickForm2_Loader::loadClass($className, $includeFile);
+ $this->addPlugin($i, new $className);
+ }
+ if (isset($this->_pluginMethods[$lower])) {
+ return call_user_func_array(
+ array($this->_plugins[$this->_pluginMethods[$lower]], $name),
+ $arguments
+ );
+ }
+ trigger_error("Fatal error: Call to undefined method " .
+ get_class($this->_renderer) . "::" . $name . "()", E_USER_ERROR);
+ }
+
+ /**
+ * Adds a plugin for the current renderer instance
+ *
+ * Plugin's methods are imported and can be later called as this object's own
+ *
+ * @param HTML_QuickForm2_Renderer_Plugin a plugin instance
+ * @throws HTML_QuickForm2_InvalidArgumentException if a plugin has already
+ * imported name
+ */
+ protected function addPlugin($index, HTML_QuickForm2_Renderer_Plugin $plugin)
+ {
+ $methods = array();
+ $reflection = new ReflectionObject($plugin);
+ foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
+ $lower = strtolower($method->getName());
+ if ('HTML_QuickForm2_Renderer_Plugin' == $method->getDeclaringClass()->getName()) {
+ continue;
+ } elseif (isset($this->_rendererMethods[$lower])
+ || isset($this->_pluginMethods[$lower])
+ ) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'Duplicate method name: name ' . $method->getName() . ' in plugin ' .
+ get_class($plugin) . ' already taken by ' .
+ (isset($this->_rendererMethods[$lower])?
+ get_class($this->_renderer):
+ get_class($this->_plugins[$this->_pluginMethods[$lower]])
+ )
+ );
+ }
+ $methods[$lower] = $index;
+ }
+ $plugin->setRenderer($this->_renderer);
+ $this->_plugins[$index] = $plugin;
+ $this->_pluginMethods += $methods;
+ }
+
+ /**#@+
+ * Proxies for methods defined in {@link HTML_QuickForm2_Renderer}
+ */
+ public function setOption($nameOrOptions, $value = null)
+ {
+ $this->_renderer->setOption($nameOrOptions, $value);
+ return $this;
+ }
+
+ public function getOption($name = null)
+ {
+ return $this->_renderer->getOption($name);
+ }
+
+ public function getJavascriptBuilder()
+ {
+ return $this->_renderer->getJavascriptBuilder();
+ }
+
+ public function setJavascriptBuilder(HTML_QuickForm2_JavascriptBuilder $builder = null)
+ {
+ $this->_renderer->setJavascriptBuilder($builder);
+ return $this;
+ }
+
+ public function renderElement(HTML_QuickForm2_Node $element)
+ {
+ $this->_renderer->renderElement($element);
+ }
+
+ public function renderHidden(HTML_QuickForm2_Node $element)
+ {
+ $this->_renderer->renderHidden($element);
+ }
+
+ public function startForm(HTML_QuickForm2_Node $form)
+ {
+ $this->_renderer->startForm($form);
+ }
+
+ public function finishForm(HTML_QuickForm2_Node $form)
+ {
+ $this->_renderer->finishForm($form);
+ }
+
+ public function startContainer(HTML_QuickForm2_Node $container)
+ {
+ $this->_renderer->startContainer($container);
+ }
+
+ public function finishContainer(HTML_QuickForm2_Node $container)
+ {
+ $this->_renderer->finishContainer($container);
+ }
+
+ public function startGroup(HTML_QuickForm2_Node $group)
+ {
+ $this->_renderer->startGroup($group);
+ }
+
+ public function finishGroup(HTML_QuickForm2_Node $group)
+ {
+ $this->_renderer->finishGroup($group);
+ }
+ /**#@-*/
+
+ public function __toString()
+ {
+ if (method_exists($this->_renderer, '__toString')) {
+ return $this->_renderer->__toString();
+ }
+ trigger_error("Fatal error: Object of class " . get_class($this->_renderer) .
+ " could not be converted to string", E_USER_ERROR);
+ }
+}
+?> \ No newline at end of file
diff --git a/libs/HTML/QuickForm2/Rule.php b/libs/HTML/QuickForm2/Rule.php
new file mode 100644
index 0000000000..dfb11868b0
--- /dev/null
+++ b/libs/HTML/QuickForm2/Rule.php
@@ -0,0 +1,333 @@
+<?php
+/**
+ * Base class for HTML_QuickForm2 rules
+ *
+ * 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: Rule.php 299706 2010-05-24 18:32:37Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Abstract base class for HTML_QuickForm2 rules
+ *
+ * This class provides methods that allow chaining several rules together.
+ * Its validate() method executes the whole rule chain starting from this rule.
+ *
+ * @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_Rule
+{
+ /**
+ * Constant showing that validation should be run server-side
+ * @see HTML_QuickForm2_Node::addRule()
+ */
+ const RUNAT_SERVER = 1;
+
+ /**
+ * Constant showing that validation should be run client-side
+ * @see HTML_QuickForm2_Node::addRule()
+ */
+ const RUNAT_CLIENT = 2;
+
+ /**
+ * An element whose value will be validated by this rule
+ * @var HTML_QuickForm2_Node
+ */
+ protected $owner;
+
+ /**
+ * An error message to display if validation fails
+ * @var string
+ */
+ protected $message;
+
+ /**
+ * Configuration data for the rule
+ * @var mixed
+ */
+ protected $config;
+
+ /**
+ * Rules chained to this via "and" and "or" operators
+ *
+ * The contents can be described as "disjunctive normal form", where an outer
+ * array represents a disjunction of conjunctive clauses represented by inner
+ * arrays.
+ *
+ * @var array
+ */
+ protected $chainedRules = array(array());
+
+
+ /**
+ * Class constructor
+ *
+ * @param HTML_QuickForm2_Node Element to validate
+ * @param string Error message to display if validation fails
+ * @param mixed Configuration data for the rule
+ */
+ public function __construct(HTML_QuickForm2_Node $owner, $message = '', $config = null)
+ {
+ $this->setOwner($owner);
+ $this->setMessage($message);
+ $this->setConfig($config);
+ }
+
+ /**
+ * Merges local configuration with that provided for registerRule()
+ *
+ * Default behaviour is for global config to override local one, different
+ * Rules may implement more complex merging behaviours.
+ *
+ * @param mixed Local configuration
+ * @param mixed Global configuration, usually provided to {@link HTML_QuickForm2_Factory::registerRule()}
+ * @return mixed Merged configuration
+ */
+ public static function mergeConfig($localConfig, $globalConfig)
+ {
+ return is_null($globalConfig)? $localConfig: $globalConfig;
+ }
+
+ /**
+ * Sets configuration data for the rule
+ *
+ * @param mixed Rule configuration data (specific for a Rule)
+ * @return HTML_QuickForm2_Rule
+ * @throws HTML_QuickForm2_InvalidArgumentException in case of invalid
+ * configuration data
+ */
+ public function setConfig($config)
+ {
+ $this->config = $config;
+ return $this;
+ }
+
+ /**
+ * Returns the rule's configuration data
+ *
+ * @return mixed Configuration data (specific for a Rule)
+ */
+ public function getConfig()
+ {
+ return $this->config;
+ }
+
+ /**
+ * Sets the error message output by the rule
+ *
+ * @param string Error message to display if validation fails
+ * @return HTML_QuickForm2_Rule
+ */
+ public function setMessage($message)
+ {
+ $this->message = (string)$message;
+ return $this;
+ }
+
+ /**
+ * Returns the error message output by the rule
+ *
+ * @return string Error message
+ */
+ public function getMessage()
+ {
+ return $this->message;
+ }
+
+ /**
+ * Sets the element that will be validated by this rule
+ *
+ * @param HTML_QuickForm2_Node Element to validate
+ */
+ public function setOwner(HTML_QuickForm2_Node $owner)
+ {
+ if (null !== $this->owner) {
+ $this->owner->removeRule($this);
+ }
+ $this->owner = $owner;
+ }
+
+ /**
+ * Adds a rule to the chain with an "and" operator
+ *
+ * Evaluation is short-circuited, next rule will not be evaluated if the
+ * previous one returns false. The method is named this way because "and" is
+ * a reserved word in PHP.
+ *
+ * @param HTML_QuickForm2_Rule
+ * @return HTML_QuickForm2_Rule first rule in the chain (i.e. $this)
+ * @throws HTML_QuickForm2_InvalidArgumentException when trying to add
+ * a "required" rule to the chain
+ */
+ public function and_(HTML_QuickForm2_Rule $next)
+ {
+ if ($next instanceof HTML_QuickForm2_Rule_Required) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'and_(): Cannot add a "required" rule'
+ );
+ }
+ $this->chainedRules[count($this->chainedRules) - 1][] = $next;
+ return $this;
+ }
+
+ /**
+ * Adds a rule to the chain with an "or" operator
+ *
+ * Evaluation is short-circuited, next rule will not be evaluated if the
+ * previous one returns true. The method is named this way because "or" is
+ * a reserved word in PHP.
+ *
+ * @param HTML_QuickForm2_Rule
+ * @return HTML_QuickForm2_Rule first rule in the chain (i.e. $this)
+ * @throws HTML_QuickForm2_InvalidArgumentException when trying to add
+ * a "required" rule to the chain
+ */
+ public function or_(HTML_QuickForm2_Rule $next)
+ {
+ if ($next instanceof HTML_QuickForm2_Rule_Required) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'or_(): Cannot add a "required" rule'
+ );
+ }
+ $this->chainedRules[] = array($next);
+ return $this;
+ }
+
+ /**
+ * Performs validation
+ *
+ * The whole rule chain is executed. Note that the side effect of this
+ * method is setting the error message on element if validation fails
+ *
+ * @return boolean Whether the element is valid
+ */
+ public function validate()
+ {
+ $globalValid = false;
+ $localValid = $this->validateOwner();
+ foreach ($this->chainedRules as $item) {
+ foreach ($item as $multiplier) {
+ if (!($localValid = $localValid && $multiplier->validate())) {
+ break;
+ }
+ }
+ if ($globalValid = $globalValid || $localValid) {
+ break;
+ }
+ $localValid = true;
+ }
+ $globalValid or $this->setOwnerError();
+ return $globalValid;
+ }
+
+ /**
+ * Validates the owner element
+ *
+ * @return bool Whether owner element is valid according to the rule
+ */
+ abstract protected function validateOwner();
+
+ /**
+ * Sets the error message on the owner element
+ */
+ protected function setOwnerError()
+ {
+ if (strlen($this->getMessage()) && !$this->owner->getError()) {
+ $this->owner->setError($this->getMessage());
+ }
+ }
+
+ /**
+ * Returns the client-side validation callback
+ *
+ * This essentially builds a Javascript version of validateOwner() method,
+ * with element ID and Rule configuration hardcoded.
+ *
+ * @return string Javascript function to validate the element's value
+ * @throws HTML_QuickForm2_Exception if Rule can only be run server-side
+ */
+ protected function getJavascriptCallback()
+ {
+ throw new HTML_QuickForm2_Exception(
+ get_class($this) . ' does not implement javascript validation'
+ );
+ }
+
+ /**
+ * Returns the client-side representation of the Rule
+ *
+ * The Javascript object returned contains the following fields:
+ * - callback: {@see getJavascriptCallback()}
+ * - elementId: element ID to set error for if validation fails
+ * - errorMessage: error message to set if validation fails
+ * - chained: chained rules, array of arrays like in $chainedRules property
+ *
+ * @return string
+ * @throws HTML_QuickForm2_Exception if Rule or its chained Rules can only
+ * be run server-side
+ */
+ public function getJavascript()
+ {
+ $js = "{\n\tcallback: " . $this->getJavascriptCallback() . ",\n" .
+ "\telementId: '" . $this->owner->getId() . "',\n" .
+ "\terrorMessage: '" . strtr($this->getMessage(), array(
+ "\r" => '\r',
+ "\n" => '\n',
+ "\t" => '\t',
+ "'" => "\\'",
+ '"' => '\"',
+ '\\' => '\\\\'
+ )) . "',\n\tchained: [";
+ $chained = array();
+ foreach ($this->chainedRules as $item) {
+ $multipliers = array();
+ foreach ($item as $multiplier) {
+ $multipliers[] = $multiplier->getJavascript();
+ }
+ $chained[] = '[' . implode(",\n", $multipliers) . ']';
+ }
+ $js .= implode(",\n", $chained) . "]\n}";
+ return $js;
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Rule/Callback.php b/libs/HTML/QuickForm2/Rule/Callback.php
new file mode 100644
index 0000000000..c013d6b033
--- /dev/null
+++ b/libs/HTML/QuickForm2/Rule/Callback.php
@@ -0,0 +1,172 @@
+<?php
+/**
+ * Rule checking the value via a callback function (method)
+ *
+ * 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: Callback.php 294057 2010-01-26 21:10:28Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for HTML_QuickForm2 rules
+ */
+require_once 'HTML/QuickForm2/Rule.php';
+
+/**
+ * Rule checking the value via a callback function (method)
+ *
+ * The Rule needs a valid callback as a configuration parameter for its work, it
+ * may also be given additional arguments to pass to the callback alongside the
+ * element's value. See {@link mergeConfig()} for description of possible ways
+ * to pass configuration parameters.
+ *
+ * The callback will be called with element's value as the first argument, if
+ * additional arguments were provided they'll be passed as well. It is expected
+ * to return false if the value is invalid and true if it is valid.
+ *
+ * Checking that the value is not empty:
+ * <code>
+ * $str->addRule('callback', 'The field should not be empty', 'strlen');
+ * </code>
+ * Checking that the value is in the given array:
+ * <code>
+ * $meta->addRule('callback', 'Unknown variable name',
+ * array('callback' => 'in_array',
+ * 'arguments' => array(array('foo', 'bar', 'baz'))));
+ * </code>
+ * The same, but with rule registering first:
+ * <code>
+ * HTML_QuickForm2_Factory::registerRule(
+ * 'in_array', 'HTML_QuickForm2_Rule_Callback',
+ * 'HTML/QuickForm2/Rule/Callback.php', 'in_array'
+ * );
+ * $meta->addRule('in_array', 'Unknown variable name', array(array('foo', 'bar', 'baz')));
+ * </code>
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Rule_Callback extends HTML_QuickForm2_Rule
+{
+ /**
+ * Validates the owner element
+ *
+ * @return bool the value returned by a callback function
+ */
+ protected function validateOwner()
+ {
+ $value = $this->owner->getValue();
+ $config = $this->getConfig();
+ return (bool)call_user_func_array(
+ $config['callback'], array_merge(array($value), $config['arguments'])
+ );
+ }
+
+ /**
+ * Merges local configuration with that provided for registerRule()
+ *
+ * "Global" configuration may be passed to
+ * {@link HTML_QuickForm2_Factory::registerRule()} in either of the
+ * following formats
+ * - callback
+ * - array(['callback' => callback, ]['arguments' => array(...)])
+ *
+ * "Local" configuration may be passed to the constructor in either of
+ * the following formats
+ * - callback or arguments (interpretation depends on whether the global
+ * configuration already contains the callback)
+ * - array(['callback' => callback, ]['arguments' => array(...)])
+ *
+ * As usual, global config overrides local one. It is a good idea to use the
+ * associative array format to prevent ambiguity.
+ *
+ * @param mixed Local configuration
+ * @param mixed Global configuration
+ * @return mixed Merged configuration
+ */
+ public static function mergeConfig($localConfig, $globalConfig)
+ {
+ if (!isset($globalConfig)) {
+ $config = $localConfig;
+
+ } else {
+ if (!is_array($globalConfig) ||
+ !isset($globalConfig['callback']) && !isset($globalConfig['arguments'])
+ ) {
+ $config = array('callback' => $globalConfig);
+ } else {
+ $config = $globalConfig;
+ }
+ if (is_array($localConfig) && (isset($localConfig['callback'])
+ || isset($localConfig['arguments']))
+ ) {
+ $config += $localConfig;
+ } elseif(isset($localConfig)) {
+ $config += array('callback' => $localConfig, 'arguments' => $localConfig);
+ }
+ }
+ return $config;
+ }
+
+ /**
+ * Sets the callback to use for validation and its additional arguments
+ *
+ * @param callback|array Callback or array ('callback' => validation callback,
+ * 'arguments' => additional arguments)
+ * @return HTML_QuickForm2_Rule
+ * @throws HTML_QuickForm2_InvalidArgumentException if callback is missing or invalid
+ */
+ public function setConfig($config)
+ {
+ if (!is_array($config) || !isset($config['callback'])) {
+ $config = array('callback' => $config);
+ }
+ if (!is_callable($config['callback'], false, $callbackName)) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'Callback Rule requires a valid callback, \'' . $callbackName .
+ '\' was given'
+ );
+ }
+ return parent::setConfig($config + array('arguments' => array()));
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Rule/Compare.php b/libs/HTML/QuickForm2/Rule/Compare.php
new file mode 100644
index 0000000000..b6e83e59df
--- /dev/null
+++ b/libs/HTML/QuickForm2/Rule/Compare.php
@@ -0,0 +1,231 @@
+<?php
+/**
+ * Rule comparing the value of the field with some other value
+ *
+ * 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: Compare.php 299480 2010-05-19 06:55:03Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for HTML_QuickForm2 rules
+ */
+require_once 'HTML/QuickForm2/Rule.php';
+
+/**
+ * Rule comparing the value of the field with some other value
+ *
+ * The Rule needs two configuration parameters for its work
+ * - comparison operator (defaults to equality)
+ * - operand to compare with; this can be either a constant or another form
+ * element (its value will be used)
+ * See {@link mergeConfig()} for description of possible ways to pass
+ * configuration parameters.
+ *
+ * Note that 'less than [or equal]' and 'greater than [or equal]' operators
+ * compare the operands numerically, since this is considered as more useful
+ * approach by the authors.
+ *
+ * For convenience, this Rule is already registered in the Factory with the
+ * names 'eq', 'neq', 'lt', 'gt', 'lte', 'gte' corresponding to the relevant
+ * operators:
+ * <code>
+ * $password->addRule('eq', 'Passwords do not match', $passwordRepeat);
+ * $orderQty->addRule('lte', 'Should not order more than 10 of these', 10);
+ * </code>
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Rule_Compare extends HTML_QuickForm2_Rule
+{
+ /**
+ * Possible comparison operators
+ * @var array
+ */
+ protected $operators = array('==', '!=', '===', '!==', '<', '<=', '>', '>=');
+
+
+ /**
+ * Validates the owner element
+ *
+ * @return bool whether (element_value operator operand) expression is true
+ */
+ protected function validateOwner()
+ {
+ $value = $this->owner->getValue();
+ $config = $this->getConfig();
+ if (!in_array($config['operator'], array('===', '!=='))) {
+ $compareFn = create_function(
+ '$a, $b', 'return floatval($a) ' . $config['operator'] . ' floatval($b);'
+ );
+ } else {
+ $compareFn = create_function(
+ '$a, $b', 'return strval($a) ' . $config['operator'] . ' strval($b);'
+ );
+ }
+ return $compareFn($value, $config['operand'] instanceof HTML_QuickForm2_Node
+ ? $config['operand']->getValue(): $config['operand']);
+ }
+
+ protected function getJavascriptCallback()
+ {
+ $config = $this->getConfig();
+ $operand1 = $this->owner->getJavascriptValue();
+ $operand2 = $config['operand'] instanceof HTML_QuickForm2_Node
+ ? $config['operand']->getJavascriptValue()
+ : "'" . strtr($config['operand'], array(
+ "\r" => '\r',
+ "\n" => '\n',
+ "\t" => '\t',
+ "'" => "\\'",
+ '"' => '\"',
+ '\\' => '\\\\'
+ )) . "'";
+
+ if (!in_array($config['operator'], array('===', '!=='))) {
+ $check = "Number({$operand1}) {$config['operator']} Number({$operand2})";
+ } else {
+ $check = "String({$operand1}) {$config['operator']} String({$operand2})";
+ }
+
+ return "function () { return {$check}; }";
+ }
+
+ /**
+ * Merges local configuration with that provided for registerRule()
+ *
+ * "Global" configuration may be passed to
+ * {@link HTML_QuickForm2_Factory::registerRule()} in
+ * either of the following formats
+ * - operator
+ * - array(operator[, operand])
+ * - array(['operator' => operator, ]['operand' => operand])
+
+ * "Local" configuration may be passed to the constructor in either of
+ * the following formats
+ * - operand
+ * - array([operator, ]operand)
+ * - array(['operator' => operator, ]['operand' => operand])
+ *
+ * As usual, global configuration overrides local one.
+ *
+ * @param mixed Local configuration
+ * @param mixed Global configuration
+ * @return mixed Merged configuration
+ */
+ public static function mergeConfig($localConfig, $globalConfig)
+ {
+ $config = null;
+ if (0 < count($globalConfig)) {
+ $config = self::toCanonicalForm($globalConfig, 'operator');
+ }
+ if (0 < count($localConfig)) {
+ $config = (isset($config)? $config: array())
+ + self::toCanonicalForm($localConfig);
+ }
+ return $config;
+ }
+
+ /**
+ * Converts configuration data to a canonical associative array form
+ *
+ * @param mixed Configuration data
+ * @param string Array key to assign $config to if it is scalar
+ * @return array Associative array that may contain 'operand' and 'operator' keys
+ */
+ protected static function toCanonicalForm($config, $key = 'operand')
+ {
+ if (!is_array($config)) {
+ return array($key => $config);
+
+ } elseif (array_key_exists('operator', $config)
+ || array_key_exists('operand', $config)
+ ) {
+ return $config;
+
+ } elseif (1 == count($config)) {
+ return array($key => end($config));
+
+ } else {
+ return array('operator' => reset($config), 'operand' => end($config));
+ }
+ }
+
+ /**
+ * Sets the comparison operator and operand to compare to
+ *
+ * $config can be either of the following
+ * - operand
+ * - array([operator, ]operand)
+ * - array(['operator' => operator, ]['operand' => operand])
+ * If operator is missing it will default to '==='
+ *
+ * @param mixed Configuration data
+ * @return HTML_QuickForm2_Rule
+ * @throws HTML_QuickForm2_InvalidArgumentException if a bogus comparison
+ * operator is used for configuration, if an operand is missing
+ */
+ public function setConfig($config)
+ {
+ if (0 == count($config)) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'Compare Rule requires an argument to compare with'
+ );
+ }
+ $config = self::toCanonicalForm($config);
+
+ $config += array('operator' => '===');
+ if (!in_array($config['operator'], $this->operators)) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'Compare Rule requires a valid comparison operator, ' .
+ preg_replace('/\s+/', ' ', var_export($config['operator'], true)) . ' given'
+ );
+ }
+ if (in_array($config['operator'], array('==', '!='))) {
+ $config['operator'] .= '=';
+ }
+
+ return parent::setConfig($config);
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Rule/Each.php b/libs/HTML/QuickForm2/Rule/Each.php
new file mode 100644
index 0000000000..721c87950f
--- /dev/null
+++ b/libs/HTML/QuickForm2/Rule/Each.php
@@ -0,0 +1,137 @@
+<?php
+/**
+ * Validates all elements in a Container using a template Rule
+ *
+ * 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: Each.php 294057 2010-01-26 21:10:28Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for HTML_QuickForm2 rules
+ */
+require_once 'HTML/QuickForm2/Rule.php';
+
+/**
+ * Validates all elements in a Container using a template Rule
+ *
+ * This Rule needs one configuration parameter for its work: the template Rule
+ * to use for actual validation. It can be passed either to
+ * {@link HTML_QuickForm2_Rule::__construct() the Rule constructor} as local
+ * configuration or to {@link HTML_QuickForm2_Factory::registerRule()} as
+ * global one. As usual, global configuration overrides local.
+ *
+ * The container will be considered valid if all its elements are valid
+ * according to a template Rule.
+ *
+ * <code>
+ * $group->addRule('each', 'The fields should contain only letters',
+ * $group->createRule('regex', '/^[a-z]+$/i'));
+ * </code>
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Rule_Each extends HTML_QuickForm2_Rule
+{
+ /**
+ * Validates the owner's children using the template Rule
+ *
+ * @return bool Whether all children are valid according to a template Rule
+ */
+ protected function validateOwner()
+ {
+ $rule = clone $this->getConfig();
+ foreach ($this->owner->getRecursiveIterator(RecursiveIteratorIterator::LEAVES_ONLY) as $child) {
+ $rule->setOwner($child);
+ if (!$rule->validateOwner()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Sets the template Rule to use for actual validation
+ *
+ * We do not allow using Required rules here, they are able to validate
+ * containers themselves without the help of Each rule.
+ *
+ * @param HTML_QuickForm2_Rule Template Rule
+ * @return HTML_QuickForm2_Rule
+ * @throws HTML_QuickForm2_InvalidArgumentException if $config is either not
+ * an instance of Rule or is an instance of Rule_Required
+ */
+ public function setConfig($config)
+ {
+ if (!$config instanceof HTML_QuickForm2_Rule) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'Each Rule requires a template Rule to validate with, ' .
+ preg_replace('/\s+/', ' ', var_export($config, true)) . ' given'
+ );
+ } elseif ($config instanceof HTML_QuickForm2_Rule_Required) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'Cannot use "required" Rule as a template'
+ );
+ }
+ return parent::setConfig($config);
+ }
+
+ /**
+ * Sets the element that will be validated by this rule
+ *
+ * @param HTML_QuickForm2_Container Container to validate
+ * @throws HTML_QuickForm2_InvalidArgumentException if trying to use
+ * this Rule on something that isn't a Container
+ */
+ public function setOwner(HTML_QuickForm2_Node $owner)
+ {
+ if (!$owner instanceof HTML_QuickForm2_Container) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'Each Rule can only validate Containers, '.
+ get_class($owner) . ' given'
+ );
+ }
+ parent::setOwner($owner);
+ }
+}
+?> \ No newline at end of file
diff --git a/libs/HTML/QuickForm2/Rule/Empty.php b/libs/HTML/QuickForm2/Rule/Empty.php
new file mode 100644
index 0000000000..76808bb288
--- /dev/null
+++ b/libs/HTML/QuickForm2/Rule/Empty.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ * Rule checking that the field is empty
+ *
+ * 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: Empty.php 299480 2010-05-19 06:55:03Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for HTML_QuickForm2 rules
+ */
+require_once 'HTML/QuickForm2/Rule.php';
+
+/**
+ * Rule checking that the field is empty
+ *
+ * Handles both simple form fields and file uploads, the latter are considered
+ * valid iff no file upload was attempted.
+ *
+ * The rule doesn't make much sense if used separately, but can be very helpful
+ * if chained:
+ * <code>
+ * $spamCheck->addRule('empty')
+ * ->or_($email->createRule('nonempty', 'Supply a valid email if you want to receive our spam')
+ * ->and_($email->createRule('email')));
+ * </code>
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Rule_Empty extends HTML_QuickForm2_Rule
+{
+ protected function validateOwner()
+ {
+ $value = $this->owner->getValue();
+ if (!$this->owner instanceof HTML_QuickForm2_Element_InputFile) {
+ return 0 == strlen($value);
+ } else {
+ return isset($value['error']) && UPLOAD_ERR_NO_FILE == $value['error'];
+ }
+ }
+
+ protected function getJavascriptCallback()
+ {
+ return "function() { return " . $this->owner->getJavascriptValue() . " == ''; }";
+ }
+}
+
+?> \ No newline at end of file
diff --git a/libs/HTML/QuickForm2/Rule/Length.php b/libs/HTML/QuickForm2/Rule/Length.php
new file mode 100644
index 0000000000..178bbe35cb
--- /dev/null
+++ b/libs/HTML/QuickForm2/Rule/Length.php
@@ -0,0 +1,236 @@
+<?php
+/**
+ * Rule checking the value's length
+ *
+ * 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: Length.php 299480 2010-05-19 06:55:03Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for HTML_QuickForm2 rules
+ */
+require_once 'HTML/QuickForm2/Rule.php';
+
+/**
+ * Rule checking the value's length
+ *
+ * The rule needs an "allowed length" parameter for its work, it can be either
+ * - a scalar: the value will be valid if it is exactly this long
+ * - an array: the value will be valid if its length is between the given values
+ * (inclusive). If one of these evaluates to 0, then length will be compared
+ * only with the remaining one.
+ * See {@link mergeConfig()} for description of possible ways to pass
+ * configuration parameters.
+ *
+ * The Rule considers empty fields as valid and doesn't try to compare their
+ * lengths with provided limits.
+ *
+ * For convenience this Rule is also registered with the names 'minlength' and
+ * 'maxlength' (having, respectively, 'max' and 'min' parameters set to 0):
+ * <code>
+ * $password->addRule('minlength', 'The password should be at least 6 characters long', 6);
+ * $message->addRule('maxlength', 'Your message is too verbose', 1000);
+ * </code>
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Rule_Length extends HTML_QuickForm2_Rule
+{
+ /**
+ * Validates the owner element
+ *
+ * @return bool whether length of the element's value is within allowed range
+ */
+ protected function validateOwner()
+ {
+ if (0 == ($valueLength = strlen($this->owner->getValue()))) {
+ return true;
+ }
+
+ $allowedLength = $this->getConfig();
+ if (is_scalar($allowedLength)) {
+ return $valueLength == $allowedLength;
+ } else {
+ return (empty($allowedLength['min']) || $valueLength >= $allowedLength['min']) &&
+ (empty($allowedLength['max']) || $valueLength <= $allowedLength['max']);
+ }
+ }
+
+ protected function getJavascriptCallback()
+ {
+ $allowedLength = $this->getConfig();
+ if (is_scalar($allowedLength)) {
+ $check = "length == {$allowedLength}";
+ } else {
+ $checks = array();
+ if (!empty($allowedLength['min'])) {
+ $checks[] = "length >= {$allowedLength['min']}";
+ }
+ if (!empty($allowedLength['max'])) {
+ $checks[] = "length <= {$allowedLength['max']}";
+ }
+ $check = implode(' && ', $checks);
+ }
+ return "function() { var length = " . $this->owner->getJavascriptValue() .
+ ".length; if (0 == length) { return true; } else { return {$check}; } }";
+ }
+
+ /**
+ * Adds the 'min' and 'max' fields from one array to the other
+ *
+ * @param array Rule configuration, array with 'min' and 'max' keys
+ * @param array Additional configuration, fields will be added to
+ * $length if it doesn't contain such a key already
+ * @return array
+ */
+ protected static function mergeMinMaxLength($length, $config)
+ {
+ if (array_key_exists('min', $config) || array_key_exists('max', $config)) {
+ if (!array_key_exists('min', $length) && array_key_exists('min', $config)) {
+ $length['min'] = $config['min'];
+ }
+ if (!array_key_exists('max', $length) && array_key_exists('max', $config)) {
+ $length['max'] = $config['max'];
+ }
+ } else {
+ if (!array_key_exists('min', $length)) {
+ $length['min'] = reset($config);
+ }
+ if (!array_key_exists('max', $length)) {
+ $length['max'] = end($config);
+ }
+ }
+ return $length;
+ }
+
+ /**
+ * Merges length limits given on rule creation with those given to registerRule()
+ *
+ * "Global" length limits may be passed to
+ * {@link HTML_QuickForm2_Factory::registerRule()} in either of the
+ * following formats
+ * - scalar (exact length)
+ * - array(minlength, maxlength)
+ * - array(['min' => minlength, ]['max' => maxlength])
+ *
+ * "Local" length limits may be passed to the constructor in either of
+ * the following formats
+ * - scalar (if global config is unset then it is treated as an exact
+ * length, if 'min' or 'max' is in global config then it is treated
+ * as 'max' or 'min', respectively)
+ * - array(minlength, maxlength)
+ * - array(['min' => minlength, ]['max' => maxlength])
+ *
+ * As usual, global configuration overrides local one.
+ *
+ * @param int|array Local length limits
+ * @param int|array Global length limits, usually provided to {@link HTML_QuickForm2_Factory::registerRule()}
+ * @return int|array Merged length limits
+ */
+ public static function mergeConfig($localConfig, $globalConfig)
+ {
+ if (!isset($globalConfig)) {
+ $length = $localConfig;
+
+ } elseif (!is_array($globalConfig)) {
+ $length = $globalConfig;
+
+ } else {
+ $length = self::mergeMinMaxLength(array(), $globalConfig);
+ if (isset($localConfig)) {
+ $length = self::mergeMinMaxLength(
+ $length, is_array($localConfig)? $localConfig: array($localConfig)
+ );
+ }
+ }
+ return $length;
+ }
+
+ /**
+ * Sets the allowed length limits
+ *
+ * $config can be either of the following
+ * - integer (rule checks for exact length)
+ * - array(minlength, maxlength)
+ * - array(['min' => minlength, ]['max' => maxlength])
+ *
+ * @param int|array Length limits
+ * @return HTML_QuickForm2_Rule
+ * @throws HTML_QuickForm2_InvalidArgumentException if bogus length limits
+ * were provided
+ */
+ public function setConfig($config)
+ {
+ if (is_array($config)) {
+ $config = self::mergeMinMaxLength(array(), $config)
+ + array('min' => 0, 'max' => 0);
+ }
+ if (is_array($config) && ($config['min'] < 0 || $config['max'] < 0) ||
+ !is_array($config) && $config < 0)
+ {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'Length Rule requires limits to be nonnegative, ' .
+ preg_replace('/\s+/', ' ', var_export($config, true)) . ' given'
+ );
+
+ } elseif (is_array($config) && $config['min'] == 0 && $config['max'] == 0 ||
+ !is_array($config) && 0 == $config)
+ {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'Length Rule requires at least one non-zero limit, ' .
+ preg_replace('/\s+/', ' ', var_export($config, true)) . ' given'
+ );
+ }
+
+ if (!empty($config['min']) && !empty($config['max'])) {
+ if ($config['min'] > $config['max']) {
+ list($config['min'], $config['max']) = array($config['max'], $config['min']);
+ } elseif ($config['min'] == $config['max']) {
+ $config = $config['min'];
+ }
+ }
+ return parent::setConfig($config);
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Rule/MaxFileSize.php b/libs/HTML/QuickForm2/Rule/MaxFileSize.php
new file mode 100644
index 0000000000..b879b14502
--- /dev/null
+++ b/libs/HTML/QuickForm2/Rule/MaxFileSize.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * Rule checking that uploaded file size does not exceed the given limit
+ *
+ * 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: MaxFileSize.php 294057 2010-01-26 21:10:28Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for HTML_QuickForm2 rules
+ */
+require_once 'HTML/QuickForm2/Rule.php';
+
+/**
+ * Rule checking that uploaded file size does not exceed the given limit
+ *
+ * The Rule needs one configuration parameter for its work: the size limit.
+ * This limit can be passed either to
+ * {@link HTML_QuickForm2_Rule::__construct() the Rule constructor} as local
+ * configuration or to {@link HTML_QuickForm2_Factory::registerRule()} as
+ * global one. As usual, global configuration overrides local one.
+ *
+ * Note that if file upload failed due to upload_max_filesize php.ini setting
+ * or MAX_FILE_SIZE form field, then this rule won't even be called, due to
+ * File element's built-in validation setting the error message.
+ *
+ * The Rule considers missing file uploads (UPLOAD_ERR_NO_FILE) valid.
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Rule_MaxFileSize extends HTML_QuickForm2_Rule
+{
+ /**
+ * Validates the owner element
+ *
+ * @return bool whether uploaded file's size is within given limit
+ */
+ protected function validateOwner()
+ {
+ $value = $this->owner->getValue();
+ if (!isset($value['error']) || UPLOAD_ERR_NO_FILE == $value['error']) {
+ return true;
+ }
+ return ($this->getConfig() >= @filesize($value['tmp_name']));
+ }
+
+ /**
+ * Sets maximum allowed file size
+ *
+ * @param int Maximum allowed size
+ * @return HTML_QuickForm2_Rule
+ * @throws HTML_QuickForm2_InvalidArgumentException if a bogus size limit was provided
+ */
+ public function setConfig($config)
+ {
+ if (0 >= $config) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'MaxFileSize Rule requires a positive size limit, ' .
+ preg_replace('/\s+/', ' ', var_export($config, true)) . ' given'
+ );
+ }
+ return parent::setConfig($config);
+ }
+
+ /**
+ * Sets the element that will be validated by this rule
+ *
+ * @param HTML_QuickForm2_Element_InputFile File upload field to validate
+ * @throws HTML_QuickForm2_InvalidArgumentException if trying to use
+ * this Rule on something that isn't a file upload field
+ */
+ public function setOwner(HTML_QuickForm2_Node $owner)
+ {
+ if (!$owner instanceof HTML_QuickForm2_Element_InputFile) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'MaxFileSize Rule can only validate file upload fields, '.
+ get_class($owner) . ' given'
+ );
+ }
+ parent::setOwner($owner);
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Rule/MimeType.php b/libs/HTML/QuickForm2/Rule/MimeType.php
new file mode 100644
index 0000000000..067a41c1d0
--- /dev/null
+++ b/libs/HTML/QuickForm2/Rule/MimeType.php
@@ -0,0 +1,122 @@
+<?php
+/**
+ * Rule checking that uploaded file is of the correct MIME type
+ *
+ * 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: MimeType.php 294057 2010-01-26 21:10:28Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for HTML_QuickForm2 rules
+ */
+require_once 'HTML/QuickForm2/Rule.php';
+
+/**
+ * Rule checking that uploaded file is of the correct MIME type
+ *
+ * The Rule needs one configuration parameter for its work: a string with a
+ * desired MIME type or array of such strings. This parameter can be passed
+ * either to {@link HTML_QuickForm2_Rule::__construct() the Rule constructor}
+ * as local configuration or to {@link HTML_QuickForm2_Factory::registerRule()}
+ * as global one. As usual, global configuration overrides local one.
+ *
+ * The Rule considers missing file uploads (UPLOAD_ERR_NO_FILE) valid.
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Rule_MimeType extends HTML_QuickForm2_Rule
+{
+ /**
+ * Validates the owner element
+ *
+ * @return bool whether uploaded file's MIME type is correct
+ */
+ protected function validateOwner()
+ {
+ $value = $this->owner->getValue();
+ if (!isset($value['error']) || UPLOAD_ERR_NO_FILE == $value['error']) {
+ return true;
+ }
+ $mime = $this->getConfig();
+ return is_array($mime)? in_array($value['type'], $mime):
+ $value['type'] == $mime;
+ }
+
+ /**
+ * Sets allowed MIME type(s) for the uploaded file
+ *
+ * @param string|array Allowed MIME type or an array of types
+ * @return HTML_QuickForm2_Rule
+ * @throws HTML_QuickForm2_InvalidArgumentException if bogus configuration provided
+ */
+ public function setConfig($config)
+ {
+ if (0 == count($config) || !is_string($config) && !is_array($config)) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'MimeType Rule requires MIME type(s), ' .
+ preg_replace('/\s+/', ' ', var_export($config, true)) . ' given'
+ );
+ }
+ return parent::setConfig($config);
+ }
+
+ /**
+ * Sets the element that will be validated by this rule
+ *
+ * @param HTML_QuickForm2_Element_InputFile File upload field to validate
+ * @throws HTML_QuickForm2_InvalidArgumentException if trying to use
+ * this Rule on something that isn't a file upload field
+ */
+ public function setOwner(HTML_QuickForm2_Node $owner)
+ {
+ if (!$owner instanceof HTML_QuickForm2_Element_InputFile) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'MimeType Rule can only validate file upload fields, '.
+ get_class($owner) . ' given'
+ );
+ }
+ parent::setOwner($owner);
+ }
+}
+?>
diff --git a/libs/HTML/QuickForm2/Rule/Nonempty.php b/libs/HTML/QuickForm2/Rule/Nonempty.php
new file mode 100644
index 0000000000..e815089072
--- /dev/null
+++ b/libs/HTML/QuickForm2/Rule/Nonempty.php
@@ -0,0 +1,141 @@
+<?php
+/**
+ * Rule checking that the field is not empty
+ *
+ * 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: Nonempty.php 299706 2010-05-24 18:32:37Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for HTML_QuickForm2 rules
+ */
+require_once 'HTML/QuickForm2/Rule.php';
+
+/**
+ * Rule checking that the field is not empty
+ *
+ * Handles simple form fields, file uploads and Containers.
+ *
+ * When validating <select multiple> fields and Containers it may use an
+ * optional configuration parameter for minimum number of nonempty values,
+ * defaulting to 1. It can be passed either to
+ * {@link HTML_QuickForm2_Rule::__construct() the Rule constructor} as local
+ * configuration or to {@link HTML_QuickForm2_Factory::registerRule()} as
+ * global one. As usual, global configuration overrides local.
+ *
+ * <code>
+ * // Required rule is 'nonempty' with a bit of special handling
+ * $login->addRule('required', 'Please provide your login');
+ * $multiSelect->addRule('required', 'Please select at least two options', 2);
+ * </code>
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Rule_Nonempty extends HTML_QuickForm2_Rule
+{
+ protected function validateOwner()
+ {
+ if ($this->owner instanceof HTML_QuickForm2_Container) {
+ $nonempty = 0;
+ foreach ($this->owner->getRecursiveIterator(RecursiveIteratorIterator::LEAVES_ONLY) as $child) {
+ $rule = new self($child);
+ if ($rule->validateOwner()) {
+ $nonempty++;
+ }
+ }
+ return $nonempty >= $this->getConfig();
+ }
+
+ $value = $this->owner->getValue();
+ if ($this->owner instanceof HTML_QuickForm2_Element_InputFile) {
+ return isset($value['error']) && (UPLOAD_ERR_OK == $value['error']);
+ } elseif (is_array($value)) {
+ return count(array_filter($value, 'strlen')) >= $this->getConfig();
+ } else {
+ return (bool)strlen($value);
+ }
+ }
+
+ /**
+ * Sets minimum number of nonempty values
+ *
+ * This is useful for multiple selects and Containers, will be ignored for
+ * all other elements. Defaults to 1, thus multiple select will be
+ * considered not empty if at least one option is selected, Container will
+ * be considered not empty if at least one contained element is not empty.
+ *
+ * @param int Maximum allowed size
+ * @return HTML_QuickForm2_Rule
+ * @throws HTML_QuickForm2_InvalidArgumentException if a bogus size limit was provided
+ */
+ public function setConfig($config)
+ {
+ if (is_null($config)) {
+ $config = 1;
+ } elseif (1 > intval($config)) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'Nonempty Rule accepts a positive count of nonempty values, ' .
+ preg_replace('/\s+/', ' ', var_export($config, true)) . ' given'
+ );
+ }
+ return parent::setConfig(intval($config));
+ }
+
+ protected function getJavascriptCallback()
+ {
+ $js = "function() {var value = " . $this->owner->getJavascriptValue() . ";";
+ if (!$this->owner instanceof HTML_QuickForm2_Container) {
+ $js .= " if (!value instanceof Array) { return value != ''; } else { " .
+ "var valid = 0; for (var i = 0; i < value.length; i++) { " .
+ "if ('' != value[i]) { valid++; } } return valid >= " . $this->getConfig() . "; } }";
+ } else {
+ $js .= " var values = value.getValues(); var valid = 0; " .
+ "for (var i = 0; i < values.length; i++) { " .
+ "if ('' != values[i]) { valid++; } } return valid >= " . $this->getConfig() . "; }";
+ }
+ return $js;
+ }
+}
+
+?>
diff --git a/libs/HTML/QuickForm2/Rule/NotCallback.php b/libs/HTML/QuickForm2/Rule/NotCallback.php
new file mode 100644
index 0000000000..ace4f83704
--- /dev/null
+++ b/libs/HTML/QuickForm2/Rule/NotCallback.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Rule checking the value via a callback function (method) with logical negation
+ *
+ * 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: NotCallback.php 299305 2010-05-12 20:15:28Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Rule checking the value via a callback function (method)
+ */
+require_once 'HTML/QuickForm2/Rule/Callback.php';
+
+/**
+ * Rule checking the value via a callback function (method) with logical negation
+ *
+ * The Rule accepts the same configuration parameters as the Callback Rule
+ * does, but the callback is expected to return false if the element is valid
+ * and true if it is invalid.
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Rule_NotCallback extends HTML_QuickForm2_Rule_Callback
+{
+ /**
+ * Validates the owner element
+ *
+ * @return bool negated result of a callback function
+ */
+ protected function validateOwner()
+ {
+ $value = $this->owner->getValue();
+ $config = $this->getConfig();
+ return !call_user_func_array(
+ $config['callback'], array_merge(array($value), $config['arguments'])
+ );
+ }
+}
+?> \ No newline at end of file
diff --git a/libs/HTML/QuickForm2/Rule/NotRegex.php b/libs/HTML/QuickForm2/Rule/NotRegex.php
new file mode 100644
index 0000000000..acb7873787
--- /dev/null
+++ b/libs/HTML/QuickForm2/Rule/NotRegex.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * Checks that the element's value does not match a regular expression
+ *
+ * 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: NotRegex.php 299480 2010-05-19 06:55:03Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Validates values using regular expressions
+ */
+require_once 'HTML/QuickForm2/Rule/Regex.php';
+
+/**
+ * Checks that the element's value does not match a regular expression
+ *
+ * The Rule behaves like Regex Rule, but it considers the element valid if its
+ * value does not match the given regular expression.
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Rule_NotRegex extends HTML_QuickForm2_Rule_Regex
+{
+ /**
+ * Validates the owner element
+ *
+ * @return bool whether element's value does not match given regular expression
+ */
+ protected function validateOwner()
+ {
+ $value = $this->owner->getValue();
+ if ($this->owner instanceof HTML_QuickForm2_Element_InputFile) {
+ if (!isset($value['error']) || UPLOAD_ERR_NO_FILE == $value['error']) {
+ return true;
+ }
+ $value = $value['name'];
+ } elseif (!strlen($value)) {
+ return true;
+ }
+ return !preg_match($this->getConfig() . 'D', $value);
+ }
+
+ /**
+ * Returns the client-side validation callback
+ *
+ * For this to work properly, slashes have to be used as regex delimiters.
+ * The method takes care of transforming PHP unicode escapes in regexps to
+ * JS unicode escapes if using 'u' modifier (see bug #12376)
+ *
+ * @return string
+ */
+ protected function getJavascriptCallback()
+ {
+ $regex = $this->getConfig();
+
+ if ($pos = strpos($regex, 'u', strrpos($regex, '/'))) {
+ $regex = substr($regex, 0, $pos) . substr($regex, $pos + 1);
+ $regex = preg_replace('/(?<!\\\\)(?>\\\\\\\\)*\\\\x{([a-fA-F0-9]+)}/', '\\u$1', $regex);
+ }
+
+ return "function() { var regex = {$regex}; var value = " . $this->owner->getJavascriptValue() .
+ "; return value == '' || !regex.test(value); }";
+ }
+}
+?> \ No newline at end of file
diff --git a/libs/HTML/QuickForm2/Rule/Regex.php b/libs/HTML/QuickForm2/Rule/Regex.php
new file mode 100644
index 0000000000..a3eeea30f3
--- /dev/null
+++ b/libs/HTML/QuickForm2/Rule/Regex.php
@@ -0,0 +1,133 @@
+<?php
+/**
+ * Validates values using regular expressions
+ *
+ * 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: Regex.php 299480 2010-05-19 06:55:03Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Base class for HTML_QuickForm2 rules
+ */
+require_once 'HTML/QuickForm2/Rule.php';
+
+/**
+ * Validates values using regular expressions
+ *
+ * The Rule needs one configuration parameter for its work: a Perl-compatible
+ * regular expression. This parameter can be passed either to
+ * {@link HTML_QuickForm2_Rule::__construct() the Rule constructor} as local
+ * configuration or to {@link HTML_QuickForm2_Factory::registerRule()}
+ * as global one. As usual, global configuration overrides local one.
+ *
+ * The Rule can also validate file uploads, in this case the regular expression
+ * is applied to upload's 'name' field.
+ *
+ * The Rule considers empty fields (file upload fields with UPLOAD_ERR_NO_FILE)
+ * as valid and doesn't try to test them with the regular expression.
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Rule_Regex extends HTML_QuickForm2_Rule
+{
+ /**
+ * Validates the owner element
+ *
+ * @return bool whether element's value matches given regular expression
+ */
+ protected function validateOwner()
+ {
+ $value = $this->owner->getValue();
+ if ($this->owner instanceof HTML_QuickForm2_Element_InputFile) {
+ if (!isset($value['error']) || UPLOAD_ERR_NO_FILE == $value['error']) {
+ return true;
+ }
+ $value = $value['name'];
+ } elseif (!strlen($value)) {
+ return true;
+ }
+ return preg_match($this->getConfig() . 'D', $value);
+ }
+
+ /**
+ * Sets the regular expression to validate with
+ *
+ * @param string Regular expression
+ * @return HTML_QuickForm2_Rule
+ * @throws HTML_QuickForm2_InvalidArgumentException if $config is not a string
+ */
+ public function setConfig($config)
+ {
+ if (!is_string($config)) {
+ throw new HTML_QuickForm2_InvalidArgumentException(
+ 'Regex Rule requires a regular expression, ' .
+ preg_replace('/\s+/', ' ', var_export($config, true)) . ' given'
+ );
+ }
+ return parent::setConfig($config);
+ }
+
+ /**
+ * Returns the client-side validation callback
+ *
+ * For this to work properly, slashes have to be used as regex delimiters.
+ * The method takes care of transforming PHP unicode escapes in regexps to
+ * JS unicode escapes if using 'u' modifier (see bug #12376)
+ *
+ * @return string
+ */
+ protected function getJavascriptCallback()
+ {
+ $regex = $this->getConfig();
+
+ if ($pos = strpos($regex, 'u', strrpos($regex, '/'))) {
+ $regex = substr($regex, 0, $pos) . substr($regex, $pos + 1);
+ $regex = preg_replace('/(?<!\\\\)(?>\\\\\\\\)*\\\\x{([a-fA-F0-9]+)}/', '\\u$1', $regex);
+ }
+
+ return "function() { var regex = {$regex}; var value = " . $this->owner->getJavascriptValue() .
+ "; return value == '' || regex.test(value); }";
+ }
+}
+?> \ No newline at end of file
diff --git a/libs/HTML/QuickForm2/Rule/Required.php b/libs/HTML/QuickForm2/Rule/Required.php
new file mode 100644
index 0000000000..9fa3f3c1af
--- /dev/null
+++ b/libs/HTML/QuickForm2/Rule/Required.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Rule for required elements
+ *
+ * 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: Required.php 294057 2010-01-26 21:10:28Z avb $
+ * @link http://pear.php.net/package/HTML_QuickForm2
+ */
+
+/**
+ * Rule checking that the form field is not empty
+ */
+require_once 'HTML/QuickForm2/Rule/Nonempty.php';
+
+/**
+ * Rule for required elements
+ *
+ * The main difference from "nonempty" Rule is that
+ * - elements to which this Rule is attached will be considered required
+ * ({@link HTML_QuickForm2_Node::isRequired()} will return true for them) and
+ * marked accordingly when outputting the form
+ * - this Rule can only be added directly to the element and other Rules can
+ * only be added to it via and_() method
+ *
+ * @category HTML
+ * @package HTML_QuickForm2
+ * @author Alexey Borzov <avb@php.net>
+ * @author Bertrand Mansion <golgote@mamasam.com>
+ * @version Release: @package_version@
+ */
+class HTML_QuickForm2_Rule_Required extends HTML_QuickForm2_Rule_Nonempty
+{
+ /**
+ * Disallows adding a rule to the chain with an "or" operator
+ *
+ * Required rules are different from all others because they affect the
+ * visual representation of an element ("* denotes required field").
+ * Therefore we cannot allow chaining other rules to these via or_(), since
+ * this will effectively mean that the field is not required anymore and the
+ * visual difference is bogus.
+ *
+ * @param HTML_QuickForm2_Rule
+ * @throws HTML_QuickForm2_Exception
+ */
+ public function or_(HTML_QuickForm2_Rule $next)
+ {
+ throw new HTML_QuickForm2_Exception(
+ 'or_(): Cannot add a rule to "required" rule'
+ );
+ }
+}
+?>