00001 <?php 00024 require_once 'Zend/View/Helper/Placeholder/Container/Standalone.php'; 00025 00035 class Zend_View_Helper_HeadStyle extends Zend_View_Helper_Placeholder_Container_Standalone 00036 { 00041 protected $_regKey = 'Zend_View_Helper_HeadStyle'; 00042 00047 protected $_optionalAttributes = array('lang', 'title', 'media', 'dir'); 00048 00053 protected $_mediaTypes = array( 00054 'all', 'aural', 'braille', 'handheld', 'print', 00055 'projection', 'screen', 'tty', 'tv' 00056 ); 00057 00062 protected $_captureAttrs = null; 00063 00068 protected $_captureLock; 00069 00074 protected $_captureType; 00075 00083 public function __construct() 00084 { 00085 parent::__construct(); 00086 $this->setSeparator(PHP_EOL); 00087 } 00088 00099 public function headStyle($content = null, $placement = 'APPEND', $attributes = array()) 00100 { 00101 if ((null !== $content) && is_string($content)) { 00102 switch (strtoupper($placement)) { 00103 case 'SET': 00104 $action = 'setStyle'; 00105 break; 00106 case 'PREPEND': 00107 $action = 'prependStyle'; 00108 break; 00109 case 'APPEND': 00110 default: 00111 $action = 'appendStyle'; 00112 break; 00113 } 00114 $this->$action($content, $attributes); 00115 } 00116 00117 return $this; 00118 } 00119 00134 public function __call($method, $args) 00135 { 00136 if (preg_match('/^(?P<action>set|(ap|pre)pend|offsetSet)(Style)$/', $method, $matches)) { 00137 $index = null; 00138 $argc = count($args); 00139 $action = $matches['action']; 00140 00141 if ('offsetSet' == $action) { 00142 if (0 < $argc) { 00143 $index = array_shift($args); 00144 --$argc; 00145 } 00146 } 00147 00148 if (1 > $argc) { 00149 require_once 'Zend/View/Exception.php'; 00150 throw new Zend_View_Exception(sprintf('Method "%s" requires minimally content for the stylesheet', $method)); 00151 } 00152 00153 $content = $args[0]; 00154 $attrs = array(); 00155 if (isset($args[1])) { 00156 $attrs = (array) $args[1]; 00157 } 00158 00159 $item = $this->createData($content, $attrs); 00160 00161 if ('offsetSet' == $action) { 00162 $this->offsetSet($index, $item); 00163 } else { 00164 $this->$action($item); 00165 } 00166 00167 return $this; 00168 } 00169 00170 return parent::__call($method, $args); 00171 } 00172 00180 protected function _isValid($value) 00181 { 00182 if ((!$value instanceof stdClass) 00183 || !isset($value->content) 00184 || !isset($value->attributes)) 00185 { 00186 return false; 00187 } 00188 00189 return true; 00190 } 00191 00198 public function append($value) 00199 { 00200 if (!$this->_isValid($value)) { 00201 require_once 'Zend/View/Exception.php'; 00202 throw new Zend_View_Exception('Invalid value passed to append; please use appendStyle()'); 00203 } 00204 00205 return $this->getContainer()->append($value); 00206 } 00207 00215 public function offsetSet($index, $value) 00216 { 00217 if (!$this->_isValid($value)) { 00218 require_once 'Zend/View/Exception.php'; 00219 throw new Zend_View_Exception('Invalid value passed to offsetSet; please use offsetSetStyle()'); 00220 } 00221 00222 return $this->getContainer()->offsetSet($index, $value); 00223 } 00224 00231 public function prepend($value) 00232 { 00233 if (!$this->_isValid($value)) { 00234 require_once 'Zend/View/Exception.php'; 00235 throw new Zend_View_Exception('Invalid value passed to prepend; please use prependStyle()'); 00236 } 00237 00238 return $this->getContainer()->prepend($value); 00239 } 00240 00247 public function set($value) 00248 { 00249 if (!$this->_isValid($value)) { 00250 require_once 'Zend/View/Exception.php'; 00251 throw new Zend_View_Exception('Invalid value passed to set; please use setStyle()'); 00252 } 00253 00254 return $this->getContainer()->set($value); 00255 } 00256 00264 public function captureStart($type = Zend_View_Helper_Placeholder_Container_Abstract::APPEND, $attrs = null) 00265 { 00266 if ($this->_captureLock) { 00267 require_once 'Zend/View/Helper/Placeholder/Container/Exception.php'; 00268 throw new Zend_View_Helper_Placeholder_Container_Exception('Cannot nest headStyle captures'); 00269 } 00270 00271 $this->_captureLock = true; 00272 $this->_captureAttrs = $attrs; 00273 $this->_captureType = $type; 00274 ob_start(); 00275 } 00276 00282 public function captureEnd() 00283 { 00284 $content = ob_get_clean(); 00285 $attrs = $this->_captureAttrs; 00286 $this->_captureAttrs = null; 00287 $this->_captureLock = false; 00288 00289 switch ($this->_captureType) { 00290 case Zend_View_Helper_Placeholder_Container_Abstract::SET: 00291 $this->setStyle($content, $attrs); 00292 break; 00293 case Zend_View_Helper_Placeholder_Container_Abstract::PREPEND: 00294 $this->prependStyle($content, $attrs); 00295 break; 00296 case Zend_View_Helper_Placeholder_Container_Abstract::APPEND: 00297 default: 00298 $this->appendStyle($content, $attrs); 00299 break; 00300 } 00301 } 00302 00310 public function itemToString(stdClass $item, $indent) 00311 { 00312 $attrString = ''; 00313 if (!empty($item->attributes)) { 00314 $enc = 'UTF-8'; 00315 if ($this->view instanceof Zend_View_Interface 00316 && method_exists($this->view, 'getEncoding') 00317 ) { 00318 $enc = $this->view->getEncoding(); 00319 } 00320 foreach ($item->attributes as $key => $value) { 00321 if (!in_array($key, $this->_optionalAttributes)) { 00322 continue; 00323 } 00324 if ('media' == $key) { 00325 if(false === strpos($value, ',')) { 00326 if (!in_array($value, $this->_mediaTypes)) { 00327 continue; 00328 } 00329 } else { 00330 $media_types = explode(',', $value); 00331 $value = ''; 00332 foreach($media_types as $type) { 00333 $type = trim($type); 00334 if (!in_array($type, $this->_mediaTypes)) { 00335 continue; 00336 } 00337 $value .= $type .','; 00338 } 00339 $value = substr($value, 0, -1); 00340 } 00341 } 00342 $attrString .= sprintf(' %s="%s"', $key, htmlspecialchars($value, ENT_COMPAT, $enc)); 00343 } 00344 } 00345 00346 $html = '<style type="text/css"' . $attrString . '>' . PHP_EOL 00347 . $indent . '<!--' . PHP_EOL . $indent . $item->content . PHP_EOL . $indent . '-->' . PHP_EOL 00348 . '</style>'; 00349 00350 if (isset($item->attributes['conditional']) 00351 && !empty($item->attributes['conditional']) 00352 && is_string($item->attributes['conditional'])) 00353 { 00354 $html = '<!--[if ' . $item->attributes['conditional'] . ']> ' . $html . '<![endif]-->'; 00355 } 00356 00357 return $html; 00358 } 00359 00366 public function toString($indent = null) 00367 { 00368 $indent = (null !== $indent) 00369 ? $this->getWhitespace($indent) 00370 : $this->getIndent(); 00371 00372 $items = array(); 00373 $this->getContainer()->ksort(); 00374 foreach ($this as $item) { 00375 if (!$this->_isValid($item)) { 00376 continue; 00377 } 00378 $items[] = $this->itemToString($item, $indent); 00379 } 00380 00381 $return = $indent . implode($this->getSeparator() . $indent, $items); 00382 $return = preg_replace("/(\r\n?|\n)/", '$1' . $indent, $return); 00383 return $return; 00384 } 00385 00393 public function createData($content, array $attributes) 00394 { 00395 if (!isset($attributes['media'])) { 00396 $attributes['media'] = 'screen'; 00397 } else if(is_array($attributes['media'])) { 00398 $attributes['media'] = implode(',', $attributes['media']); 00399 } 00400 00401 $data = new stdClass(); 00402 $data->content = $content; 00403 $data->attributes = $attributes; 00404 00405 return $data; 00406 } 00407 }