PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/app/code/core/Mage/Page/Block/Html/Head.php

https://bitbucket.org/claudiu_marginean/magento-hg-mirror
PHP | 515 lines | 264 code | 36 blank | 215 comment | 31 complexity | 5bdecd9517b68f4279e335ea33e11922 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-2.1, GPL-2.0, WTFPL
  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  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@magentocommerce.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magentocommerce.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Page
  23. * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * Html page block
  28. *
  29. * @category Mage
  30. * @package Mage_Page
  31. * @author Magento Core Team <core@magentocommerce.com>
  32. */
  33. class Mage_Page_Block_Html_Head extends Mage_Core_Block_Template
  34. {
  35. /**
  36. * Initialize template
  37. *
  38. */
  39. protected function _construct()
  40. {
  41. $this->setTemplate('page/html/head.phtml');
  42. }
  43. /**
  44. * Add CSS file to HEAD entity
  45. *
  46. * @param string $name
  47. * @param string $params
  48. * @return Mage_Page_Block_Html_Head
  49. */
  50. public function addCss($name, $params = "")
  51. {
  52. $this->addItem('skin_css', $name, $params);
  53. return $this;
  54. }
  55. /**
  56. * Add JavaScript file to HEAD entity
  57. *
  58. * @param string $name
  59. * @param string $params
  60. * @return Mage_Page_Block_Html_Head
  61. */
  62. public function addJs($name, $params = "")
  63. {
  64. $this->addItem('js', $name, $params);
  65. return $this;
  66. }
  67. /**
  68. * Add CSS file for Internet Explorer only to HEAD entity
  69. *
  70. * @param string $name
  71. * @param string $params
  72. * @return Mage_Page_Block_Html_Head
  73. */
  74. public function addCssIe($name, $params = "")
  75. {
  76. $this->addItem('skin_css', $name, $params, 'IE');
  77. return $this;
  78. }
  79. /**
  80. * Add JavaScript file for Internet Explorer only to HEAD entity
  81. *
  82. * @param string $name
  83. * @param string $params
  84. * @return Mage_Page_Block_Html_Head
  85. */
  86. public function addJsIe($name, $params = "")
  87. {
  88. $this->addItem('js', $name, $params, 'IE');
  89. return $this;
  90. }
  91. /**
  92. * Add Link element to HEAD entity
  93. *
  94. * @param string $rel forward link types
  95. * @param string $href URI for linked resource
  96. * @return Mage_Page_Block_Html_Head
  97. */
  98. public function addLinkRel($rel, $href)
  99. {
  100. $this->addItem('link_rel', $href, 'rel="' . $rel . '"');
  101. return $this;
  102. }
  103. /**
  104. * Add HEAD Item
  105. *
  106. * Allowed types:
  107. * - js
  108. * - js_css
  109. * - skin_js
  110. * - skin_css
  111. * - rss
  112. *
  113. * @param string $type
  114. * @param string $name
  115. * @param string $params
  116. * @param string $if
  117. * @param string $cond
  118. * @return Mage_Page_Block_Html_Head
  119. */
  120. public function addItem($type, $name, $params=null, $if=null, $cond=null)
  121. {
  122. if ($type==='skin_css' && empty($params)) {
  123. $params = 'media="all"';
  124. }
  125. $this->_data['items'][$type.'/'.$name] = array(
  126. 'type' => $type,
  127. 'name' => $name,
  128. 'params' => $params,
  129. 'if' => $if,
  130. 'cond' => $cond,
  131. );
  132. return $this;
  133. }
  134. /**
  135. * Remove Item from HEAD entity
  136. *
  137. * @param string $type
  138. * @param string $name
  139. * @return Mage_Page_Block_Html_Head
  140. */
  141. public function removeItem($type, $name)
  142. {
  143. unset($this->_data['items'][$type.'/'.$name]);
  144. return $this;
  145. }
  146. /**
  147. * Get HEAD HTML with CSS/JS/RSS definitions
  148. * (actually it also renders other elements, TODO: fix it up or rename this method)
  149. *
  150. * @return string
  151. */
  152. public function getCssJsHtml()
  153. {
  154. // separate items by types
  155. $lines = array();
  156. foreach ($this->_data['items'] as $item) {
  157. if (!is_null($item['cond']) && !$this->getData($item['cond']) || !isset($item['name'])) {
  158. continue;
  159. }
  160. $if = !empty($item['if']) ? $item['if'] : '';
  161. $params = !empty($item['params']) ? $item['params'] : '';
  162. switch ($item['type']) {
  163. case 'js': // js/*.js
  164. case 'skin_js': // skin/*/*.js
  165. case 'js_css': // js/*.css
  166. case 'skin_css': // skin/*/*.css
  167. $lines[$if][$item['type']][$params][$item['name']] = $item['name'];
  168. break;
  169. default:
  170. $this->_separateOtherHtmlHeadElements($lines, $if, $item['type'], $params, $item['name'], $item);
  171. break;
  172. }
  173. }
  174. // prepare HTML
  175. $shouldMergeJs = Mage::getStoreConfigFlag('dev/js/merge_files');
  176. $shouldMergeCss = Mage::getStoreConfigFlag('dev/css/merge_css_files');
  177. $html = '';
  178. foreach ($lines as $if => $items) {
  179. if (empty($items)) {
  180. continue;
  181. }
  182. if (!empty($if)) {
  183. $html .= '<!--[if '.$if.']>'."\n";
  184. }
  185. // static and skin css
  186. $html .= $this->_prepareStaticAndSkinElements('<link rel="stylesheet" type="text/css" href="%s"%s />' . "\n",
  187. empty($items['js_css']) ? array() : $items['js_css'],
  188. empty($items['skin_css']) ? array() : $items['skin_css'],
  189. $shouldMergeCss ? array(Mage::getDesign(), 'getMergedCssUrl') : null
  190. );
  191. // static and skin javascripts
  192. $html .= $this->_prepareStaticAndSkinElements('<script type="text/javascript" src="%s"%s></script>' . "\n",
  193. empty($items['js']) ? array() : $items['js'],
  194. empty($items['skin_js']) ? array() : $items['skin_js'],
  195. $shouldMergeJs ? array(Mage::getDesign(), 'getMergedJsUrl') : null
  196. );
  197. // other stuff
  198. if (!empty($items['other'])) {
  199. $html .= $this->_prepareOtherHtmlHeadElements($items['other']) . "\n";
  200. }
  201. if (!empty($if)) {
  202. $html .= '<![endif]-->'."\n";
  203. }
  204. }
  205. return $html;
  206. }
  207. /**
  208. * Merge static and skin files of the same format into 1 set of HEAD directives or even into 1 directive
  209. *
  210. * Will attempt to merge into 1 directive, if merging callback is provided. In this case it will generate
  211. * filenames, rather than render urls.
  212. * The merger callback is responsible for checking whether files exist, merging them and giving result URL
  213. *
  214. * @param string $format - HTML element format for sprintf('<element src="%s"%s />', $src, $params)
  215. * @param array $staticItems - array of relative names of static items to be grabbed from js/ folder
  216. * @param array $skinItems - array of relative names of skin items to be found in skins according to design config
  217. * @param callback $mergeCallback
  218. * @return string
  219. */
  220. protected function &_prepareStaticAndSkinElements($format, array $staticItems, array $skinItems, $mergeCallback = null)
  221. {
  222. $designPackage = Mage::getDesign();
  223. $baseJsUrl = Mage::getBaseUrl('js');
  224. $items = array();
  225. if ($mergeCallback && !is_callable($mergeCallback)) {
  226. $mergeCallback = null;
  227. }
  228. // get static files from the js folder, no need in lookups
  229. foreach ($staticItems as $params => $rows) {
  230. foreach ($rows as $name) {
  231. $items[$params][] = $mergeCallback ? Mage::getBaseDir() . DS . 'js' . DS . $name : $baseJsUrl . $name;
  232. }
  233. }
  234. // lookup each file basing on current theme configuration
  235. foreach ($skinItems as $params => $rows) {
  236. foreach ($rows as $name) {
  237. $items[$params][] = $mergeCallback ? $designPackage->getFilename($name, array('_type' => 'skin'))
  238. : $designPackage->getSkinUrl($name, array());
  239. }
  240. }
  241. $html = '';
  242. foreach ($items as $params => $rows) {
  243. // attempt to merge
  244. $mergedUrl = false;
  245. if ($mergeCallback) {
  246. $mergedUrl = call_user_func($mergeCallback, $rows);
  247. }
  248. // render elements
  249. $params = trim($params);
  250. $params = $params ? ' ' . $params : '';
  251. if ($mergedUrl) {
  252. $html .= sprintf($format, $mergedUrl, $params);
  253. } else {
  254. foreach ($rows as $src) {
  255. $html .= sprintf($format, $src, $params);
  256. }
  257. }
  258. }
  259. return $html;
  260. }
  261. /**
  262. * Classify HTML head item and queue it into "lines" array
  263. *
  264. * @see self::getCssJsHtml()
  265. * @param array &$lines
  266. * @param string $itemIf
  267. * @param string $itemType
  268. * @param string $itemParams
  269. * @param string $itemName
  270. * @param array $itemThe
  271. */
  272. protected function _separateOtherHtmlHeadElements(&$lines, $itemIf, $itemType, $itemParams, $itemName, $itemThe)
  273. {
  274. $params = $itemParams ? ' ' . $itemParams : '';
  275. $href = $itemName;
  276. switch ($itemType) {
  277. case 'rss':
  278. $lines[$itemIf]['other'][] = sprintf('<link href="%s"%s rel="alternate" type="application/rss+xml" />',
  279. $href, $params
  280. );
  281. break;
  282. case 'link_rel':
  283. $lines[$itemIf]['other'][] = sprintf('<link%s href="%s" />', $params, $href);
  284. break;
  285. }
  286. }
  287. /**
  288. * Render arbitrary HTML head items
  289. *
  290. * @see self::getCssJsHtml()
  291. * @param array $items
  292. * @return string
  293. */
  294. protected function _prepareOtherHtmlHeadElements($items)
  295. {
  296. return implode("\n", $items);
  297. }
  298. /**
  299. * Retrieve Chunked Items
  300. *
  301. * @param array $items
  302. * @param string $prefix
  303. * @param int $maxLen
  304. * @return array
  305. */
  306. public function getChunkedItems($items, $prefix = '', $maxLen = 450)
  307. {
  308. $chunks = array();
  309. $chunk = $prefix;
  310. foreach ($items as $item) {
  311. if (strlen($chunk.','.$item)>$maxLen) {
  312. $chunks[] = $chunk;
  313. $chunk = $prefix;
  314. }
  315. $chunk .= ','.$item;
  316. }
  317. $chunks[] = $chunk;
  318. return $chunks;
  319. }
  320. /**
  321. * Retrieve Content Type
  322. *
  323. * @return string
  324. */
  325. public function getContentType()
  326. {
  327. if (empty($this->_data['content_type'])) {
  328. $this->_data['content_type'] = $this->getMediaType().'; charset='.$this->getCharset();
  329. }
  330. return $this->_data['content_type'];
  331. }
  332. /**
  333. * Retrieve Media Type
  334. *
  335. * @return string
  336. */
  337. public function getMediaType()
  338. {
  339. if (empty($this->_data['media_type'])) {
  340. $this->_data['media_type'] = Mage::getStoreConfig('design/head/default_media_type');
  341. }
  342. return $this->_data['media_type'];
  343. }
  344. /**
  345. * Retrieve Charset
  346. *
  347. * @return string
  348. */
  349. public function getCharset()
  350. {
  351. if (empty($this->_data['charset'])) {
  352. $this->_data['charset'] = Mage::getStoreConfig('design/head/default_charset');
  353. }
  354. return $this->_data['charset'];
  355. }
  356. /**
  357. * Set title element text
  358. *
  359. * @param string $title
  360. * @return Mage_Page_Block_Html_Head
  361. */
  362. public function setTitle($title)
  363. {
  364. $this->_data['title'] = Mage::getStoreConfig('design/head/title_prefix') . ' ' . $title
  365. . ' ' . Mage::getStoreConfig('design/head/title_suffix');
  366. return $this;
  367. }
  368. /**
  369. * Retrieve title element text (encoded)
  370. *
  371. * @return string
  372. */
  373. public function getTitle()
  374. {
  375. if (empty($this->_data['title'])) {
  376. $this->_data['title'] = $this->getDefaultTitle();
  377. }
  378. return htmlspecialchars(html_entity_decode(trim($this->_data['title']), ENT_QUOTES, 'UTF-8'));
  379. }
  380. /**
  381. * Retrieve default title text
  382. *
  383. * @return string
  384. */
  385. public function getDefaultTitle()
  386. {
  387. return Mage::getStoreConfig('design/head/default_title');
  388. }
  389. /**
  390. * Retrieve content for description tag
  391. *
  392. * @return string
  393. */
  394. public function getDescription()
  395. {
  396. if (empty($this->_data['description'])) {
  397. $this->_data['description'] = Mage::getStoreConfig('design/head/default_description');
  398. }
  399. return $this->_data['description'];
  400. }
  401. /**
  402. * Retrieve content for keyvords tag
  403. *
  404. * @return string
  405. */
  406. public function getKeywords()
  407. {
  408. if (empty($this->_data['keywords'])) {
  409. $this->_data['keywords'] = Mage::getStoreConfig('design/head/default_keywords');
  410. }
  411. return $this->_data['keywords'];
  412. }
  413. /**
  414. * Retrieve URL to robots file
  415. *
  416. * @return string
  417. */
  418. public function getRobots()
  419. {
  420. if (empty($this->_data['robots'])) {
  421. $this->_data['robots'] = Mage::getStoreConfig('design/head/default_robots');
  422. }
  423. return $this->_data['robots'];
  424. }
  425. /**
  426. * Get miscellanious scripts/styles to be included in head before head closing tag
  427. *
  428. * @return string
  429. */
  430. public function getIncludes()
  431. {
  432. if (empty($this->_data['includes'])) {
  433. $this->_data['includes'] = Mage::getStoreConfig('design/head/includes');
  434. }
  435. return $this->_data['includes'];
  436. }
  437. /**
  438. * Getter for path to Favicon
  439. *
  440. * @return string
  441. */
  442. public function getFaviconFile()
  443. {
  444. if (empty($this->_data['favicon_file'])) {
  445. $this->_data['favicon_file'] = $this->_getFaviconFile();
  446. }
  447. return $this->_data['favicon_file'];
  448. }
  449. /**
  450. * Retrieve path to Favicon
  451. *
  452. * @return string
  453. */
  454. protected function _getFaviconFile()
  455. {
  456. $folderName = Mage_Adminhtml_Model_System_Config_Backend_Image_Favicon::UPLOAD_DIR;
  457. $storeConfig = Mage::getStoreConfig('design/head/shortcut_icon');
  458. $faviconFile = Mage::getBaseUrl('media') . $folderName . '/' . $storeConfig;
  459. $absolutePath = Mage::getBaseDir('media') . '/' . $folderName . '/' . $storeConfig;
  460. if(!is_null($storeConfig) && $this->_isFile($absolutePath)) {
  461. $url = $faviconFile;
  462. } else {
  463. $url = $this->getSkinUrl('favicon.ico');
  464. }
  465. return $url;
  466. }
  467. /**
  468. * If DB file storage is on - find there, otherwise - just file_exists
  469. *
  470. * @param string $filename
  471. * @return bool
  472. */
  473. protected function _isFile($filename) {
  474. if (Mage::helper('core/file_storage_database')->checkDbUsage() && !is_file($filename)) {
  475. Mage::helper('core/file_storage_database')->saveFileToFilesystem($filename);
  476. }
  477. return is_file($filename);
  478. }
  479. }