PageRenderTime 53ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/DevApp/library/Zend/View/Helper/HeadScript.php

http://firephp.googlecode.com/
PHP | 471 lines | 244 code | 45 blank | 182 comment | 41 complexity | f4c3b6d93a6603d8f95be004a796e2de MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.0, MIT, Apache-2.0
  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. * @package Zend_View
  16. * @subpackage Helper
  17. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @version $Id: Placeholder.php 7078 2007-12-11 14:29:33Z matthew $
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. */
  21. /** Zend_View_Helper_Placeholder_Container_Standalone */
  22. require_once 'Zend/View/Helper/Placeholder/Container/Standalone.php';
  23. /**
  24. * Helper for setting and retrieving script elements for HTML head section
  25. *
  26. * @uses Zend_View_Helper_Placeholder_Container_Standalone
  27. * @package Zend_View
  28. * @subpackage Helper
  29. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  30. * @license http://framework.zend.com/license/new-bsd New BSD License
  31. */
  32. class Zend_View_Helper_HeadScript extends Zend_View_Helper_Placeholder_Container_Standalone
  33. {
  34. /**#@+
  35. * Script type contants
  36. * @const string
  37. */
  38. const FILE = 'FILE';
  39. const SCRIPT = 'SCRIPT';
  40. /**#@-*/
  41. /**
  42. * Registry key for placeholder
  43. * @var string
  44. */
  45. protected $_regKey = 'Zend_View_Helper_HeadScript';
  46. /**
  47. * Are arbitrary attributes allowed?
  48. * @var bool
  49. */
  50. protected $_arbitraryAttributes = false;
  51. /**#@+
  52. * Capture type and/or attributes (used for hinting during capture)
  53. * @var string
  54. */
  55. protected $_captureLock;
  56. protected $_captureScriptType = null;
  57. protected $_captureScriptAttrs = null;
  58. protected $_captureType;
  59. /**#@-*/
  60. /**
  61. * Optional allowed attributes for script tag
  62. * @var array
  63. */
  64. protected $_optionalAttributes = array(
  65. 'charset', 'defer', 'language', 'src'
  66. );
  67. /**
  68. * Required attributes for script tag
  69. * @var string
  70. */
  71. protected $_requiredAttributes = array('type');
  72. /**
  73. * Whether or not to format scripts using CDATA; used only if doctype
  74. * helper is not accessible
  75. * @var bool
  76. */
  77. public $useCdata = false;
  78. /**
  79. * Constructor
  80. *
  81. * Set separator to PHP_EOL.
  82. *
  83. * @return void
  84. */
  85. public function __construct()
  86. {
  87. parent::__construct();
  88. $this->setSeparator(PHP_EOL);
  89. }
  90. /**
  91. * Return headScript object
  92. *
  93. * Returns headScript helper object; optionally, allows specifying a script
  94. * or script file to include.
  95. *
  96. * @param string $mode Script or file
  97. * @param string $spec Script/url
  98. * @param string $placement Append, prepend, or set
  99. * @param array $attrs Array of script attributes
  100. * @param string $type Script type and/or array of script attributes
  101. * @return Zend_View_Helper_HeadScript
  102. */
  103. public function headScript($mode = Zend_View_Helper_HeadScript::FILE, $spec = null, $placement = 'APPEND', array $attrs = array(), $type = 'text/javascript')
  104. {
  105. if ((null !== $spec) && is_string($spec)) {
  106. $action = ucfirst(strtolower($mode));
  107. $placement = strtolower($placement);
  108. switch ($placement) {
  109. case 'set':
  110. case 'prepend':
  111. case 'append':
  112. $action = $placement . $action;
  113. break;
  114. default:
  115. $action = 'append' . $action;
  116. break;
  117. }
  118. $this->$action($spec, $type, $attrs);
  119. }
  120. return $this;
  121. }
  122. /**
  123. * Start capture action
  124. *
  125. * @param mixed $captureType
  126. * @param string $typeOrAttrs
  127. * @return void
  128. */
  129. public function captureStart($captureType = Zend_View_Helper_Placeholder_Container_Abstract::APPEND, $type = 'text/javascript', $attrs = array())
  130. {
  131. if ($this->_captureLock) {
  132. require_once 'Zend/View/Helper/Placeholder/Container/Exception.php';
  133. throw new Zend_View_Helper_Placeholder_Container_Exception('Cannot nest headScript captures');
  134. }
  135. $this->_captureLock = true;
  136. $this->_captureType = $captureType;
  137. $this->_captureScriptType = $type;
  138. $this->_captureScriptAttrs = $attrs;
  139. ob_start();
  140. }
  141. /**
  142. * End capture action and store
  143. *
  144. * @return void
  145. */
  146. public function captureEnd()
  147. {
  148. $content = ob_get_clean();
  149. $type = $this->_captureScriptType;
  150. $attrs = $this->_captureScriptAttrs;
  151. $this->_captureScriptType = null;
  152. $this->_captureScriptAttrs = null;
  153. $this->_captureLock = false;
  154. switch ($this->_captureType) {
  155. case Zend_View_Helper_Placeholder_Container_Abstract::SET:
  156. case Zend_View_Helper_Placeholder_Container_Abstract::PREPEND:
  157. case Zend_View_Helper_Placeholder_Container_Abstract::APPEND:
  158. $action = strtolower($this->_captureType) . 'Script';
  159. break;
  160. default:
  161. $action = 'appendScript';
  162. break;
  163. }
  164. $this->$action($content, $type, $attrs);
  165. }
  166. /**
  167. * Overload method access
  168. *
  169. * Allows the following method calls:
  170. * - appendFile($src, $type = 'text/javascript', $attrs = array())
  171. * - offsetSetFile($index, $src, $type = 'text/javascript', $attrs = array())
  172. * - prependFile($src, $type = 'text/javascript', $attrs = array())
  173. * - setFile($src, $type = 'text/javascript', $attrs = array())
  174. * - appendScript($script, $type = 'text/javascript', $attrs = array())
  175. * - offsetSetScript($index, $src, $type = 'text/javascript', $attrs = array())
  176. * - prependScript($script, $type = 'text/javascript', $attrs = array())
  177. * - setScript($script, $type = 'text/javascript', $attrs = array())
  178. *
  179. * @param string $method
  180. * @param array $args
  181. * @return Zend_View_Helper_HeadScript
  182. * @throws Zend_View_Exception if too few arguments or invalid method
  183. */
  184. public function __call($method, $args)
  185. {
  186. if (preg_match('/^(?P<action>set|(ap|pre)pend|offsetSet)(?P<mode>File|Script)$/', $method, $matches)) {
  187. if (1 > count($args)) {
  188. require_once 'Zend/View/Exception.php';
  189. throw new Zend_View_Exception(sprintf('Method "%s" requires at least one argument', $method));
  190. }
  191. $action = $matches['action'];
  192. $mode = strtolower($matches['mode']);
  193. $type = 'text/javascript';
  194. $attrs = array();
  195. if ('offsetSet' == $action) {
  196. $index = array_shift($args);
  197. if (1 > count($args)) {
  198. require_once 'Zend/View/Exception.php';
  199. throw new Zend_View_Exception(sprintf('Method "%s" requires at least two arguments, an index and source', $method));
  200. }
  201. }
  202. $content = $args[0];
  203. if (isset($args[1])) {
  204. $type = (string) $args[1];
  205. }
  206. if (isset($args[2])) {
  207. $attrs = (array) $args[2];
  208. }
  209. switch ($mode) {
  210. case 'script':
  211. $item = $this->createData($type, $attrs, $content);
  212. if ('offsetSet' == $action) {
  213. $this->offsetSet($index, $item);
  214. } else {
  215. $this->$action($item);
  216. }
  217. break;
  218. case 'file':
  219. default:
  220. if (!$this->_isDuplicate($content)) {
  221. $attrs['src'] = $content;
  222. $item = $this->createData($type, $attrs);
  223. if ('offsetSet' == $action) {
  224. $this->offsetSet($index, $item);
  225. } else {
  226. $this->$action($item);
  227. }
  228. }
  229. break;
  230. }
  231. return $this;
  232. }
  233. return parent::__call($method, $args);
  234. }
  235. /**
  236. * Is the file specified a duplicate?
  237. *
  238. * @param string $file
  239. * @return bool
  240. */
  241. protected function _isDuplicate($file)
  242. {
  243. foreach ($this->getContainer() as $item) {
  244. if (($item->source === null)
  245. && array_key_exists('src', $item->attributes)
  246. && ($file == $item->attributes['src']))
  247. {
  248. return true;
  249. }
  250. }
  251. return false;
  252. }
  253. /**
  254. * Is the script provided valid?
  255. *
  256. * @param mixed $value
  257. * @param string $method
  258. * @return bool
  259. */
  260. protected function _isValid($value)
  261. {
  262. if ((!$value instanceof stdClass)
  263. || !isset($value->type)
  264. || (!isset($value->source) && !isset($value->attributes)))
  265. {
  266. return false;
  267. }
  268. return true;
  269. }
  270. /**
  271. * Override append
  272. *
  273. * @param string $value
  274. * @return void
  275. */
  276. public function append($value)
  277. {
  278. if (!$this->_isValid($value)) {
  279. require_once 'Zend/View/Exception.php';
  280. throw new Zend_View_Exception('Invalid argument passed to append(); please use one of the helper methods, appendScript() or appendFile()');
  281. }
  282. return $this->getContainer()->append($value);
  283. }
  284. /**
  285. * Override prepend
  286. *
  287. * @param string $value
  288. * @return void
  289. */
  290. public function prepend($value)
  291. {
  292. if (!$this->_isValid($value)) {
  293. require_once 'Zend/View/Exception.php';
  294. throw new Zend_View_Exception('Invalid argument passed to prepend(); please use one of the helper methods, prependScript() or prependFile()');
  295. }
  296. return $this->getContainer()->prepend($value);
  297. }
  298. /**
  299. * Override set
  300. *
  301. * @param string $value
  302. * @return void
  303. */
  304. public function set($value)
  305. {
  306. if (!$this->_isValid($value)) {
  307. require_once 'Zend/View/Exception.php';
  308. throw new Zend_View_Exception('Invalid argument passed to set(); please use one of the helper methods, setScript() or setFile()');
  309. }
  310. return $this->getContainer()->set($value);
  311. }
  312. /**
  313. * Override offsetSet
  314. *
  315. * @param string|int $index
  316. * @param mixed $value
  317. * @return void
  318. */
  319. public function offsetSet($index, $value)
  320. {
  321. if (!$this->_isValid($value)) {
  322. require_once 'Zend/View/Exception.php';
  323. throw new Zend_View_Exception('Invalid argument passed to offsetSet(); please use one of the helper methods, offsetSetScript() or offsetSetFile()');
  324. }
  325. $this->_isValid($value);
  326. return $this->getContainer()->offsetSet($index, $value);
  327. }
  328. /**
  329. * Set flag indicating if arbitrary attributes are allowed
  330. *
  331. * @param bool $flag
  332. * @return Zend_View_Helper_HeadScript
  333. */
  334. public function setAllowArbitraryAttributes($flag)
  335. {
  336. $this->_arbitraryAttributes = (bool) $flag;
  337. return $this;
  338. }
  339. /**
  340. * Are arbitrary attributes allowed?
  341. *
  342. * @return bool
  343. */
  344. public function arbitraryAttributesAllowed()
  345. {
  346. return $this->_arbitraryAttributes;
  347. }
  348. /**
  349. * Create script HTML
  350. *
  351. * @param string $type
  352. * @param array $attributes
  353. * @param string $content
  354. * @param string|int $indent
  355. * @return string
  356. */
  357. public function itemToString($item, $indent, $escapeStart, $escapeEnd)
  358. {
  359. $attrString = '';
  360. if (!empty($item->attributes)) {
  361. foreach ($item->attributes as $key => $value) {
  362. if (!$this->arbitraryAttributesAllowed()
  363. && !in_array($key, $this->_optionalAttributes))
  364. {
  365. continue;
  366. }
  367. if ('defer' == $key) {
  368. $value = 'defer';
  369. }
  370. $attrString .= sprintf(' %s="%s"', $key, ($this->_autoEscape) ? $this->_escape($value) : $value);
  371. }
  372. }
  373. $type = ($this->_autoEscape) ? $this->_escape($item->type) : $item->type;
  374. $html = $indent . '<script type="' . $type . '"' . $attrString . '>';
  375. if (!empty($item->source)) {
  376. $html .= PHP_EOL . $indent . $escapeStart . PHP_EOL . $indent . $indent . $item->source . PHP_EOL . $indent . $escapeEnd . PHP_EOL . $indent;
  377. }
  378. $html .= '</script>';
  379. return $html;
  380. }
  381. /**
  382. * Retrieve string representation
  383. *
  384. * @param string|int $indent
  385. * @return string
  386. */
  387. public function toString($indent = null)
  388. {
  389. $indent = (null !== $indent)
  390. ? $this->getWhitespace($indent)
  391. : $this->getIndent();
  392. if ($this->view) {
  393. $useCdata = $this->view->doctype()->isXhtml() ? true : false;
  394. } else {
  395. $useCdata = $this->useCdata ? true : false;
  396. }
  397. $escapeStart = ($useCdata) ? '//<![CDATA[' : '//<!--';
  398. $escapeEnd = ($useCdata) ? '//]]>' : '//-->';
  399. $items = array();
  400. foreach ($this as $item) {
  401. if (!$this->_isValid($item)) {
  402. continue;
  403. }
  404. $items[] = $this->itemToString($item, $indent, $escapeStart, $escapeEnd);
  405. }
  406. $return = $indent . implode($this->getSeparator() . $indent, $items);
  407. $return = preg_replace("/(\r\n?|\n)/", '$1' . $indent, $return);
  408. return $return;
  409. }
  410. /**
  411. * Create data item containing all necessary components of script
  412. *
  413. * @param string $type
  414. * @param array $attributes
  415. * @param string $content
  416. * @return stdClass
  417. */
  418. public function createData($type, array $attributes, $content = null)
  419. {
  420. $data = new stdClass();
  421. $data->type = $type;
  422. $data->attributes = $attributes;
  423. $data->source = $content;
  424. return $data;
  425. }
  426. }