00001 <?php 00024 require_once 'Zend/View/Helper/Placeholder/Container/Standalone.php'; 00025 00036 class Zend_View_Helper_HeadLink extends Zend_View_Helper_Placeholder_Container_Standalone 00037 { 00043 protected $_itemKeys = array('charset', 'href', 'hreflang', 'media', 'rel', 'rev', 'type', 'title', 'extras'); 00044 00048 protected $_regKey = 'Zend_View_Helper_HeadLink'; 00049 00057 public function __construct() 00058 { 00059 parent::__construct(); 00060 $this->setSeparator(PHP_EOL); 00061 } 00062 00071 public function headLink(array $attributes = null, $placement = Zend_View_Helper_Placeholder_Container_Abstract::APPEND) 00072 { 00073 if (null !== $attributes) { 00074 $item = $this->createData($attributes); 00075 switch ($placement) { 00076 case Zend_View_Helper_Placeholder_Container_Abstract::SET: 00077 $this->set($item); 00078 break; 00079 case Zend_View_Helper_Placeholder_Container_Abstract::PREPEND: 00080 $this->prepend($item); 00081 break; 00082 case Zend_View_Helper_Placeholder_Container_Abstract::APPEND: 00083 default: 00084 $this->append($item); 00085 break; 00086 } 00087 } 00088 return $this; 00089 } 00090 00126 public function __call($method, $args) 00127 { 00128 if (preg_match('/^(?P<action>set|(ap|pre)pend|offsetSet)(?P<type>Stylesheet|Alternate)$/', $method, $matches)) { 00129 $argc = count($args); 00130 $action = $matches['action']; 00131 $type = $matches['type']; 00132 $index = null; 00133 00134 if ('offsetSet' == $action) { 00135 if (0 < $argc) { 00136 $index = array_shift($args); 00137 --$argc; 00138 } 00139 } 00140 00141 if (1 > $argc) { 00142 require_once 'Zend/View/Exception.php'; 00143 throw new Zend_View_Exception(sprintf('%s requires at least one argument', $method)); 00144 } 00145 00146 if (is_array($args[0])) { 00147 $item = $this->createData($args[0]); 00148 } else { 00149 $dataMethod = 'createData' . $type; 00150 $item = $this->$dataMethod($args); 00151 } 00152 00153 if ($item) { 00154 if ('offsetSet' == $action) { 00155 $this->offsetSet($index, $item); 00156 } else { 00157 $this->$action($item); 00158 } 00159 } 00160 00161 return $this; 00162 } 00163 00164 return parent::__call($method, $args); 00165 } 00166 00173 protected function _isValid($value) 00174 { 00175 if (!$value instanceof stdClass) { 00176 return false; 00177 } 00178 00179 $vars = get_object_vars($value); 00180 $keys = array_keys($vars); 00181 $intersection = array_intersect($this->_itemKeys, $keys); 00182 if (empty($intersection)) { 00183 return false; 00184 } 00185 00186 return true; 00187 } 00188 00195 public function append($value) 00196 { 00197 if (!$this->_isValid($value)) { 00198 require_once 'Zend/View/Exception.php'; 00199 throw new Zend_View_Exception('append() expects a data token; please use one of the custom append*() methods'); 00200 } 00201 00202 return $this->getContainer()->append($value); 00203 } 00204 00212 public function offsetSet($index, $value) 00213 { 00214 if (!$this->_isValid($value)) { 00215 require_once 'Zend/View/Exception.php'; 00216 throw new Zend_View_Exception('offsetSet() expects a data token; please use one of the custom offsetSet*() methods'); 00217 } 00218 00219 return $this->getContainer()->offsetSet($index, $value); 00220 } 00221 00228 public function prepend($value) 00229 { 00230 if (!$this->_isValid($value)) { 00231 require_once 'Zend/View/Exception.php'; 00232 throw new Zend_View_Exception('prepend() expects a data token; please use one of the custom prepend*() methods'); 00233 } 00234 00235 return $this->getContainer()->prepend($value); 00236 } 00237 00244 public function set($value) 00245 { 00246 if (!$this->_isValid($value)) { 00247 require_once 'Zend/View/Exception.php'; 00248 throw new Zend_View_Exception('set() expects a data token; please use one of the custom set*() methods'); 00249 } 00250 00251 return $this->getContainer()->set($value); 00252 } 00253 00254 00261 public function itemToString(stdClass $item) 00262 { 00263 $attributes = (array) $item; 00264 $link = '<link '; 00265 00266 foreach ($this->_itemKeys as $itemKey) { 00267 if (isset($attributes[$itemKey])) { 00268 if(is_array($attributes[$itemKey])) { 00269 foreach($attributes[$itemKey] as $key => $value) { 00270 $link .= sprintf('%s="%s" ', $key, ($this->_autoEscape) ? $this->_escape($value) : $value); 00271 } 00272 } else { 00273 $link .= sprintf('%s="%s" ', $itemKey, ($this->_autoEscape) ? $this->_escape($attributes[$itemKey]) : $attributes[$itemKey]); 00274 } 00275 } 00276 } 00277 00278 if ($this->view instanceof Zend_View_Abstract) { 00279 $link .= ($this->view->doctype()->isXhtml()) ? '/>' : '>'; 00280 } else { 00281 $link .= '/>'; 00282 } 00283 00284 if (($link == '<link />') || ($link == '<link >')) { 00285 return ''; 00286 } 00287 00288 if (isset($attributes['conditionalStylesheet']) 00289 && !empty($attributes['conditionalStylesheet']) 00290 && is_string($attributes['conditionalStylesheet'])) 00291 { 00292 $link = '<!--[if ' . $attributes['conditionalStylesheet'] . ']> ' . $link . '<![endif]-->'; 00293 } 00294 00295 return $link; 00296 } 00297 00304 public function toString($indent = null) 00305 { 00306 $indent = (null !== $indent) 00307 ? $this->getWhitespace($indent) 00308 : $this->getIndent(); 00309 00310 $items = array(); 00311 $this->getContainer()->ksort(); 00312 foreach ($this as $item) { 00313 $items[] = $this->itemToString($item); 00314 } 00315 00316 return $indent . implode($this->_escape($this->getSeparator()) . $indent, $items); 00317 } 00318 00325 public function createData(array $attributes) 00326 { 00327 $data = (object) $attributes; 00328 return $data; 00329 } 00330 00337 public function createDataStylesheet(array $args) 00338 { 00339 $rel = 'stylesheet'; 00340 $type = 'text/css'; 00341 $media = 'screen'; 00342 $conditionalStylesheet = false; 00343 $href = array_shift($args); 00344 00345 if ($this->_isDuplicateStylesheet($href)) { 00346 return false; 00347 } 00348 00349 if (0 < count($args)) { 00350 $media = array_shift($args); 00351 if(is_array($media)) { 00352 $media = implode(',', $media); 00353 } else { 00354 $media = (string) $media; 00355 } 00356 } 00357 if (0 < count($args)) { 00358 $conditionalStylesheet = array_shift($args); 00359 if(!empty($conditionalStylesheet) && is_string($conditionalStylesheet)) { 00360 $conditionalStylesheet = (string) $conditionalStylesheet; 00361 } else { 00362 $conditionalStylesheet = null; 00363 } 00364 } 00365 00366 if(0 < count($args) && is_array($args[0])) { 00367 $extras = array_shift($args); 00368 $extras = (array) $extras; 00369 } 00370 00371 $attributes = compact('rel', 'type', 'href', 'media', 'conditionalStylesheet', 'extras'); 00372 return $this->createData($attributes); 00373 } 00374 00381 protected function _isDuplicateStylesheet($uri) 00382 { 00383 foreach ($this->getContainer() as $item) { 00384 if (($item->rel == 'stylesheet') && ($item->href == $uri)) { 00385 return true; 00386 } 00387 } 00388 return false; 00389 } 00390 00397 public function createDataAlternate(array $args) 00398 { 00399 if (3 > count($args)) { 00400 require_once 'Zend/View/Exception.php'; 00401 throw new Zend_View_Exception(sprintf('Alternate tags require 3 arguments; %s provided', count($args))); 00402 } 00403 00404 $rel = 'alternate'; 00405 $href = array_shift($args); 00406 $type = array_shift($args); 00407 $title = array_shift($args); 00408 00409 if(0 < count($args) && is_array($args[0])) { 00410 $extras = array_shift($args); 00411 $extras = (array) $extras; 00412 00413 if(isset($extras['media']) && is_array($extras['media'])) { 00414 $extras['media'] = implode(',', $extras['media']); 00415 } 00416 } 00417 00418 $href = (string) $href; 00419 $type = (string) $type; 00420 $title = (string) $title; 00421 00422 $attributes = compact('rel', 'href', 'type', 'title', 'extras'); 00423 return $this->createData($attributes); 00424 } 00425 }