,
* Bertrand Mansion
* 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
* @author Bertrand Mansion
* @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
* @author Bertrand Mansion
* @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();
}
}
?>