PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/w3-total-cache/lib/W3/Plugin/Minify.php

https://github.com/sharpmachine/wakeupmedia.com
PHP | 1051 lines | 599 code | 184 blank | 268 comment | 147 complexity | b31ece2d6e629b6e2f64d99f59eddd57 MD5 | raw file
  1. <?php
  2. /**
  3. * W3 Minify plugin
  4. */
  5. if (!defined('W3TC')) {
  6. die();
  7. }
  8. require_once W3TC_LIB_W3_DIR . '/Plugin.php';
  9. /**
  10. * Class W3_Plugin_Minify
  11. */
  12. class W3_Plugin_Minify extends W3_Plugin {
  13. /**
  14. * Minify reject reason
  15. *
  16. * @var string
  17. */
  18. var $minify_reject_reason = '';
  19. /**
  20. * Error
  21. *
  22. * @var string
  23. */
  24. var $error = '';
  25. /**
  26. * Array of printed styles
  27. *
  28. * @var array
  29. */
  30. var $printed_styles = array();
  31. /**
  32. * Array of printed scripts
  33. *
  34. * @var array
  35. */
  36. var $printed_scripts = array();
  37. /**
  38. * Array of replaced styles
  39. *
  40. * @var array
  41. */
  42. var $replaced_styles = array();
  43. /**
  44. * Array of replaced scripts
  45. *
  46. * @var array
  47. */
  48. var $replaced_scripts = array();
  49. /**
  50. * Runs plugin
  51. */
  52. function run() {
  53. add_filter('cron_schedules', array(
  54. &$this,
  55. 'cron_schedules'
  56. ));
  57. if ($this->_config->get_string('minify.engine') == 'file') {
  58. add_action('w3_minify_cleanup', array(
  59. &$this,
  60. 'cleanup'
  61. ));
  62. }
  63. /**
  64. * Start minify
  65. */
  66. if ($this->can_minify()) {
  67. ob_start(array(
  68. &$this,
  69. 'ob_callback'
  70. ));
  71. }
  72. }
  73. /**
  74. * Instantiates worker with admin functionality on demand
  75. *
  76. * @return W3_Plugin_MinifyAdmin
  77. */
  78. function &get_admin() {
  79. return w3_instance('W3_Plugin_MinifyAdmin');
  80. }
  81. /**
  82. * Activate plugin action (called by W3_PluginProxy)
  83. */
  84. function activate() {
  85. $this->get_admin()->activate();
  86. }
  87. /**
  88. * Deactivate plugin action (called by W3_PluginProxy)
  89. */
  90. function deactivate() {
  91. $this->get_admin()->deactivate();
  92. }
  93. /**
  94. * Does disk cache cleanup
  95. *
  96. * @return void
  97. */
  98. function cleanup() {
  99. $this->get_admin()->cleanup();
  100. }
  101. /**
  102. * Cron schedules filter
  103. *
  104. * @param array $schedules
  105. * @return array
  106. */
  107. function cron_schedules($schedules) {
  108. $gc = $this->_config->get_integer('minify.file.gc');
  109. return array_merge($schedules, array(
  110. 'w3_minify_cleanup' => array(
  111. 'interval' => $gc,
  112. 'display' => sprintf('[W3TC] Minify file GC (every %d seconds)', $gc)
  113. )
  114. ));
  115. }
  116. /**
  117. * OB callback
  118. *
  119. * @param string $buffer
  120. * @return string
  121. */
  122. function ob_callback(&$buffer) {
  123. if ($buffer != '' && w3_is_xml($buffer)) {
  124. if ($this->can_minify2($buffer)) {
  125. /**
  126. * Replace script and style tags
  127. */
  128. if (function_exists('is_feed') && !is_feed()) {
  129. $head_prepend = '';
  130. $body_prepend = '';
  131. $body_append = '';
  132. if ($this->_config->get_boolean('minify.auto')) {
  133. if ($this->_config->get_boolean('minify.css.enable')) {
  134. $files_css = $this->get_files_css($buffer);
  135. $style = $this->get_style_custom($files_css);
  136. if ($style) {
  137. $head_prepend .= $style;
  138. $this->remove_styles($buffer, $files_css);
  139. }
  140. }
  141. if ($this->_config->get_boolean('minify.js.enable')) {
  142. $files_js = $this->get_files_js($buffer);
  143. $script = $this->get_script_custom($files_js);
  144. if ($script) {
  145. $head_prepend .= $script;
  146. $this->remove_scripts($buffer, $files_js);
  147. }
  148. }
  149. } else {
  150. if ($this->_config->get_boolean('minify.css.enable') && !in_array('include', $this->printed_styles)) {
  151. $style = $this->get_style_group('include');
  152. if ($style) {
  153. $head_prepend .= $style;
  154. $this->remove_styles_group($buffer, 'include');
  155. }
  156. }
  157. if ($this->_config->get_boolean('minify.js.enable')) {
  158. if (!in_array('include', $this->printed_scripts)) {
  159. $script = $this->get_script_group('include');
  160. if ($script) {
  161. $head_prepend .= $script;
  162. $this->remove_scripts_group($buffer, 'include');
  163. }
  164. }
  165. if (!in_array('include-nb', $this->printed_scripts)) {
  166. $script = $this->get_script_group('include-nb');
  167. if ($script) {
  168. $head_prepend .= $script;
  169. $this->remove_scripts_group($buffer, 'include-nb');
  170. }
  171. }
  172. if (!in_array('include-body', $this->printed_scripts)) {
  173. $script = $this->get_script_group('include-body');
  174. if ($script) {
  175. $body_prepend .= $script;
  176. $this->remove_scripts_group($buffer, 'include-body');
  177. }
  178. }
  179. if (!in_array('include-body-nb', $this->printed_scripts)) {
  180. $script = $this->get_script_group('include-body-nb');
  181. if ($script) {
  182. $body_prepend .= $script;
  183. $this->remove_scripts_group($buffer, 'include-body-nb');
  184. }
  185. }
  186. if (!in_array('include-footer', $this->printed_scripts)) {
  187. $script = $this->get_script_group('include-footer');
  188. if ($script) {
  189. $body_append .= $script;
  190. $this->remove_scripts_group($buffer, 'include-footer');
  191. }
  192. }
  193. if (!in_array('include-footer-nb', $this->printed_scripts)) {
  194. $script = $this->get_script_group('include-footer-nb');
  195. if ($script) {
  196. $body_append .= $script;
  197. $this->remove_scripts_group($buffer, 'include-footer-nb');
  198. }
  199. }
  200. }
  201. }
  202. if ($head_prepend != '') {
  203. $buffer = preg_replace('~<head(\s+[^<>]+)*>~Ui', '\\0' . $head_prepend, $buffer, 1);
  204. }
  205. if ($body_prepend != '') {
  206. $buffer = preg_replace('~<body(\s+[^<>]+)*>~Ui', '\\0' . $body_prepend, $buffer, 1);
  207. }
  208. if ($body_append != '') {
  209. $buffer = preg_replace('~<\\/body>~', $body_append . '\\0', $buffer, 1);
  210. }
  211. }
  212. /**
  213. * Minify HTML/Feed
  214. */
  215. if ($this->_config->get_boolean('minify.html.enable')) {
  216. try {
  217. $this->minify_html($buffer);
  218. } catch (Exception $exception) {
  219. $this->error = $exception->getMessage();
  220. }
  221. }
  222. }
  223. if ($this->_config->get_boolean('minify.debug')) {
  224. $buffer .= "\r\n\r\n" . $this->get_debug_info();
  225. }
  226. }
  227. return $buffer;
  228. }
  229. /**
  230. * Parse buffer and return array of JS files from it
  231. *
  232. * @param string $buffer
  233. * @return array
  234. */
  235. function get_files_js(&$buffer) {
  236. require_once W3TC_INC_DIR . '/functions/extract.php';
  237. $files = w3_extract_js($buffer);
  238. $files = $this->filter_files($files);
  239. return $files;
  240. }
  241. /**
  242. * Parse buffer and return array of CSS files from it
  243. *
  244. * @param string $buffer
  245. * @return array
  246. */
  247. function get_files_css(&$buffer) {
  248. require_once W3TC_INC_DIR . '/functions/extract.php';
  249. $files = w3_extract_css($buffer);
  250. $files = $this->filter_files($files);
  251. return $files;
  252. }
  253. /**
  254. * Filters files
  255. *
  256. * @param array $files
  257. * @return array
  258. */
  259. function filter_files($files) {
  260. $files = array_map('w3_normalize_file_minify2', $files);
  261. $files = array_filter($files, array(&$this, '_filter_files'));
  262. $files = array_values(array_unique($files));
  263. return $files;
  264. }
  265. /**
  266. * URL file filter
  267. *
  268. * @param string $file
  269. * @return bool
  270. */
  271. function _filter_files($file) {
  272. if (w3_is_url($file)) {
  273. return false;
  274. }
  275. $ext = strrchr($file, '.');
  276. if ($ext != '.js' && $ext != '.css') {
  277. return false;
  278. }
  279. $path = w3_get_document_root() . '/' . $file;
  280. if (!file_exists($path)) {
  281. return false;
  282. }
  283. return true;
  284. }
  285. /**
  286. * Removes style tags from the source
  287. *
  288. * @param string $content
  289. * @param array $files
  290. * @return void
  291. */
  292. function remove_styles(&$content, $files) {
  293. $regexps = array();
  294. $domain_url_regexp = w3_get_domain_url_regexp();
  295. foreach ($files as $file) {
  296. $this->replaced_styles[] = $file;
  297. if (w3_is_url($file) && !preg_match('~' . $domain_url_regexp . '~i', $file)) {
  298. // external CSS files
  299. $regexps[] = w3_preg_quote($file);
  300. } else {
  301. // local CSS files
  302. $file = ltrim(preg_replace('~' . $domain_url_regexp . '~i', '', $file), '/\\');
  303. $regexps[] = '(' . $domain_url_regexp . ')?/?' . w3_preg_quote($file);
  304. }
  305. }
  306. foreach ($regexps as $regexp) {
  307. $content = preg_replace('~<link\s+[^<>]*href=["\']?' . $regexp . '["\']?[^<>]*/?>(.*</link>)?~Uis', '', $content);
  308. $content = preg_replace('~@import\s+(url\s*)?\(?["\']?\s*' . $regexp . '\s*["\']?\)?[^;]*;?~is', '', $content);
  309. }
  310. $content = preg_replace('~<style[^<>]*>\s*</style>~', '', $content);
  311. }
  312. /**
  313. * Remove script tags from the source
  314. *
  315. * @param string $content
  316. * @param array $files
  317. * @return void
  318. */
  319. function remove_scripts(&$content, $files) {
  320. $regexps = array();
  321. $domain_url_regexp = w3_get_domain_url_regexp();
  322. foreach ($files as $file) {
  323. $this->replaced_scripts[] = $file;
  324. if (w3_is_url($file) && !preg_match('~' . $domain_url_regexp . '~i', $file)) {
  325. // external JS files
  326. $regexps[] = w3_preg_quote($file);
  327. } else {
  328. // local JS files
  329. $file = ltrim(preg_replace('~' . $domain_url_regexp . '~i', '', $file), '/\\');
  330. $regexps[] = '(' . $domain_url_regexp . ')?/?' . w3_preg_quote($file);
  331. }
  332. }
  333. foreach ($regexps as $regexp) {
  334. $content = preg_replace('~<script\s+[^<>]*src=["\']?' . $regexp . '["\']?[^<>]*>\s*</script>~Uis', '', $content);
  335. }
  336. }
  337. /**
  338. * Removes style tag from the source for group
  339. *
  340. * @param string $content
  341. * @param string $location
  342. * @return void
  343. */
  344. function remove_styles_group(&$content, $location) {
  345. $theme = $this->get_theme();
  346. $template = $this->get_template();
  347. $files = array();
  348. $groups = $this->_config->get_array('minify.css.groups');
  349. if (isset($groups[$theme]['default'][$location]['files'])) {
  350. $files = (array) $groups[$theme]['default'][$location]['files'];
  351. }
  352. if ($template != 'default' && isset($groups[$theme][$template][$location]['files'])) {
  353. $files = array_merge($files, (array) $groups[$theme][$template][$location]['files']);
  354. }
  355. $this->remove_styles($content, $files);
  356. }
  357. /**
  358. * Removes script tags from the source for group
  359. *
  360. * @param string $content
  361. * @param string $location
  362. * @return void
  363. */
  364. function remove_scripts_group(&$content, $location) {
  365. $theme = $this->get_theme();
  366. $template = $this->get_template();
  367. $files = array();
  368. $groups = $this->_config->get_array('minify.js.groups');
  369. if (isset($groups[$theme]['default'][$location]['files'])) {
  370. $files = (array) $groups[$theme]['default'][$location]['files'];
  371. }
  372. if ($template != 'default' && isset($groups[$theme][$template][$location]['files'])) {
  373. $files = array_merge($files, (array) $groups[$theme][$template][$location]['files']);
  374. }
  375. $this->remove_scripts($content, $files);
  376. }
  377. /**
  378. * Minifies HTML
  379. *
  380. * @param string $html
  381. * @return string
  382. */
  383. function minify_html(&$html) {
  384. $w3_minifier = & w3_instance('W3_Minifier');
  385. $ignored_comments = $this->_config->get_array('minify.html.comments.ignore');
  386. if (count($ignored_comments)) {
  387. require_once W3TC_LIB_MINIFY_DIR . '/Minify/IgnoredCommentPreserver.php';
  388. @$ignored_comments_preserver =& new Minify_IgnoredCommentPreserver();
  389. $ignored_comments_preserver->setIgnoredComments($ignored_comments);
  390. $ignored_comments_preserver->search($html);
  391. }
  392. if ($this->_config->get_boolean('minify.html.inline.js')) {
  393. $js_engine = $this->_config->get_string('minify.js.engine');
  394. if (!$w3_minifier->exists($js_engine) || !$w3_minifier->available($js_engine)) {
  395. $js_engine = 'js';
  396. }
  397. $js_minifier = $w3_minifier->get_minifier($js_engine);
  398. $js_options = $w3_minifier->get_options($js_engine);
  399. $w3_minifier->init($js_engine);
  400. require_once W3TC_LIB_MINIFY_DIR . '/Minify/Inline.php';
  401. require_once W3TC_LIB_MINIFY_DIR . '/Minify/Inline/JavaScript.php';
  402. $html = Minify_Inline_JavaScript::minify($html, $js_minifier, $js_options);
  403. }
  404. if ($this->_config->get_boolean('minify.html.inline.css')) {
  405. $css_engine = $this->_config->get_string('minify.css.engine');
  406. if (!$w3_minifier->exists($css_engine) || !$w3_minifier->available($css_engine)) {
  407. $css_engine = 'css';
  408. }
  409. $css_minifier = $w3_minifier->get_minifier($css_engine);
  410. $css_options = $w3_minifier->get_options($css_engine);
  411. $w3_minifier->init($css_engine);
  412. require_once W3TC_LIB_MINIFY_DIR . '/Minify/Inline.php';
  413. require_once W3TC_LIB_MINIFY_DIR . '/Minify/Inline/CSS.php';
  414. $html = Minify_Inline_CSS::minify($html, $css_minifier, $css_options);
  415. }
  416. $engine = $this->_config->get_string('minify.html.engine');
  417. if (!$w3_minifier->exists($engine) || !$w3_minifier->available($engine)) {
  418. $engine = 'html';
  419. }
  420. if (function_exists('is_feed') && is_feed()) {
  421. $engine .= 'xml';
  422. }
  423. $minifier = $w3_minifier->get_minifier($engine);
  424. $options = $w3_minifier->get_options($engine);
  425. $w3_minifier->init($engine);
  426. $html = call_user_func($minifier, $html, $options);
  427. if (isset($ignored_comments_preserver)) {
  428. $ignored_comments_preserver->replace($html);
  429. }
  430. }
  431. /**
  432. * Returns current theme
  433. *
  434. * @return string
  435. */
  436. function get_theme() {
  437. static $theme = null;
  438. if ($theme === null) {
  439. $theme = w3_get_theme_key(get_theme_root(), get_template(), get_stylesheet());
  440. }
  441. return $theme;
  442. }
  443. /**
  444. * Returns current template
  445. *
  446. * @return string
  447. */
  448. function get_template() {
  449. static $template = null;
  450. if ($template === null) {
  451. switch (true) {
  452. case (is_404() && ($template_file = get_404_template())):
  453. case (is_search() && ($template_file = get_search_template())):
  454. case (is_tax() && ($template_file = get_taxonomy_template())):
  455. case (is_front_page() && function_exists('get_front_page_template') && $template = get_front_page_template()):
  456. case (is_home() && ($template_file = get_home_template())):
  457. case (is_attachment() && ($template_file = get_attachment_template())):
  458. case (is_single() && ($template_file = get_single_template())):
  459. case (is_page() && ($template_file = get_page_template())):
  460. case (is_category() && ($template_file = get_category_template())):
  461. case (is_tag() && ($template_file = get_tag_template())):
  462. case (is_author() && ($template_file = get_author_template())):
  463. case (is_date() && ($template_file = get_date_template())):
  464. case (is_archive() && ($template_file = get_archive_template())):
  465. case (is_comments_popup() && ($template_file = get_comments_popup_template())):
  466. case (is_paged() && ($template_file = get_paged_template())):
  467. break;
  468. default:
  469. if (function_exists('get_index_template')) {
  470. $template_file = get_index_template();
  471. } else {
  472. $template_file = 'index.php';
  473. }
  474. break;
  475. }
  476. $template = basename($template_file, '.php');
  477. }
  478. return $template;
  479. }
  480. /**
  481. * Returns style tag
  482. *
  483. * @param string $url
  484. * @param boolean $import
  485. * @return string
  486. */
  487. function get_style($url, $import = false) {
  488. if ($import) {
  489. return "<style type=\"text/css\" media=\"all\">@import url(\"" . $url . "\");</style>\r\n";
  490. } else {
  491. return "<link rel=\"stylesheet\" type=\"text/css\" href=\"" . str_replace('&', '&amp;', $url) . "\" media=\"all\" />\r\n";
  492. }
  493. }
  494. /**
  495. * Prints script tag
  496. *
  497. * @param string $url
  498. * @param boolean $blocking
  499. * @return string
  500. */
  501. function get_script($url, $blocking = true) {
  502. static $non_blocking_function = false;
  503. if ($blocking) {
  504. return '<script type="text/javascript" src="' . str_replace('&', '&amp;', $url) . '"></script>';
  505. } else {
  506. $script = '';
  507. if (!$non_blocking_function) {
  508. $non_blocking_function = true;
  509. $script = "<script type=\"text/javascript\">function w3tc_load_js(u){var d=document,p=d.getElementsByTagName('HEAD')[0],c=d.createElement('script');c.type='text/javascript';c.src=u;p.appendChild(c);}</script>";
  510. }
  511. $script .= "<script type=\"text/javascript\">w3tc_load_js('" . $url . "');</script>";
  512. return $script;
  513. }
  514. }
  515. /**
  516. * Returns style tag for style group
  517. *
  518. * @param string $location
  519. * @return array
  520. */
  521. function get_style_group($location) {
  522. $style = false;
  523. $type = 'css';
  524. $groups = $this->_config->get_array('minify.css.groups');
  525. $theme = $this->get_theme();
  526. $template = $this->get_template();
  527. if ($template != 'default' && empty($groups[$theme][$template][$location]['files'])) {
  528. $template = 'default';
  529. }
  530. if (!empty($groups[$theme][$template][$location]['files'])) {
  531. $url = $this->format_url_group($theme, $template, $location, $type);
  532. if ($url) {
  533. $import = (isset($groups[$theme][$template][$location]['import']) ? (boolean) $groups[$theme][$template][$location]['import'] : false);
  534. $style = $this->get_style($url, $import);
  535. }
  536. }
  537. return $style;
  538. }
  539. /**
  540. * Returns script tag for script group
  541. *
  542. * @param string $location
  543. * @return array
  544. */
  545. function get_script_group($location) {
  546. $script = false;
  547. $type = 'js';
  548. $theme = $this->get_theme();
  549. $template = $this->get_template();
  550. $groups = $this->_config->get_array('minify.js.groups');
  551. if ($template != 'default' && empty($groups[$theme][$template][$location]['files'])) {
  552. $template = 'default';
  553. }
  554. if (!empty($groups[$theme][$template][$location]['files'])) {
  555. $url = $this->format_url_group($theme, $template, $location, $type);
  556. if ($url) {
  557. $blocking = (isset($groups[$theme][$template][$location]['blocking']) ? (boolean) $groups[$theme][$template][$location]['blocking'] : true);
  558. $script = $this->get_script($url, $blocking);
  559. }
  560. }
  561. return $script;
  562. }
  563. /**
  564. * Returns script tag for custom files
  565. *
  566. * @param string|array $files
  567. * @param bool $blocking
  568. * @return string
  569. */
  570. function get_script_custom($files, $blocking = true) {
  571. $script = false;
  572. if (count($files)) {
  573. $url = $this->format_url_custom($files, 'js');
  574. if ($url) {
  575. $script = $this->get_script($url, $blocking);
  576. }
  577. }
  578. return $script;
  579. }
  580. /**
  581. * Returns style tag for custom files
  582. *
  583. * @param string|array $files
  584. * @param boolean $import
  585. * @return string
  586. */
  587. function get_style_custom($files, $import = false) {
  588. $style = false;
  589. if (count($files)) {
  590. $url = $this->format_url_custom($files, 'css');
  591. if ($url) {
  592. $style = $this->get_style($url, $import);
  593. }
  594. }
  595. return $style;
  596. }
  597. /**
  598. * Formats URL
  599. *
  600. * @param string $theme
  601. * @param string $template
  602. * @param string $location
  603. * @param string $type
  604. * @param boolean $rewrite
  605. * @return string
  606. */
  607. function format_url_group($theme, $template, $location, $type, $rewrite = null) {
  608. $w3_minify = & w3_instance('W3_Minify');
  609. $url = false;
  610. $id = $w3_minify->get_id_group($theme, $template, $location, $type);
  611. if ($id) {
  612. $site_url_ssl = w3_get_site_url_ssl();
  613. if ($this->_config->get_boolean('minify.rewrite')) {
  614. $url = sprintf('%s/%s/%s/%s.%s.%s.%s', $site_url_ssl, W3TC_CONTENT_MINIFY_DIR_NAME, $theme, $template, $location, $id, $type);
  615. } else {
  616. $url = sprintf('%s/%s/index.php?file=%s/%s.%s.%s.%s', $site_url_ssl, W3TC_CONTENT_MINIFY_DIR_NAME, $theme, $template, $location, $id, $type);
  617. }
  618. }
  619. return $url;
  620. }
  621. /**
  622. * Formats custom URL
  623. *
  624. * @param array $files
  625. * @param string $type
  626. * @return string
  627. */
  628. function format_url_custom($files, $type) {
  629. $w3_minify = & w3_instance('W3_Minify');
  630. $url = false;
  631. $w3_minify->set_custom_files($files, $type);
  632. $hash = $w3_minify->get_custom_files_hash($files);
  633. $id = $w3_minify->get_id_custom($hash, $type);
  634. if ($id) {
  635. $site_url_ssl = w3_get_site_url_ssl();
  636. if ($this->_config->get_boolean('minify.rewrite')) {
  637. $url = sprintf('%s/%s/%s.%s.%s', $site_url_ssl, W3TC_CONTENT_MINIFY_DIR_NAME, $hash, $id, $type);
  638. } else {
  639. $url = sprintf('%s/%s/index.php?file=%s.%s.%s', $site_url_ssl, W3TC_CONTENT_MINIFY_DIR_NAME, $hash, $id, $type);
  640. }
  641. }
  642. return $url;
  643. }
  644. /**
  645. * Returns array of minify URLs
  646. *
  647. * @return array
  648. */
  649. function get_urls() {
  650. $files = array();
  651. $js_groups = $this->_config->get_array('minify.js.groups');
  652. $css_groups = $this->_config->get_array('minify.css.groups');
  653. foreach ($js_groups as $js_theme => $js_templates) {
  654. foreach ($js_templates as $js_template => $js_locations) {
  655. foreach ((array) $js_locations as $js_location => $js_config) {
  656. if (!empty($js_config['files'])) {
  657. $files[] = $this->format_url_group($js_theme, $js_template, $js_location, 'js');
  658. }
  659. }
  660. }
  661. }
  662. foreach ($css_groups as $css_theme => $css_templates) {
  663. foreach ($css_templates as $css_template => $css_locations) {
  664. foreach ((array) $css_locations as $css_location => $css_config) {
  665. if (!empty($css_config['files'])) {
  666. $files[] = $this->format_url_group($css_theme, $css_template, $css_location, 'css');
  667. }
  668. }
  669. }
  670. }
  671. return $files;
  672. }
  673. /**
  674. * Returns debug info
  675. *
  676. * @return string
  677. */
  678. function get_debug_info() {
  679. $debug_info = "<!-- W3 Total Cache: Minify debug info:\r\n";
  680. $debug_info .= sprintf("%s%s\r\n", str_pad('Engine: ', 20), w3_get_engine_name($this->_config->get_string('minify.engine')));
  681. $debug_info .= sprintf("%s%s\r\n", str_pad('Theme: ', 20), $this->get_theme());
  682. $debug_info .= sprintf("%s%s\r\n", str_pad('Template: ', 20), $this->get_template());
  683. if ($this->minify_reject_reason) {
  684. $debug_info .= sprintf("%s%s\r\n", str_pad('Reject reason: ', 20), $this->minify_reject_reason);
  685. }
  686. if ($this->error) {
  687. $debug_info .= sprintf("%s%s\r\n", str_pad('Errors: ', 20), $this->error);
  688. }
  689. if (count($this->replaced_styles)) {
  690. $debug_info .= "\r\nReplaced CSS files:\r\n";
  691. foreach ($this->replaced_styles as $index => $file) {
  692. $debug_info .= sprintf("%d. %s\r\n", $index + 1, w3_escape_comment($file));
  693. }
  694. }
  695. if (count($this->replaced_scripts)) {
  696. $debug_info .= "\r\nReplaced JavaScript files:\r\n";
  697. foreach ($this->replaced_scripts as $index => $file) {
  698. $debug_info .= sprintf("%d. %s\r\n", $index + 1, w3_escape_comment($file));
  699. }
  700. }
  701. $debug_info .= '-->';
  702. return $debug_info;
  703. }
  704. /**
  705. * Check if we can do minify logic
  706. *
  707. * @return boolean
  708. */
  709. function can_minify() {
  710. /**
  711. * Skip if doint AJAX
  712. */
  713. if (defined('DOING_AJAX')) {
  714. $this->minify_reject_reason = 'Doing AJAX';
  715. return false;
  716. }
  717. /**
  718. * Skip if doing cron
  719. */
  720. if (defined('DOING_CRON')) {
  721. $this->minify_reject_reason = 'Doing cron';
  722. return false;
  723. }
  724. /**
  725. * Skip if APP request
  726. */
  727. if (defined('APP_REQUEST')) {
  728. $this->minify_reject_reason = 'Application request';
  729. return false;
  730. }
  731. /**
  732. * Skip if XMLRPC request
  733. */
  734. if (defined('XMLRPC_REQUEST')) {
  735. $this->minify_reject_reason = 'XMLRPC request';
  736. return false;
  737. }
  738. /**
  739. * Skip if Admin
  740. */
  741. if (defined('WP_ADMIN')) {
  742. $this->minify_reject_reason = 'wp-admin';
  743. return false;
  744. }
  745. /**
  746. * Check for WPMU's and WP's 3.0 short init
  747. */
  748. if (defined('SHORTINIT') && SHORTINIT) {
  749. $this->minify_reject_reason = 'Short init';
  750. return false;
  751. }
  752. /**
  753. * Check User agent
  754. */
  755. if (!$this->check_ua()) {
  756. $this->minify_reject_reason = 'User agent is rejected';
  757. return false;
  758. }
  759. /**
  760. * Check request URI
  761. */
  762. if (!$this->check_request_uri()) {
  763. $this->minify_reject_reason = 'Request URI is rejected';
  764. return false;
  765. }
  766. /**
  767. * Skip if user is logged in
  768. */
  769. if ($this->_config->get_boolean('minify.reject.logged') && !$this->check_logged_in()) {
  770. $this->minify_reject_reason = 'User is logged in';
  771. return false;
  772. }
  773. return true;
  774. }
  775. /**
  776. * Returns true if we can minify
  777. *
  778. * @param string $buffer
  779. * @return string
  780. */
  781. function can_minify2(&$buffer) {
  782. /**
  783. * Check for database error
  784. */
  785. if (w3_is_database_error($buffer)) {
  786. $this->minify_reject_reason = 'Database Error occurred';
  787. return false;
  788. }
  789. /**
  790. * Check for DONOTMINIFY constant
  791. */
  792. if (defined('DONOTMINIFY') && DONOTMINIFY) {
  793. $this->minify_reject_reason = 'DONOTMINIFY constant is defined';
  794. return false;
  795. }
  796. /**
  797. * Check feed minify
  798. */
  799. if ($this->_config->get_boolean('minify.html.reject.feed') && function_exists('is_feed') && is_feed()) {
  800. $this->minify_reject_reason = 'Feed is rejected';
  801. return false;
  802. }
  803. return true;
  804. }
  805. /**
  806. * Checks User Agent
  807. *
  808. * @return boolean
  809. */
  810. function check_ua() {
  811. $uas = array_merge($this->_config->get_array('minify.reject.ua'), array(
  812. W3TC_POWERED_BY
  813. ));
  814. foreach ($uas as $ua) {
  815. if (isset($_SERVER['HTTP_USER_AGENT']) && stristr($_SERVER['HTTP_USER_AGENT'], $ua) !== false) {
  816. return false;
  817. }
  818. }
  819. return true;
  820. }
  821. /**
  822. * Check if user is logged in
  823. *
  824. * @return boolean
  825. */
  826. function check_logged_in() {
  827. foreach (array_keys($_COOKIE) as $cookie_name) {
  828. if ($cookie_name == 'wordpress_test_cookie') {
  829. continue;
  830. }
  831. if (strpos($cookie_name, 'wordpress') === 0) {
  832. return false;
  833. }
  834. }
  835. return true;
  836. }
  837. /**
  838. * Checks request URI
  839. *
  840. * @return boolean
  841. */
  842. function check_request_uri() {
  843. $auto_reject_uri = array(
  844. 'wp-login',
  845. 'wp-register'
  846. );
  847. foreach ($auto_reject_uri as $uri) {
  848. if (strstr($_SERVER['REQUEST_URI'], $uri) !== false) {
  849. return false;
  850. }
  851. }
  852. $reject_uri = $this->_config->get_array('minify.reject.uri');
  853. $reject_uri = array_map('w3_parse_path', $reject_uri);
  854. foreach ($reject_uri as $expr) {
  855. $expr = trim($expr);
  856. if ($expr != '' && preg_match('~' . $expr . '~i', $_SERVER['REQUEST_URI'])) {
  857. return false;
  858. }
  859. }
  860. return true;
  861. }
  862. }