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

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

https://github.com/failstar/polycaro
PHP | 803 lines | 531 code | 132 blank | 140 comment | 79 complexity | dcede7cecba84a08cf34b8959c02a13c MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, GPL-3.0, LGPL-2.1
  1. <?php
  2. /**
  3. * W3 PgCache plugin - administrative interface
  4. */
  5. if (!defined('W3TC')) {
  6. die();
  7. }
  8. w3_require_once(W3TC_INC_DIR . '/functions/activation.php');
  9. w3_require_once(W3TC_INC_DIR . '/functions/file.php');
  10. w3_require_once(W3TC_INC_DIR . '/functions/rule.php');
  11. /**
  12. * Class W3_BrowserCacheAdminEnvironment
  13. */
  14. class W3_BrowserCacheAdminEnvironment {
  15. /**
  16. * Fixes environment in each wp-admin request
  17. *
  18. * @param W3_Config $config
  19. * @param bool $force_all_checks
  20. * @throws SelfTestExceptions
  21. **/
  22. public function fix_on_wpadmin_request($config, $force_all_checks) {
  23. $exs = new SelfTestExceptions();
  24. if ($config->get_boolean('config.check') || $force_all_checks) {
  25. if ($config->get_boolean('browsercache.enabled')) {
  26. $this->rules_cache_add($config, $exs);
  27. } else {
  28. $this->rules_cache_remove($exs);
  29. }
  30. if ($config->get_boolean('browsercache.enabled') &&
  31. $config->get_boolean('browsercache.no404wp')) {
  32. $this->rules_no404wp_add($config, $exs);
  33. } else {
  34. $this->rules_no404wp_remove($exs);
  35. }
  36. }
  37. if (count($exs->exceptions()) > 0)
  38. throw $exs;
  39. }
  40. /**
  41. * Fixes environment once event occurs
  42. * @throws SelfTestExceptions
  43. **/
  44. public function fix_on_event($config, $event, $old_config = null) {
  45. }
  46. /**
  47. * Fixes environment after plugin deactivation
  48. * @throws SelfTestExceptions
  49. */
  50. public function fix_after_deactivation() {
  51. $exs = new SelfTestExceptions();
  52. $this->rules_cache_remove($exs);
  53. $this->rules_no404wp_remove($exs);
  54. if (count($exs->exceptions()) > 0)
  55. throw $exs;
  56. }
  57. /**
  58. * Returns required rules for module
  59. *
  60. * @param W3_Config $config
  61. * @return array
  62. */
  63. public function get_required_rules($config) {
  64. if (!$config->get_boolean('browsercache.enabled'))
  65. return null;
  66. $rewrite_rules = array();
  67. $dispatcher = w3_instance('W3_Dispatcher');
  68. if ($dispatcher->should_browsercache_generate_rules_for_cdn($config)) {
  69. $domain = $dispatcher->get_cdn_domain();
  70. $cdn_rules_path = sprintf('ftp://%s/%s', $domain,
  71. w3_get_cdn_rules_path());
  72. $rewrite_rules[] = array(
  73. 'filename' => $cdn_rules_path,
  74. 'content' => $this->rules_cache_generate($config, true)
  75. );
  76. }
  77. $browsercache_rules_cache_path = w3_get_browsercache_rules_cache_path();
  78. $rewrite_rules[] = array(
  79. 'filename' => $browsercache_rules_cache_path,
  80. 'content' => $this->rules_cache_generate($config)
  81. );
  82. if ($config->get_boolean('browsercache.no404wp')) {
  83. $browsercache_rules_no404wp_path =
  84. w3_get_browsercache_rules_no404wp_path();
  85. $rewrite_rules[] = array(
  86. 'filename' => $browsercache_rules_no404wp_path,
  87. 'content' => $this->rules_no404wp_generate($config)
  88. );
  89. }
  90. return $rewrite_rules;
  91. }
  92. /**
  93. * Returns mime types
  94. *
  95. * @return array
  96. */
  97. public function get_mime_types() {
  98. return array(
  99. 'cssjs' => include W3TC_INC_DIR . '/mime/cssjs.php',
  100. 'html' => include W3TC_INC_DIR . '/mime/html.php',
  101. 'other' => include W3TC_INC_DIR . '/mime/other.php'
  102. );
  103. }
  104. /**
  105. * Generate rules for FTP upload
  106. *
  107. * @param W3_Config $config
  108. * @return string
  109. **/
  110. public function rules_cache_generate_for_ftp($config) {
  111. return $this->rules_cache_generate($config, true);
  112. }
  113. /**
  114. * rules cache
  115. **/
  116. /**
  117. * Writes cache rules
  118. *
  119. * @throws FilesystemOperationException with S/FTP form if it can't get the required filesystem credentials
  120. * @throws FileOperationException
  121. */
  122. private function rules_cache_add($config, $exs) {
  123. w3_add_rules($exs,
  124. w3_get_browsercache_rules_cache_path(),
  125. $this->rules_cache_generate($config),
  126. W3TC_MARKER_BEGIN_BROWSERCACHE_CACHE,
  127. W3TC_MARKER_END_BROWSERCACHE_CACHE,
  128. array(
  129. W3TC_MARKER_BEGIN_MINIFY_CORE => 0,
  130. W3TC_MARKER_BEGIN_PGCACHE_CORE => 0,
  131. W3TC_MARKER_BEGIN_BROWSERCACHE_NO404WP => 0,
  132. W3TC_MARKER_BEGIN_WORDPRESS => 0,
  133. W3TC_MARKER_END_PGCACHE_CACHE => strlen(W3TC_MARKER_END_PGCACHE_CACHE) + 1,
  134. W3TC_MARKER_END_MINIFY_CACHE => strlen(W3TC_MARKER_END_MINIFY_CACHE) + 1
  135. )
  136. );
  137. }
  138. /**
  139. * Removes cache directives
  140. *
  141. * @throws FilesystemOperationException with S/FTP form if it can't get the required filesystem credentials
  142. * @throws FileOperationException
  143. */
  144. private function rules_cache_remove($exs) {
  145. w3_remove_rules($exs,
  146. w3_get_browsercache_rules_cache_path(),
  147. W3TC_MARKER_BEGIN_BROWSERCACHE_CACHE,
  148. W3TC_MARKER_END_BROWSERCACHE_CACHE);
  149. }
  150. /**
  151. * Returns cache rules
  152. *
  153. * @param W3_Config $config
  154. * @param bool $cdnftp
  155. * @return string
  156. */
  157. public function rules_cache_generate($config, $cdnftp = false) {
  158. switch (true) {
  159. case w3_is_apache():
  160. case w3_is_litespeed():
  161. return $this->rules_cache_generate_apache($config);
  162. case w3_is_nginx():
  163. return $this->rules_cache_generate_nginx($config, $cdnftp);
  164. }
  165. return '';
  166. }
  167. /**
  168. * Returns cache rules
  169. *
  170. * @param W3_Config $config
  171. * @return string
  172. */
  173. private function rules_cache_generate_apache($config) {
  174. $mime_types2 = $this->get_mime_types();
  175. $cssjs_types = $mime_types2['cssjs'];
  176. $cssjs_types = array_unique($cssjs_types);
  177. $html_types = $mime_types2['html'];
  178. $other_types = $mime_types2['other'];
  179. $cssjs_expires = $config->get_boolean('browsercache.cssjs.expires');
  180. $html_expires = $config->get_boolean('browsercache.html.expires');
  181. $other_expires = $config->get_boolean('browsercache.other.expires');
  182. $cssjs_lifetime = $config->get_integer('browsercache.cssjs.lifetime');
  183. $html_lifetime = $config->get_integer('browsercache.html.lifetime');
  184. $other_lifetime = $config->get_integer('browsercache.other.lifetime');
  185. $compatibility = $config->get_boolean('pgcache.compatibility');
  186. $mime_types = array();
  187. if ($cssjs_expires && $cssjs_lifetime) {
  188. $mime_types = array_merge($mime_types, $cssjs_types);
  189. }
  190. if ($html_expires && $html_lifetime) {
  191. $mime_types = array_merge($mime_types, $html_types);
  192. }
  193. if ($other_expires && $other_lifetime) {
  194. $mime_types = array_merge($mime_types, $other_types);
  195. }
  196. $rules = '';
  197. $rules .= W3TC_MARKER_BEGIN_BROWSERCACHE_CACHE . "\n";
  198. if (count($mime_types)) {
  199. $rules .= "<IfModule mod_mime.c>\n";
  200. foreach ($mime_types as $ext => $mime_type) {
  201. $extensions = explode('|', $ext);
  202. if (!is_array($mime_type))
  203. $mime_type = (array)$mime_type;
  204. foreach($mime_type as $mime_type2) {
  205. $rules .= " AddType " . $mime_type2;
  206. foreach ($extensions as $extension) {
  207. $rules .= " ." . $extension;
  208. }
  209. $rules .= "\n";
  210. }
  211. }
  212. $rules .= "</IfModule>\n";
  213. $rules .= "<IfModule mod_expires.c>\n";
  214. $rules .= " ExpiresActive On\n";
  215. if ($cssjs_expires && $cssjs_lifetime) {
  216. foreach ($cssjs_types as $mime_type) {
  217. $rules .= " ExpiresByType " . $mime_type . " A" . $cssjs_lifetime . "\n";
  218. }
  219. }
  220. if ($html_expires && $html_lifetime) {
  221. foreach ($html_types as $mime_type) {
  222. $rules .= " ExpiresByType " . $mime_type . " A" . $html_lifetime . "\n";
  223. }
  224. }
  225. if ($other_expires && $other_lifetime) {
  226. foreach ($other_types as $mime_type) {
  227. if (is_array($mime_type))
  228. foreach ($mime_type as $mime_type2)
  229. $rules .= " ExpiresByType " . $mime_type2 . " A" . $other_lifetime . "\n";
  230. else
  231. $rules .= " ExpiresByType " . $mime_type . " A" . $other_lifetime . "\n";
  232. }
  233. }
  234. $rules .= "</IfModule>\n";
  235. }
  236. $cssjs_compression = $config->get_boolean('browsercache.cssjs.compression');
  237. $html_compression = $config->get_boolean('browsercache.html.compression');
  238. $other_compression = $config->get_boolean('browsercache.other.compression');
  239. if ($cssjs_compression || $html_compression || $other_compression) {
  240. $compression_types = array();
  241. if ($cssjs_compression) {
  242. $compression_types = array_merge($compression_types, $cssjs_types);
  243. }
  244. if ($html_compression) {
  245. $compression_types = array_merge($compression_types, $html_types);
  246. }
  247. if ($other_compression) {
  248. $compression_types = array_merge($compression_types, array(
  249. //for some reason the 'other' types are not loaded from the 'other' file
  250. 'ico' => 'image/x-icon',
  251. 'json' => 'application/json'
  252. ));
  253. }
  254. $rules .= "<IfModule mod_deflate.c>\n";
  255. if ($compatibility) {
  256. $rules .= " <IfModule mod_setenvif.c>\n";
  257. $rules .= " BrowserMatch ^Mozilla/4 gzip-only-text/html\n";
  258. $rules .= " BrowserMatch ^Mozilla/4\\.0[678] no-gzip\n";
  259. $rules .= " BrowserMatch \\bMSIE !no-gzip !gzip-only-text/html\n";
  260. $rules .= " BrowserMatch \\bMSI[E] !no-gzip !gzip-only-text/html\n";
  261. $rules .= " </IfModule>\n";
  262. }
  263. $rules .= " <IfModule mod_headers.c>\n";
  264. $rules .= " Header append Vary User-Agent env=!dont-vary\n";
  265. $rules .= " </IfModule>\n";
  266. if (version_compare($this->_get_server_version(), '2.3.7', '>=')) {
  267. $rules .= " <IfModule mod_filter.c>\n";
  268. }
  269. $rules .= " AddOutputFilterByType DEFLATE " . implode(' ', $compression_types) . "\n";
  270. $rules .= " <IfModule mod_mime.c>\n";
  271. $rules .= " # DEFLATE by extension\n";
  272. $rules .= " AddOutputFilter DEFLATE js css htm html xml\n";
  273. $rules .= " </IfModule>\n";
  274. if (version_compare($this->_get_server_version(), '2.3.7', '>=')) {
  275. $rules .= " </IfModule>\n";
  276. }
  277. $rules .= "</IfModule>\n";
  278. }
  279. foreach ($mime_types2 as $type => $extensions)
  280. $rules .= $this->_rules_cache_generate_apache_for_type($config,
  281. $extensions, $type);
  282. $rules .= W3TC_MARKER_END_BROWSERCACHE_CACHE . "\n";
  283. return $rules;
  284. }
  285. /**
  286. * Writes cache rules
  287. *
  288. * @param W3_Config $config
  289. * @param array $mime_types
  290. * @param string $section
  291. * @return string
  292. */
  293. private function _rules_cache_generate_apache_for_type($config, $mime_types,
  294. $section) {
  295. $is_disc_enhanced = $config->get_boolean('pgcache.enabled') &&
  296. $config->get_string('pgcache.engine') == 'file_generic';
  297. $cache_control = $config->get_boolean('browsercache.' . $section . '.cache.control');
  298. $etag = $config->get_boolean('browsercache.' . $section . '.etag');
  299. $w3tc = $config->get_boolean('browsercache.' . $section . '.w3tc');
  300. $unset_setcookie = $config->get_boolean('browsercache.' . $section . '.nocookies');
  301. $set_last_modified = $config->get_boolean('browsercache.' . $section . '.last_modified');
  302. $compatibility = $config->get_boolean('pgcache.compatibility');
  303. $extensions = array_keys($mime_types);
  304. // Remove ext from filesmatch if its the same as permalink extension
  305. $pext = strtolower(pathinfo(get_option('permalink_structure'), PATHINFO_EXTENSION));
  306. if ($pext) {
  307. $extensions = $this->_remove_extension_from_list($extensions, $pext);
  308. }
  309. $extensions_lowercase = array_map('strtolower', $extensions);
  310. $extensions_uppercase = array_map('strtoupper', $extensions);
  311. $rules = '';
  312. $headers_rules = '';
  313. if ($cache_control) {
  314. $cache_policy = $config->get_string('browsercache.' . $section . '.cache.policy');
  315. switch ($cache_policy) {
  316. case 'cache':
  317. $headers_rules .= " Header set Pragma \"public\"\n";
  318. $headers_rules .= " Header set Cache-Control \"public\"\n";
  319. break;
  320. case 'cache_public_maxage':
  321. $expires = $config->get_boolean('browsercache.' . $section . '.expires');
  322. $lifetime = $config->get_integer('browsercache.' . $section . '.lifetime');
  323. $headers_rules .= " Header set Pragma \"public\"\n";
  324. if ($expires)
  325. $headers_rules .= " Header append Cache-Control \"public\"\n";
  326. else
  327. $headers_rules .= " Header set Cache-Control \"max-age=" . $lifetime . ", public\"\n";
  328. break;
  329. case 'cache_validation':
  330. $headers_rules .= " Header set Pragma \"public\"\n";
  331. $headers_rules .= " Header set Cache-Control \"public, must-revalidate, proxy-revalidate\"\n";
  332. break;
  333. case 'cache_noproxy':
  334. $headers_rules .= " Header set Pragma \"public\"\n";
  335. $headers_rules .= " Header set Cache-Control \"private, must-revalidate\"\n";
  336. break;
  337. case 'cache_maxage':
  338. $expires = $config->get_boolean('browsercache.' . $section . '.expires');
  339. $lifetime = $config->get_integer('browsercache.' . $section . '.lifetime');
  340. $headers_rules .= " Header set Pragma \"public\"\n";
  341. if ($expires)
  342. $headers_rules .= " Header append Cache-Control \"public, must-revalidate, proxy-revalidate\"\n";
  343. else
  344. $headers_rules .= " Header set Cache-Control \"max-age=" . $lifetime . ", public, must-revalidate, proxy-revalidate\"\n";
  345. break;
  346. case 'no_cache':
  347. $headers_rules .= " Header set Pragma \"no-cache\"\n";
  348. $headers_rules .= " Header set Cache-Control \"max-age=0, private, no-store, no-cache, must-revalidate\"\n";
  349. break;
  350. }
  351. }
  352. if ($etag) {
  353. $rules .= " FileETag MTime Size\n";
  354. } else {
  355. if ($compatibility) {
  356. $rules .= " FileETag None\n";
  357. $headers_rules .= " Header unset ETag\n";
  358. }
  359. }
  360. if ($unset_setcookie)
  361. $headers_rules .= " Header unset Set-Cookie\n";
  362. if (!$set_last_modified)
  363. $headers_rules .= " Header unset Last-Modified\n";
  364. if ($w3tc)
  365. $headers_rules .= " Header set X-Powered-By \"" . W3TC_POWERED_BY . "\"\n";
  366. if (strlen($headers_rules) > 0) {
  367. $rules .= " <IfModule mod_headers.c>\n";
  368. $rules .= $headers_rules;
  369. $rules .= " </IfModule>\n";
  370. }
  371. if (strlen($rules) > 0) {
  372. $rules = "<FilesMatch \"\\.(" . implode('|',
  373. array_merge($extensions_lowercase, $extensions_uppercase)) .
  374. ")$\">\n" . $rules;
  375. $rules .= "</FilesMatch>\n";
  376. }
  377. return $rules;
  378. }
  379. /**
  380. * Returns cache rules
  381. *
  382. * @param W3_Config $config
  383. * @param bool $cdnftp
  384. * @return string
  385. */
  386. private function rules_cache_generate_nginx($config, $cdnftp = false) {
  387. $mime_types = $this->get_mime_types();
  388. $cssjs_types = $mime_types['cssjs'];
  389. $cssjs_types = array_unique($cssjs_types);
  390. $html_types = $mime_types['html'];
  391. $other_types = $mime_types['other'];
  392. $rules = '';
  393. $rules .= W3TC_MARKER_BEGIN_BROWSERCACHE_CACHE . "\n";
  394. $cssjs_compression = $config->get_boolean('browsercache.cssjs.compression');
  395. $html_compression = $config->get_boolean('browsercache.html.compression');
  396. $other_compression = $config->get_boolean('browsercache.other.compression');
  397. if ($cssjs_compression || $html_compression || $other_compression) {
  398. $compression_types = array();
  399. if ($cssjs_compression) {
  400. $compression_types = array_merge($compression_types, $cssjs_types);
  401. }
  402. if ($html_compression) {
  403. $compression_types = array_merge($compression_types, $html_types);
  404. }
  405. if ($other_compression) {
  406. $compression_types = array_merge($compression_types, array(
  407. 'ico' => 'image/x-icon'
  408. ));
  409. }
  410. unset($compression_types['html|htm']);
  411. $rules .= "gzip on;\n";
  412. $rules .= "gzip_types " . implode(' ', $compression_types) . ";\n";
  413. }
  414. foreach ($mime_types as $type => $extensions)
  415. $this->_rules_cache_generate_nginx_for_type($config, $rules,
  416. $extensions, $type);
  417. $rules .= W3TC_MARKER_END_BROWSERCACHE_CACHE . "\n";
  418. return $rules;
  419. }
  420. /**
  421. * Adds cache rules for type to &$rules
  422. *
  423. * @param W3_Config $config
  424. * @param string $rules
  425. * @param array $mime_types
  426. * @param string $section
  427. * @param boolean $write_location
  428. * @param boolean $cdnftp
  429. * @return void
  430. */
  431. private function _rules_cache_generate_nginx_for_type($config, &$rules,
  432. $mime_types, $section, $write_location = false, $cdnftp = false) {
  433. $expires = $config->get_boolean('browsercache.' . $section . '.expires');
  434. $cache_control = $config->get_boolean('browsercache.' . $section . '.cache.control');
  435. $w3tc = $config->get_boolean('browsercache.' . $section . '.w3tc');
  436. if ($expires || $cache_control || $w3tc) {
  437. $lifetime = $config->get_integer('browsercache.' . $section . '.lifetime');
  438. $extensions = array_keys($mime_types);
  439. // Remove ext from filesmatch if its the same as permalink extension
  440. $pext = strtolower(pathinfo(get_option('permalink_structure'), PATHINFO_EXTENSION));
  441. if ($pext) {
  442. $extensions = $this->_remove_extension_from_list($extensions, $pext);
  443. }
  444. $rules .= "location ~ \\.(" . implode('|', $extensions) . ")$ {\n";
  445. if ($expires) {
  446. $rules .= " expires " . $lifetime . "s;\n";
  447. }
  448. if ($cache_control) {
  449. $cache_policy = $config->get_string('browsercache.cssjs.cache.policy');
  450. switch ($cache_policy) {
  451. case 'cache':
  452. $rules .= " add_header Pragma \"public\";\n";
  453. $rules .= " add_header Cache-Control \"public\";\n";
  454. break;
  455. case 'cache_public_maxage':
  456. $rules .= " add_header Pragma \"public\";\n";
  457. $rules .= " add_header Cache-Control \"max-age=" . $lifetime . ", public\";\n";
  458. break;
  459. case 'cache_validation':
  460. $rules .= " add_header Pragma \"public\";\n";
  461. $rules .= " add_header Cache-Control \"public, must-revalidate, proxy-revalidate\";\n";
  462. break;
  463. case 'cache_noproxy':
  464. $rules .= " add_header Pragma \"public\";\n";
  465. $rules .= " add_header Cache-Control \"private, must-revalidate\";\n";
  466. break;
  467. case 'cache_maxage':
  468. $rules .= " add_header Pragma \"public\";\n";
  469. $rules .= " add_header Cache-Control \"max-age=" . $lifetime . ", public, must-revalidate, proxy-revalidate\";\n";
  470. break;
  471. case 'no_cache':
  472. $rules .= " add_header Pragma \"no-cache\";\n";
  473. $rules .= " add_header Cache-Control \"max-age=0, private, no-store, no-cache, must-revalidate\";\n";
  474. break;
  475. }
  476. }
  477. $w3_dispatcher = w3_instance('W3_Dispatcher');
  478. $rules .= $w3_dispatcher->on_browsercache_rules_generation_for_section(
  479. $config, $cdnftp, $section);
  480. if ($w3tc) {
  481. $rules .= " add_header X-Powered-By \"" . W3TC_POWERED_BY . "\";\n";
  482. }
  483. if ($write_location) {
  484. $rules .= ' try_files $uri $uri/ $uri.html /index.php?$args;' . "\n";
  485. }
  486. $rules .= "}\n";
  487. }
  488. }
  489. /**
  490. * rules_no404wp
  491. **/
  492. /**
  493. * Writes no 404 by WP rules
  494. *
  495. * @param W3_Config $config
  496. * @param SelfTestExceptions $exs
  497. * @throws FilesystemOperationException with S/FTP form
  498. * @throws FileOperationException
  499. */
  500. private function rules_no404wp_add($config, $exs) {
  501. w3_add_rules($exs, w3_get_browsercache_rules_no404wp_path(),
  502. $this->rules_no404wp_generate($config),
  503. W3TC_MARKER_BEGIN_BROWSERCACHE_NO404WP,
  504. W3TC_MARKER_END_BROWSERCACHE_NO404WP,
  505. array(
  506. W3TC_MARKER_BEGIN_WORDPRESS => 0,
  507. W3TC_MARKER_END_PGCACHE_CORE =>
  508. strlen(W3TC_MARKER_END_PGCACHE_CORE) + 1,
  509. W3TC_MARKER_END_MINIFY_CORE =>
  510. strlen(W3TC_MARKER_END_MINIFY_CORE) + 1,
  511. W3TC_MARKER_END_BROWSERCACHE_CACHE =>
  512. strlen(W3TC_MARKER_END_BROWSERCACHE_CACHE) + 1,
  513. W3TC_MARKER_END_PGCACHE_CACHE =>
  514. strlen(W3TC_MARKER_END_PGCACHE_CACHE) + 1,
  515. W3TC_MARKER_END_MINIFY_CACHE =>
  516. strlen(W3TC_MARKER_END_MINIFY_CACHE) + 1
  517. )
  518. );
  519. }
  520. /**
  521. * Removes 404 directives
  522. *
  523. * @throws FilesystemOperationException with S/FTP form
  524. * @throws FileOperationException
  525. */
  526. private function rules_no404wp_remove($exs) {
  527. w3_remove_rules($exs,
  528. w3_get_browsercache_rules_no404wp_path(),
  529. W3TC_MARKER_BEGIN_BROWSERCACHE_NO404WP,
  530. W3TC_MARKER_END_BROWSERCACHE_NO404WP
  531. );
  532. }
  533. /**
  534. * Generate rules related to prevent for media 404 error by WP
  535. *
  536. * @param W3_Config $config
  537. * @return string
  538. */
  539. private function rules_no404wp_generate($config) {
  540. switch (true) {
  541. case w3_is_apache():
  542. case w3_is_litespeed():
  543. return $this->rules_no404wp_generate_apache($config);
  544. case w3_is_nginx():
  545. return $this->rules_no404wp_generate_nginx($config);
  546. }
  547. return false;
  548. }
  549. /**
  550. * Generate rules related to prevent for media 404 error by WP
  551. *
  552. * @param W3_Config $config
  553. * @return string
  554. */
  555. private function rules_no404wp_generate_apache($config) {
  556. $a = $this->get_mime_types();
  557. $cssjs_types = $a['cssjs'];
  558. $html_types = $a['html'];
  559. $other_types = $a['other'];
  560. $extensions = array_merge(array_keys($cssjs_types),
  561. array_keys($html_types), array_keys($other_types));
  562. $permalink_structure = get_option('permalink_structure');
  563. $permalink_structure_ext = ltrim(strrchr($permalink_structure, '.'),
  564. '.');
  565. if ($permalink_structure_ext != '') {
  566. foreach ($extensions as $index => $extension) {
  567. if (strstr($extension, $permalink_structure_ext) !== false) {
  568. $extensions[$index] = preg_replace('~\|?' .
  569. w3_preg_quote($permalink_structure_ext) .
  570. '\|?~', '', $extension);
  571. }
  572. }
  573. }
  574. $exceptions = $config->get_array('browsercache.no404wp.exceptions');
  575. $rules = '';
  576. $rules .= W3TC_MARKER_BEGIN_BROWSERCACHE_NO404WP . "\n";
  577. $rules .= "<IfModule mod_rewrite.c>\n";
  578. $rules .= " RewriteEngine On\n";
  579. $rules .= " RewriteCond %{REQUEST_FILENAME} !-f\n";
  580. $rules .= " RewriteCond %{REQUEST_FILENAME} !-d\n";
  581. if (count($exceptions)) {
  582. $rules .= " RewriteCond %{REQUEST_URI} !(" .
  583. implode('|', $exceptions) . ")\n";
  584. }
  585. $rules .= " RewriteCond %{REQUEST_FILENAME} \\.(" .
  586. implode('|', $extensions) . ")$ [NC]\n";
  587. $rules .= " RewriteRule .* - [L]\n";
  588. $rules .= "</IfModule>\n";
  589. $rules .= W3TC_MARKER_END_BROWSERCACHE_NO404WP . "\n";
  590. return $rules;
  591. }
  592. /**
  593. * Generate rules related to prevent for media 404 error by WP
  594. *
  595. * @param W3_Config $config
  596. * @return string
  597. */
  598. private function rules_no404wp_generate_nginx($config) {
  599. $a = $this->get_mime_types();
  600. $cssjs_types = $a['cssjs'];
  601. $html_types = $a['html'];
  602. $other_types = $a['other'];
  603. $extensions = array_merge(array_keys($cssjs_types),
  604. array_keys($html_types), array_keys($other_types));
  605. $permalink_structure = get_option('permalink_structure');
  606. $permalink_structure_ext =
  607. ltrim(strrchr($permalink_structure, '.'), '.');
  608. if ($permalink_structure_ext != '') {
  609. foreach ($extensions as $index => $extension) {
  610. if (strstr($extension, $permalink_structure_ext) !== false) {
  611. $extensions[$index] = preg_replace('~\|?' .
  612. w3_preg_quote($permalink_structure_ext) . '\|?~', '',
  613. $extension);
  614. }
  615. }
  616. }
  617. $exceptions = $config->get_array('browsercache.no404wp.exceptions');
  618. $rules = '';
  619. $rules .= W3TC_MARKER_BEGIN_BROWSERCACHE_NO404WP . "\n";
  620. $rules .= "if (-f \$request_filename) {\n";
  621. $rules .= " break;\n";
  622. $rules .= "}\n";
  623. $rules .= "if (-d \$request_filename) {\n";
  624. $rules .= " break;\n";
  625. $rules .= "}\n";
  626. if (count($exceptions)) {
  627. $rules .= "if (\$request_uri ~ \"(" . implode('|', $exceptions) .
  628. ")\") {\n";
  629. $rules .= " break;\n";
  630. $rules .= "}\n";
  631. }
  632. $rules .= "if (\$request_uri ~* \\.(" . implode('|', $extensions) .
  633. ")$) {\n";
  634. $rules .= " return 404;\n";
  635. $rules .= "}\n";
  636. $rules .= W3TC_MARKER_END_BROWSERCACHE_NO404WP . "\n";
  637. return $rules;
  638. }
  639. /**
  640. * Returns the apache, nginx version
  641. * @return string
  642. */
  643. private function _get_server_version() {
  644. $sig= explode('/', $_SERVER['SERVER_SOFTWARE']);
  645. $temp = isset($sig[1]) ? explode(' ', $sig[1]) : array('0');
  646. $version = $temp[0];
  647. return $version;
  648. }
  649. /**
  650. * Takes an array of extensions single per row and/or extensions delimited by |
  651. * @param $extensions
  652. * @param $ext
  653. * @return array
  654. */
  655. private function _remove_extension_from_list($extensions, $ext) {
  656. for ($i = 0; $i < sizeof($extensions); $i++) {
  657. if ($extensions[$i] == $ext) {
  658. unset($extensions[$i]);
  659. return $extensions;
  660. } elseif (strpos($extensions[$i], $ext) !== false &&
  661. strpos($extensions[$i], '|') !== false) {
  662. $exts = explode('|', $extensions[$i]);
  663. $key = array_search($ext, $exts);
  664. unset($exts[$key]);
  665. $extensions[$i] = implode('|', $exts);
  666. return $extensions;
  667. }
  668. }
  669. return $extensions;
  670. }
  671. }