File indexing completed on 2024-12-22 05:37:13
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_View 0017 * @subpackage Helper 0018 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0019 * @version $Id$ 0020 * @license http://framework.zend.com/license/new-bsd New BSD License 0021 */ 0022 0023 /** Zend_View_Helper_Placeholder_Container_Standalone */ 0024 // require_once 'Zend/View/Helper/Placeholder/Container/Standalone.php'; 0025 0026 /** 0027 * Zend_Layout_View_Helper_HeadMeta 0028 * 0029 * @see http://www.w3.org/TR/xhtml1/dtds.html 0030 * @uses Zend_View_Helper_Placeholder_Container_Standalone 0031 * @package Zend_View 0032 * @subpackage Helper 0033 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0034 * @license http://framework.zend.com/license/new-bsd New BSD License 0035 * @method $this appendHttpEquiv($keyValue, $content, $conditionalHttpEquiv) 0036 * @method $this appendName($keyValue, $content, $conditionalName) 0037 * @method $this appendProperty($property, $content, $modifiers) 0038 * @method $this offsetSetHttpEquiv($index, $keyValue, $content, $conditionalHttpEquiv) 0039 * @method $this offsetSetName($index, $keyValue, $content, $conditionalName) 0040 * @method $this offsetSetProperty($index, $property, $content, $modifiers) 0041 * @method $this prependHttpEquiv($keyValue, $content, $conditionalHttpEquiv) 0042 * @method $this prependName($keyValue, $content, $conditionalName) 0043 * @method $this prependProperty($property, $content, $modifiers) 0044 * @method $this setCharset($charset) 0045 * @method $this setHttpEquiv($keyValue, $content, $modifiers) 0046 * @method $this setName($keyValue, $content, $modifiers) 0047 * @method $this setProperty($property, $content, $modifiers) 0048 */ 0049 class Zend_View_Helper_HeadMeta extends Zend_View_Helper_Placeholder_Container_Standalone 0050 { 0051 /** 0052 * Types of attributes 0053 * @var array 0054 */ 0055 protected $_typeKeys = array('name', 'http-equiv', 'charset', 'property'); 0056 protected $_requiredKeys = array('content'); 0057 protected $_modifierKeys = array('lang', 'scheme'); 0058 0059 /** 0060 * @var string registry key 0061 */ 0062 protected $_regKey = 'Zend_View_Helper_HeadMeta'; 0063 0064 /** 0065 * Constructor 0066 * 0067 * Set separator to PHP_EOL 0068 * 0069 * @return void 0070 */ 0071 public function __construct() 0072 { 0073 parent::__construct(); 0074 $this->setSeparator(PHP_EOL); 0075 } 0076 0077 /** 0078 * Retrieve object instance; optionally add meta tag 0079 * 0080 * @param string $content 0081 * @param string $keyValue 0082 * @param string $keyType 0083 * @param array $modifiers 0084 * @param string $placement 0085 * @return Zend_View_Helper_HeadMeta 0086 */ 0087 public function headMeta($content = null, $keyValue = null, $keyType = 'name', $modifiers = array(), $placement = Zend_View_Helper_Placeholder_Container_Abstract::APPEND) 0088 { 0089 if ((null !== $content) && (null !== $keyValue)) { 0090 $item = $this->createData($keyType, $keyValue, $content, $modifiers); 0091 $action = strtolower($placement); 0092 switch ($action) { 0093 case 'append': 0094 case 'prepend': 0095 case 'set': 0096 $this->$action($item); 0097 break; 0098 default: 0099 $this->append($item); 0100 break; 0101 } 0102 } 0103 0104 return $this; 0105 } 0106 0107 protected function _normalizeType($type) 0108 { 0109 switch ($type) { 0110 case 'Name': 0111 return 'name'; 0112 case 'HttpEquiv': 0113 return 'http-equiv'; 0114 case 'Property': 0115 return 'property'; 0116 default: 0117 // require_once 'Zend/View/Exception.php'; 0118 $e = new Zend_View_Exception(sprintf('Invalid type "%s" passed to _normalizeType', $type)); 0119 $e->setView($this->view); 0120 throw $e; 0121 } 0122 } 0123 0124 /** 0125 * Overload method access 0126 * 0127 * Allows the following 'virtual' methods: 0128 * - appendName($keyValue, $content, $modifiers = array()) 0129 * - offsetGetName($index, $keyValue, $content, $modifers = array()) 0130 * - prependName($keyValue, $content, $modifiers = array()) 0131 * - setName($keyValue, $content, $modifiers = array()) 0132 * - appendHttpEquiv($keyValue, $content, $modifiers = array()) 0133 * - offsetGetHttpEquiv($index, $keyValue, $content, $modifers = array()) 0134 * - prependHttpEquiv($keyValue, $content, $modifiers = array()) 0135 * - setHttpEquiv($keyValue, $content, $modifiers = array()) 0136 * - appendProperty($keyValue, $content, $modifiers = array()) 0137 * - offsetGetProperty($index, $keyValue, $content, $modifiers = array()) 0138 * - prependProperty($keyValue, $content, $modifiers = array()) 0139 * - setProperty($keyValue, $content, $modifiers = array()) 0140 * 0141 * @param string $method 0142 * @param array $args 0143 * @return Zend_View_Helper_HeadMeta 0144 */ 0145 public function __call($method, $args) 0146 { 0147 if (preg_match('/^(?P<action>set|(pre|ap)pend|offsetSet)(?P<type>Name|HttpEquiv|Property)$/', $method, $matches)) { 0148 $action = $matches['action']; 0149 $type = $this->_normalizeType($matches['type']); 0150 $argc = count($args); 0151 $index = null; 0152 0153 if ('offsetSet' == $action) { 0154 if (0 < $argc) { 0155 $index = array_shift($args); 0156 --$argc; 0157 } 0158 } 0159 0160 if (2 > $argc) { 0161 // require_once 'Zend/View/Exception.php'; 0162 $e = new Zend_View_Exception('Too few arguments provided; requires key value, and content'); 0163 $e->setView($this->view); 0164 throw $e; 0165 } 0166 0167 if (3 > $argc) { 0168 $args[] = array(); 0169 } 0170 0171 $item = $this->createData($type, $args[0], $args[1], $args[2]); 0172 0173 if ('offsetSet' == $action) { 0174 return $this->offsetSet($index, $item); 0175 } 0176 0177 $this->$action($item); 0178 return $this; 0179 } 0180 0181 return parent::__call($method, $args); 0182 } 0183 0184 /** 0185 * Create an HTML5-style meta charset tag. Something like <meta charset="utf-8"> 0186 * 0187 * Not valid in a non-HTML5 doctype 0188 * 0189 * @param string $charset 0190 * @return Zend_View_Helper_HeadMeta Provides a fluent interface 0191 */ 0192 public function setCharset($charset) 0193 { 0194 $item = new stdClass; 0195 $item->type = 'charset'; 0196 $item->charset = $charset; 0197 $item->content = null; 0198 $item->modifiers = array(); 0199 $this->set($item); 0200 return $this; 0201 } 0202 0203 /** 0204 * Determine if item is valid 0205 * 0206 * @param mixed $item 0207 * @return boolean 0208 */ 0209 protected function _isValid($item) 0210 { 0211 if ((!$item instanceof stdClass) 0212 || !isset($item->type) 0213 || !isset($item->modifiers)) 0214 { 0215 return false; 0216 } 0217 0218 $isHtml5 = is_null($this->view) ? false : $this->view->doctype()->isHtml5(); 0219 0220 if (!isset($item->content) 0221 && (! $isHtml5 || (! $isHtml5 && $item->type !== 'charset'))) { 0222 return false; 0223 } 0224 0225 // <meta property= ... /> is only supported with doctype RDFa 0226 if ( !is_null($this->view) && !$this->view->doctype()->isRdfa() 0227 && $item->type === 'property') { 0228 return false; 0229 } 0230 0231 return true; 0232 } 0233 0234 /** 0235 * Append 0236 * 0237 * @param string $value 0238 * @return void 0239 * @throws Zend_View_Exception 0240 */ 0241 public function append($value) 0242 { 0243 if (!$this->_isValid($value)) { 0244 // require_once 'Zend/View/Exception.php'; 0245 $e = new Zend_View_Exception('Invalid value passed to append; please use appendMeta()'); 0246 $e->setView($this->view); 0247 throw $e; 0248 } 0249 0250 return $this->getContainer()->append($value); 0251 } 0252 0253 /** 0254 * OffsetSet 0255 * 0256 * @param string|int $index 0257 * @param string $value 0258 * @return void 0259 * @throws Zend_View_Exception 0260 */ 0261 public function offsetSet($index, $value) 0262 { 0263 if (!$this->_isValid($value)) { 0264 // require_once 'Zend/View/Exception.php'; 0265 $e = new Zend_View_Exception('Invalid value passed to offsetSet; please use offsetSetName() or offsetSetHttpEquiv()'); 0266 $e->setView($this->view); 0267 throw $e; 0268 } 0269 0270 return $this->getContainer()->offsetSet($index, $value); 0271 } 0272 0273 /** 0274 * OffsetUnset 0275 * 0276 * @param string|int $index 0277 * @return void 0278 * @throws Zend_View_Exception 0279 */ 0280 public function offsetUnset($index) 0281 { 0282 if (!in_array($index, $this->getContainer()->getKeys())) { 0283 // require_once 'Zend/View/Exception.php'; 0284 $e = new Zend_View_Exception('Invalid index passed to offsetUnset()'); 0285 $e->setView($this->view); 0286 throw $e; 0287 } 0288 0289 return $this->getContainer()->offsetUnset($index); 0290 } 0291 0292 /** 0293 * Prepend 0294 * 0295 * @param string $value 0296 * @return void 0297 * @throws Zend_View_Exception 0298 */ 0299 public function prepend($value) 0300 { 0301 if (!$this->_isValid($value)) { 0302 // require_once 'Zend/View/Exception.php'; 0303 $e = new Zend_View_Exception('Invalid value passed to prepend; please use prependMeta()'); 0304 $e->setView($this->view); 0305 throw $e; 0306 } 0307 0308 return $this->getContainer()->prepend($value); 0309 } 0310 0311 /** 0312 * Set 0313 * 0314 * @param string $value 0315 * @return void 0316 * @throws Zend_View_Exception 0317 */ 0318 public function set($value) 0319 { 0320 if (!$this->_isValid($value)) { 0321 // require_once 'Zend/View/Exception.php'; 0322 $e = new Zend_View_Exception('Invalid value passed to set; please use setMeta()'); 0323 $e->setView($this->view); 0324 throw $e; 0325 } 0326 0327 $container = $this->getContainer(); 0328 foreach ($container->getArrayCopy() as $index => $item) { 0329 if ($item->type == $value->type && $item->{$item->type} == $value->{$value->type}) { 0330 $this->offsetUnset($index); 0331 } 0332 } 0333 0334 return $this->append($value); 0335 } 0336 0337 /** 0338 * Build meta HTML string 0339 * 0340 * @param string $type 0341 * @param string $typeValue 0342 * @param string $content 0343 * @param array $modifiers 0344 * @return string 0345 */ 0346 public function itemToString(stdClass $item) 0347 { 0348 if (!in_array($item->type, $this->_typeKeys)) { 0349 // require_once 'Zend/View/Exception.php'; 0350 $e = new Zend_View_Exception(sprintf('Invalid type "%s" provided for meta', $item->type)); 0351 $e->setView($this->view); 0352 throw $e; 0353 } 0354 $type = $item->type; 0355 0356 $modifiersString = ''; 0357 foreach ($item->modifiers as $key => $value) { 0358 if (!is_null($this->view) && $this->view->doctype()->isHtml5() 0359 && $key == 'scheme') { 0360 // require_once 'Zend/View/Exception.php'; 0361 throw new Zend_View_Exception('Invalid modifier ' 0362 . '"scheme" provided; not supported by HTML5'); 0363 } 0364 if (!in_array($key, $this->_modifierKeys)) { 0365 continue; 0366 } 0367 $modifiersString .= $key . '="' . $this->_escape($value) . '" '; 0368 } 0369 0370 if ($this->view instanceof Zend_View_Abstract) { 0371 if ($this->view->doctype()->isHtml5() 0372 && $type == 'charset') { 0373 $tpl = ($this->view->doctype()->isXhtml()) 0374 ? '<meta %s="%s"/>' 0375 : '<meta %s="%s">'; 0376 } elseif ($this->view->doctype()->isXhtml()) { 0377 $tpl = '<meta %s="%s" content="%s" %s/>'; 0378 } else { 0379 $tpl = '<meta %s="%s" content="%s" %s>'; 0380 } 0381 } else { 0382 $tpl = '<meta %s="%s" content="%s" %s/>'; 0383 } 0384 0385 $meta = sprintf( 0386 $tpl, 0387 $type, 0388 $this->_escape($item->$type), 0389 $this->_escape($item->content), 0390 $modifiersString 0391 ); 0392 0393 if (isset($item->modifiers['conditional']) 0394 && !empty($item->modifiers['conditional']) 0395 && is_string($item->modifiers['conditional'])) 0396 { 0397 if (str_replace(' ', '', $item->modifiers['conditional']) === '!IE') { 0398 $meta = '<!-->' . $meta . '<!--'; 0399 } 0400 $meta = '<!--[if ' . $this->_escape($item->modifiers['conditional']) . ']>' . $meta . '<![endif]-->'; 0401 } 0402 0403 return $meta; 0404 } 0405 0406 /** 0407 * Render placeholder as string 0408 * 0409 * @param string|int $indent 0410 * @return string 0411 */ 0412 public function toString($indent = null) 0413 { 0414 $indent = (null !== $indent) 0415 ? $this->getWhitespace($indent) 0416 : $this->getIndent(); 0417 0418 $items = array(); 0419 $this->getContainer()->ksort(); 0420 try { 0421 foreach ($this as $item) { 0422 $items[] = $this->itemToString($item); 0423 } 0424 } catch (Zend_View_Exception $e) { 0425 trigger_error($e->getMessage(), E_USER_WARNING); 0426 return ''; 0427 } 0428 return $indent . implode($this->_escape($this->getSeparator()) . $indent, $items); 0429 } 0430 0431 /** 0432 * Create data item for inserting into stack 0433 * 0434 * @param string $type 0435 * @param string $typeValue 0436 * @param string $content 0437 * @param array $modifiers 0438 * @return stdClass 0439 */ 0440 public function createData($type, $typeValue, $content, array $modifiers) 0441 { 0442 $data = new stdClass; 0443 $data->type = $type; 0444 $data->$type = $typeValue; 0445 $data->content = $content; 0446 $data->modifiers = $modifiers; 0447 return $data; 0448 } 0449 }