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 * Helper for setting and retrieving stylesheets 0028 * 0029 * @uses Zend_View_Helper_Placeholder_Container_Standalone 0030 * @package Zend_View 0031 * @subpackage Helper 0032 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0033 * @license http://framework.zend.com/license/new-bsd New BSD License 0034 * @method $this appendStyle($content, array $attributes = array()) 0035 * @method $this offsetSetStyle($index, $content, array $attributes = array()) 0036 * @method $this prependStyle($content, array $attributes = array()) 0037 * @method $this setStyle($content, array $attributes = array()) 0038 */ 0039 class Zend_View_Helper_HeadStyle extends Zend_View_Helper_Placeholder_Container_Standalone 0040 { 0041 /** 0042 * Registry key for placeholder 0043 * @var string 0044 */ 0045 protected $_regKey = 'Zend_View_Helper_HeadStyle'; 0046 0047 /** 0048 * Allowed optional attributes 0049 * @var array 0050 */ 0051 protected $_optionalAttributes = array('lang', 'title', 'media', 'dir'); 0052 0053 /** 0054 * Allowed media types 0055 * @var array 0056 */ 0057 protected $_mediaTypes = array( 0058 'all', 'aural', 'braille', 'handheld', 'print', 0059 'projection', 'screen', 'tty', 'tv' 0060 ); 0061 0062 /** 0063 * Capture type and/or attributes (used for hinting during capture) 0064 * @var string 0065 */ 0066 protected $_captureAttrs = null; 0067 0068 /** 0069 * Capture lock 0070 * @var bool 0071 */ 0072 protected $_captureLock; 0073 0074 /** 0075 * Capture type (append, prepend, set) 0076 * @var string 0077 */ 0078 protected $_captureType; 0079 0080 /** 0081 * Constructor 0082 * 0083 * Set separator to PHP_EOL. 0084 * 0085 * @return void 0086 */ 0087 public function __construct() 0088 { 0089 parent::__construct(); 0090 $this->setSeparator(PHP_EOL); 0091 } 0092 0093 /** 0094 * Return headStyle object 0095 * 0096 * Returns headStyle helper object; optionally, allows specifying 0097 * 0098 * @param string $content Stylesheet contents 0099 * @param string $placement Append, prepend, or set 0100 * @param string|array $attributes Optional attributes to utilize 0101 * @return Zend_View_Helper_HeadStyle 0102 */ 0103 public function headStyle($content = null, $placement = 'APPEND', $attributes = array()) 0104 { 0105 if ((null !== $content) && is_string($content)) { 0106 switch (strtoupper($placement)) { 0107 case 'SET': 0108 $action = 'setStyle'; 0109 break; 0110 case 'PREPEND': 0111 $action = 'prependStyle'; 0112 break; 0113 case 'APPEND': 0114 default: 0115 $action = 'appendStyle'; 0116 break; 0117 } 0118 $this->$action($content, $attributes); 0119 } 0120 0121 return $this; 0122 } 0123 0124 /** 0125 * Overload method calls 0126 * 0127 * Allows the following method calls: 0128 * - appendStyle($content, $attributes = array()) 0129 * - offsetSetStyle($index, $content, $attributes = array()) 0130 * - prependStyle($content, $attributes = array()) 0131 * - setStyle($content, $attributes = array()) 0132 * 0133 * @param string $method 0134 * @param array $args 0135 * @return void 0136 * @throws Zend_View_Exception When no $content provided or invalid method 0137 */ 0138 public function __call($method, $args) 0139 { 0140 if (preg_match('/^(?P<action>set|(ap|pre)pend|offsetSet)(Style)$/', $method, $matches)) { 0141 $index = null; 0142 $argc = count($args); 0143 $action = $matches['action']; 0144 0145 if ('offsetSet' == $action) { 0146 if (0 < $argc) { 0147 $index = array_shift($args); 0148 --$argc; 0149 } 0150 } 0151 0152 if (1 > $argc) { 0153 // require_once 'Zend/View/Exception.php'; 0154 $e = new Zend_View_Exception(sprintf('Method "%s" requires minimally content for the stylesheet', $method)); 0155 $e->setView($this->view); 0156 throw $e; 0157 } 0158 0159 $content = $args[0]; 0160 $attrs = array(); 0161 if (isset($args[1])) { 0162 $attrs = (array) $args[1]; 0163 } 0164 0165 $item = $this->createData($content, $attrs); 0166 0167 if ('offsetSet' == $action) { 0168 $this->offsetSet($index, $item); 0169 } else { 0170 $this->$action($item); 0171 } 0172 0173 return $this; 0174 } 0175 0176 return parent::__call($method, $args); 0177 } 0178 0179 /** 0180 * Determine if a value is a valid style tag 0181 * 0182 * @param mixed $value 0183 * @param string $method 0184 * @return boolean 0185 */ 0186 protected function _isValid($value) 0187 { 0188 if ((!$value instanceof stdClass) 0189 || !isset($value->content) 0190 || !isset($value->attributes)) 0191 { 0192 return false; 0193 } 0194 0195 return true; 0196 } 0197 0198 /** 0199 * Override append to enforce style creation 0200 * 0201 * @param mixed $value 0202 * @return void 0203 */ 0204 public function append($value) 0205 { 0206 if (!$this->_isValid($value)) { 0207 // require_once 'Zend/View/Exception.php'; 0208 $e = new Zend_View_Exception('Invalid value passed to append; please use appendStyle()'); 0209 $e->setView($this->view); 0210 throw $e; 0211 } 0212 0213 return $this->getContainer()->append($value); 0214 } 0215 0216 /** 0217 * Override offsetSet to enforce style creation 0218 * 0219 * @param string|int $index 0220 * @param mixed $value 0221 * @return void 0222 */ 0223 public function offsetSet($index, $value) 0224 { 0225 if (!$this->_isValid($value)) { 0226 // require_once 'Zend/View/Exception.php'; 0227 $e = new Zend_View_Exception('Invalid value passed to offsetSet; please use offsetSetStyle()'); 0228 $e->setView($this->view); 0229 throw $e; 0230 } 0231 0232 return $this->getContainer()->offsetSet($index, $value); 0233 } 0234 0235 /** 0236 * Override prepend to enforce style creation 0237 * 0238 * @param mixed $value 0239 * @return void 0240 */ 0241 public function prepend($value) 0242 { 0243 if (!$this->_isValid($value)) { 0244 // require_once 'Zend/View/Exception.php'; 0245 $e = new Zend_View_Exception('Invalid value passed to prepend; please use prependStyle()'); 0246 $e->setView($this->view); 0247 throw $e; 0248 } 0249 0250 return $this->getContainer()->prepend($value); 0251 } 0252 0253 /** 0254 * Override set to enforce style creation 0255 * 0256 * @param mixed $value 0257 * @return void 0258 */ 0259 public function set($value) 0260 { 0261 if (!$this->_isValid($value)) { 0262 // require_once 'Zend/View/Exception.php'; 0263 $e = new Zend_View_Exception('Invalid value passed to set; please use setStyle()'); 0264 $e->setView($this->view); 0265 throw $e; 0266 } 0267 0268 return $this->getContainer()->set($value); 0269 } 0270 0271 /** 0272 * Start capture action 0273 * 0274 * @param mixed $captureType 0275 * @param string $typeOrAttrs 0276 * @return void 0277 */ 0278 public function captureStart($type = Zend_View_Helper_Placeholder_Container_Abstract::APPEND, $attrs = null) 0279 { 0280 if ($this->_captureLock) { 0281 // require_once 'Zend/View/Helper/Placeholder/Container/Exception.php'; 0282 $e = new Zend_View_Helper_Placeholder_Container_Exception('Cannot nest headStyle captures'); 0283 $e->setView($this->view); 0284 throw $e; 0285 } 0286 0287 $this->_captureLock = true; 0288 $this->_captureAttrs = $attrs; 0289 $this->_captureType = $type; 0290 ob_start(); 0291 } 0292 0293 /** 0294 * End capture action and store 0295 * 0296 * @return void 0297 */ 0298 public function captureEnd() 0299 { 0300 $content = ob_get_clean(); 0301 $attrs = $this->_captureAttrs; 0302 $this->_captureAttrs = null; 0303 $this->_captureLock = false; 0304 0305 switch ($this->_captureType) { 0306 case Zend_View_Helper_Placeholder_Container_Abstract::SET: 0307 $this->setStyle($content, $attrs); 0308 break; 0309 case Zend_View_Helper_Placeholder_Container_Abstract::PREPEND: 0310 $this->prependStyle($content, $attrs); 0311 break; 0312 case Zend_View_Helper_Placeholder_Container_Abstract::APPEND: 0313 default: 0314 $this->appendStyle($content, $attrs); 0315 break; 0316 } 0317 } 0318 0319 /** 0320 * Convert content and attributes into valid style tag 0321 * 0322 * @param stdClass $item Item to render 0323 * @param string $indent Indentation to use 0324 * @return string 0325 */ 0326 public function itemToString(stdClass $item, $indent) 0327 { 0328 $attrString = ''; 0329 if (!empty($item->attributes)) { 0330 $enc = 'UTF-8'; 0331 if ($this->view instanceof Zend_View_Interface 0332 && method_exists($this->view, 'getEncoding') 0333 ) { 0334 $enc = $this->view->getEncoding(); 0335 } 0336 foreach ($item->attributes as $key => $value) { 0337 if (!in_array($key, $this->_optionalAttributes)) { 0338 continue; 0339 } 0340 if ('media' == $key) { 0341 if(false === strpos($value, ',')) { 0342 if (!in_array($value, $this->_mediaTypes)) { 0343 continue; 0344 } 0345 } else { 0346 $media_types = explode(',', $value); 0347 $value = ''; 0348 foreach($media_types as $type) { 0349 $type = trim($type); 0350 if (!in_array($type, $this->_mediaTypes)) { 0351 continue; 0352 } 0353 $value .= $type .','; 0354 } 0355 $value = substr($value, 0, -1); 0356 } 0357 } 0358 $attrString .= sprintf(' %s="%s"', $key, htmlspecialchars($value, ENT_COMPAT, $enc)); 0359 } 0360 } 0361 0362 $escapeStart = $indent . '<!--'. PHP_EOL; 0363 $escapeEnd = $indent . '-->'. PHP_EOL; 0364 if (isset($item->attributes['conditional']) 0365 && !empty($item->attributes['conditional']) 0366 && is_string($item->attributes['conditional']) 0367 ) { 0368 $escapeStart = null; 0369 $escapeEnd = null; 0370 } 0371 0372 $html = '<style type="text/css"' . $attrString . '>' . PHP_EOL 0373 . $escapeStart . $indent . $item->content . PHP_EOL . $escapeEnd 0374 . '</style>'; 0375 0376 if (null == $escapeStart && null == $escapeEnd) { 0377 if (str_replace(' ', '', $item->attributes['conditional']) === '!IE') { 0378 $html = '<!-->' . $html . '<!--'; 0379 } 0380 $html = '<!--[if ' . $item->attributes['conditional'] . ']>' . $html . '<![endif]-->'; 0381 } 0382 0383 return $html; 0384 } 0385 0386 /** 0387 * Create string representation of placeholder 0388 * 0389 * @param string|int $indent 0390 * @return string 0391 */ 0392 public function toString($indent = null) 0393 { 0394 $indent = (null !== $indent) 0395 ? $this->getWhitespace($indent) 0396 : $this->getIndent(); 0397 0398 $items = array(); 0399 $this->getContainer()->ksort(); 0400 foreach ($this as $item) { 0401 if (!$this->_isValid($item)) { 0402 continue; 0403 } 0404 $items[] = $this->itemToString($item, $indent); 0405 } 0406 0407 $return = $indent . implode($this->getSeparator() . $indent, $items); 0408 $return = preg_replace("/(\r\n?|\n)/", '$1' . $indent, $return); 0409 return $return; 0410 } 0411 0412 /** 0413 * Create data item for use in stack 0414 * 0415 * @param string $content 0416 * @param array $attributes 0417 * @return stdClass 0418 */ 0419 public function createData($content, array $attributes) 0420 { 0421 if (!isset($attributes['media'])) { 0422 $attributes['media'] = 'screen'; 0423 } else if(is_array($attributes['media'])) { 0424 $attributes['media'] = implode(',', $attributes['media']); 0425 } 0426 0427 $data = new stdClass(); 0428 $data->content = $content; 0429 $data->attributes = $attributes; 0430 0431 return $data; 0432 } 0433 }