PageRenderTime 26ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Zend/View/Helper/HeadLink.php

https://bitbucket.org/Ebozavrik/test-application
PHP | 487 lines | 259 code | 53 blank | 175 comment | 52 complexity | 13f8b9a16a2408fbb62c107bd94ca633 MD5 | raw file
  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-2012 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @version $Id: HeadLink.php 24858 2012-06-01 01:24:17Z adamlundrigan $
  20. * @license http://framework.zend.com/license/new-bsd New BSD License
  21. */
  22. /** Zend_View_Helper_Placeholder_Container_Standalone */
  23. require_once 'Zend/View/Helper/Placeholder/Container/Standalone.php';
  24. /**
  25. * Zend_Layout_View_Helper_HeadLink
  26. *
  27. * @see http://www.w3.org/TR/xhtml1/dtds.html
  28. * @uses Zend_View_Helper_Placeholder_Container_Standalone
  29. * @package Zend_View
  30. * @subpackage Helper
  31. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  32. * @license http://framework.zend.com/license/new-bsd New BSD License
  33. */
  34. class Zend_View_Helper_HeadLink extends Zend_View_Helper_Placeholder_Container_Standalone
  35. {
  36. /**
  37. * $_validAttributes
  38. *
  39. * @var array
  40. */
  41. protected $_itemKeys = array(
  42. 'charset',
  43. 'href',
  44. 'hreflang',
  45. 'id',
  46. 'media',
  47. 'rel',
  48. 'rev',
  49. 'type',
  50. 'title',
  51. 'extras',
  52. 'sizes',
  53. );
  54. /**
  55. * @var string registry key
  56. */
  57. protected $_regKey = 'Zend_View_Helper_HeadLink';
  58. /**
  59. * Constructor
  60. *
  61. * Use PHP_EOL as separator
  62. *
  63. * @return void
  64. */
  65. public function __construct ()
  66. {
  67. parent::__construct();
  68. $this->setSeparator(PHP_EOL);
  69. }
  70. /**
  71. * headLink() - View Helper Method
  72. *
  73. * Returns current object instance. Optionally, allows passing array of
  74. * values to build link.
  75. *
  76. * @return Zend_View_Helper_HeadLink
  77. */
  78. public function headLink (array $attributes = null, $placement = Zend_View_Helper_Placeholder_Container_Abstract::APPEND)
  79. {
  80. if (null !== $attributes) {
  81. $item = $this->createData($attributes);
  82. switch ($placement) {
  83. case Zend_View_Helper_Placeholder_Container_Abstract::SET:
  84. $this->set($item);
  85. break;
  86. case Zend_View_Helper_Placeholder_Container_Abstract::PREPEND:
  87. $this->prepend($item);
  88. break;
  89. case Zend_View_Helper_Placeholder_Container_Abstract::APPEND:
  90. default:
  91. $this->append($item);
  92. break;
  93. }
  94. }
  95. return $this;
  96. }
  97. /**
  98. * Overload method access
  99. *
  100. * Creates the following virtual methods:
  101. * - appendStylesheet($href, $media, $conditionalStylesheet, $extras)
  102. * - offsetSetStylesheet($index, $href, $media, $conditionalStylesheet, $extras)
  103. * - prependStylesheet($href, $media, $conditionalStylesheet, $extras)
  104. * - setStylesheet($href, $media, $conditionalStylesheet, $extras)
  105. * - appendAlternate($href, $type, $title, $extras)
  106. * - offsetSetAlternate($index, $href, $type, $title, $extras)
  107. * - prependAlternate($href, $type, $title, $extras)
  108. * - setAlternate($href, $type, $title, $extras)
  109. *
  110. * Items that may be added in the future:
  111. * - Navigation? need to find docs on this
  112. * - public function appendStart()
  113. * - public function appendContents()
  114. * - public function appendPrev()
  115. * - public function appendNext()
  116. * - public function appendIndex()
  117. * - public function appendEnd()
  118. * - public function appendGlossary()
  119. * - public function appendAppendix()
  120. * - public function appendHelp()
  121. * - public function appendBookmark()
  122. * - Other?
  123. * - public function appendCopyright()
  124. * - public function appendChapter()
  125. * - public function appendSection()
  126. * - public function appendSubsection()
  127. *
  128. * @param mixed $method
  129. * @param mixed $args
  130. *
  131. * @return void
  132. */
  133. public function __call ($method, $args)
  134. {
  135. if (preg_match('/^(?P<action>set|(ap|pre)pend|offsetSet)(?P<type>Stylesheet|Alternate)$/', $method, $matches)) {
  136. $argc = count($args);
  137. $action = $matches['action'];
  138. $type = $matches['type'];
  139. $index = null;
  140. if ('offsetSet' == $action) {
  141. if (0 < $argc) {
  142. $index = array_shift($args);
  143. --$argc;
  144. }
  145. }
  146. if (1 > $argc) {
  147. require_once 'Zend/View/Exception.php';
  148. $e = new Zend_View_Exception( sprintf('%s requires at least one argument', $method) );
  149. $e->setView($this->view);
  150. throw $e;
  151. }
  152. if (is_array($args[0])) {
  153. $item = $this->createData($args[0]);
  154. } else {
  155. $dataMethod = 'createData' . $type;
  156. $item = $this->$dataMethod($args);
  157. }
  158. if ($item) {
  159. if ('offsetSet' == $action) {
  160. $this->offsetSet($index, $item);
  161. } else {
  162. $this->$action($item);
  163. }
  164. }
  165. return $this;
  166. }
  167. return parent::__call($method, $args);
  168. }
  169. /**
  170. * Check if value is valid
  171. *
  172. * @param mixed $value
  173. *
  174. * @return boolean
  175. */
  176. protected function _isValid ($value)
  177. {
  178. if (!$value instanceof stdClass) {
  179. return false;
  180. }
  181. $vars = get_object_vars($value);
  182. $keys = array_keys($vars);
  183. $intersection = array_intersect($this->_itemKeys, $keys);
  184. if (empty( $intersection )) {
  185. return false;
  186. }
  187. return true;
  188. }
  189. /**
  190. * append()
  191. *
  192. * @param array $value
  193. *
  194. * @return void
  195. */
  196. public function append ($value)
  197. {
  198. if (!$this->_isValid($value)) {
  199. require_once 'Zend/View/Exception.php';
  200. $e = new Zend_View_Exception( 'append() expects a data token; please use one of the custom append*() methods' );
  201. $e->setView($this->view);
  202. throw $e;
  203. }
  204. return $this->getContainer()->append($value);
  205. }
  206. /**
  207. * offsetSet()
  208. *
  209. * @param string|int $index
  210. * @param array $value
  211. *
  212. * @return void
  213. */
  214. public function offsetSet ($index, $value)
  215. {
  216. if (!$this->_isValid($value)) {
  217. require_once 'Zend/View/Exception.php';
  218. $e = new Zend_View_Exception( 'offsetSet() expects a data token; please use one of the custom offsetSet*() methods' );
  219. $e->setView($this->view);
  220. throw $e;
  221. }
  222. return $this->getContainer()->offsetSet($index, $value);
  223. }
  224. /**
  225. * prepend()
  226. *
  227. * @param array $value
  228. *
  229. * @return Zend_Layout_ViewHelper_HeadLink
  230. */
  231. public function prepend ($value)
  232. {
  233. if (!$this->_isValid($value)) {
  234. require_once 'Zend/View/Exception.php';
  235. $e = new Zend_View_Exception( 'prepend() expects a data token; please use one of the custom prepend*() methods' );
  236. $e->setView($this->view);
  237. throw $e;
  238. }
  239. return $this->getContainer()->prepend($value);
  240. }
  241. /**
  242. * set()
  243. *
  244. * @param array $value
  245. *
  246. * @return Zend_Layout_ViewHelper_HeadLink
  247. */
  248. public function set ($value)
  249. {
  250. if (!$this->_isValid($value)) {
  251. require_once 'Zend/View/Exception.php';
  252. $e = new Zend_View_Exception( 'set() expects a data token; please use one of the custom set*() methods' );
  253. $e->setView($this->view);
  254. throw $e;
  255. }
  256. return $this->getContainer()->set($value);
  257. }
  258. /**
  259. * Create HTML link element from data item
  260. *
  261. * @param stdClass $item
  262. *
  263. * @return string
  264. */
  265. public function itemToString (stdClass $item)
  266. {
  267. $attributes = (array)$item;
  268. $link = '<link ';
  269. foreach ($this->_itemKeys as $itemKey) {
  270. if (isset( $attributes[$itemKey] )) {
  271. if (is_array($attributes[$itemKey])) {
  272. foreach ($attributes[$itemKey] as $key => $value) {
  273. $link .= sprintf('%s="%s" ', $key, ( $this->_autoEscape ) ? $this->_escape($value) : $value);
  274. }
  275. } else {
  276. $link .= sprintf('%s="%s" ', $itemKey, ( $this->_autoEscape ) ? $this->_escape($attributes[$itemKey]) : $attributes[$itemKey]);
  277. }
  278. }
  279. }
  280. if ($this->view instanceof Zend_View_Abstract) {
  281. $link .= ( $this->view->doctype()->isXhtml() ) ? '/>' : '>';
  282. } else {
  283. $link .= '/>';
  284. }
  285. if (( $link == '<link />' ) || ( $link == '<link >' )) {
  286. return '';
  287. }
  288. if (isset( $attributes['conditionalStylesheet'] )
  289. && !empty( $attributes['conditionalStylesheet'] )
  290. && is_string($attributes['conditionalStylesheet'])
  291. ) {
  292. $link = '<!--[if ' . $attributes['conditionalStylesheet'] . ']> ' . $link . '<![endif]-->';
  293. }
  294. return $link;
  295. }
  296. /**
  297. * Render link elements as string
  298. *
  299. * @param string|int $indent
  300. *
  301. * @return string
  302. */
  303. public function toString ($indent = null)
  304. {
  305. $indent = ( null !== $indent )
  306. ? $this->getWhitespace($indent)
  307. : $this->getIndent();
  308. $items = array();
  309. $this->getContainer()->ksort();
  310. foreach ($this as $item) {
  311. $items[] = $this->itemToString($item);
  312. }
  313. return $indent . implode($this->_escape($this->getSeparator()) . $indent, $items);
  314. }
  315. /**
  316. * Create data item for stack
  317. *
  318. * @param array $attributes
  319. *
  320. * @return stdClass
  321. */
  322. public function createData (array $attributes)
  323. {
  324. $data = (object)$attributes;
  325. return $data;
  326. }
  327. /**
  328. * Create item for stylesheet link item
  329. *
  330. * @param array $args
  331. *
  332. * @return stdClass|false Returns fals if stylesheet is a duplicate
  333. */
  334. public function createDataStylesheet (array $args)
  335. {
  336. $rel = 'stylesheet';
  337. $type = 'text/css';
  338. $media = 'screen';
  339. $conditionalStylesheet = false;
  340. $href = array_shift($args);
  341. if ($this->_isDuplicateStylesheet($href)) {
  342. return false;
  343. }
  344. if (0 < count($args)) {
  345. $media = array_shift($args);
  346. if (is_array($media)) {
  347. $media = implode(',', $media);
  348. } else {
  349. $media = (string)$media;
  350. }
  351. }
  352. if (0 < count($args)) {
  353. $conditionalStylesheet = array_shift($args);
  354. if (!empty( $conditionalStylesheet ) && is_string($conditionalStylesheet)) {
  355. $conditionalStylesheet = (string)$conditionalStylesheet;
  356. } else {
  357. $conditionalStylesheet = null;
  358. }
  359. }
  360. if (0 < count($args) && is_array($args[0])) {
  361. $extras = array_shift($args);
  362. $extras = (array)$extras;
  363. }
  364. $attributes = compact('rel', 'type', 'href', 'media', 'conditionalStylesheet', 'extras');
  365. return $this->createData($this->_applyExtras($attributes));
  366. }
  367. /**
  368. * Is the linked stylesheet a duplicate?
  369. *
  370. * @param string $uri
  371. *
  372. * @return bool
  373. */
  374. protected function _isDuplicateStylesheet ($uri)
  375. {
  376. foreach ($this->getContainer() as $item) {
  377. if (( $item->rel == 'stylesheet' ) && ( $item->href == $uri )) {
  378. return true;
  379. }
  380. }
  381. return false;
  382. }
  383. /**
  384. * Create item for alternate link item
  385. *
  386. * @param array $args
  387. *
  388. * @return stdClass
  389. */
  390. public function createDataAlternate (array $args)
  391. {
  392. if (3 > count($args)) {
  393. require_once 'Zend/View/Exception.php';
  394. $e = new Zend_View_Exception( sprintf('Alternate tags require 3 arguments; %s provided', count($args)) );
  395. $e->setView($this->view);
  396. throw $e;
  397. }
  398. $rel = 'alternate';
  399. $href = array_shift($args);
  400. $type = array_shift($args);
  401. $title = array_shift($args);
  402. if (0 < count($args) && is_array($args[0])) {
  403. $extras = array_shift($args);
  404. $extras = (array)$extras;
  405. if (isset( $extras['media'] ) && is_array($extras['media'])) {
  406. $extras['media'] = implode(',', $extras['media']);
  407. }
  408. }
  409. $href = (string)$href;
  410. $type = (string)$type;
  411. $title = (string)$title;
  412. $attributes = compact('rel', 'href', 'type', 'title', 'extras');
  413. return $this->createData($this->_applyExtras($attributes));
  414. }
  415. /**
  416. * Apply any overrides specified in the 'extras' array
  417. *
  418. * @param array $attributes
  419. *
  420. * @return array
  421. */
  422. protected function _applyExtras ($attributes)
  423. {
  424. if (isset( $attributes['extras'] )) {
  425. foreach ($attributes['extras'] as $eKey => $eVal) {
  426. if (isset( $attributes[$eKey] )) {
  427. $attributes[$eKey] = $eVal;
  428. unset( $attributes['extras'][$eKey] );
  429. }
  430. }
  431. }
  432. return $attributes;
  433. }
  434. }