Viewing file: Element.php (25.53 KB) -rw-rw-rw- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?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 299896 2010-05-28 06:03:39Z alan_k $
/** * 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; /** * If an input element has a label element associated to it * *and* the 'useElementLabels' option is true, then you can * optionally set the text of this label. This permits * to set custom strings for doing translations. * @var string | null * @access public */ var $label = 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('&nbsp;',' ',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; } // removed - see bug 15279 - not sure if there is any knock on effects from this. ///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($ret->attributes['flexy:xhtml'])) { $this->attributes['/'] = true; }
} 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 /** * merge this element with another * originally was in main engine * * @param HTML_Template_Flexy_Element $new (with data to replace/merge) * @return HTML_Template_Flexy_Element the combined/merged data. * @static * @access public */ function merge($new) { // Clone objects is possible to avoid creating references between elements $original = clone($this); // no new - return original if (!$new) { return $original; }
$new = clone($new); // If the properties of $original differ from those of $new and // they are set on $new, set them to $new's. Otherwise leave them // as they are.
if ($new->tag && ($new->tag != $original->tag)) { $original->tag = $new->tag; } if ($new->override !== false) { $original->override = $new->override; } if (count($new->children)) { //echo "<PRE> COPY CHILDREN"; print_r($from->children); $original->children = $new->children; } if (is_array($new->attributes)) { foreach ($new->attributes as $key => $value) { $original->attributes[$key] = $value; } } // originals never have prefixes or suffixes.. $original->prefix = $new->prefix; $original->suffix = $new->suffix;
if ($new->value !== null) { $original->setValue($new->value); } if ($new->label !== null) { $original->label = $new->label; } return $original; } } // end class HTML_Template_Flexy_Element
|