home *** CD-ROM | disk | FTP | other *** search
- <?php
- /* vim: set expandtab tabstop=4 shiftwidth=4: */
- // +----------------------------------------------------------------------+
- // | PHP Version 4 |
- // +----------------------------------------------------------------------+
- // | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
- // +----------------------------------------------------------------------+
- // | This source file is subject to version 2.0 of the PHP license, |
- // | that is bundled with this package in the file LICENSE, and is |
- // | available at through the world-wide-web at |
- // | http://www.php.net/license/2_02.txt. |
- // | If you did not receive a copy of the PHP license and are unable to |
- // | obtain it through the world-wide-web, please send a note to |
- // | license@php.net so we can mail you a copy immediately. |
- // +----------------------------------------------------------------------+
- // | Author: Alan Knowles <alan@akbkhome.com> |
- // | Based on HTML_Common by: Adam Daniel <adaniel1@eesus.jnj.com> |
- // +----------------------------------------------------------------------+
- //
- // $Id: Element.php,v 1.49 2007/10/18 03:26:34 alan_k Exp $
-
- /**
- * Lightweight HTML Element builder and render
- *
- * This differs from HTML_Common in the following ways:
- *
- * $element->attributes is Public
- * $element->override if set to anything other than false, renders the value rather than
- * the defined element
- *
- * $element->children is a recursvable child array which is rendered by toHTML
- * $element->toHtml() is implemented
- * $element->toHtmlNoClose() renders only the first tag and children (designed for <form
- * No support for tab offsets, comments ...
- *
- * Full support for Select, and common Form elements using
- * setValue()
- * setOptions()
- *
- * overlay support with SetFrom - base + inherited..
- *
- * attributes array values:
- * key="value" // standard key="value" in output
- * key = true // outputs just key.
- *
- * children can be
- * another HTML_Element
- * or string (raw text)
- *
- *
- * @author Adam Daniel <adaniel1@eesus.jnj.com>
- * @version 1.6
- * @since PHP 4.0.3pl1
- * @abstract
- */
- class HTML_Template_Flexy_Element {
-
-
-
- /**
- * Tag that this Element represents.
- * @var array
- * @access public
- */
- var $tag = '';
- /**
- * Associative array of table attributes
- * Note Special values:
- * true == only display the key
- * false == remove
- *
- * @var array
- * @access public
- */
- var $attributes = array();
-
- /**
- * Sequence array of children
- * children that are strings are assumed to be text
- * @var array
- * @access public
- */
- var $children = array();
-
- /**
- * override the tag.
- * if this is set to anything other than false, it will be output
- * rather than the tags+children
- * @var array
- * @access public
- */
- var $override = false;
- /**
- * prefix the tag.
- * this is output by toHtml as a prefix to the tag (can be used for require tags)
- * @var array
- * @access private
- */
- var $prefix = '';
- /**
- * suffix the tag.
- * this is output by toHtml as a suffix to the tag (can be used for error messages)
- * @var array
- * @access private
- */
- var $suffix = '';
-
- /**
- * a value for delayed merging into live objects
- * if you set this on an element, it is merged by setValue, at merge time.
- * @var array
- * @access public
- */
- var $value = null;
- /**
- * Class constructor
- * @param mixed $attributes Associative array of table tag attributes
- * or HTML attributes name="value" pairs
- * @access public
- */
- function HTML_Template_Flexy_Element($tag='', $attributes=null)
- {
-
- $this->tag = strtolower($tag);
- if (false !== strpos($tag, ':')) {
- $bits = explode(':',$this->tag);
- $this->tag = $bits[0] . ':'.strtolower($bits[1]);
- }
-
- $this->setAttributes($attributes);
- } // end constructor
-
-
- /**
- * Returns an HTML formatted attribute string
- * @param array $attributes
- * @return string
- * @access private
- */
- function attributesToHTML()
- {
- $strAttr = '';
- $xhtmlclose = '';
- $charset = empty($GLOBALS['HTML_Template_Flexy']['options']['charset']) ? 'ISO-8859-1' : $GLOBALS['HTML_Template_Flexy']['options']['charset'];
- foreach ($this->attributes as $key => $value) {
-
- // you shouldn't do this, but It shouldnt barf when you do..
- if (is_array($value) || is_object($value)) {
- continue;
- }
-
- if ($key == 'flexy:xhtml') {
- continue;
- }
- if ($value === false) {
- continue;
- }
- if ($value === true) {
- // this is not xhtml compatible..
- if ($key == '/') {
- $xhtmlclose = ' /';
- continue;
- }
- if (isset($this->attributes['flexy:xhtml'])) {
- $strAttr .= " {$key}=\"{$key}\"";
- } else {
- $strAttr .= ' ' . $key;
- }
- } else {
- // dont replace & with &
- if ($this->tag == 'textbox') { // XUL linefeed fix.
- $value = str_replace("\n", '
', htmlspecialchars($value,ENT_COMPAT,$charset));
- } else {
- $value = str_replace(' ',' ',htmlspecialchars($value,ENT_COMPAT,$charset));
- }
- $strAttr .= ' ' . $key . '="' . $value . '"';
- }
-
- }
- $strAttr .= $xhtmlclose;
- return $strAttr;
- } // end func _getAttrString
-
- /**
- * Static Method to get key/value array from attributes.
- * Returns a valid atrributes array from either a string or array
- * @param mixed $attributes Either a typical HTML attribute string or an associative array
- * @access private
- */
- function parseAttributes($attributes)
- {
- if (is_array($attributes)) {
- $ret = array();
- foreach ($attributes as $key => $value) {
- if (is_int($key)) {
- $ret[strtolower($value)] = true;
- } else {
- $ret[strtolower($key)] = $value;
- }
- }
- return $ret;
-
- } elseif (is_string($attributes)) {
- $preg = "/(([A-Za-z_:]|[^\\x00-\\x7F])([A-Za-z0-9_:.-]|[^\\x00-\\x7F])*)" .
- "([ \\n\\t\\r]+)?(=([ \\n\\t\\r]+)?(\"[^\"]*\"|'[^']*'|[^ \\n\\t\\r]*))?/";
- if (preg_match_all($preg, $attributes, $regs)) {
- for ($counter=0; $counter<count($regs[1]); $counter++) {
- $name = $regs[1][$counter];
- $check = $regs[0][$counter];
- $value = $regs[7][$counter];
- if (trim($name) == trim($check)) {
- $arrAttr[strtolower(trim($name))] = strtolower(trim($name));
- } else {
- if (substr($value, 0, 1) == "\"" || substr($value, 0, 1) == "'") {
- $value = substr($value, 1, -1);
- }
- $arrAttr[strtolower(trim($name))] = trim($value);
- }
- }
- return $arrAttr;
- }
- }
- } // end func _parseAttributes
-
-
-
-
- /**
- * Utility function to set values from common tag types.
- * @param HTML_Element $from override settings from another element.
- * @access public
- */
-
- function setValue($value) {
- // store the value in all situations
- $this->value = $value;
- $tag = strtolower($this->tag);
- if (strpos($tag,':') !== false) {
- $bits = explode(':',$tag);
- $tag = $bits[1];
- }
- switch ($tag) {
- case 'input':
- switch (isset($this->attributes['type']) ? strtolower($this->attributes['type']) : '') {
- case 'checkbox':
- if (isset($this->attributes['checked'])) {
- unset($this->attributes['checked']);
- }
- // if value is nto set, it doesnt make any difference what you set ?
- if (!isset($this->attributes['value'])) {
- return;
- }
- //print_r($this); echo "SET TO "; serialize($value);
- if (isset($this->attributes['name']) && (substr($this->attributes['name'],-2) == '[]')) {
- if (is_array($value) &&
- in_array((string) $this->attributes['value'],$value)
- ) {
- $this->attributes['checked'] = true;
- }
- return;
- }
- if ($this->attributes['value'] == $value) {
- $this->attributes['checked'] = true;
- }
-
-
- return;
- case 'radio':
- if (isset($this->attributes['checked'])) {
- unset($this->attributes['checked']);
- }
- // if we dont have values associated yet, store it..
- if (!isset($this->attributes['value'])) {
- $this->value = $value;
- return;
- }
- if ($this->attributes['value'] == $value) {
- $this->attributes['checked'] = true;
- }
- return;
-
- default:
- // no other input accepts array as a value.
- if (is_array($value)) {
- return;
- }
-
- $this->attributes['value'] = $value;
- return;
- }
-
- case 'select':
-
- if (!is_array($value)) {
- $value = array($value);
- }
-
- // its setting the default value..
-
- foreach($this->children as $i=>$child) {
-
- if (is_string($child)) {
- continue;
- }
- if ($child->tag == 'optgroup') {
- foreach($this->children[$i]->children as $ii=>$child) {
-
- // does the value exist and match..
- if (isset($child->attributes['value'])
- && in_array((string) $child->attributes['value'], $value))
- {
- $this->children[$i]->children[$ii]->attributes['selected'] =
- isset($this->attributes['flexy:xhtml']) ? 'selected' : true;
- continue;
- }
- if (isset($child->attributes['value']) &&
- isset($this->children[$i]->children[$ii]->attributes['selected']))
- {
- unset($this->children[$i]->children[$ii]->attributes['selected']);
- continue;
- }
- // value doesnt exst..
-
- if (isset($this->children[$i]->children[$ii]->attributes['selected'])) {
- unset($this->children[$i]->children[$ii]->attributes['selected']);
- continue;
- }
- }
- continue;
- }
-
- // standard option value...
- //echo "testing {$child->attributes['value']} against ". print_r($value,true)."\n";
- // does the value exist and match..
-
- if (isset($child->attributes['value'])
- && in_array((string) $child->attributes['value'], $value))
- {
-
-
- $this->children[$i]->attributes['selected'] =
- isset($this->attributes['flexy:xhtml']) ? 'selected' : true;;
- continue;
- }
- // no value attribute try and use the contents.
- if (!isset($child->attributes['value'])
- && is_string($child->children[0])
- && in_array((string) $child->children[0], $value))
- {
-
- $this->children[$i]->attributes['selected'] =
- isset($this->attributes['flexy:xhtml']) ? 'selected' : true;
- continue;
- }
-
- if (isset($child->attributes['value']) &&
- isset($this->children[$i]->attributes['selected']))
- {
- //echo "clearing selected\n";
- unset($this->children[$i]->attributes['selected']);
- continue;
- }
- // value doesnt exst..
-
- if (isset($this->children[$i]->attributes['selected'])) {
- //echo "clearing selected\n";
- unset($this->children[$i]->attributes['selected']);
- continue;
- }
-
-
- }
- return;
- case 'textarea':
- case 'label':
- $charset = empty($GLOBALS['HTML_Template_Flexy']['options']['charset']) ? 'ISO-8859-1' : $GLOBALS['HTML_Template_Flexy']['options']['charset'];
- $this->children = array(htmlspecialchars($value,ENT_COMPAT,$charset));
- return;
- case '': // dummy objects.
- $this->value = $value;
- return;
-
- // XUL elements
- case 'menulist':
- case 'textbox':
- case 'checkbox':
- require_once 'HTML/Template/Flexy/Element/Xul.php';
- HTML_Template_Flexy_Element_Xul::setValue($this,$value);
- return ;
-
- default:
- if (is_array($value)) {
- return;
- }
- $this->value = $value;
- }
-
-
-
-
- }
- /**
- * Utility function equivilant to HTML_Select - loadArray **
- * but using
- * key=>value maps
- * <option value="key">Value</option>
- * Key=key (eg. both the same) maps to
- * <option>key</option>
- * and label = array(key=>value) maps to
- * <optgroup label="label"> <option value="key">value</option></optgroup>
- *
- * $element->setOptions(array('a'=>'xxx','b'=>'yyy'));
- * or
- * $element->setOptions(array('a','b','c','d'),true);
- *
- *
- *.
- * @param HTML_Element $from override settings from another element.
- * @param HTML_Element $noValue ignore the key part of the array
- * @access public
- */
-
- function setOptions($array,$noValue=false)
- {
- if (!is_array($array)) {
- $this->children = array();
- return;
- }
-
- $charset = empty($GLOBALS['HTML_Template_Flexy']['options']['charset']) ? 'ISO-8859-1' : $GLOBALS['HTML_Template_Flexy']['options']['charset'];
-
- $tag = strtolower($this->tag);
- $namespace = '';
- if (false !== strpos($this->tag, ':')) {
-
- $bits = explode(':',$this->tag);
- $namespace = $bits[0] . ':';
- $tag = strtolower($bits[1]);
-
- }
- // if we have specified a xultag!!?
- if (strlen($tag) && ($tag != 'select')) {
- require_once 'HTML/Template/Flexy/Element/Xul.php';
- return HTML_Template_Flexy_Element_Xul::setOptions($this,$array,$noValue);
- }
-
- foreach($array as $k=>$v) {
- if (is_array($v)) { // optgroup
- $child = new HTML_Template_Flexy_Element($namespace . 'optgroup',array('label'=>$k));
- foreach($v as $kk=>$vv) {
- $atts=array();
- if (($kk !== $vv) && !$noValue) {
- $atts = array('value'=>$kk);
- } else {
- $atts = array('value'=>$vv);
- }
- $add = new HTML_Template_Flexy_Element($namespace . 'option',$atts);
- $add->children = array(htmlspecialchars($vv,ENT_COMPAT,$charset));
- $child->children[] = $add;
- }
- $this->children[] = $child;
- continue;
- }
- $atts=array();
- if (($k !== $v) && !$noValue) {
- $atts = array('value'=>$k);
- } else {
- $atts = array('value'=>$v);
- }
- $add = new HTML_Template_Flexy_Element($namespace . 'option',$atts);
- $add->children = array(htmlspecialchars($v,ENT_COMPAT,$charset));
- $this->children[] = $add;
- }
-
- }
-
-
-
- /**
- * Returns THIS select element's options as an associative array
- * Validates that $this element is "select"
- * @return array $options
- * @access public
- */
- function getOptions()
- {
-
- $tag = strtolower($this->tag);
- $namespace = '';
- if (false !== strpos($this->tag, ':')) {
- $bits = explode(':',$this->tag);
- $namespace = $bits[0] . ':';
- $tag = strtolower($bits[1]);
- }
-
- // this is not a select element
- if (strlen($tag) && ($tag != 'select')) {
- return false;
- }
-
- // creates an associative array that can be used by setOptions()
- // null does work for no value ( a "Please Choose" option, for example)
- foreach ($this->children as $child) {
- if (is_object($child)) {
- $child->attributes['value'] = isset($child->attributes['value']) ? $child->attributes['value'] : '';
- $children[$child->attributes['value']] = $child->children[0];
- }
- }
- return $children;
- }
-
- /**
- * Removes all of this element's options
- * Validates that $this element is "select"
- * @return bool result
- * @access public
- */
- function clearOptions($children = array())
- {
- $tag = strtolower($this->tag);
- $namespace = '';
- if (false !== strpos($this->tag, ':')) {
- $bits = explode(':',$this->tag);
- $namespace = $bits[0] . ':';
- $tag = strtolower($bits[1]);
- }
-
- // this is not a select element
- if (strlen($tag) && ($tag != 'select')) {
- return false;
- }
-
- // clear this select's options
- $this->children = array(null);
- $this->values = array(null);
-
- // If called with an array of new options go ahead and set them
- $this->setOptions($children);
-
- return true;
- }
-
- /**
- * Sets the HTML attributes
- * @param mixed $attributes Either a typical HTML attribute string or an associative array
- * @access public
- */
-
- function setAttributes($attributes)
- {
- $attrs= $this->parseAttributes($attributes);
- if (!is_array($attrs)) {
- return false;
- }
- foreach ($attrs as $key => $value) {
- $this->attributes[$key] = $value;
- }
- } // end func updateAttributes
-
- /**
- * Removes an attributes
- *
- * @param string $attr Attribute name
- * @since 1.4
- * @access public
- * @return void
- * @throws
- */
- function removeAttributes($attrs)
- {
- if (is_string($attrs)) {
- $attrs = array($attrs);
- }
- foreach ($attrs as $attr) {
- if (isset($this->attributes[strtolower($attr)])) {
- $this->attributes[strtolower($attr)] = false;
- }
- }
- } //end func removeAttribute
-
-
- /**
- * Output HTML and children
- *
- * @access public
- * @param object $overlay = merge data from object.
- * @return string
- * @abstract
- */
- function toHtml($overlay=false)
- {
-
- //echo "BEFORE<PRE>";print_R($this);
- $ret = $this;
- if ($overlay !== false) {
- $ret = HTML_Template_Flexy::mergeElement($this,$overlay);
- }
-
- if ($ret->override !== false) {
- return $ret->override;
- }
- $prefix = $ret->prefix;
- if (is_object($prefix)) {
- $prefix = $prefix->toHtml();
- }
- $suffix = $ret->suffix;
- if (is_object($suffix)) {
- $suffix = $suffix->toHtml();
- }
- //echo "AFTER<PRE>";print_R($ret);
-
- $tag = $this->tag;
- if (strpos($tag,':') !== false) {
- $bits = explode(':',$tag);
- $tag = $bits[1];
- }
- // tags that never should have closers
- $close = "</{$ret->tag}>";
- if (in_array(strtoupper($tag),array("INPUT","IMG", "LINK", "META", "HR", "BR"))) {
- $close = '';
- }
- if (isset($this->attributes['/'])) {
- $close = '';
- }
-
- $close .= $suffix ;
-
- return "{$prefix}<{$ret->tag}".$ret->attributesToHTML() . '>'.$ret->childrenToHTML() .$close;
-
-
- } // end func toHtml
-
-
- /**
- * Output Open Tag and any children and not Child tag (designed for use with <form + hidden elements>
- *
- * @access public
- * @param object $overlay = merge data from object.
- * @return string
- * @abstract
- */
- function toHtmlnoClose($overlay=false)
- {
- $ret = $this;
- if ($ret->override !== false) {
- return $ret->override;
- }
- if ($overlay !== false) {
- $ret = HTML_Template_Flexy::mergeElement($this,$overlay);
- }
-
-
- return "<{$ret->tag}".$ret->attributesToHTML() . '>' . $ret->childrenToHTML();
-
-
- } // end func toHtml
-
-
- /**
- * Output HTML and children
- *
- * @access public
- * @return string
- * @abstract
- */
- function childrenToHtml()
- {
- $ret = '';
- foreach($this->children as $child) {
- if (!is_object($child)) {
- $ret .= $child;
- continue;
- }
-
- $ret .= $child->toHtml();
- }
- return $ret;
- } // end func toHtml
-
-
-
-
-
- } // end class HTML_Template_Flexy_Element
-