home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / HTML / Template / Flexy / Element.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  23.3 KB  |  685 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group             |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Author: Alan Knowles <alan@akbkhome.com>                             |
  17. // | Based on HTML_Common by: Adam Daniel <adaniel1@eesus.jnj.com>        |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // $Id: Element.php,v 1.49 2007/10/18 03:26:34 alan_k Exp $
  21.  
  22. /**
  23.  * Lightweight HTML Element builder and render
  24.  *
  25.  * This differs from HTML_Common in the following ways:
  26.  *
  27.  * $element->attributes is Public
  28.  * $element->override if set to anything other than false, renders the value rather than 
  29.  *   the defined element
  30.  *
  31.  * $element->children is a recursvable child array which is rendered by toHTML
  32.  * $element->toHtml() is implemented
  33.  * $element->toHtmlNoClose() renders  only the first tag and children (designed for <form
  34.  * No support for tab offsets, comments ...
  35.  *
  36.  * Full support for Select, and common Form elements using
  37.  * setValue()
  38.  * setOptions()
  39.  * 
  40.  * overlay support with SetFrom - base + inherited..
  41.  *
  42.  * attributes array values:
  43.  *  key="value" // standard key="value" in output
  44.  *  key = true // outputs just key.
  45.  *
  46.  * children can be 
  47.  *  another HTML_Element
  48.  *  or string (raw text)
  49.  *
  50.  *
  51.  * @author      Adam Daniel <adaniel1@eesus.jnj.com>
  52.  * @version     1.6
  53.  * @since       PHP 4.0.3pl1
  54.  * @abstract
  55.  */
  56. class HTML_Template_Flexy_Element {
  57.  
  58.     
  59.  
  60.     /**
  61.      * Tag that this Element represents.
  62.      * @var  array
  63.      * @access   public
  64.      */
  65.     var $tag =  '';
  66.     /**
  67.      * Associative array of table attributes
  68.      * Note Special values:
  69.      *   true == only display the key 
  70.      *   false == remove
  71.      *
  72.      * @var  array
  73.      * @access   public
  74.      */
  75.     var $attributes = array();
  76.  
  77.     /**
  78.      * Sequence array of children
  79.      * children that are strings are assumed to be text 
  80.      * @var  array
  81.      * @access   public
  82.      */
  83.     var $children = array();
  84.     
  85.     /**
  86.      * override the tag.
  87.      * if this is set to anything other than false, it will be output 
  88.      * rather than the tags+children
  89.      * @var  array
  90.      * @access   public
  91.      */
  92.     var $override = false;
  93.     /**
  94.      * prefix the tag.
  95.      * this is output by toHtml as a prefix to the tag (can be used for require tags)
  96.      * @var  array
  97.      * @access   private
  98.      */
  99.     var $prefix = '';
  100.     /**
  101.      * suffix the tag.
  102.      * this is output by toHtml as a suffix to the tag (can be used for error messages)
  103.      * @var  array
  104.      * @access   private
  105.      */
  106.     var $suffix = '';
  107.     
  108.     /**
  109.      * a value for delayed merging into live objects
  110.      * if you set this on an element, it is merged by setValue, at merge time.
  111.      * @var  array
  112.      * @access   public
  113.      */
  114.     var $value = null;
  115.     /**
  116.      * Class constructor
  117.      * @param    mixed   $attributes     Associative array of table tag attributes 
  118.      *                                   or HTML attributes name="value" pairs
  119.      * @access   public
  120.      */
  121.     function HTML_Template_Flexy_Element($tag='', $attributes=null)
  122.     {
  123.         
  124.         $this->tag = strtolower($tag);
  125.         if (false !== strpos($tag, ':')) {
  126.             $bits = explode(':',$this->tag);
  127.             $this->tag = $bits[0] . ':'.strtolower($bits[1]);
  128.         }
  129.         
  130.         $this->setAttributes($attributes);
  131.     } // end constructor
  132.  
  133.       
  134.     /**
  135.      * Returns an HTML formatted attribute string
  136.      * @param    array   $attributes
  137.      * @return   string
  138.      * @access   private
  139.      */
  140.     function attributesToHTML()
  141.     {
  142.         $strAttr = '';
  143.         $xhtmlclose = '';
  144.         $charset = empty($GLOBALS['HTML_Template_Flexy']['options']['charset']) ? 'ISO-8859-1' : $GLOBALS['HTML_Template_Flexy']['options']['charset'];
  145.         foreach ($this->attributes as $key => $value) {
  146.         
  147.             // you shouldn't do this, but It shouldnt barf when you do..
  148.             if (is_array($value) || is_object($value)) {
  149.                 continue;
  150.             }
  151.             
  152.             if ($key == 'flexy:xhtml') {
  153.                 continue;
  154.             }
  155.             if ($value === false) {
  156.                 continue;
  157.             }
  158.             if ($value === true) {
  159.                 // this is not xhtml compatible..
  160.                 if ($key == '/') {
  161.                     $xhtmlclose = ' /';
  162.                     continue;
  163.                 }
  164.                 if (isset($this->attributes['flexy:xhtml'])) {
  165.                     $strAttr .= " {$key}=\"{$key}\"";
  166.                 } else {
  167.                     $strAttr .= ' ' . $key;
  168.                 }
  169.             } else {
  170.                 // dont replace & with &
  171.                 if ($this->tag == 'textbox') {  // XUL linefeed fix.
  172.                     $value = str_replace("\n", ' ', htmlspecialchars($value,ENT_COMPAT,$charset));
  173.                 } else {
  174.                     $value = str_replace('&nbsp;',' ',htmlspecialchars($value,ENT_COMPAT,$charset));
  175.                 }
  176.                 $strAttr .= ' ' . $key . '="' . $value  . '"';
  177.             }
  178.             
  179.         }
  180.         $strAttr .= $xhtmlclose;
  181.         return $strAttr;
  182.     } // end func _getAttrString
  183.  
  184.     /**
  185.      * Static Method to get key/value array from attributes.
  186.      * Returns a valid atrributes array from either a string or array
  187.      * @param    mixed   $attributes     Either a typical HTML attribute string or an associative array
  188.      * @access   private
  189.      */
  190.     function parseAttributes($attributes)
  191.     {
  192.         if (is_array($attributes)) {
  193.             $ret = array();
  194.             foreach ($attributes as $key => $value) {
  195.                 if (is_int($key)) {
  196.                     $ret[strtolower($value)] = true;
  197.                 } else {
  198.                     $ret[strtolower($key)]   = $value;
  199.                 }
  200.             }
  201.             return $ret;
  202.  
  203.         } elseif (is_string($attributes)) {
  204.             $preg = "/(([A-Za-z_:]|[^\\x00-\\x7F])([A-Za-z0-9_:.-]|[^\\x00-\\x7F])*)" .
  205.                 "([ \\n\\t\\r]+)?(=([ \\n\\t\\r]+)?(\"[^\"]*\"|'[^']*'|[^ \\n\\t\\r]*))?/";
  206.             if (preg_match_all($preg, $attributes, $regs)) {
  207.                 for ($counter=0; $counter<count($regs[1]); $counter++) {
  208.                     $name  = $regs[1][$counter];
  209.                     $check = $regs[0][$counter];
  210.                     $value = $regs[7][$counter];
  211.                     if (trim($name) == trim($check)) {
  212.                         $arrAttr[strtolower(trim($name))] = strtolower(trim($name));
  213.                     } else {
  214.                         if (substr($value, 0, 1) == "\"" || substr($value, 0, 1) == "'") {
  215.                             $value = substr($value, 1, -1);
  216.                         }
  217.                         $arrAttr[strtolower(trim($name))] = trim($value);
  218.                     }
  219.                 }
  220.                 return $arrAttr;
  221.             }
  222.         }
  223.     } // end func _parseAttributes
  224.  
  225.      
  226.      
  227.        
  228.     /**
  229.      * Utility function to set values from common tag types.
  230.      * @param    HTML_Element   $from  override settings from another element.
  231.      * @access   public
  232.      */
  233.      
  234.     function setValue($value) {
  235.         // store the value in all situations
  236.         $this->value = $value;
  237.         $tag = strtolower($this->tag);
  238.         if (strpos($tag,':') !==  false) {
  239.             $bits = explode(':',$tag);
  240.             $tag = $bits[1];
  241.         }
  242.         switch ($tag) {
  243.             case 'input':
  244.                 switch (isset($this->attributes['type']) ? strtolower($this->attributes['type']) : '') {
  245.                     case 'checkbox':
  246.                         if (isset($this->attributes['checked'])) {
  247.                             unset($this->attributes['checked']);
  248.                         }
  249.                         // if value is nto set, it doesnt make any difference what you set ?
  250.                         if (!isset($this->attributes['value'])) {
  251.                             return;
  252.                         }
  253.                         //print_r($this); echo "SET TO "; serialize($value);
  254.                         if (isset($this->attributes['name']) && (substr($this->attributes['name'],-2) == '[]')) {
  255.                             if (is_array($value) && 
  256.                                 in_array((string) $this->attributes['value'],$value)
  257.                                 ) {
  258.                                 $this->attributes['checked'] =  true;
  259.                             }
  260.                             return;
  261.                         }
  262.                         if ($this->attributes['value'] == $value) {
  263.                             $this->attributes['checked'] =  true;
  264.                         }
  265.                         
  266.                         
  267.                         return;
  268.                     case 'radio':
  269.                         if (isset($this->attributes['checked'])) {
  270.                             unset($this->attributes['checked']);
  271.                         }
  272.                         // if we dont have values associated yet, store it..
  273.                         if (!isset($this->attributes['value'])) {
  274.                             $this->value = $value;
  275.                             return;
  276.                         }
  277.                         if ($this->attributes['value'] == $value) {
  278.                             $this->attributes['checked'] =  true;
  279.                         }
  280.                         return;
  281.                     
  282.                     default:
  283.                         // no other input accepts array as a value.
  284.                         if (is_array($value)) {
  285.                             return;
  286.                         }
  287.                     
  288.                         $this->attributes['value'] = $value;
  289.                         return;
  290.                 }
  291.                 
  292.             case 'select':
  293.                 
  294.                 if (!is_array($value)) {
  295.                     $value = array($value);
  296.                 }
  297.                 
  298.                 // its setting the default value..
  299.                 
  300.                 foreach($this->children as $i=>$child) {
  301.                     
  302.                     if (is_string($child)) {
  303.                         continue;
  304.                     }
  305.                     if ($child->tag == 'optgroup') {
  306.                         foreach($this->children[$i]->children as $ii=>$child) {
  307.                         
  308.                             // does the value exist and match..
  309.                             if (isset($child->attributes['value']) 
  310.                                 && in_array((string) $child->attributes['value'], $value)) 
  311.                             {
  312.                                 $this->children[$i]->children[$ii]->attributes['selected'] = 
  313.                                     isset($this->attributes['flexy:xhtml']) ? 'selected' : true;
  314.                                 continue;
  315.                             }
  316.                             if (isset($child->attributes['value']) && 
  317.                                 isset($this->children[$i]->children[$ii]->attributes['selected'])) 
  318.                             {
  319.                                 unset($this->children[$i]->children[$ii]->attributes['selected']);
  320.                                 continue;
  321.                             }
  322.                             // value doesnt exst..
  323.                           
  324.                             if (isset($this->children[$i]->children[$ii]->attributes['selected'])) {
  325.                                 unset($this->children[$i]->children[$ii]->attributes['selected']);
  326.                                 continue;
  327.                             }
  328.                         }
  329.                         continue;
  330.                     }
  331.                     
  332.                     // standard option value...
  333.                     //echo "testing {$child->attributes['value']} against ". print_r($value,true)."\n";
  334.                     // does the value exist and match..
  335.                      
  336.                     if (isset($child->attributes['value']) 
  337.                         && in_array((string) $child->attributes['value'], $value)) 
  338.                     {
  339.                         
  340.                       
  341.                         $this->children[$i]->attributes['selected'] = 
  342.                             isset($this->attributes['flexy:xhtml']) ? 'selected' : true;;
  343.                         continue;
  344.                     }
  345.                     // no value attribute try and use the contents.
  346.                     if (!isset($child->attributes['value'])
  347.                         && is_string($child->children[0])
  348.                         && in_array((string) $child->children[0], $value))
  349.                     {
  350.                         
  351.                         $this->children[$i]->attributes['selected'] =
  352.                             isset($this->attributes['flexy:xhtml']) ? 'selected' : true;
  353.                         continue;
  354.                     }
  355.                      
  356.                     if (isset($child->attributes['value']) && 
  357.                         isset($this->children[$i]->attributes['selected'])) 
  358.                     {
  359.                         //echo "clearing selected\n";
  360.                         unset($this->children[$i]->attributes['selected']);
  361.                         continue;
  362.                     }
  363.                     // value doesnt exst..
  364.                     
  365.                     if (isset($this->children[$i]->attributes['selected'])) {
  366.                         //echo "clearing selected\n";
  367.                         unset($this->children[$i]->attributes['selected']);
  368.                         continue;
  369.                     }
  370.                     
  371.                     
  372.                 }
  373.                 return;
  374.             case 'textarea':
  375.             case 'label':
  376.                 $charset = empty($GLOBALS['HTML_Template_Flexy']['options']['charset']) ? 'ISO-8859-1' : $GLOBALS['HTML_Template_Flexy']['options']['charset'];
  377.                 $this->children = array(htmlspecialchars($value,ENT_COMPAT,$charset));
  378.                 return;
  379.             case '':  // dummy objects.
  380.                 $this->value = $value;
  381.                 return;
  382.                 
  383.             // XUL elements
  384.             case 'menulist':
  385.             case 'textbox':
  386.             case 'checkbox':
  387.                 require_once 'HTML/Template/Flexy/Element/Xul.php';
  388.                 HTML_Template_Flexy_Element_Xul::setValue($this,$value);
  389.                 return ;
  390.                 
  391.             default:
  392.                 if (is_array($value)) {
  393.                     return;
  394.                 }
  395.                 $this->value = $value;
  396.         }
  397.             
  398.         
  399.     
  400.     
  401.     }
  402.     /**
  403.      * Utility function equivilant to HTML_Select - loadArray ** 
  404.      * but using 
  405.      * key=>value maps 
  406.      * <option value="key">Value</option>
  407.      * Key=key (eg. both the same) maps to
  408.      * <option>key</option>
  409.      * and label = array(key=>value) maps to 
  410.      * <optgroup label="label"> <option value="key">value</option></optgroup>
  411.      * 
  412.      * $element->setOptions(array('a'=>'xxx','b'=>'yyy'));
  413.      * or
  414.      * $element->setOptions(array('a','b','c','d'),true);
  415.      *
  416.      *
  417.      *.
  418.      * @param    HTML_Element   $from  override settings from another element.
  419.      * @param    HTML_Element   $noValue  ignore the key part of the array
  420.      * @access   public
  421.      */
  422.      
  423.     function setOptions($array,$noValue=false) 
  424.     {
  425.         if (!is_array($array)) {
  426.             $this->children = array();
  427.             return;
  428.         }
  429.         
  430.         $charset = empty($GLOBALS['HTML_Template_Flexy']['options']['charset']) ? 'ISO-8859-1' : $GLOBALS['HTML_Template_Flexy']['options']['charset'];
  431.         
  432.         $tag = strtolower($this->tag);
  433.         $namespace = '';
  434.         if (false !== strpos($this->tag, ':')) {
  435.             
  436.             $bits = explode(':',$this->tag);
  437.             $namespace = $bits[0] . ':';
  438.             $tag = strtolower($bits[1]);
  439.             
  440.         }
  441.         // if we have specified a xultag!!?
  442.         if (strlen($tag) && ($tag != 'select')) {
  443.                 require_once 'HTML/Template/Flexy/Element/Xul.php';
  444.                 return HTML_Template_Flexy_Element_Xul::setOptions($this,$array,$noValue);
  445.         }
  446.         
  447.         foreach($array as $k=>$v) {
  448.             if (is_array($v)) {     // optgroup
  449.                 $child = new HTML_Template_Flexy_Element($namespace . 'optgroup',array('label'=>$k));
  450.                 foreach($v as $kk=>$vv) {
  451.                     $atts=array();
  452.                     if (($kk !== $vv) && !$noValue) {
  453.                         $atts = array('value'=>$kk);
  454.                     } else {
  455.                         $atts = array('value'=>$vv);
  456.                     }
  457.                     $add = new HTML_Template_Flexy_Element($namespace . 'option',$atts);
  458.                     $add->children = array(htmlspecialchars($vv,ENT_COMPAT,$charset));
  459.                     $child->children[] = $add;
  460.                 }
  461.                 $this->children[] = $child;
  462.                 continue;
  463.             } 
  464.             $atts=array();
  465.             if (($k !== $v) && !$noValue) {
  466.                 $atts = array('value'=>$k);
  467.             } else {
  468.                 $atts = array('value'=>$v);
  469.             }
  470.             $add = new HTML_Template_Flexy_Element($namespace . 'option',$atts);
  471.             $add->children = array(htmlspecialchars($v,ENT_COMPAT,$charset));
  472.             $this->children[] = $add;
  473.         }
  474.        
  475.     }
  476.     
  477.     
  478.     
  479.     /**
  480.      *  Returns THIS select element's options as an associative array
  481.      *  Validates that $this element is "select"
  482.      * @return array $options
  483.      * @access public
  484.     */
  485.     function getOptions()
  486.     {
  487.  
  488.         $tag = strtolower($this->tag);
  489.         $namespace = '';
  490.         if (false !== strpos($this->tag, ':')) {
  491.             $bits = explode(':',$this->tag);
  492.             $namespace = $bits[0] . ':';
  493.             $tag = strtolower($bits[1]);
  494.         }
  495.  
  496.         // this is not a select element
  497.         if (strlen($tag) && ($tag != 'select'))  {
  498.             return false;
  499.         }
  500.  
  501.         // creates an associative array that can be used by setOptions()
  502.         // null does work for no value ( a "Please Choose" option, for example)
  503.         foreach ($this->children as $child) {
  504.             if (is_object($child)) {
  505.                 $child->attributes['value'] = isset($child->attributes['value']) ? $child->attributes['value'] : '';
  506.                 $children[$child->attributes['value']] = $child->children[0];
  507.             }
  508.         }
  509.         return $children;
  510.     }
  511.  
  512.      /**
  513.      *  Removes all of this element's options
  514.      *  Validates that $this element is "select"
  515.      * @return bool result
  516.      * @access public
  517.     */
  518.     function clearOptions($children = array())
  519.     {
  520.         $tag = strtolower($this->tag);
  521.         $namespace = '';
  522.         if (false !== strpos($this->tag, ':')) {
  523.             $bits = explode(':',$this->tag);
  524.             $namespace = $bits[0] . ':';
  525.             $tag = strtolower($bits[1]);
  526.         }
  527.  
  528.         // this is not a select element
  529.         if (strlen($tag) && ($tag != 'select')) {
  530.             return false;
  531.         }
  532.  
  533.         // clear this select's options
  534.         $this->children = array(null);
  535.         $this->values = array(null);
  536.  
  537.         // If called with an array of new options go ahead and set them
  538.         $this->setOptions($children);
  539.  
  540.         return true;
  541.     }
  542.     
  543.     /**
  544.      * Sets the HTML attributes
  545.      * @param    mixed   $attributes     Either a typical HTML attribute string or an associative array
  546.      * @access   public
  547.      */
  548.      
  549.     function setAttributes($attributes)
  550.     {
  551.         $attrs= $this->parseAttributes($attributes);
  552.         if (!is_array($attrs)) {
  553.             return false;
  554.         }
  555.         foreach ($attrs as $key => $value) {
  556.             $this->attributes[$key] = $value;
  557.         }
  558.     } // end func updateAttributes
  559.  
  560.     /**
  561.      * Removes an attributes
  562.      * 
  563.      * @param     string    $attr   Attribute name
  564.      * @since     1.4
  565.      * @access    public
  566.      * @return    void
  567.      * @throws
  568.      */
  569.     function removeAttributes($attrs)
  570.     {
  571.         if (is_string($attrs)) {
  572.             $attrs = array($attrs);
  573.         }
  574.         foreach ($attrs as $attr) { 
  575.             if (isset($this->attributes[strtolower($attr)])) {
  576.                  $this->attributes[strtolower($attr)] = false;
  577.             } 
  578.         }
  579.     } //end func removeAttribute
  580.  
  581.       
  582.     /**
  583.      * Output HTML and children
  584.      *
  585.      * @access    public
  586.      * @param     object    $overlay = merge data from object.
  587.      * @return    string
  588.      * @abstract
  589.      */
  590.     function toHtml($overlay=false)
  591.     {
  592.          
  593.         //echo "BEFORE<PRE>";print_R($this);
  594.         $ret = $this;
  595.         if ($overlay !== false) {
  596.             $ret = HTML_Template_Flexy::mergeElement($this,$overlay);
  597.         }
  598.         
  599.         if ($ret->override !== false) {
  600.             return $ret->override;
  601.         }
  602.         $prefix = $ret->prefix;
  603.         if (is_object($prefix)) {
  604.             $prefix = $prefix->toHtml();
  605.         }
  606.         $suffix = $ret->suffix;
  607.         if (is_object($suffix)) {
  608.             $suffix = $suffix->toHtml();
  609.         }
  610.         //echo "AFTER<PRE>";print_R($ret);
  611.       
  612.         $tag = $this->tag;
  613.         if (strpos($tag,':') !==  false) {
  614.             $bits = explode(':',$tag);
  615.             $tag = $bits[1];
  616.         }
  617.         // tags that never should have closers  
  618.         $close = "</{$ret->tag}>";
  619.         if (in_array(strtoupper($tag),array("INPUT","IMG", "LINK", "META", "HR", "BR"))) {
  620.             $close = '';
  621.         }
  622.         if (isset($this->attributes['/'])) {
  623.             $close = '';
  624.         }
  625.  
  626.         $close .= $suffix ;
  627.        
  628.         return "{$prefix}<{$ret->tag}".$ret->attributesToHTML() . '>'.$ret->childrenToHTML() .$close;
  629.         
  630.          
  631.     } // end func toHtml
  632.     
  633.     
  634.     /**
  635.      * Output Open Tag and any children and not Child tag (designed for use with <form + hidden elements>
  636.      *
  637.      * @access    public
  638.      * @param     object    $overlay = merge data from object.
  639.      * @return    string
  640.      * @abstract
  641.      */
  642.     function toHtmlnoClose($overlay=false)
  643.     {
  644.         $ret = $this;
  645.         if ($ret->override !== false) {
  646.             return $ret->override;
  647.         }
  648.         if ($overlay !== false) {
  649.             $ret = HTML_Template_Flexy::mergeElement($this,$overlay);
  650.         }
  651.         
  652.   
  653.         return "<{$ret->tag}".$ret->attributesToHTML() . '>' . $ret->childrenToHTML();
  654.        
  655.          
  656.     } // end func toHtml
  657.     
  658.     
  659.     /**
  660.      * Output HTML and children
  661.      *
  662.      * @access    public
  663.      * @return    string
  664.      * @abstract
  665.      */
  666.     function childrenToHtml()
  667.     {
  668.         $ret = '';
  669.         foreach($this->children as $child) {
  670.             if (!is_object($child)) {
  671.                 $ret .= $child;
  672.                 continue;
  673.             }
  674.             
  675.             $ret .= $child->toHtml();
  676.         }
  677.         return $ret;
  678.     } // end func toHtml
  679.     
  680.      
  681.     
  682.     
  683.     
  684. } // end class HTML_Template_Flexy_Element
  685.