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 / Common2.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  12.8 KB  |  417 lines

  1. <?php
  2. /**
  3.  * HTML_Common2: port of HTML_Common package to PHP5
  4.  *
  5.  * PHP version 5
  6.  *
  7.  * LICENSE:
  8.  * 
  9.  * Copyright (c) 2004-2007, Alexey Borzov <avb@php.net>
  10.  *  
  11.  * All rights reserved.
  12.  *
  13.  * Redistribution and use in source and binary forms, with or without
  14.  * modification, are permitted provided that the following conditions
  15.  * are met:
  16.  *
  17.  *    * Redistributions of source code must retain the above copyright
  18.  *      notice, this list of conditions and the following disclaimer.
  19.  *    * Redistributions in binary form must reproduce the above copyright
  20.  *      notice, this list of conditions and the following disclaimer in the 
  21.  *      documentation and/or other materials provided with the distribution.
  22.  *    * The names of the authors may not be used to endorse or promote products 
  23.  *      derived from this software without specific prior written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  26.  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  27.  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  28.  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  29.  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  30.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  31.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  32.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  33.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  34.  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  35.  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36.  *
  37.  * @category   HTML
  38.  * @package    HTML_Common2
  39.  * @author     Alexey Borzov <avb@php.net>
  40.  * @license    http://opensource.org/licenses/bsd-license.php New BSD License
  41.  * @version    CVS: $Id: Common2.php,v 1.5 2007/05/04 10:01:32 avb Exp $
  42.  * @link       http://pear.php.net/package/HTML_Common2
  43.  */
  44.  
  45. /**
  46.  * Base class for HTML classes
  47.  * 
  48.  * Implements methods for working with HTML attributes, parsing and generating
  49.  * attribute strings. Port of HTML_Common class for PHP4 originally written by 
  50.  * Adam Daniel with contributions from numerous other developers.
  51.  * 
  52.  * @category   HTML
  53.  * @package    HTML_Common2
  54.  * @author     Alexey Borzov <avb@php.net>
  55.  * @version    Release: 2.0.0beta1
  56.  */
  57. abstract class HTML_Common2
  58. {
  59.    /**
  60.     * Associative array of attributes
  61.     * @var array
  62.     */
  63.     protected $attributes = array();
  64.  
  65.    /**
  66.     * List of attribites changes to which will be announced via onAttributeChange()
  67.     * method rather than performed by HTML_Common2 class itself 
  68.     * @var array
  69.     * @see onAttributeChange()
  70.     */
  71.     protected $watchedAttributes = array();
  72.  
  73.    /**
  74.     * Indentation level of the element
  75.     * @var int
  76.     */
  77.     private $_indentLevel = 0;
  78.  
  79.    /**
  80.     * Comment associated with the element  
  81.     * @var string
  82.     */
  83.     private $_comment = null;
  84.  
  85.    /**
  86.     * Global options for all elements generated by subclasses of HTML_Common2
  87.     *
  88.     * Preset options are
  89.     * - 'charset': charset parameter used in htmlspecialchars() calls,
  90.     *   defaults to 'ISO-8859-1'
  91.     * - 'indent': string used to indent HTML elements, defaults to "\11"
  92.     * - 'linebreak': string used to indicate linebreak, defaults to "\12"
  93.     *
  94.     * @var array
  95.     */
  96.     private static $_options = array(
  97.         'charset'   => 'ISO-8859-1',
  98.         'indent'    => "\11",
  99.         'linebreak' => "\12"
  100.     );
  101.  
  102.    /**
  103.     * Sets a global option
  104.     * 
  105.     * @param    string  Option name
  106.     * @param    mixed   Option value
  107.     */
  108.     public static function setOption($name, $value)
  109.     {
  110.         $linebreaks = array('win' => "\15\12", 'unix' => "\12", 'mac' => "\15");
  111.         if ('linebreak' == $name && isset($linebreaks[$value])) {
  112.             $value = $linebreaks[$value];
  113.         }
  114.         self::$_options[$name] = $value;
  115.     }
  116.  
  117.    /**
  118.     * Gets a global option
  119.     *
  120.     * @param    string  Option name
  121.     * @return   mixed   Option value, null if option does not exist
  122.     */
  123.     public static function getOption($name)
  124.     {
  125.         return isset(self::$_options[$name])? self::$_options[$name]: null;
  126.     }
  127.  
  128.    /**
  129.     * Parses the HTML attributes given as string
  130.     *
  131.     * @param    string  HTML attribute string
  132.     * @return   array   An associative aray of attributes
  133.     */
  134.     protected static function parseAttributes($attrString)
  135.     {
  136.         $attributes = array();
  137.         if (preg_match_all(
  138.                 "/(([A-Za-z_:]|[^\\x00-\\x7F])([A-Za-z0-9_:.-]|[^\\x00-\\x7F])*)" .
  139.                 "([ \\n\\t\\r]+)?(=([ \\n\\t\\r]+)?(\"[^\"]*\"|'[^']*'|[^ \\n\\t\\r]*))?/", 
  140.                 $attrString, 
  141.                 $regs
  142.            )) {
  143.             for ($i = 0; $i < count($regs[1]); $i++) {
  144.                 $name  = trim($regs[1][$i]);
  145.                 $check = trim($regs[0][$i]);
  146.                 $value = trim($regs[7][$i]);
  147.                 if ($name == $check) {
  148.                     $attributes[strtolower($name)] = strtolower($name);
  149.                 } else {
  150.                     if (!empty($value) && ($value[0] == '\'' || $value[0] == '"')) {
  151.                         $value = substr($value, 1, -1);
  152.                     }
  153.                     $attributes[strtolower($name)] = $value;
  154.                 }
  155.             }
  156.         }
  157.         return $attributes;
  158.     }
  159.  
  160.    /**
  161.     * Creates a valid attribute array from either a string or an array
  162.     *
  163.     * @param    mixed   Array of attributes or HTML attribute string
  164.     * @return   array   An associative aray of attributes
  165.     */
  166.     protected static function prepareAttributes($attributes)
  167.     {
  168.         $prepared = array();
  169.         if (is_string($attributes)) {
  170.             return self::parseAttributes($attributes);
  171.  
  172.         } elseif (is_array($attributes)) {
  173.             foreach ($attributes as $key => $value) {
  174.                 if (is_int($key)) {
  175.                     $key = strtolower($value);
  176.                     $prepared[$key] = $key;
  177.                 } else {
  178.                     $prepared[strtolower($key)] = (string)$value;
  179.                 }
  180.             }
  181.         }
  182.         return $prepared;
  183.     }
  184.  
  185.    /**
  186.     * Removes an attribute from an attribute array
  187.     * 
  188.     * @param    array   Attribute array
  189.     * @param    string  Name of attribute to remove
  190.     */
  191.     protected static function removeAttributeArray(&$attributes, $name)
  192.     {
  193.         unset($attributes[strtolower($name)]);
  194.     }
  195.  
  196.    /**
  197.     * Creates HTML attribute string from array
  198.     * 
  199.     * @param    array   Attribute array
  200.     * @return   string  Attribute string
  201.     */
  202.     protected static function getAttributesString($attributes)
  203.     {
  204.         $str = '';
  205.         if (is_array($attributes)) {
  206.             $charset = self::getOption('charset');
  207.             foreach ($attributes as $key => $value) {
  208.                 $str .= ' ' . $key . '="' . htmlspecialchars($value, ENT_QUOTES, $charset) . '"';
  209.             }
  210.         }
  211.         return $str;
  212.     }
  213.  
  214.    /**
  215.     * Class constructor, sets default attributes
  216.     * 
  217.     * @param    mixed   Array of attribute 'name' => 'value' pairs or HTML attribute string
  218.     */
  219.     public function __construct($attributes = null)
  220.     {
  221.         $this->mergeAttributes($attributes);
  222.     }
  223.  
  224.    /**
  225.     * Sets the value of the attribute
  226.     * 
  227.     * @param    string  Attribute name
  228.     * @param    string  Attribute value (will be set to $name if omitted)
  229.     * @return   HTML_Common2
  230.     */
  231.     public function setAttribute($name, $value = null)
  232.     {
  233.         $name = strtolower($name);
  234.         if (is_null($value)) {
  235.             $value = $name;
  236.         }
  237.         if (in_array($name, $this->watchedAttributes)) {
  238.             $this->onAttributeChange($name, $value);
  239.         } else {
  240.             $this->attributes[$name] = (string)$value;
  241.         }
  242.         return $this;
  243.     }
  244.  
  245.    /**
  246.     * Returns the value of an attribute
  247.     *
  248.     * @param    string  Attribute name
  249.     * @return   string  Attribute value, null if attribute does not exist
  250.     */
  251.     public function getAttribute($name)
  252.     {
  253.         $name = strtolower($name);
  254.         return isset($this->attributes[$name])? $this->attributes[$name]: null;
  255.     }
  256.  
  257.    /**
  258.     * Sets the attributes 
  259.     *
  260.     * @param    mixed   Array of attribute 'name' => 'value' pairs or HTML attribute string
  261.     * @return   HTML_Common2
  262.     */
  263.     public function setAttributes($attributes)
  264.     {
  265.         $attributes = self::prepareAttributes($attributes);
  266.         $watched    = array();
  267.         foreach ($this->watchedAttributes as $watchedKey) {
  268.             if (isset($attributes[$watchedKey])) {
  269.                 $this->setAttribute($watchedKey, $attributes[$watchedKey]);
  270.                 unset($attributes[$watchedKey]);
  271.             } else {
  272.                 $this->removeAttribute($watchedKey);
  273.             }
  274.             if (isset($this->attributes[$watchedKey])) {
  275.                 $watched[$watchedKey] = $this->attributes[$watchedKey]; 
  276.             }
  277.         }
  278.         $this->attributes = array_merge($watched, $attributes);
  279.         return $this;
  280.     }
  281.  
  282.    /**
  283.     * Returns the attribute array or string
  284.     * 
  285.     * @param    bool    Whether to return attributes as string
  286.     * @return   mixed   Either an array or string of attributes
  287.     */
  288.     public function getAttributes($asString = false)
  289.     {
  290.         if ($asString) {
  291.             return self::getAttributesString($this->attributes);
  292.         } else {
  293.             return $this->attributes;
  294.         }
  295.     }
  296.  
  297.    /**
  298.     * Merges the existing attributes with the new ones
  299.     *
  300.     * @param    mixed   Array of attribute 'name' => 'value' pairs or HTML attribute string
  301.     * @return   HTML_Common2
  302.     */
  303.     public function mergeAttributes($attributes)
  304.     {
  305.         $attributes = self::prepareAttributes($attributes);
  306.         foreach ($this->watchedAttributes as $watchedKey) {
  307.             if (isset($attributes[$watchedKey])) {
  308.                 $this->onAttributeChange($watchedKey, $attributes[$watchedKey]);
  309.                 unset($attributes[$watchedKey]);
  310.             }
  311.         }
  312.         $this->attributes = array_merge($this->attributes, $attributes);
  313.         return $this;
  314.     }
  315.  
  316.    /**
  317.     * Removes an attribute
  318.     *
  319.     * @param    string  Name of attribute to remove
  320.     * @return   HTML_Common2
  321.     */
  322.     public function removeAttribute($attribute)
  323.     {
  324.         if (in_array(strtolower($attribute), $this->watchedAttributes)) {
  325.             $this->onAttributeChange(strtolower($attribute), null);
  326.         } else {
  327.             self::removeAttributeArray($this->attributes, $attribute);
  328.         }
  329.         return $this;
  330.     }
  331.  
  332.    /**
  333.     * Sets the indentation level
  334.     *
  335.     * @param    int
  336.     * @return   HTML_Common2
  337.     */
  338.     public function setIndentLevel($level)
  339.     {
  340.         $level = intval($level);
  341.         if (0 <= $level) {
  342.             $this->_indentLevel = $level;
  343.         }
  344.         return $this;
  345.     }
  346.  
  347.    /**
  348.     * Gets the indentation level
  349.     *
  350.     * @return   int
  351.     */
  352.     public function getIndentLevel()
  353.     {
  354.         return $this->_indentLevel;
  355.     }
  356.  
  357.    /**
  358.     * Returns the string to indent the element
  359.     *
  360.     * @return   string
  361.     */
  362.     protected function getIndent()
  363.     {
  364.         return str_repeat(self::getOption('indent'), $this->getIndentLevel());
  365.     }
  366.  
  367.    /**
  368.     * Sets the comment for the element
  369.     * 
  370.     * @param    string
  371.     * @return   HTML_Common2
  372.     */
  373.     public function setComment($comment)
  374.     {
  375.         $this->_comment = $comment;
  376.         return $this;
  377.     }
  378.  
  379.    /**
  380.     * Returns the comment associated with the element
  381.     *
  382.     * @return   string
  383.     */
  384.     public function getComment()
  385.     {
  386.         return $this->_comment;
  387.     }
  388.  
  389.    /**
  390.     * Returns the HTML representation of the element
  391.     *
  392.     * This magic method allows using the instances of HTML_Common2 in string
  393.     * contexts
  394.     *
  395.     * @return string
  396.     */
  397.     abstract public function __toString();
  398.  
  399.    /**
  400.     * Called if trying to change an attribute with name in $watchedAttributes
  401.     *
  402.     * This method is called for each attribute whose name is in the
  403.     * $watchedAttributes array and which is being changed by setAttribute(),
  404.     * setAttributes() or mergeAttributes() or removed via removeAttribute().
  405.     * Note that the operation for the attribute is not carried on after calling
  406.     * this method, it is the responsibility of this method to change or remove
  407.     * (or not) the attribute.   
  408.     *
  409.     * @param    string  Attribute name
  410.     * @param    string  Attribute value, null if attribute is being removed
  411.     */
  412.     protected function onAttributeChange($name, $value = null)
  413.     {
  414.     }
  415. }
  416. ?>
  417.