web/lib/Zend/View/Helper/HeadMeta.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     1 <?php
       
     2 /**
       
     3  * Zend Framework
       
     4  *
       
     5  * LICENSE
       
     6  *
       
     7  * This source file is subject to the new BSD license that is bundled
       
     8  * with this package in the file LICENSE.txt.
       
     9  * It is also available through the world-wide-web at this URL:
       
    10  * http://framework.zend.com/license/new-bsd
       
    11  * If you did not receive a copy of the license and are unable to
       
    12  * obtain it through the world-wide-web, please send an email
       
    13  * to license@zend.com so we can send you a copy immediately.
       
    14  *
       
    15  * @category   Zend
       
    16  * @package    Zend_View
       
    17  * @subpackage Helper
       
    18  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    19  * @version    $Id: HeadMeta.php 20096 2010-01-06 02:05:09Z bkarwin $
       
    20  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    21  */
       
    22 
       
    23 /** Zend_View_Helper_Placeholder_Container_Standalone */
       
    24 require_once 'Zend/View/Helper/Placeholder/Container/Standalone.php';
       
    25 
       
    26 /**
       
    27  * Zend_Layout_View_Helper_HeadMeta
       
    28  *
       
    29  * @see        http://www.w3.org/TR/xhtml1/dtds.html
       
    30  * @uses       Zend_View_Helper_Placeholder_Container_Standalone
       
    31  * @package    Zend_View
       
    32  * @subpackage Helper
       
    33  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    34  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    35  */
       
    36 class Zend_View_Helper_HeadMeta extends Zend_View_Helper_Placeholder_Container_Standalone
       
    37 {
       
    38     /**
       
    39      * Types of attributes
       
    40      * @var array
       
    41      */
       
    42     protected $_typeKeys     = array('name', 'http-equiv', 'charset');
       
    43     protected $_requiredKeys = array('content');
       
    44     protected $_modifierKeys = array('lang', 'scheme');
       
    45 
       
    46     /**
       
    47      * @var string registry key
       
    48      */
       
    49     protected $_regKey = 'Zend_View_Helper_HeadMeta';
       
    50 
       
    51     /**
       
    52      * Constructor
       
    53      *
       
    54      * Set separator to PHP_EOL
       
    55      *
       
    56      * @return void
       
    57      */
       
    58     public function __construct()
       
    59     {
       
    60         parent::__construct();
       
    61         $this->setSeparator(PHP_EOL);
       
    62     }
       
    63 
       
    64     /**
       
    65      * Retrieve object instance; optionally add meta tag
       
    66      *
       
    67      * @param  string $content
       
    68      * @param  string $keyValue
       
    69      * @param  string $keyType
       
    70      * @param  array $modifiers
       
    71      * @param  string $placement
       
    72      * @return Zend_View_Helper_HeadMeta
       
    73      */
       
    74     public function headMeta($content = null, $keyValue = null, $keyType = 'name', $modifiers = array(), $placement = Zend_View_Helper_Placeholder_Container_Abstract::APPEND)
       
    75     {
       
    76         if ((null !== $content) && (null !== $keyValue)) {
       
    77             $item   = $this->createData($keyType, $keyValue, $content, $modifiers);
       
    78             $action = strtolower($placement);
       
    79             switch ($action) {
       
    80                 case 'append':
       
    81                 case 'prepend':
       
    82                 case 'set':
       
    83                     $this->$action($item);
       
    84                     break;
       
    85                 default:
       
    86                     $this->append($item);
       
    87                     break;
       
    88             }
       
    89         }
       
    90 
       
    91         return $this;
       
    92     }
       
    93 
       
    94     protected function _normalizeType($type)
       
    95     {
       
    96         switch ($type) {
       
    97             case 'Name':
       
    98                 return 'name';
       
    99             case 'HttpEquiv':
       
   100                 return 'http-equiv';
       
   101             default:
       
   102                 require_once 'Zend/View/Exception.php';
       
   103                 $e = new Zend_View_Exception(sprintf('Invalid type "%s" passed to _normalizeType', $type));
       
   104                 $e->setView($this->view);
       
   105                 throw $e;
       
   106         }
       
   107     }
       
   108 
       
   109     /**
       
   110      * Overload method access
       
   111      *
       
   112      * Allows the following 'virtual' methods:
       
   113      * - appendName($keyValue, $content, $modifiers = array())
       
   114      * - offsetGetName($index, $keyValue, $content, $modifers = array())
       
   115      * - prependName($keyValue, $content, $modifiers = array())
       
   116      * - setName($keyValue, $content, $modifiers = array())
       
   117      * - appendHttpEquiv($keyValue, $content, $modifiers = array())
       
   118      * - offsetGetHttpEquiv($index, $keyValue, $content, $modifers = array())
       
   119      * - prependHttpEquiv($keyValue, $content, $modifiers = array())
       
   120      * - setHttpEquiv($keyValue, $content, $modifiers = array())
       
   121      *
       
   122      * @param  string $method
       
   123      * @param  array $args
       
   124      * @return Zend_View_Helper_HeadMeta
       
   125      */
       
   126     public function __call($method, $args)
       
   127     {
       
   128         if (preg_match('/^(?P<action>set|(pre|ap)pend|offsetSet)(?P<type>Name|HttpEquiv)$/', $method, $matches)) {
       
   129             $action = $matches['action'];
       
   130             $type   = $this->_normalizeType($matches['type']);
       
   131             $argc   = count($args);
       
   132             $index  = null;
       
   133 
       
   134             if ('offsetSet' == $action) {
       
   135                 if (0 < $argc) {
       
   136                     $index = array_shift($args);
       
   137                     --$argc;
       
   138                 }
       
   139             }
       
   140 
       
   141             if (2 > $argc) {
       
   142                 require_once 'Zend/View/Exception.php';
       
   143                 $e = new Zend_View_Exception('Too few arguments provided; requires key value, and content');
       
   144                 $e->setView($this->view);
       
   145                 throw $e;
       
   146             }
       
   147 
       
   148             if (3 > $argc) {
       
   149                 $args[] = array();
       
   150             }
       
   151 
       
   152             $item  = $this->createData($type, $args[0], $args[1], $args[2]);
       
   153 
       
   154             if ('offsetSet' == $action) {
       
   155                 return $this->offsetSet($index, $item);
       
   156             }
       
   157 
       
   158             $this->$action($item);
       
   159             return $this;
       
   160         }
       
   161 
       
   162         return parent::__call($method, $args);
       
   163     }
       
   164 
       
   165 	/**
       
   166 	 * Create an HTML5-style meta charset tag. Something like <meta charset="utf-8">
       
   167 	 * 
       
   168 	 * Not valid in a non-HTML5 doctype
       
   169 	 *
       
   170 	 * @param string $charset 
       
   171 	 * @return Zend_View_Helper_HeadMeta Provides a fluent interface
       
   172 	 */
       
   173     public function setCharset($charset)
       
   174     {
       
   175         $item = new stdClass;
       
   176         $item->type = 'charset';
       
   177         $item->charset = $charset;
       
   178         $item->content = null;
       
   179         $item->modifiers = array();
       
   180         $this->set($item);
       
   181         return $this;
       
   182     }
       
   183 
       
   184     /**
       
   185      * Determine if item is valid
       
   186      *
       
   187      * @param  mixed $item
       
   188      * @return boolean
       
   189      */
       
   190     protected function _isValid($item)
       
   191     {
       
   192         if ((!$item instanceof stdClass)
       
   193             || !isset($item->type)
       
   194             || !isset($item->modifiers))
       
   195         {
       
   196             return false;
       
   197         }
       
   198 
       
   199         if (!isset($item->content)
       
   200         && (! $this->view->doctype()->isHtml5()
       
   201         || (! $this->view->doctype()->isHtml5() && $item->type !== 'charset'))) {
       
   202             return false;
       
   203         }
       
   204 
       
   205         return true;
       
   206     }
       
   207 
       
   208     /**
       
   209      * Append
       
   210      *
       
   211      * @param  string $value
       
   212      * @return void
       
   213      * @throws Zend_View_Exception
       
   214      */
       
   215     public function append($value)
       
   216     {
       
   217         if (!$this->_isValid($value)) {
       
   218             require_once 'Zend/View/Exception.php';
       
   219             $e = new Zend_View_Exception('Invalid value passed to append; please use appendMeta()');
       
   220             $e->setView($this->view);
       
   221             throw $e;
       
   222         }
       
   223 
       
   224         return $this->getContainer()->append($value);
       
   225     }
       
   226 
       
   227     /**
       
   228      * OffsetSet
       
   229      *
       
   230      * @param  string|int $index
       
   231      * @param  string $value
       
   232      * @return void
       
   233      * @throws Zend_View_Exception
       
   234      */
       
   235     public function offsetSet($index, $value)
       
   236     {
       
   237         if (!$this->_isValid($value)) {
       
   238             require_once 'Zend/View/Exception.php';
       
   239             $e =  new Zend_View_Exception('Invalid value passed to offsetSet; please use offsetSetName() or offsetSetHttpEquiv()');
       
   240             $e->setView($this->view);
       
   241             throw $e;
       
   242         }
       
   243 
       
   244         return $this->getContainer()->offsetSet($index, $value);
       
   245     }
       
   246 
       
   247     /**
       
   248      * OffsetUnset
       
   249      *
       
   250      * @param  string|int $index
       
   251      * @return void
       
   252      * @throws Zend_View_Exception
       
   253      */
       
   254     public function offsetUnset($index)
       
   255     {
       
   256         if (!in_array($index, $this->getContainer()->getKeys())) {
       
   257             require_once 'Zend/View/Exception.php';
       
   258             $e = new Zend_View_Exception('Invalid index passed to offsetUnset()');
       
   259             $e->setView($this->view);
       
   260             throw $e;
       
   261         }
       
   262 
       
   263         return $this->getContainer()->offsetUnset($index);
       
   264     }
       
   265 
       
   266     /**
       
   267      * Prepend
       
   268      *
       
   269      * @param  string $value
       
   270      * @return void
       
   271      * @throws Zend_View_Exception
       
   272      */
       
   273     public function prepend($value)
       
   274     {
       
   275         if (!$this->_isValid($value)) {
       
   276             require_once 'Zend/View/Exception.php';
       
   277             $e = new Zend_View_Exception('Invalid value passed to prepend; please use prependMeta()');
       
   278             $e->setView($this->view);
       
   279             throw $e;
       
   280         }
       
   281 
       
   282         return $this->getContainer()->prepend($value);
       
   283     }
       
   284 
       
   285     /**
       
   286      * Set
       
   287      *
       
   288      * @param  string $value
       
   289      * @return void
       
   290      * @throws Zend_View_Exception
       
   291      */
       
   292     public function set($value)
       
   293     {
       
   294         if (!$this->_isValid($value)) {
       
   295             require_once 'Zend/View/Exception.php';
       
   296             $e = new Zend_View_Exception('Invalid value passed to set; please use setMeta()');
       
   297             $e->setView($this->view);
       
   298             throw $e;
       
   299         }
       
   300 
       
   301         $container = $this->getContainer();
       
   302         foreach ($container->getArrayCopy() as $index => $item) {
       
   303             if ($item->type == $value->type && $item->{$item->type} == $value->{$value->type}) {
       
   304                 $this->offsetUnset($index);
       
   305             }
       
   306         }
       
   307 
       
   308         return $this->append($value);
       
   309     }
       
   310 
       
   311     /**
       
   312      * Build meta HTML string
       
   313      *
       
   314      * @param  string $type
       
   315      * @param  string $typeValue
       
   316      * @param  string $content
       
   317      * @param  array $modifiers
       
   318      * @return string
       
   319      */
       
   320     public function itemToString(stdClass $item)
       
   321     {
       
   322         if (!in_array($item->type, $this->_typeKeys)) {
       
   323             require_once 'Zend/View/Exception.php';
       
   324             $e = new Zend_View_Exception(sprintf('Invalid type "%s" provided for meta', $item->type));
       
   325             $e->setView($this->view);
       
   326             throw $e;
       
   327         }
       
   328         $type = $item->type;
       
   329 
       
   330         $modifiersString = '';
       
   331         foreach ($item->modifiers as $key => $value) {
       
   332             if ($this->view->doctype()->isHtml5()
       
   333             && $key == 'scheme') {
       
   334                 require_once 'Zend/View/Exception.php';
       
   335                 throw new Zend_View_Exception('Invalid modifier '
       
   336                 . '"scheme" provided; not supported by HTML5');
       
   337             }
       
   338             if (!in_array($key, $this->_modifierKeys)) {
       
   339                 continue;
       
   340             }
       
   341             $modifiersString .= $key . '="' . $this->_escape($value) . '" ';
       
   342         }
       
   343 
       
   344         if ($this->view instanceof Zend_View_Abstract) {
       
   345             if ($this->view->doctype()->isHtml5()
       
   346             && $type == 'charset') {
       
   347 				$tpl = ($this->view->doctype()->isXhtml())
       
   348 					? '<meta %s="%s"/>'
       
   349 					: '<meta %s="%s">';
       
   350             } elseif ($this->view->doctype()->isXhtml()) {
       
   351                 $tpl = '<meta %s="%s" content="%s" %s/>';
       
   352             } else {
       
   353                 $tpl = '<meta %s="%s" content="%s" %s>';
       
   354             }
       
   355         } else {
       
   356             $tpl = '<meta %s="%s" content="%s" %s/>';
       
   357         }
       
   358 
       
   359         $meta = sprintf(
       
   360             $tpl,
       
   361             $type,
       
   362             $this->_escape($item->$type),
       
   363             $this->_escape($item->content),
       
   364             $modifiersString
       
   365         );
       
   366         return $meta;
       
   367     }
       
   368 
       
   369     /**
       
   370      * Render placeholder as string
       
   371      *
       
   372      * @param  string|int $indent
       
   373      * @return string
       
   374      */
       
   375     public function toString($indent = null)
       
   376     {
       
   377         $indent = (null !== $indent)
       
   378                 ? $this->getWhitespace($indent)
       
   379                 : $this->getIndent();
       
   380 
       
   381         $items = array();
       
   382         $this->getContainer()->ksort();
       
   383         try {
       
   384             foreach ($this as $item) {
       
   385                 $items[] = $this->itemToString($item);
       
   386             }
       
   387         } catch (Zend_View_Exception $e) {
       
   388             trigger_error($e->getMessage(), E_USER_WARNING);
       
   389             return '';
       
   390         }
       
   391         return $indent . implode($this->_escape($this->getSeparator()) . $indent, $items);
       
   392     }
       
   393 
       
   394     /**
       
   395      * Create data item for inserting into stack
       
   396      *
       
   397      * @param  string $type
       
   398      * @param  string $typeValue
       
   399      * @param  string $content
       
   400      * @param  array $modifiers
       
   401      * @return stdClass
       
   402      */
       
   403     public function createData($type, $typeValue, $content, array $modifiers)
       
   404     {
       
   405         $data            = new stdClass;
       
   406         $data->type      = $type;
       
   407         $data->$type     = $typeValue;
       
   408         $data->content   = $content;
       
   409         $data->modifiers = $modifiers;
       
   410         return $data;
       
   411     }
       
   412 }