PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/classes/Media.php

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