PDF rausgenommen

This commit is contained in:
aschwarz
2023-01-23 11:03:31 +01:00
parent 82d562a322
commit a6523903eb
28078 changed files with 4247552 additions and 2 deletions

View File

@ -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
*/
public function updateValue()
{
foreach ($this as $child) {
$child->updateValue();
}
}
/**
* Performs the server-side validation
*
* This method also calls validate() on all contained elements.
*
* @return boolean Whether the container and all contained elements are valid
*/
protected function validate()
{
$valid = parent::validate();
foreach ($this as $child) {
$valid = $child->validate() && $valid;
}
return $valid;
}
/**
* Appends an element to the container, creating it first
*
* The element will be created via {@link HTML_QuickForm2_Factory::createElement()}
* and then added via the {@link appendChild()} method.
* The element type is deduced from the method name.
* This is a convenience method to reduce typing.
*
* @param mixed Element name
* @param mixed Element attributes
* @param array Element-specific data
* @return HTML_QuickForm2_Node Added element
* @throws HTML_QuickForm2_InvalidArgumentException
* @throws HTML_QuickForm2_NotFoundException
*/
public function __call($m, $a)
{
if (preg_match('/^(add)([a-zA-Z0-9_]+)$/', $m, $match)) {
if ($match[1] == 'add') {
$type = strtolower($match[2]);
$name = isset($a[0]) ? $a[0] : null;
$attr = isset($a[1]) ? $a[1] : null;
$data = isset($a[2]) ? $a[2] : array();
return $this->addElement($type, $name, $attr, $data);
}
}
trigger_error("Fatal error: Call to undefined method ".get_class($this)."::".$m."()", E_USER_ERROR);
}
/**
* Renders the container using the given renderer
*
* @param HTML_QuickForm2_Renderer Renderer instance
* @return HTML_QuickForm2_Renderer
*/
public function render(HTML_QuickForm2_Renderer $renderer)
{
foreach ($this->rules as $rule) {
if ($rule[1] & HTML_QuickForm2_Rule::RUNAT_CLIENT) {
$renderer->getJavascriptBuilder()->addRule($rule[0]);
}
}
$renderer->startContainer($this);
foreach ($this as $element) {
$element->render($renderer);
}
$renderer->finishContainer($this);
return $renderer;
}
public function __toString()
{
// require_once 'HTML/QuickForm2/Renderer.php';
return $this->render(HTML_QuickForm2_Renderer::factory('default'))->__toString();
}
/**
* Returns Javascript code for getting the element's value
*
* @return string
*/
public function getJavascriptValue()
{
$args = array();
foreach ($this as $child) {
if ($child instanceof HTML_QuickForm2_Container) {
$args[] = $child->getJavascriptValue();
} else {
$args[] = "'" . $child->getId() . "'";
}
}
return 'qf.form.getContainerValue(' . implode(', ', $args) . ')';
}
}
/**
* 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());
}
}
?>

View File

@ -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');
}
}
?>

View File

@ -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();
}
}
?>

View File

@ -0,0 +1,508 @@
<?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);
if (!class_exists($className)) {
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);
}
}
?>

View File

@ -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);
}
?>

View File

@ -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');
}
}
}
?>

View File

@ -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');
}
}
?>

View File

@ -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;
}
}
?>

View File

@ -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;
}
}
?>

View File

@ -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');
}
}
}
?>

View File

@ -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');
}
}
}
?>

View File

@ -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;
}
}
?>

View File

@ -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);
}
}
?>

View File

@ -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;
}
}

View File

@ -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);
}
?>

View File

@ -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;
}
}
}
?>

View File

@ -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;
}
}
?>

View File

@ -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);
}
?>

View File

@ -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;
}
}
}
?>

View File

@ -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.
*/
public 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() . "'))";
}
}
?>

View File

@ -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>';
}
public 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;
}
}
?>

View File

@ -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.
*/
public 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;')
)
);
}
?>

View File

@ -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();
}
}
?>

View File

@ -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;
}
}
?>

View File

@ -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'];
}
}
}
?>

View File

@ -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);
}
}
public 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;
}
}
}
}
?>

View File

@ -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;
}
public 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'
);
}
}
?>

View File

@ -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;
}
}
?>

View File

@ -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;
}
}
public 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;
}
}
?>

View File

@ -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();
}
}
?>

View File

@ -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>'
);
}
?>

View File

@ -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;
}
}
?>

View File

@ -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);
}
public 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;
}
}
?>

View File

@ -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');
}
?>

View File

@ -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);
}
public 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;
}
}
}
}
}
?>

View File

@ -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.
*/
public function updateValue()
{
foreach ($this->getDataSources() as $ds) {
if (!$ds instanceof HTML_QuickForm2_DataSource_Submit &&
null !== ($value = $ds->getValue($this->getName())))
{
$this->setContent($value);
return;
}
}
}
}
?>

View File

@ -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();
}
}
?>

View File

@ -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
{
}
?>

View File

@ -0,0 +1,233 @@
<?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];
if (!class_exists($className)) {
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];
if (!class_exists($className)) {
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);
}
}
?>

View File

@ -0,0 +1,121 @@
<?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';
require_once dirname(__FILE__) . '/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;
}
}
?>

View File

@ -0,0 +1,141 @@
<?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';
require_once dirname(__FILE__) . '/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;
}
}
}
?>

View File

@ -0,0 +1,693 @@
<?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';
require_once dirname(__FILE__) . '/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 public 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);
}
}
?>

View File

@ -0,0 +1,367 @@
<?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
*/
use Piwik\Plugin;
/**
* 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];
if (!class_exists($className)) {
HTML_QuickForm2_Loader::loadClass($className, $includeFile);
}
if (!class_exists('HTML_QuickForm2_Renderer_Proxy')) {
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
*/
public 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)) {
if (!class_exists('HTML_QuickForm2_JavascriptBuilder')) {
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);
}
?>

View File

@ -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;
}
public 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);
}
/**#@-*/
}
?>

View File

@ -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();
public 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;
}
}
?>

View File

@ -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;
}
}
?>

View File

@ -0,0 +1,264 @@
<?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];
if (!class_exists($className)) {
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);
}
}
?>

View File

@ -0,0 +1,292 @@
<?php
/**
* A renderer for HTML_QuickForm2 suitable for using with the Smarty template engine.
* See: http://www.smarty.net/
*
* PHP version 5
*
* LICENSE:
*
* Copyright (c) 2009, Alain D D Williams <addw@phcomp.co.uk>
* Based on the QuickForm2 Array renderer.
*
* 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 Alain D D Williams <addw@phcomp.co.uk>
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version SCCS: %W% %G% %U%
* @link http://pear.php.net/package/HTML_QuickForm2
*/
/**
* This generates an array, bring in the array renderer and extend it a bit:
*/
// require_once 'HTML/QuickForm2/Renderer/Array.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),
* 'requirednote' => note about the required elements (string),
* NB: no '_' in the middle
* In old_compat this is a span style="font-size:80%;"
* with the '*' also color:#ff0000;
* Not old_compat it is in a div class="reqnote"
* // 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
* )
* '1st_elements_name' => array for the 1st element,
* ... references into 'elements' above
* 'nth_elements_name' => array for the nth element,
* )
* );
* </pre>
* Where element_i is an array of the form
* <pre>
* array(
* 'id' => element id (string),
* 'name' => element name (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
* )
*
* If the type is 'radio' an element (type = 'radio') is created for each choice that the user has,
* keyed by the 'id' value. An 'element' will be created having an array with one element key '0'.
* The 'id' above will be set to the value in 'name'.
* The 'type' of each element will be 'radio'
* );
* </pre>
*
* The following additional options are available:
* <ul>
* <li>'old_compat' - generate something compatible with an old renderer</li>
* <li>'key_id' - the key to elements is the field's 'id' rather than 'name'</li>
* </ul>
*
* 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 Alain D D Williams <addw@phcomp.co.uk>
* @version Release: SCCS: %W% %G% %U%
*/
class HTML_QuickForm2_Renderer_Smarty extends HTML_QuickForm2_Renderer_Array
{
/**
* Constructor, adds new options
*/
protected function __construct()
{
parent::__construct();
$this->options += array(
'old_compat' => false,
'key_id' => false,
);
}
/**
* 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)
{
$keyn = $this->options['key_id'] ? 'id' : 'name';
$ary = array(
'id' => $element->getId(),
'frozen' => $element->toggleFrozen(),
'name' => $element->getName(),
);
// Key that we use for putting into arrays so that smarty can extract them.
// Note that the name may be empty.
$key_val = $ary[$keyn];
if($key_val == '')
$key_val = $ary['id'];
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;
}
}
}
}
// Smarty: group_errors under 'name' or 'id' depending on key_id option:
if (($error = $element->getError()) && $this->options['group_errors']) {
$this->array['errors'][$key_val] = $error;
} elseif ($error) {
$ary['error'] = $error;
}
if (isset($this->styles[$key_val])) {
$ary['style'] = $this->styles[$key_val];
}
if (!$element instanceof HTML_QuickForm2_Container) {
$ary['html'] = $element->__toString();
} else {
$ary['elements'] = array();
$ary['attributes'] = $element->getAttributes(true);
}
return $ary;
}
public function startForm(HTML_QuickForm2_Node $form)
{
if($this->options['old_compat'])
$this->options['group_hiddens'] = true;
parent::startForm($form);
}
public function finishForm(HTML_QuickForm2_Node $form)
{
parent::finishForm($form);
if ($this->hasRequired) {
// Create element 'requirednote' - note no '_'
if($this->options['old_compat']) {
// Old QuickForm had the requirednote styled & a different name:
$this->array['requirednote'] = preg_replace('|<em>([^<]+)</em>(.*)|',
'<span style="font-size:80%; color:#ff0000;">$1</span><span style="font-size:80%;">$2</span>',
$this->options['required_note']);
} else {
$this->array['requirednote'] = '<div class="reqnote">'. $this->options['required_note'] . '</div>';
}
}
// Create top level elements keyed by form field 'name' or 'id'
if(isset($this->array['elements']['0']))
$this->linkToLevelAbove($this->array, $this->array['elements']);
// For compat: it is expected that 'hidden' is a string, not an array:
if($this->options['old_compat'] && isset($this->array['hidden']) && is_array($this->array['hidden']))
$this->array['hidden'] = join(' ', $this->array['hidden']);
}
// Look through the elements (numerically indexed) array, make fields
// members of the level above. This is so that they can be easily accessed by smarty templates.
// If we find a group, recurse down. Used for smarty only.
// Key is 'name' or 'id'.
private function linkToLevelAbove(&$top, $elements, $inGroup = false)
{
$key = $this->options['key_id'] ? 'id' : 'name';
foreach($elements as &$elem) {
$top_key = $elem[$key];
// If in a group, convert something like inGrp[F4grp][F4_1] to F4_1
// Don't do if key_id as the value is a straight id.
if( !$this->options['key_id'] && $inGroup && $top_key != '') {
if(!(preg_match("/\[?([\w_]+)\]?$/i", $top_key, $match)))
throw new HTML_QuickForm2_InvalidArgumentException(
"linkToLevelAbove can't obtain the name from '$top_key'");
$top_key = $match[1];
}
// Radio buttons: several elements with the same name, make an array
if(isset($elem['type']) && $elem['type'] == 'radio') {
if( ! isset($top[$top_key]))
$top[$top_key] = array('id' => $top_key, 'type' => 'radio', 'elements' => array(0));
$top[$top_key][$elem['id']] = &$elem;
} else // Normal field, just link into the level above.
if( ! isset($top[$top_key]))
$top[$top_key] = &$elem; // Link into the level above
// If we have a group link its fields up to this level:
if(isset($elem['elements']['0']))
$this->linkToLevelAbove($elem, $elem['elements'], true);
// Link errors to the top level:
if(isset($elem['error']) && isset($this->array[$elem['error']]))
$this->array['errors'][$top_key] = $this->array[$elem['error']];
}
}
/**#@-*/
}

View File

@ -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;
}
}
?>

View File

@ -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()));
}
}
?>

View File

@ -0,0 +1,250 @@
<?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('==', '!=', '===', '!==', '<', '<=', '>', '>=');
protected function doOperation($a, $b, $operator)
{
switch ($operator) {
case "==": return $a == $b;
case "!=": return $a != $b;
case "===": return $a === $b;
case "!==": return $a !== $b;
case ">": return $a > $b;
case "<=": return $a <= $b;
case "<": return $a < $b;
case ">=": return $a >= $b;
default: return true;
}
}
/**
* 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 ($config['operand'] instanceof HTML_QuickForm2_Node) {
$b = $config['operand']->getValue();
} else {
$b = $config['operand'];
}
if (!in_array($config['operator'], array('===', '!=='))) {
$a = floatval($value);
$b = floatval($b);
} else {
$a = strval($value);
$b = strval($b);
}
return $this->doOperation($a, $b, $config['operator']);
}
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 (is_array($globalConfig) && 0 < count($globalConfig)) {
$config = self::toCanonicalForm($globalConfig, 'operator');
}
if (is_array($localConfig) && 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);
}
}
?>

View File

@ -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);
}
}
?>

View File

@ -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() . " == ''; }";
}
}
?>

View File

@ -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);
}
}
?>

View File

@ -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);
}
}
?>

View File

@ -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);
}
}
?>

View File

@ -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;
}
}
?>

View File

@ -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'])
);
}
}
?>

View File

@ -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); }";
}
}
?>

View File

@ -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); }";
}
}
?>

View File

@ -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'
);
}
}
?>