PageRenderTime 51ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/classes/Media.php

https://github.com/Broceliande/PrestaShop
PHP | 561 lines | 405 code | 57 blank | 99 comment | 56 complexity | aaf6bd0804e4b575a83818e0df6951ab MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. /*
  3. * 2007-2012 PrestaShop
  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@prestashop.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 PrestaShop to newer
  18. * versions in the future. If you wish to customize PrestaShop for your
  19. * needs please refer to http://www.prestashop.com for more information.
  20. *
  21. * @author PrestaShop SA <contact@prestashop.com>
  22. * @copyright 2007-2012 PrestaShop SA
  23. * @version Release: $Revision: 7521 $
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. * International Registered Trademark & Property of PrestaShop SA
  26. */
  27. class MediaCore
  28. {
  29. public static $jquery_ui_dependencies = array(
  30. 'ui.core' => array('fileName' => 'jquery.ui.core.min.js', 'dependencies' => array(), 'theme' => true),
  31. 'ui.widget' => array('fileName' => 'jquery.ui.widget.min.js', 'dependencies' => array(), 'theme' => false),
  32. 'ui.mouse' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('ui.core', 'ui.widget'), 'theme' => false),
  33. 'ui.position' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array(), 'theme' => false),
  34. 'ui.draggable' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('ui.core', 'ui.widget', 'ui.mouse'), 'theme' => false),
  35. 'ui.droppable' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('uicore', 'ui.widget', 'ui.mouse', 'ui.draggable'), 'theme' => false),
  36. 'ui.resizable' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('ui.core', 'ui.widget', 'ui.mouse'), 'theme' => true),
  37. 'ui.selectable' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('ui.core', 'ui.widget', 'ui.mouse'), 'theme' => true),
  38. 'ui.sortable' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('ui.core', 'ui.widget', 'ui.mouse'), 'theme' => true),
  39. 'ui.accordion' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('ui.core', 'ui.widget'), 'theme' => true),
  40. 'ui.autocomplete' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('ui.core', 'ui.widget', 'ui.position'), 'theme' => true),
  41. 'ui.button' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('ui.core', 'ui.widget'), 'theme' => true),
  42. 'ui.dialog' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('ui.core', 'ui.widget', 'ui.position'), 'theme' => true),
  43. 'ui.slider' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('ui.core', 'ui.widget', 'ui.mouse'), 'theme' => true),
  44. 'ui.tabs' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('ui.core', 'ui.widget'), 'theme' => true),
  45. 'ui.datepicker' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('ui.core'), 'theme' => true),
  46. 'ui.progressbar' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('ui.core', 'ui.widget'), 'theme' => true),
  47. 'effects.core' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array(), 'theme' => false),
  48. 'effects.blind' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('effects.core'), 'theme' => false),
  49. 'effects.bounce' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('effects.core'), 'theme' => false),
  50. 'effects.clip' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('effects.core'), 'theme' => false),
  51. 'effects.drop' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('effects.core'), 'theme' => false),
  52. 'effects.explode' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('effects.core'), 'theme' => false),
  53. 'effects.fade' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('effects.core'), 'theme' => false),
  54. 'effects.fold' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('effects.core'), 'theme' => false),
  55. 'effects.highlight' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('effects.core'), 'theme' => false),
  56. 'effects.pulsate' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('effects.core'), 'theme' => false),
  57. 'effects.scale' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('effects.core'), 'theme' => false),
  58. 'effects.shake' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('effects.core'), 'theme' => false),
  59. 'effects.slide' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('effects.core'), 'theme' => false),
  60. 'effects.transfer' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('effects.core'), 'theme' => false)
  61. );
  62. public static function minifyHTML($html_content)
  63. {
  64. if (strlen($html_content) > 0)
  65. {
  66. //set an alphabetical order for args
  67. $html_content = preg_replace_callback(
  68. '/(<[a-zA-Z0-9]+)((\s?[a-zA-Z0-9]+=[\"\\\'][^\"\\\']*[\"\\\']\s?)*)>/',
  69. array('Media', 'minifyHTMLpregCallback'),
  70. $html_content);
  71. require_once(_PS_TOOL_DIR_.'minify_html/minify_html.class.php');
  72. $html_content = str_replace(chr(194).chr(160), '&nbsp;', $html_content);
  73. $html_content = Minify_HTML::minify($html_content, array('xhtml', 'cssMinifier', 'jsMinifier'));
  74. if (Configuration::get('PS_HIGH_HTML_THEME_COMPRESSION'))
  75. {
  76. //$html_content = preg_replace('/"([^\>\s"]*)"/i', '$1', $html_content);//FIXME create a js bug
  77. $html_content = preg_replace('/<!DOCTYPE \w[^\>]*dtd\">/is', '', $html_content);
  78. $html_content = preg_replace('/\s\>/is', '>', $html_content);
  79. $html_content = str_replace('</li>', '', $html_content);
  80. $html_content = str_replace('</dt>', '', $html_content);
  81. $html_content = str_replace('</dd>', '', $html_content);
  82. $html_content = str_replace('</head>', '', $html_content);
  83. $html_content = str_replace('<head>', '', $html_content);
  84. $html_content = str_replace('</html>', '', $html_content);
  85. $html_content = str_replace('</body>', '', $html_content);
  86. //$html_content = str_replace('</p>', '', $html_content);//FIXME doesnt work...
  87. $html_content = str_replace("</option>\n", '', $html_content);//TODO with bellow
  88. $html_content = str_replace('</option>', '', $html_content);
  89. $html_content = str_replace('<script type=text/javascript>', '<script>', $html_content);//Do a better expreg
  90. $html_content = str_replace("<script>\n", '<script>', $html_content);//Do a better expreg
  91. }
  92. return $html_content;
  93. }
  94. return false;
  95. }
  96. public static function minifyHTMLpregCallback($preg_matches)
  97. {
  98. $args = array();
  99. preg_match_all('/[a-zA-Z0-9]+=[\"\\\'][^\"\\\']*[\"\\\']/is', $preg_matches[2], $args);
  100. $args = $args[0];
  101. sort($args);
  102. // if there is no args in the balise, we don't write a space (avoid previous : <title >, now : <title>)
  103. if (empty($args))
  104. $output = $preg_matches[1].'>';
  105. else
  106. $output = $preg_matches[1].' '.implode(' ', $args).'>';
  107. return $output;
  108. }
  109. public static function packJSinHTML($html_content)
  110. {
  111. if (strlen($html_content) > 0)
  112. {
  113. $html_content_copy = $html_content;
  114. $html_content = preg_replace_callback(
  115. '/\\s*(<script\\b[^>]*?>)([\\s\\S]*?)(<\\/script>)\\s*/i',
  116. array('Media', 'packJSinHTMLpregCallback'),
  117. $html_content);
  118. // If the string is too big preg_replace return an error
  119. // In this case, we don't compress the content
  120. if (preg_last_error() == PREG_BACKTRACK_LIMIT_ERROR)
  121. {
  122. error_log('ERROR: PREG_BACKTRACK_LIMIT_ERROR in function packJSinHTML');
  123. return $html_content_copy;
  124. }
  125. return $html_content;
  126. }
  127. return false;
  128. }
  129. public static function packJSinHTMLpregCallback($preg_matches)
  130. {
  131. $preg_matches[1] = $preg_matches[1].'/* <![CDATA[ */';
  132. $preg_matches[2] = Media::packJS($preg_matches[2]);
  133. $preg_matches[count($preg_matches) - 1] = '/* ]]> */'.$preg_matches[count($preg_matches) - 1];
  134. unset($preg_matches[0]);
  135. $output = implode('', $preg_matches);
  136. return $output;
  137. }
  138. public static function packJS($js_content)
  139. {
  140. if (strlen($js_content) > 0)
  141. {
  142. require_once(_PS_TOOL_DIR_.'js_minify/jsmin.php');
  143. return JSMin::minify($js_content);
  144. }
  145. return false;
  146. }
  147. public static function minifyCSS($css_content, $fileuri = false, &$import_url = array())
  148. {
  149. global $current_css_file;
  150. $current_css_file = $fileuri;
  151. if (strlen($css_content) > 0)
  152. {
  153. $css_content = preg_replace('#/\*.*?\*/#s', '', $css_content);
  154. $css_content = preg_replace_callback('#url\((?:\'|")?([^\)\'"]*)(?:\'|")?\)#s', array('Tools', 'replaceByAbsoluteURL'), $css_content);
  155. $css_content = preg_replace('#\s+#', ' ', $css_content);
  156. $css_content = str_replace("\t", '', $css_content);
  157. $css_content = str_replace("\n", '', $css_content);
  158. //$css_content = str_replace('}', "}\n", $css_content);
  159. $css_content = str_replace('; ', ';', $css_content);
  160. $css_content = str_replace(': ', ':', $css_content);
  161. $css_content = str_replace(' {', '{', $css_content);
  162. $css_content = str_replace('{ ', '{', $css_content);
  163. $css_content = str_replace(', ', ',', $css_content);
  164. $css_content = str_replace('} ', '}', $css_content);
  165. $css_content = str_replace(' }', '}', $css_content);
  166. $css_content = str_replace(';}', '}', $css_content);
  167. $css_content = str_replace(':0px', ':0', $css_content);
  168. $css_content = str_replace(' 0px', ' 0', $css_content);
  169. $css_content = str_replace(':0em', ':0', $css_content);
  170. $css_content = str_replace(' 0em', ' 0', $css_content);
  171. $css_content = str_replace(':0pt', ':0', $css_content);
  172. $css_content = str_replace(' 0pt', ' 0', $css_content);
  173. $css_content = str_replace(':0%', ':0', $css_content);
  174. $css_content = str_replace(' 0%', ' 0', $css_content);
  175. // Store all import url
  176. preg_match_all('#@import .*?;#i', $css_content, $m);
  177. for ($i = 0, $total = count($m[0]); $i < $total; $i++)
  178. {
  179. $import_url[] = $m[0][$i];
  180. $css_content = str_replace($m[0][$i], '', $css_content);
  181. }
  182. return trim($css_content);
  183. }
  184. return false;
  185. }
  186. /**
  187. * addJS return javascript path
  188. *
  189. * @param mixed $js_uri
  190. * @return string
  191. */
  192. public static function getJSPath($js_uri)
  193. {
  194. if (is_array($js_uri) || $js_uri === null || empty($js_uri))
  195. return false;
  196. $url_data = parse_url($js_uri);
  197. if (!array_key_exists('host', $url_data))
  198. $file_uri = _PS_ROOT_DIR_.Tools::str_replace_once(__PS_BASE_URI__, DIRECTORY_SEPARATOR, $url_data['path']); // remove PS_BASE_URI on _PS_ROOT_DIR_ for the following
  199. else
  200. $file_uri = $js_uri;
  201. // check if js files exists
  202. if (!preg_match('/^http(s?):\/\//i', $file_uri) && !@filemtime($file_uri))
  203. return false;
  204. if (Context::getContext()->controller->controller_type == 'admin')
  205. {
  206. $js_uri = preg_replace('/^'.preg_quote(__PS_BASE_URI__, '/').'/', '/', $js_uri);
  207. $js_uri = dirname(preg_replace('/\?.+$/', '', $_SERVER['REQUEST_URI']).'a').'/..'.$js_uri;
  208. }
  209. return $js_uri;
  210. }
  211. /**
  212. * addCSS return stylesheet path.
  213. *
  214. * @param mixed $css_uri
  215. * @param string $css_media_type
  216. * @return string
  217. */
  218. public static function getCSSPath($css_uri, $css_media_type = 'all')
  219. {
  220. if (empty($css_uri))
  221. return false;
  222. // remove PS_BASE_URI on _PS_ROOT_DIR_ for the following
  223. $url_data = parse_url($css_uri);
  224. $file_uri = _PS_ROOT_DIR_.Tools::str_replace_once(__PS_BASE_URI__, DIRECTORY_SEPARATOR, $url_data['path']);
  225. // check if css files exists
  226. if (!@filemtime($file_uri))
  227. return false;
  228. if (Context::getContext()->controller->controller_type == 'admin')
  229. {
  230. $css_uri = preg_replace('/^'.preg_quote(__PS_BASE_URI__, '/').'/', '/', $css_uri);
  231. $css_uri = dirname(preg_replace('/\?.+$/', '', $_SERVER['REQUEST_URI']).'a').'/..'.$css_uri;
  232. }
  233. return array($css_uri => $css_media_type);
  234. }
  235. /**
  236. * return jquery path.
  237. *
  238. * @param mixed $version
  239. * @return string
  240. */
  241. public static function getJqueryPath($version = null, $folder = null, $minifier = true)
  242. {
  243. $add_no_conflict = false;
  244. if ($version === null)
  245. $version = _PS_JQUERY_VERSION_; //set default version
  246. else if (preg_match('/^([0-9]+\.)+[0-9]$/Ui', $version))
  247. $add_no_conflict = true;
  248. else
  249. return false;
  250. if ($folder === null)
  251. $folder = _PS_JS_DIR_.'jquery/'; //set default folder
  252. //check if file exist
  253. $file = $folder.'jquery-'.$version.($minifier ? '.min.js' : '.js');
  254. // remove PS_BASE_URI on _PS_ROOT_DIR_ for the following
  255. $url_data = parse_url($file);
  256. $file_uri = _PS_ROOT_DIR_.Tools::str_replace_once(__PS_BASE_URI__, DIRECTORY_SEPARATOR, $url_data['path']);
  257. // check if js files exists, if not try to load query from ajax.googleapis.com
  258. $return = array();
  259. if (@filemtime($file_uri))
  260. $return[] = Media::getJSPath($file);
  261. else
  262. $return[] = Media::getJSPath(Tools::getCurrentUrlProtocolPrefix().'ajax.googleapis.com/ajax/libs/jquery/'.$version.'/jquery'.($minifier ? '.min.js' : '.js'));
  263. if ($add_no_conflict)
  264. $return[] = Media::getJSPath(_PS_JS_DIR_.'jquery/jquery.noConflict.php?version='.$version);
  265. return $return;
  266. }
  267. /**
  268. * return jqueryUI component path.
  269. *
  270. * @param mixed $component
  271. * @return string
  272. */
  273. public static function getJqueryUIPath($component, $theme, $check_dependencies)
  274. {
  275. $ui_path = array('js' => array(), 'css' => array());
  276. $folder = _PS_JS_DIR_.'jquery/ui/';
  277. $file = 'jquery.'.$component.'.min.js';
  278. $url_data = parse_url($folder.$file);
  279. $file_uri = _PS_ROOT_DIR_.Tools::str_replace_once(__PS_BASE_URI__, DIRECTORY_SEPARATOR, $url_data['path']);
  280. $ui_tmp = array();
  281. if (self::$jquery_ui_dependencies[$component]['theme'] && $check_dependencies)
  282. {
  283. $theme_css = Media::getCSSPath($folder.'themes/'.$theme.'/jquery.ui.theme.css');
  284. $comp_css = Media::getCSSPath($folder.'themes/'.$theme.'/jquery.'.$component.'.css');
  285. if (!empty($theme_css) || $theme_css)
  286. $ui_path['css'] = array_merge($ui_path['css'], $theme_css);
  287. if (!empty($comp_css) || $comp_css)
  288. $ui_path['css'] = array_merge($ui_path['css'], $comp_css);
  289. }
  290. if ($check_dependencies && array_key_exists($component, self::$jquery_ui_dependencies))
  291. {
  292. foreach (self::$jquery_ui_dependencies[$component]['dependencies'] as $dependency)
  293. {
  294. $ui_tmp[] = Media::getJqueryUIPath($dependency, $theme, false);
  295. if (self::$jquery_ui_dependencies[$dependency]['theme'])
  296. $dep_css = Media::getCSSPath($folder.'themes/'.$theme.'/jquery.'.$dependency.'.css');
  297. if (!empty($dep_css) || $dep_css)
  298. $ui_path['css'] = array_merge($ui_path['css'], $dep_css);
  299. }
  300. }
  301. if (@filemtime($file_uri))
  302. {
  303. if (!empty($ui_tmp))
  304. {
  305. foreach ($ui_tmp as $ui)
  306. {
  307. $ui_path['js'][] = $ui['js'];
  308. $ui_path['css'][] = $ui['css'];
  309. }
  310. $ui_path['js'][] = Media::getJSPath($folder.$file);
  311. }
  312. else
  313. $ui_path['js'] = Media::getJSPath($folder.$file);
  314. }
  315. //add i18n file for datepicker
  316. if ($component == 'ui.datepicker')
  317. $ui_path['js'][] = Media::getJSPath($folder.'i18n/jquery.ui.datepicker-'.Context::getContext()->language->iso_code.'.js');
  318. return $ui_path;
  319. }
  320. /**
  321. * return jquery plugin path.
  322. *
  323. * @param mixed $name
  324. * @return void
  325. */
  326. public static function getJqueryPluginPath($name, $folder)
  327. {
  328. $plugin_path = array('js' => array(), 'css' => array());
  329. if ($folder === null)
  330. $folder = _PS_JS_DIR_.'jquery/plugins/'; //set default folder
  331. $file = 'jquery.'.$name.'.js';
  332. $url_data = parse_url($folder);
  333. $file_uri = _PS_ROOT_DIR_.Tools::str_replace_once(__PS_BASE_URI__, DIRECTORY_SEPARATOR, $url_data['path']);
  334. if (@filemtime($file_uri.$file))
  335. $plugin_path['js'] = Media::getJSPath($folder.$file);
  336. elseif (@filemtime($file_uri.$name.'/'.$file))
  337. $plugin_path['js'] = Media::getJSPath($folder.$name.'/'.$file);
  338. else
  339. return false;
  340. $plugin_path['css'] = Media::getJqueryPluginCSSPath($name);
  341. return $plugin_path;
  342. }
  343. /**
  344. * return jquery plugin css path if exist.
  345. *
  346. * @param mixed $name
  347. * @return void
  348. */
  349. public static function getJqueryPluginCSSPath($name)
  350. {
  351. $folder = _PS_JS_DIR_.'jquery/plugins/';
  352. $file = 'jquery.'.$name.'.css';
  353. $url_data = parse_url($folder);
  354. $file_uri = _PS_ROOT_DIR_.Tools::str_replace_once(__PS_BASE_URI__, DIRECTORY_SEPARATOR, $url_data['path']);
  355. if (@filemtime($file_uri.$file))
  356. return Media::getCSSPath($folder.$file);
  357. elseif (@filemtime($file_uri.$name.'/'.$file))
  358. return Media::getCSSPath($folder.$name.'/'.$file);
  359. else
  360. return false;
  361. }
  362. /**
  363. * Combine Compress and Cache CSS (ccc) calls
  364. *
  365. * @param array css_files
  366. * @return array processed css_files
  367. */
  368. public static function cccCss($css_files)
  369. {
  370. //inits
  371. $css_files_by_media = array();
  372. $compressed_css_files = array();
  373. $compressed_css_files_not_found = array();
  374. $compressed_css_files_infos = array();
  375. $protocol_link = Tools::getCurrentUrlProtocolPrefix();
  376. // group css files by media
  377. foreach ($css_files as $filename => $media)
  378. {
  379. if (!array_key_exists($media, $css_files_by_media))
  380. $css_files_by_media[$media] = array();
  381. $infos = array();
  382. $infos['uri'] = $filename;
  383. $url_data = parse_url($filename);
  384. $infos['path'] = _PS_ROOT_DIR_.Tools::str_replace_once(__PS_BASE_URI__, '/', $url_data['path']);
  385. $css_files_by_media[$media]['files'][] = $infos;
  386. if (!array_key_exists('date', $css_files_by_media[$media]))
  387. $css_files_by_media[$media]['date'] = 0;
  388. $css_files_by_media[$media]['date'] = max(
  389. file_exists($infos['path']) ? filemtime($infos['path']) : 0,
  390. $css_files_by_media[$media]['date']
  391. );
  392. if (!array_key_exists($media, $compressed_css_files_infos))
  393. $compressed_css_files_infos[$media] = array('key' => '');
  394. $compressed_css_files_infos[$media]['key'] .= $filename;
  395. }
  396. // get compressed css file infos
  397. foreach ($compressed_css_files_infos as $media => &$info)
  398. {
  399. $key = md5($info['key'].$protocol_link);
  400. $filename = _PS_THEME_DIR_.'cache/'.$key.'_'.$media.'.css';
  401. $info = array(
  402. 'key' => $key,
  403. 'date' => file_exists($filename) ? filemtime($filename) : 0
  404. );
  405. }
  406. // aggregate and compress css files content, write new caches files
  407. $import_url = array();
  408. foreach ($css_files_by_media as $media => $media_infos)
  409. {
  410. $cache_filename = _PS_THEME_DIR_.'cache/'.$compressed_css_files_infos[$media]['key'].'_'.$media.'.css';
  411. if ($media_infos['date'] > $compressed_css_files_infos[$media]['date'])
  412. {
  413. $compressed_css_files[$media] = '';
  414. foreach ($media_infos['files'] as $file_infos)
  415. {
  416. if (file_exists($file_infos['path']))
  417. $compressed_css_files[$media] .= Media::minifyCSS(file_get_contents($file_infos['path']), $file_infos['uri'], $import_url);
  418. else
  419. $compressed_css_files_not_found[] = $file_infos['path'];
  420. }
  421. if (!empty($compressed_css_files_not_found))
  422. $content = '/* WARNING ! file(s) not found : "'.
  423. implode(',', $compressed_css_files_not_found).
  424. '" */'."\n".$compressed_css_files[$media];
  425. else
  426. $content = $compressed_css_files[$media];
  427. $content = implode('', $import_url).$content;
  428. file_put_contents($cache_filename, $content);
  429. chmod($cache_filename, 0777);
  430. }
  431. $compressed_css_files[$media] = $cache_filename;
  432. }
  433. // rebuild the original css_files array
  434. $css_files = array();
  435. foreach ($compressed_css_files as $media => $filename)
  436. {
  437. $url = str_replace(_PS_THEME_DIR_, _THEMES_DIR_._THEME_NAME_.'/', $filename);
  438. $css_files[$protocol_link.Tools::getMediaServer($url).$url] = $media;
  439. }
  440. return $css_files;
  441. }
  442. /**
  443. * Combine Compress and Cache (ccc) JS calls
  444. *
  445. * @param array js_files
  446. * @return array processed js_files
  447. */
  448. public static function cccJS($js_files)
  449. {
  450. //inits
  451. $compressed_js_files_not_found = array();
  452. $js_files_infos = array();
  453. $js_files_date = 0;
  454. $compressed_js_filename = '';
  455. $js_external_files = array();
  456. $protocol_link = Tools::getCurrentUrlProtocolPrefix();
  457. // get js files infos
  458. foreach ($js_files as $filename)
  459. {
  460. $expr = explode(':', $filename);
  461. if ($expr[0] == 'http')
  462. $js_external_files[] = $filename;
  463. else
  464. {
  465. $infos = array();
  466. $infos['uri'] = $filename;
  467. $url_data = parse_url($filename);
  468. $infos['path'] = _PS_ROOT_DIR_.Tools::str_replace_once(__PS_BASE_URI__, '/', $url_data['path']);
  469. $js_files_infos[] = $infos;
  470. $js_files_date = max(
  471. file_exists($infos['path']) ? filemtime($infos['path']) : 0,
  472. $js_files_date
  473. );
  474. $compressed_js_filename .= $filename;
  475. }
  476. }
  477. // get compressed js file infos
  478. $compressed_js_filename = md5($compressed_js_filename);
  479. $compressed_js_path = _PS_THEME_DIR_.'cache/'.$compressed_js_filename.'.js';
  480. $compressed_js_file_date = file_exists($compressed_js_path) ? filemtime($compressed_js_path) : 0;
  481. // aggregate and compress js files content, write new caches files
  482. if ($js_files_date > $compressed_js_file_date)
  483. {
  484. $content = '';
  485. foreach ($js_files_infos as $file_infos)
  486. {
  487. if (file_exists($file_infos['path']))
  488. $content .= file_get_contents($file_infos['path']).';';
  489. else
  490. $compressed_js_files_not_found[] = $file_infos['path'];
  491. }
  492. $content = Media::packJS($content);
  493. if (!empty($compressed_js_files_not_found))
  494. $content = '/* WARNING ! file(s) not found : "'.
  495. implode(',', $compressed_js_files_not_found).
  496. '" */'."\n".$content;
  497. file_put_contents($compressed_js_path, $content);
  498. chmod($compressed_js_path, 0777);
  499. }
  500. // rebuild the original js_files array
  501. $url = str_replace(_PS_ROOT_DIR_.'/', __PS_BASE_URI__, $compressed_js_path);
  502. return array_merge(array($protocol_link.Tools::getMediaServer($url).$url), $js_external_files);
  503. }
  504. }