| // | Based on HTML_Common by: Adam Daniel | // +----------------------------------------------------------------------+ // // $Id$ /** * 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
* @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; $countervalue = $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': $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 * * Key=key (eg. both the same) maps to * * and label = array(key=>value) maps to * * * $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; } } /** * 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
";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
";print_R($ret);
      
        $tag = $this->tag;
        if (strpos($tag,':') !==  false) {
            $bits = explode(':',$tag);
            $tag = $bits[1];
        }
        // tags that never should have closers  
        $close = "tag}>";
        if (in_array(strtoupper($tag),array("INPUT","IMG"))) {
            $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 
     *
     * @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